// file : xsd/cxx/tree/parsing/date-time.txx // copyright : Copyright (c) 2005-2014 Code Synthesis Tools CC // license : GNU GPL v2 + exceptions; see accompanying LICENSE file #include #include #include // xml::transcode #include // text_content namespace xsd { namespace cxx { namespace tree { // time_zone // template void time_zone:: zone_parse (const C* s, std::size_t n) { // time_zone := Z|(+|-)HH:MM // if (n == 0) { return; } else if (s[0] == C ('Z')) { hours_ = 0; minutes_ = 0; present_ = true; } else if (n == 6) { // Parse hours. // hours_ = 10 * (s[1] - C ('0')) + (s[2] - C ('0')); // Parse minutes. // minutes_ = 10 * (s[4] - C ('0')) + (s[5] - C ('0')); if (s[0] == C ('-')) { hours_ = -hours_; minutes_ = -minutes_; } present_ = true; } } // gday // template gday:: gday (const xercesc::DOMElement& e, flags f, container* c) : B (e, f, c) { parse (text_content (e)); } template gday:: gday (const xercesc::DOMAttr& a, flags f, container* c) : B (a, f, c) { parse (xml::transcode (a.getValue ())); } template gday:: gday (const std::basic_string& s, const xercesc::DOMElement* e, flags f, container* c) : B (s, e, f, c) { parse (s); } template void gday:: parse (const std::basic_string& str) { typedef typename ro_string::size_type size_type; ro_string tmp (str); size_type n (trim (tmp)); const C* s (tmp.data ()); // gday := ---DD[Z|(+|-)HH:MM] // if (n >= 5) { day_ = 10 * (s[3] - C ('0')) + (s[4] - C ('0')); if (n > 5) zone_parse (s + 5, n - 5); } } // gmonth // template gmonth:: gmonth (const xercesc::DOMElement& e, flags f, container* c) : B (e, f, c) { parse (text_content (e)); } template gmonth:: gmonth (const xercesc::DOMAttr& a, flags f, container* c) : B (a, f, c) { parse (xml::transcode (a.getValue ())); } template gmonth:: gmonth (const std::basic_string& s, const xercesc::DOMElement* e, flags f, container* c) : B (s, e, f, c) { parse (s); } template void gmonth:: parse (const std::basic_string& str) { typedef typename ro_string::size_type size_type; ro_string tmp (str); size_type n (trim (tmp)); const C* s (tmp.data ()); // gmonth := --MM[Z|(+|-)HH:MM] // if (n >= 4) { month_ = 10 * (s[2] - C ('0')) + (s[3] - C ('0')); if (n > 4) zone_parse (s + 4, n - 4); } } // gyear // template gyear:: gyear (const xercesc::DOMElement& e, flags f, container* c) : B (e, f, c) { parse (text_content (e)); } template gyear:: gyear (const xercesc::DOMAttr& a, flags f, container* c) : B (a, f, c) { parse (xml::transcode (a.getValue ())); } template gyear:: gyear (const std::basic_string& s, const xercesc::DOMElement* e, flags f, container* c) : B (s, e, f, c) { parse (s); } template void gyear:: parse (const std::basic_string& str) { typedef typename ro_string::size_type size_type; ro_string tmp (str); size_type n (trim (tmp)); const C* s (tmp.data ()); // gyear := [-]CCYY[N]*[Z|(+|-)HH:MM] // if (n >= 4) { // Find the end of the year token. // size_type pos (4); for (; pos < n; ++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 < n) zone_parse (s + pos, n - pos); } } // gmonth_day // template gmonth_day:: gmonth_day (const xercesc::DOMElement& e, flags f, container* c) : B (e, f, c) { parse (text_content (e)); } template gmonth_day:: gmonth_day (const xercesc::DOMAttr& a, flags f, container* c) : B (a, f, c) { parse (xml::transcode (a.getValue ())); } template gmonth_day:: gmonth_day (const std::basic_string& s, const xercesc::DOMElement* e, flags f, container* c) : B (s, e, f, c) { parse (s); } template void gmonth_day:: parse (const std::basic_string& str) { typedef typename ro_string::size_type size_type; ro_string tmp (str); size_type n (trim (tmp)); const C* s (tmp.data ()); // gmonth_day := --MM-DD[Z|(+|-)HH:MM] // if (n >= 7) { month_ = 10 * (s[2] - C ('0')) + (s[3] - C ('0')); day_ = 10 * (s[5] - C ('0')) + (s[6] - C ('0')); if (n > 7) zone_parse (s + 7, n - 7); } } // gyear_month // template gyear_month:: gyear_month (const xercesc::DOMElement& e, flags f, container* c) : B (e, f, c) { parse (text_content (e)); } template gyear_month:: gyear_month (const xercesc::DOMAttr& a, flags f, container* c) : B (a, f, c) { parse (xml::transcode (a.getValue ())); } template gyear_month:: gyear_month (const std::basic_string& s, const xercesc::DOMElement* e, flags f, container* c) : B (s, e, f, c) { parse (s); } template void gyear_month:: parse (const std::basic_string& str) { typedef typename ro_string::size_type size_type; ro_string tmp (str); size_type n (trim (tmp)); const C* s (tmp.data ()); // gyear_month := [-]CCYY[N]*-MM[Z|(+|-)HH:MM] // if (n >= 7) { // Find the end of the year token. // size_type pos (tmp.find (C ('-'), 4)); if (pos != ro_string::npos && (n - pos - 1) >= 2) { ro_string year_fragment (s, pos); zc_istream is (year_fragment); is >> year_; month_ = 10 * (s[pos + 1] - C ('0')) + (s[pos + 2] - C ('0')); pos += 3; if (pos < n) zone_parse (s + pos, n - pos); } } } // date // template date:: date (const xercesc::DOMElement& e, flags f, container* c) : B (e, f, c) { parse (text_content (e)); } template date:: date (const xercesc::DOMAttr& a, flags f, container* c) : B (a, f, c) { parse (xml::transcode (a.getValue ())); } template date:: date (const std::basic_string& s, const xercesc::DOMElement* e, flags f, container* c) : B (s, e, f, c) { parse (s); } template void date:: parse (const std::basic_string& str) { typedef typename ro_string::size_type size_type; ro_string tmp (str); size_type n (trim (tmp)); const C* s (tmp.data ()); // date := [-]CCYY[N]*-MM-DD[Z|(+|-)HH:MM] // if (n >= 10) { // Find the end of the year token. // size_type pos (tmp.find (C ('-'), 4)); if (pos != ro_string::npos && (n - pos - 1) >= 5) { ro_string year_fragment (s, pos); zc_istream is (year_fragment); is >> year_; month_ = 10 * (s[pos + 1] - C ('0')) + (s[pos + 2] - C ('0')); day_ = 10 * (s[pos + 4] - C ('0')) + (s[pos + 5] - C ('0')); pos += 6; if (pos < n) zone_parse (s + pos, n - pos); } } } // time // template time:: time (const xercesc::DOMElement& e, flags f, container* c) : B (e, f, c) { parse (text_content (e)); } template time:: time (const xercesc::DOMAttr& a, flags f, container* c) : B (a, f, c) { parse (xml::transcode (a.getValue ())); } template time:: time (const std::basic_string& s, const xercesc::DOMElement* e, flags f, container* c) : B (s, e, f, c) { parse (s); } template void time:: parse (const std::basic_string& str) { typedef typename ro_string::size_type size_type; ro_string tmp (str); size_type n (trim (tmp)); const C* s (tmp.data ()); // time := HH:MM:SS[.S+][Z|(+|-)HH:MM] // if (n >= 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 < n; ++pos) { C c (s[pos]); if (c == C ('Z') || c == C ('+') || c == C ('-')) break; } ro_string seconds_fragment (s + 6, pos - 6); zc_istream is (seconds_fragment); is >> seconds_; if (pos < n) zone_parse (s + pos, n - pos); } } // date_time // template date_time:: date_time (const xercesc::DOMElement& e, flags f, container* c) : B (e, f, c) { parse (text_content (e)); } template date_time:: date_time (const xercesc::DOMAttr& a, flags f, container* c) : B (a, f, c) { parse (xml::transcode (a.getValue ())); } template date_time:: date_time (const std::basic_string& s, const xercesc::DOMElement* e, flags f, container* c) : B (s, e, f, c) { parse (s); } template void date_time:: parse (const std::basic_string& str) { typedef typename ro_string::size_type size_type; ro_string tmp (str); size_type n (trim (tmp)); const C* s (tmp.data ()); // date_time := [-]CCYY[N]*-MM-DDTHH:MM:SS[.S+][Z|(+|-)HH:MM] // if (n >= 19) { // Find the end of the year token. // size_type pos (tmp.find (C ('-'), 4)); if (pos != ro_string::npos && (n - pos - 1) >= 14) { ro_string year_fragment (s, pos); zc_istream yis (year_fragment); yis >> year_; month_ = 10 * (s[pos + 1] - C ('0')) + (s[pos + 2] - C ('0')); pos += 3; day_ = 10 * (s[pos + 1] - C ('0')) + (s[pos + 2] - C ('0')); pos += 3; hours_ = 10 * (s[pos + 1] - C ('0')) + (s[pos + 2] - C ('0')); pos += 3; minutes_ = 10 * (s[pos + 1] - C ('0')) + (s[pos + 2] - C ('0')); pos += 4; // Point to the first S. // Find the end of the seconds fragment. // size_type sec_end (pos + 2); for (; sec_end < n; ++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 < n) zone_parse (s + sec_end, n - sec_end); } } } // duration // template duration:: duration (const xercesc::DOMElement& e, flags f, container* c) : B (e, f, c) { parse (text_content (e)); } template duration:: duration (const xercesc::DOMAttr& a, flags f, container* c) : B (a, f, c) { parse (xml::transcode (a.getValue ())); } template duration:: duration (const std::basic_string& s, const xercesc::DOMElement* e, flags f, container* c) : B (s, e, f, c) { parse (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 void duration:: parse (const std::basic_string& str) { typedef typename ro_string::size_type size_type; ro_string tmp (str); size_type n (trim (tmp)); const C* s (tmp.data ()); // Set all the fields since some of them may not be specified. // years_ = months_ = days_ = hours_ = minutes_ = 0; seconds_ = 0.0; // duration := [-]P[nY][nM][nD][TnHnMn[.n+]S] // if (n >= 3) { size_type pos (0); if (s[0] == C ('-')) { negative_ = true; pos++; } else negative_ = false; pos++; // Skip 'P'. size_type del (bits::duration_delim (s, pos, n)); if (del != n && 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, n); } if (del != n && 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, n); } if (del != n && 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, n); } if (del != n && s[del] == C ('T')) { pos = del + 1; del = bits::duration_delim (s, pos, n); if (del != n && 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, n); } if (del != n && 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, n); } if (del != n && s[del] == C ('S')) { ro_string fragment (s + pos, del - pos); zc_istream is (fragment); is >> seconds_; } } } } } } }