26 tmpStrCat(
"unicodemaps/character_set_mappings/", mappingName));
28 throw MSXException(
"Couldn't find MSX character mapping file that was specified in unicodemap: ", mappingName,
" (", e.getMessage(),
")");
32 auto buf = file.
mmap();
33 parseVid(std::string_view(std::bit_cast<const char*>(buf.data()), buf.size()));
35 throw MSXException(
"Couldn't load MSX character mapping file that was specified in unicodemap: ", filename);
45static constexpr std::string_view getLine(std::string_view& text)
47 if (
auto pos = text.find_first_of(
'\n'); pos != std::string_view::npos) {
49 auto pos2 = ((pos != 0) && (text[pos - 1] ==
'\r')) ? pos - 1 : pos;
50 auto result = text.substr(0, pos2);
51 text.remove_prefix(pos + 1);
54 return std::exchange(text, {});
61[[nodiscard]]
static constexpr std::string_view stripComments(std::string_view line)
63 if (
auto pos = line.find_first_of(
'#'); pos != std::string_view::npos) {
64 line = line.substr(0, pos);
72[[nodiscard]]
static constexpr bool isSep(
char c)
74 return c ==
one_of(
' ',
'\t',
'\r');
82static constexpr std::string_view getToken(std::string_view& line)
84 size_t s = line.size();
86 while ((i < s) && !isSep(line[i])) {
89 auto result = line.substr(0, i);
90 while ((i < s) && isSep(line[i])) {
93 line.remove_prefix(i);
97void MsxChar2Unicode::parseVid(std::string_view file)
108 unicode2msx.reserve(256);
110 while (!file.empty()) {
111 auto origLine = getLine(file);
112 auto line = stripComments(origLine);
114 auto msxTok = getToken(line);
115 if (msxTok.empty())
continue;
116 auto msx = StringOp::stringTo<uint8_t>(msxTok);
118 throw MSXException(
"Invalid msx character value, expected an "
119 "integer in range 0x00..0xff, but got: ", msxTok);
122 auto unicodeTok = getToken(line);
123 if ((unicodeTok.size() >= 5) && (unicodeTok[0] ==
'<') &&
124 (unicodeTok[3] ==
'>') && (unicodeTok[4] ==
'+')) {
132 unicodeTok.remove_prefix(5);
134 auto unicode = StringOp::stringTo<uint32_t>(unicodeTok);
135 if (!unicode || *unicode > 0x10ffff) {
136 throw MSXException(
"Invalid unicode character value, expected an "
137 "integer in range 0..0x10ffff, but got: ", unicodeTok);
141 throw MSXException(
"Syntax error, expected \"<msx-char> <unicode>\", "
142 "but got: ", origLine);
147 if (msx2unicode[*msx] == uint32_t(-1)) {
148 msx2unicode[*msx] = *unicode;
151 unicode2msx.emplace_back(*unicode, *msx);
158 unicode2msx.erase(
ranges::unique(unicode2msx, {}, &Entry::unicode),
end(unicode2msx));
162 std::span<const uint8_t> msx,
const std::function<uint32_t(uint8_t)>& fallback)
const
165 utf8.reserve(msx.size());
166 auto out = std::back_inserter(
utf8);
168 auto u = msx2unicode[m];
169 auto u2 = (u != uint32_t(-1)) ? u : fallback(m);
176 std::string_view
utf8,
const std::function<uint8_t(uint32_t)>& fallback)
const
178 std::vector<uint8_t> msx;
179 auto it =
utf8.begin(), et =
utf8.end();
182 auto m =
binary_find(unicode2msx, u, {}, &Entry::unicode);
183 msx.push_back(m ? m->msx : fallback(u));
190 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)