mirror of
https://github.com/holub/mame
synced 2025-07-06 10:29:38 +03:00
[Imgtool] Changing imgtool::simple_charconverter::from_utf8() to not perform an O(n) lookup whenever locating a character
This commit is contained in:
parent
46ddd46f25
commit
e38b9b63ba
@ -36,6 +36,29 @@ void imgtool::charconverter::to_utf8(std::ostream &dest, const std::string &src)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// simple_charconverter::simple_charconverter
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
imgtool::simple_charconverter::simple_charconverter(const char32_t lowpage[0x80], const char32_t highpage[0x80], unicode_normalization_form norm)
|
||||||
|
: m_norm(norm), m_lowpage(lowpage), m_highpage(highpage)
|
||||||
|
{
|
||||||
|
// build the reverse lookup table
|
||||||
|
for (int i = 0; i < 256; i++)
|
||||||
|
{
|
||||||
|
const char32_t *page = i >= 128 ? m_highpage : m_lowpage;
|
||||||
|
char32_t unicode_char = page ? page[i % 128] : i;
|
||||||
|
m_reverse_lookup.emplace_back(unicode_char, (char)i);
|
||||||
|
}
|
||||||
|
|
||||||
|
// and sort it
|
||||||
|
std::sort(m_reverse_lookup.begin(), m_reverse_lookup.end(), [](const std::pair<char32_t, char> &a, const std::pair<char32_t, char> &b)
|
||||||
|
{
|
||||||
|
return b.first > a.first;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
// from_utf8
|
// from_utf8
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
@ -58,39 +81,16 @@ void imgtool::simple_charconverter::from_utf8(std::ostream &dest, const char *sr
|
|||||||
}
|
}
|
||||||
iter += rc;
|
iter += rc;
|
||||||
|
|
||||||
// look in all pages
|
// do the reverse lookup
|
||||||
const char32_t *pages[2];
|
auto lookup = std::lower_bound(m_reverse_lookup.begin(), m_reverse_lookup.end(), ch, [](const std::pair<char32_t, char> &a, const char32_t &b)
|
||||||
pages[0] = m_lowpage;
|
|
||||||
pages[1] = m_highpage;
|
|
||||||
|
|
||||||
bool found = false;
|
|
||||||
for (int i = 0; !found && i < ARRAY_LENGTH(pages); i++)
|
|
||||||
{
|
{
|
||||||
if (pages[i] == nullptr)
|
return a.first < b;
|
||||||
{
|
});
|
||||||
// null page; perhaps we can just emit this
|
if (lookup == m_reverse_lookup.end())
|
||||||
if (ch >= i * 0x80 && (ch < (i + 1) * 0x80))
|
|
||||||
{
|
|
||||||
dest << (char)ch;
|
|
||||||
found = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// non-null page; perform a lookup
|
|
||||||
// if we have a page, perform the lookup
|
|
||||||
const util::contiguous_sequence_wrapper<const char32_t> lookup(pages[i], 0x80);
|
|
||||||
auto lookup_iter = std::find(lookup.begin(), lookup.end(), ch);
|
|
||||||
if (lookup_iter != lookup.end())
|
|
||||||
{
|
|
||||||
// and emit the result
|
|
||||||
dest << (char)((i * 0x80) + (lookup_iter - lookup.begin()));
|
|
||||||
found = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!found)
|
|
||||||
throw charconverter_exception();
|
throw charconverter_exception();
|
||||||
|
|
||||||
|
// and output the results
|
||||||
|
dest << lookup->second;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,20 +52,18 @@ namespace imgtool
|
|||||||
class simple_charconverter : public charconverter
|
class simple_charconverter : public charconverter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
constexpr simple_charconverter(const char32_t highpage[0x80], unicode_normalization_form norm = unicode_normalization_form::C)
|
simple_charconverter(const char32_t highpage[0x80], unicode_normalization_form norm = unicode_normalization_form::C)
|
||||||
: m_norm(norm), m_lowpage(nullptr), m_highpage(highpage)
|
: simple_charconverter(nullptr, highpage, norm)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr simple_charconverter(const char32_t lowpage[0x80], const char32_t highpage[0x80], unicode_normalization_form norm = unicode_normalization_form::C)
|
simple_charconverter(const char32_t lowpage[0x80], const char32_t highpage[0x80], unicode_normalization_form norm = unicode_normalization_form::C);
|
||||||
: m_norm(norm), m_lowpage(lowpage), m_highpage(highpage)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void from_utf8(std::ostream &dest, const char *src, size_t src_length) const override;
|
virtual void from_utf8(std::ostream &dest, const char *src, size_t src_length) const override;
|
||||||
virtual void to_utf8(std::ostream &dest, const char *src, size_t src_length) const override;
|
virtual void to_utf8(std::ostream &dest, const char *src, size_t src_length) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
std::vector<std::pair<char32_t, char> > m_reverse_lookup;
|
||||||
unicode_normalization_form m_norm;
|
unicode_normalization_form m_norm;
|
||||||
const char32_t *m_lowpage;
|
const char32_t *m_lowpage;
|
||||||
const char32_t *m_highpage;
|
const char32_t *m_highpage;
|
||||||
|
Loading…
Reference in New Issue
Block a user