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 | |
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.
-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&); |