root/win32/xsd-3.1.0-i686/libxsd/xsd/cxx/tree/parsing/date-time.txx @ 111

Revision 111, 17.2 kB (checked in by mido, 16 years ago)

pridana knihovna XSD (a jeji chlebodarkyne XERCES), v ramci Win32 zprovoznen priklad tests/test_xsd_hello.cxx

Line 
1// file      : xsd/cxx/tree/parsing/date-time.txx
2// author    : Boris Kolpackov <boris@codesynthesis.com>
3// copyright : Copyright (c) 2005-2008 Code Synthesis Tools CC
4// license   : GNU GPL v2 + exceptions; see accompanying LICENSE file
5
6#include <xsd/cxx/ro-string.hxx>
7#include <xsd/cxx/zc-istream.hxx>
8
9#include <xsd/cxx/xml/string.hxx> // xml::transcode
10
11#include <xsd/cxx/tree/text.hxx>  // text_content
12
13namespace xsd
14{
15  namespace cxx
16  {
17    namespace tree
18    {
19      // time_zone
20      //
21      template <typename C>
22      void time_zone::
23      zone_parse (const C* s, std::size_t n)
24      {
25        // time_zone := Z|(+|-)HH:MM
26        //
27        if (n == 0)
28        {
29          return;
30        }
31        else if (s[0] == C ('Z'))
32        {
33          hours_ = 0;
34          minutes_ = 0;
35          present_ = true;
36        }
37        else if (n == 6)
38        {
39          // Parse hours.
40          //
41          hours_ = 10 * (s[1] - C ('0')) + (s[2] - C ('0'));
42
43          // Parse minutes.
44          //
45          minutes_ = 10 * (s[4] - C ('0')) + (s[5] - C ('0'));
46
47          if (s[0] == C ('-'))
48          {
49            hours_ = -hours_;
50            minutes_ = -minutes_;
51          }
52          present_ = true;
53        }
54      }
55
56      // gday
57      //
58      template <typename C, typename B>
59      gday<C, B>::
60      gday (const xercesc::DOMElement& e, flags f, container* c)
61          : B (e, f, c)
62      {
63        parse (text_content<C> (e));
64      }
65
66      template <typename C, typename B>
67      gday<C, B>::
68      gday (const xercesc::DOMAttr& a, flags f, container* c)
69          : B (a, f, c)
70      {
71        parse (xml::transcode<C> (a.getValue ()));
72      }
73
74      template <typename C, typename B>
75      gday<C, B>::
76      gday (const std::basic_string<C>& s,
77            const xercesc::DOMElement* e,
78            flags f,
79            container* c)
80          : B (s, e, f, c)
81      {
82        parse (s);
83      }
84
85      template <typename C, typename B>
86      void gday<C, B>::
87      parse (const std::basic_string<C>& str)
88      {
89        typedef typename ro_string<C>::size_type size_type;
90
91        ro_string<C> tmp (str);
92        size_type n (trim (tmp));
93        const C* s (tmp.data ());
94
95        // gday := ---DD[Z|(+|-)HH:MM]
96        //
97        if (n >= 5)
98        {
99          day_ = 10 * (s[3] - C ('0')) + (s[4] - C ('0'));
100
101          if (n > 5)
102            zone_parse (s + 5, n - 5);
103        }
104      }
105
106      // gmonth
107      //
108      template <typename C, typename B>
109      gmonth<C, B>::
110      gmonth (const xercesc::DOMElement& e, flags f, container* c)
111          : B (e, f, c)
112      {
113        parse (text_content<C> (e));
114      }
115
116      template <typename C, typename B>
117      gmonth<C, B>::
118      gmonth (const xercesc::DOMAttr& a, flags f, container* c)
119          : B (a, f, c)
120      {
121        parse (xml::transcode<C> (a.getValue ()));
122      }
123
124      template <typename C, typename B>
125      gmonth<C, B>::
126      gmonth (const std::basic_string<C>& s,
127              const xercesc::DOMElement* e,
128              flags f,
129              container* c)
130          : B (s, e, f, c)
131      {
132        parse (s);
133      }
134
135      template <typename C, typename B>
136      void gmonth<C, B>::
137      parse (const std::basic_string<C>& str)
138      {
139        typedef typename ro_string<C>::size_type size_type;
140
141        ro_string<C> tmp (str);
142        size_type n (trim (tmp));
143        const C* s (tmp.data ());
144
145        // gmonth := --MM[Z|(+|-)HH:MM]
146        //
147        if (n >= 4)
148        {
149          month_ = 10 * (s[2] - C ('0')) + (s[3] - C ('0'));
150
151          if (n > 4)
152            zone_parse (s + 4, n - 4);
153        }
154      }
155
156      // gyear
157      //
158      template <typename C, typename B>
159      gyear<C, B>::
160      gyear (const xercesc::DOMElement& e, flags f, container* c)
161          : B (e, f, c)
162      {
163        parse (text_content<C> (e));
164      }
165
166      template <typename C, typename B>
167      gyear<C, B>::
168      gyear (const xercesc::DOMAttr& a, flags f, container* c)
169          : B (a, f, c)
170      {
171        parse (xml::transcode<C> (a.getValue ()));
172      }
173
174      template <typename C, typename B>
175      gyear<C, B>::
176      gyear (const std::basic_string<C>& s,
177             const xercesc::DOMElement* e,
178             flags f,
179             container* c)
180          : B (s, e, f, c)
181      {
182        parse (s);
183      }
184
185      template <typename C, typename B>
186      void gyear<C, B>::
187      parse (const std::basic_string<C>& str)
188      {
189        typedef typename ro_string<C>::size_type size_type;
190
191        ro_string<C> tmp (str);
192        size_type n (trim (tmp));
193        const C* s (tmp.data ());
194
195        // gyear := [-]CCYY[N]*[Z|(+|-)HH:MM]
196        //
197        if (n >= 4)
198        {
199          // Find the end of the year token.
200          //
201          size_type pos (4);
202          for (; pos < n; ++pos)
203          {
204            C c (s[pos]);
205
206            if (c == C ('Z') || c == C ('+') || c == C ('-'))
207              break;
208          }
209
210          ro_string<C> year_fragment (s, pos);
211          zc_istream<C> is (year_fragment);
212          is >> year_;
213
214          if (pos < n)
215            zone_parse (s + pos, n - pos);
216        }
217      }
218
219      // gmonth_day
220      //
221      template <typename C, typename B>
222      gmonth_day<C, B>::
223      gmonth_day (const xercesc::DOMElement& e, flags f, container* c)
224          : B (e, f, c)
225      {
226        parse (text_content<C> (e));
227      }
228
229      template <typename C, typename B>
230      gmonth_day<C, B>::
231      gmonth_day (const xercesc::DOMAttr& a, flags f, container* c)
232          : B (a, f, c)
233      {
234        parse (xml::transcode<C> (a.getValue ()));
235      }
236
237      template <typename C, typename B>
238      gmonth_day<C, B>::
239      gmonth_day (const std::basic_string<C>& s,
240                  const xercesc::DOMElement* e,
241                  flags f,
242                  container* c)
243          : B (s, e, f, c)
244      {
245        parse (s);
246      }
247
248      template <typename C, typename B>
249      void gmonth_day<C, B>::
250      parse (const std::basic_string<C>& str)
251      {
252        typedef typename ro_string<C>::size_type size_type;
253
254        ro_string<C> tmp (str);
255        size_type n (trim (tmp));
256        const C* s (tmp.data ());
257
258        // gmonth_day := --MM-DD[Z|(+|-)HH:MM]
259        //
260        if (n >= 7)
261        {
262          month_ = 10 * (s[2] - C ('0')) + (s[3] - C ('0'));
263          day_ = 10 * (s[5] - C ('0')) + (s[6] - C ('0'));
264
265          if (n > 7)
266            zone_parse (s + 7, n - 7);
267        }
268      }
269
270      // gyear_month
271      //
272      template <typename C, typename B>
273      gyear_month<C, B>::
274      gyear_month (const xercesc::DOMElement& e, flags f, container* c)
275          : B (e, f, c)
276      {
277        parse (text_content<C> (e));
278      }
279
280      template <typename C, typename B>
281      gyear_month<C, B>::
282      gyear_month (const xercesc::DOMAttr& a, flags f, container* c)
283          : B (a, f, c)
284      {
285        parse (xml::transcode<C> (a.getValue ()));
286      }
287
288      template <typename C, typename B>
289      gyear_month<C, B>::
290      gyear_month (const std::basic_string<C>& s,
291                   const xercesc::DOMElement* e,
292                   flags f,
293                   container* c)
294          : B (s, e, f, c)
295      {
296        parse (s);
297      }
298
299      template <typename C, typename B>
300      void gyear_month<C, B>::
301      parse (const std::basic_string<C>& str)
302      {
303        typedef typename ro_string<C>::size_type size_type;
304
305        ro_string<C> tmp (str);
306        size_type n (trim (tmp));
307        const C* s (tmp.data ());
308
309        // gyear_month := [-]CCYY[N]*-MM[Z|(+|-)HH:MM]
310        //
311
312        if (n >= 7)
313        {
314          // Find the end of the year token.
315          //
316          size_type pos (tmp.find (C ('-'), 4));
317
318          if (pos != ro_string<C>::npos && (n - pos - 1) >= 2)
319          {
320            ro_string<C> year_fragment (s, pos);
321            zc_istream<C> is (year_fragment);
322            is >> year_;
323
324            month_ = 10 * (s[pos + 1] - C ('0')) + (s[pos + 2] - C ('0'));
325
326            pos += 3;
327
328            if (pos < n)
329              zone_parse (s + pos, n - pos);
330          }
331        }
332      }
333
334      // date
335      //
336      template <typename C, typename B>
337      date<C, B>::
338      date (const xercesc::DOMElement& e, flags f, container* c)
339          : B (e, f, c)
340      {
341        parse (text_content<C> (e));
342      }
343
344      template <typename C, typename B>
345      date<C, B>::
346      date (const xercesc::DOMAttr& a, flags f, container* c)
347          : B (a, f, c)
348      {
349        parse (xml::transcode<C> (a.getValue ()));
350      }
351
352      template <typename C, typename B>
353      date<C, B>::
354      date (const std::basic_string<C>& s,
355            const xercesc::DOMElement* e,
356            flags f,
357            container* c)
358          : B (s, e, f, c)
359      {
360        parse (s);
361      }
362
363      template <typename C, typename B>
364      void date<C, B>::
365      parse (const std::basic_string<C>& str)
366      {
367        typedef typename ro_string<C>::size_type size_type;
368
369        ro_string<C> tmp (str);
370        size_type n (trim (tmp));
371        const C* s (tmp.data ());
372
373        // date := [-]CCYY[N]*-MM-DD[Z|(+|-)HH:MM]
374        //
375
376        if (n >= 10)
377        {
378          // Find the end of the year token.
379          //
380          size_type pos (tmp.find (C ('-'), 4));
381
382          if (pos != ro_string<C>::npos && (n - pos - 1) >= 5)
383          {
384            ro_string<C> year_fragment (s, pos);
385            zc_istream<C> is (year_fragment);
386            is >> year_;
387
388            month_ = 10 * (s[pos + 1] - C ('0')) + (s[pos + 2] - C ('0'));
389            day_ = 10 * (s[pos + 4] - C ('0')) + (s[pos + 5] - C ('0'));
390
391            pos += 6;
392
393            if (pos < n)
394              zone_parse (s + pos, n - pos);
395          }
396        }
397      }
398
399      // time
400      //
401      template <typename C, typename B>
402      time<C, B>::
403      time (const xercesc::DOMElement& e, flags f, container* c)
404          : B (e, f, c)
405      {
406        parse (text_content<C> (e));
407      }
408
409      template <typename C, typename B>
410      time<C, B>::
411      time (const xercesc::DOMAttr& a, flags f, container* c)
412          : B (a, f, c)
413      {
414        parse (xml::transcode<C> (a.getValue ()));
415      }
416
417      template <typename C, typename B>
418      time<C, B>::
419      time (const std::basic_string<C>& s,
420            const xercesc::DOMElement* e,
421            flags f,
422            container* c)
423          : B (s, e, f, c)
424      {
425        parse (s);
426      }
427
428      template <typename C, typename B>
429      void time<C, B>::
430      parse (const std::basic_string<C>& str)
431      {
432        typedef typename ro_string<C>::size_type size_type;
433
434        ro_string<C> tmp (str);
435        size_type n (trim (tmp));
436        const C* s (tmp.data ());
437
438        // time := HH:MM:SS[.S+][Z|(+|-)HH:MM]
439        //
440
441        if (n >= 8)
442        {
443          hours_ = 10 * (s[0] - '0') + (s[1] - '0');
444          minutes_ = 10 * (s[3] - '0') + (s[4] - '0');
445
446          // Find the end of the seconds fragment.
447          //
448          size_type pos (8);
449          for (; pos < n; ++pos)
450          {
451            C c (s[pos]);
452
453            if (c == C ('Z') || c == C ('+') || c == C ('-'))
454              break;
455          }
456
457          ro_string<C> seconds_fragment (s + 6, pos - 6);
458          zc_istream<C> is (seconds_fragment);
459          is >> seconds_;
460
461          if (pos < n)
462            zone_parse (s + pos, n - pos);
463        }
464      }
465
466      // date_time
467      //
468      template <typename C, typename B>
469      date_time<C, B>::
470      date_time (const xercesc::DOMElement& e, flags f, container* c)
471          : B (e, f, c)
472      {
473        parse (text_content<C> (e));
474      }
475
476      template <typename C, typename B>
477      date_time<C, B>::
478      date_time (const xercesc::DOMAttr& a, flags f, container* c)
479          : B (a, f, c)
480      {
481        parse (xml::transcode<C> (a.getValue ()));
482      }
483
484      template <typename C, typename B>
485      date_time<C, B>::
486      date_time (const std::basic_string<C>& s,
487                 const xercesc::DOMElement* e,
488                 flags f,
489                 container* c)
490          : B (s, e, f, c)
491      {
492        parse (s);
493      }
494
495      template <typename C, typename B>
496      void date_time<C, B>::
497      parse (const std::basic_string<C>& str)
498      {
499        typedef typename ro_string<C>::size_type size_type;
500
501        ro_string<C> tmp (str);
502        size_type n (trim (tmp));
503        const C* s (tmp.data ());
504
505        // date_time := [-]CCYY[N]*-MM-DDTHH:MM:SS[.S+][Z|(+|-)HH:MM]
506        //
507
508        if (n >= 19)
509        {
510          // Find the end of the year token.
511          //
512          size_type pos (tmp.find (C ('-'), 4));
513
514          if (pos != ro_string<C>::npos && (n - pos - 1) >= 14)
515          {
516            ro_string<C> year_fragment (s, pos);
517            zc_istream<C> yis (year_fragment);
518            yis >> year_;
519
520            month_ = 10 * (s[pos + 1] - C ('0')) + (s[pos + 2] - C ('0'));
521            pos += 3;
522
523            day_ = 10 * (s[pos + 1] - C ('0')) + (s[pos + 2] - C ('0'));
524            pos += 3;
525
526            hours_ = 10 * (s[pos + 1] - C ('0')) + (s[pos + 2] - C ('0'));
527            pos += 3;
528
529            minutes_ = 10 * (s[pos + 1] - C ('0')) + (s[pos + 2] - C ('0'));
530            pos += 4; // Point to the first S.
531
532            // Find the end of the seconds fragment.
533            //
534            size_type sec_end (pos + 2);
535            for (; sec_end < n; ++sec_end)
536            {
537              C c (s[sec_end]);
538
539              if (c == C ('Z') || c == C ('+') || c == C ('-'))
540                break;
541            }
542
543            ro_string<C> seconds_fragment (s + pos, sec_end - pos);
544            zc_istream<C> sis (seconds_fragment);
545            sis >> seconds_;
546
547            if (sec_end < n)
548              zone_parse (s + sec_end, n - sec_end);
549          }
550        }
551      }
552
553      // duration
554      //
555      template <typename C, typename B>
556      duration<C, B>::
557      duration (const xercesc::DOMElement& e, flags f, container* c)
558          : B (e, f, c)
559      {
560        parse (text_content<C> (e));
561      }
562
563      template <typename C, typename B>
564      duration<C, B>::
565      duration (const xercesc::DOMAttr& a, flags f, container* c)
566          : B (a, f, c)
567      {
568        parse (xml::transcode<C> (a.getValue ()));
569      }
570
571      template <typename C, typename B>
572      duration<C, B>::
573      duration (const std::basic_string<C>& s,
574                const xercesc::DOMElement* e,
575                flags f,
576                container* c)
577          : B (s, e, f, c)
578      {
579        parse (s);
580      }
581
582      namespace bits
583      {
584        template <typename C>
585        inline typename ro_string<C>::size_type
586        duration_delim (const C* s,
587                        typename ro_string<C>::size_type pos,
588                        typename ro_string<C>::size_type size)
589        {
590          const C* p (s + pos);
591          for (; p < (s + size); ++p)
592          {
593            if (*p == C ('Y') || *p == C ('D') || *p == C ('M') ||
594                *p == C ('H') || *p == C ('M') || *p == C ('S') ||
595                *p == C ('T'))
596              break;
597          }
598
599          return p - s;
600        }
601      }
602
603      template <typename C, typename B>
604      void duration<C, B>::
605      parse (const std::basic_string<C>& str)
606      {
607        typedef typename ro_string<C>::size_type size_type;
608
609        ro_string<C> tmp (str);
610        size_type n (trim (tmp));
611        const C* s (tmp.data ());
612
613        // duration := [-]P[nY][nM][nD][TnHnMn[.n+]S]
614        //
615        if (n >= 3)
616        {
617          size_type pos (0);
618
619          if (s[0] == C ('-'))
620          {
621            negative_ = true;
622            pos++;
623          }
624          else
625            negative_ = false;
626
627          pos++; // Skip 'P'.
628
629          size_type del (bits::duration_delim (s, pos, n));
630
631          if (del != n && s[del] == C ('Y'))
632          {
633            ro_string<C> fragment (s + pos, del - pos);
634            zc_istream<C> is (fragment);
635            is >> years_;
636
637            pos = del + 1;
638            del = bits::duration_delim (s, pos, n);
639          }
640
641          if (del != n && s[del] == C ('M'))
642          {
643            ro_string<C> fragment (s + pos, del - pos);
644            zc_istream<C> is (fragment);
645            is >> months_;
646
647            pos = del + 1;
648            del = bits::duration_delim (s, pos, n);
649          }
650
651          if (del != n && s[del] == C ('D'))
652          {
653            ro_string<C> fragment (s + pos, del - pos);
654            zc_istream<C> is (fragment);
655            is >> days_;
656
657            pos = del + 1;
658            del = bits::duration_delim (s, pos, n);
659          }
660
661          if (del != n && s[del] == C ('T'))
662          {
663            pos = del + 1;
664            del = bits::duration_delim (s, pos, n);
665
666            if (del != n && s[del] == C ('H'))
667            {
668              ro_string<C> fragment (s + pos, del - pos);
669              zc_istream<C> is (fragment);
670              is >> hours_;
671
672              pos = del + 1;
673              del = bits::duration_delim (s, pos, n);
674            }
675
676            if (del != n && s[del] == C ('M'))
677            {
678              ro_string<C> fragment (s + pos, del - pos);
679              zc_istream<C> is (fragment);
680              is >> minutes_;
681
682              pos = del + 1;
683              del = bits::duration_delim (s, pos, n);
684            }
685
686            if (del != n && s[del] == C ('S'))
687            {
688              ro_string<C> fragment (s + pos, del - pos);
689              zc_istream<C> is (fragment);
690              is >> seconds_;
691            }
692          }
693        }
694      }
695    }
696  }
697}
Note: See TracBrowser for help on using the browser.