Add missing facets for extraction from an idocstream on platforms

lacking support for wchar_t. This solves bug 4076.


git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@19233 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Enrico Forestieri 2007-07-30 13:15:27 +00:00
parent 6b87509156
commit 128bb9ed49

View File

@ -560,19 +560,146 @@ public:
string_num_get_facet() : std::num_get<char, std::basic_string<char>::iterator>(1) {}
};
private:
bool isNumpunct(lyx::char_type const c) const
/// Numpunct facet defining the I/O format.
class numpunct_facet : public std::numpunct<char>
{
/// 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');
}
public:
numpunct_facet() : std::numpunct<char>(1) {}
};
protected:
iter_type
do_get(iter_type iit, iter_type eit, std::ios_base & b,
std::ios_base::iostate & err, bool & v) const
{
// This facet has been adapted from the STLPort library
if (b.flags() & std::ios_base::boolalpha) {
numpunct_facet p;
lyx::docstring const truename = from_local8bit(p.truename());
lyx::docstring const falsename = from_local8bit(p.falsename());
bool true_ok = true;
bool false_ok = true;
size_t n = 0;
for (; iit != eit; ++iit) {
lyx::char_type c = *iit;
true_ok = true_ok && (c == truename[n]);
false_ok = false_ok && (c == falsename[n]);
++n;
if ((!true_ok && !false_ok) ||
(true_ok && n >= truename.size()) ||
(false_ok && n >= falsename.size())) {
++iit;
break;
}
}
if (true_ok && n < truename.size())
true_ok = false;
if (false_ok && n < falsename.size())
false_ok = false;
if (true_ok || false_ok) {
err = std::ios_base::goodbit;
v = true_ok;
} else
err = std::ios_base::failbit;
if (iit == eit)
err |= std::ios_base::eofbit;
return iit;
} else {
long l;
iter_type end = this->do_get(iit, eit, b, err, l);
if (!(err & std::ios_base::failbit)) {
if (l == 0)
v = false;
else if (l == 1)
v = true;
else
err |= std::ios_base::failbit;
}
return end;
}
}
iter_type
do_get(iter_type iit, iter_type eit, std::ios_base & b,
std::ios_base::iostate & err, long & v) const
{
return do_get_integer(iit, eit, b, err, v);
}
iter_type
do_get(iter_type iit, iter_type eit, std::ios_base & b,
std::ios_base::iostate & err, unsigned short & v) const
{
return do_get_integer(iit, eit, b, err, v);
}
iter_type
do_get(iter_type iit, iter_type eit, std::ios_base & b,
std::ios_base::iostate & err, unsigned int & v) const
{
return do_get_integer(iit, eit, b, err, v);
}
iter_type
do_get(iter_type iit, iter_type eit, std::ios_base & b,
std::ios_base::iostate & err, unsigned long & v) const
{
return do_get_integer(iit, eit, b, err, v);
}
#ifdef _GLIBCXX_USE_LONG_LONG
iter_type
do_get(iter_type iit, iter_type eit, std::ios_base & b,
std::ios_base::iostate & err, long long & v) const
{
return do_get_integer(iit, eit, b, err, v);
}
iter_type
do_get(iter_type iit, iter_type eit, std::ios_base & b,
std::ios_base::iostate & err, unsigned long long & v) const
{
return do_get_integer(iit, eit, b, err, v);
}
#endif
iter_type
do_get(iter_type iit, iter_type eit, std::ios_base & b,
std::ios_base::iostate & err, float & v) const
{
return do_get_float(iit, eit, b, err, v);
}
iter_type
do_get(iter_type iit, iter_type eit, std::ios_base & b,
std::ios_base::iostate & err, double & v) const
{
return do_get_float(iit, eit, b, err, v);
}
iter_type
do_get(iter_type iit, iter_type eit, std::ios_base & b,
std::ios_base::iostate & err, long double & v) const
{
return do_get_float(iit, eit, b, err, v);
}
iter_type
do_get(iter_type iit, iter_type eit, std::ios_base & b,
std::ios_base::iostate & err, void * & v) const
{
unsigned long val;
iter_type end = do_get_integer(iit, eit, b, err, val);
if (!(err & std::ios_base::failbit))
v = reinterpret_cast<void *>(val);
return end;
}
private:
template <typename ValueType>
iter_type
do_get_integer(iter_type iit, iter_type eit, std::ios_base & b,
std::ios_base::iostate & err, ValueType & v) const
{
std::string s;
s.reserve(64);
@ -585,9 +712,65 @@ protected:
s += ' ';
string_num_get_facet f;
f.get(s.begin(), s.end(), b, err, v);
if (iit == eit)
err |= std::ios_base::eofbit;
return iit;
}
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');
}
template <typename ValueType>
iter_type
do_get_float(iter_type iit, iter_type eit, std::ios_base & b,
std::ios_base::iostate & err, ValueType & v) const
{
// Gather a string of the form
// [+-]? [0-9]* .? [0-9]* ([eE] [+-]? [0-9]+)?
std::string s;
s.reserve(64);
char c;
numpunct_facet p;
char const dot = p.decimal_point();
char const sep = p.thousands_sep();
// Get an optional sign
if (iit != eit && (*iit == '-' || *iit == '+')) {
s += static_cast<char>(*iit);
++iit;
}
for (; iit != eit && isDigitOrSep(*iit, sep); ++iit)
s += static_cast<char>(*iit);
if (iit != eit && *iit == dot) {
s += dot;
++iit;
for (; iit != eit && isDigitOrSep(*iit, 0); ++iit)
s += static_cast<char>(*iit);
if (iit != eit && (*iit == 'e' || *iit == 'E')) {
s += static_cast<char>(*iit);
++iit;
for (; iit != eit && isDigitOrSep(*iit, 0); ++iit)
s += static_cast<char>(*iit);
}
}
s += '\n';
string_num_get_facet f;
f.get(s.begin(), s.end(), b, err, v);
if (iit == eit)
err |= std::ios_base::eofbit;
return iit;
}
bool isDigitOrSep(lyx::char_type const c, char const sep) const
{
return (c >= '0' && c <= '9') || (c != 0 && c == sep);
}
};