116 lines
5.5 KiB
C++
116 lines
5.5 KiB
C++
#include "prx/libc/include/general/VabiMacros.hpp"
|
|
#include <cstdint>
|
|
#include <cstdlib>
|
|
#include <cstring>
|
|
|
|
extern "C" {
|
|
const std::uint8_t* APS5_VABI sceCesRefersUcsProfileCp1252(void);
|
|
const std::uint8_t* APS5_VABI sceCesRefersUcsProfileCp1251(void);
|
|
int APS5_VABI sceCesMbcsUcsContextInit(void*, const void*);
|
|
int APS5_VABI sceCesSbcToUtf8(const std::uint8_t*, std::uint8_t, std::uint8_t*, std::uint32_t, std::uint32_t*);
|
|
int APS5_VABI sceCesUtf8ToSbc(const std::uint8_t*, std::uint32_t, std::uint32_t*, const std::uint8_t*, std::uint8_t*);
|
|
void* APS5_VABI sceCesUcsProfileInitSJis1997Cp932(void*);
|
|
}
|
|
|
|
static void Require(bool value) { if (!value) std::abort(); }
|
|
|
|
static void RequireSbcToUtf8(const std::uint8_t* profile, std::uint8_t sbc, const char* expected) {
|
|
std::uint8_t utf8[4] = {};
|
|
std::uint32_t length = 0;
|
|
Require(sceCesSbcToUtf8(profile, sbc, utf8, sizeof(utf8), &length) == 0);
|
|
Require(length == std::strlen(expected) && std::memcmp(utf8, expected, length) == 0);
|
|
}
|
|
|
|
static void RequireUtf8ToSbc(const std::uint8_t* profile, const char* utf8, std::uint8_t expected) {
|
|
const auto size = static_cast<std::uint32_t>(std::strlen(utf8));
|
|
std::uint32_t length = 0;
|
|
std::uint8_t sbc = 0;
|
|
Require(sceCesUtf8ToSbc(reinterpret_cast<const std::uint8_t*>(utf8), size + 4, &length, profile, &sbc) == 0);
|
|
Require(length == size && sbc == expected);
|
|
}
|
|
|
|
static int Utf8ToSbc(const std::uint8_t* profile, const char* utf8, std::uint32_t utf8max) {
|
|
std::uint32_t length = 0;
|
|
std::uint8_t sbc = 0;
|
|
return sceCesUtf8ToSbc(reinterpret_cast<const std::uint8_t*>(utf8), utf8max, &length, profile, &sbc);
|
|
}
|
|
|
|
int main() {
|
|
constexpr int invalidParameter = static_cast<int>(0x805C0001);
|
|
constexpr int invalidSrcBuffer = static_cast<int>(0x805C0010);
|
|
constexpr int srcBufferEnd = static_cast<int>(0x805C0011);
|
|
constexpr int invalidEncode = static_cast<int>(0x805C0014);
|
|
constexpr int unassignedCode = static_cast<int>(0x805C0020);
|
|
constexpr int invalidDstBuffer = static_cast<int>(0x805C0030);
|
|
constexpr int dstBufferEnd = static_cast<int>(0x805C0031);
|
|
|
|
const std::uint8_t* profile = sceCesRefersUcsProfileCp1252();
|
|
Require(profile != nullptr && profile == sceCesRefersUcsProfileCp1252());
|
|
|
|
RequireSbcToUtf8(profile, 'A', "A");
|
|
RequireSbcToUtf8(profile, 0x80, "\xE2\x82\xAC");
|
|
RequireSbcToUtf8(profile, 0x9F, "\xC5\xB8");
|
|
RequireSbcToUtf8(profile, 0x81, "\xC2\x81");
|
|
RequireSbcToUtf8(profile, 0xE9, "\xC3\xA9");
|
|
RequireSbcToUtf8(profile, 0xFF, "\xC3\xBF");
|
|
|
|
RequireUtf8ToSbc(profile, "A", 'A');
|
|
RequireUtf8ToSbc(profile, "\xE2\x82\xAC", 0x80);
|
|
RequireUtf8ToSbc(profile, "\xE2\x84\xA2", 0x99);
|
|
RequireUtf8ToSbc(profile, "\xC3\xA9", 0xE9);
|
|
RequireUtf8ToSbc(profile, "\xC2\x8D", 0x8D);
|
|
for (int sbc = 1; sbc < 256; ++sbc) {
|
|
std::uint8_t utf8[4] = {};
|
|
std::uint32_t length = 0;
|
|
std::uint8_t back = 0;
|
|
Require(sceCesSbcToUtf8(profile, static_cast<std::uint8_t>(sbc), utf8, sizeof(utf8), &length) == 0);
|
|
Require(sceCesUtf8ToSbc(utf8, length, &length, profile, &back) == 0 && back == sbc);
|
|
}
|
|
|
|
std::uint8_t utf8[4] = {};
|
|
std::uint32_t length = 0;
|
|
std::uint8_t sbc = 0;
|
|
Require(sceCesSbcToUtf8(nullptr, 'A', utf8, sizeof(utf8), &length) == invalidParameter);
|
|
Require(sceCesSbcToUtf8(profile, 'A', nullptr, sizeof(utf8), &length) == invalidDstBuffer);
|
|
Require(sceCesSbcToUtf8(profile, 0x80, utf8, 2, &length) == dstBufferEnd);
|
|
Require(sceCesUtf8ToSbc(utf8, 1, &length, nullptr, &sbc) == invalidParameter);
|
|
Require(sceCesUtf8ToSbc(nullptr, 1, &length, profile, &sbc) == invalidSrcBuffer);
|
|
Require(sceCesUtf8ToSbc(utf8, 1, &length, profile, nullptr) == invalidDstBuffer);
|
|
Require(Utf8ToSbc(profile, "A", 0) == srcBufferEnd);
|
|
Require(Utf8ToSbc(profile, "\xE2\x82\xAC", 2) == srcBufferEnd);
|
|
Require(Utf8ToSbc(profile, "\x80", 1) == invalidEncode);
|
|
Require(Utf8ToSbc(profile, "\xC0\xAF", 2) == invalidEncode);
|
|
Require(Utf8ToSbc(profile, "\xED\xA0\x80", 3) == invalidEncode);
|
|
Require(Utf8ToSbc(profile, "\xE3\x81\x82", 3) == unassignedCode);
|
|
Require(Utf8ToSbc(profile, "\xF0\x9F\x98\x80", 4) == unassignedCode);
|
|
|
|
const std::uint8_t* cyrillic = sceCesRefersUcsProfileCp1251();
|
|
Require(cyrillic != nullptr && cyrillic == sceCesRefersUcsProfileCp1251() && cyrillic != profile);
|
|
RequireSbcToUtf8(cyrillic, 'A', "A");
|
|
RequireSbcToUtf8(cyrillic, 0x88, "\xE2\x82\xAC");
|
|
RequireSbcToUtf8(cyrillic, 0xC0, "\xD0\x90");
|
|
RequireSbcToUtf8(cyrillic, 0xFF, "\xD1\x8F");
|
|
RequireSbcToUtf8(cyrillic, 0xA8, "\xD0\x81");
|
|
RequireSbcToUtf8(cyrillic, 0xB9, "\xE2\x84\x96");
|
|
RequireUtf8ToSbc(cyrillic, "\xD0\x9F", 0xCF);
|
|
RequireUtf8ToSbc(cyrillic, "\xD1\x91", 0xB8);
|
|
for (int sbc = 1; sbc < 256; ++sbc) {
|
|
std::uint8_t cp[4] = {};
|
|
std::uint32_t cpLength = 0;
|
|
std::uint8_t back = 0;
|
|
Require(sceCesSbcToUtf8(cyrillic, static_cast<std::uint8_t>(sbc), cp, sizeof(cp), &cpLength) == 0);
|
|
Require(sceCesUtf8ToSbc(cp, cpLength, &cpLength, cyrillic, &back) == 0 && back == sbc);
|
|
}
|
|
Require(Utf8ToSbc(cyrillic, "\xC3\xA9", 2) == unassignedCode);
|
|
Require(Utf8ToSbc(profile, "\xD0\x90", 2) == unassignedCode);
|
|
|
|
char context[256] = {};
|
|
Require(sceCesMbcsUcsContextInit(context, cyrillic) == 0);
|
|
Require(sceCesMbcsUcsContextInit(nullptr, cyrillic) == invalidParameter);
|
|
|
|
char sheet[256] = {};
|
|
Require(sceCesUcsProfileInitSJis1997Cp932(sheet) == sheet);
|
|
Require(sceCesUcsProfileInitSJis1997Cp932(nullptr) == nullptr);
|
|
Require(sceCesMbcsUcsContextInit(context, sheet) == 0);
|
|
}
|