// file : xsd/cxx/tree/serialization/date-time.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 #include #include // bits::{gday_prefix,gmonth_prefix} namespace xsd { namespace cxx { namespace tree { // time_zone // namespace bits { // Assumes the fill character is set to '0'. // template void zone_insert (std::basic_ostream& os, const time_zone& z) { // time-zone := Z|(+|-)HH:MM // short h = z.zone_hours (); short m = z.zone_minutes (); if (h == 0 && m == 0) { os << C ('Z'); } else { if (h < 0 || m < 0) { h = -h; m = -m; os << C ('-'); } else os << C ('+'); if (h >= 0 && h <= 14 && m >= 0 && m <= 59) { os.width (2); os << h << C (':'); os.width (2); os << m; } } } } // gday // namespace bits { template void insert (std::basic_ostream& os, const tree::gday& x) { if (x.day () < 32) { // Save some time and space by not restoring the fill character // since it is the same in case of a list. // os.fill (C ('0')); os << bits::gday_prefix (); os.width (2); os << x.day (); if (x.zone_present ()) zone_insert (os, x); } } } template inline void operator<< (xercesc::DOMElement& e, const gday& x) { std::basic_ostringstream os; bits::insert (os, x); e << os.str (); } template inline void operator<< (xercesc::DOMAttr& a, const gday& x) { std::basic_ostringstream os; bits::insert (os, x); a << os.str (); } template inline void operator<< (list_stream& ls, const gday& x) { bits::insert (ls.os_, x); } // gmonth // namespace bits { template void insert (std::basic_ostream& os, const tree::gmonth& x) { if (x.month () < 13) { os.fill (C ('0')); os << bits::gmonth_prefix (); os.width (2); os << x.month (); if (x.zone_present ()) zone_insert (os, x); } } } template inline void operator<< (xercesc::DOMElement& e, const gmonth& x) { std::basic_ostringstream os; bits::insert (os, x); e << os.str (); } template inline void operator<< (xercesc::DOMAttr& a, const gmonth& x) { std::basic_ostringstream os; bits::insert (os, x); a << os.str (); } template inline void operator<< (list_stream& ls, const gmonth& x) { bits::insert (ls.os_, x); } // gyear // namespace bits { template void insert (std::basic_ostream& os, const tree::gyear& x) { os.fill (C ('0')); os.width (4); os << x.year (); if (x.zone_present ()) zone_insert (os, x); } } template inline void operator<< (xercesc::DOMElement& e, const gyear& x) { std::basic_ostringstream os; bits::insert (os, x); e << os.str (); } template inline void operator<< (xercesc::DOMAttr& a, const gyear& x) { std::basic_ostringstream os; bits::insert (os, x); a << os.str (); } template inline void operator<< (list_stream& ls, const gyear& x) { bits::insert (ls.os_, x); } // gmonth_day // namespace bits { template void insert (std::basic_ostream& os, const tree::gmonth_day& x) { if (x.month () < 13 && x.day () < 32) { os.fill (C ('0')); os << bits::gmonth_prefix (); os.width (2); os << x.month () << C ('-'); os.width (2); os << x.day (); if (x.zone_present ()) zone_insert (os, x); } } } template inline void operator<< (xercesc::DOMElement& e, const gmonth_day& x) { std::basic_ostringstream os; bits::insert (os, x); e << os.str (); } template inline void operator<< (xercesc::DOMAttr& a, const gmonth_day& x) { std::basic_ostringstream os; bits::insert (os, x); a << os.str (); } template inline void operator<< (list_stream& ls, const gmonth_day& x) { bits::insert (ls.os_, x); } // gyear_month // namespace bits { template void insert (std::basic_ostream& os, const tree::gyear_month& x) { if (x.month () < 13) { os.fill (C ('0')); os.width (4); os << x.year () << C ('-'); os.width (2); os << x.month (); if (x.zone_present ()) zone_insert (os, x); } } } template inline void operator<< (xercesc::DOMElement& e, const gyear_month& x) { std::basic_ostringstream os; bits::insert (os, x); e << os.str (); } template inline void operator<< (xercesc::DOMAttr& a, const gyear_month& x) { std::basic_ostringstream os; bits::insert (os, x); a << os.str (); } template inline void operator<< (list_stream& ls, const gyear_month& x) { bits::insert (ls.os_, x); } // date // namespace bits { template void insert (std::basic_ostream& os, const tree::date& x) { if (x.month () < 13 && x.day () < 32) { os.fill (C ('0')); os.width (4); os << x.year () << C ('-'); os.width (2); os << x.month () << C ('-'); os.width (2); os << x.day (); if (x.zone_present ()) zone_insert (os, x); } } } template inline void operator<< (xercesc::DOMElement& e, const date& x) { std::basic_ostringstream os; bits::insert (os, x); e << os.str (); } template inline void operator<< (xercesc::DOMAttr& a, const date& x) { std::basic_ostringstream os; bits::insert (os, x); a << os.str (); } template inline void operator<< (list_stream& ls, const date& x) { bits::insert (ls.os_, x); } // time // namespace bits { template void insert (std::basic_ostream& os, const tree::time& x) { if (x.hours () <= 24 && x.minutes () <= 59 && x.seconds () >= 0.0 && x.seconds () < 60.0) { os.fill (C ('0')); os.width (2); os << x.hours () << C (':'); os.width (2); os << x.minutes () << C (':'); std::basic_ostringstream ostr; ostr.imbue (std::locale::classic ()); ostr.width (9); ostr.fill (C ('0')); ostr << std::fixed << x.seconds (); std::basic_string s (ostr.str ()); // Remove the trailing zeros and the decimal point if necessary. // typedef typename std::basic_string::size_type size_type; size_type size (s.size ()), n (size); for (; n > 0 && s[n - 1] == C ('0'); --n)/*noop*/; if (n > 0 && s[n - 1] == C ('.')) --n; if (n != size) s.resize (n); os << s; if (x.zone_present ()) zone_insert (os, x); } } } template inline void operator<< (xercesc::DOMElement& e, const time& x) { std::basic_ostringstream os; bits::insert (os, x); e << os.str (); } template inline void operator<< (xercesc::DOMAttr& a, const time& x) { std::basic_ostringstream os; bits::insert (os, x); a << os.str (); } template inline void operator<< (list_stream& ls, const time& x) { bits::insert (ls.os_, x); } // date_time // namespace bits { template void insert (std::basic_ostream& os, const tree::date_time& x) { if (x.month () <= 12 && x.day () <= 31 && x.hours () <= 24 && x.minutes () <= 59 && x.seconds () >= 0.0 && x.seconds () < 60.0) { os.fill (C ('0')); os.width (4); os << x.year () << C ('-'); os.width (2); os << x.month () << C ('-'); os.width (2); os << x.day () << C ('T'); os.width (2); os << x.hours () << C (':'); os.width (2); os << x.minutes () << C (':'); std::basic_ostringstream ostr; ostr.imbue (std::locale::classic ()); ostr.width (9); ostr.fill (C ('0')); ostr << std::fixed << x.seconds (); std::basic_string s (ostr.str ()); // Remove the trailing zeros and the decimal point if necessary. // typedef typename std::basic_string::size_type size_type; size_type size (s.size ()), n (size); for (; n > 0 && s[n - 1] == C ('0'); --n)/*noop*/; if (n > 0 && s[n - 1] == C ('.')) --n; if (n != size) s.resize (n); os << s; if (x.zone_present ()) zone_insert (os, x); } } } template inline void operator<< (xercesc::DOMElement& e, const date_time& x) { std::basic_ostringstream os; bits::insert (os, x); e << os.str (); } template inline void operator<< (xercesc::DOMAttr& a, const date_time& x) { std::basic_ostringstream os; bits::insert (os, x); a << os.str (); } template inline void operator<< (list_stream& ls, const date_time& x) { bits::insert (ls.os_, x); } // duration // namespace bits { template void insert (std::basic_ostream& os, const tree::duration& x) { if (x.negative ()) os << C ('-'); os << C ('P'); // years // // In case it is 0-duration, use the years field to handle // this case. // if (x.years () != 0 || (x.months () == 0 && x.days () == 0 && x.hours () == 0 && x.minutes () == 0 && x.seconds () == 0.0)) { os << x.years () << C ('Y'); } // months // if (x.months () != 0) { os << x.months () << C ('M'); } // days // if (x.days () != 0) { os << x.days () << C ('D'); } // Figure out if we need the 'T' delimiter. // if (x.hours () != 0 || x.minutes () != 0 || x.seconds () != 0.0) os << C ('T'); // hours // if (x.hours () != 0) { os << x.hours () << C ('H'); } // minutes // if (x.minutes () != 0) { os << x.minutes () << C ('M'); } // seconds // if (x.seconds () > 0.0) { std::basic_ostringstream ostr; ostr.imbue (std::locale::classic ()); ostr << std::fixed << x.seconds (); std::basic_string s (ostr.str ()); // Remove the trailing zeros and the decimal point if necessary. // typedef typename std::basic_string::size_type size_type; size_type size (s.size ()), n (size); for (; n > 0 && s[n - 1] == C ('0'); --n)/*noop*/; if (n > 0 && s[n - 1] == C ('.')) --n; if (n != size) s.resize (n); os << s << C ('S'); } } } template inline void operator<< (xercesc::DOMElement& e, const duration& x) { std::basic_ostringstream os; bits::insert (os, x); e << os.str (); } template inline void operator<< (xercesc::DOMAttr& a, const duration& x) { std::basic_ostringstream os; bits::insert (os, x); a << os.str (); } template inline void operator<< (list_stream& ls, const duration& x) { bits::insert (ls.os_, x); } } } }