void utf8_to_ucs4(std::string const & utf8, docstring & ucs4)
{
- // FIXME (Abdel 17/11/06): static data are evil!
- // This function cannot be used in the final exit process on Mac because
- // static data are already destroyed at this stage.
- // One solution would be to instantiate the utf8 to ucs4 IconvProcessor as a
- // singleton inside the LyX main class to ensure that it does not get
- // destroyed too early.
- static IconvProcessor iconv(ucs4_codeset, "UTF-8");
-
size_t n = utf8.size();
// as utf8 is a multi-byte encoding, there would be at most
// n characters:
// basic_string::data() is not recognized by some old gcc version
// so we use &(ucs4[0]) instead.
char * outbuf = (char *)(&(ucs4[0]));
- int bytes = iconv.convert(utf8.c_str(), n, outbuf, maxoutsize);
+ int bytes = utf8ToUcs4().convert(utf8.c_str(), n, outbuf, maxoutsize);
// adjust to the real converted size
ucs4.resize(bytes/4);
};
+/// Facet for inputting ascii representations of numbers from idocstreams.
+/// Here we simply need defining the virtual do_get functions.
+class ascii_num_get_facet : public std::num_get<lyx::char_type, std::istreambuf_iterator<lyx::char_type, std::char_traits<lyx::char_type> > >
+{
+ typedef std::istreambuf_iterator<lyx::char_type, std::char_traits<lyx::char_type> > iter_type;
+public:
+ ascii_num_get_facet(size_t refs = 0) : std::num_get<lyx::char_type, iter_type>(refs) {}
+
+ /// Facet for converting ascii representation of numbers to a value.
+ class string_num_get_facet : public std::num_get<char, std::basic_string<char>::iterator>
+ {
+ public:
+ string_num_get_facet() : std::num_get<char, std::basic_string<char>::iterator>(1) {}
+ };
+
+private:
+ bool isNumpunct(lyx::char_type const c) const
+ {
+ /// Only account for the standard numpunct "C" locale facet.
+ return c < 0x80 && (c == '-' || c == '+' || isdigit(c)
+ || ('a' <= c && c <= 'f') || ('A' <= c && c <= 'F')
+ || c == 'x' || c == 'X');
+ }
+
+protected:
+ iter_type
+ do_get(iter_type iit, iter_type eit, std::ios_base & b,
+ std::ios_base::iostate & err, long & v) const
+ {
+ std::string s;
+ s.reserve(64);
+ for (; iit != eit && isNumpunct(*iit); ++iit)
+ s += static_cast<char>(*iit);
+ // We add another character, not part of the numpunct facet,
+ // in order to avoid setting the eofbit in the stream state,
+ // which would prevent any further read. The space seems a
+ // good choice here.
+ s += ' ';
+ string_num_get_facet f;
+ f.get(s.begin(), s.end(), b, err, v);
+
+ return iit;
+ }
+};
+
+
/// class to add our facets to the global locale
class locale_initializer {
public:
std::locale global;
std::locale const loc1(global, new ascii_ctype_facet);
std::locale const loc2(loc1, new ascii_num_put_facet);
- std::locale::global(loc2);
+ std::locale const loc3(loc2, new ascii_num_get_facet);
+ std::locale::global(loc3);
}
};