diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2009-12-03 10:22:45 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2009-12-03 10:22:45 +0200 |
commit | 99bb3eba4018f7e0c3e048fa439cc9d3bfb2d1d6 (patch) | |
tree | f5dbc826e31659b1931df52cc7734ffdb8a648bb /libxsd | |
parent | dbcf3be992bb7f1500e190e911065cc0ceea4875 (diff) |
Fail when trying to extract negative value to unsigned type
The standard iostream behavior requires such an extraction to succeed.
Because of that we weren't detecting some invalid value.
Diffstat (limited to 'libxsd')
-rw-r--r-- | libxsd/xsd/cxx/zc-istream.hxx | 125 |
1 files changed, 125 insertions, 0 deletions
diff --git a/libxsd/xsd/cxx/zc-istream.hxx b/libxsd/xsd/cxx/zc-istream.hxx index 2f0c1ed..c82d437 100644 --- a/libxsd/xsd/cxx/zc-istream.hxx +++ b/libxsd/xsd/cxx/zc-istream.hxx @@ -68,6 +68,8 @@ namespace xsd class zc_istream: protected zc_istream_base<C>, public std::basic_istream<C> { + typedef std::basic_istream<C> base; + public: zc_istream (const ro_string<C>&); zc_istream (const std::basic_string<C>&); @@ -78,6 +80,129 @@ namespace xsd return this->get () == std::basic_istream<C>::traits_type::eof (); } + zc_istream& + operator>> (unsigned char& x) + { + if (check_unsigned ()) + static_cast<base&> (*this) >> x; + + return *this; + } + + zc_istream& + operator>> (signed char& x) + { + if (check_signed ()) + static_cast<base&> (*this) >> x; + + return *this; + } + + zc_istream& + operator>> (unsigned short& x) + { + if (check_unsigned ()) + static_cast<base&> (*this) >> x; + + return *this; + } + + zc_istream& + operator>> (short& x) + { + if (check_signed ()) + static_cast<base&> (*this) >> x; + + return *this; + } + + zc_istream& + operator>> (unsigned int& x) + { + if (check_unsigned ()) + static_cast<base&> (*this) >> x; + + return *this; + } + + zc_istream& + operator>> (int& x) + { + if (check_signed ()) + static_cast<base&> (*this) >> x; + + return *this; + } + + zc_istream& + operator>> (unsigned long& x) + { + if (check_unsigned ()) + static_cast<base&> (*this) >> x; + + return *this; + } + + zc_istream& + operator>> (long& x) + { + if (check_signed ()) + static_cast<base&> (*this) >> x; + + return *this; + } + + zc_istream& + operator>> (unsigned long long& x) + { + if (check_unsigned ()) + static_cast<base&> (*this) >> x; + + return *this; + } + + zc_istream& + operator>> (long long& x) + { + if (check_signed ()) + static_cast<base&> (*this) >> x; + + return *this; + } + + template <typename X> + zc_istream& + operator>> (X& x) + { + static_cast<base&> (*this) >> x; + return *this; + } + + private: + bool + check_signed () + { + typename std::basic_istream<C>::traits_type::int_type p (this->peek ()); + bool r ((p >= C ('0') && p <= C ('9')) || p == C ('-') || p == C ('+')); + + if (!r) + this->setstate (std::ios_base::failbit); + + return r; + } + + bool + check_unsigned () + { + typename std::basic_istream<C>::traits_type::int_type p (this->peek ()); + bool r ((p >= C ('0') && p <= C ('9')) || p == C ('+')); + + if (!r) + this->setstate (std::ios_base::failbit); + + return r; + } + private: zc_istream (const zc_istream&); |