summaryrefslogtreecommitdiff
path: root/libxsd/xsd/cxx/parser/non-validating/parser.txx
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2009-09-17 07:15:29 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2009-09-17 07:15:29 +0200
commitf0510d2f90467de8e8f260b47d79a9baaf9bef17 (patch)
tree0b9929946f06a9cbe9b9e8f2a7600dae4e048f79 /libxsd/xsd/cxx/parser/non-validating/parser.txx
Start tracking XSD with git
Diffstat (limited to 'libxsd/xsd/cxx/parser/non-validating/parser.txx')
-rw-r--r--libxsd/xsd/cxx/parser/non-validating/parser.txx464
1 files changed, 464 insertions, 0 deletions
diff --git a/libxsd/xsd/cxx/parser/non-validating/parser.txx b/libxsd/xsd/cxx/parser/non-validating/parser.txx
new file mode 100644
index 0000000..d379d7a
--- /dev/null
+++ b/libxsd/xsd/cxx/parser/non-validating/parser.txx
@@ -0,0 +1,464 @@
+// file : xsd/cxx/parser/non-validating/parser.txx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <cassert>
+
+#include <xsd/cxx/xml/bits/literals.hxx>
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace parser
+ {
+ namespace non_validating
+ {
+
+ // empty_content
+ //
+
+ template <typename C>
+ void empty_content<C>::
+ _start_any_element (const ro_string<C>&,
+ const ro_string<C>&,
+ const ro_string<C>*)
+ {
+ }
+
+ template <typename C>
+ void empty_content<C>::
+ _end_any_element (const ro_string<C>&,
+ const ro_string<C>&)
+ {
+ }
+
+ template <typename C>
+ void empty_content<C>::
+ _any_attribute (const ro_string<C>&,
+ const ro_string<C>&,
+ const ro_string<C>&)
+ {
+ }
+
+ template <typename C>
+ void empty_content<C>::
+ _any_characters (const ro_string<C>&)
+ {
+ }
+
+ //
+ //
+ template <typename C>
+ bool empty_content<C>::
+ _start_element_impl (const ro_string<C>&,
+ const ro_string<C>&,
+ const ro_string<C>*)
+ {
+ return false;
+ }
+
+ template <typename C>
+ bool empty_content<C>::
+ _end_element_impl (const ro_string<C>&,
+ const ro_string<C>&)
+ {
+ return false;
+ }
+
+ template <typename C>
+ bool empty_content<C>::
+ _attribute_impl (const ro_string<C>&,
+ const ro_string<C>&,
+ const ro_string<C>&)
+ {
+ return false;
+ }
+
+ template <typename C>
+ bool empty_content<C>::
+ _characters_impl (const ro_string<C>&)
+ {
+ return false;
+ }
+
+ template <typename C>
+ void empty_content<C>::
+ _start_element (const ro_string<C>& ns,
+ const ro_string<C>& name,
+ const ro_string<C>* type)
+ {
+ if (!_start_element_impl (ns, name, type))
+ _start_any_element (ns, name, type);
+ }
+
+ template <typename C>
+ void empty_content<C>::
+ _end_element (const ro_string<C>& ns,
+ const ro_string<C>& name)
+ {
+ if (!_end_element_impl (ns, name))
+ _end_any_element (ns, name);
+ }
+
+ template <typename C>
+ void empty_content<C>::
+ _attribute (const ro_string<C>& ns,
+ const ro_string<C>& name,
+ const ro_string<C>& value)
+ {
+ // Weed out special attributes: xsi:type, xsi:nil,
+ // xsi:schemaLocation and noNamespaceSchemaLocation.
+ // See section 3.2.7 in Structures for details.
+ //
+ if (ns == xml::bits::xsi_namespace<C> () &&
+ (name == xml::bits::type<C> () ||
+ name == xml::bits::nil<C> () ||
+ name == xml::bits::schema_location<C> () ||
+ name == xml::bits::no_namespace_schema_location<C> ()))
+ return;
+
+ // Also some parsers (notably Xerces-C++) supplies us with
+ // namespace-prefix mapping attributes.
+ //
+ if (ns == xml::bits::xmlns_namespace<C> ())
+ return;
+
+ if (!_attribute_impl (ns, name, value))
+ _any_attribute (ns, name, value);
+ }
+
+ template <typename C>
+ void empty_content<C>::
+ _characters (const ro_string<C>& s)
+ {
+ if (!_characters_impl (s))
+ _any_characters (s);
+ }
+
+
+ // simple_content
+ //
+
+ template <typename C>
+ void simple_content<C>::
+ _attribute (const ro_string<C>& ns,
+ const ro_string<C>& name,
+ const ro_string<C>& value)
+ {
+ // Weed out special attributes: xsi:type, xsi:nil,
+ // xsi:schemaLocation and xsi:noNamespaceSchemaLocation.
+ // See section 3.2.7 in Structures for details.
+ //
+ if (ns == xml::bits::xsi_namespace<C> () &&
+ (name == xml::bits::type<C> () ||
+ name == xml::bits::nil<C> () ||
+ name == xml::bits::schema_location<C> () ||
+ name == xml::bits::no_namespace_schema_location<C> ()))
+ return;
+
+ // Also some parsers (notably Xerces-C++) supplies us with
+ // namespace-prefix mapping attributes.
+ //
+ if (ns == xml::bits::xmlns_namespace<C> ())
+ return;
+
+ if (!_attribute_impl (ns, name, value))
+ _any_attribute (ns, name, value);
+ }
+
+ template <typename C>
+ void simple_content<C>::
+ _characters (const ro_string<C>& str)
+ {
+ _characters_impl (str);
+ }
+
+
+ // complex_content
+ //
+
+ template <typename C>
+ void complex_content<C>::
+ _start_element (const ro_string<C>& ns,
+ const ro_string<C>& name,
+ const ro_string<C>* type)
+ {
+ state& s (context_.top ());
+
+ if (s.depth_++ > 0)
+ {
+ if (s.any_)
+ _start_any_element (ns, name, type);
+ else if (s.parser_)
+ s.parser_->_start_element (ns, name, type);
+ }
+ else
+ {
+ if (!_start_element_impl (ns, name, type))
+ {
+ _start_any_element (ns, name, type);
+ s.any_ = true;
+ }
+ else if (s.parser_ != 0)
+ s.parser_->_pre_impl ();
+ }
+ }
+
+ template <typename C>
+ void complex_content<C>::
+ _end_element (const ro_string<C>& ns,
+ const ro_string<C>& name)
+ {
+ // To understand what's going on here it is helpful to think of
+ // a "total depth" as being the sum of individual depths over
+ // all elements.
+ //
+
+ if (context_.top ().depth_ == 0)
+ {
+ state& s (context_.under_top ()); // One before last.
+
+ if (--s.depth_ > 0)
+ {
+ // Indirect recursion.
+ //
+ if (s.parser_)
+ s.parser_->_end_element (ns, name);
+ }
+ else
+ {
+ // Direct recursion.
+ //
+ assert (this == s.parser_);
+
+ this->_post_impl ();
+
+ if (!_end_element_impl (ns, name))
+ assert (false);
+ }
+ }
+ else
+ {
+ state& s (context_.top ());
+
+ if (--s.depth_ > 0)
+ {
+ if (s.any_)
+ _end_any_element (ns, name);
+ else if (s.parser_)
+ s.parser_->_end_element (ns, name);
+ }
+ else
+ {
+ if (s.parser_ != 0 && !s.any_)
+ s.parser_->_post_impl ();
+
+ if (!_end_element_impl (ns, name))
+ {
+ s.any_ = false;
+ _end_any_element (ns, name);
+ }
+ }
+ }
+ }
+
+ template <typename C>
+ void complex_content<C>::
+ _attribute (const ro_string<C>& ns,
+ const ro_string<C>& name,
+ const ro_string<C>& value)
+ {
+ // Weed out special attributes: xsi:type, xsi:nil,
+ // xsi:schemaLocation and xsi:noNamespaceSchemaLocation.
+ // See section 3.2.7 in Structures for details.
+ //
+ if (ns == xml::bits::xsi_namespace<C> () &&
+ (name == xml::bits::type<C> () ||
+ name == xml::bits::nil<C> () ||
+ name == xml::bits::schema_location<C> () ||
+ name == xml::bits::no_namespace_schema_location<C> ()))
+ return;
+
+ // Also some parsers (notably Xerces-C++) supplies us with
+ // namespace-prefix mapping attributes.
+ //
+ if (ns == xml::bits::xmlns_namespace<C> ())
+ return;
+
+ state& s (context_.top ());
+
+ if (s.depth_ > 0)
+ {
+ if (s.any_)
+ _any_attribute (ns, name, value);
+ else if (s.parser_)
+ s.parser_->_attribute (ns, name, value);
+ }
+ else
+ {
+ if (!_attribute_impl (ns, name, value))
+ _any_attribute (ns, name, value);
+ }
+ }
+
+ template <typename C>
+ void complex_content<C>::
+ _characters (const ro_string<C>& str)
+ {
+ state& s (context_.top ());
+
+ if (s.depth_ > 0)
+ {
+ if (s.any_)
+ _any_characters (str);
+ else if (s.parser_)
+ s.parser_->_characters (str);
+ }
+ else
+ {
+ if (!_characters_impl (str))
+ _any_characters (str);
+ }
+ }
+
+ template <typename C>
+ void complex_content<C>::
+ _pre_impl ()
+ {
+ context_.push (state ());
+ this->_pre ();
+ }
+
+ template <typename C>
+ void complex_content<C>::
+ _post_impl ()
+ {
+ this->_post ();
+ context_.pop ();
+ }
+
+ // list_base
+ //
+ namespace bits
+ {
+ // Find first non-space character.
+ //
+ template <typename C>
+ typename ro_string<C>::size_type
+ find_ns (const C* s,
+ typename ro_string<C>::size_type size,
+ typename ro_string<C>::size_type pos)
+ {
+ while (pos < size &&
+ (s[pos] == C (0x20) || s[pos] == C (0x0A) ||
+ s[pos] == C (0x0D) || s[pos] == C (0x09)))
+ ++pos;
+
+ return pos < size ? pos : ro_string<C>::npos;
+ }
+
+ // Find first space character.
+ //
+ template <typename C>
+ typename ro_string<C>::size_type
+ find_s (const C* s,
+ typename ro_string<C>::size_type size,
+ typename ro_string<C>::size_type pos)
+ {
+ while (pos < size &&
+ s[pos] != C (0x20) && s[pos] != C (0x0A) &&
+ s[pos] != C (0x0D) && s[pos] != C (0x09))
+ ++pos;
+
+ return pos < size ? pos : ro_string<C>::npos;
+ }
+ }
+
+ // Relevant XML Schema Part 2: Datatypes sections: 4.2.1.2, 4.3.6.
+ //
+
+ template <typename C>
+ void list_base<C>::
+ _pre_impl ()
+ {
+ simple_content<C>::_pre_impl ();
+ buf_.clear ();
+ }
+
+ template <typename C>
+ void list_base<C>::
+ _characters (const ro_string<C>& s)
+ {
+ typedef typename ro_string<C>::size_type size_type;
+
+ const C* data (s.data ());
+ size_type size (s.size ());
+
+ // Handle the previous chunk if we start with a ws.
+ //
+ if (!buf_.empty () &&
+ (data[0] == C (0x20) || data[0] == C (0x0A) ||
+ data[0] == C (0x0D) || data[0] == C (0x09)))
+ {
+ ro_string<C> tmp (buf_); // Private copy ctor.
+ _xsd_parse_item (tmp);
+ buf_.clear ();
+ }
+
+ // Traverse the data while logically collapsing spaces.
+ //
+ for (size_type i (bits::find_ns (data, size, 0));
+ i != ro_string<C>::npos;)
+ {
+ size_type j (bits::find_s (data, size, i));
+
+ if (j != ro_string<C>::npos)
+ {
+ if (buf_.empty ())
+ {
+ ro_string<C> tmp (data + i, j - i); // Private copy ctor.
+ _xsd_parse_item (tmp);
+ }
+ else
+ {
+ // Assemble the first item in str from buf_ and s.
+ //
+ std::basic_string<C> str;
+ str.swap (buf_);
+ str.append (data + i, j - i);
+ ro_string<C> tmp (str); // Private copy ctor.
+ _xsd_parse_item (tmp);
+ }
+
+ i = bits::find_ns (data, size, j);
+ }
+ else
+ {
+ // Last fragment, append it to the buf_.
+ //
+ buf_.append (data + i, size - i);
+ break;
+ }
+ }
+ }
+
+ template <typename C>
+ void list_base<C>::
+ _post_impl ()
+ {
+ // Handle the last item.
+ //
+ if (!buf_.empty ())
+ {
+ ro_string<C> tmp (buf_); // Private copy ctor.
+ _xsd_parse_item (tmp);
+ }
+
+ simple_content<C>::_post_impl ();
+ }
+ }
+ }
+ }
+}