root/win32/xsd-3.1.0-i686/libxsd/xsd/cxx/parser/validating/parser.txx @ 111

Revision 111, 18.4 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/parser/validating/parser.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 <cassert>
7
8#include <xsd/cxx/xml/bits/literals.hxx>
9#include <xsd/cxx/parser/validating/exceptions.hxx>
10
11namespace xsd
12{
13  namespace cxx
14  {
15    namespace parser
16    {
17      namespace validating
18      {
19
20        // empty_content
21        //
22
23
24        template <typename C>
25        void empty_content<C>::
26        _start_any_element (const ro_string<C>&,
27                            const ro_string<C>&,
28                            const ro_string<C>*)
29        {
30        }
31
32        template <typename C>
33        void empty_content<C>::
34        _end_any_element (const ro_string<C>&,
35                          const ro_string<C>&)
36        {
37        }
38
39        template <typename C>
40        void empty_content<C>::
41        _any_attribute (const ro_string<C>&,
42                        const ro_string<C>&,
43                        const ro_string<C>&)
44        {
45        }
46
47        template <typename C>
48        void empty_content<C>::
49        _any_characters (const ro_string<C>&)
50        {
51        }
52
53        //
54        //
55        template <typename C>
56        bool empty_content<C>::
57        _start_element_impl (const ro_string<C>&,
58                             const ro_string<C>&,
59                             const ro_string<C>*)
60        {
61          return false;
62        }
63
64        template <typename C>
65        bool empty_content<C>::
66        _end_element_impl (const ro_string<C>&,
67                           const ro_string<C>&)
68        {
69          return false;
70        }
71
72        template <typename C>
73        bool empty_content<C>::
74        _attribute_impl (const ro_string<C>&,
75                         const ro_string<C>&,
76                         const ro_string<C>&)
77        {
78          return false;
79        }
80
81        template <typename C>
82        bool empty_content<C>::
83        _characters_impl (const ro_string<C>&)
84        {
85          return false;
86        }
87
88        //
89        //
90        template <typename C>
91        void empty_content<C>::
92        _start_element (const ro_string<C>& ns,
93                        const ro_string<C>& name,
94                        const ro_string<C>* type)
95        {
96          if (!_start_element_impl (ns, name, type))
97            _unexpected_element (ns, name);
98        }
99
100        template <typename C>
101        void empty_content<C>::
102        _end_element (const ro_string<C>& ns,
103                      const ro_string<C>& name)
104        {
105          if (!_end_element_impl (ns, name))
106            _unexpected_element (ns, name);
107        }
108
109        template <typename C>
110        void empty_content<C>::
111        _attribute (const ro_string<C>& ns,
112                    const ro_string<C>& name,
113                    const ro_string<C>& value)
114        {
115          // Weed out special attributes: xsi:type, xsi:nil,
116          // xsi:schemaLocation and noNamespaceSchemaLocation.
117          // See section 3.2.7 in Structures for details.
118          //
119          if (ns == xml::bits::xsi_namespace<C> () &&
120              (name == xml::bits::type<C> () ||
121               name == xml::bits::nil<C> () ||
122               name == xml::bits::schema_location<C> () ||
123               name == xml::bits::no_namespace_schema_location<C> ()))
124            return;
125
126          // Also some parsers (notably Xerces-C++) supplies us with
127          // namespace-prefix mapping attributes.
128          //
129          if (ns == xml::bits::xmlns_namespace<C> ())
130            return;
131
132          if (!_attribute_impl (ns, name, value))
133            _unexpected_attribute (ns, name, value);
134        }
135
136        template <typename C>
137        void empty_content<C>::
138        _characters (const ro_string<C>& s)
139        {
140          if (!_characters_impl (s))
141            _unexpected_characters (s);
142        }
143
144        //
145        //
146        template <typename C>
147        void empty_content<C>::
148        _expected_element (const C* ex_ns, const C* ex_name)
149        {
150          throw expected_element<C> (ex_ns, ex_name);
151        }
152
153        template <typename C>
154        void empty_content<C>::
155        _expected_element (const C* ex_ns,
156                           const C* ex_name,
157                           const ro_string<C>& en_ns,
158                           const ro_string<C>& en_name)
159        {
160          throw expected_element<C> (ex_ns, ex_name, en_ns, en_name);
161        }
162
163        template <typename C>
164        void empty_content<C>::
165        _unexpected_element (const ro_string<C>& ns,
166                             const ro_string<C>& name)
167        {
168          throw unexpected_element<C> (ns, name);
169        }
170
171        template <typename C>
172        void empty_content<C>::
173        _expected_attribute (const C* ex_ns, const C* ex_name)
174        {
175          throw expected_attribute<C> (ex_ns, ex_name);
176        }
177
178        template <typename C>
179        void empty_content<C>::
180        _unexpected_attribute (const ro_string<C>& ns,
181                               const ro_string<C>& name,
182                               const ro_string<C>&)
183        {
184          throw unexpected_attribute<C> (ns, name);
185        }
186
187        template <typename C>
188        void empty_content<C>::
189        _unexpected_characters (const ro_string<C>& s)
190        {
191          throw unexpected_characters<C> (s);
192        }
193
194
195        // simple_content
196        //
197
198        template <typename C>
199        void simple_content<C>::
200        _attribute (const ro_string<C>& ns,
201                    const ro_string<C>& name,
202                    const ro_string<C>& value)
203        {
204          // Weed out special attributes: xsi:type, xsi:nil,
205          // xsi:schemaLocation and xsi:noNamespaceSchemaLocation.
206          // See section 3.2.7 in Structures for details.
207          //
208          if (ns == xml::bits::xsi_namespace<C> () &&
209              (name == xml::bits::type<C> () ||
210               name == xml::bits::nil<C> () ||
211               name == xml::bits::schema_location<C> () ||
212               name == xml::bits::no_namespace_schema_location<C> ()))
213            return;
214
215          // Also some parsers (notably Xerces-C++) supplies us with
216          // namespace-prefix mapping attributes.
217          //
218          if (ns == xml::bits::xmlns_namespace<C> ())
219            return;
220
221          if (!_attribute_impl (ns, name, value))
222            _unexpected_attribute (ns, name, value);
223        }
224
225        template <typename C>
226        void simple_content<C>::
227        _characters (const ro_string<C>& str)
228        {
229          if (!_characters_impl (str))
230          {
231            // Mixed content is implemented in the generated code
232            // by overriding _characters_impl and forwarding to
233            // _any_characters.
234            //
235
236            // Scan the string for any non-whitespace characters
237            // (Structures, section 3.4.4, clause 1.3).
238            //
239            for (typename ro_string<C>::size_type i (0), e (str.size ());
240                 i < e; ++i)
241            {
242              C c (str[i]);
243
244              if (c != C (0x20) && // space
245                  c != C (0x0D) && // carriage return
246                  c != C (0x09) && // tab
247                  c != C (0x0A))
248                _unexpected_characters (str);
249            }
250          }
251        }
252
253        template <typename C>
254        void simple_content<C>::
255        _pre_impl ()
256        {
257          this->_pre ();
258          _pre_a_validate ();
259        }
260
261        template <typename C>
262        void simple_content<C>::
263        _post_impl ()
264        {
265          _post_a_validate ();
266          this->_post ();
267        }
268
269        template <typename C>
270        void simple_content<C>::
271        _pre_a_validate ()
272        {
273        }
274
275        template <typename C>
276        void simple_content<C>::
277        _post_a_validate ()
278        {
279        }
280
281        template <typename C>
282        bool simple_content<C>::
283        _attribute_impl (const ro_string<C>& ns,
284                         const ro_string<C>& name,
285                         const ro_string<C>& value)
286        {
287          return _attribute_impl_phase_one (ns, name, value) ||
288            _attribute_impl_phase_two (ns, name, value);
289        }
290
291        template <typename C>
292        bool simple_content<C>::
293        _attribute_impl_phase_one (const ro_string<C>&,
294                                   const ro_string<C>&,
295                                   const ro_string<C>&)
296        {
297          return false;
298        }
299
300        template <typename C>
301        bool simple_content<C>::
302        _attribute_impl_phase_two (const ro_string<C>&,
303                                   const ro_string<C>&,
304                                   const ro_string<C>&)
305        {
306          return false;
307        }
308
309
310        // complex_content
311        //
312
313
314        template <typename C>
315        void complex_content<C>::
316        _start_element (const ro_string<C>& ns,
317                        const ro_string<C>& name,
318                        const ro_string<C>* type)
319        {
320          state& s (context_.top ());
321
322          if (s.depth_++ > 0)
323          {
324            if (s.any_)
325              _start_any_element (ns, name, type);
326            else if (s.parser_)
327              s.parser_->_start_element (ns, name, type);
328          }
329          else
330          {
331            if (!_start_element_impl (ns, name, type))
332              _unexpected_element (ns, name);
333            else if (s.parser_ != 0)
334              s.parser_->_pre_impl ();
335          }
336        }
337
338        template <typename C>
339        void complex_content<C>::
340        _end_element (const ro_string<C>& ns,
341                      const ro_string<C>& name)
342        {
343          // To understand what's going on here it is helpful to think of
344          // a "total depth" as being the sum of individual depths over
345          // all elements.
346          //
347
348          if (context_.top ().depth_ == 0)
349          {
350            state& s (context_.under_top ()); // One before last.
351
352            if (--s.depth_ > 0)
353            {
354              // Indirect recursion.
355              //
356              if (s.parser_)
357                s.parser_->_end_element (ns, name);
358            }
359            else
360            {
361              // Direct recursion.
362              //
363              assert (this == s.parser_);
364
365              this->_post_impl ();
366
367              if (!_end_element_impl (ns, name))
368                assert (false);
369            }
370          }
371          else
372          {
373            state& s (context_.top ());
374
375            if (--s.depth_ > 0)
376            {
377              if (s.any_)
378                _end_any_element (ns, name);
379              else if (s.parser_)
380                s.parser_->_end_element (ns, name);
381            }
382            else
383            {
384              if (s.parser_ != 0 && !s.any_)
385                s.parser_->_post_impl ();
386
387              if (!_end_element_impl (ns, name))
388                _unexpected_element (ns, name);
389            }
390          }
391        }
392
393        template <typename C>
394        void complex_content<C>::
395        _attribute (const ro_string<C>& ns,
396                    const ro_string<C>& name,
397                    const ro_string<C>& value)
398        {
399          // Weed out special attributes: xsi:type, xsi:nil,
400          // xsi:schemaLocation and xsi:noNamespaceSchemaLocation.
401          // See section 3.2.7 in Structures for details.
402          //
403          if (ns == xml::bits::xsi_namespace<C> () &&
404              (name == xml::bits::type<C> () ||
405               name == xml::bits::nil<C> () ||
406               name == xml::bits::schema_location<C> () ||
407               name == xml::bits::no_namespace_schema_location<C> ()))
408            return;
409
410          // Also some parsers (notably Xerces-C++) supplies us with
411          // namespace-prefix mapping attributes.
412          //
413          if (ns == xml::bits::xmlns_namespace<C> ())
414            return;
415
416          const state& s (context_.top ());
417
418          if (s.depth_ > 0)
419          {
420            if (s.any_)
421              _any_attribute (ns, name, value);
422            else if (s.parser_)
423              s.parser_->_attribute (ns, name, value);
424          }
425          else
426          {
427            if (!_attribute_impl (ns, name, value))
428              _unexpected_attribute (ns, name, value);
429          }
430        }
431
432        template <typename C>
433        void complex_content<C>::
434        _characters (const ro_string<C>& str)
435        {
436          const state& s (context_.top ());
437
438          if (s.depth_ > 0)
439          {
440            if (s.any_)
441              _any_characters (str);
442            else if (s.parser_)
443              s.parser_->_characters (str);
444          }
445          else
446          {
447            if (!_characters_impl (str))
448            {
449              // Mixed content is implemented in the generated code
450              // by overriding _characters_impl and forwarding to
451              // _any_characters.
452              //
453
454              // Scan the string for any non-whitespace characters
455              // (Structures, section 3.4.4, clause 1.3).
456              //
457              for (typename ro_string<C>::size_type i (0), e (str.size ());
458                   i < e; ++i)
459              {
460                C c (str[i]);
461
462                if (c != C (0x20) && // space
463                    c != C (0x0D) && // carriage return
464                    c != C (0x09) && // tab
465                    c != C (0x0A))
466                  _unexpected_characters (str);
467              }
468            }
469          }
470        }
471
472        template <typename C>
473        void complex_content<C>::
474        _pre_impl ()
475        {
476          context_.push (state ());
477          this->_pre ();
478          _pre_a_validate ();
479          _pre_e_validate ();
480        }
481
482        template <typename C>
483        void complex_content<C>::
484        _post_impl ()
485        {
486          _post_e_validate ();
487          _post_a_validate ();
488          this->_post ();
489          context_.pop ();
490        }
491
492        template <typename C>
493        void complex_content<C>::
494        _pre_e_validate ()
495        {
496        }
497
498        template <typename C>
499        void complex_content<C>::
500        _post_e_validate ()
501        {
502        }
503
504        template <typename C>
505        void complex_content<C>::
506        _pre_a_validate ()
507        {
508        }
509
510        template <typename C>
511        void complex_content<C>::
512        _post_a_validate ()
513        {
514        }
515
516        template <typename C>
517        bool complex_content<C>::
518        _attribute_impl (const ro_string<C>& ns,
519                         const ro_string<C>& name,
520                         const ro_string<C>& value)
521        {
522          return _attribute_impl_phase_one (ns, name, value) ||
523            _attribute_impl_phase_two (ns, name, value);
524        }
525
526        template <typename C>
527        bool complex_content<C>::
528        _attribute_impl_phase_one (const ro_string<C>&,
529                                   const ro_string<C>&,
530                                   const ro_string<C>&)
531        {
532          return false;
533        }
534
535        template <typename C>
536        bool complex_content<C>::
537        _attribute_impl_phase_two (const ro_string<C>&,
538                                   const ro_string<C>&,
539                                   const ro_string<C>&)
540        {
541          return false;
542        }
543
544
545        // list_base
546        //
547        namespace bits
548        {
549          // Find first non-space character.
550          //
551          template <typename C>
552          typename ro_string<C>::size_type
553          find_ns (const C* s,
554                   typename ro_string<C>::size_type size,
555                   typename ro_string<C>::size_type pos)
556          {
557            while (pos < size &&
558                   (s[pos] == C (0x20) || s[pos] == C (0x0A) ||
559                    s[pos] == C (0x0D) || s[pos] == C (0x09)))
560              ++pos;
561
562            return pos < size ? pos : ro_string<C>::npos;
563          }
564
565          // Find first space character.
566          //
567          template <typename C>
568          typename ro_string<C>::size_type
569          find_s (const C* s,
570                  typename ro_string<C>::size_type size,
571                  typename ro_string<C>::size_type pos)
572          {
573            while (pos < size &&
574                   s[pos] != C (0x20) && s[pos] != C (0x0A) &&
575                   s[pos] != C (0x0D) && s[pos] != C (0x09))
576              ++pos;
577
578            return pos < size ? pos : ro_string<C>::npos;
579          }
580        }
581
582        // Relevant XML Schema Part 2: Datatypes sections: 4.2.1.2, 4.3.6.
583        //
584
585        template <typename C>
586        void list_base<C>::
587        _pre ()
588        {
589          buf_.clear ();
590        }
591
592        template <typename C>
593        void list_base<C>::
594        _characters (const ro_string<C>& s)
595        {
596          typedef typename ro_string<C>::size_type size_type;
597
598          const C* data (s.data ());
599          size_type size (s.size ());
600
601          // Handle the previous chunk if we start with a ws.
602          //
603          if (!buf_.empty () &&
604              (data[0] == C (0x20) || data[0] == C (0x0A) ||
605               data[0] == C (0x0D) || data[0] == C (0x09)))
606          {
607            ro_string<C> tmp (buf_); // Private copy ctor.
608            _xsd_parse_item (tmp);
609            buf_.clear ();
610          }
611
612          // Traverse the data while logically collapsing spaces.
613          //
614          for (size_type i (bits::find_ns (data, size, 0));
615               i != ro_string<C>::npos;)
616          {
617            size_type j (bits::find_s (data, size, i));
618
619            if (j != ro_string<C>::npos)
620            {
621              if (buf_.empty ())
622              {
623                ro_string<C> tmp (data + i, j - i); // Private copy ctor.
624                _xsd_parse_item (tmp);
625              }
626              else
627              {
628                // Assemble the first item in str from buf_ and s.
629                //
630                std::basic_string<C> str;
631                str.swap (buf_);
632                str.append (data + i, j - i);
633                ro_string<C> tmp (str); // Private copy ctor.
634                _xsd_parse_item (tmp);
635              }
636
637              i = bits::find_ns (data, size, j);
638            }
639            else
640            {
641              // Last fragment, append it to the buf_.
642              //
643              buf_.append (data + i, size - i);
644              break;
645            }
646          }
647        }
648
649        template <typename C>
650        void list_base<C>::
651        _post ()
652        {
653          // Handle the last item.
654          //
655          if (!buf_.empty ())
656          {
657            ro_string<C> tmp (buf_); // Private copy ctor.
658            _xsd_parse_item (tmp);
659          }
660        }
661      }
662    }
663  }
664}
Note: See TracBrowser for help on using the browser.