diff options
Diffstat (limited to 'libxsd/xsd/cxx/parser/validating/xml-schema-pimpl.txx')
-rw-r--r-- | libxsd/xsd/cxx/parser/validating/xml-schema-pimpl.txx | 2756 |
1 files changed, 0 insertions, 2756 deletions
diff --git a/libxsd/xsd/cxx/parser/validating/xml-schema-pimpl.txx b/libxsd/xsd/cxx/parser/validating/xml-schema-pimpl.txx deleted file mode 100644 index 5ef2455..0000000 --- a/libxsd/xsd/cxx/parser/validating/xml-schema-pimpl.txx +++ /dev/null @@ -1,2756 +0,0 @@ -// file : xsd/cxx/parser/validating/xml-schema-pimpl.txx -// license : GNU GPL v2 + exceptions; see accompanying LICENSE file - -#include <limits> -#include <locale> - -#ifdef XSD_CXX11 -# include <utility> // std::move -#endif - -#include <xsd/cxx/zc-istream.hxx> -#include <xsd/cxx/parser/validating/exceptions.hxx> - -namespace xsd -{ - namespace cxx - { - namespace parser - { - namespace validating - { - // Note that most of the types implemented here cannot have - // whitespaces in the value. As result we don't need to waste - // time collapsing whitespaces. All we need to do is trim the - // string representation which can be done without copying. - // - - // Character table. - // - namespace bits - { - const unsigned char ncname_mask = 0x1; - const unsigned char name_first_mask = 0x2; - const unsigned char name_mask = 0x4; - - template <typename C> - struct char_table - { - static C table[0x80]; - }; - - template <typename C> - C char_table<C>::table[0x80] = - { - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD8, 0xD0, 0x00, 0x00, 0xD0, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xD8, 0x48, 0x58, 0x48, 0x48, 0x48, 0x40, 0x58, 0x48, 0x48, 0x48, 0x48, 0x48, 0x4D, 0x4D, 0x58, - 0x4D, 0x4D, 0x4D, 0x4D, 0x4D, 0x4D, 0x4D, 0x4D, 0x4D, 0x4D, 0x4E, 0x48, 0x50, 0x48, 0x58, 0x48, - 0x48, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, - 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x48, 0x48, 0x40, 0x48, 0x4F, - 0x48, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, - 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x48, 0x48, 0x48, 0x48, 0x48 - }; - } - - // any_type - // - - template <typename C> - void any_type_pimpl<C>:: - post_any_type () - { - } - - // any_simple_type - // - - template <typename C> - void any_simple_type_pimpl<C>:: - post_any_simple_type () - { - } - - // boolean - // - - template <typename C> - void boolean_pimpl<C>:: - _pre () - { - str_.clear (); - } - - template <typename C> - void boolean_pimpl<C>:: - _characters (const ro_string<C>& s) - { - str_ += s; - } - - template <typename C> - void boolean_pimpl<C>:: - _post () - { - ro_string<C> str (str_); - trim (str); - - if (str == bits::true_<C> () || str == bits::one<C> ()) - value_ = true; - else if (str == bits::false_<C> () || str == bits::zero<C> ()) - value_ = false; - else - throw invalid_value<C> (bits::boolean<C> (), str); - } - - template <typename C> - bool boolean_pimpl<C>:: - post_boolean () - { - return value_; - } - - // byte - // - - template <typename C> - void byte_pimpl<C>:: - _pre () - { - str_.clear (); - } - - template <typename C> - void byte_pimpl<C>:: - _characters (const ro_string<C>& s) - { - str_ += s; - } - - template <typename C> - void byte_pimpl<C>:: - _post () - { - ro_string<C> str (str_); - trim (str); - - short t; - zc_istream<C> is (str); - - if (is >> t && is.exhausted () && t >= -128 && t <= 127) - value_ = static_cast<signed char> (t); - else - throw invalid_value<C> (bits::byte<C> (), str); - } - - template <typename C> - signed char byte_pimpl<C>:: - post_byte () - { - return value_; - } - - // unsigned_byte - // - - template <typename C> - void unsigned_byte_pimpl<C>:: - _pre () - { - str_.clear (); - } - - template <typename C> - void unsigned_byte_pimpl<C>:: - _characters (const ro_string<C>& s) - { - str_ += s; - } - - template <typename C> - void unsigned_byte_pimpl<C>:: - _post () - { - ro_string<C> str (str_); - trim (str); - - unsigned short t; - zc_istream<C> is (str); - - if (is >> t && is.exhausted () && t <= 255) - value_ = static_cast<unsigned char> (t); - else - throw invalid_value<C> (bits::unsigned_byte<C> (), str); - } - - template <typename C> - unsigned char unsigned_byte_pimpl<C>:: - post_unsigned_byte () - { - return value_; - } - - // short - // - - template <typename C> - void short_pimpl<C>:: - _pre () - { - str_.clear (); - } - - template <typename C> - void short_pimpl<C>:: - _characters (const ro_string<C>& s) - { - str_ += s; - } - - template <typename C> - void short_pimpl<C>:: - _post () - { - ro_string<C> str (str_); - trim (str); - - zc_istream<C> is (str); - - if (!(is >> value_ && is.exhausted ())) - throw invalid_value<C> (bits::short_<C> (), str); - } - - template <typename C> - short short_pimpl<C>:: - post_short () - { - return value_; - } - - - // unsigned_short - // - - template <typename C> - void unsigned_short_pimpl<C>:: - _pre () - { - str_.clear (); - } - - template <typename C> - void unsigned_short_pimpl<C>:: - _characters (const ro_string<C>& s) - { - str_ += s; - } - - template <typename C> - void unsigned_short_pimpl<C>:: - _post () - { - ro_string<C> str (str_); - trim (str); - - zc_istream<C> is (str); - - if (!(is >> value_ && is.exhausted ())) - throw invalid_value<C> (bits::unsigned_short<C> (), str); - } - - template <typename C> - unsigned short unsigned_short_pimpl<C>:: - post_unsigned_short () - { - return value_; - } - - // int - // - - template <typename C> - void int_pimpl<C>:: - _pre () - { - str_.clear (); - } - - template <typename C> - void int_pimpl<C>:: - _characters (const ro_string<C>& s) - { - str_ += s; - } - - template <typename C> - void int_pimpl<C>:: - _post () - { - ro_string<C> str (str_); - trim (str); - - zc_istream<C> is (str); - - if (!(is >> value_ && is.exhausted ())) - throw invalid_value<C> (bits::int_<C> (), str); - } - - template <typename C> - int int_pimpl<C>:: - post_int () - { - return value_; - } - - - // unsigned_int - // - - template <typename C> - void unsigned_int_pimpl<C>:: - _pre () - { - str_.clear (); - } - - template <typename C> - void unsigned_int_pimpl<C>:: - _characters (const ro_string<C>& s) - { - str_ += s; - } - - template <typename C> - void unsigned_int_pimpl<C>:: - _post () - { - ro_string<C> str (str_); - trim (str); - - zc_istream<C> is (str); - - if (!(is >> value_ && is.exhausted ())) - throw invalid_value<C> (bits::unsigned_int<C> (), str); - } - - template <typename C> - unsigned int unsigned_int_pimpl<C>:: - post_unsigned_int () - { - return value_; - } - - - // long - // - template <typename C> - void long_pimpl<C>:: - _pre () - { - str_.clear (); - } - - template <typename C> - void long_pimpl<C>:: - _characters (const ro_string<C>& s) - { - str_ += s; - } - - template <typename C> - void long_pimpl<C>:: - _post () - { - ro_string<C> str (str_); - trim (str); - - zc_istream<C> is (str); - - if (!(is >> value_ && is.exhausted ())) - throw invalid_value<C> (bits::long_<C> (), str); - } - - template <typename C> - long long long_pimpl<C>:: - post_long () - { - return value_; - } - - // unsigned_long - // - template <typename C> - void unsigned_long_pimpl<C>:: - _pre () - { - str_.clear (); - } - - template <typename C> - void unsigned_long_pimpl<C>:: - _characters (const ro_string<C>& s) - { - str_ += s; - } - - template <typename C> - void unsigned_long_pimpl<C>:: - _post () - { - ro_string<C> str (str_); - trim (str); - - zc_istream<C> is (str); - - if (!(is >> value_ && is.exhausted ())) - throw invalid_value<C> (bits::unsigned_long<C> (), str); - } - - template <typename C> - unsigned long long unsigned_long_pimpl<C>:: - post_unsigned_long () - { - return value_; - } - - - // integer - // - template <typename C> - void integer_pimpl<C>:: - _pre () - { - str_.clear (); - } - - template <typename C> - void integer_pimpl<C>:: - _characters (const ro_string<C>& s) - { - str_ += s; - } - - template <typename C> - void integer_pimpl<C>:: - _post () - { - ro_string<C> str (str_); - trim (str); - - zc_istream<C> is (str); - - if (!(is >> value_ && is.exhausted ())) - throw invalid_value<C> (bits::integer<C> (), str); - } - - template <typename C> - long long integer_pimpl<C>:: - post_integer () - { - return value_; - } - - // negative_integer - // - template <typename C> - void negative_integer_pimpl<C>:: - _pre () - { - str_.clear (); - } - - template <typename C> - void negative_integer_pimpl<C>:: - _characters (const ro_string<C>& s) - { - str_ += s; - } - - template <typename C> - void negative_integer_pimpl<C>:: - _post () - { - ro_string<C> str (str_); - trim (str); - - zc_istream<C> is (str); - - if (!(is >> value_ && is.exhausted () && value_ < 0)) - throw invalid_value<C> (bits::negative_integer<C> (), str); - } - - template <typename C> - long long negative_integer_pimpl<C>:: - post_negative_integer () - { - return value_; - } - - - // non_positive_integer - // - template <typename C> - void non_positive_integer_pimpl<C>:: - _pre () - { - str_.clear (); - } - - template <typename C> - void non_positive_integer_pimpl<C>:: - _characters (const ro_string<C>& s) - { - str_ += s; - } - - template <typename C> - void non_positive_integer_pimpl<C>:: - _post () - { - ro_string<C> str (str_); - trim (str); - - zc_istream<C> is (str); - - if (!(is >> value_ && is.exhausted () && value_ <= 0)) - throw invalid_value<C> (bits::non_positive_integer<C> (), str); - } - - template <typename C> - long long non_positive_integer_pimpl<C>:: - post_non_positive_integer () - { - return value_; - } - - // positive_integer - // - template <typename C> - void positive_integer_pimpl<C>:: - _pre () - { - str_.clear (); - } - - template <typename C> - void positive_integer_pimpl<C>:: - _characters (const ro_string<C>& s) - { - str_ += s; - } - - template <typename C> - void positive_integer_pimpl<C>:: - _post () - { - ro_string<C> str (str_); - trim (str); - - zc_istream<C> is (str); - - if (!(is >> value_ && is.exhausted () && value_ > 0)) - throw invalid_value<C> (bits::positive_integer<C> (), str); - } - - template <typename C> - unsigned long long positive_integer_pimpl<C>:: - post_positive_integer () - { - return value_; - } - - - // non_negative_integer - // - template <typename C> - void non_negative_integer_pimpl<C>:: - _pre () - { - str_.clear (); - } - - template <typename C> - void non_negative_integer_pimpl<C>:: - _characters (const ro_string<C>& s) - { - str_ += s; - } - - template <typename C> - void non_negative_integer_pimpl<C>:: - _post () - { - ro_string<C> str (str_); - trim (str); - - zc_istream<C> is (str); - - if (!(is >> value_ && is.exhausted ())) - throw invalid_value<C> (bits::non_negative_integer<C> (), str); - } - - template <typename C> - unsigned long long non_negative_integer_pimpl<C>:: - post_non_negative_integer () - { - return value_; - } - - - // float - // - template <typename C> - void float_pimpl<C>:: - _pre () - { - str_.clear (); - } - - template <typename C> - void float_pimpl<C>:: - _characters (const ro_string<C>& s) - { - str_ += s; - } - - template <typename C> - void float_pimpl<C>:: - _post () - { - ro_string<C> str (str_); - trim (str); - - if (str == bits::positive_inf<C> ()) - value_ = std::numeric_limits<float>::infinity (); - else if (str == bits::negative_inf<C> ()) - value_ = -std::numeric_limits<float>::infinity (); - else if (str == bits::nan<C> ()) - value_ = std::numeric_limits<float>::quiet_NaN (); - else - { - zc_istream<C> is (str); - is.imbue (std::locale::classic ()); - - if (!(is >> value_ && is.exhausted ())) - throw invalid_value<C> (bits::float_<C> (), str); - } - } - - template <typename C> - float float_pimpl<C>:: - post_float () - { - return value_; - } - - - // double - // - template <typename C> - void double_pimpl<C>:: - _pre () - { - str_.clear (); - } - - template <typename C> - void double_pimpl<C>:: - _characters (const ro_string<C>& s) - { - str_ += s; - } - - template <typename C> - void double_pimpl<C>:: - _post () - { - ro_string<C> str (str_); - trim (str); - - if (str == bits::positive_inf<C> ()) - value_ = std::numeric_limits<double>::infinity (); - else if (str == bits::negative_inf<C> ()) - value_ = -std::numeric_limits<double>::infinity (); - else if (str == bits::nan<C> ()) - value_ = std::numeric_limits<double>::quiet_NaN (); - else - { - zc_istream<C> is (str); - is.imbue (std::locale::classic ()); - - if (!(is >> value_ && is.exhausted ())) - throw invalid_value<C> (bits::double_<C> (), str); - } - } - - template <typename C> - double double_pimpl<C>:: - post_double () - { - return value_; - } - - // decimal - // - template <typename C> - void decimal_pimpl<C>:: - _pre () - { - str_.clear (); - } - - template <typename C> - void decimal_pimpl<C>:: - _characters (const ro_string<C>& s) - { - str_ += s; - } - - template <typename C> - void decimal_pimpl<C>:: - _post () - { - ro_string<C> str (str_); - trim (str); - - zc_istream<C> is (str); - is.imbue (std::locale::classic ()); - - //@@ TODO: now we accept scientific notations and INF/NaN. - // - if (!(is >> value_ && is.exhausted ())) - throw invalid_value<C> (bits::decimal<C> (), str); - } - - template <typename C> - double decimal_pimpl<C>:: - post_decimal () - { - return value_; - } - - // string - // - template <typename C> - void string_pimpl<C>:: - _pre () - { - str_.clear (); - } - - template <typename C> - void string_pimpl<C>:: - _characters (const ro_string<C>& s) - { - str_ += s; - } - - template <typename C> - std::basic_string<C> string_pimpl<C>:: - post_string () - { - std::basic_string<C> r; - r.swap (str_); - return r; - } - - // normalized_string - // - template <typename C> - void normalized_string_pimpl<C>:: - _pre () - { - str_.clear (); - } - - template <typename C> - void normalized_string_pimpl<C>:: - _characters (const ro_string<C>& s) - { - str_ += s; - } - - template <typename C> - std::basic_string<C> normalized_string_pimpl<C>:: - post_normalized_string () - { - typedef typename std::basic_string<C>::size_type size_type; - - size_type size (str_.size ()); - - for (size_type i (0); i < size; ++i) - { - C& c = str_[i]; - - if (c == C (0x0A) || c == C (0x0D) || c == C (0x09)) - c = C (0x20); - } - - std::basic_string<C> r; - r.swap (str_); - return r; - } - - // token - // - template <typename C> - void token_pimpl<C>:: - _pre () - { - str_.clear (); - } - - template <typename C> - void token_pimpl<C>:: - _characters (const ro_string<C>& s) - { - if (str_.size () == 0) - { - ro_string<C> tmp (s.data (), s.size ()); - - if (trim_left (tmp) != 0) - str_ += tmp; - } - else - str_ += s; - } - - template <typename C> - std::basic_string<C> token_pimpl<C>:: - post_token () - { - typedef typename std::basic_string<C>::size_type size_type; - - size_type size (str_.size ()); - size_type j (0); - - bool subs (false); - - for (size_type i (0); i < size; ++i) - { - C c = str_[i]; - - if (c == C (0x20) || c == C (0x0A) || - c == C (0x0D) || c == C (0x09)) - { - subs = true; - } - else - { - if (subs) - { - subs = false; - str_[j++] = C (0x20); - } - - str_[j++] = c; - } - } - - str_.resize (j); - - std::basic_string<C> r; - r.swap (str_); - return r; - } - - // name - // - template <typename C> - void name_pimpl<C>:: - _pre () - { - str_.clear (); - } - - template <typename C> - void name_pimpl<C>:: - _characters (const ro_string<C>& s) - { - if (str_.size () == 0) - { - ro_string<C> tmp (s.data (), s.size ()); - - if (trim_left (tmp) != 0) - str_ += tmp; - } - else - str_ += s; - } - - template <typename C> - void name_pimpl<C>:: - _post () - { - typedef typename ro_string<C>::size_type size_type; - - ro_string<C> tmp (str_); - size_type size (trim_right (tmp)); - - // For now we are only checking the US-ASCII characters. - // - - bool ok (size != 0); - - if (ok) - { - unsigned int c (static_cast<unsigned int> (str_[0])); - - ok = c >= 0x80 || - (bits::char_table<unsigned char>::table[c] & - bits::name_first_mask); - - if (ok) - { - for (size_type i (1); i < size; ++i) - { - c = static_cast<unsigned int> (str_[i]); - - if (c < 0x80 && - !(bits::char_table<unsigned char>::table[c] & - bits::name_mask)) - { - ok = false; - break; - } - } - } - } - - if (!ok) - throw invalid_value<C> (bits::name<C> (), tmp); - - str_.resize (size); - } - - template <typename C> - std::basic_string<C> name_pimpl<C>:: - post_name () - { - std::basic_string<C> r; - r.swap (str_); - return r; - } - - // nmtoken - // - template <typename C> - void nmtoken_pimpl<C>:: - _pre () - { - str_.clear (); - } - - template <typename C> - void nmtoken_pimpl<C>:: - _characters (const ro_string<C>& s) - { - if (str_.size () == 0) - { - ro_string<C> tmp (s.data (), s.size ()); - - if (trim_left (tmp) != 0) - str_ += tmp; - } - else - str_ += s; - } - - template <typename C> - void nmtoken_pimpl<C>:: - _post () - { - typedef typename ro_string<C>::size_type size_type; - - ro_string<C> tmp (str_); - size_type size (trim_right (tmp)); - - // For now we are only checking the US-ASCII characters. - // - - bool ok (size != 0); - - if (ok) - { - for (size_type i (0); i < size; ++i) - { - unsigned int c (static_cast<unsigned int> (str_[i])); - - if (c < 0x80 && - !(bits::char_table<unsigned char>::table[c] & - bits::name_mask)) - { - ok = false; - break; - } - } - } - - if (!ok) - throw invalid_value<C> (bits::nmtoken<C> (), tmp); - - str_.resize (size); - } - - template <typename C> - std::basic_string<C> nmtoken_pimpl<C>:: - post_nmtoken () - { - std::basic_string<C> r; - r.swap (str_); - return r; - } - - // nmtokens - // - template <typename C> - void nmtokens_pimpl<C>:: - _pre () - { - nmtokens_pskel<C>::_pre (); - seq_.clear (); - } - - template <typename C> - void nmtokens_pimpl<C>:: - _post () - { - nmtokens_pskel<C>::_post (); - - // Should have at least one element. - // - if (seq_.size () < 1) - { - ro_string<C> tmp; - throw invalid_value<C> (bits::nmtokens<C> (), tmp); - } - } - - template <typename C> - string_sequence<C> nmtokens_pimpl<C>:: - post_nmtokens () - { - string_sequence<C> r; - r.swap (seq_); - return r; - } - - template <typename C> - void nmtokens_pimpl<C>:: - _xsd_parse_item (const ro_string<C>& s) - { - parser_.pre (); - parser_._pre (); - parser_._characters (s); - parser_._post (); - seq_.push_back (parser_.post_nmtoken ()); - } - - // ncname - // - namespace bits - { - template <typename C> - bool - valid_ncname (const C* s, typename ro_string<C>::size_type size) - { - typedef typename ro_string<C>::size_type size_type; - - // For now we are only checking the US-ASCII characters. - // - bool ok (size != 0); - - if (ok) - { - unsigned int c (static_cast<unsigned int> (s[0])); - - ok = c >= 0x80 || - ((bits::char_table<unsigned char>::table[c] & - bits::name_first_mask) && c != C (':')); - - if (ok) - { - for (size_type i (1); i < size; ++i) - { - c = static_cast<unsigned int> (s[i]); - - if (c < 0x80 && - !(bits::char_table<unsigned char>::table[c] & - bits::ncname_mask)) - { - ok = false; - break; - } - } - } - } - - return ok; - } - } - - template <typename C> - void ncname_pimpl<C>:: - _pre () - { - str_.clear (); - } - - template <typename C> - void ncname_pimpl<C>:: - _characters (const ro_string<C>& s) - { - if (str_.size () == 0) - { - ro_string<C> tmp (s.data (), s.size ()); - - if (trim_left (tmp) != 0) - str_ += tmp; - } - else - str_ += s; - } - - template <typename C> - void ncname_pimpl<C>:: - _post () - { - typedef typename ro_string<C>::size_type size_type; - - ro_string<C> tmp (str_); - size_type size (trim_right (tmp)); - - if (!bits::valid_ncname (tmp.data (), size)) - throw invalid_value<C> (bits::ncname<C> (), tmp); - - str_.resize (size); - } - - template <typename C> - std::basic_string<C> ncname_pimpl<C>:: - post_ncname () - { - std::basic_string<C> r; - r.swap (str_); - return r; - } - - // id - // - template <typename C> - void id_pimpl<C>:: - _pre () - { - str_.clear (); - } - - template <typename C> - void id_pimpl<C>:: - _characters (const ro_string<C>& s) - { - if (str_.size () == 0) - { - ro_string<C> tmp (s.data (), s.size ()); - - if (trim_left (tmp) != 0) - str_ += tmp; - } - else - str_ += s; - } - - template <typename C> - void id_pimpl<C>:: - _post () - { - typedef typename ro_string<C>::size_type size_type; - - ro_string<C> tmp (str_); - size_type size (trim_right (tmp)); - - if (!bits::valid_ncname (tmp.data (), size)) - throw invalid_value<C> (bits::id<C> (), tmp); - - str_.resize (size); - } - - template <typename C> - std::basic_string<C> id_pimpl<C>:: - post_id () - { - std::basic_string<C> r; - r.swap (str_); - return r; - } - - // idref - // - template <typename C> - void idref_pimpl<C>:: - _pre () - { - str_.clear (); - } - - template <typename C> - void idref_pimpl<C>:: - _characters (const ro_string<C>& s) - { - if (str_.size () == 0) - { - ro_string<C> tmp (s.data (), s.size ()); - - if (trim_left (tmp) != 0) - str_ += tmp; - } - else - str_ += s; - } - - template <typename C> - void idref_pimpl<C>:: - _post () - { - typedef typename ro_string<C>::size_type size_type; - - ro_string<C> tmp (str_); - size_type size (trim_right (tmp)); - - if (!bits::valid_ncname (tmp.data (), size)) - throw invalid_value<C> (bits::idref<C> (), tmp); - - str_.resize (size); - } - - template <typename C> - std::basic_string<C> idref_pimpl<C>:: - post_idref () - { - std::basic_string<C> r; - r.swap (str_); - return r; - } - - // idrefs - // - template <typename C> - void idrefs_pimpl<C>:: - _pre () - { - idrefs_pskel<C>::_pre (); - seq_.clear (); - } - - template <typename C> - void idrefs_pimpl<C>:: - _post () - { - idrefs_pskel<C>::_post (); - - // Should have at least one element. - // - if (seq_.size () < 1) - { - ro_string<C> tmp; - throw invalid_value<C> (bits::idrefs<C> (), tmp); - } - } - - template <typename C> - string_sequence<C> idrefs_pimpl<C>:: - post_idrefs () - { - string_sequence<C> r; - r.swap (seq_); - return r; - } - - template <typename C> - void idrefs_pimpl<C>:: - _xsd_parse_item (const ro_string<C>& s) - { - parser_.pre (); - parser_._pre (); - parser_._characters (s); - parser_._post (); - seq_.push_back (parser_.post_idref ()); - } - - // language - // - template <typename C> - void language_pimpl<C>:: - _pre () - { - str_.clear (); - } - - template <typename C> - void language_pimpl<C>:: - _characters (const ro_string<C>& s) - { - if (str_.size () == 0) - { - ro_string<C> tmp (s.data (), s.size ()); - - if (trim_left (tmp) != 0) - str_ += tmp; - } - else - str_ += s; - } - - template <typename C> - void language_pimpl<C>:: - _post () - { - typedef typename ro_string<C>::size_type size_type; - - ro_string<C> tmp (str_); - size_type size (trim_right (tmp)); - - // language := ALPHA{1,8} *(-(ALPHA | DIGIT){1,8}) - // - bool ok (true); - - for (size_type tag (0), i (0); ; ++tag) - { - size_type n (0); - - for (; i < size && n < 8; ++n, ++i) - { - C c (tmp[i]); - - if (!((c >= C ('a') && c <= C ('z')) || - (c >= C ('A') && c <= C ('Z')) || - (tag != 0 && c >= C ('0') && c <= C ('9')))) - break; - } - - if (n == 0) - { - ok = false; - break; - } - - if (i == size) - break; - - if (tmp[i++] != C ('-')) - { - ok = false; - break; - } - } - - if (!ok) - throw invalid_value<C> (bits::language<C> (), tmp); - - str_.resize (size); - } - - template <typename C> - std::basic_string<C> language_pimpl<C>:: - post_language () - { - std::basic_string<C> r; - r.swap (str_); - return r; - } - - // uri - // - template <typename C> - void uri_pimpl<C>:: - _pre () - { - str_.clear (); - } - - template <typename C> - void uri_pimpl<C>:: - _characters (const ro_string<C>& s) - { - if (str_.size () == 0) - { - ro_string<C> tmp (s.data (), s.size ()); - - if (trim_left (tmp) != 0) - str_ += tmp; - } - else - str_ += s; - } - - template <typename C> - std::basic_string<C> uri_pimpl<C>:: - post_uri () - { - // According to Datatypes 3.2.17 and RFC2396 pretty much anything - // can be a URI and conforming processors do not need to figure - // out and verify particular URI schemes. - // - ro_string<C> tmp (str_); - str_.resize (trim_right (tmp)); - - std::basic_string<C> r; - r.swap (str_); - return r; - } - - // qname - // - template <typename C> - void qname_pimpl<C>:: - _pre () - { - str_.clear (); - } - - template <typename C> - void qname_pimpl<C>:: - _characters (const ro_string<C>& s) - { - if (str_.size () == 0) - { - ro_string<C> tmp (s.data (), s.size ()); - - if (trim_left (tmp) != 0) - str_ += tmp; - } - else - str_ += s; - } - - template <typename C> - void qname_pimpl<C>:: - _post () - { - typedef typename ro_string<C>::size_type size_type; - - ro_string<C> tmp (str_); - size_type size (trim_right (tmp)); - size_type pos (tmp.find (C (':'))); - - const C* s (tmp.data ()); - - if (pos != ro_string<C>::npos) - { - if (!bits::valid_ncname (s, pos) || - !bits::valid_ncname (s + pos + 1, size - pos - 1)) - throw invalid_value<C> (bits::qname<C> (), tmp); - - prefix_.assign (s, pos); - name_.assign (s + pos + 1, size - pos - 1); - } - else - { - if (!bits::valid_ncname (s, size)) - throw invalid_value<C> (bits::qname<C> (), tmp); - - prefix_.clear (); - str_.resize (size); - name_.swap (str_); - } - } - - template <typename C> - qname<C> qname_pimpl<C>:: - post_qname () - { - return prefix_.empty () - ? qname<C> (name_) - : qname<C> (prefix_, name_); - } - - // base64_binary - // - template <typename C> - void base64_binary_pimpl<C>:: - _pre () - { - str_.clear (); - } - - template <typename C> - void base64_binary_pimpl<C>:: - _characters (const ro_string<C>& s) - { - if (str_.size () == 0) - { - ro_string<C> tmp (s.data (), s.size ()); - - if (trim_left (tmp) != 0) - str_ += tmp; - } - else - str_ += s; - } - - namespace bits - { - template <typename C> - inline unsigned char - base64_decode (C c) - { - unsigned char r (0xFF); - - if (c >= C('A') && c <= C ('Z')) - r = static_cast<unsigned char> (c - C ('A')); - else if (c >= C('a') && c <= C ('z')) - r = static_cast<unsigned char> (c - C ('a') + 26); - else if (c >= C('0') && c <= C ('9')) - r = static_cast<unsigned char> (c - C ('0') + 52); - else if (c == C ('+')) - r = 62; - else if (c == C ('/')) - r = 63; - - return r; - } - } - - template <typename C> - void base64_binary_pimpl<C>:: - _post () - { - typedef typename std::basic_string<C>::size_type size_type; - - size_type size (str_.size ()); - const C* src (str_.c_str ()); - - // Remove all whitespaces. - // - { - size_type j (0); - - bool subs (false); - - for (size_type i (0); i < size; ++i) - { - C c = str_[i]; - - if (c == C (0x20) || c == C (0x0A) || - c == C (0x0D) || c == C (0x09)) - { - subs = true; - } - else - { - if (subs) - subs = false; - - str_[j++] = c; - } - } - - size = j; - str_.resize (size); - } - - // Our length should be a multiple of four. - // - if (size == 0 || size % 4 != 0) - throw invalid_value<C> (bits::base64_binary<C> (), str_); - - size_type quad_count (size / 4); - size_type capacity (quad_count * 3 + 1); - - buf_.reset (new buffer (capacity, capacity)); - char* dst (buf_->data ()); - - size_type si (0), di (0); // Source and destination indexes. - - // Process all quads except the last one. - // - unsigned char b1, b2, b3, b4; - - for (size_type q (0); q < quad_count - 1; ++q) - { - b1 = bits::base64_decode (src[si++]); - b2 = bits::base64_decode (src[si++]); - b3 = bits::base64_decode (src[si++]); - b4 = bits::base64_decode (src[si++]); - - if (b1 == 0xFF || b2 == 0xFF || b3 == 0xFF || b4 == 0xFF) - throw invalid_value<C> (bits::base64_binary<C> (), str_); - - dst[di++] = (b1 << 2) | (b2 >> 4); - dst[di++] = (b2 << 4) | (b3 >> 2); - dst[di++] = (b3 << 6) | b4; - } - - // Process the last quad. The first two octets are always there. - // - b1 = bits::base64_decode (src[si++]); - b2 = bits::base64_decode (src[si++]); - - if (b1 == 0xFF || b2 == 0xFF) - throw invalid_value<C> (bits::base64_binary<C> (), str_); - - C e3 (src[si++]); - C e4 (src[si++]); - - if (e4 == C ('=')) - { - if (e3 == C ('=')) - { - // Two pads. Last 4 bits in b2 should be zero. - // - if ((b2 & 0x0F) != 0) - throw invalid_value<C> (bits::base64_binary<C> (), str_); - - dst[di++] = (b1 << 2) | (b2 >> 4); - } - else - { - // One pad. Last 2 bits in b3 should be zero. - // - b3 = bits::base64_decode (e3); - - if (b3 == 0xFF || (b3 & 0x03) != 0) - throw invalid_value<C> (bits::base64_binary<C> (), str_); - - dst[di++] = (b1 << 2) | (b2 >> 4); - dst[di++] = (b2 << 4) | (b3 >> 2); - } - } - else - { - // No pads. - // - b3 = bits::base64_decode (e3); - b4 = bits::base64_decode (e4); - - if (b3 == 0xFF || b4 == 0xFF) - throw invalid_value<C> (bits::base64_binary<C> (), str_); - - dst[di++] = (b1 << 2) | (b2 >> 4); - dst[di++] = (b2 << 4) | (b3 >> 2); - dst[di++] = (b3 << 6) | b4; - } - - // Set the real size. - // - buf_->size (di); - } - - template <typename C> - XSD_AUTO_PTR<buffer> base64_binary_pimpl<C>:: - post_base64_binary () - { -#ifdef XSD_CXX11 - return std::move (buf_); -#else - return buf_; -#endif - } - - // hex_binary - // - template <typename C> - void hex_binary_pimpl<C>:: - _pre () - { - str_.clear (); - } - - template <typename C> - void hex_binary_pimpl<C>:: - _characters (const ro_string<C>& s) - { - if (str_.size () == 0) - { - ro_string<C> tmp (s.data (), s.size ()); - - if (trim_left (tmp) != 0) - str_ += tmp; - } - else - str_ += s; - } - - namespace bits - { - template <typename C> - inline unsigned char - hex_decode (C c) - { - unsigned char r (0xFF); - - if (c >= C('0') && c <= C ('9')) - r = static_cast<unsigned char> (c - C ('0')); - else if (c >= C ('A') && c <= C ('F')) - r = static_cast<unsigned char> (10 + (c - C ('A'))); - else if (c >= C ('a') && c <= C ('f')) - r = static_cast<unsigned char> (10 + (c - C ('a'))); - - return r; - } - } - - template <typename C> - void hex_binary_pimpl<C>:: - _post () - { - typedef typename ro_string<C>::size_type size_type; - - ro_string<C> tmp (str_); - size_type size (trim_right (tmp)); - - if (size % 2 != 0) - throw invalid_value<C> (bits::hex_binary<C> (), tmp); - - buffer::size_t n (size / 2); - buf_.reset (new buffer (n)); - - if (n != 0) - { - const C* src (tmp.data ()); - char* dst (buf_->data ()); - buffer::size_t i (0); - - for (; i < n; ++i) - { - unsigned char h (bits::hex_decode (src[2 * i])); - unsigned char l (bits::hex_decode (src[2 * i + 1])); - - if (h == 0xFF || l == 0xFF) - break; - - dst[i] = (h << 4) | l; - } - - if (i != n) - throw invalid_value<C> (bits::hex_binary<C> (), tmp); - } - } - - template <typename C> - XSD_AUTO_PTR<buffer> hex_binary_pimpl<C>:: - post_hex_binary () - { -#ifdef XSD_CXX11 - return std::move (buf_); -#else - return buf_; -#endif - } - - // time_zone - // - namespace bits - { - // Datatypes 3.2.7.3. Return false if time zone is invalid. - // - template <typename C> - bool - parse_tz (const C* s, - typename std::basic_string<C>::size_type n, - short& h, short& m) - { - // time_zone := Z|(+|-)HH:MM - // - if (n == 0) - { - return false; - } - else if (s[0] == 'Z') - { - if (n != 1) - return false; - - h = 0; - m = 0; - } - else - { - if (n != 6 || (s[0] != '-' && s[0] != '+') || s[3] != ':') - return false; - - // Parse hours. - // - char d1 = s[1]; - char d2 = s[2]; - - if (d1 < '0' || d1 > '9' || d2 < '0' || d2 > '9') - return false; - - h = 10 * (d1 - '0') + (d2 - '0'); - - if (h > 14) - return false; - - // Parse minutes. - // - d1 = s[4]; - d2 = s[5]; - - if (d1 < '0' || d1 > '9' || d2 < '0' || d2 > '9') - return false; - - m = 10 * (d1 - '0') + (d2 - '0'); - - if (m > 59 || (h == 14 && m != 0)) - return false; - - if (s[0] == '-') - { - h = -h; - m = -m; - } - } - - return true; - } - } - - // gday - // - template <typename C> - void gday_pimpl<C>:: - _pre () - { - str_.clear (); - } - - template <typename C> - void gday_pimpl<C>:: - _characters (const ro_string<C>& s) - { - if (str_.size () == 0) - { - ro_string<C> tmp (s.data (), s.size ()); - - if (trim_left (tmp) != 0) - str_ += tmp; - } - else - str_ += s; - } - - template <typename C> - void gday_pimpl<C>:: - _post () - { - typedef typename ro_string<C>::size_type size_type; - - ro_string<C> tmp (str_); - size_type size (trim_right (tmp)); - const C* s (tmp.data ()); - - // gday := ---DD[Z|(+|-)HH:MM] - // - if (size < 5 || - s[0] != C ('-') || s[1] != C ('-') || s[2] != C ('-')) - throw invalid_value<C> (bits::gday<C> (), tmp); - - C d1 (s[3]), d2 (s[4]); - - if (d1 < '0' || d1 > '9' || d2 < '0' || d2 > '9') - throw invalid_value<C> (bits::gday<C> (), tmp); - - day_ = 10 * (d1 - '0') + (d2 - '0'); - - if (day_ < 1 || day_ > 31) - throw invalid_value<C> (bits::gday<C> (), tmp); - - if (size > 5) - { - if (!bits::parse_tz (s + 5, size - 5, zh_, zm_)) - throw invalid_value<C> (bits::gday<C> (), tmp); - - z_ = true; - } - else - z_ = false; - } - - template <typename C> - gday gday_pimpl<C>:: - post_gday () - { - return z_ ? gday (day_, zh_, zm_) : gday (day_); - } - - // gmonth - // - template <typename C> - void gmonth_pimpl<C>:: - _pre () - { - str_.clear (); - } - - template <typename C> - void gmonth_pimpl<C>:: - _characters (const ro_string<C>& s) - { - if (str_.size () == 0) - { - ro_string<C> tmp (s.data (), s.size ()); - - if (trim_left (tmp) != 0) - str_ += tmp; - } - else - str_ += s; - } - - template <typename C> - void gmonth_pimpl<C>:: - _post () - { - typedef typename ro_string<C>::size_type size_type; - - ro_string<C> tmp (str_); - size_type size (trim_right (tmp)); - const C* s (tmp.data ()); - - // gmonth := --MM[Z|(+|-)HH:MM] - // - if (size < 4 || s[0] != C ('-') || s[1] != C ('-')) - throw invalid_value<C> (bits::gmonth<C> (), tmp); - - C d1 (s[2]), d2 (s[3]); - - if (d1 < '0' || d1 > '9' || d2 < '0' || d2 > '9') - throw invalid_value<C> (bits::gmonth<C> (), tmp); - - month_ = 10 * (d1 - '0') + (d2 - '0'); - - if (month_ < 1 || month_ > 12) - throw invalid_value<C> (bits::gmonth<C> (), tmp); - - if (size > 4) - { - if (!bits::parse_tz (s + 4, size - 4, zh_, zm_)) - throw invalid_value<C> (bits::gmonth<C> (), tmp); - - z_ = true; - } - else - z_ = false; - } - - template <typename C> - gmonth gmonth_pimpl<C>:: - post_gmonth () - { - return z_ ? gmonth (month_, zh_, zm_) : gmonth (month_); - } - - // gyear - // - template <typename C> - void gyear_pimpl<C>:: - _pre () - { - str_.clear (); - } - - template <typename C> - void gyear_pimpl<C>:: - _characters (const ro_string<C>& s) - { - if (str_.size () == 0) - { - ro_string<C> tmp (s.data (), s.size ()); - - if (trim_left (tmp) != 0) - str_ += tmp; - } - else - str_ += s; - } - - template <typename C> - void gyear_pimpl<C>:: - _post () - { - typedef typename ro_string<C>::size_type size_type; - - ro_string<C> tmp (str_); - size_type size (trim_right (tmp)); - const C* s (tmp.data ()); - - // gyear := [-]CCYY[N]*[Z|(+|-)HH:MM] - // - - if (size < 4 || (s[0] == C ('-') && size < 5)) - throw invalid_value<C> (bits::gyear<C> (), tmp); - - // Find the end of the year token. - // - size_type pos (s[0] == C ('-') ? 5 : 4); - for (; pos < size; ++pos) - { - C c (s[pos]); - - if (c == C ('Z') || c == C ('+') || c == C ('-')) - break; - } - - ro_string<C> year_fragment (s, pos); - zc_istream<C> is (year_fragment); - - if (!(is >> year_ && is.exhausted () && year_ != 0)) - throw invalid_value<C> (bits::gyear<C> (), tmp); - - if (pos < size) - { - if (!bits::parse_tz (s + pos, size - pos, zh_, zm_)) - throw invalid_value<C> (bits::gyear<C> (), tmp); - - z_ = true; - } - else - z_ = false; - } - - template <typename C> - gyear gyear_pimpl<C>:: - post_gyear () - { - return z_ ? gyear (year_, zh_, zm_) : gyear (year_); - } - - // gmonth_day - // - template <typename C> - void gmonth_day_pimpl<C>:: - _pre () - { - str_.clear (); - } - - template <typename C> - void gmonth_day_pimpl<C>:: - _characters (const ro_string<C>& s) - { - if (str_.size () == 0) - { - ro_string<C> tmp (s.data (), s.size ()); - - if (trim_left (tmp) != 0) - str_ += tmp; - } - else - str_ += s; - } - - template <typename C> - void gmonth_day_pimpl<C>:: - _post () - { - typedef typename ro_string<C>::size_type size_type; - - ro_string<C> tmp (str_); - size_type size (trim_right (tmp)); - const C* s (tmp.data ()); - - // gmonth_day := --MM-DD[Z|(+|-)HH:MM] - // - if (size < 7 || - s[0] != C ('-') || s[1] != C ('-') || s[4] != C ('-')) - throw invalid_value<C> (bits::gmonth_day<C> (), tmp); - - // month - // - C d1 (s[2]), d2 (s[3]); - - if (d1 < '0' || d1 > '9' || d2 < '0' || d2 > '9') - throw invalid_value<C> (bits::gmonth_day<C> (), tmp); - - month_ = 10 * (d1 - '0') + (d2 - '0'); - - if (month_ < 1 || month_ > 12) - throw invalid_value<C> (bits::gmonth_day<C> (), tmp); - - // day - // - d1 = s[5]; - d2 = s[6]; - - if (d1 < '0' || d1 > '9' || d2 < '0' || d2 > '9') - throw invalid_value<C> (bits::gmonth_day<C> (), tmp); - - day_ = 10 * (d1 - '0') + (d2 - '0'); - - if (day_ < 1 || day_ > 31) - throw invalid_value<C> (bits::gmonth_day<C> (), tmp); - - // zone - // - if (size > 7) - { - if (!bits::parse_tz (s + 7, size - 7, zh_, zm_)) - throw invalid_value<C> (bits::gmonth_day<C> (), tmp); - - z_ = true; - } - else - z_ = false; - } - - template <typename C> - gmonth_day gmonth_day_pimpl<C>:: - post_gmonth_day () - { - return z_ - ? gmonth_day (month_, day_, zh_, zm_) - : gmonth_day (month_, day_); - } - - // gyear_month - // - template <typename C> - void gyear_month_pimpl<C>:: - _pre () - { - str_.clear (); - } - - template <typename C> - void gyear_month_pimpl<C>:: - _characters (const ro_string<C>& s) - { - if (str_.size () == 0) - { - ro_string<C> tmp (s.data (), s.size ()); - - if (trim_left (tmp) != 0) - str_ += tmp; - } - else - str_ += s; - } - - template <typename C> - void gyear_month_pimpl<C>:: - _post () - { - typedef typename ro_string<C>::size_type size_type; - - ro_string<C> tmp (str_); - size_type size (trim_right (tmp)); - const C* s (tmp.data ()); - - // gyear_month := [-]CCYY[N]*-MM[Z|(+|-)HH:MM] - // - - if (size < 7 || (s[0] == C ('-') && size < 8)) - throw invalid_value<C> (bits::gyear_month<C> (), tmp); - - // Find the end of the year token. - // - size_type pos (tmp.find (C ('-'), s[0] == C ('-') ? 5 : 4)); - - if (pos == ro_string<C>::npos || (size - pos - 1) < 2) - throw invalid_value<C> (bits::gyear_month<C> (), tmp); - - ro_string<C> year_fragment (s, pos); - zc_istream<C> yis (year_fragment); - - if (!(yis >> year_ && yis.exhausted () && year_ != 0)) - throw invalid_value<C> (bits::gyear_month<C> (), tmp); - - // month - // - C d1 (s[pos + 1]), d2 (s[pos + 2]); - - if (d1 < '0' || d1 > '9' || d2 < '0' || d2 > '9') - throw invalid_value<C> (bits::gyear_month<C> (), tmp); - - month_ = 10 * (d1 - '0') + (d2 - '0'); - - if (month_ < 1 || month_ > 12) - throw invalid_value<C> (bits::gyear_month<C> (), tmp); - - // zone - // - pos += 3; - - if (pos < size) - { - if (!bits::parse_tz (s + pos, size - pos, zh_, zm_)) - throw invalid_value<C> (bits::gyear_month<C> (), tmp); - - z_ = true; - } - else - z_ = false; - } - - template <typename C> - gyear_month gyear_month_pimpl<C>:: - post_gyear_month () - { - return z_ - ? gyear_month (year_, month_, zh_, zm_) - : gyear_month (year_, month_); - } - - // date - // - template <typename C> - void date_pimpl<C>:: - _pre () - { - str_.clear (); - } - - template <typename C> - void date_pimpl<C>:: - _characters (const ro_string<C>& s) - { - if (str_.size () == 0) - { - ro_string<C> tmp (s.data (), s.size ()); - - if (trim_left (tmp) != 0) - str_ += tmp; - } - else - str_ += s; - } - - template <typename C> - void date_pimpl<C>:: - _post () - { - typedef typename ro_string<C>::size_type size_type; - - ro_string<C> tmp (str_); - size_type size (trim_right (tmp)); - const C* s (tmp.data ()); - - // date := [-]CCYY[N]*-MM-DD[Z|(+|-)HH:MM] - // - - if (size < 10 || (s[0] == C ('-') && size < 11)) - throw invalid_value<C> (bits::date<C> (), tmp); - - // Find the end of the year token. - // - size_type pos (tmp.find (C ('-'), s[0] == C ('-') ? 5 : 4)); - - if (pos == ro_string<C>::npos - || (size - pos - 1) < 5 - || s[pos + 3] != C ('-')) - throw invalid_value<C> (bits::date<C> (), tmp); - - ro_string<C> year_fragment (s, pos); - zc_istream<C> yis (year_fragment); - - if (!(yis >> year_ && yis.exhausted () && year_ != 0)) - throw invalid_value<C> (bits::date<C> (), tmp); - - // month - // - C d1 (s[pos + 1]), d2 (s[pos + 2]); - - if (d1 < '0' || d1 > '9' || d2 < '0' || d2 > '9') - throw invalid_value<C> (bits::date<C> (), tmp); - - month_ = 10 * (d1 - '0') + (d2 - '0'); - - if (month_ < 1 || month_ > 12) - throw invalid_value<C> (bits::date<C> (), tmp); - - // day - // - d1 = s[pos + 4]; - d2 = s[pos + 5]; - - if (d1 < '0' || d1 > '9' || d2 < '0' || d2 > '9') - throw invalid_value<C> (bits::date<C> (), tmp); - - day_ = 10 * (d1 - '0') + (d2 - '0'); - - if (day_ < 1 || day_ > 31) - throw invalid_value<C> (bits::date<C> (), tmp); - - // zone - // - pos += 6; - - if (pos < size) - { - if (!bits::parse_tz (s + pos, size - pos, zh_, zm_)) - throw invalid_value<C> (bits::date<C> (), tmp); - - z_ = true; - } - else - z_ = false; - } - - template <typename C> - date date_pimpl<C>:: - post_date () - { - return z_ - ? date (year_, month_, day_, zh_, zm_) - : date (year_, month_, day_); - } - - // time - // - template <typename C> - void time_pimpl<C>:: - _pre () - { - str_.clear (); - } - - template <typename C> - void time_pimpl<C>:: - _characters (const ro_string<C>& s) - { - if (str_.size () == 0) - { - ro_string<C> tmp (s.data (), s.size ()); - - if (trim_left (tmp) != 0) - str_ += tmp; - } - else - str_ += s; - } - - template <typename C> - void time_pimpl<C>:: - _post () - { - typedef typename ro_string<C>::size_type size_type; - - ro_string<C> tmp (str_); - size_type size (trim_right (tmp)); - const C* s (tmp.data ()); - - // time := HH:MM:SS[.S+][Z|(+|-)HH:MM] - // - - if (size < 8 || s[2] != C (':') || s[5] != C (':')) - throw invalid_value<C> (bits::time<C> (), tmp); - - // hours - // - C d1 (s[0]), d2 (s[1]); - - if (d1 < '0' || d1 > '9' || d2 < '0' || d2 > '9') - throw invalid_value<C> (bits::time<C> (), tmp); - - hours_ = 10 * (d1 - '0') + (d2 - '0'); - - if (hours_ > 24) - throw invalid_value<C> (bits::time<C> (), tmp); - - // minutes - // - d1 = s[3]; - d2 = s[4]; - - if (d1 < '0' || d1 > '9' || d2 < '0' || d2 > '9') - throw invalid_value<C> (bits::time<C> (), tmp); - - minutes_ = 10 * (d1 - '0') + (d2 - '0'); - - if (minutes_ > 59) - throw invalid_value<C> (bits::time<C> (), tmp); - - // Find the end of the seconds fragment. - // - size_type pos (8); - for (; pos < size; ++pos) - { - C c (s[pos]); - - if (c == C ('Z') || c == C ('+') || c == C ('-')) - break; - } - - // At least one digit should follow the fraction point. - // - if ((pos - 6) == 3) - throw invalid_value<C> (bits::time<C> (), tmp); - - ro_string<C> seconds_fragment (s + 6, pos - 6); - zc_istream<C> sis (seconds_fragment); - - if (!(sis >> seconds_ && sis.exhausted () && seconds_ < 60.0)) - throw invalid_value<C> (bits::time<C> (), tmp); - - if (hours_ == 24 && (minutes_ != 0 || seconds_ != 0.0)) - throw invalid_value<C> (bits::time<C> (), tmp); - - // zone - // - if (pos < size) - { - if (!bits::parse_tz (s + pos, size - pos, zh_, zm_)) - throw invalid_value<C> (bits::time<C> (), tmp); - - z_ = true; - } - else - z_ = false; - } - - template <typename C> - time time_pimpl<C>:: - post_time () - { - return z_ - ? time (hours_, minutes_, seconds_, zh_, zm_) - : time (hours_, minutes_, seconds_); - } - - - // date_time - // - template <typename C> - void date_time_pimpl<C>:: - _pre () - { - str_.clear (); - } - - template <typename C> - void date_time_pimpl<C>:: - _characters (const ro_string<C>& s) - { - if (str_.size () == 0) - { - ro_string<C> tmp (s.data (), s.size ()); - - if (trim_left (tmp) != 0) - str_ += tmp; - } - else - str_ += s; - } - - template <typename C> - void date_time_pimpl<C>:: - _post () - { - typedef typename ro_string<C>::size_type size_type; - - ro_string<C> tmp (str_); - size_type size (trim_right (tmp)); - const C* s (tmp.data ()); - - // date_time := [-]CCYY[N]*-MM-DDTHH:MM:SS[.S+][Z|(+|-)HH:MM] - // - - if (size < 19 || (s[0] == C ('-') && size < 20)) - throw invalid_value<C> (bits::date_time<C> (), tmp); - - // Find the end of the year token. - // - size_type pos (tmp.find (C ('-'), s[0] == C ('-') ? 5 : 4)); - - if (pos == ro_string<C>::npos || (size - pos - 1) < 14 - || s[pos + 3] != C ('-') || s[pos + 6] != C ('T') - || s[pos + 9] != C (':') || s[pos + 12] != C (':')) - throw invalid_value<C> (bits::date_time<C> (), tmp); - - // year - // - ro_string<C> year_fragment (s, pos); - zc_istream<C> yis (year_fragment); - - if (!(yis >> year_ && yis.exhausted () && year_ != 0)) - throw invalid_value<C> (bits::date_time<C> (), tmp); - - // month - // - C d1 (s[pos + 1]), d2 (s[pos + 2]); - - if (d1 < '0' || d1 > '9' || d2 < '0' || d2 > '9') - throw invalid_value<C> (bits::date_time<C> (), tmp); - - month_ = 10 * (d1 - '0') + (d2 - '0'); - - if (month_ < 1 || month_ > 12) - throw invalid_value<C> (bits::date_time<C> (), tmp); - - // day - // - d1 = s[pos + 4]; - d2 = s[pos + 5]; - - if (d1 < '0' || d1 > '9' || d2 < '0' || d2 > '9') - throw invalid_value<C> (bits::date_time<C> (), tmp); - - day_ = 10 * (d1 - '0') + (d2 - '0'); - - if (day_ < 1 || day_ > 31) - throw invalid_value<C> (bits::date_time<C> (), tmp); - - pos += 7; // Point to the first H. - - // hours - // - d1 = s[pos]; - d2 = s[pos + 1]; - - if (d1 < '0' || d1 > '9' || d2 < '0' || d2 > '9') - throw invalid_value<C> (bits::date_time<C> (), tmp); - - hours_ = 10 * (d1 - '0') + (d2 - '0'); - - if (hours_ > 24) - throw invalid_value<C> (bits::date_time<C> (), tmp); - - // minutes - // - d1 = s[pos + 3]; - d2 = s[pos + 4]; - - if (d1 < '0' || d1 > '9' || d2 < '0' || d2 > '9') - throw invalid_value<C> (bits::date_time<C> (), tmp); - - minutes_ = 10 * (d1 - '0') + (d2 - '0'); - - if (minutes_ > 59) - throw invalid_value<C> (bits::date_time<C> (), tmp); - - // Find the end of the seconds fragment. - // - pos += 6; // Point to the first S. - - size_type sec_end (pos + 2); - for (; sec_end < size; ++sec_end) - { - C c (s[sec_end]); - - if (c == C ('Z') || c == C ('+') || c == C ('-')) - break; - } - - // At least one digit should should follow the fraction point. - // - if ((sec_end - pos) == 3) - throw invalid_value<C> (bits::date_time<C> (), tmp); - - ro_string<C> seconds_fragment (s + pos, sec_end - pos); - zc_istream<C> sis (seconds_fragment); - - if (!(sis >> seconds_ && sis.exhausted () && seconds_ < 60.0)) - throw invalid_value<C> (bits::date_time<C> (), tmp); - - if (hours_ == 24 && (minutes_ != 0 || seconds_ != 0.0)) - throw invalid_value<C> (bits::date_time<C> (), tmp); - - // zone - // - if (sec_end < size) - { - if (!bits::parse_tz (s + sec_end, size - sec_end, zh_, zm_)) - throw invalid_value<C> (bits::date_time<C> (), tmp); - - z_ = true; - } - else - z_ = false; - } - - template <typename C> - date_time date_time_pimpl<C>:: - post_date_time () - { - return z_ - ? date_time (year_, month_, day_, hours_, minutes_, seconds_, - zh_, zm_) - : date_time (year_, month_, day_, hours_, minutes_, seconds_); - } - - // duration - // - template <typename C> - void duration_pimpl<C>:: - _pre () - { - str_.clear (); - } - - template <typename C> - void duration_pimpl<C>:: - _characters (const ro_string<C>& s) - { - if (str_.size () == 0) - { - ro_string<C> tmp (s.data (), s.size ()); - - if (trim_left (tmp) != 0) - str_ += tmp; - } - else - str_ += s; - } - - namespace bits - { - template <typename C> - inline typename ro_string<C>::size_type - duration_delim (const C* s, - typename ro_string<C>::size_type pos, - typename ro_string<C>::size_type size) - { - const C* p (s + pos); - for (; p < (s + size); ++p) - { - if (*p == C ('Y') || *p == C ('D') || *p == C ('M') || - *p == C ('H') || *p == C ('M') || *p == C ('S') || - *p == C ('T')) - break; - } - - return p - s; - } - } - - template <typename C> - void duration_pimpl<C>:: - _post () - { - typedef typename ro_string<C>::size_type size_type; - - ro_string<C> tmp (str_); - size_type size (trim_right (tmp)); - - negative_ = false; - years_ = 0; - months_ = 0; - days_ = 0; - hours_ = 0; - minutes_ = 0; - seconds_ = 0.0; - - // duration := [-]P[nY][nM][nD][TnHnMn[.n+]S] - // - const C* s (tmp.data ()); - - if (size < 3 || (s[0] == C ('-') && size < 4)) - throw invalid_value<C> (bits::duration<C> (), tmp); - - size_type pos (0); - - if (s[0] == C ('-')) - { - negative_ = true; - pos++; - } - - if (s[pos++] != C ('P')) - throw invalid_value<C> (bits::duration<C> (), tmp); - - size_type del (bits::duration_delim (s, pos, size)); - - // Duration should contain at least one component. - // - if (del == size) - throw invalid_value<C> (bits::duration<C> (), tmp); - - if (s[del] == C ('Y')) - { - ro_string<C> fragment (s + pos, del - pos); - zc_istream<C> is (fragment); - - if (!(is >> years_ && is.exhausted ())) - throw invalid_value<C> (bits::duration<C> (), tmp); - - pos = del + 1; - del = bits::duration_delim (s, pos, size); - } - - if (del != size && s[del] == C ('M')) - { - ro_string<C> fragment (s + pos, del - pos); - zc_istream<C> is (fragment); - - if (!(is >> months_ && is.exhausted ())) - throw invalid_value<C> (bits::duration<C> (), tmp); - - pos = del + 1; - del = bits::duration_delim (s, pos, size); - } - - if (del != size && s[del] == C ('D')) - { - ro_string<C> fragment (s + pos, del - pos); - zc_istream<C> is (fragment); - - if (!(is >> days_ && is.exhausted ())) - throw invalid_value<C> (bits::duration<C> (), tmp); - - pos = del + 1; - del = bits::duration_delim (s, pos, size); - } - - if (del != size && s[del] == C ('T')) - { - pos = del + 1; - del = bits::duration_delim (s, pos, size); - - // At least one time component should be present. - // - if (del == size) - throw invalid_value<C> (bits::duration<C> (), tmp); - - if (s[del] == C ('H')) - { - ro_string<C> fragment (s + pos, del - pos); - zc_istream<C> is (fragment); - - if (!(is >> hours_ && is.exhausted ())) - throw invalid_value<C> (bits::duration<C> (), tmp); - - pos = del + 1; - del = bits::duration_delim (s, pos, size); - } - - if (del != size && s[del] == C ('M')) - { - ro_string<C> fragment (s + pos, del - pos); - zc_istream<C> is (fragment); - - if (!(is >> minutes_ && is.exhausted ())) - throw invalid_value<C> (bits::duration<C> (), tmp); - - pos = del + 1; - del = bits::duration_delim (s, pos, size); - } - - if (del != size && s[del] == C ('S')) - { - ro_string<C> fragment (s + pos, del - pos); - zc_istream<C> is (fragment); - - if (!(is >> seconds_ && is.exhausted () && seconds_ >= 0.0)) - throw invalid_value<C> (bits::duration<C> (), tmp); - - pos = del + 1; - } - } - - // Something did not match or appeared in the wrong order. - // - if (pos != size) - throw invalid_value<C> (bits::duration<C> (), tmp); - } - - template <typename C> - duration duration_pimpl<C>:: - post_duration () - { - return duration ( - negative_, years_, months_, days_, hours_, minutes_, seconds_); - } - } - } - } -} |