From f0510d2f90467de8e8f260b47d79a9baaf9bef17 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Thu, 17 Sep 2009 07:15:29 +0200 Subject: Start tracking XSD with git --- .../cxx/parser/non-validating/xml-schema-pimpl.txx | 2068 ++++++++++++++++++++ 1 file changed, 2068 insertions(+) create mode 100644 libxsd/xsd/cxx/parser/non-validating/xml-schema-pimpl.txx (limited to 'libxsd/xsd/cxx/parser/non-validating/xml-schema-pimpl.txx') diff --git a/libxsd/xsd/cxx/parser/non-validating/xml-schema-pimpl.txx b/libxsd/xsd/cxx/parser/non-validating/xml-schema-pimpl.txx new file mode 100644 index 0000000..5ce50d6 --- /dev/null +++ b/libxsd/xsd/cxx/parser/non-validating/xml-schema-pimpl.txx @@ -0,0 +1,2068 @@ +// file : xsd/cxx/parser/non-validating/xml-schema-pimpl.txx +// author : Boris Kolpackov +// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#include +#include + +#include + +namespace xsd +{ + namespace cxx + { + namespace parser + { + namespace non_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. + // + + // any_type + // + + template + void any_type_pimpl:: + post_any_type () + { + } + + // any_simple_type + // + + template + void any_simple_type_pimpl:: + post_any_simple_type () + { + } + + // boolean + // + template + void boolean_pimpl:: + _pre () + { + str_.clear (); + } + + template + void boolean_pimpl:: + _characters (const ro_string& s) + { + str_ += s; + } + + template + bool boolean_pimpl:: + post_boolean () + { + std::basic_string tmp; + tmp.swap (str_); + + ro_string str (tmp); + trim (str); + + return str == bits::true_ () || str == bits::one (); + } + + // byte + // + + template + void byte_pimpl:: + _pre () + { + str_.clear (); + } + + template + void byte_pimpl:: + _characters (const ro_string& s) + { + str_ += s; + } + + template + signed char byte_pimpl:: + post_byte () + { + std::basic_string tmp; + tmp.swap (str_); + + ro_string str (tmp); + trim (str); + + short t; + zc_istream is (str); + is >> t; + + return static_cast (t); + } + + // unsigned_byte + // + + template + void unsigned_byte_pimpl:: + _pre () + { + str_.clear (); + } + + template + void unsigned_byte_pimpl:: + _characters (const ro_string& s) + { + str_ += s; + } + + template + unsigned char unsigned_byte_pimpl:: + post_unsigned_byte () + { + std::basic_string tmp; + tmp.swap (str_); + + ro_string str (tmp); + trim (str); + + unsigned short t; + zc_istream is (str); + is >> t; + + return static_cast (t); + } + + // short + // + + template + void short_pimpl:: + _pre () + { + str_.clear (); + } + + template + void short_pimpl:: + _characters (const ro_string& s) + { + str_ += s; + } + + template + short short_pimpl:: + post_short () + { + std::basic_string tmp; + tmp.swap (str_); + + ro_string str (tmp); + trim (str); + + short t; + zc_istream is (str); + is >> t; + + return t; + } + + // unsigned_short + // + + template + void unsigned_short_pimpl:: + _pre () + { + str_.clear (); + } + + template + void unsigned_short_pimpl:: + _characters (const ro_string& s) + { + str_ += s; + } + + template + unsigned short unsigned_short_pimpl:: + post_unsigned_short () + { + std::basic_string tmp; + tmp.swap (str_); + + ro_string str (tmp); + trim (str); + + unsigned short t; + zc_istream is (str); + is >> t; + + return t; + } + + // int + // + + template + void int_pimpl:: + _pre () + { + str_.clear (); + } + + template + void int_pimpl:: + _characters (const ro_string& s) + { + str_ += s; + } + + template + int int_pimpl:: + post_int () + { + std::basic_string tmp; + tmp.swap (str_); + + ro_string str (tmp); + trim (str); + + int t; + zc_istream is (str); + is >> t; + + return t; + } + + // unsigned_int + // + + template + void unsigned_int_pimpl:: + _pre () + { + str_.clear (); + } + + template + void unsigned_int_pimpl:: + _characters (const ro_string& s) + { + str_ += s; + } + + template + unsigned int unsigned_int_pimpl:: + post_unsigned_int () + { + std::basic_string tmp; + tmp.swap (str_); + + ro_string str (tmp); + trim (str); + + unsigned int t; + zc_istream is (str); + is >> t; + + return t; + } + + // long + // + template + void long_pimpl:: + _pre () + { + str_.clear (); + } + + template + void long_pimpl:: + _characters (const ro_string& s) + { + str_ += s; + } + + template + long long long_pimpl:: + post_long () + { + std::basic_string tmp; + tmp.swap (str_); + + ro_string str (tmp); + trim (str); + + long long t; + zc_istream is (str); + is >> t; + + return t; + } + + // unsigned_long + // + template + void unsigned_long_pimpl:: + _pre () + { + str_.clear (); + } + + template + void unsigned_long_pimpl:: + _characters (const ro_string& s) + { + str_ += s; + } + + template + unsigned long long unsigned_long_pimpl:: + post_unsigned_long () + { + std::basic_string tmp; + tmp.swap (str_); + + ro_string str (tmp); + trim (str); + + unsigned long long t; + zc_istream is (str); + is >> t; + + return t; + } + + // integer + // + template + void integer_pimpl:: + _pre () + { + str_.clear (); + } + + template + void integer_pimpl:: + _characters (const ro_string& s) + { + str_ += s; + } + + template + long long integer_pimpl:: + post_integer () + { + std::basic_string tmp; + tmp.swap (str_); + + ro_string str (tmp); + trim (str); + + long long t; + zc_istream is (str); + is >> t; + + return t; + } + + // negative_integer + // + template + void negative_integer_pimpl:: + _pre () + { + str_.clear (); + } + + template + void negative_integer_pimpl:: + _characters (const ro_string& s) + { + str_ += s; + } + + template + long long negative_integer_pimpl:: + post_negative_integer () + { + std::basic_string tmp; + tmp.swap (str_); + + ro_string str (tmp); + trim (str); + + long long t; + zc_istream is (str); + is >> t; + + return t; + } + + // non_positive_integer + // + template + void non_positive_integer_pimpl:: + _pre () + { + str_.clear (); + } + + template + void non_positive_integer_pimpl:: + _characters (const ro_string& s) + { + str_ += s; + } + + template + long long non_positive_integer_pimpl:: + post_non_positive_integer () + { + std::basic_string tmp; + tmp.swap (str_); + + ro_string str (tmp); + trim (str); + + long long t; + zc_istream is (str); + is >> t; + + return t; + } + + // positive_integer + // + template + void positive_integer_pimpl:: + _pre () + { + str_.clear (); + } + + template + void positive_integer_pimpl:: + _characters (const ro_string& s) + { + str_ += s; + } + + template + unsigned long long positive_integer_pimpl:: + post_positive_integer () + { + std::basic_string tmp; + tmp.swap (str_); + + ro_string str (tmp); + trim (str); + + unsigned long long t; + zc_istream is (str); + is >> t; + + return t; + } + + // non_negative_integer + // + template + void non_negative_integer_pimpl:: + _pre () + { + str_.clear (); + } + + template + void non_negative_integer_pimpl:: + _characters (const ro_string& s) + { + str_ += s; + } + + template + unsigned long long non_negative_integer_pimpl:: + post_non_negative_integer () + { + std::basic_string tmp; + tmp.swap (str_); + + ro_string str (tmp); + trim (str); + + unsigned long long t; + zc_istream is (str); + is >> t; + + return t; + } + + // float + // + template + void float_pimpl:: + _pre () + { + str_.clear (); + } + + template + void float_pimpl:: + _characters (const ro_string& s) + { + str_ += s; + } + + template + float float_pimpl:: + post_float () + { + std::basic_string tmp; + tmp.swap (str_); + + ro_string str (tmp); + trim (str); + + if (str == bits::positive_inf ()) + return std::numeric_limits::infinity (); + + if (str == bits::negative_inf ()) + return -std::numeric_limits::infinity (); + + if (str == bits::nan ()) + return std::numeric_limits::quiet_NaN (); + + float t; + zc_istream is (str); + is.imbue (std::locale::classic ()); + is >> t; + + return t; + } + + // double + // + template + void double_pimpl:: + _pre () + { + str_.clear (); + } + + template + void double_pimpl:: + _characters (const ro_string& s) + { + str_ += s; + } + + template + double double_pimpl:: + post_double () + { + std::basic_string tmp; + tmp.swap (str_); + + ro_string str (tmp); + trim (str); + + if (str == bits::positive_inf ()) + return std::numeric_limits::infinity (); + + if (str == bits::negative_inf ()) + return -std::numeric_limits::infinity (); + + if (str == bits::nan ()) + return std::numeric_limits::quiet_NaN (); + + double t; + zc_istream is (str); + is.imbue (std::locale::classic ()); + is >> t; + + return t; + } + + // decimal + // + template + void decimal_pimpl:: + _pre () + { + str_.clear (); + } + + template + void decimal_pimpl:: + _characters (const ro_string& s) + { + str_ += s; + } + + template + double decimal_pimpl:: + post_decimal () + { + std::basic_string tmp; + tmp.swap (str_); + + ro_string str (tmp); + trim (str); + + double t; + zc_istream is (str); + is.imbue (std::locale::classic ()); + is >> t; + + return t; + } + + + // string + // + template + void string_pimpl:: + _pre () + { + str_.clear (); + } + + template + void string_pimpl:: + _characters (const ro_string& s) + { + str_ += s; + } + + template + std::basic_string string_pimpl:: + post_string () + { + std::basic_string r; + r.swap (str_); + return r; + } + + // normalized_string + // + template + void normalized_string_pimpl:: + _pre () + { + str_.clear (); + } + + template + void normalized_string_pimpl:: + _characters (const ro_string& s) + { + str_ += s; + } + + template + std::basic_string normalized_string_pimpl:: + post_normalized_string () + { + typedef typename std::basic_string::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 r; + r.swap (str_); + return r; + } + + // token + // + template + void token_pimpl:: + _pre () + { + str_.clear (); + } + + template + void token_pimpl:: + _characters (const ro_string& s) + { + if (str_.size () == 0) + { + ro_string tmp (s.data (), s.size ()); + + if (trim_left (tmp) != 0) + str_ += tmp; + } + else + str_ += s; + } + + template + std::basic_string token_pimpl:: + post_token () + { + typedef typename std::basic_string::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 r; + r.swap (str_); + return r; + } + + // name + // + template + void name_pimpl:: + _pre () + { + str_.clear (); + } + + template + void name_pimpl:: + _characters (const ro_string& s) + { + if (str_.size () == 0) + { + ro_string tmp (s.data (), s.size ()); + + if (trim_left (tmp) != 0) + str_ += tmp; + } + else + str_ += s; + } + + template + std::basic_string name_pimpl:: + post_name () + { + ro_string tmp (str_); + str_.resize (trim_right (tmp)); + + std::basic_string r; + r.swap (str_); + return r; + } + + // nmtoken + // + template + void nmtoken_pimpl:: + _pre () + { + str_.clear (); + } + + template + void nmtoken_pimpl:: + _characters (const ro_string& s) + { + if (str_.size () == 0) + { + ro_string tmp (s.data (), s.size ()); + + if (trim_left (tmp) != 0) + str_ += tmp; + } + else + str_ += s; + } + + template + std::basic_string nmtoken_pimpl:: + post_nmtoken () + { + ro_string tmp (str_); + str_.resize (trim_right (tmp)); + + std::basic_string r; + r.swap (str_); + return r; + } + + // nmtokens + // + template + void nmtokens_pimpl:: + _pre () + { + nmtokens_pskel::_pre (); + seq_.clear (); + } + + template + string_sequence nmtokens_pimpl:: + post_nmtokens () + { + string_sequence r; + r.swap (seq_); + return r; + } + + template + void nmtokens_pimpl:: + _xsd_parse_item (const ro_string& s) + { + parser_.pre (); + parser_._pre (); + parser_._characters (s); + parser_._post (); + seq_.push_back (parser_.post_nmtoken ()); + } + + // ncname + // + template + void ncname_pimpl:: + _pre () + { + str_.clear (); + } + + template + void ncname_pimpl:: + _characters (const ro_string& s) + { + if (str_.size () == 0) + { + ro_string tmp (s.data (), s.size ()); + + if (trim_left (tmp) != 0) + str_ += tmp; + } + else + str_ += s; + } + + template + std::basic_string ncname_pimpl:: + post_ncname () + { + ro_string tmp (str_); + str_.resize (trim_right (tmp)); + + std::basic_string r; + r.swap (str_); + return r; + } + + // id + // + template + void id_pimpl:: + _pre () + { + str_.clear (); + } + + template + void id_pimpl:: + _characters (const ro_string& s) + { + if (str_.size () == 0) + { + ro_string tmp (s.data (), s.size ()); + + if (trim_left (tmp) != 0) + str_ += tmp; + } + else + str_ += s; + } + + template + std::basic_string id_pimpl:: + post_id () + { + ro_string tmp (str_); + str_.resize (trim_right (tmp)); + + std::basic_string r; + r.swap (str_); + return r; + } + + // idref + // + template + void idref_pimpl:: + _pre () + { + str_.clear (); + } + + template + void idref_pimpl:: + _characters (const ro_string& s) + { + if (str_.size () == 0) + { + ro_string tmp (s.data (), s.size ()); + + if (trim_left (tmp) != 0) + str_ += tmp; + } + else + str_ += s; + } + + template + std::basic_string idref_pimpl:: + post_idref () + { + ro_string tmp (str_); + str_.resize (trim_right (tmp)); + + std::basic_string r; + r.swap (str_); + return r; + } + + // idrefs + // + template + void idrefs_pimpl:: + _pre () + { + idrefs_pskel::_pre (); + seq_.clear (); + } + + template + string_sequence idrefs_pimpl:: + post_idrefs () + { + string_sequence r; + r.swap (seq_); + return r; + } + + template + void idrefs_pimpl:: + _xsd_parse_item (const ro_string& s) + { + parser_.pre (); + parser_._pre (); + parser_._characters (s); + parser_._post (); + seq_.push_back (parser_.post_idref ()); + } + + // language + // + template + void language_pimpl:: + _pre () + { + str_.clear (); + } + + template + void language_pimpl:: + _characters (const ro_string& s) + { + if (str_.size () == 0) + { + ro_string tmp (s.data (), s.size ()); + + if (trim_left (tmp) != 0) + str_ += tmp; + } + else + str_ += s; + } + + template + std::basic_string language_pimpl:: + post_language () + { + ro_string tmp (str_); + str_.resize (trim_right (tmp)); + + std::basic_string r; + r.swap (str_); + return r; + } + + // uri + // + template + void uri_pimpl:: + _pre () + { + str_.clear (); + } + + template + void uri_pimpl:: + _characters (const ro_string& s) + { + if (str_.size () == 0) + { + ro_string tmp (s.data (), s.size ()); + + if (trim_left (tmp) != 0) + str_ += tmp; + } + else + str_ += s; + } + + template + std::basic_string uri_pimpl:: + post_uri () + { + ro_string tmp (str_); + str_.resize (trim_right (tmp)); + + std::basic_string r; + r.swap (str_); + return r; + } + + // qname + // + template + void qname_pimpl:: + _pre () + { + str_.clear (); + } + + template + void qname_pimpl:: + _characters (const ro_string& s) + { + if (str_.size () == 0) + { + ro_string tmp (s.data (), s.size ()); + + if (trim_left (tmp) != 0) + str_ += tmp; + } + else + str_ += s; + } + + template + qname qname_pimpl:: + post_qname () + { + typedef typename ro_string::size_type size_type; + + ro_string tmp (str_); + size_type size (trim_right (tmp)); + size_type pos (tmp.find (C (':'))); + + if (pos != ro_string::npos) + { + std::basic_string prefix (tmp.data (), pos++); + std::basic_string name (tmp.data () + pos, size - pos); + return qname (prefix, name); + } + else + { + str_.resize (size); + return qname (str_); + } + } + + // base64_binary + // + template + void base64_binary_pimpl:: + _pre () + { + str_.clear (); + } + + template + void base64_binary_pimpl:: + _characters (const ro_string& s) + { + if (str_.size () == 0) + { + ro_string tmp (s.data (), s.size ()); + + if (trim_left (tmp) != 0) + str_ += tmp; + } + else + str_ += s; + } + + namespace bits + { + template + inline unsigned char + base64_decode (C c) + { + unsigned char r (0xFF); + + if (c >= C('A') && c <= C ('Z')) + r = static_cast (c - C ('A')); + else if (c >= C('a') && c <= C ('z')) + r = static_cast (c - C ('a') + 26); + else if (c >= C('0') && c <= C ('9')) + r = static_cast (c - C ('0') + 52); + else if (c == C ('+')) + r = 62; + else if (c == C ('/')) + r = 63; + + return r; + } + } + + template + std::auto_ptr base64_binary_pimpl:: + post_base64_binary () + { + typedef typename std::basic_string::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. + // + size_type quad_count (size / 4); + size_type capacity (quad_count * 3 + 1); + + std::auto_ptr buf (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++]); + + 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++]); + + C e3 (src[si++]); + C e4 (src[si++]); + + if (e4 == C ('=')) + { + if (e3 == C ('=')) + { + // Two pads. Last 4 bits in b2 should be zero. + // + dst[di++] = (b1 << 2) | (b2 >> 4); + } + else + { + // One pad. Last 2 bits in b3 should be zero. + // + b3 = bits::base64_decode (e3); + + 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); + + dst[di++] = (b1 << 2) | (b2 >> 4); + dst[di++] = (b2 << 4) | (b3 >> 2); + dst[di++] = (b3 << 6) | b4; + } + + // Set the real size. + // + buf->size (di); + + return buf; + } + + // hex_binary + // + template + void hex_binary_pimpl:: + _pre () + { + str_.clear (); + } + + template + void hex_binary_pimpl:: + _characters (const ro_string& s) + { + if (str_.size () == 0) + { + ro_string tmp (s.data (), s.size ()); + + if (trim_left (tmp) != 0) + str_ += tmp; + } + else + str_ += s; + } + + namespace bits + { + template + inline unsigned char + hex_decode (C c) + { + unsigned char r (0xFF); + + if (c >= C('0') && c <= C ('9')) + r = static_cast (c - C ('0')); + else if (c >= C ('A') && c <= C ('F')) + r = static_cast (10 + (c - C ('A'))); + else if (c >= C ('a') && c <= C ('f')) + r = static_cast (10 + (c - C ('a'))); + + return r; + } + } + + template + std::auto_ptr hex_binary_pimpl:: + post_hex_binary () + { + typedef typename ro_string::size_type size_type; + + ro_string tmp (str_); + size_type size (trim_right (tmp)); + + buffer::size_t n (size / 2); + std::auto_ptr buf (new buffer (n)); + + const C* src (tmp.data ()); + char* dst (buf->data ()); + + for (buffer::size_t i (0); i < n; ++i) + { + unsigned char h (bits::hex_decode (src[2 * i])); + unsigned char l (bits::hex_decode (src[2 * i + 1])); + dst[i] = (h << 4) | l; + } + + return buf; + } + + // time_zone + // + namespace bits + { + // Datatypes 3.2.7.3. + // + template + void + parse_tz (const C* s, + typename std::basic_string::size_type n, + short& h, short& m) + { + // time_zone := Z|(+|-)HH:MM + // + if (n == 0) + { + return; + } + else if (s[0] == 'Z') + { + h = 0; + m = 0; + } + else if (n == 6) + { + // Parse hours. + // + h = 10 * (s[1] - '0') + (s[2] - '0'); + + // Parse minutes. + // + m = 10 * (s[4] - '0') + (s[5] - '0'); + + if (s[0] == '-') + { + h = -h; + m = -m; + } + } + } + } + + // gday + // + template + void gday_pimpl:: + _pre () + { + str_.clear (); + } + + template + void gday_pimpl:: + _characters (const ro_string& s) + { + if (str_.size () == 0) + { + ro_string tmp (s.data (), s.size ()); + + if (trim_left (tmp) != 0) + str_ += tmp; + } + else + str_ += s; + } + + template + gday gday_pimpl:: + post_gday () + { + typedef typename ro_string::size_type size_type; + + ro_string tmp (str_); + size_type size (trim_right (tmp)); + const C* s (tmp.data ()); + + unsigned short day (0); + bool z (false); + short zh (0), zm (0); + + // gday := ---DD[Z|(+|-)HH:MM] + // + if (size >= 5) + { + day = 10 * (s[3] - '0') + (s[4] - '0'); + + if (size > 5) + { + bits::parse_tz (s + 5, size - 5, zh, zm); + z = true; + } + } + + return z ? gday (day, zh, zm) : gday (day); + } + + // gmonth + // + template + void gmonth_pimpl:: + _pre () + { + str_.clear (); + } + + template + void gmonth_pimpl:: + _characters (const ro_string& s) + { + if (str_.size () == 0) + { + ro_string tmp (s.data (), s.size ()); + + if (trim_left (tmp) != 0) + str_ += tmp; + } + else + str_ += s; + } + + template + gmonth gmonth_pimpl:: + post_gmonth () + { + typedef typename ro_string::size_type size_type; + + ro_string tmp (str_); + size_type size (trim_right (tmp)); + const C* s (tmp.data ()); + + unsigned short month (0); + bool z (false); + short zh (0), zm (0); + + // gmonth := --MM[Z|(+|-)HH:MM] + // + if (size >= 4) + { + month = 10 * (s[2] - '0') + (s[3] - '0'); + + if (size > 4) + { + bits::parse_tz (s + 4, size - 4, zh, zm); + z = true; + } + } + + return z ? gmonth (month, zh, zm) : gmonth (month); + } + + // gyear + // + template + void gyear_pimpl:: + _pre () + { + str_.clear (); + } + + template + void gyear_pimpl:: + _characters (const ro_string& s) + { + if (str_.size () == 0) + { + ro_string tmp (s.data (), s.size ()); + + if (trim_left (tmp) != 0) + str_ += tmp; + } + else + str_ += s; + } + + template + gyear gyear_pimpl:: + post_gyear () + { + typedef typename ro_string::size_type size_type; + + ro_string tmp (str_); + size_type size (trim_right (tmp)); + const C* s (tmp.data ()); + + int year (0); + bool z (false); + short zh (0), zm (0); + + // gyear := [-]CCYY[N]*[Z|(+|-)HH:MM] + // + + if (size >= 4) + { + // Find the end of the year token. + // + size_type pos (4); + for (; pos < size; ++pos) + { + C c (s[pos]); + + if (c == C ('Z') || c == C ('+') || c == C ('-')) + break; + } + + ro_string year_fragment (s, pos); + zc_istream is (year_fragment); + is >> year; + + if (pos < size) + { + bits::parse_tz (s + pos, size - pos, zh, zm); + z = true; + } + } + + return z ? gyear (year, zh, zm) : gyear (year); + } + + // gmonth_day + // + template + void gmonth_day_pimpl:: + _pre () + { + str_.clear (); + } + + template + void gmonth_day_pimpl:: + _characters (const ro_string& s) + { + if (str_.size () == 0) + { + ro_string tmp (s.data (), s.size ()); + + if (trim_left (tmp) != 0) + str_ += tmp; + } + else + str_ += s; + } + + template + gmonth_day gmonth_day_pimpl:: + post_gmonth_day () + { + typedef typename ro_string::size_type size_type; + + ro_string tmp (str_); + size_type size (trim_right (tmp)); + const C* s (tmp.data ()); + + unsigned short month (0), day (0); + bool z (false); + short zh (0), zm (0); + + // gmonth_day := --MM-DD[Z|(+|-)HH:MM] + // + if (size >= 7) + { + month = 10 * (s[2] - '0') + (s[3] - '0'); + day = 10 * (s[5] - '0') + (s[6] - '0'); + + if (size > 7) + { + bits::parse_tz (s + 7, size - 7, zh, zm); + z = true; + } + } + + return z + ? gmonth_day (month, day, zh, zm) + : gmonth_day (month, day); + } + + // gyear_month + // + template + void gyear_month_pimpl:: + _pre () + { + str_.clear (); + } + + template + void gyear_month_pimpl:: + _characters (const ro_string& s) + { + if (str_.size () == 0) + { + ro_string tmp (s.data (), s.size ()); + + if (trim_left (tmp) != 0) + str_ += tmp; + } + else + str_ += s; + } + + template + gyear_month gyear_month_pimpl:: + post_gyear_month () + { + typedef typename ro_string::size_type size_type; + + ro_string tmp (str_); + size_type size (trim_right (tmp)); + const C* s (tmp.data ()); + + int year (0); + unsigned short month (0); + bool z (false); + short zh (0), zm (0); + + // gyear_month := [-]CCYY[N]*-MM[Z|(+|-)HH:MM] + // + + if (size >= 7) + { + // Find the end of the year token. + // + size_type pos (tmp.find (C ('-'), 4)); + + if (pos != ro_string::npos && (size - pos - 1) >= 2) + { + ro_string year_fragment (s, pos); + zc_istream yis (year_fragment); + yis >> year; + + month = 10 * (s[pos + 1] - '0') + (s[pos + 2] - '0'); + + pos += 3; + + if (pos < size) + { + bits::parse_tz (s + pos, size - pos, zh, zm); + z = true; + } + } + } + + return z + ? gyear_month (year, month, zh, zm) + : gyear_month (year, month); + } + + // date + // + template + void date_pimpl:: + _pre () + { + str_.clear (); + } + + template + void date_pimpl:: + _characters (const ro_string& s) + { + if (str_.size () == 0) + { + ro_string tmp (s.data (), s.size ()); + + if (trim_left (tmp) != 0) + str_ += tmp; + } + else + str_ += s; + } + + template + date date_pimpl:: + post_date () + { + typedef typename ro_string::size_type size_type; + + ro_string tmp (str_); + size_type size (trim_right (tmp)); + const C* s (tmp.data ()); + + int year (0); + unsigned short month (0), day (0); + bool z (false); + short zh (0), zm (0); + + // date := [-]CCYY[N]*-MM-DD[Z|(+|-)HH:MM] + // + + if (size >= 10) + { + // Find the end of the year token. + // + size_type pos (tmp.find (C ('-'), 4)); + + if (pos != ro_string::npos && (size - pos - 1) >= 5) + { + ro_string year_fragment (s, pos); + zc_istream yis (year_fragment); + yis >> year; + + month = 10 * (s[pos + 1] - '0') + (s[pos + 2] - '0'); + day = 10 * (s[pos + 4] - '0') + (s[pos + 5] - '0'); + + pos += 6; + + if (pos < size) + { + bits::parse_tz (s + pos, size - pos, zh, zm); + z = true; + } + } + } + + return z + ? date (year, month, day, zh, zm) + : date (year, month, day); + } + + // time + // + template + void time_pimpl:: + _pre () + { + str_.clear (); + } + + template + void time_pimpl:: + _characters (const ro_string& s) + { + if (str_.size () == 0) + { + ro_string tmp (s.data (), s.size ()); + + if (trim_left (tmp) != 0) + str_ += tmp; + } + else + str_ += s; + } + + template + time time_pimpl:: + post_time () + { + typedef typename ro_string::size_type size_type; + + ro_string tmp (str_); + size_type size (trim_right (tmp)); + const C* s (tmp.data ()); + + unsigned short hours (0), minutes (0); + double seconds (0.0); + bool z (false); + short zh (0), zm (0); + + // time := HH:MM:SS[.S+][Z|(+|-)HH:MM] + // + + if (size >= 8) + { + hours = 10 * (s[0] - '0') + (s[1] - '0'); + minutes = 10 * (s[3] - '0') + (s[4] - '0'); + + // 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; + } + + ro_string seconds_fragment (s + 6, pos - 6); + zc_istream sis (seconds_fragment); + sis >> seconds; + + if (pos < size) + { + bits::parse_tz (s + pos, size - pos, zh, zm); + z = true; + } + } + + return z + ? time (hours, minutes, seconds, zh, zm) + : time (hours, minutes, seconds); + } + + + // date_time + // + template + void date_time_pimpl:: + _pre () + { + str_.clear (); + } + + template + void date_time_pimpl:: + _characters (const ro_string& s) + { + if (str_.size () == 0) + { + ro_string tmp (s.data (), s.size ()); + + if (trim_left (tmp) != 0) + str_ += tmp; + } + else + str_ += s; + } + + template + date_time date_time_pimpl:: + post_date_time () + { + typedef typename ro_string::size_type size_type; + + ro_string tmp (str_); + size_type size (trim_right (tmp)); + const C* s (tmp.data ()); + + int year (0); + unsigned short month (0), day (0), hours (0), minutes (0); + double seconds (0.0); + bool z (false); + short zh (0), zm (0); + + // date_time := [-]CCYY[N]*-MM-DDTHH:MM:SS[.S+][Z|(+|-)HH:MM] + // + + if (size >= 19) + { + // Find the end of the year token. + // + size_type pos (tmp.find (C ('-'), 4)); + + if (pos != ro_string::npos && (size - pos - 1) >= 14) + { + ro_string year_fragment (s, pos); + zc_istream yis (year_fragment); + yis >> year; + + month = 10 * (s[pos + 1] - '0') + (s[pos + 2] - '0'); + day = 10 * (s[pos + 4] - '0') + (s[pos + 5] - '0'); + + pos += 7; // Point to the first H. + + hours = 10 * (s[pos] - '0') + (s[pos + 1] - '0'); + minutes = 10 * (s[pos + 3] - '0') + (s[pos + 4] - '0'); + + // 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; + } + + ro_string seconds_fragment (s + pos, sec_end - pos); + zc_istream sis (seconds_fragment); + sis >> seconds; + + if (sec_end < size) + { + bits::parse_tz (s + sec_end, size - sec_end, zh, zm); + z = true; + } + } + } + + return z + ? date_time (year, month, day, hours, minutes, seconds, zh, zm) + : date_time (year, month, day, hours, minutes, seconds); + } + + // duration + // + template + void duration_pimpl:: + _pre () + { + str_.clear (); + } + + template + void duration_pimpl:: + _characters (const ro_string& s) + { + if (str_.size () == 0) + { + ro_string tmp (s.data (), s.size ()); + + if (trim_left (tmp) != 0) + str_ += tmp; + } + else + str_ += s; + } + + namespace bits + { + template + inline typename ro_string::size_type + duration_delim (const C* s, + typename ro_string::size_type pos, + typename ro_string::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 + duration duration_pimpl:: + post_duration () + { + typedef typename ro_string::size_type size_type; + + ro_string tmp (str_); + size_type size (trim_right (tmp)); + + bool negative (false); + unsigned int years (0), months (0), days (0), hours (0), minutes (0); + double seconds (0.0); + + // duration := [-]P[nY][nM][nD][TnHnMn[.n+]S] + // + const C* s (tmp.data ()); + + if (size >= 3) + { + size_type pos (0); + + if (s[0] == C ('-')) + { + negative = true; + pos++; + } + + pos++; // Skip 'P'. + + size_type del (bits::duration_delim (s, pos, size)); + + if (del != size && s[del] == C ('Y')) + { + ro_string fragment (s + pos, del - pos); + zc_istream is (fragment); + is >> years; + + pos = del + 1; + del = bits::duration_delim (s, pos, size); + } + + if (del != size && s[del] == C ('M')) + { + ro_string fragment (s + pos, del - pos); + zc_istream is (fragment); + is >> months; + + pos = del + 1; + del = bits::duration_delim (s, pos, size); + } + + if (del != size && s[del] == C ('D')) + { + ro_string fragment (s + pos, del - pos); + zc_istream is (fragment); + is >> days; + + 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); + + if (del != size && s[del] == C ('H')) + { + ro_string fragment (s + pos, del - pos); + zc_istream is (fragment); + is >> hours; + + pos = del + 1; + del = bits::duration_delim (s, pos, size); + } + + if (del != size && s[del] == C ('M')) + { + ro_string fragment (s + pos, del - pos); + zc_istream is (fragment); + is >> minutes; + + pos = del + 1; + del = bits::duration_delim (s, pos, size); + } + + if (del != size && s[del] == C ('S')) + { + ro_string fragment (s + pos, del - pos); + zc_istream is (fragment); + is >> seconds; + } + } + } + + return duration ( + negative, years, months, days, hours, minutes, seconds); + } + } + } + } +} -- cgit v1.1