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

Revision 111, 12.7 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/non-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
10namespace xsd
11{
12  namespace cxx
13  {
14    namespace parser
15    {
16      namespace non_validating
17      {
18
19        // empty_content
20        //
21
22        template <typename C>
23        void empty_content<C>::
24        _start_any_element (const ro_string<C>&,
25                            const ro_string<C>&,
26                            const ro_string<C>*)
27        {
28        }
29
30        template <typename C>
31        void empty_content<C>::
32        _end_any_element (const ro_string<C>&,
33                          const ro_string<C>&)
34        {
35        }
36
37        template <typename C>
38        void empty_content<C>::
39        _any_attribute (const ro_string<C>&,
40                        const ro_string<C>&,
41                        const ro_string<C>&)
42        {
43        }
44
45        template <typename C>
46        void empty_content<C>::
47        _any_characters (const ro_string<C>&)
48        {
49        }
50
51        //
52        //
53        template <typename C>
54        bool empty_content<C>::
55        _start_element_impl (const ro_string<C>&,
56                             const ro_string<C>&,
57                             const ro_string<C>*)
58        {
59          return false;
60        }
61
62        template <typename C>
63        bool empty_content<C>::
64        _end_element_impl (const ro_string<C>&,
65                           const ro_string<C>&)
66        {
67          return false;
68        }
69
70        template <typename C>
71        bool empty_content<C>::
72        _attribute_impl (const ro_string<C>&,
73                         const ro_string<C>&,
74                         const ro_string<C>&)
75        {
76          return false;
77        }
78
79        template <typename C>
80        bool empty_content<C>::
81        _characters_impl (const ro_string<C>&)
82        {
83          return false;
84        }
85
86        template <typename C>
87        void empty_content<C>::
88        _start_element (const ro_string<C>& ns,
89                        const ro_string<C>& name,
90                        const ro_string<C>* type)
91        {
92          if (!_start_element_impl (ns, name, type))
93            _start_any_element (ns, name, type);
94        }
95
96        template <typename C>
97        void empty_content<C>::
98        _end_element (const ro_string<C>& ns,
99                      const ro_string<C>& name)
100        {
101          if (!_end_element_impl (ns, name))
102            _end_any_element (ns, name);
103        }
104
105        template <typename C>
106        void empty_content<C>::
107        _attribute (const ro_string<C>& ns,
108                    const ro_string<C>& name,
109                    const ro_string<C>& value)
110        {
111          // Weed out special attributes: xsi:type, xsi:nil,
112          // xsi:schemaLocation and noNamespaceSchemaLocation.
113          // See section 3.2.7 in Structures for details.
114          //
115          if (ns == xml::bits::xsi_namespace<C> () &&
116              (name == xml::bits::type<C> () ||
117               name == xml::bits::nil<C> () ||
118               name == xml::bits::schema_location<C> () ||
119               name == xml::bits::no_namespace_schema_location<C> ()))
120            return;
121
122          // Also some parsers (notably Xerces-C++) supplies us with
123          // namespace-prefix mapping attributes.
124          //
125          if (ns == xml::bits::xmlns_namespace<C> ())
126            return;
127
128          if (!_attribute_impl (ns, name, value))
129            _any_attribute (ns, name, value);
130        }
131
132        template <typename C>
133        void empty_content<C>::
134        _characters (const ro_string<C>& s)
135        {
136          if (!_characters_impl (s))
137            _any_characters (s);
138        }
139
140
141        // simple_content
142        //
143
144        template <typename C>
145        void simple_content<C>::
146        _attribute (const ro_string<C>& ns,
147                    const ro_string<C>& name,
148                    const ro_string<C>& value)
149        {
150          // Weed out special attributes: xsi:type, xsi:nil,
151          // xsi:schemaLocation and xsi:noNamespaceSchemaLocation.
152          // See section 3.2.7 in Structures for details.
153          //
154          if (ns == xml::bits::xsi_namespace<C> () &&
155              (name == xml::bits::type<C> () ||
156               name == xml::bits::nil<C> () ||
157               name == xml::bits::schema_location<C> () ||
158               name == xml::bits::no_namespace_schema_location<C> ()))
159            return;
160
161          // Also some parsers (notably Xerces-C++) supplies us with
162          // namespace-prefix mapping attributes.
163          //
164          if (ns == xml::bits::xmlns_namespace<C> ())
165            return;
166
167          if (!_attribute_impl (ns, name, value))
168            _any_attribute (ns, name, value);
169        }
170
171        template <typename C>
172        void simple_content<C>::
173        _characters (const ro_string<C>& str)
174        {
175          _characters_impl (str);
176        }
177
178
179        // complex_content
180        //
181
182        template <typename C>
183        void complex_content<C>::
184        _start_element (const ro_string<C>& ns,
185                        const ro_string<C>& name,
186                        const ro_string<C>* type)
187        {
188          state& s (context_.top ());
189
190          if (s.depth_++ > 0)
191          {
192            if (s.any_)
193              _start_any_element (ns, name, type);
194            else if (s.parser_)
195              s.parser_->_start_element (ns, name, type);
196          }
197          else
198          {
199            if (!_start_element_impl (ns, name, type))
200            {
201              _start_any_element (ns, name, type);
202              s.any_ = true;
203            }
204            else if (s.parser_ != 0)
205              s.parser_->_pre_impl ();
206          }
207        }
208
209        template <typename C>
210        void complex_content<C>::
211        _end_element (const ro_string<C>& ns,
212                      const ro_string<C>& name)
213        {
214          // To understand what's going on here it is helpful to think of
215          // a "total depth" as being the sum of individual depths over
216          // all elements.
217          //
218
219          if (context_.top ().depth_ == 0)
220          {
221            state& s (context_.under_top ()); // One before last.
222
223            if (--s.depth_ > 0)
224            {
225              // Indirect recursion.
226              //
227              if (s.parser_)
228                s.parser_->_end_element (ns, name);
229            }
230            else
231            {
232              // Direct recursion.
233              //
234              assert (this == s.parser_);
235
236              this->_post_impl ();
237
238              if (!_end_element_impl (ns, name))
239                assert (false);
240            }
241          }
242          else
243          {
244            state& s (context_.top ());
245
246            if (--s.depth_ > 0)
247            {
248              if (s.any_)
249                _end_any_element (ns, name);
250              else if (s.parser_)
251                s.parser_->_end_element (ns, name);
252            }
253            else
254            {
255              if (s.parser_ != 0 && !s.any_)
256                s.parser_->_post_impl ();
257
258              if (!_end_element_impl (ns, name))
259              {
260                s.any_ = false;
261                _end_any_element (ns, name);
262              }
263            }
264          }
265        }
266
267        template <typename C>
268        void complex_content<C>::
269        _attribute (const ro_string<C>& ns,
270                    const ro_string<C>& name,
271                    const ro_string<C>& value)
272        {
273          // Weed out special attributes: xsi:type, xsi:nil,
274          // xsi:schemaLocation and xsi:noNamespaceSchemaLocation.
275          // See section 3.2.7 in Structures for details.
276          //
277          if (ns == xml::bits::xsi_namespace<C> () &&
278              (name == xml::bits::type<C> () ||
279               name == xml::bits::nil<C> () ||
280               name == xml::bits::schema_location<C> () ||
281               name == xml::bits::no_namespace_schema_location<C> ()))
282            return;
283
284          // Also some parsers (notably Xerces-C++) supplies us with
285          // namespace-prefix mapping attributes.
286          //
287          if (ns == xml::bits::xmlns_namespace<C> ())
288            return;
289
290          state& s (context_.top ());
291
292          if (s.depth_ > 0)
293          {
294            if (s.any_)
295              _any_attribute (ns, name, value);
296            else if (s.parser_)
297              s.parser_->_attribute (ns, name, value);
298          }
299          else
300          {
301            if (!_attribute_impl (ns, name, value))
302              _any_attribute (ns, name, value);
303          }
304        }
305
306        template <typename C>
307        void complex_content<C>::
308        _characters (const ro_string<C>& str)
309        {
310          state& s (context_.top ());
311
312          if (s.depth_ > 0)
313          {
314            if (s.any_)
315              _any_characters (str);
316            else if (s.parser_)
317              s.parser_->_characters (str);
318          }
319          else
320          {
321            if (!_characters_impl (str))
322              _any_characters (str);
323          }
324        }
325
326        template <typename C>
327        void complex_content<C>::
328        _pre_impl ()
329        {
330          context_.push (state ());
331          this->_pre ();
332        }
333
334        template <typename C>
335        void complex_content<C>::
336        _post_impl ()
337        {
338          this->_post ();
339          context_.pop ();
340        }
341
342        // list_base
343        //
344        namespace bits
345        {
346          // Find first non-space character.
347          //
348          template <typename C>
349          typename ro_string<C>::size_type
350          find_ns (const C* s,
351                   typename ro_string<C>::size_type size,
352                   typename ro_string<C>::size_type pos)
353          {
354            while (pos < size &&
355                   (s[pos] == C (0x20) || s[pos] == C (0x0A) ||
356                    s[pos] == C (0x0D) || s[pos] == C (0x09)))
357              ++pos;
358
359            return pos < size ? pos : ro_string<C>::npos;
360          }
361
362          // Find first space character.
363          //
364          template <typename C>
365          typename ro_string<C>::size_type
366          find_s (const C* s,
367                  typename ro_string<C>::size_type size,
368                  typename ro_string<C>::size_type pos)
369          {
370            while (pos < size &&
371                   s[pos] != C (0x20) && s[pos] != C (0x0A) &&
372                   s[pos] != C (0x0D) && s[pos] != C (0x09))
373              ++pos;
374
375            return pos < size ? pos : ro_string<C>::npos;
376          }
377        }
378
379        // Relevant XML Schema Part 2: Datatypes sections: 4.2.1.2, 4.3.6.
380        //
381
382        template <typename C>
383        void list_base<C>::
384        _pre ()
385        {
386          buf_.clear ();
387        }
388
389        template <typename C>
390        void list_base<C>::
391        _characters (const ro_string<C>& s)
392        {
393          typedef typename ro_string<C>::size_type size_type;
394
395          const C* data (s.data ());
396          size_type size (s.size ());
397
398          // Handle the previous chunk if we start with a ws.
399          //
400          if (!buf_.empty () &&
401              (data[0] == C (0x20) || data[0] == C (0x0A) ||
402               data[0] == C (0x0D) || data[0] == C (0x09)))
403          {
404            ro_string<C> tmp (buf_); // Private copy ctor.
405            _xsd_parse_item (tmp);
406            buf_.clear ();
407          }
408
409          // Traverse the data while logically collapsing spaces.
410          //
411          for (size_type i (bits::find_ns (data, size, 0));
412               i != ro_string<C>::npos;)
413          {
414            size_type j (bits::find_s (data, size, i));
415
416            if (j != ro_string<C>::npos)
417            {
418              if (buf_.empty ())
419              {
420                ro_string<C> tmp (data + i, j - i); // Private copy ctor.
421                _xsd_parse_item (tmp);
422              }
423              else
424              {
425                // Assemble the first item in str from buf_ and s.
426                //
427                std::basic_string<C> str;
428                str.swap (buf_);
429                str.append (data + i, j - i);
430                ro_string<C> tmp (str); // Private copy ctor.
431                _xsd_parse_item (tmp);
432              }
433
434              i = bits::find_ns (data, size, j);
435            }
436            else
437            {
438              // Last fragment, append it to the buf_.
439              //
440              buf_.append (data + i, size - i);
441              break;
442            }
443          }
444        }
445
446        template <typename C>
447        void list_base<C>::
448        _post ()
449        {
450          // Handle the last item.
451          //
452          if (!buf_.empty ())
453          {
454            ro_string<C> tmp (buf_); // Private copy ctor.
455            _xsd_parse_item (tmp);
456          }
457        }
458      }
459    }
460  }
461}
Note: See TracBrowser for help on using the browser.