22 tmpStrCat(
"unicodemaps/character_set_mappings/", mappingName));
24 throw MSXException(
"Couldn't find MSX character mapping file that was specified in unicodemap: ", mappingName,
" (",
e.getMessage(),
")");
28 auto buf = file.
mmap();
29 parseVid(std::string_view(
reinterpret_cast<const char*
>(buf.data()), buf.size()));
31 throw MSXException(
"Couldn't load MSX character mapping file that was specified in unicodemap: ", filename);
41static constexpr std::string_view getLine(std::string_view& text)
43 if (
auto pos = text.find_first_of(
'\n'); pos != std::string_view::npos) {
45 auto pos2 = ((pos != 0) && (text[pos - 1] ==
'\r')) ? pos - 1 : pos;
46 auto result = text.substr(0, pos2);
47 text.remove_prefix(pos + 1);
50 return std::exchange(text, {});
57[[nodiscard]]
static constexpr std::string_view stripComments(std::string_view line)
59 if (
auto pos = line.find_first_of(
'#'); pos != std::string_view::npos) {
60 line = line.substr(0, pos);
68[[nodiscard]]
static constexpr bool isSep(
char c)
70 return c ==
one_of(
' ',
'\t',
'\r');
78static constexpr std::string_view getToken(std::string_view& line)
80 size_t s = line.size();
82 while ((i < s) && !isSep(line[i])) {
85 auto result = line.substr(0, i);
86 while ((i < s) && isSep(line[i])) {
89 line.remove_prefix(i);
93void MsxChar2Unicode::parseVid(std::string_view file)
104 unicode2msx.reserve(256);
106 while (!file.empty()) {
107 auto origLine = getLine(file);
108 auto line = stripComments(origLine);
110 auto msxTok = getToken(line);
111 if (msxTok.empty())
continue;
112 auto msx = StringOp::stringTo<uint8_t>(msxTok);
114 throw MSXException(
"Invalid msx character value, expected an "
115 "integer in range 0x00..0xff, but got: ", msxTok);
118 auto unicodeTok = getToken(line);
119 if ((unicodeTok.size() >= 5) && (unicodeTok[0] ==
'<') &&
120 (unicodeTok[3] ==
'>') && (unicodeTok[4] ==
'+')) {
128 unicodeTok.remove_prefix(5);
130 auto unicode = StringOp::stringTo<uint32_t>(unicodeTok);
131 if (!unicode || *unicode > 0x10ffff) {
132 throw MSXException(
"Invalid unicode character value, expected an "
133 "integer in range 0..0x10ffff, but got: ", unicodeTok);
137 throw MSXException(
"Syntax error, expected \"<msx-char> <unicode>\", "
138 "but got: ", origLine);
143 if (msx2unicode[*msx] == uint32_t(-1)) {
144 msx2unicode[*msx] = *unicode;
147 unicode2msx.emplace_back(*unicode, *msx);
154 unicode2msx.erase(
ranges::unique(unicode2msx, {}, &Entry::unicode),
end(unicode2msx));
158 std::span<const uint8_t> msx,
const std::function<uint32_t(uint8_t)>& fallback)
const
161 utf8.reserve(msx.size());
162 auto out = std::back_inserter(
utf8);
164 auto u = msx2unicode[m];
165 auto u2 = (u != uint32_t(-1)) ? u : fallback(m);
172 std::string_view
utf8,
const std::function<uint8_t(uint32_t)>& fallback)
const
174 std::vector<uint8_t> msx;
175 auto it =
utf8.begin(), et =
utf8.end();
178 auto m =
binary_find(unicode2msx, u, {}, &Entry::unicode);
179 msx.push_back(m ? m->msx : fallback(u));
186 return msxToUtf8(msx, [&](uint32_t) {
return fallback; });
std::string resolve(std::string_view filename) const
std::span< const uint8_t > mmap()
Map file in memory.
std::vector< uint8_t > utf8ToMsx(std::string_view utf8, const std::function< uint8_t(uint32_t)> &fallback) const
TODO.
MsxChar2Unicode(std::string_view mappingName)
std::string msxToUtf8(std::span< const uint8_t > msx, const std::function< uint32_t(uint8_t)> &fallback) const
TODO.
This file implemented 3 utility functions:
const FileContext & systemFileContext()
auto unique(ForwardRange &&range)
constexpr void fill(ForwardRange &&range, const T &value)
void stable_sort(RandomAccessRange &&range)
uint32_t next(octet_iterator &it)
octet_iterator append(uint32_t cp, octet_iterator result)
auto * binary_find(ForwardRange &&range, const T &value, Compare comp={}, Proj proj={})
TemporaryString tmpStrCat(Ts &&... ts)
constexpr auto end(const zstring_view &x)