summaryrefslogtreecommitdiff
path: root/libxsd/xsd/cxx
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2009-12-03 10:22:45 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2009-12-03 10:22:45 +0200
commit99bb3eba4018f7e0c3e048fa439cc9d3bfb2d1d6 (patch)
treef5dbc826e31659b1931df52cc7734ffdb8a648bb /libxsd/xsd/cxx
parentdbcf3be992bb7f1500e190e911065cc0ceea4875 (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/xsd/cxx')
-rw-r--r--libxsd/xsd/cxx/zc-istream.hxx125
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&);