diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2009-09-17 07:15:29 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2009-09-17 07:15:29 +0200 |
commit | f0510d2f90467de8e8f260b47d79a9baaf9bef17 (patch) | |
tree | 0b9929946f06a9cbe9b9e8f2a7600dae4e048f79 /libxsd/xsd/cxx/parser |
Start tracking XSD with git
Diffstat (limited to 'libxsd/xsd/cxx/parser')
45 files changed, 19764 insertions, 0 deletions
diff --git a/libxsd/xsd/cxx/parser/document.hxx b/libxsd/xsd/cxx/parser/document.hxx new file mode 100644 index 0000000..dd8be4a --- /dev/null +++ b/libxsd/xsd/cxx/parser/document.hxx @@ -0,0 +1,90 @@ +// file : xsd/cxx/parser/document.hxx +// author : Boris Kolpackov <boris@codesynthesis.com> +// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSD_CXX_PARSER_DOCUMENT_HXX +#define XSD_CXX_PARSER_DOCUMENT_HXX + +#include <string> +#include <cstddef> // std::size_t + +#include <xsd/cxx/ro-string.hxx> +#include <xsd/cxx/parser/elements.hxx> + +namespace xsd +{ + namespace cxx + { + namespace parser + { + // If you want to use a different underlying XML parser, all you + // need to do is to route events to this interface. + // + template <typename C> + class document + { + public: + virtual + ~document (); + + document (parser_base<C>& root, + const std::basic_string<C>& ns, + const std::basic_string<C>& name); + + public: + // The type argument is a type name and namespace from the + // xsi:type attribute in the form "<name> <namespace>" with + // the space and namespace part absent if the type does not + // have a namespace or 0 if xsi:type is not present. + // + void + start_element (const ro_string<C>& ns, + const ro_string<C>& name, + const ro_string<C>* type); + + void + end_element (const ro_string<C>& ns, const ro_string<C>& name); + + void + attribute (const ro_string<C>& ns, + const ro_string<C>& name, + const ro_string<C>& value); + + void + characters (const ro_string<C>&); + + protected: + document (); + + // This function is called to obtain the root element type parser. + // If the returned pointed is 0 then the whole document content + // is ignored. + // + virtual parser_base<C>* + start_root_element (const ro_string<C>& ns, + const ro_string<C>& name, + const ro_string<C>* type); + + // This function is called to indicate the completion of document + // parsing. The parser argument contains the pointer returned by + // start_root_element. + // + virtual void + end_root_element (const ro_string<C>& ns, + const ro_string<C>& name, + parser_base<C>* parser); + + private: + parser_base<C>* root_; + std::basic_string<C> ns_; + std::basic_string<C> name_; + std::size_t depth_; + }; + } + } +} + +#include <xsd/cxx/parser/document.txx> + +#endif // XSD_CXX_PARSER_DOCUMENT_HXX diff --git a/libxsd/xsd/cxx/parser/document.txx b/libxsd/xsd/cxx/parser/document.txx new file mode 100644 index 0000000..451eb71 --- /dev/null +++ b/libxsd/xsd/cxx/parser/document.txx @@ -0,0 +1,129 @@ +// file : xsd/cxx/parser/document.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/parser/schema-exceptions.hxx> + +namespace xsd +{ + namespace cxx + { + namespace parser + { + // document + // + template <typename C> + document<C>:: + ~document () + { + } + + template <typename C> + document<C>:: + document (parser_base<C>& root, + const std::basic_string<C>& ns, + const std::basic_string<C>& name) + : root_ (&root), ns_ (ns), name_ (name), depth_ (0) + { + } + + template <typename C> + document<C>:: + document () + : root_ (0), depth_ (0) + { + } + + template <typename C> + void document<C>:: + start_element (const ro_string<C>& ns, + const ro_string<C>& name, + const ro_string<C>* type) + { + if (depth_++ > 0) + { + if (root_) + root_->_start_element (ns, name, type); + } + else + { + root_ = start_root_element (ns, name, type); + + if (root_) + { + // pre () is called by the user. + // + root_->_pre_impl (); + } + } + } + + template <typename C> + void document<C>:: + end_element (const ro_string<C>& ns, const ro_string<C>& name) + { + assert (depth_ > 0); + + if (--depth_ > 0) + { + if (root_) + root_->_end_element (ns, name); + } + else + { + if (root_) + { + root_->_post_impl (); + // + // post() is called by the user. + } + + end_root_element (ns, name, root_); + } + } + + template <typename C> + void document<C>:: + attribute (const ro_string<C>& ns, + const ro_string<C>& name, + const ro_string<C>& value) + { + if (root_) + root_->_attribute (ns, name, value); + } + + template <typename C> + void document<C>:: + characters (const ro_string<C>& s) + { + if (root_) + root_->_characters (s); + } + + template <typename C> + parser_base<C>* document<C>:: + start_root_element (const ro_string<C>& ns, + const ro_string<C>& name, + const ro_string<C>*) + { + if (name_ == name && ns_ == ns) + { + return root_; + } + else + throw expected_element<C> (ns_, name_, ns, name); + } + + template <typename C> + void document<C>:: + end_root_element (const ro_string<C>&, + const ro_string<C>&, + parser_base<C>*) + { + } + } + } +} diff --git a/libxsd/xsd/cxx/parser/elements.hxx b/libxsd/xsd/cxx/parser/elements.hxx new file mode 100644 index 0000000..e900189 --- /dev/null +++ b/libxsd/xsd/cxx/parser/elements.hxx @@ -0,0 +1,95 @@ +// file : xsd/cxx/parser/elements.hxx +// author : Boris Kolpackov <boris@codesynthesis.com> +// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSD_CXX_PARSER_ELEMENTS_HXX +#define XSD_CXX_PARSER_ELEMENTS_HXX + +#include <xsd/cxx/ro-string.hxx> + +namespace xsd +{ + namespace cxx + { + namespace parser + { + // pre() and post() are overridable pre/post callbacks, i.e., the + // derived parser can override them without calling the base version. + // _pre() and _post() are not overridable pre/post callbacks in the + // sense that the derived parser may override them but has to call + // the base version. The call sequence is as shown below: + // + // pre () + // _pre () + // _post () + // post () + // + template <typename C> + class parser_base + { + public: + virtual + ~parser_base (); + + virtual void + pre (); + + virtual void + _pre (); + + // The type argument is a type name and namespace from the + // xsi:type attribute in the form "<name> <namespace>" with + // the space and namespace part absent if the type does not + // have a namespace or 0 if xsi:type is not present. + // + virtual void + _start_element (const ro_string<C>& ns, + const ro_string<C>& name, + const ro_string<C>* type) = 0; + + virtual void + _end_element (const ro_string<C>& ns, + const ro_string<C>& name) = 0; + + virtual void + _attribute (const ro_string<C>& ns, + const ro_string<C>& name, + const ro_string<C>& value) = 0; + + virtual void + _characters (const ro_string<C>&) = 0; + + virtual void + _post (); + + // The post() signature varies depending on the parser return + // type. + // + + // Implementation callbacks for _pre and _post. The _pre and _post + // callbacks should never be called directly. Instead, the *_impl + // versions should be used. By default _pre_impl and _post_impl + // simply call _pre and _post respectively. + // + virtual void + _pre_impl (); + + virtual void + _post_impl (); + + public: + // Dynamic type in the form "<name> <namespace>" with + // the space and namespace part absent if the type does + // not have a namespace. Used in polymorphism-aware code. + // + virtual const C* + _dynamic_type () const; + }; + } + } +} + +#include <xsd/cxx/parser/elements.txx> + +#endif // XSD_CXX_PARSER_ELEMENTS_HXX diff --git a/libxsd/xsd/cxx/parser/elements.txx b/libxsd/xsd/cxx/parser/elements.txx new file mode 100644 index 0000000..3bfb7be --- /dev/null +++ b/libxsd/xsd/cxx/parser/elements.txx @@ -0,0 +1,60 @@ +// file : xsd/cxx/parser/elements.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 + +namespace xsd +{ + namespace cxx + { + namespace parser + { + // parser_base + // + template <typename C> + parser_base<C>:: + ~parser_base () + { + } + + template <typename C> + void parser_base<C>:: + pre () + { + } + + template <typename C> + void parser_base<C>:: + _pre () + { + } + + template <typename C> + void parser_base<C>:: + _post () + { + } + + template <typename C> + void parser_base<C>:: + _pre_impl () + { + _pre (); + } + + template <typename C> + void parser_base<C>:: + _post_impl () + { + _post (); + } + + template <typename C> + const C* parser_base<C>:: + _dynamic_type () const + { + return 0; + } + } + } +} diff --git a/libxsd/xsd/cxx/parser/error-handler.hxx b/libxsd/xsd/cxx/parser/error-handler.hxx new file mode 100644 index 0000000..b44974f --- /dev/null +++ b/libxsd/xsd/cxx/parser/error-handler.hxx @@ -0,0 +1,57 @@ +// file : xsd/cxx/parser/error-handler.hxx +// author : Boris Kolpackov <boris@codesynthesis.com> +// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSD_CXX_PARSER_ERROR_HANDLER_HXX +#define XSD_CXX_PARSER_ERROR_HANDLER_HXX + +#include <xsd/cxx/xml/error-handler.hxx> + +#include <xsd/cxx/parser/exceptions.hxx> + +namespace xsd +{ + namespace cxx + { + namespace parser + { + template <typename C> + class error_handler: public xml::error_handler<C> + { + typedef typename xml::error_handler<C>::severity severity; + + public: + error_handler () + : failed_ (false) + { + } + + virtual bool + handle (const std::basic_string<C>& id, + unsigned long line, + unsigned long column, + severity s, + const std::basic_string<C>& message); + + void + throw_if_failed () const; + + void + reset () + { + failed_ = false; + diagnostics_.clear (); + } + + private: + bool failed_; + diagnostics<C> diagnostics_; + }; + } + } +} + +#include <xsd/cxx/parser/error-handler.txx> + +#endif // XSD_CXX_PARSER_ERROR_HANDLER_HXX diff --git a/libxsd/xsd/cxx/parser/error-handler.txx b/libxsd/xsd/cxx/parser/error-handler.txx new file mode 100644 index 0000000..9b5feb7 --- /dev/null +++ b/libxsd/xsd/cxx/parser/error-handler.txx @@ -0,0 +1,41 @@ +// file : xsd/cxx/parser/error-handler.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 + +namespace xsd +{ + namespace cxx + { + namespace parser + { + template <typename C> + bool error_handler<C>:: + handle (const std::basic_string<C>& id, + unsigned long line, + unsigned long column, + severity s, + const std::basic_string<C>& message) + { + diagnostics_.push_back ( + error<C> (s == severity::warning + ? cxx::parser::severity::warning + : cxx::parser::severity::error, + id, line, column, message)); + + if (!failed_ && s != severity::warning) + failed_ = true; + + return true; + } + + template <typename C> + void error_handler<C>:: + throw_if_failed () const + { + if (failed_) + throw parsing<C> (diagnostics_); + } + } + } +} diff --git a/libxsd/xsd/cxx/parser/exceptions.hxx b/libxsd/xsd/cxx/parser/exceptions.hxx new file mode 100644 index 0000000..a19fb7d --- /dev/null +++ b/libxsd/xsd/cxx/parser/exceptions.hxx @@ -0,0 +1,153 @@ +// file : xsd/cxx/parser/exceptions.hxx +// author : Boris Kolpackov <boris@codesynthesis.com> +// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSD_CXX_PARSER_EXCEPTIONS_HXX +#define XSD_CXX_PARSER_EXCEPTIONS_HXX + +#include <string> +#include <vector> +#include <ostream> + +#include <xsd/cxx/exceptions.hxx> // xsd::cxx::exception +#include <xsd/cxx/ro-string.hxx> + +namespace xsd +{ + namespace cxx + { + namespace parser + { + // + // + template <typename C> + struct exception: xsd::cxx::exception + { + friend + std::basic_ostream<C>& + operator<< (std::basic_ostream<C>& os, const exception& e) + { + e.print (os); + return os; + } + + protected: + virtual void + print (std::basic_ostream<C>&) const = 0; + }; + + + // + // + struct severity + { + enum value + { + warning, + error + }; + + severity (value v) : v_ (v) {} + operator value () const { return v_; } + + private: + value v_; + }; + + template <typename C> + struct error + { + error (cxx::parser::severity, + const std::basic_string<C>& id, + unsigned long line, + unsigned long column, + const std::basic_string<C>& message); + + cxx::parser::severity + severity () const + { + return severity_; + } + + const std::basic_string<C>& + id () const + { + return id_; + } + + unsigned long + line () const + { + return line_; + } + + unsigned long + column () const + { + return column_; + } + + const std::basic_string<C>& + message () const + { + return message_; + } + + private: + cxx::parser::severity severity_; + std::basic_string<C> id_; + unsigned long line_; + unsigned long column_; + std::basic_string<C> message_; + }; + + // See exceptions.ixx for operator<< (error). + + + // + // + template <typename C> + struct diagnostics: std::vector<error<C> > + { + }; + + // See exceptions.ixx for operator<< (diagnostics). + + // + // + template <typename C> + struct parsing: exception<C> + { + virtual + ~parsing () throw (); + + parsing (); + + parsing (const cxx::parser::diagnostics<C>&); + + const cxx::parser::diagnostics<C>& + diagnostics () const + { + return diagnostics_; + } + + virtual const char* + what () const throw (); + + protected: + virtual void + print (std::basic_ostream<C>&) const; + + private: + cxx::parser::diagnostics<C> diagnostics_; + }; + } + } +} + +#include <xsd/cxx/parser/exceptions.txx> + +#endif // XSD_CXX_PARSER_EXCEPTIONS_HXX + +#include <xsd/cxx/parser/exceptions.ixx> diff --git a/libxsd/xsd/cxx/parser/exceptions.ixx b/libxsd/xsd/cxx/parser/exceptions.ixx new file mode 100644 index 0000000..b583ed0 --- /dev/null +++ b/libxsd/xsd/cxx/parser/exceptions.ixx @@ -0,0 +1,129 @@ +// file : xsd/cxx/parser/exceptions.ixx +// author : Boris Kolpackov <boris@codesynthesis.com> +// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#if defined(XSD_CXX_PARSER_USE_CHAR) || !defined(XSD_CXX_PARSER_USE_WCHAR) + +#ifndef XSD_CXX_PARSER_EXCEPTIONS_IXX_CHAR +#define XSD_CXX_PARSER_EXCEPTIONS_IXX_CHAR + +namespace xsd +{ + namespace cxx + { + namespace parser + { + // error + // + inline + std::basic_ostream<char>& + operator<< (std::basic_ostream<char>& os, const error<char>& e) + { + return os << e.id () << ':' << e.line () << ':' << e.column () + << (e.severity () == severity::error + ? " error: " + : " warning: ") << e.message (); + } + + + // diagnostics + // + inline + std::basic_ostream<char>& + operator<< (std::basic_ostream<char>& os, const diagnostics<char>& d) + { + for (diagnostics<char>::const_iterator b (d.begin ()), i (b); + i != d.end (); + ++i) + { + if (i != b) + os << "\n"; + + os << *i; + } + + return os; + } + + // parsing + // + template<> + inline + void parsing<char>:: + print (std::basic_ostream<char>& os) const + { + if (diagnostics_.empty ()) + os << "instance document parsing failed"; + else + os << diagnostics_; + } + } + } +} + +#endif // XSD_CXX_PARSER_EXCEPTIONS_IXX_CHAR +#endif // XSD_CXX_PARSER_USE_CHAR + + +#if defined(XSD_CXX_PARSER_USE_WCHAR) || !defined(XSD_CXX_PARSER_USE_CHAR) + +#ifndef XSD_CXX_PARSER_EXCEPTIONS_IXX_WCHAR +#define XSD_CXX_PARSER_EXCEPTIONS_IXX_WCHAR + +namespace xsd +{ + namespace cxx + { + namespace parser + { + // error + // + inline + std::basic_ostream<wchar_t>& + operator<< (std::basic_ostream<wchar_t>& os, const error<wchar_t>& e) + { + return os << e.id () << L':' << e.line () << L':' << e.column () + << (e.severity () == severity::error + ? L" error: " + : L" warning: ") << e.message (); + } + + // diagnostics + // + inline + std::basic_ostream<wchar_t>& + operator<< (std::basic_ostream<wchar_t>& os, + const diagnostics<wchar_t>& d) + { + for (diagnostics<wchar_t>::const_iterator b (d.begin ()), i (b); + i != d.end (); + ++i) + { + if (i != b) + os << L"\n"; + + os << *i; + } + + return os; + } + + // parsing + // + template<> + inline + void parsing<wchar_t>:: + print (std::basic_ostream<wchar_t>& os) const + { + if (diagnostics_.empty ()) + os << L"instance document parsing failed"; + else + os << diagnostics_; + } + } + } +} + +#endif // XSD_CXX_PARSER_EXCEPTIONS_IXX_WCHAR +#endif // XSD_CXX_PARSER_USE_WCHAR diff --git a/libxsd/xsd/cxx/parser/exceptions.txx b/libxsd/xsd/cxx/parser/exceptions.txx new file mode 100644 index 0000000..ddb20b0 --- /dev/null +++ b/libxsd/xsd/cxx/parser/exceptions.txx @@ -0,0 +1,59 @@ +// file : xsd/cxx/parser/exceptions.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 + +namespace xsd +{ + namespace cxx + { + namespace parser + { + // error + // + template <typename C> + error<C>:: + error (cxx::parser::severity s, + const std::basic_string<C>& id, + unsigned long line, + unsigned long column, + const std::basic_string<C>& message) + : severity_ (s), + id_ (id), + line_ (line), + column_ (column), + message_ (message) + { + } + + + // parsing + // + template <typename C> + parsing<C>:: + ~parsing () throw () + { + } + + template <typename C> + parsing<C>:: + parsing () + { + } + + template <typename C> + parsing<C>:: + parsing (const cxx::parser::diagnostics<C>& diagnostics) + : diagnostics_ (diagnostics) + { + } + + template <typename C> + const char* parsing<C>:: + what () const throw () + { + return "instance document parsing failed"; + } + } + } +} diff --git a/libxsd/xsd/cxx/parser/expat/elements.hxx b/libxsd/xsd/cxx/parser/expat/elements.hxx new file mode 100644 index 0000000..a0de3e3 --- /dev/null +++ b/libxsd/xsd/cxx/parser/expat/elements.hxx @@ -0,0 +1,344 @@ +// file : xsd/cxx/parser/expat/elements.hxx +// author : Boris Kolpackov <boris@codesynthesis.com> +// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSD_CXX_PARSER_EXPAT_ELEMENTS_HXX +#define XSD_CXX_PARSER_EXPAT_ELEMENTS_HXX + +#include <string> +#include <iosfwd> +#include <cstddef> // std::size_t +#include <vector> + +#include <expat.h> + +// We only support UTF-8 expat for now. +// +#ifdef XML_UNICODE +#error UTF-16 expat (XML_UNICODE defined) is not supported +#endif + +#include <xsd/cxx/xml/error-handler.hxx> + +#include <xsd/cxx/parser/exceptions.hxx> +#include <xsd/cxx/parser/elements.hxx> +#include <xsd/cxx/parser/document.hxx> +#include <xsd/cxx/parser/error-handler.hxx> +#include <xsd/cxx/parser/schema-exceptions.hxx> + +namespace xsd +{ + namespace cxx + { + namespace parser + { + namespace expat + { + // Simple auto pointer for Expat's XML_Parser object. + // + struct parser_auto_ptr + { + ~parser_auto_ptr () + { + if (parser_ != 0) + XML_ParserFree (parser_); + } + + explicit + parser_auto_ptr (XML_Parser parser = 0) + : parser_ (parser) + { + } + + parser_auto_ptr& + operator= (XML_Parser parser) + { + if (parser_ != 0) + XML_ParserFree (parser_); + + parser_ = parser; + return *this; + } + + public: + operator XML_Parser () + { + return parser_; + } + + private: + parser_auto_ptr (const parser_auto_ptr&); + + parser_auto_ptr& + operator= (const parser_auto_ptr&); + + private: + XML_Parser parser_; + }; + + + // + // + template <typename C> + struct document: cxx::parser::document<C> // VC 7.1 likes it qualified + { + public: + document (parser_base<C>&, + const C* root_element_name, + bool polymorphic = false); + + document (parser_base<C>&, + const std::basic_string<C>& root_element_name, + bool polymorphic = false); + + document (parser_base<C>&, + const C* root_element_namespace, + const C* root_element_name, + bool polymorphic = false); + + document (parser_base<C>&, + const std::basic_string<C>& root_element_namespace, + const std::basic_string<C>& root_element_name, + bool polymorphic = false); + + protected: + document (bool polymorphic = false); + + public: + // Parse a local file. The file is accessed with std::ifstream + // in binary mode. The std::ios_base::failure exception is used + // to report io errors (badbit and failbit). + void + parse (const std::basic_string<C>& file); + + // Parse a local file with a user-provided error_handler + // object. The file is accessed with std::ifstream in binary + // mode. The std::ios_base::failure exception is used to report + // io errors (badbit and failbit). + // + void + parse (const std::basic_string<C>& file, xml::error_handler<C>&); + + public: + // System id is a "system" identifier of the resources (e.g., + // URI or a full file path). Public id is a "public" identifier + // of the resource (e.g., application-specific name or relative + // file path). System id is used to resolve relative paths. + // In diagnostics messages system id is used if public id is + // not available. Otherwise public id is used. + // + + // Parse std::istream. + // + void + parse (std::istream&); + + // Parse std::istream with a user-provided error_handler object. + // + void + parse (std::istream&, xml::error_handler<C>&); + + // Parse std::istream with a system id. + // + void + parse (std::istream&, const std::basic_string<C>& system_id); + + // Parse std::istream with a system id and a user-provided + // error_handler object. + // + void + parse (std::istream&, + const std::basic_string<C>& system_id, + xml::error_handler<C>&); + + // Parse std::istream with system and public ids. + // + void + parse (std::istream&, + const std::basic_string<C>& system_id, + const std::basic_string<C>& public_id); + + // Parse std::istream with system and public ids and a user-provided + // error_handler object. + // + void + parse (std::istream&, + const std::basic_string<C>& system_id, + const std::basic_string<C>& public_id, + xml::error_handler<C>&); + + public: + // Parse a chunk of input. You can call these functions multiple + // times with the last call having the last argument true. + // + void + parse (const void* data, std::size_t size, bool last); + + void + parse (const void* data, std::size_t size, bool last, + xml::error_handler<C>&); + + void + parse (const void* data, std::size_t size, bool last, + const std::basic_string<C>& system_id); + + void + parse (const void* data, std::size_t size, bool last, + const std::basic_string<C>& system_id, + xml::error_handler<C>&); + + void + parse (const void* data, std::size_t size, bool last, + const std::basic_string<C>& system_id, + const std::basic_string<C>& public_id); + + void + parse (const void* data, std::size_t size, bool last, + const std::basic_string<C>& system_id, + const std::basic_string<C>& public_id, + xml::error_handler<C>&); + + public: + // Low-level Expat-specific parsing API. A typical use case + // would look like this (pseudo-code): + // + // xxx_pimpl root; + // document doc (root, "root"); + // + // root.pre (); + // doc.parse_begin (xml_parser, "file.xml"); + // + // while (more_stuff_to_parse &&) + // { + // // Call XML_Parse or XML_ParseBuffer. + // + // if (status == XML_STATUS_ERROR) + // break; + // } + // + // // Call parse_end even in case of an error to translate + // // XML and Schema errors to exceptions or error_handler + // // calls. + // // + // doc.parse_end (); + // result_type result (root.post_xxx ()); + // + // Notes: + // + // 1. If your XML instances use XML namespaces, the + // XML_ParserCreateNS functions should be used to create the + // XML parser. Space (XML_Char (' ')) should be used as a + // separator (the second argument to XML_ParserCreateNS). + // + void + parse_begin (XML_Parser); + + void + parse_begin (XML_Parser, const std::basic_string<C>& public_id); + + void + parse_begin (XML_Parser, xml::error_handler<C>&); + + void + parse_begin (XML_Parser, + const std::basic_string<C>& public_id, + xml::error_handler<C>&); + void + parse_end (); + + // Event routing. + // + public: + static void XMLCALL + start_element_thunk_ (void*, const XML_Char*, const XML_Char**); + + static void XMLCALL + end_element_thunk_ (void*, const XML_Char*); + + static void XMLCALL + characters_thunk_ (void*, const XML_Char*, int); + + static void XMLCALL + start_namespace_decl_thunk_ ( + void*, const XML_Char*, const XML_Char*); + + static void XMLCALL + end_namespace_decl_thunk_ (void*, const XML_Char*); + + protected: + void + start_element_ (const XML_Char* ns_name, const XML_Char** atts); + + void + end_element_ (const XML_Char* ns_name); + + void + characters_ (const XML_Char* s, std::size_t n); + + void + start_namespace_decl_ (const XML_Char* prefix, const XML_Char* ns); + + void + end_namespace_decl_ (const XML_Char* prefix); + + protected: + void + set (); + + void + clear (); + + bool + parse (std::istream&, + const std::basic_string<C>* system_id, + const std::basic_string<C>* public_id, + xml::error_handler<C>&); + + bool + parse (const void* data, std::size_t size, bool last, + const std::basic_string<C>* system_id, + const std::basic_string<C>* public_id, + xml::error_handler<C>&); + + + void + translate_schema_exception (const schema_exception<C>& e); + + protected: + XML_Parser xml_parser_; + parser_auto_ptr auto_xml_parser_; + + xml::error_handler<C>* eh_; + error_handler<C> default_eh_; + std::basic_string<C> public_id_; + + bool polymorphic_; + + // Namespace-prefix mapping. Only maintained in the polymorphic + // case. + // + struct ns_decl + { + ns_decl (const std::basic_string<C>& p, + const std::basic_string<C>& n) + : prefix (p), ns (n) + { + } + + std::basic_string<C> prefix; + std::basic_string<C> ns; + }; + + typedef std::vector<ns_decl> ns_decls; + + ns_decls ns_decls_; + }; + } + } + } +} + +#include <xsd/cxx/parser/expat/elements.txx> + +#endif // XSD_CXX_PARSER_EXPAT_ELEMENTS_HXX diff --git a/libxsd/xsd/cxx/parser/expat/elements.txx b/libxsd/xsd/cxx/parser/expat/elements.txx new file mode 100644 index 0000000..5a60eb5 --- /dev/null +++ b/libxsd/xsd/cxx/parser/expat/elements.txx @@ -0,0 +1,822 @@ +// file : xsd/cxx/parser/expat/elements.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 <new> // std::bad_alloc +#include <istream> +#include <fstream> +#include <cstring> // std::strchr +#include <cassert> + +#include <xsd/cxx/xml/bits/literals.hxx> // xml::bits::{xml_prefix, etc} + +namespace xsd +{ + namespace cxx + { + namespace parser + { + namespace expat + { + + // document + // + + template <typename C> + document<C>:: + document (parser_base<C>& p, + const std::basic_string<C>& name, + bool polymorphic) + : cxx::parser::document<C> (p, std::basic_string<C> (), name), + xml_parser_ (0), + eh_ (0), + polymorphic_ (polymorphic) + { + } + + template <typename C> + document<C>:: + document (parser_base<C>& p, + const C* name, + bool polymorphic) + : cxx::parser::document<C> (p, std::basic_string<C> (), name), + xml_parser_ (0), + eh_ (0), + polymorphic_ (polymorphic) + { + } + + template <typename C> + document<C>:: + document (parser_base<C>& p, + const C* ns, + const C* name, + bool polymorphic) + : cxx::parser::document<C> (p, ns, name), + xml_parser_ (0), + eh_ (0), + polymorphic_ (polymorphic) + { + } + + template <typename C> + document<C>:: + document (parser_base<C>& p, + const std::basic_string<C>& ns, + const std::basic_string<C>& name, + bool polymorphic) + : cxx::parser::document<C> (p, ns, name), + xml_parser_ (0), + eh_ (0), + polymorphic_ (polymorphic) + { + } + + template <typename C> + document<C>:: + document (bool polymorphic) + : xml_parser_ (0), + eh_ (0), + polymorphic_ (polymorphic) + { + } + + // file + // + + template <typename C> + void document<C>:: + parse (const std::basic_string<C>& file) + { + std::ifstream ifs; + ifs.exceptions (std::ios_base::badbit | std::ios_base::failbit); + ifs.open (file.c_str (), std::ios_base::in | std::ios_base::binary); + + parse (ifs, file); + } + + template <typename C> + void document<C>:: + parse (const std::basic_string<C>& file, xml::error_handler<C>& eh) + { + std::ifstream ifs; + ifs.exceptions (std::ios_base::badbit | std::ios_base::failbit); + ifs.open (file.c_str (), std::ios_base::in | std::ios_base::binary); + + parse (ifs, file, eh); + } + + + // istream + // + + template <typename C> + void document<C>:: + parse (std::istream& is) + { + parse (is, 0, 0, default_eh_); + } + + template <typename C> + void document<C>:: + parse (std::istream& is, xml::error_handler<C>& eh) + { + if (!parse (is, 0, 0, eh)) + throw parsing<C> (); + } + + template <typename C> + void document<C>:: + parse (std::istream& is, const std::basic_string<C>& system_id) + { + default_eh_.reset (); + parse (is, &system_id, 0, default_eh_); + } + + template <typename C> + void document<C>:: + parse (std::istream& is, + const std::basic_string<C>& system_id, + xml::error_handler<C>& eh) + { + if (!parse (is, &system_id, 0, eh)) + throw parsing<C> (); + } + + template <typename C> + void document<C>:: + parse (std::istream& is, + const std::basic_string<C>& system_id, + const std::basic_string<C>& public_id) + { + default_eh_.reset (); + parse (is, &system_id, &public_id, default_eh_); + } + + template <typename C> + void document<C>:: + parse (std::istream& is, + const std::basic_string<C>& system_id, + const std::basic_string<C>& public_id, + xml::error_handler<C>& eh) + { + if (!parse (is, &system_id, &public_id, eh)) + throw parsing<C> (); + } + + // data + // + + template <typename C> + void document<C>:: + parse (const void* data, std::size_t size, bool last) + { + default_eh_.reset (); + parse (data, size, last, 0, 0, default_eh_); + } + + template <typename C> + void document<C>:: + parse (const void* data, std::size_t size, bool last, + xml::error_handler<C>& eh) + { + if (!parse (data, size, last, 0, 0, eh)) + throw parsing<C> (); + } + + template <typename C> + void document<C>:: + parse (const void* data, std::size_t size, bool last, + const std::basic_string<C>& system_id) + { + default_eh_.reset (); + parse (data, size, last, &system_id, 0, default_eh_); + } + + template <typename C> + void document<C>:: + parse (const void* data, std::size_t size, bool last, + const std::basic_string<C>& system_id, + xml::error_handler<C>& eh) + { + if (!parse (data, size, last, &system_id, 0, eh)) + throw parsing<C> (); + } + + template <typename C> + void document<C>:: + parse (const void* data, std::size_t size, bool last, + const std::basic_string<C>& system_id, + const std::basic_string<C>& public_id) + { + default_eh_.reset (); + parse (data, size, last, &system_id, &public_id, default_eh_); + } + + template <typename C> + void document<C>:: + parse (const void* data, std::size_t size, bool last, + const std::basic_string<C>& system_id, + const std::basic_string<C>& public_id, + xml::error_handler<C>& eh) + { + if (!parse (data, size, last, &system_id, &public_id, eh)) + throw parsing<C> (); + } + + // Implementation details. + // + + namespace bits + { + struct stream_exception_controller + { + ~stream_exception_controller () + { + std::ios_base::iostate s = is_.rdstate (); + s &= ~std::ios_base::failbit; + + // If our error state (sans failbit) intersects with the + // exception state then that means we have an active + // exception and changing error/exception state will + // cause another to be thrown. + // + if (!(old_state_ & s)) + { + // Clear failbit if it was caused by eof. + // + if (is_.fail () && is_.eof ()) + is_.clear (s); + + is_.exceptions (old_state_); + } + } + + stream_exception_controller (std::istream& is) + : is_ (is), old_state_ (is_.exceptions ()) + { + is_.exceptions (old_state_ & ~std::ios_base::failbit); + } + + private: + stream_exception_controller (const stream_exception_controller&); + + stream_exception_controller& + operator= (const stream_exception_controller&); + + private: + std::istream& is_; + std::ios_base::iostate old_state_; + }; + }; + + template <typename C> + bool document<C>:: + parse (std::istream& is, + const std::basic_string<C>* system_id, + const std::basic_string<C>* public_id, + xml::error_handler<C>& eh) + { + parser_auto_ptr parser (XML_ParserCreateNS (0, XML_Char (' '))); + + if (parser == 0) + throw std::bad_alloc (); + + if (system_id || public_id) + parse_begin (parser, system_id ? *system_id : *public_id, eh); + else + parse_begin (parser, eh); + + // Temporarily unset the exception failbit. Also clear the + // fail bit when we reset the old state if it was caused + // by eof. + // + bits::stream_exception_controller sec (is); + + char buf[16384]; // 4 x page size. + + bool r (true); + + do + { + is.read (buf, sizeof (buf)); + + if (is.bad () || (is.fail () && !is.eof ())) + { + // If the stream is not using exceptions then the user + // will have to test for stream failures before calling + // post. + // + break; + } + + if (XML_Parse ( + parser, buf, is.gcount (), is.eof ()) == XML_STATUS_ERROR) + { + r = false; + break; + } + } while (!is.eof ()); + + parse_end (); + return r; + } + + template <typename C> + bool document<C>:: + parse (const void* data, + std::size_t size, + bool last, + const std::basic_string<C>* system_id, + const std::basic_string<C>* public_id, + xml::error_handler<C>& eh) + { + // First call. + // + if (auto_xml_parser_ == 0) + { + auto_xml_parser_ = XML_ParserCreateNS (0, XML_Char (' ')); + + if (auto_xml_parser_ == 0) + throw std::bad_alloc (); + + if (system_id || public_id) + parse_begin (auto_xml_parser_, + system_id ? *system_id : *public_id, eh); + else + parse_begin (auto_xml_parser_, eh); + } + + bool r (XML_Parse (xml_parser_, + static_cast<const char*> (data), + static_cast<int> (size), + last) != XML_STATUS_ERROR); + parse_end (); + return r; + } + + // XML_Parser + // + + template <typename C> + void document<C>:: + parse_begin (XML_Parser parser) + { + xml_parser_ = parser; + eh_ = &default_eh_; + public_id_.clear (); + set (); + } + + template <typename C> + void document<C>:: + parse_begin (XML_Parser parser, + const std::basic_string<C>& public_id) + { + xml_parser_ = parser; + eh_ = &default_eh_; + public_id_ = public_id; + set (); + } + + template <typename C> + void document<C>:: + parse_begin (XML_Parser parser, xml::error_handler<C>& eh) + { + xml_parser_ = parser; + eh_ = &eh; + public_id_.clear (); + set (); + } + + template <typename C> + void document<C>:: + parse_begin (XML_Parser parser, + const std::basic_string<C>& public_id, + xml::error_handler<C>& eh) + { + xml_parser_ = parser; + eh_ = &eh; + public_id_ = public_id; + set (); + } + + template <typename C> + void document<C>:: + parse_end () + { + XML_Error e (XML_GetErrorCode (xml_parser_)); + + if (e == XML_ERROR_NONE || e == XML_ERROR_ABORTED) + { + clear (); + xml_parser_ = 0; + auto_xml_parser_ = 0; + } + else + { + unsigned long l = XML_GetCurrentLineNumber (xml_parser_); + unsigned long c = XML_GetCurrentColumnNumber (xml_parser_); + std::basic_string<C> message (XML_ErrorString (e)); + + eh_->handle (public_id_, + l, c, + xml::error_handler<C>::severity::fatal, + message); + + clear (); + xml_parser_ = 0; + auto_xml_parser_ = 0; + + // We don't want to throw an empty parsing exception here + // since the user probably already knows about the error. + } + + if (eh_ == &default_eh_) + default_eh_.throw_if_failed (); + } + + // + // + template <typename C> + void document<C>:: + set () + { + assert (xml_parser_ != 0); + + XML_SetUserData(xml_parser_, this); + + XML_SetStartElementHandler (xml_parser_, start_element_thunk_); + XML_SetEndElementHandler (xml_parser_, end_element_thunk_); + XML_SetCharacterDataHandler (xml_parser_, characters_thunk_); + + if (polymorphic_) + { + XML_SetNamespaceDeclHandler (xml_parser_, + start_namespace_decl_thunk_, + end_namespace_decl_thunk_); + } + } + + template <typename C> + void document<C>:: + clear () + { + assert (xml_parser_ != 0); + + XML_SetUserData (xml_parser_, 0); + XML_SetStartElementHandler (xml_parser_, 0); + XML_SetEndElementHandler (xml_parser_, 0); + XML_SetCharacterDataHandler (xml_parser_, 0); + + if (polymorphic_) + XML_SetNamespaceDeclHandler (xml_parser_, 0, 0); + } + + template <typename C> + void document<C>:: + translate_schema_exception (const schema_exception<C>& e) + { + unsigned long l = XML_GetCurrentLineNumber (xml_parser_); + unsigned long c = XML_GetCurrentColumnNumber (xml_parser_); + + eh_->handle (public_id_, + l, c, + xml::error_handler<C>::severity::fatal, + e.message ()); + + XML_StopParser (xml_parser_, false); + } + + // Event routing. + // + + // Expat thunks. + // + template <typename C> + void XMLCALL document<C>:: + start_element_thunk_ (void* data, + const XML_Char* ns_name, + const XML_Char** atts) + { + document& d (*reinterpret_cast<document*> (data)); + d.start_element_ (ns_name, atts); + } + + template <typename C> + void XMLCALL document<C>:: + end_element_thunk_ (void* data, const XML_Char* ns_name) + { + document& d (*reinterpret_cast<document*> (data)); + d.end_element_ (ns_name); + } + + template <typename C> + void XMLCALL document<C>:: + characters_thunk_ (void* data, const XML_Char* s, int n) + { + document& d (*reinterpret_cast<document*> (data)); + d.characters_ (s, static_cast<std::size_t> (n)); + } + + template <typename C> + void XMLCALL document<C>:: + start_namespace_decl_thunk_ (void* data, + const XML_Char* prefix, + const XML_Char* ns) + { + document& d (*reinterpret_cast<document*> (data)); + d.start_namespace_decl_ (prefix, ns); + } + + template <typename C> + void XMLCALL document<C>:: + end_namespace_decl_thunk_ (void* data, const XML_Char* prefix) + { + document& d (*reinterpret_cast<document*> (data)); + d.end_namespace_decl_ (prefix); + } + + namespace bits + { + inline void + split_name (const XML_Char* s, + const char*& ns, std::size_t& ns_s, + const char*& name, std::size_t& name_s) + { + const char* p (std::strchr (s, ' ')); + + if (p) + { + ns = s; + ns_s = p - s; + name = p + 1; + } + else + { + ns = s; + ns_s = 0; + name = s; + } + + name_s = std::char_traits<char>::length (name); + } + } + + template <typename C> + void document<C>:: + start_element_ (const XML_Char* ns_name, const XML_Char** atts) + { + // Current Expat (2.0.0) has a (mis)-feature of a possibility of + // calling callbacks even after the non-resumable XML_StopParser + // call. The following code accounts for this. + // + { + XML_ParsingStatus s; + XML_GetParsingStatus (xml_parser_, &s); + if (s.parsing == XML_FINISHED) + return; + } + + typedef std::basic_string<C> string; + + const char* ns_p; + const char* name_p; + size_t ns_s, name_s; + + bits::split_name (ns_name, ns_p, ns_s, name_p, name_s); + + { + const ro_string<C> ns (ns_p, ns_s), name (name_p, name_s); + + if (!polymorphic_) + { + try + { + start_element (ns, name, 0); + } + catch (const schema_exception<C>& e) + { + translate_schema_exception (e); + return; + } + } + else + { + // Search for the xsi:type attribute. + // + const XML_Char** p = atts; // VC8 can't handle p (atts) + for (; *p != 0; p += 2) + { + bits::split_name (*p, ns_p, ns_s, name_p, name_s); + const ro_string<C> ns (ns_p, ns_s), name (name_p, name_s); + + if (name == xml::bits::type<C> () && + ns == xml::bits::xsi_namespace<C> ()) + break; + } + + if (*p == 0) + { + try + { + start_element (ns, name, 0); + } + catch (const schema_exception<C>& e) + { + translate_schema_exception (e); + return; + } + } + else + { + // @@ Need proper QName validation. + // + // Get the qualified type name and try to resolve it. + // + ro_string<C> qn (*(p + 1)); + + ro_string<C> tp, tn; + typename ro_string<C>::size_type pos (qn.find (C (':'))); + + try + { + if (pos != ro_string<C>::npos) + { + tp.assign (qn.data (), pos); + tn.assign (qn.data () + pos + 1); + + if (tp.empty ()) + throw dynamic_type<C> (qn); + } + else + tn.assign (qn.data (), qn.size ()); + + if (tn.empty ()) + throw dynamic_type<C> (qn); + + // Search our namespace declaration stack. Note that + // we need to do this even if prefix is empty. Sun CC + // 5.7 blows if we use const_reverse_iterator. + // + ro_string<C> tns; + for (typename ns_decls::reverse_iterator + it (ns_decls_.rbegin ()), e (ns_decls_.rend ()); + it != e; ++it) + { + if (it->prefix == tp) + { + tns.assign (it->ns); + break; + } + } + + if (!tp.empty () && tns.empty ()) + { + // The 'xml' prefix requires special handling. + // + if (tp == xml::bits::xml_prefix<C> ()) + tns.assign (xml::bits::xml_namespace<C> ()); + else + throw dynamic_type<C> (qn); + } + + // Construct the compound type id. + // + string id (tn.data (), tn.size ()); + + if (!tns.empty ()) + { + id += C (' '); + id.append (tns.data (), tns.size ()); + } + + ro_string<C> ro_id (id); + start_element (ns, name, &ro_id); + } + catch (const schema_exception<C>& e) + { + translate_schema_exception (e); + return; + } + } + } + } + + for (; *atts != 0; atts += 2) + { + bits::split_name (*atts, ns_p, ns_s, name_p, name_s); + + const ro_string<C> ns (ns_p, ns_s), name (name_p, name_s); + const ro_string<C> value (*(atts + 1)); + + try + { + attribute (ns, name, value); + } + catch (const schema_exception<C>& e) + { + translate_schema_exception (e); + break; + } + } + } + + template <typename C> + void document<C>:: + end_element_ (const XML_Char* ns_name) + { + // Current Expat (2.0.0) has a (mis)-feature of a possibility of + // calling callbacks even after the non-resumable XML_StopParser + // call. The following code accounts for this. + // + { + XML_ParsingStatus s; + XML_GetParsingStatus (xml_parser_, &s); + if (s.parsing == XML_FINISHED) + return; + } + + const char* ns_p; + const char* name_p; + size_t ns_s, name_s; + + bits::split_name (ns_name, ns_p, ns_s, name_p, name_s); + + const ro_string<C> ns (ns_p, ns_s), name (name_p, name_s); + + try + { + end_element (ns, name); + } + catch (const schema_exception<C>& e) + { + translate_schema_exception (e); + } + } + + template <typename C> + void document<C>:: + characters_ (const XML_Char* s, std::size_t n) + { + // Current Expat (2.0.0) has a (mis)-feature of a possibility of + // calling callbacks even after the non-resumable XML_StopParser + // call. The following code accounts for this. + // + { + XML_ParsingStatus s; + XML_GetParsingStatus (xml_parser_, &s); + if (s.parsing == XML_FINISHED) + return; + } + + if (n != 0) + { + const ro_string<C> str (s, n); + + try + { + characters (str); + } + catch (const schema_exception<C>& e) + { + translate_schema_exception (e); + } + } + } + + template <typename C> + void document<C>:: + start_namespace_decl_ (const XML_Char* p, const XML_Char* ns) + { + // prefix is 0 for default namespace + // namespace is 0 when unsetting default namespace + // + if (polymorphic_) + ns_decls_.push_back (ns_decl ((p ? p : ""), (ns ? ns : ""))); + } + + template <typename C> + void document<C>:: + end_namespace_decl_ (const XML_Char* p) + { + // prefix is 0 for default namespace + // + if (polymorphic_) + { + // Here we assume the prefixes are removed in the reverse + // order of them being added. This appears to how every + // sensible implementation works. + // + assert (p + ? ns_decls_.back ().prefix == p + : ns_decls_.back ().prefix.empty ()); + + ns_decls_.pop_back (); + } + } + } + } + } +} diff --git a/libxsd/xsd/cxx/parser/map.hxx b/libxsd/xsd/cxx/parser/map.hxx new file mode 100644 index 0000000..7d3696a --- /dev/null +++ b/libxsd/xsd/cxx/parser/map.hxx @@ -0,0 +1,79 @@ +// file : xsd/cxx/parser/map.hxx +// author : Boris Kolpackov <boris@codesynthesis.com> +// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSD_CXX_PARSER_MAP_HXX +#define XSD_CXX_PARSER_MAP_HXX + +#include <map> +#include <string> + +#include <xsd/cxx/ro-string.hxx> +#include <xsd/cxx/parser/elements.hxx> + +namespace xsd +{ + namespace cxx + { + namespace parser + { + // Parser map. Used in the polymorphic document parsing. + // + template <typename C> + struct parser_map + { + virtual + ~parser_map (); + + // The type argument is the type name and namespace from the + // xsi:type attribute or substitution group map in the form + // "<name> <namespace>" with the space and namespace part + // absent if the type does not have a namespace. + // + virtual parser_base<C>* + find (const ro_string<C>& type) const = 0; + }; + + + // Parser map implementation. + // + template <typename C> + struct parser_map_impl: parser_map<C> + { + parser_map_impl (); + + void + insert (parser_base<C>&); + + virtual parser_base<C>* + find (const ro_string<C>& type) const; + + private: + parser_map_impl (const parser_map_impl&); + + parser_map_impl& + operator= (const parser_map_impl&); + + private: + struct string_comparison + { + bool + operator() (const C* x, const C* y) const + { + ro_string<C> s (x); + return s.compare (y) < 0; + } + }; + + typedef std::map<const C*, parser_base<C>*, string_comparison> map; + map map_; + }; + } + } +} + +#include <xsd/cxx/parser/map.ixx> +#include <xsd/cxx/parser/map.txx> + +#endif // XSD_CXX_PARSER_MAP_HXX diff --git a/libxsd/xsd/cxx/parser/map.ixx b/libxsd/xsd/cxx/parser/map.ixx new file mode 100644 index 0000000..17ac4e4 --- /dev/null +++ b/libxsd/xsd/cxx/parser/map.ixx @@ -0,0 +1,27 @@ +// file : xsd/cxx/parser/map.ixx +// author : Boris Kolpackov <boris@codesynthesis.com> +// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +namespace xsd +{ + namespace cxx + { + namespace parser + { + // parser_map_impl + // + template <typename C> + inline parser_map_impl<C>::parser_map_impl () + { + } + + template <typename C> + inline void parser_map_impl<C>:: + insert (parser_base<C>& parser) + { + map_[parser._dynamic_type ()] = &parser; + } + } + } +} diff --git a/libxsd/xsd/cxx/parser/map.txx b/libxsd/xsd/cxx/parser/map.txx new file mode 100644 index 0000000..5d31894 --- /dev/null +++ b/libxsd/xsd/cxx/parser/map.txx @@ -0,0 +1,31 @@ +// file : xsd/cxx/parser/map.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 + +namespace xsd +{ + namespace cxx + { + namespace parser + { + // parser_map + // + template <typename C> + parser_map<C>:: + ~parser_map () + { + } + + // parser_map_impl + // + template <typename C> + parser_base<C>* parser_map_impl<C>:: + find (const ro_string<C>& type) const + { + typename map::const_iterator i (map_.find (type.data ())); + return i != map_.end () ? i->second : 0; + } + } + } +} diff --git a/libxsd/xsd/cxx/parser/non-validating/parser.hxx b/libxsd/xsd/cxx/parser/non-validating/parser.hxx new file mode 100644 index 0000000..480d8ab --- /dev/null +++ b/libxsd/xsd/cxx/parser/non-validating/parser.hxx @@ -0,0 +1,248 @@ +// file : xsd/cxx/parser/non-validating/parser.hxx +// author : Boris Kolpackov <boris@codesynthesis.com> +// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSD_CXX_PARSER_NON_VALIDATING_PARSER_HXX +#define XSD_CXX_PARSER_NON_VALIDATING_PARSER_HXX + +#include <stack> +#include <string> +#include <cstddef> // std::size_t + +#include <xsd/cxx/ro-string.hxx> +#include <xsd/cxx/parser/elements.hxx> + +namespace xsd +{ + namespace cxx + { + namespace parser + { + namespace non_validating + { + // + // + template <typename C> + struct empty_content: parser_base<C> + { + // The _*_any_* functions are called when wildcard content + // is encountered. Use them to handle mixed content models, + // any/anyAttribute, and anyType/anySimpleType. By default + // these functions do nothing. + // + + // The type argument is a type name and namespace from the + // xsi:type attribute in the form "<name> <namespace>" with + // the space and namespace part absent if the type does not + // have a namespace or 0 if xsi:type is not present. + // + virtual void + _start_any_element (const ro_string<C>& ns, + const ro_string<C>& name, + const ro_string<C>* type); + + virtual void + _end_any_element (const ro_string<C>& ns, + const ro_string<C>& name); + + virtual void + _any_attribute (const ro_string<C>& ns, + const ro_string<C>& name, + const ro_string<C>& value); + + virtual void + _any_characters (const ro_string<C>&); + + + // + // + virtual bool + _start_element_impl (const ro_string<C>&, + const ro_string<C>&, + const ro_string<C>*); + + virtual bool + _end_element_impl (const ro_string<C>&, + const ro_string<C>&); + + virtual bool + _attribute_impl (const ro_string<C>&, + const ro_string<C>&, + const ro_string<C>&); + + virtual bool + _characters_impl (const ro_string<C>&); + + + // + // + virtual void + _start_element (const ro_string<C>& ns, + const ro_string<C>& name, + const ro_string<C>* type); + + virtual void + _end_element (const ro_string<C>& ns, + const ro_string<C>& name); + + virtual void + _attribute (const ro_string<C>& ns, + const ro_string<C>& name, + const ro_string<C>& value); + + virtual void + _characters (const ro_string<C>& s); + }; + + + // + // + template <typename C> + struct simple_content: empty_content<C> + { + // + // + virtual void + _attribute (const ro_string<C>& ns, + const ro_string<C>& name, + const ro_string<C>& value); + + virtual void + _characters (const ro_string<C>&); + }; + + + // + // + template <typename C> + struct complex_content: empty_content<C> + { + // + // + virtual void + _start_element (const ro_string<C>& ns, + const ro_string<C>& name, + const ro_string<C>* type); + + virtual void + _end_element (const ro_string<C>& ns, + const ro_string<C>& name); + + virtual void + _attribute (const ro_string<C>& ns, + const ro_string<C>& name, + const ro_string<C>& value); + + virtual void + _characters (const ro_string<C>&); + + + // + // + virtual void + _pre_impl (); + + virtual void + _post_impl (); + + protected: + struct state + { + state () + : any_ (false), depth_ (0), parser_ (0) + { + } + + bool any_; + std::size_t depth_; + parser_base<C>* parser_; + }; + + // Optimized state stack for non-recursive case (one element). + // + struct state_stack + { + state_stack () + : size_ (0) + { + } + + void + push (const state& s) + { + if (size_ > 0) + rest_.push (top_); + + top_ = s; + ++size_; + } + + void + pop () + { + if (size_ > 1) + { + top_ = rest_.top (); + rest_.pop (); + } + + --size_; + } + + const state& + top () const + { + return top_; + } + + state& + top () + { + return top_; + } + + state& + under_top () + { + return rest_.top (); + } + + private: + state top_; + std::stack<state> rest_; + std::size_t size_; + }; + + state_stack context_; + }; + + + // Base for xsd:list. + // + template <typename C> + struct list_base: simple_content<C> + { + virtual void + _xsd_parse_item (const ro_string<C>&) = 0; + + virtual void + _pre_impl (); + + virtual void + _characters (const ro_string<C>&); + + virtual void + _post_impl (); + + protected: + std::basic_string<C> buf_; + }; + } + } + } +} + +#include <xsd/cxx/parser/non-validating/parser.txx> + +#endif // XSD_CXX_PARSER_NON_VALIDATING_PARSER_HXX 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 (); + } + } + } + } +} diff --git a/libxsd/xsd/cxx/parser/non-validating/xml-schema-pimpl.hxx b/libxsd/xsd/cxx/parser/non-validating/xml-schema-pimpl.hxx new file mode 100644 index 0000000..0e8443d --- /dev/null +++ b/libxsd/xsd/cxx/parser/non-validating/xml-schema-pimpl.hxx @@ -0,0 +1,791 @@ +// file : xsd/cxx/parser/non-validating/xml-schema-pimpl.hxx +// author : Boris Kolpackov <boris@codesynthesis.com> +// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSD_CXX_PARSER_NON_VALIDATING_XML_SCHEMA_PIMPL_HXX +#define XSD_CXX_PARSER_NON_VALIDATING_XML_SCHEMA_PIMPL_HXX + +#include <string> + +#include <xsd/cxx/parser/non-validating/xml-schema-pskel.hxx> + +namespace xsd +{ + namespace cxx + { + namespace parser + { + namespace non_validating + { + // any_type + // + template <typename C> + struct any_type_pimpl: virtual any_type_pskel<C> + { + virtual void + post_any_type (); + }; + + // any_simple_type + // + template <typename C> + struct any_simple_type_pimpl: virtual any_simple_type_pskel<C> + { + virtual void + post_any_simple_type (); + }; + + // boolean + // + template <typename C> + struct boolean_pimpl: virtual boolean_pskel<C> + { + virtual void + _pre (); + + virtual void + _characters (const ro_string<C>&); + + virtual bool + post_boolean (); + + protected: + std::basic_string<C> str_; + }; + + + // 8-bit + // + template <typename C> + struct byte_pimpl: virtual byte_pskel<C> + { + virtual void + _pre (); + + virtual void + _characters (const ro_string<C>&); + + virtual signed char + post_byte (); + + protected: + std::basic_string<C> str_; + }; + + + template <typename C> + struct unsigned_byte_pimpl: virtual unsigned_byte_pskel<C> + { + virtual void + _pre (); + + virtual void + _characters (const ro_string<C>&); + + virtual unsigned char + post_unsigned_byte (); + + protected: + std::basic_string<C> str_; + }; + + + // 16-bit + // + template <typename C> + struct short_pimpl: virtual short_pskel<C> + { + virtual void + _pre (); + + virtual void + _characters (const ro_string<C>&); + + virtual short + post_short (); + + protected: + std::basic_string<C> str_; + }; + + + template <typename C> + struct unsigned_short_pimpl: virtual unsigned_short_pskel<C> + { + virtual void + _pre (); + + virtual void + _characters (const ro_string<C>&); + + virtual unsigned short + post_unsigned_short (); + + protected: + std::basic_string<C> str_; + }; + + + // 32-bit + // + template <typename C> + struct int_pimpl: virtual int_pskel<C> + { + virtual void + _pre (); + + virtual void + _characters (const ro_string<C>&); + + virtual int + post_int (); + + protected: + std::basic_string<C> str_; + }; + + + template <typename C> + struct unsigned_int_pimpl: virtual unsigned_int_pskel<C> + { + virtual void + _pre (); + + virtual void + _characters (const ro_string<C>&); + + virtual unsigned int + post_unsigned_int (); + + protected: + std::basic_string<C> str_; + }; + + + // 64-bit + // + template <typename C> + struct long_pimpl: virtual long_pskel<C> + { + virtual void + _pre (); + + virtual void + _characters (const ro_string<C>&); + + virtual long long + post_long (); + + protected: + std::basic_string<C> str_; + }; + + + template <typename C> + struct unsigned_long_pimpl: virtual unsigned_long_pskel<C> + { + virtual void + _pre (); + + virtual void + _characters (const ro_string<C>&); + + virtual unsigned long long + post_unsigned_long (); + + protected: + std::basic_string<C> str_; + }; + + + // Arbitrary-length integers. + // + template <typename C> + struct integer_pimpl: virtual integer_pskel<C> + { + virtual void + _pre (); + + virtual void + _characters (const ro_string<C>&); + + virtual long long + post_integer (); + + protected: + std::basic_string<C> str_; + }; + + template <typename C> + struct negative_integer_pimpl: virtual negative_integer_pskel<C> + { + virtual void + _pre (); + + virtual void + _characters (const ro_string<C>&); + + virtual long long + post_negative_integer (); + + protected: + std::basic_string<C> str_; + }; + + template <typename C> + struct non_positive_integer_pimpl: virtual non_positive_integer_pskel<C> + { + virtual void + _pre (); + + virtual void + _characters (const ro_string<C>&); + + virtual long long + post_non_positive_integer (); + + protected: + std::basic_string<C> str_; + }; + + template <typename C> + struct positive_integer_pimpl: virtual positive_integer_pskel<C> + { + virtual void + _pre (); + + virtual void + _characters (const ro_string<C>&); + + virtual unsigned long long + post_positive_integer (); + + protected: + std::basic_string<C> str_; + }; + + template <typename C> + struct non_negative_integer_pimpl: virtual non_negative_integer_pskel<C> + { + virtual void + _pre (); + + virtual void + _characters (const ro_string<C>&); + + virtual unsigned long long + post_non_negative_integer (); + + protected: + std::basic_string<C> str_; + }; + + + // Floats. + // + template <typename C> + struct float_pimpl: virtual float_pskel<C> + { + virtual void + _pre (); + + virtual void + _characters (const ro_string<C>&); + + virtual float + post_float (); + + protected: + std::basic_string<C> str_; + }; + + + template <typename C> + struct double_pimpl: virtual double_pskel<C> + { + virtual void + _pre (); + + virtual void + _characters (const ro_string<C>&); + + virtual double + post_double (); + + protected: + std::basic_string<C> str_; + }; + + + template <typename C> + struct decimal_pimpl: virtual decimal_pskel<C> + { + virtual void + _pre (); + + virtual void + _characters (const ro_string<C>&); + + virtual double + post_decimal (); + + protected: + std::basic_string<C> str_; + }; + + + // Strings. + // + template <typename C> + struct string_pimpl: virtual string_pskel<C> + { + virtual void + _pre (); + + virtual void + _characters (const ro_string<C>&); + + virtual std::basic_string<C> + post_string (); + + protected: + std::basic_string<C> str_; + }; + + template <typename C> + struct normalized_string_pimpl: virtual normalized_string_pskel<C> + { + virtual void + _pre (); + + virtual void + _characters (const ro_string<C>&); + + virtual std::basic_string<C> + post_normalized_string (); + + protected: + std::basic_string<C> str_; + }; + + template <typename C> + struct token_pimpl: virtual token_pskel<C> + { + virtual void + _pre (); + + virtual void + _characters (const ro_string<C>&); + + virtual std::basic_string<C> + post_token (); + + protected: + std::basic_string<C> str_; + }; + + template <typename C> + struct name_pimpl: virtual name_pskel<C> + { + virtual void + _pre (); + + virtual void + _characters (const ro_string<C>&); + + virtual std::basic_string<C> + post_name (); + + protected: + std::basic_string<C> str_; + }; + + template <typename C> + struct nmtoken_pimpl: virtual nmtoken_pskel<C> + { + virtual void + _pre (); + + virtual void + _characters (const ro_string<C>&); + + virtual std::basic_string<C> + post_nmtoken (); + + protected: + std::basic_string<C> str_; + }; + + template <typename C> + struct nmtokens_pimpl: virtual nmtokens_pskel<C> + { + virtual void + _pre (); + + virtual void + _xsd_parse_item (const ro_string<C>&); + + virtual string_sequence<C> + post_nmtokens (); + + protected: + string_sequence<C> seq_; + nmtoken_pimpl<C> parser_; + }; + + template <typename C> + struct ncname_pimpl: virtual ncname_pskel<C> + { + virtual void + _pre (); + + virtual void + _characters (const ro_string<C>&); + + virtual std::basic_string<C> + post_ncname (); + + protected: + std::basic_string<C> str_; + }; + + template <typename C> + struct id_pimpl: virtual id_pskel<C> + { + virtual void + _pre (); + + virtual void + _characters (const ro_string<C>&); + + virtual std::basic_string<C> + post_id (); + + protected: + std::basic_string<C> str_; + }; + + template <typename C> + struct idref_pimpl: virtual idref_pskel<C> + { + virtual void + _pre (); + + virtual void + _characters (const ro_string<C>&); + + virtual std::basic_string<C> + post_idref (); + + protected: + std::basic_string<C> str_; + }; + + template <typename C> + struct idrefs_pimpl: virtual idrefs_pskel<C> + { + virtual void + _pre (); + + virtual void + _xsd_parse_item (const ro_string<C>&); + + virtual string_sequence<C> + post_idrefs (); + + protected: + string_sequence<C> seq_; + idref_pimpl<C> parser_; + }; + + // language + // + template <typename C> + struct language_pimpl: virtual language_pskel<C> + { + virtual void + _pre (); + + virtual void + _characters (const ro_string<C>&); + + virtual std::basic_string<C> + post_language (); + + protected: + std::basic_string<C> str_; + }; + + // anyURI + // + template <typename C> + struct uri_pimpl: virtual uri_pskel<C> + { + virtual void + _pre (); + + virtual void + _characters (const ro_string<C>&); + + virtual std::basic_string<C> + post_uri (); + + protected: + std::basic_string<C> str_; + }; + + // QName + // + template <typename C> + struct qname_pimpl: virtual qname_pskel<C> + { + virtual void + _pre (); + + virtual void + _characters (const ro_string<C>&); + + virtual qname<C> + post_qname (); + + protected: + std::basic_string<C> str_; + }; + + // base64Binary + // + template <typename C> + struct base64_binary_pimpl: virtual base64_binary_pskel<C> + { + virtual void + _pre (); + + virtual void + _characters (const ro_string<C>&); + + virtual std::auto_ptr<buffer> + post_base64_binary (); + + protected: + std::basic_string<C> str_; + }; + + // hexBinary + // + template <typename C> + struct hex_binary_pimpl: virtual hex_binary_pskel<C> + { + virtual void + _pre (); + + virtual void + _characters (const ro_string<C>&); + + virtual std::auto_ptr<buffer> + post_hex_binary (); + + protected: + std::basic_string<C> str_; + }; + + // gday + // + template <typename C> + struct gday_pimpl: virtual gday_pskel<C> + { + virtual void + _pre (); + + virtual void + _characters (const ro_string<C>&); + + virtual gday + post_gday (); + + protected: + std::basic_string<C> str_; + }; + + // gmonth + // + template <typename C> + struct gmonth_pimpl: virtual gmonth_pskel<C> + { + virtual void + _pre (); + + virtual void + _characters (const ro_string<C>&); + + virtual gmonth + post_gmonth (); + + protected: + std::basic_string<C> str_; + }; + + // gyear + // + template <typename C> + struct gyear_pimpl: virtual gyear_pskel<C> + { + virtual void + _pre (); + + virtual void + _characters (const ro_string<C>&); + + virtual gyear + post_gyear (); + + protected: + std::basic_string<C> str_; + }; + + // gmonth_day + // + template <typename C> + struct gmonth_day_pimpl: virtual gmonth_day_pskel<C> + { + virtual void + _pre (); + + virtual void + _characters (const ro_string<C>&); + + virtual gmonth_day + post_gmonth_day (); + + protected: + std::basic_string<C> str_; + }; + + // gyear_month + // + template <typename C> + struct gyear_month_pimpl: virtual gyear_month_pskel<C> + { + virtual void + _pre (); + + virtual void + _characters (const ro_string<C>&); + + virtual gyear_month + post_gyear_month (); + + protected: + std::basic_string<C> str_; + }; + + // date + // + template <typename C> + struct date_pimpl: virtual date_pskel<C> + { + virtual void + _pre (); + + virtual void + _characters (const ro_string<C>&); + + virtual date + post_date (); + + protected: + std::basic_string<C> str_; + }; + + // time + // + template <typename C> + struct time_pimpl: virtual time_pskel<C> + { + virtual void + _pre (); + + virtual void + _characters (const ro_string<C>&); + + virtual time + post_time (); + + protected: + std::basic_string<C> str_; + }; + + // date_time + // + template <typename C> + struct date_time_pimpl: virtual date_time_pskel<C> + { + virtual void + _pre (); + + virtual void + _characters (const ro_string<C>&); + + virtual date_time + post_date_time (); + + protected: + std::basic_string<C> str_; + }; + + // duration + // + template <typename C> + struct duration_pimpl: virtual duration_pskel<C> + { + virtual void + _pre (); + + virtual void + _characters (const ro_string<C>&); + + virtual duration + post_duration (); + + protected: + std::basic_string<C> str_; + }; + + // + // + namespace bits + { + // float literals: INF -INF NaN + // + template<typename C> + const C* + positive_inf (); + + template<typename C> + const C* + negative_inf (); + + template<typename C> + const C* + nan (); + + // boolean literals + // + template<typename C> + const C* + true_ (); + + template<typename C> + const C* + one (); + } + } + } + } +} + +#include <xsd/cxx/parser/non-validating/xml-schema-pimpl.txx> + +#endif // XSD_CXX_PARSER_NON_VALIDATING_XML_SCHEMA_PIMPL_HXX + +#include <xsd/cxx/parser/non-validating/xml-schema-pimpl.ixx> diff --git a/libxsd/xsd/cxx/parser/non-validating/xml-schema-pimpl.ixx b/libxsd/xsd/cxx/parser/non-validating/xml-schema-pimpl.ixx new file mode 100644 index 0000000..0220117 --- /dev/null +++ b/libxsd/xsd/cxx/parser/non-validating/xml-schema-pimpl.ixx @@ -0,0 +1,129 @@ +// file : xsd/cxx/parser/non-validating/xml-schema-pimpl.ixx +// author : Boris Kolpackov <boris@codesynthesis.com> +// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#if defined(XSD_CXX_PARSER_USE_CHAR) || !defined(XSD_CXX_PARSER_USE_WCHAR) + +#ifndef XSD_CXX_PARSER_NON_VALIDATING_XML_SCHEMA_PIMPL_IXX_CHAR +#define XSD_CXX_PARSER_NON_VALIDATING_XML_SCHEMA_PIMPL_IXX_CHAR + +namespace xsd +{ + namespace cxx + { + namespace parser + { + namespace non_validating + { + namespace bits + { + // + // + template<> + inline const char* + positive_inf<char> () + { + return "INF"; + } + + template<> + inline const char* + negative_inf<char> () + { + return "-INF"; + } + + template<> + inline const char* + nan<char> () + { + return "NaN"; + } + + // + // + template<> + inline const char* + true_<char> () + { + return "true"; + } + + template<> + inline const char* + one<char> () + { + return "1"; + } + } + } + } + } +} + +#endif // XSD_CXX_PARSER_NON_VALIDATING_XML_SCHEMA_PIMPL_IXX_CHAR +#endif // XSD_CXX_PARSER_USE_CHAR + + +#if defined(XSD_CXX_PARSER_USE_WCHAR) || !defined(XSD_CXX_PARSER_USE_CHAR) + +#ifndef XSD_CXX_PARSER_NON_VALIDATING_XML_SCHEMA_PIMPL_IXX_WCHAR +#define XSD_CXX_PARSER_NON_VALIDATING_XML_SCHEMA_PIMPL_IXX_WCHAR + +namespace xsd +{ + namespace cxx + { + namespace parser + { + namespace non_validating + { + namespace bits + { + // + // + template<> + inline const wchar_t* + positive_inf<wchar_t> () + { + return L"INF"; + } + + template<> + inline const wchar_t* + negative_inf<wchar_t> () + { + return L"-INF"; + } + + template<> + inline const wchar_t* + nan<wchar_t> () + { + return L"NaN"; + } + + // + // + template<> + inline const wchar_t* + true_<wchar_t> () + { + return L"true"; + } + + template<> + inline const wchar_t* + one<wchar_t> () + { + return L"1"; + } + } + } + } + } +} + +#endif // XSD_CXX_PARSER_NON_VALIDATING_XML_SCHEMA_PIMPL_IXX_WCHAR +#endif // XSD_CXX_PARSER_USE_WCHAR diff --git a/libxsd/xsd/cxx/parser/non-validating/xml-schema-pimpl.txx b/libxsd/xsd/cxx/parser/non-validating/xml-schema-pimpl.txx new file mode 100644 index 0000000..5ce50d6 --- /dev/null +++ b/libxsd/xsd/cxx/parser/non-validating/xml-schema-pimpl.txx @@ -0,0 +1,2068 @@ +// file : xsd/cxx/parser/non-validating/xml-schema-pimpl.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 <limits> +#include <locale> + +#include <xsd/cxx/zc-istream.hxx> + +namespace xsd +{ + namespace cxx + { + namespace parser + { + namespace non_validating + { + // Note that most of the types implemented here cannot have + // whitespaces in the value. As result we don't need to waste + // time collapsing whitespaces. All we need to do is trim the + // string representation which can be done without copying. + // + + // any_type + // + + template <typename C> + void any_type_pimpl<C>:: + post_any_type () + { + } + + // any_simple_type + // + + template <typename C> + void any_simple_type_pimpl<C>:: + post_any_simple_type () + { + } + + // boolean + // + template <typename C> + void boolean_pimpl<C>:: + _pre () + { + str_.clear (); + } + + template <typename C> + void boolean_pimpl<C>:: + _characters (const ro_string<C>& s) + { + str_ += s; + } + + template <typename C> + bool boolean_pimpl<C>:: + post_boolean () + { + std::basic_string<C> tmp; + tmp.swap (str_); + + ro_string<C> str (tmp); + trim (str); + + return str == bits::true_<C> () || str == bits::one<C> (); + } + + // byte + // + + template <typename C> + void byte_pimpl<C>:: + _pre () + { + str_.clear (); + } + + template <typename C> + void byte_pimpl<C>:: + _characters (const ro_string<C>& s) + { + str_ += s; + } + + template <typename C> + signed char byte_pimpl<C>:: + post_byte () + { + std::basic_string<C> tmp; + tmp.swap (str_); + + ro_string<C> str (tmp); + trim (str); + + short t; + zc_istream<C> is (str); + is >> t; + + return static_cast<signed char> (t); + } + + // unsigned_byte + // + + template <typename C> + void unsigned_byte_pimpl<C>:: + _pre () + { + str_.clear (); + } + + template <typename C> + void unsigned_byte_pimpl<C>:: + _characters (const ro_string<C>& s) + { + str_ += s; + } + + template <typename C> + unsigned char unsigned_byte_pimpl<C>:: + post_unsigned_byte () + { + std::basic_string<C> tmp; + tmp.swap (str_); + + ro_string<C> str (tmp); + trim (str); + + unsigned short t; + zc_istream<C> is (str); + is >> t; + + return static_cast<unsigned char> (t); + } + + // short + // + + template <typename C> + void short_pimpl<C>:: + _pre () + { + str_.clear (); + } + + template <typename C> + void short_pimpl<C>:: + _characters (const ro_string<C>& s) + { + str_ += s; + } + + template <typename C> + short short_pimpl<C>:: + post_short () + { + std::basic_string<C> tmp; + tmp.swap (str_); + + ro_string<C> str (tmp); + trim (str); + + short t; + zc_istream<C> is (str); + is >> t; + + return t; + } + + // unsigned_short + // + + template <typename C> + void unsigned_short_pimpl<C>:: + _pre () + { + str_.clear (); + } + + template <typename C> + void unsigned_short_pimpl<C>:: + _characters (const ro_string<C>& s) + { + str_ += s; + } + + template <typename C> + unsigned short unsigned_short_pimpl<C>:: + post_unsigned_short () + { + std::basic_string<C> tmp; + tmp.swap (str_); + + ro_string<C> str (tmp); + trim (str); + + unsigned short t; + zc_istream<C> is (str); + is >> t; + + return t; + } + + // int + // + + template <typename C> + void int_pimpl<C>:: + _pre () + { + str_.clear (); + } + + template <typename C> + void int_pimpl<C>:: + _characters (const ro_string<C>& s) + { + str_ += s; + } + + template <typename C> + int int_pimpl<C>:: + post_int () + { + std::basic_string<C> tmp; + tmp.swap (str_); + + ro_string<C> str (tmp); + trim (str); + + int t; + zc_istream<C> is (str); + is >> t; + + return t; + } + + // unsigned_int + // + + template <typename C> + void unsigned_int_pimpl<C>:: + _pre () + { + str_.clear (); + } + + template <typename C> + void unsigned_int_pimpl<C>:: + _characters (const ro_string<C>& s) + { + str_ += s; + } + + template <typename C> + unsigned int unsigned_int_pimpl<C>:: + post_unsigned_int () + { + std::basic_string<C> tmp; + tmp.swap (str_); + + ro_string<C> str (tmp); + trim (str); + + unsigned int t; + zc_istream<C> is (str); + is >> t; + + return t; + } + + // long + // + template <typename C> + void long_pimpl<C>:: + _pre () + { + str_.clear (); + } + + template <typename C> + void long_pimpl<C>:: + _characters (const ro_string<C>& s) + { + str_ += s; + } + + template <typename C> + long long long_pimpl<C>:: + post_long () + { + std::basic_string<C> tmp; + tmp.swap (str_); + + ro_string<C> str (tmp); + trim (str); + + long long t; + zc_istream<C> is (str); + is >> t; + + return t; + } + + // unsigned_long + // + template <typename C> + void unsigned_long_pimpl<C>:: + _pre () + { + str_.clear (); + } + + template <typename C> + void unsigned_long_pimpl<C>:: + _characters (const ro_string<C>& s) + { + str_ += s; + } + + template <typename C> + unsigned long long unsigned_long_pimpl<C>:: + post_unsigned_long () + { + std::basic_string<C> tmp; + tmp.swap (str_); + + ro_string<C> str (tmp); + trim (str); + + unsigned long long t; + zc_istream<C> is (str); + is >> t; + + return t; + } + + // integer + // + template <typename C> + void integer_pimpl<C>:: + _pre () + { + str_.clear (); + } + + template <typename C> + void integer_pimpl<C>:: + _characters (const ro_string<C>& s) + { + str_ += s; + } + + template <typename C> + long long integer_pimpl<C>:: + post_integer () + { + std::basic_string<C> tmp; + tmp.swap (str_); + + ro_string<C> str (tmp); + trim (str); + + long long t; + zc_istream<C> is (str); + is >> t; + + return t; + } + + // negative_integer + // + template <typename C> + void negative_integer_pimpl<C>:: + _pre () + { + str_.clear (); + } + + template <typename C> + void negative_integer_pimpl<C>:: + _characters (const ro_string<C>& s) + { + str_ += s; + } + + template <typename C> + long long negative_integer_pimpl<C>:: + post_negative_integer () + { + std::basic_string<C> tmp; + tmp.swap (str_); + + ro_string<C> str (tmp); + trim (str); + + long long t; + zc_istream<C> is (str); + is >> t; + + return t; + } + + // non_positive_integer + // + template <typename C> + void non_positive_integer_pimpl<C>:: + _pre () + { + str_.clear (); + } + + template <typename C> + void non_positive_integer_pimpl<C>:: + _characters (const ro_string<C>& s) + { + str_ += s; + } + + template <typename C> + long long non_positive_integer_pimpl<C>:: + post_non_positive_integer () + { + std::basic_string<C> tmp; + tmp.swap (str_); + + ro_string<C> str (tmp); + trim (str); + + long long t; + zc_istream<C> is (str); + is >> t; + + return t; + } + + // positive_integer + // + template <typename C> + void positive_integer_pimpl<C>:: + _pre () + { + str_.clear (); + } + + template <typename C> + void positive_integer_pimpl<C>:: + _characters (const ro_string<C>& s) + { + str_ += s; + } + + template <typename C> + unsigned long long positive_integer_pimpl<C>:: + post_positive_integer () + { + std::basic_string<C> tmp; + tmp.swap (str_); + + ro_string<C> str (tmp); + trim (str); + + unsigned long long t; + zc_istream<C> is (str); + is >> t; + + return t; + } + + // non_negative_integer + // + template <typename C> + void non_negative_integer_pimpl<C>:: + _pre () + { + str_.clear (); + } + + template <typename C> + void non_negative_integer_pimpl<C>:: + _characters (const ro_string<C>& s) + { + str_ += s; + } + + template <typename C> + unsigned long long non_negative_integer_pimpl<C>:: + post_non_negative_integer () + { + std::basic_string<C> tmp; + tmp.swap (str_); + + ro_string<C> str (tmp); + trim (str); + + unsigned long long t; + zc_istream<C> is (str); + is >> t; + + return t; + } + + // float + // + template <typename C> + void float_pimpl<C>:: + _pre () + { + str_.clear (); + } + + template <typename C> + void float_pimpl<C>:: + _characters (const ro_string<C>& s) + { + str_ += s; + } + + template <typename C> + float float_pimpl<C>:: + post_float () + { + std::basic_string<C> tmp; + tmp.swap (str_); + + ro_string<C> str (tmp); + trim (str); + + if (str == bits::positive_inf<C> ()) + return std::numeric_limits<float>::infinity (); + + if (str == bits::negative_inf<C> ()) + return -std::numeric_limits<float>::infinity (); + + if (str == bits::nan<C> ()) + return std::numeric_limits<float>::quiet_NaN (); + + float t; + zc_istream<C> is (str); + is.imbue (std::locale::classic ()); + is >> t; + + return t; + } + + // double + // + template <typename C> + void double_pimpl<C>:: + _pre () + { + str_.clear (); + } + + template <typename C> + void double_pimpl<C>:: + _characters (const ro_string<C>& s) + { + str_ += s; + } + + template <typename C> + double double_pimpl<C>:: + post_double () + { + std::basic_string<C> tmp; + tmp.swap (str_); + + ro_string<C> str (tmp); + trim (str); + + if (str == bits::positive_inf<C> ()) + return std::numeric_limits<double>::infinity (); + + if (str == bits::negative_inf<C> ()) + return -std::numeric_limits<double>::infinity (); + + if (str == bits::nan<C> ()) + return std::numeric_limits<double>::quiet_NaN (); + + double t; + zc_istream<C> is (str); + is.imbue (std::locale::classic ()); + is >> t; + + return t; + } + + // decimal + // + template <typename C> + void decimal_pimpl<C>:: + _pre () + { + str_.clear (); + } + + template <typename C> + void decimal_pimpl<C>:: + _characters (const ro_string<C>& s) + { + str_ += s; + } + + template <typename C> + double decimal_pimpl<C>:: + post_decimal () + { + std::basic_string<C> tmp; + tmp.swap (str_); + + ro_string<C> str (tmp); + trim (str); + + double t; + zc_istream<C> is (str); + is.imbue (std::locale::classic ()); + is >> t; + + return t; + } + + + // string + // + template <typename C> + void string_pimpl<C>:: + _pre () + { + str_.clear (); + } + + template <typename C> + void string_pimpl<C>:: + _characters (const ro_string<C>& s) + { + str_ += s; + } + + template <typename C> + std::basic_string<C> string_pimpl<C>:: + post_string () + { + std::basic_string<C> r; + r.swap (str_); + return r; + } + + // normalized_string + // + template <typename C> + void normalized_string_pimpl<C>:: + _pre () + { + str_.clear (); + } + + template <typename C> + void normalized_string_pimpl<C>:: + _characters (const ro_string<C>& s) + { + str_ += s; + } + + template <typename C> + std::basic_string<C> normalized_string_pimpl<C>:: + post_normalized_string () + { + typedef typename std::basic_string<C>::size_type size_type; + + size_type size (str_.size ()); + + for (size_type i (0); i < size; ++i) + { + C& c = str_[i]; + + if (c == C (0x0A) || c == C (0x0D) || c == C (0x09)) + c = C (0x20); + } + + std::basic_string<C> r; + r.swap (str_); + return r; + } + + // token + // + template <typename C> + void token_pimpl<C>:: + _pre () + { + str_.clear (); + } + + template <typename C> + void token_pimpl<C>:: + _characters (const ro_string<C>& s) + { + if (str_.size () == 0) + { + ro_string<C> tmp (s.data (), s.size ()); + + if (trim_left (tmp) != 0) + str_ += tmp; + } + else + str_ += s; + } + + template <typename C> + std::basic_string<C> token_pimpl<C>:: + post_token () + { + typedef typename std::basic_string<C>::size_type size_type; + + size_type size (str_.size ()); + size_type j (0); + + bool subs (false); + + for (size_type i (0); i < size; ++i) + { + C c = str_[i]; + + if (c == C (0x20) || c == C (0x0A) || + c == C (0x0D) || c == C (0x09)) + { + subs = true; + } + else + { + if (subs) + { + subs = false; + str_[j++] = C (0x20); + } + + str_[j++] = c; + } + } + + str_.resize (j); + + std::basic_string<C> r; + r.swap (str_); + return r; + } + + // name + // + template <typename C> + void name_pimpl<C>:: + _pre () + { + str_.clear (); + } + + template <typename C> + void name_pimpl<C>:: + _characters (const ro_string<C>& s) + { + if (str_.size () == 0) + { + ro_string<C> tmp (s.data (), s.size ()); + + if (trim_left (tmp) != 0) + str_ += tmp; + } + else + str_ += s; + } + + template <typename C> + std::basic_string<C> name_pimpl<C>:: + post_name () + { + ro_string<C> tmp (str_); + str_.resize (trim_right (tmp)); + + std::basic_string<C> r; + r.swap (str_); + return r; + } + + // nmtoken + // + template <typename C> + void nmtoken_pimpl<C>:: + _pre () + { + str_.clear (); + } + + template <typename C> + void nmtoken_pimpl<C>:: + _characters (const ro_string<C>& s) + { + if (str_.size () == 0) + { + ro_string<C> tmp (s.data (), s.size ()); + + if (trim_left (tmp) != 0) + str_ += tmp; + } + else + str_ += s; + } + + template <typename C> + std::basic_string<C> nmtoken_pimpl<C>:: + post_nmtoken () + { + ro_string<C> tmp (str_); + str_.resize (trim_right (tmp)); + + std::basic_string<C> r; + r.swap (str_); + return r; + } + + // nmtokens + // + template <typename C> + void nmtokens_pimpl<C>:: + _pre () + { + nmtokens_pskel<C>::_pre (); + seq_.clear (); + } + + template <typename C> + string_sequence<C> nmtokens_pimpl<C>:: + post_nmtokens () + { + string_sequence<C> r; + r.swap (seq_); + return r; + } + + template <typename C> + void nmtokens_pimpl<C>:: + _xsd_parse_item (const ro_string<C>& s) + { + parser_.pre (); + parser_._pre (); + parser_._characters (s); + parser_._post (); + seq_.push_back (parser_.post_nmtoken ()); + } + + // ncname + // + template <typename C> + void ncname_pimpl<C>:: + _pre () + { + str_.clear (); + } + + template <typename C> + void ncname_pimpl<C>:: + _characters (const ro_string<C>& s) + { + if (str_.size () == 0) + { + ro_string<C> tmp (s.data (), s.size ()); + + if (trim_left (tmp) != 0) + str_ += tmp; + } + else + str_ += s; + } + + template <typename C> + std::basic_string<C> ncname_pimpl<C>:: + post_ncname () + { + ro_string<C> tmp (str_); + str_.resize (trim_right (tmp)); + + std::basic_string<C> r; + r.swap (str_); + return r; + } + + // id + // + template <typename C> + void id_pimpl<C>:: + _pre () + { + str_.clear (); + } + + template <typename C> + void id_pimpl<C>:: + _characters (const ro_string<C>& s) + { + if (str_.size () == 0) + { + ro_string<C> tmp (s.data (), s.size ()); + + if (trim_left (tmp) != 0) + str_ += tmp; + } + else + str_ += s; + } + + template <typename C> + std::basic_string<C> id_pimpl<C>:: + post_id () + { + ro_string<C> tmp (str_); + str_.resize (trim_right (tmp)); + + std::basic_string<C> r; + r.swap (str_); + return r; + } + + // idref + // + template <typename C> + void idref_pimpl<C>:: + _pre () + { + str_.clear (); + } + + template <typename C> + void idref_pimpl<C>:: + _characters (const ro_string<C>& s) + { + if (str_.size () == 0) + { + ro_string<C> tmp (s.data (), s.size ()); + + if (trim_left (tmp) != 0) + str_ += tmp; + } + else + str_ += s; + } + + template <typename C> + std::basic_string<C> idref_pimpl<C>:: + post_idref () + { + ro_string<C> tmp (str_); + str_.resize (trim_right (tmp)); + + std::basic_string<C> r; + r.swap (str_); + return r; + } + + // idrefs + // + template <typename C> + void idrefs_pimpl<C>:: + _pre () + { + idrefs_pskel<C>::_pre (); + seq_.clear (); + } + + template <typename C> + string_sequence<C> idrefs_pimpl<C>:: + post_idrefs () + { + string_sequence<C> r; + r.swap (seq_); + return r; + } + + template <typename C> + void idrefs_pimpl<C>:: + _xsd_parse_item (const ro_string<C>& s) + { + parser_.pre (); + parser_._pre (); + parser_._characters (s); + parser_._post (); + seq_.push_back (parser_.post_idref ()); + } + + // language + // + template <typename C> + void language_pimpl<C>:: + _pre () + { + str_.clear (); + } + + template <typename C> + void language_pimpl<C>:: + _characters (const ro_string<C>& s) + { + if (str_.size () == 0) + { + ro_string<C> tmp (s.data (), s.size ()); + + if (trim_left (tmp) != 0) + str_ += tmp; + } + else + str_ += s; + } + + template <typename C> + std::basic_string<C> language_pimpl<C>:: + post_language () + { + ro_string<C> tmp (str_); + str_.resize (trim_right (tmp)); + + std::basic_string<C> r; + r.swap (str_); + return r; + } + + // uri + // + template <typename C> + void uri_pimpl<C>:: + _pre () + { + str_.clear (); + } + + template <typename C> + void uri_pimpl<C>:: + _characters (const ro_string<C>& s) + { + if (str_.size () == 0) + { + ro_string<C> tmp (s.data (), s.size ()); + + if (trim_left (tmp) != 0) + str_ += tmp; + } + else + str_ += s; + } + + template <typename C> + std::basic_string<C> uri_pimpl<C>:: + post_uri () + { + ro_string<C> tmp (str_); + str_.resize (trim_right (tmp)); + + std::basic_string<C> r; + r.swap (str_); + return r; + } + + // qname + // + template <typename C> + void qname_pimpl<C>:: + _pre () + { + str_.clear (); + } + + template <typename C> + void qname_pimpl<C>:: + _characters (const ro_string<C>& s) + { + if (str_.size () == 0) + { + ro_string<C> tmp (s.data (), s.size ()); + + if (trim_left (tmp) != 0) + str_ += tmp; + } + else + str_ += s; + } + + template <typename C> + qname<C> qname_pimpl<C>:: + post_qname () + { + typedef typename ro_string<C>::size_type size_type; + + ro_string<C> tmp (str_); + size_type size (trim_right (tmp)); + size_type pos (tmp.find (C (':'))); + + if (pos != ro_string<C>::npos) + { + std::basic_string<C> prefix (tmp.data (), pos++); + std::basic_string<C> name (tmp.data () + pos, size - pos); + return qname<C> (prefix, name); + } + else + { + str_.resize (size); + return qname<C> (str_); + } + } + + // base64_binary + // + template <typename C> + void base64_binary_pimpl<C>:: + _pre () + { + str_.clear (); + } + + template <typename C> + void base64_binary_pimpl<C>:: + _characters (const ro_string<C>& s) + { + if (str_.size () == 0) + { + ro_string<C> tmp (s.data (), s.size ()); + + if (trim_left (tmp) != 0) + str_ += tmp; + } + else + str_ += s; + } + + namespace bits + { + template <typename C> + inline unsigned char + base64_decode (C c) + { + unsigned char r (0xFF); + + if (c >= C('A') && c <= C ('Z')) + r = static_cast<unsigned char> (c - C ('A')); + else if (c >= C('a') && c <= C ('z')) + r = static_cast<unsigned char> (c - C ('a') + 26); + else if (c >= C('0') && c <= C ('9')) + r = static_cast<unsigned char> (c - C ('0') + 52); + else if (c == C ('+')) + r = 62; + else if (c == C ('/')) + r = 63; + + return r; + } + } + + template <typename C> + std::auto_ptr<buffer> base64_binary_pimpl<C>:: + post_base64_binary () + { + typedef typename std::basic_string<C>::size_type size_type; + + size_type size (str_.size ()); + const C* src (str_.c_str ()); + + // Remove all whitespaces. + // + { + size_type j (0); + + bool subs (false); + + for (size_type i (0); i < size; ++i) + { + C c = str_[i]; + + if (c == C (0x20) || c == C (0x0A) || + c == C (0x0D) || c == C (0x09)) + { + subs = true; + } + else + { + if (subs) + subs = false; + + str_[j++] = c; + } + } + + size = j; + str_.resize (size); + } + + // Our length should be a multiple of four. + // + size_type quad_count (size / 4); + size_type capacity (quad_count * 3 + 1); + + std::auto_ptr<buffer> buf (new buffer (capacity, capacity)); + char* dst (buf->data ()); + + size_type si (0), di (0); // Source and destination indexes. + + // Process all quads except the last one. + // + unsigned char b1, b2, b3, b4; + + for (size_type q (0); q < quad_count - 1; ++q) + { + b1 = bits::base64_decode (src[si++]); + b2 = bits::base64_decode (src[si++]); + b3 = bits::base64_decode (src[si++]); + b4 = bits::base64_decode (src[si++]); + + dst[di++] = (b1 << 2) | (b2 >> 4); + dst[di++] = (b2 << 4) | (b3 >> 2); + dst[di++] = (b3 << 6) | b4; + } + + // Process the last quad. The first two octets are always there. + // + b1 = bits::base64_decode (src[si++]); + b2 = bits::base64_decode (src[si++]); + + C e3 (src[si++]); + C e4 (src[si++]); + + if (e4 == C ('=')) + { + if (e3 == C ('=')) + { + // Two pads. Last 4 bits in b2 should be zero. + // + dst[di++] = (b1 << 2) | (b2 >> 4); + } + else + { + // One pad. Last 2 bits in b3 should be zero. + // + b3 = bits::base64_decode (e3); + + dst[di++] = (b1 << 2) | (b2 >> 4); + dst[di++] = (b2 << 4) | (b3 >> 2); + } + } + else + { + // No pads. + // + b3 = bits::base64_decode (e3); + b4 = bits::base64_decode (e4); + + dst[di++] = (b1 << 2) | (b2 >> 4); + dst[di++] = (b2 << 4) | (b3 >> 2); + dst[di++] = (b3 << 6) | b4; + } + + // Set the real size. + // + buf->size (di); + + return buf; + } + + // hex_binary + // + template <typename C> + void hex_binary_pimpl<C>:: + _pre () + { + str_.clear (); + } + + template <typename C> + void hex_binary_pimpl<C>:: + _characters (const ro_string<C>& s) + { + if (str_.size () == 0) + { + ro_string<C> tmp (s.data (), s.size ()); + + if (trim_left (tmp) != 0) + str_ += tmp; + } + else + str_ += s; + } + + namespace bits + { + template <typename C> + inline unsigned char + hex_decode (C c) + { + unsigned char r (0xFF); + + if (c >= C('0') && c <= C ('9')) + r = static_cast<unsigned char> (c - C ('0')); + else if (c >= C ('A') && c <= C ('F')) + r = static_cast<unsigned char> (10 + (c - C ('A'))); + else if (c >= C ('a') && c <= C ('f')) + r = static_cast<unsigned char> (10 + (c - C ('a'))); + + return r; + } + } + + template <typename C> + std::auto_ptr<buffer> hex_binary_pimpl<C>:: + post_hex_binary () + { + typedef typename ro_string<C>::size_type size_type; + + ro_string<C> tmp (str_); + size_type size (trim_right (tmp)); + + buffer::size_t n (size / 2); + std::auto_ptr<buffer> buf (new buffer (n)); + + const C* src (tmp.data ()); + char* dst (buf->data ()); + + for (buffer::size_t i (0); i < n; ++i) + { + unsigned char h (bits::hex_decode (src[2 * i])); + unsigned char l (bits::hex_decode (src[2 * i + 1])); + dst[i] = (h << 4) | l; + } + + return buf; + } + + // time_zone + // + namespace bits + { + // Datatypes 3.2.7.3. + // + template <typename C> + void + parse_tz (const C* s, + typename std::basic_string<C>::size_type n, + short& h, short& m) + { + // time_zone := Z|(+|-)HH:MM + // + if (n == 0) + { + return; + } + else if (s[0] == 'Z') + { + h = 0; + m = 0; + } + else if (n == 6) + { + // Parse hours. + // + h = 10 * (s[1] - '0') + (s[2] - '0'); + + // Parse minutes. + // + m = 10 * (s[4] - '0') + (s[5] - '0'); + + if (s[0] == '-') + { + h = -h; + m = -m; + } + } + } + } + + // gday + // + template <typename C> + void gday_pimpl<C>:: + _pre () + { + str_.clear (); + } + + template <typename C> + void gday_pimpl<C>:: + _characters (const ro_string<C>& s) + { + if (str_.size () == 0) + { + ro_string<C> tmp (s.data (), s.size ()); + + if (trim_left (tmp) != 0) + str_ += tmp; + } + else + str_ += s; + } + + template <typename C> + gday gday_pimpl<C>:: + post_gday () + { + typedef typename ro_string<C>::size_type size_type; + + ro_string<C> tmp (str_); + size_type size (trim_right (tmp)); + const C* s (tmp.data ()); + + unsigned short day (0); + bool z (false); + short zh (0), zm (0); + + // gday := ---DD[Z|(+|-)HH:MM] + // + if (size >= 5) + { + day = 10 * (s[3] - '0') + (s[4] - '0'); + + if (size > 5) + { + bits::parse_tz (s + 5, size - 5, zh, zm); + z = true; + } + } + + return z ? gday (day, zh, zm) : gday (day); + } + + // gmonth + // + template <typename C> + void gmonth_pimpl<C>:: + _pre () + { + str_.clear (); + } + + template <typename C> + void gmonth_pimpl<C>:: + _characters (const ro_string<C>& s) + { + if (str_.size () == 0) + { + ro_string<C> tmp (s.data (), s.size ()); + + if (trim_left (tmp) != 0) + str_ += tmp; + } + else + str_ += s; + } + + template <typename C> + gmonth gmonth_pimpl<C>:: + post_gmonth () + { + typedef typename ro_string<C>::size_type size_type; + + ro_string<C> tmp (str_); + size_type size (trim_right (tmp)); + const C* s (tmp.data ()); + + unsigned short month (0); + bool z (false); + short zh (0), zm (0); + + // gmonth := --MM[Z|(+|-)HH:MM] + // + if (size >= 4) + { + month = 10 * (s[2] - '0') + (s[3] - '0'); + + if (size > 4) + { + bits::parse_tz (s + 4, size - 4, zh, zm); + z = true; + } + } + + return z ? gmonth (month, zh, zm) : gmonth (month); + } + + // gyear + // + template <typename C> + void gyear_pimpl<C>:: + _pre () + { + str_.clear (); + } + + template <typename C> + void gyear_pimpl<C>:: + _characters (const ro_string<C>& s) + { + if (str_.size () == 0) + { + ro_string<C> tmp (s.data (), s.size ()); + + if (trim_left (tmp) != 0) + str_ += tmp; + } + else + str_ += s; + } + + template <typename C> + gyear gyear_pimpl<C>:: + post_gyear () + { + typedef typename ro_string<C>::size_type size_type; + + ro_string<C> tmp (str_); + size_type size (trim_right (tmp)); + const C* s (tmp.data ()); + + int year (0); + bool z (false); + short zh (0), zm (0); + + // gyear := [-]CCYY[N]*[Z|(+|-)HH:MM] + // + + if (size >= 4) + { + // Find the end of the year token. + // + size_type pos (4); + for (; pos < size; ++pos) + { + C c (s[pos]); + + if (c == C ('Z') || c == C ('+') || c == C ('-')) + break; + } + + ro_string<C> year_fragment (s, pos); + zc_istream<C> is (year_fragment); + is >> year; + + if (pos < size) + { + bits::parse_tz (s + pos, size - pos, zh, zm); + z = true; + } + } + + return z ? gyear (year, zh, zm) : gyear (year); + } + + // gmonth_day + // + template <typename C> + void gmonth_day_pimpl<C>:: + _pre () + { + str_.clear (); + } + + template <typename C> + void gmonth_day_pimpl<C>:: + _characters (const ro_string<C>& s) + { + if (str_.size () == 0) + { + ro_string<C> tmp (s.data (), s.size ()); + + if (trim_left (tmp) != 0) + str_ += tmp; + } + else + str_ += s; + } + + template <typename C> + gmonth_day gmonth_day_pimpl<C>:: + post_gmonth_day () + { + typedef typename ro_string<C>::size_type size_type; + + ro_string<C> tmp (str_); + size_type size (trim_right (tmp)); + const C* s (tmp.data ()); + + unsigned short month (0), day (0); + bool z (false); + short zh (0), zm (0); + + // gmonth_day := --MM-DD[Z|(+|-)HH:MM] + // + if (size >= 7) + { + month = 10 * (s[2] - '0') + (s[3] - '0'); + day = 10 * (s[5] - '0') + (s[6] - '0'); + + if (size > 7) + { + bits::parse_tz (s + 7, size - 7, zh, zm); + z = true; + } + } + + return z + ? gmonth_day (month, day, zh, zm) + : gmonth_day (month, day); + } + + // gyear_month + // + template <typename C> + void gyear_month_pimpl<C>:: + _pre () + { + str_.clear (); + } + + template <typename C> + void gyear_month_pimpl<C>:: + _characters (const ro_string<C>& s) + { + if (str_.size () == 0) + { + ro_string<C> tmp (s.data (), s.size ()); + + if (trim_left (tmp) != 0) + str_ += tmp; + } + else + str_ += s; + } + + template <typename C> + gyear_month gyear_month_pimpl<C>:: + post_gyear_month () + { + typedef typename ro_string<C>::size_type size_type; + + ro_string<C> tmp (str_); + size_type size (trim_right (tmp)); + const C* s (tmp.data ()); + + int year (0); + unsigned short month (0); + bool z (false); + short zh (0), zm (0); + + // gyear_month := [-]CCYY[N]*-MM[Z|(+|-)HH:MM] + // + + if (size >= 7) + { + // Find the end of the year token. + // + size_type pos (tmp.find (C ('-'), 4)); + + if (pos != ro_string<C>::npos && (size - pos - 1) >= 2) + { + ro_string<C> year_fragment (s, pos); + zc_istream<C> yis (year_fragment); + yis >> year; + + month = 10 * (s[pos + 1] - '0') + (s[pos + 2] - '0'); + + pos += 3; + + if (pos < size) + { + bits::parse_tz (s + pos, size - pos, zh, zm); + z = true; + } + } + } + + return z + ? gyear_month (year, month, zh, zm) + : gyear_month (year, month); + } + + // date + // + template <typename C> + void date_pimpl<C>:: + _pre () + { + str_.clear (); + } + + template <typename C> + void date_pimpl<C>:: + _characters (const ro_string<C>& s) + { + if (str_.size () == 0) + { + ro_string<C> tmp (s.data (), s.size ()); + + if (trim_left (tmp) != 0) + str_ += tmp; + } + else + str_ += s; + } + + template <typename C> + date date_pimpl<C>:: + post_date () + { + typedef typename ro_string<C>::size_type size_type; + + ro_string<C> tmp (str_); + size_type size (trim_right (tmp)); + const C* s (tmp.data ()); + + int year (0); + unsigned short month (0), day (0); + bool z (false); + short zh (0), zm (0); + + // date := [-]CCYY[N]*-MM-DD[Z|(+|-)HH:MM] + // + + if (size >= 10) + { + // Find the end of the year token. + // + size_type pos (tmp.find (C ('-'), 4)); + + if (pos != ro_string<C>::npos && (size - pos - 1) >= 5) + { + ro_string<C> year_fragment (s, pos); + zc_istream<C> yis (year_fragment); + yis >> year; + + month = 10 * (s[pos + 1] - '0') + (s[pos + 2] - '0'); + day = 10 * (s[pos + 4] - '0') + (s[pos + 5] - '0'); + + pos += 6; + + if (pos < size) + { + bits::parse_tz (s + pos, size - pos, zh, zm); + z = true; + } + } + } + + return z + ? date (year, month, day, zh, zm) + : date (year, month, day); + } + + // time + // + template <typename C> + void time_pimpl<C>:: + _pre () + { + str_.clear (); + } + + template <typename C> + void time_pimpl<C>:: + _characters (const ro_string<C>& s) + { + if (str_.size () == 0) + { + ro_string<C> tmp (s.data (), s.size ()); + + if (trim_left (tmp) != 0) + str_ += tmp; + } + else + str_ += s; + } + + template <typename C> + time time_pimpl<C>:: + post_time () + { + typedef typename ro_string<C>::size_type size_type; + + ro_string<C> tmp (str_); + size_type size (trim_right (tmp)); + const C* s (tmp.data ()); + + unsigned short hours (0), minutes (0); + double seconds (0.0); + bool z (false); + short zh (0), zm (0); + + // time := HH:MM:SS[.S+][Z|(+|-)HH:MM] + // + + if (size >= 8) + { + hours = 10 * (s[0] - '0') + (s[1] - '0'); + minutes = 10 * (s[3] - '0') + (s[4] - '0'); + + // Find the end of the seconds fragment. + // + size_type pos (8); + for (; pos < size; ++pos) + { + C c (s[pos]); + + if (c == C ('Z') || c == C ('+') || c == C ('-')) + break; + } + + ro_string<C> seconds_fragment (s + 6, pos - 6); + zc_istream<C> sis (seconds_fragment); + sis >> seconds; + + if (pos < size) + { + bits::parse_tz (s + pos, size - pos, zh, zm); + z = true; + } + } + + return z + ? time (hours, minutes, seconds, zh, zm) + : time (hours, minutes, seconds); + } + + + // date_time + // + template <typename C> + void date_time_pimpl<C>:: + _pre () + { + str_.clear (); + } + + template <typename C> + void date_time_pimpl<C>:: + _characters (const ro_string<C>& s) + { + if (str_.size () == 0) + { + ro_string<C> tmp (s.data (), s.size ()); + + if (trim_left (tmp) != 0) + str_ += tmp; + } + else + str_ += s; + } + + template <typename C> + date_time date_time_pimpl<C>:: + post_date_time () + { + typedef typename ro_string<C>::size_type size_type; + + ro_string<C> tmp (str_); + size_type size (trim_right (tmp)); + const C* s (tmp.data ()); + + int year (0); + unsigned short month (0), day (0), hours (0), minutes (0); + double seconds (0.0); + bool z (false); + short zh (0), zm (0); + + // date_time := [-]CCYY[N]*-MM-DDTHH:MM:SS[.S+][Z|(+|-)HH:MM] + // + + if (size >= 19) + { + // Find the end of the year token. + // + size_type pos (tmp.find (C ('-'), 4)); + + if (pos != ro_string<C>::npos && (size - pos - 1) >= 14) + { + ro_string<C> year_fragment (s, pos); + zc_istream<C> yis (year_fragment); + yis >> year; + + month = 10 * (s[pos + 1] - '0') + (s[pos + 2] - '0'); + day = 10 * (s[pos + 4] - '0') + (s[pos + 5] - '0'); + + pos += 7; // Point to the first H. + + hours = 10 * (s[pos] - '0') + (s[pos + 1] - '0'); + minutes = 10 * (s[pos + 3] - '0') + (s[pos + 4] - '0'); + + // Find the end of the seconds fragment. + // + pos += 6; // Point to the first S. + + size_type sec_end (pos + 2); + for (; sec_end < size; ++sec_end) + { + C c (s[sec_end]); + + if (c == C ('Z') || c == C ('+') || c == C ('-')) + break; + } + + ro_string<C> seconds_fragment (s + pos, sec_end - pos); + zc_istream<C> sis (seconds_fragment); + sis >> seconds; + + if (sec_end < size) + { + bits::parse_tz (s + sec_end, size - sec_end, zh, zm); + z = true; + } + } + } + + return z + ? date_time (year, month, day, hours, minutes, seconds, zh, zm) + : date_time (year, month, day, hours, minutes, seconds); + } + + // duration + // + template <typename C> + void duration_pimpl<C>:: + _pre () + { + str_.clear (); + } + + template <typename C> + void duration_pimpl<C>:: + _characters (const ro_string<C>& s) + { + if (str_.size () == 0) + { + ro_string<C> tmp (s.data (), s.size ()); + + if (trim_left (tmp) != 0) + str_ += tmp; + } + else + str_ += s; + } + + namespace bits + { + template <typename C> + inline typename ro_string<C>::size_type + duration_delim (const C* s, + typename ro_string<C>::size_type pos, + typename ro_string<C>::size_type size) + { + const C* p (s + pos); + for (; p < (s + size); ++p) + { + if (*p == C ('Y') || *p == C ('D') || *p == C ('M') || + *p == C ('H') || *p == C ('M') || *p == C ('S') || + *p == C ('T')) + break; + } + + return p - s; + } + } + + template <typename C> + duration duration_pimpl<C>:: + post_duration () + { + typedef typename ro_string<C>::size_type size_type; + + ro_string<C> tmp (str_); + size_type size (trim_right (tmp)); + + bool negative (false); + unsigned int years (0), months (0), days (0), hours (0), minutes (0); + double seconds (0.0); + + // duration := [-]P[nY][nM][nD][TnHnMn[.n+]S] + // + const C* s (tmp.data ()); + + if (size >= 3) + { + size_type pos (0); + + if (s[0] == C ('-')) + { + negative = true; + pos++; + } + + pos++; // Skip 'P'. + + size_type del (bits::duration_delim (s, pos, size)); + + if (del != size && s[del] == C ('Y')) + { + ro_string<C> fragment (s + pos, del - pos); + zc_istream<C> is (fragment); + is >> years; + + pos = del + 1; + del = bits::duration_delim (s, pos, size); + } + + if (del != size && s[del] == C ('M')) + { + ro_string<C> fragment (s + pos, del - pos); + zc_istream<C> is (fragment); + is >> months; + + pos = del + 1; + del = bits::duration_delim (s, pos, size); + } + + if (del != size && s[del] == C ('D')) + { + ro_string<C> fragment (s + pos, del - pos); + zc_istream<C> is (fragment); + is >> days; + + pos = del + 1; + del = bits::duration_delim (s, pos, size); + } + + if (del != size && s[del] == C ('T')) + { + pos = del + 1; + del = bits::duration_delim (s, pos, size); + + if (del != size && s[del] == C ('H')) + { + ro_string<C> fragment (s + pos, del - pos); + zc_istream<C> is (fragment); + is >> hours; + + pos = del + 1; + del = bits::duration_delim (s, pos, size); + } + + if (del != size && s[del] == C ('M')) + { + ro_string<C> fragment (s + pos, del - pos); + zc_istream<C> is (fragment); + is >> minutes; + + pos = del + 1; + del = bits::duration_delim (s, pos, size); + } + + if (del != size && s[del] == C ('S')) + { + ro_string<C> fragment (s + pos, del - pos); + zc_istream<C> is (fragment); + is >> seconds; + } + } + } + + return duration ( + negative, years, months, days, hours, minutes, seconds); + } + } + } + } +} diff --git a/libxsd/xsd/cxx/parser/non-validating/xml-schema-pskel.hxx b/libxsd/xsd/cxx/parser/non-validating/xml-schema-pskel.hxx new file mode 100644 index 0000000..7b90b91 --- /dev/null +++ b/libxsd/xsd/cxx/parser/non-validating/xml-schema-pskel.hxx @@ -0,0 +1,647 @@ +// file : xsd/cxx/parser/non-validating/xml-schema-pskel.hxx +// author : Boris Kolpackov <boris@codesynthesis.com> +// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSD_CXX_PARSER_NON_VALIDATING_XML_SCHEMA_PSKEL_HXX +#define XSD_CXX_PARSER_NON_VALIDATING_XML_SCHEMA_PSKEL_HXX + +#include <string> +#include <memory> // auto_ptr + +#include <xsd/cxx/parser/xml-schema.hxx> +#include <xsd/cxx/parser/non-validating/parser.hxx> + +namespace xsd +{ + namespace cxx + { + namespace parser + { + namespace non_validating + { + // anyType and anySimpleType. All events are routed to the + // _any_* callbacks. + // + template <typename C> + struct any_type_pskel: complex_content<C> + { + virtual bool + _start_element_impl (const ro_string<C>&, + const ro_string<C>&, + const ro_string<C>*); + + virtual bool + _end_element_impl (const ro_string<C>&, + const ro_string<C>&); + + virtual bool + _attribute_impl (const ro_string<C>&, + const ro_string<C>&, + const ro_string<C>&); + + virtual bool + _characters_impl (const ro_string<C>&); + + virtual void + post_any_type () = 0; + + static const C* + _static_type (); + + virtual const C* + _dynamic_type () const; + }; + + template <typename C> + struct any_simple_type_pskel: simple_content<C> + { + virtual bool + _characters_impl (const ro_string<C>&); + + virtual void + post_any_simple_type () = 0; + + static const C* + _static_type (); + + virtual const C* + _dynamic_type () const; + }; + + + // Boolean. + // + template <typename C> + struct boolean_pskel: simple_content<C> + { + virtual bool + post_boolean () = 0; + + static const C* + _static_type (); + + virtual const C* + _dynamic_type () const; + }; + + + // 8-bit + // + template <typename C> + struct byte_pskel: simple_content<C> + { + virtual signed char + post_byte () = 0; + + static const C* + _static_type (); + + virtual const C* + _dynamic_type () const; + }; + + template <typename C> + struct unsigned_byte_pskel: simple_content<C> + { + virtual unsigned char + post_unsigned_byte () = 0; + + static const C* + _static_type (); + + virtual const C* + _dynamic_type () const; + }; + + + // 16-bit + // + template <typename C> + struct short_pskel: simple_content<C> + { + virtual short + post_short () = 0; + + static const C* + _static_type (); + + virtual const C* + _dynamic_type () const; + }; + + template <typename C> + struct unsigned_short_pskel: simple_content<C> + { + virtual unsigned short + post_unsigned_short () = 0; + + static const C* + _static_type (); + + virtual const C* + _dynamic_type () const; + }; + + + // 32-bit + // + template <typename C> + struct int_pskel: simple_content<C> + { + virtual int + post_int () = 0; + + static const C* + _static_type (); + + virtual const C* + _dynamic_type () const; + }; + + template <typename C> + struct unsigned_int_pskel: simple_content<C> + { + virtual unsigned int + post_unsigned_int () = 0; + + static const C* + _static_type (); + + virtual const C* + _dynamic_type () const; + }; + + + // 64-bit + // + template <typename C> + struct long_pskel: simple_content<C> + { + virtual long long + post_long () = 0; + + static const C* + _static_type (); + + virtual const C* + _dynamic_type () const; + }; + + template <typename C> + struct unsigned_long_pskel: simple_content<C> + { + virtual unsigned long long + post_unsigned_long () = 0; + + static const C* + _static_type (); + + virtual const C* + _dynamic_type () const; + }; + + + // Arbitrary-length integers. + // + template <typename C> + struct integer_pskel: simple_content<C> + { + virtual long long + post_integer () = 0; + + static const C* + _static_type (); + + virtual const C* + _dynamic_type () const; + }; + + template <typename C> + struct negative_integer_pskel: simple_content<C> + { + virtual long long + post_negative_integer () = 0; + + static const C* + _static_type (); + + virtual const C* + _dynamic_type () const; + }; + + template <typename C> + struct non_positive_integer_pskel: simple_content<C> + { + virtual long long + post_non_positive_integer () = 0; + + static const C* + _static_type (); + + virtual const C* + _dynamic_type () const; + }; + + template <typename C> + struct positive_integer_pskel: simple_content<C> + { + virtual unsigned long long + post_positive_integer () = 0; + + static const C* + _static_type (); + + virtual const C* + _dynamic_type () const; + }; + + template <typename C> + struct non_negative_integer_pskel: simple_content<C> + { + virtual unsigned long long + post_non_negative_integer () = 0; + + static const C* + _static_type (); + + virtual const C* + _dynamic_type () const; + }; + + + // Floats. + // + template <typename C> + struct float_pskel: simple_content<C> + { + virtual float + post_float () = 0; + + static const C* + _static_type (); + + virtual const C* + _dynamic_type () const; + }; + + template <typename C> + struct double_pskel: simple_content<C> + { + virtual double + post_double () = 0; + + static const C* + _static_type (); + + virtual const C* + _dynamic_type () const; + }; + + template <typename C> + struct decimal_pskel: simple_content<C> + { + virtual double + post_decimal () = 0; + + static const C* + _static_type (); + + virtual const C* + _dynamic_type () const; + }; + + + // Strings. + // + template <typename C> + struct string_pskel: simple_content<C> + { + virtual std::basic_string<C> + post_string () = 0; + + static const C* + _static_type (); + + virtual const C* + _dynamic_type () const; + }; + + template <typename C> + struct normalized_string_pskel: simple_content<C> + { + virtual std::basic_string<C> + post_normalized_string () = 0; + + static const C* + _static_type (); + + virtual const C* + _dynamic_type () const; + }; + + template <typename C> + struct token_pskel: simple_content<C> + { + virtual std::basic_string<C> + post_token () = 0; + + static const C* + _static_type (); + + virtual const C* + _dynamic_type () const; + }; + + template <typename C> + struct name_pskel: simple_content<C> + { + virtual std::basic_string<C> + post_name () = 0; + + static const C* + _static_type (); + + virtual const C* + _dynamic_type () const; + }; + + template <typename C> + struct nmtoken_pskel: simple_content<C> + { + virtual std::basic_string<C> + post_nmtoken () = 0; + + static const C* + _static_type (); + + virtual const C* + _dynamic_type () const; + }; + + template <typename C> + struct nmtokens_pskel: list_base<C> + { + virtual string_sequence<C> + post_nmtokens () = 0; + + static const C* + _static_type (); + + virtual const C* + _dynamic_type () const; + }; + + template <typename C> + struct ncname_pskel: simple_content<C> + { + virtual std::basic_string<C> + post_ncname () = 0; + + static const C* + _static_type (); + + virtual const C* + _dynamic_type () const; + }; + + template <typename C> + struct id_pskel: simple_content<C> + { + virtual std::basic_string<C> + post_id () = 0; + + static const C* + _static_type (); + + virtual const C* + _dynamic_type () const; + }; + + template <typename C> + struct idref_pskel: simple_content<C> + { + virtual std::basic_string<C> + post_idref () = 0; + + static const C* + _static_type (); + + virtual const C* + _dynamic_type () const; + }; + + template <typename C> + struct idrefs_pskel: list_base<C> + { + virtual string_sequence<C> + post_idrefs () = 0; + + static const C* + _static_type (); + + virtual const C* + _dynamic_type () const; + }; + + // Language. + // + template <typename C> + struct language_pskel: simple_content<C> + { + virtual std::basic_string<C> + post_language () = 0; + + static const C* + _static_type (); + + virtual const C* + _dynamic_type () const; + }; + + // URI. + // + template <typename C> + struct uri_pskel: simple_content<C> + { + virtual std::basic_string<C> + post_uri () = 0; + + static const C* + _static_type (); + + virtual const C* + _dynamic_type () const; + }; + + // QName. + // + template <typename C> + struct qname_pskel: simple_content<C> + { + virtual qname<C> + post_qname () = 0; + + static const C* + _static_type (); + + virtual const C* + _dynamic_type () const; + }; + + // Base64 and hex binaries. + // + template <typename C> + struct base64_binary_pskel: simple_content<C> + { + virtual std::auto_ptr<buffer> + post_base64_binary () = 0; + + static const C* + _static_type (); + + virtual const C* + _dynamic_type () const; + }; + + template <typename C> + struct hex_binary_pskel: simple_content<C> + { + virtual std::auto_ptr<buffer> + post_hex_binary () = 0; + + static const C* + _static_type (); + + virtual const C* + _dynamic_type () const; + }; + + // Time and date types. + // + template <typename C> + struct gday_pskel: simple_content<C> + { + virtual gday + post_gday () = 0; + + static const C* + _static_type (); + + virtual const C* + _dynamic_type () const; + }; + + template <typename C> + struct gmonth_pskel: simple_content<C> + { + virtual gmonth + post_gmonth () = 0; + + static const C* + _static_type (); + + virtual const C* + _dynamic_type () const; + }; + + template <typename C> + struct gyear_pskel: simple_content<C> + { + virtual gyear + post_gyear () = 0; + + static const C* + _static_type (); + + virtual const C* + _dynamic_type () const; + }; + + template <typename C> + struct gmonth_day_pskel: simple_content<C> + { + virtual gmonth_day + post_gmonth_day () = 0; + + static const C* + _static_type (); + + virtual const C* + _dynamic_type () const; + }; + + template <typename C> + struct gyear_month_pskel: simple_content<C> + { + virtual gyear_month + post_gyear_month () = 0; + + static const C* + _static_type (); + + virtual const C* + _dynamic_type () const; + }; + + template <typename C> + struct date_pskel: simple_content<C> + { + virtual date + post_date () = 0; + + static const C* + _static_type (); + + virtual const C* + _dynamic_type () const; + }; + + template <typename C> + struct time_pskel: simple_content<C> + { + virtual time + post_time () = 0; + + static const C* + _static_type (); + + virtual const C* + _dynamic_type () const; + }; + + template <typename C> + struct date_time_pskel: simple_content<C> + { + virtual date_time + post_date_time () = 0; + + static const C* + _static_type (); + + virtual const C* + _dynamic_type () const; + }; + + template <typename C> + struct duration_pskel: simple_content<C> + { + virtual duration + post_duration () = 0; + + static const C* + _static_type (); + + virtual const C* + _dynamic_type () const; + }; + } + } + } +} + +#include <xsd/cxx/parser/non-validating/xml-schema-pskel.txx> + +#endif // XSD_CXX_PARSER_NON_VALIDATING_XML_SCHEMA_PSKEL_HXX + +#include <xsd/cxx/parser/non-validating/xml-schema-pskel.ixx> diff --git a/libxsd/xsd/cxx/parser/non-validating/xml-schema-pskel.ixx b/libxsd/xsd/cxx/parser/non-validating/xml-schema-pskel.ixx new file mode 100644 index 0000000..3a42c9d --- /dev/null +++ b/libxsd/xsd/cxx/parser/non-validating/xml-schema-pskel.ixx @@ -0,0 +1,1249 @@ +// file : xsd/cxx/parser/non-validating/xml-schema-pskel.ixx +// author : Boris Kolpackov <boris@codesynthesis.com> +// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#if defined(XSD_CXX_PARSER_USE_CHAR) || !defined(XSD_CXX_PARSER_USE_WCHAR) + +#ifndef XSD_CXX_PARSER_NON_VALIDATING_XML_SCHEMA_PSKEL_IXX_CHAR +#define XSD_CXX_PARSER_NON_VALIDATING_XML_SCHEMA_PSKEL_IXX_CHAR + +namespace xsd +{ + namespace cxx + { + namespace parser + { + namespace non_validating + { + template<> + inline const char* any_type_pskel<char>:: + _static_type () + { + return "anyType http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const char* any_type_pskel<char>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const char* any_simple_type_pskel<char>:: + _static_type () + { + return "anySimpleType http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const char* any_simple_type_pskel<char>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const char* boolean_pskel<char>:: + _static_type () + { + return "boolean http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const char* boolean_pskel<char>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const char* byte_pskel<char>:: + _static_type () + { + return "byte http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const char* byte_pskel<char>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const char* unsigned_byte_pskel<char>:: + _static_type () + { + return "unsignedByte http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const char* unsigned_byte_pskel<char>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const char* short_pskel<char>:: + _static_type () + { + return "short http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const char* short_pskel<char>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const char* unsigned_short_pskel<char>:: + _static_type () + { + return "unsignedShort http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const char* unsigned_short_pskel<char>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const char* int_pskel<char>:: + _static_type () + { + return "int http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const char* int_pskel<char>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const char* unsigned_int_pskel<char>:: + _static_type () + { + return "unsignedInt http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const char* unsigned_int_pskel<char>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const char* long_pskel<char>:: + _static_type () + { + return "long http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const char* long_pskel<char>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const char* unsigned_long_pskel<char>:: + _static_type () + { + return "unsignedLong http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const char* unsigned_long_pskel<char>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const char* integer_pskel<char>:: + _static_type () + { + return "integer http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const char* integer_pskel<char>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const char* negative_integer_pskel<char>:: + _static_type () + { + return "negativeInteger http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const char* negative_integer_pskel<char>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const char* non_positive_integer_pskel<char>:: + _static_type () + { + return "nonPositiveInteger http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const char* non_positive_integer_pskel<char>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const char* positive_integer_pskel<char>:: + _static_type () + { + return "positiveInteger http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const char* positive_integer_pskel<char>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const char* non_negative_integer_pskel<char>:: + _static_type () + { + return "nonNegativeInteger http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const char* non_negative_integer_pskel<char>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const char* float_pskel<char>:: + _static_type () + { + return "float http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const char* float_pskel<char>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const char* double_pskel<char>:: + _static_type () + { + return "double http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const char* double_pskel<char>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const char* decimal_pskel<char>:: + _static_type () + { + return "decimal http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const char* decimal_pskel<char>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const char* string_pskel<char>:: + _static_type () + { + return "string http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const char* string_pskel<char>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const char* normalized_string_pskel<char>:: + _static_type () + { + return "normalizedString http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const char* normalized_string_pskel<char>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const char* token_pskel<char>:: + _static_type () + { + return "token http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const char* token_pskel<char>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const char* name_pskel<char>:: + _static_type () + { + return "Name http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const char* name_pskel<char>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const char* nmtoken_pskel<char>:: + _static_type () + { + return "NMTOKEN http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const char* nmtoken_pskel<char>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const char* nmtokens_pskel<char>:: + _static_type () + { + return "NMTOKENS http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const char* nmtokens_pskel<char>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const char* ncname_pskel<char>:: + _static_type () + { + return "NCName http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const char* ncname_pskel<char>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const char* id_pskel<char>:: + _static_type () + { + return "ID http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const char* id_pskel<char>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const char* idref_pskel<char>:: + _static_type () + { + return "IDREF http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const char* idref_pskel<char>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const char* idrefs_pskel<char>:: + _static_type () + { + return "IDREFS http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const char* idrefs_pskel<char>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const char* language_pskel<char>:: + _static_type () + { + return "language http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const char* language_pskel<char>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const char* uri_pskel<char>:: + _static_type () + { + return "anyURI http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const char* uri_pskel<char>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const char* qname_pskel<char>:: + _static_type () + { + return "QName http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const char* qname_pskel<char>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const char* base64_binary_pskel<char>:: + _static_type () + { + return "base64Binary http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const char* base64_binary_pskel<char>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const char* hex_binary_pskel<char>:: + _static_type () + { + return "hexBinary http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const char* hex_binary_pskel<char>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const char* gday_pskel<char>:: + _static_type () + { + return "gDay http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const char* gday_pskel<char>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const char* gmonth_pskel<char>:: + _static_type () + { + return "gMonth http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const char* gmonth_pskel<char>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const char* gyear_pskel<char>:: + _static_type () + { + return "gYear http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const char* gyear_pskel<char>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const char* gmonth_day_pskel<char>:: + _static_type () + { + return "gMonthDay http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const char* gmonth_day_pskel<char>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const char* gyear_month_pskel<char>:: + _static_type () + { + return "gYearMonth http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const char* gyear_month_pskel<char>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const char* date_pskel<char>:: + _static_type () + { + return "date http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const char* date_pskel<char>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const char* time_pskel<char>:: + _static_type () + { + return "time http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const char* time_pskel<char>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const char* date_time_pskel<char>:: + _static_type () + { + return "dateTime http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const char* date_time_pskel<char>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const char* duration_pskel<char>:: + _static_type () + { + return "duration http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const char* duration_pskel<char>:: + _dynamic_type () const + { + return _static_type (); + } + } + } + } +} + +#endif // XSD_CXX_PARSER_NON_VALIDATING_XML_SCHEMA_PSKEL_IXX_CHAR +#endif // XSD_CXX_PARSER_USE_CHAR + + +#if defined(XSD_CXX_PARSER_USE_WCHAR) || !defined(XSD_CXX_PARSER_USE_CHAR) + +#ifndef XSD_CXX_PARSER_NON_VALIDATING_XML_SCHEMA_PSKEL_IXX_WCHAR +#define XSD_CXX_PARSER_NON_VALIDATING_XML_SCHEMA_PSKEL_IXX_WCHAR + +namespace xsd +{ + namespace cxx + { + namespace parser + { + namespace non_validating + { + template<> + inline const wchar_t* any_type_pskel<wchar_t>:: + _static_type () + { + return L"anyType http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const wchar_t* any_type_pskel<wchar_t>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const wchar_t* any_simple_type_pskel<wchar_t>:: + _static_type () + { + return L"anySimpleType http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const wchar_t* any_simple_type_pskel<wchar_t>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const wchar_t* boolean_pskel<wchar_t>:: + _static_type () + { + return L"boolean http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const wchar_t* boolean_pskel<wchar_t>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const wchar_t* byte_pskel<wchar_t>:: + _static_type () + { + return L"byte http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const wchar_t* byte_pskel<wchar_t>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const wchar_t* unsigned_byte_pskel<wchar_t>:: + _static_type () + { + return L"unsignedByte http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const wchar_t* unsigned_byte_pskel<wchar_t>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const wchar_t* short_pskel<wchar_t>:: + _static_type () + { + return L"short http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const wchar_t* short_pskel<wchar_t>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const wchar_t* unsigned_short_pskel<wchar_t>:: + _static_type () + { + return L"unsignedShort http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const wchar_t* unsigned_short_pskel<wchar_t>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const wchar_t* int_pskel<wchar_t>:: + _static_type () + { + return L"int http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const wchar_t* int_pskel<wchar_t>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const wchar_t* unsigned_int_pskel<wchar_t>:: + _static_type () + { + return L"unsignedInt http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const wchar_t* unsigned_int_pskel<wchar_t>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const wchar_t* long_pskel<wchar_t>:: + _static_type () + { + return L"long http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const wchar_t* long_pskel<wchar_t>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const wchar_t* unsigned_long_pskel<wchar_t>:: + _static_type () + { + return L"unsignedLong http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const wchar_t* unsigned_long_pskel<wchar_t>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const wchar_t* integer_pskel<wchar_t>:: + _static_type () + { + return L"integer http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const wchar_t* integer_pskel<wchar_t>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const wchar_t* negative_integer_pskel<wchar_t>:: + _static_type () + { + return L"negativeInteger http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const wchar_t* negative_integer_pskel<wchar_t>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const wchar_t* non_positive_integer_pskel<wchar_t>:: + _static_type () + { + return L"nonPositiveInteger http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const wchar_t* non_positive_integer_pskel<wchar_t>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const wchar_t* positive_integer_pskel<wchar_t>:: + _static_type () + { + return L"positiveInteger http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const wchar_t* positive_integer_pskel<wchar_t>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const wchar_t* non_negative_integer_pskel<wchar_t>:: + _static_type () + { + return L"nonNegativeInteger http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const wchar_t* non_negative_integer_pskel<wchar_t>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const wchar_t* float_pskel<wchar_t>:: + _static_type () + { + return L"float http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const wchar_t* float_pskel<wchar_t>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const wchar_t* double_pskel<wchar_t>:: + _static_type () + { + return L"double http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const wchar_t* double_pskel<wchar_t>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const wchar_t* decimal_pskel<wchar_t>:: + _static_type () + { + return L"decimal http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const wchar_t* decimal_pskel<wchar_t>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const wchar_t* string_pskel<wchar_t>:: + _static_type () + { + return L"string http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const wchar_t* string_pskel<wchar_t>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const wchar_t* normalized_string_pskel<wchar_t>:: + _static_type () + { + return L"normalizedString http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const wchar_t* normalized_string_pskel<wchar_t>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const wchar_t* token_pskel<wchar_t>:: + _static_type () + { + return L"token http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const wchar_t* token_pskel<wchar_t>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const wchar_t* name_pskel<wchar_t>:: + _static_type () + { + return L"Name http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const wchar_t* name_pskel<wchar_t>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const wchar_t* nmtoken_pskel<wchar_t>:: + _static_type () + { + return L"NMTOKEN http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const wchar_t* nmtoken_pskel<wchar_t>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const wchar_t* nmtokens_pskel<wchar_t>:: + _static_type () + { + return L"NMTOKENS http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const wchar_t* nmtokens_pskel<wchar_t>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const wchar_t* ncname_pskel<wchar_t>:: + _static_type () + { + return L"NCName http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const wchar_t* ncname_pskel<wchar_t>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const wchar_t* id_pskel<wchar_t>:: + _static_type () + { + return L"ID http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const wchar_t* id_pskel<wchar_t>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const wchar_t* idref_pskel<wchar_t>:: + _static_type () + { + return L"IDREF http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const wchar_t* idref_pskel<wchar_t>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const wchar_t* idrefs_pskel<wchar_t>:: + _static_type () + { + return L"IDREFS http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const wchar_t* idrefs_pskel<wchar_t>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const wchar_t* language_pskel<wchar_t>:: + _static_type () + { + return L"language http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const wchar_t* language_pskel<wchar_t>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const wchar_t* uri_pskel<wchar_t>:: + _static_type () + { + return L"anyURI http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const wchar_t* uri_pskel<wchar_t>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const wchar_t* qname_pskel<wchar_t>:: + _static_type () + { + return L"QName http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const wchar_t* qname_pskel<wchar_t>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const wchar_t* base64_binary_pskel<wchar_t>:: + _static_type () + { + return L"base64Binary http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const wchar_t* base64_binary_pskel<wchar_t>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const wchar_t* hex_binary_pskel<wchar_t>:: + _static_type () + { + return L"hexBinary http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const wchar_t* hex_binary_pskel<wchar_t>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const wchar_t* gday_pskel<wchar_t>:: + _static_type () + { + return L"gDay http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const wchar_t* gday_pskel<wchar_t>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const wchar_t* gmonth_pskel<wchar_t>:: + _static_type () + { + return L"gMonth http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const wchar_t* gmonth_pskel<wchar_t>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const wchar_t* gyear_pskel<wchar_t>:: + _static_type () + { + return L"gYear http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const wchar_t* gyear_pskel<wchar_t>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const wchar_t* gmonth_day_pskel<wchar_t>:: + _static_type () + { + return L"gMonthDay http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const wchar_t* gmonth_day_pskel<wchar_t>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const wchar_t* gyear_month_pskel<wchar_t>:: + _static_type () + { + return L"gYearMonth http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const wchar_t* gyear_month_pskel<wchar_t>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const wchar_t* date_pskel<wchar_t>:: + _static_type () + { + return L"date http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const wchar_t* date_pskel<wchar_t>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const wchar_t* time_pskel<wchar_t>:: + _static_type () + { + return L"time http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const wchar_t* time_pskel<wchar_t>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const wchar_t* date_time_pskel<wchar_t>:: + _static_type () + { + return L"dateTime http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const wchar_t* date_time_pskel<wchar_t>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const wchar_t* duration_pskel<wchar_t>:: + _static_type () + { + return L"duration http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const wchar_t* duration_pskel<wchar_t>:: + _dynamic_type () const + { + return _static_type (); + } + } + } + } +} + +#endif // XSD_CXX_PARSER_NON_VALIDATING_XML_SCHEMA_PSKEL_IXX_WCHAR +#endif // XSD_CXX_PARSER_USE_WCHAR diff --git a/libxsd/xsd/cxx/parser/non-validating/xml-schema-pskel.txx b/libxsd/xsd/cxx/parser/non-validating/xml-schema-pskel.txx new file mode 100644 index 0000000..899eae6 --- /dev/null +++ b/libxsd/xsd/cxx/parser/non-validating/xml-schema-pskel.txx @@ -0,0 +1,69 @@ +// file : xsd/cxx/parser/non-validating/xml-schema-pskel.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 + +namespace xsd +{ + namespace cxx + { + namespace parser + { + namespace non_validating + { + // any_type + // + + template <typename C> + bool any_type_pskel<C>:: + _start_element_impl (const ro_string<C>& ns, + const ro_string<C>& name, + const ro_string<C>* type) + { + _start_any_element (ns, name, type); + this->complex_content<C>::context_.top ().any_ = true; + return true; + } + + template <typename C> + bool any_type_pskel<C>:: + _end_element_impl (const ro_string<C>& ns, const ro_string<C>& name) + { + this->complex_content<C>::context_.top ().any_ = false; + _end_any_element (ns, name); + return true; + } + + + template <typename C> + bool any_type_pskel<C>:: + _attribute_impl (const ro_string<C>& ns, + const ro_string<C>& name, + const ro_string<C>& value) + { + _any_attribute (ns, name, value); + return true; + } + + template <typename C> + bool any_type_pskel<C>:: + _characters_impl (const ro_string<C>& s) + { + _any_characters (s); + return true; + } + + // any_simple_type + // + + template <typename C> + bool any_simple_type_pskel<C>:: + _characters_impl (const ro_string<C>& s) + { + _any_characters (s); + return true; + } + } + } + } +} diff --git a/libxsd/xsd/cxx/parser/schema-exceptions.hxx b/libxsd/xsd/cxx/parser/schema-exceptions.hxx new file mode 100644 index 0000000..f1fb358 --- /dev/null +++ b/libxsd/xsd/cxx/parser/schema-exceptions.hxx @@ -0,0 +1,187 @@ +// file : xsd/cxx/parser/schema-exceptions.hxx +// author : Boris Kolpackov <boris@codesynthesis.com> +// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSD_CXX_PARSER_SCHEMA_EXCEPTIONS_HXX +#define XSD_CXX_PARSER_SCHEMA_EXCEPTIONS_HXX + +#include <string> + +namespace xsd +{ + namespace cxx + { + namespace parser + { + template <typename C> + struct schema_exception + { + public: + virtual + ~schema_exception () + { + } + + unsigned long + line () const + { + return line_; + } + + void + line (unsigned long l) + { + line_ = l; + } + + unsigned long + column () const + { + return column_; + } + + void + column (unsigned long c) + { + column_ = c; + } + + const std::basic_string<C>& + id () const + { + return id_; + } + + void + id (const std::basic_string<C>& id) + { + id_ = id; + } + + virtual std::basic_string<C> + message () const = 0; + + protected: + unsigned long line_; + unsigned long column_; + std::basic_string<C> id_; + }; + + // + // + template <typename C> + struct expected_element: schema_exception<C> + { + virtual + ~expected_element (); + + expected_element (const std::basic_string<C>& expected_namespace, + const std::basic_string<C>& expected_name); + + expected_element (const std::basic_string<C>& expected_namespace, + const std::basic_string<C>& expected_name, + const std::basic_string<C>& encountered_namespace, + const std::basic_string<C>& encountered_name); + + const std::basic_string<C>& + expected_namespace () const + { + return expected_namespace_; + } + + const std::basic_string<C>& + expected_name () const + { + return expected_name_; + } + + // Encountered element namespace and name are empty if none + // encountered. + // + const std::basic_string<C>& + encountered_namespace () const + { + return encountered_namespace_; + } + + const std::basic_string<C>& + encountered_name () const + { + return encountered_name_; + } + + virtual std::basic_string<C> + message () const; + + private: + std::basic_string<C> expected_namespace_; + std::basic_string<C> expected_name_; + + std::basic_string<C> encountered_namespace_; + std::basic_string<C> encountered_name_; + }; + + + // + // + template <typename C> + struct unexpected_element: schema_exception<C> + { + virtual + ~unexpected_element (); + + unexpected_element (const std::basic_string<C>& encountered_namespace, + const std::basic_string<C>& encountered_name); + + const std::basic_string<C>& + encountered_namespace () const + { + return encountered_namespace_; + } + + const std::basic_string<C>& + encountered_name () const + { + return encountered_name_; + } + + virtual std::basic_string<C> + message () const; + + private: + std::basic_string<C> encountered_namespace_; + std::basic_string<C> encountered_name_; + }; + + // + // + template <typename C> + struct dynamic_type: schema_exception<C> + { + virtual + ~dynamic_type () throw (); + + dynamic_type (const std::basic_string<C>& type); + + const std::basic_string<C>& + type () const + { + return type_; + } + + virtual std::basic_string<C> + message () const; + + private: + std::basic_string<C> type_; + }; + } + } +} + +#include <xsd/cxx/parser/schema-exceptions.txx> + +#endif // XSD_CXX_PARSER_SCHEMA_EXCEPTIONS_HXX + +#include <xsd/cxx/parser/schema-exceptions.ixx> diff --git a/libxsd/xsd/cxx/parser/schema-exceptions.ixx b/libxsd/xsd/cxx/parser/schema-exceptions.ixx new file mode 100644 index 0000000..98cc2db --- /dev/null +++ b/libxsd/xsd/cxx/parser/schema-exceptions.ixx @@ -0,0 +1,145 @@ +// file : xsd/cxx/parser/schema-exceptions.ixx +// author : Boris Kolpackov <boris@codesynthesis.com> +// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#if defined(XSD_CXX_PARSER_USE_CHAR) || !defined(XSD_CXX_PARSER_USE_WCHAR) + +#ifndef XSD_CXX_PARSER_SCHEMA_EXCEPTIONS_IXX_CHAR +#define XSD_CXX_PARSER_SCHEMA_EXCEPTIONS_IXX_CHAR + +namespace xsd +{ + namespace cxx + { + namespace parser + { + // expected_element + // + template<> + inline + std::basic_string<char> expected_element<char>:: + message () const + { + std::basic_string<char> r ("expected element '"); + r += expected_namespace_; + r += expected_namespace_.empty () ? "" : "#"; + r += expected_name_; + r += "'"; + + if (!encountered_name_.empty ()) + { + r += " instead of '"; + r += encountered_namespace_; + r += encountered_namespace_.empty () ? "" : "#"; + r += encountered_name_; + r += "'"; + } + + return r; + } + + // unexpected_element + // + template<> + inline + std::basic_string<char> unexpected_element<char>:: + message () const + { + std::basic_string<char> r ("unexpected element '"); + r += encountered_namespace_; + r += encountered_namespace_.empty () ? "" : "#"; + r += encountered_name_; + r += "'"; + return r; + } + + // dynamic_type + // + template<> + inline + std::basic_string<char> dynamic_type<char>:: + message () const + { + std::basic_string<char> r ("invalid xsi:type '"); + r += type_; + r += "'"; + return r; + } + } + } +} + +#endif // XSD_CXX_PARSER_SCHEMA_EXCEPTIONS_IXX_CHAR +#endif // XSD_CXX_PARSER_USE_CHAR + + +#if defined(XSD_CXX_PARSER_USE_WCHAR) || !defined(XSD_CXX_PARSER_USE_CHAR) + +#ifndef XSD_CXX_PARSER_SCHEMA_EXCEPTIONS_IXX_WCHAR +#define XSD_CXX_PARSER_SCHEMA_EXCEPTIONS_IXX_WCHAR + +namespace xsd +{ + namespace cxx + { + namespace parser + { + // expected_element + // + template<> + inline + std::basic_string<wchar_t> expected_element<wchar_t>:: + message () const + { + std::basic_string<wchar_t> r (L"expected element '"); + r += expected_namespace_; + r += expected_namespace_.empty () ? L"" : L"#"; + r += expected_name_; + r += L"'"; + + if (!encountered_name_.empty ()) + { + r += L" instead of '"; + r += encountered_namespace_; + r += encountered_namespace_.empty () ? L"" : L"#"; + r += encountered_name_; + r += L"'"; + } + + return r; + } + + // unexpected_element + // + template<> + inline + std::basic_string<wchar_t> unexpected_element<wchar_t>:: + message () const + { + std::basic_string<wchar_t> r (L"unexpected element '"); + r += encountered_namespace_; + r += encountered_namespace_.empty () ? L"" : L"#"; + r += encountered_name_; + r += L"'"; + return r; + } + + // dynamic_type + // + template<> + inline + std::basic_string<wchar_t> dynamic_type<wchar_t>:: + message () const + { + std::basic_string<wchar_t> r (L"invalid xsi:type '"); + r += type_; + r += L"'"; + return r; + } + } + } +} + +#endif // XSD_CXX_PARSER_SCHEMA_EXCEPTIONS_IXX_WCHAR +#endif // XSD_CXX_PARSER_USE_WCHAR diff --git a/libxsd/xsd/cxx/parser/schema-exceptions.txx b/libxsd/xsd/cxx/parser/schema-exceptions.txx new file mode 100644 index 0000000..0d19604 --- /dev/null +++ b/libxsd/xsd/cxx/parser/schema-exceptions.txx @@ -0,0 +1,75 @@ +// file : xsd/cxx/parser/schema-exceptions.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 + +namespace xsd +{ + namespace cxx + { + namespace parser + { + // expected_element + // + template <typename C> + expected_element<C>:: + ~expected_element () + { + } + + template <typename C> + expected_element<C>:: + expected_element (const std::basic_string<C>& expected_namespace, + const std::basic_string<C>& expected_name) + : expected_namespace_ (expected_namespace), + expected_name_ (expected_name) + { + } + + template <typename C> + expected_element<C>:: + expected_element (const std::basic_string<C>& expected_namespace, + const std::basic_string<C>& expected_name, + const std::basic_string<C>& encountered_namespace, + const std::basic_string<C>& encountered_name) + : expected_namespace_ (expected_namespace), + expected_name_ (expected_name), + encountered_namespace_ (encountered_namespace), + encountered_name_ (encountered_name) + { + } + + // unexpected_element + // + template <typename C> + unexpected_element<C>:: + ~unexpected_element () + { + } + + template <typename C> + unexpected_element<C>:: + unexpected_element (const std::basic_string<C>& encountered_namespace, + const std::basic_string<C>& encountered_name) + : encountered_namespace_ (encountered_namespace), + encountered_name_ (encountered_name) + { + } + + // dynamic_type + // + template <typename C> + dynamic_type<C>:: + ~dynamic_type () throw () + { + } + + template <typename C> + dynamic_type<C>:: + dynamic_type (const std::basic_string<C>& type) + : type_ (type) + { + } + } + } +} diff --git a/libxsd/xsd/cxx/parser/substitution-map.hxx b/libxsd/xsd/cxx/parser/substitution-map.hxx new file mode 100644 index 0000000..60c0ec8 --- /dev/null +++ b/libxsd/xsd/cxx/parser/substitution-map.hxx @@ -0,0 +1,230 @@ +// file : xsd/cxx/parser/substitution-map.hxx +// author : Boris Kolpackov <boris@codesynthesis.com> +// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSD_CXX_PARSER_SUBSTITUTION_MAP_HXX +#define XSD_CXX_PARSER_SUBSTITUTION_MAP_HXX + +#include <map> +#include <cstddef> // std::size_t + +#include <xsd/cxx/ro-string.hxx> + +namespace xsd +{ + namespace cxx + { + namespace parser + { + template <typename C> + struct substitution_map_key + { + substitution_map_key (const C* ns, const C* name) + : ns_ (ns), name_ (name) + { + } + + substitution_map_key (const ro_string<C>& ns, + const ro_string<C>& name) + : ns_ (ns.data (), ns.size ()), + name_ (name.data (), name.size ()) + { + } + + substitution_map_key (const substitution_map_key& x) + : ns_ (x.ns_.data (), x.ns_.size ()), + name_ (x.name_.data (), x.name_.size ()) + { + } + + private: + substitution_map_key& + operator= (const substitution_map_key&); + + public: + const ro_string<C>& + ns () const + { + return ns_; + } + + const ro_string<C>& + name () const + { + return name_; + } + + private: + const ro_string<C> ns_; + const ro_string<C> name_; + }; + + template <typename C> + inline bool + operator< (const substitution_map_key<C>& x, + const substitution_map_key<C>& y) + { + int r (x.name ().compare (y.name ())); + return r < 0 || (r == 0 && x.ns () < y.ns ()); + } + + template <typename C> + struct substitution_map_value + { + substitution_map_value (const C* ns, const C* name, const C* type) + : ns_ (ns), name_ (name), type_ (type) + { + } + + substitution_map_value (const substitution_map_value& x) + : ns_ (x.ns_.data (), x.ns_.size ()), + name_ (x.name_.data (), x.name_.size ()), + type_ (x.type_.data (), x.type_.size ()) + { + } + + substitution_map_value& + operator= (const substitution_map_value& x) + { + if (this != &x) + { + ns_.assign (x.ns_.data (), x.ns_.size ()); + name_.assign (x.name_.data (), x.name_.size ()); + type_.assign (x.type_.data (), x.type_.size ()); + } + + return *this; + } + + public: + const ro_string<C>& + ns () const + { + return ns_; + } + + const ro_string<C>& + name () const + { + return name_; + } + + const ro_string<C>& + type () const + { + return type_; + } + + private: + ro_string<C> ns_; + ro_string<C> name_; + ro_string<C> type_; + }; + + template <typename C> + struct substitution_map + { + void + insert (const C* member_ns, + const C* member_name, + const C* root_ns, + const C* root_name, + const C* member_type) + { + key k (member_ns, member_name); + value v (root_ns, root_name, member_type); + map_.insert (std::pair<key, value> (k, v)); + } + + // Check and get the type set if found. + // + bool + check (const ro_string<C>& ns, + const ro_string<C>& name, + const C* root_ns, + const C* root_name, + const ro_string<C>*& type) const + { + + return map_.empty () + ? false + : check_ (ns, name, root_ns, root_name, &type); + } + + // Check but don't care about the type. + // + bool + check (const ro_string<C>& ns, + const ro_string<C>& name, + const C* root_ns, + const C* root_name) const + { + + return map_.empty () + ? false + : check_ (ns, name, root_ns, root_name, 0); + } + + private: + bool + check_ (const ro_string<C>& ns, + const ro_string<C>& name, + const C* root_ns, + const C* root_name, + const ro_string<C>** type) const; + + private: + typedef substitution_map_key<C> key; + typedef substitution_map_value<C> value; + typedef std::map<key, value> map; + + map map_; + }; + + + // Translation unit initializer. + // + template<typename C> + struct substitution_map_init + { + static substitution_map<C>* map; + static std::size_t count; + + substitution_map_init (); + ~substitution_map_init (); + }; + + template<typename C> + substitution_map<C>* substitution_map_init<C>::map = 0; + + template<typename C> + std::size_t substitution_map_init<C>::count = 0; + + template<typename C> + inline substitution_map<C>& + substitution_map_instance () + { + return *substitution_map_init<C>::map; + } + + + // Map entry initializer. + // + template<typename C> + struct substitution_map_entry + { + substitution_map_entry (const C* member_ns, + const C* member_name, + const C* root_ns, + const C* root_name, + const C* member_type); + }; + } + } +} + +#include <xsd/cxx/parser/substitution-map.txx> + +#endif // XSD_CXX_PARSER_SUBSTITUTION_MAP_HXX + diff --git a/libxsd/xsd/cxx/parser/substitution-map.txx b/libxsd/xsd/cxx/parser/substitution-map.txx new file mode 100644 index 0000000..c9d4cb1 --- /dev/null +++ b/libxsd/xsd/cxx/parser/substitution-map.txx @@ -0,0 +1,76 @@ +// file : xsd/cxx/parser/substitution-map.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 + +namespace xsd +{ + namespace cxx + { + namespace parser + { + template <typename C> + bool substitution_map<C>:: + check_ (const ro_string<C>& ns, + const ro_string<C>& name, + const C* root_ns, + const C* root_name, + const ro_string<C>** type) const + { + key k (ns, name); + typename map::const_iterator i (map_.find (k)); + + if (i == map_.end ()) + return false; + + const value& v (i->second); + + bool r (false); + + if (v.name () == root_name && v.ns () == root_ns) + r = true; + else + r = check_ (v.ns (), v.name (), root_ns, root_name, 0); + + if (r && type != 0 && *type == 0) + *type = &v.type (); + + return r; + } + + // substitution_map_init + // + template<typename C> + substitution_map_init<C>:: + substitution_map_init () + { + if (count == 0) + map = new substitution_map<C>; + + ++count; + } + + template<typename C> + substitution_map_init<C>:: + ~substitution_map_init () + { + if (--count == 0) + delete map; + } + + // substitution_map_entry + // + template<typename C> + substitution_map_entry<C>:: + substitution_map_entry (const C* member_ns, + const C* member_name, + const C* root_ns, + const C* root_name, + const C* member_type) + { + substitution_map_instance<C> ().insert ( + member_ns, member_name, root_ns, root_name, member_type); + } + } + } +} diff --git a/libxsd/xsd/cxx/parser/validating/exceptions.hxx b/libxsd/xsd/cxx/parser/validating/exceptions.hxx new file mode 100644 index 0000000..1112c60 --- /dev/null +++ b/libxsd/xsd/cxx/parser/validating/exceptions.hxx @@ -0,0 +1,153 @@ +// file : xsd/cxx/parser/validating/exceptions.hxx +// author : Boris Kolpackov <boris@codesynthesis.com> +// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSD_CXX_PARSER_VALIDATING_EXCEPTIONS_HXX +#define XSD_CXX_PARSER_VALIDATING_EXCEPTIONS_HXX + +#include <string> + +#include <xsd/cxx/parser/schema-exceptions.hxx> +#include <xsd/cxx/ro-string.hxx> + +namespace xsd +{ + namespace cxx + { + namespace parser + { + namespace validating + { + // + // + template <typename C> + struct expected_attribute: schema_exception<C> + { + virtual + ~expected_attribute (); + + expected_attribute (const std::basic_string<C>& expected_namespace, + const std::basic_string<C>& expected_name); + + const std::basic_string<C>& + expected_namespace () const + { + return expected_namespace_; + } + + const std::basic_string<C>& + expected_name () const + { + return expected_name_; + } + + virtual std::basic_string<C> + message () const; + + private: + std::basic_string<C> expected_namespace_; + std::basic_string<C> expected_name_; + }; + + // + // + template <typename C> + struct unexpected_attribute: schema_exception<C> + { + virtual + ~unexpected_attribute (); + + unexpected_attribute ( + const std::basic_string<C>& encountered_namespace, + const std::basic_string<C>& encountered_name); + + + const std::basic_string<C>& + encountered_namespace () const + { + return encountered_namespace_; + } + + const std::basic_string<C>& + encountered_name () const + { + return encountered_name_; + } + + virtual std::basic_string<C> + message () const; + + private: + std::basic_string<C> encountered_namespace_; + std::basic_string<C> encountered_name_; + }; + + + // + // + template <typename C> + struct unexpected_characters: schema_exception<C> + { + virtual + ~unexpected_characters (); + + unexpected_characters (const std::basic_string<C>& s); + + const std::basic_string<C>& + characters () const + { + return characters_; + } + + virtual std::basic_string<C> + message () const; + + private: + std::basic_string<C> characters_; + }; + + // + // + template <typename C> + struct invalid_value: schema_exception<C> + { + virtual + ~invalid_value (); + + invalid_value (const C* type, const std::basic_string<C>& value); + + invalid_value (const C* type, const ro_string<C>& value); + + invalid_value (const std::basic_string<C>& type, + const std::basic_string<C>& value); + + const std::basic_string<C>& + type () const + { + return type_; + } + + const std::basic_string<C>& + value () const + { + return value_; + } + + virtual std::basic_string<C> + message () const; + + private: + std::basic_string<C> type_; + std::basic_string<C> value_; + }; + } + } + } +} + +#include <xsd/cxx/parser/validating/exceptions.txx> + +#endif // XSD_CXX_PARSER_VALIDATING_EXCEPTIONS_HXX + +#include <xsd/cxx/parser/validating/exceptions.ixx> diff --git a/libxsd/xsd/cxx/parser/validating/exceptions.ixx b/libxsd/xsd/cxx/parser/validating/exceptions.ixx new file mode 100644 index 0000000..6535cb8 --- /dev/null +++ b/libxsd/xsd/cxx/parser/validating/exceptions.ixx @@ -0,0 +1,163 @@ +// file : xsd/cxx/parser/validating/exceptions.ixx +// author : Boris Kolpackov <boris@codesynthesis.com> +// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#if defined(XSD_CXX_PARSER_USE_CHAR) || !defined(XSD_CXX_PARSER_USE_WCHAR) + +#ifndef XSD_CXX_PARSER_VALIDATING_EXCEPTIONS_IXX_CHAR +#define XSD_CXX_PARSER_VALIDATING_EXCEPTIONS_IXX_CHAR + +namespace xsd +{ + namespace cxx + { + namespace parser + { + namespace validating + { + // expected_attribute + // + template<> + inline + std::basic_string<char> expected_attribute<char>:: + message () const + { + std::basic_string<char> r ("expected attribute '"); + r += expected_namespace_; + r += expected_namespace_.empty () ? "" : "#"; + r += expected_name_; + r += "'"; + return r; + } + + // unexpected_attribute + // + template<> + inline + std::basic_string<char> unexpected_attribute<char>:: + message () const + { + std::basic_string<char> r ("unexpected attribute '"); + r += encountered_namespace_; + r += encountered_namespace_.empty () ? "" : "#"; + r += encountered_name_; + r += "'"; + return r; + } + + // unexpected_characters + // + template<> + inline + std::basic_string<char> unexpected_characters<char>:: + message () const + { + std::basic_string<char> r ("unexpected characters '"); + r += characters_; + r += "'"; + return r; + } + + // invalid_value + // + template<> + inline + std::basic_string<char> invalid_value<char>:: + message () const + { + std::basic_string<char> r ("'"); + r += value_; + r += "' is not a valid value representation "; + r += "for type '"; + r += type_; + r += "'"; + return r; + } + } + } + } +} + +#endif // XSD_CXX_PARSER_VALIDATING_EXCEPTIONS_IXX_CHAR +#endif // XSD_CXX_PARSER_USE_CHAR + + +#if defined(XSD_CXX_PARSER_USE_WCHAR) || !defined(XSD_CXX_PARSER_USE_CHAR) + +#ifndef XSD_CXX_PARSER_VALIDATING_EXCEPTIONS_IXX_WCHAR +#define XSD_CXX_PARSER_VALIDATING_EXCEPTIONS_IXX_WCHAR + +namespace xsd +{ + namespace cxx + { + namespace parser + { + namespace validating + { + // expected_attribute + // + template<> + inline + std::basic_string<wchar_t> expected_attribute<wchar_t>:: + message () const + { + std::basic_string<wchar_t> r (L"expected attribute '"); + r += expected_namespace_; + r += expected_namespace_.empty () ? L"" : L"#"; + r += expected_name_; + r += L"'"; + return r; + } + + // unexpected_attribute + // + template<> + inline + std::basic_string<wchar_t> unexpected_attribute<wchar_t>:: + message () const + { + std::basic_string<wchar_t> r (L"unexpected attribute '"); + r += encountered_namespace_; + r += encountered_namespace_.empty () ? L"" : L"#"; + r += encountered_name_; + r += L"'"; + return r; + } + + // unexpected_characters + // + template<> + inline + std::basic_string<wchar_t> unexpected_characters<wchar_t>:: + message () const + { + std::basic_string<wchar_t> r (L"unexpected characters '"); + r += characters_; + r += L"'"; + return r; + } + + // invalid_value + // + template<> + inline + std::basic_string<wchar_t> invalid_value<wchar_t>:: + message () const + { + std::basic_string<wchar_t> r (L"'"); + r += value_; + r += L"' is not a valid value representation "; + r += L"for type '"; + r += type_; + r += L"'"; + return r; + } + } + } + } +} + +#endif // XSD_CXX_PARSER_VALIDATING_EXCEPTIONS_IXX_WCHAR +#endif // XSD_CXX_PARSER_USE_WCHAR diff --git a/libxsd/xsd/cxx/parser/validating/exceptions.txx b/libxsd/xsd/cxx/parser/validating/exceptions.txx new file mode 100644 index 0000000..f8ffe80 --- /dev/null +++ b/libxsd/xsd/cxx/parser/validating/exceptions.txx @@ -0,0 +1,97 @@ +// file : xsd/cxx/parser/validating/exceptions.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 + +namespace xsd +{ + namespace cxx + { + namespace parser + { + namespace validating + { + // expected_attribute + // + template <typename C> + expected_attribute<C>:: + ~expected_attribute () + { + } + + template <typename C> + expected_attribute<C>:: + expected_attribute (const std::basic_string<C>& expected_namespace, + const std::basic_string<C>& expected_name) + : expected_namespace_ (expected_namespace), + expected_name_ (expected_name) + { + } + + // unexpected_attribute + // + template <typename C> + unexpected_attribute<C>:: + ~unexpected_attribute () + { + } + + template <typename C> + unexpected_attribute<C>:: + unexpected_attribute (const std::basic_string<C>& encountered_namespace, + const std::basic_string<C>& encountered_name) + : encountered_namespace_ (encountered_namespace), + encountered_name_ (encountered_name) + { + } + + // unexpected_characters + // + template <typename C> + unexpected_characters<C>:: + ~unexpected_characters () + { + } + + template <typename C> + unexpected_characters<C>:: + unexpected_characters (const std::basic_string<C>& s) + : characters_ (s) + { + } + + // invalid_value + // + template <typename C> + invalid_value<C>:: + ~invalid_value () + { + } + + template <typename C> + invalid_value<C>:: + invalid_value (const C* type, + const std::basic_string<C>& value) + : type_ (type), value_ (value) + { + } + + template <typename C> + invalid_value<C>:: + invalid_value (const C* type, + const ro_string<C>& value) + : type_ (type), value_ (value) + { + } + + template <typename C> + invalid_value<C>:: + invalid_value (const std::basic_string<C>& type, + const std::basic_string<C>& value) + : type_ (type), value_ (value) + { + } + } + } + } +} diff --git a/libxsd/xsd/cxx/parser/validating/inheritance-map.hxx b/libxsd/xsd/cxx/parser/validating/inheritance-map.hxx new file mode 100644 index 0000000..ebd1d03 --- /dev/null +++ b/libxsd/xsd/cxx/parser/validating/inheritance-map.hxx @@ -0,0 +1,92 @@ +// file : xsd/cxx/parser/validating/inheritance-map.hxx +// author : Boris Kolpackov <boris@codesynthesis.com> +// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSD_CXX_PARSER_VALIDATING_INHERITANCE_MAP_HXX +#define XSD_CXX_PARSER_VALIDATING_INHERITANCE_MAP_HXX + +#include <map> +#include <cstddef> // std::size_t + +#include <xsd/cxx/ro-string.hxx> + +namespace xsd +{ + namespace cxx + { + namespace parser + { + namespace validating + { + template <typename C> + struct string_comparison + { + bool + operator() (const C* x, const C* y) const + { + ro_string<C> s (x); + return s.compare (y) < 0; + } + }; + + template <typename C> + struct inheritance_map + { + void + insert (const C* derived, const C* base) + { + map_[derived] = base; + } + + bool + check (const C* derived, const ro_string<C>& base) const; + + private: + typedef std::map<const C*, const C*, string_comparison<C> > map; + map map_; + }; + + + // Translation unit initializer. + // + template<typename C> + struct inheritance_map_init + { + static inheritance_map<C>* map; + static std::size_t count; + + inheritance_map_init (); + ~inheritance_map_init (); + }; + + template<typename C> + inheritance_map<C>* inheritance_map_init<C>::map = 0; + + template<typename C> + std::size_t inheritance_map_init<C>::count = 0; + + template<typename C> + inline inheritance_map<C>& + inheritance_map_instance () + { + return *inheritance_map_init<C>::map; + } + + + // Map entry initializer. + // + template<typename C> + struct inheritance_map_entry + { + inheritance_map_entry (const C* derived, const C* base); + }; + } + } + } +} + +#include <xsd/cxx/parser/validating/inheritance-map.txx> + +#endif // XSD_CXX_PARSER_VALIDATING_INHERITANCE_MAP_HXX + diff --git a/libxsd/xsd/cxx/parser/validating/inheritance-map.txx b/libxsd/xsd/cxx/parser/validating/inheritance-map.txx new file mode 100644 index 0000000..5e70409 --- /dev/null +++ b/libxsd/xsd/cxx/parser/validating/inheritance-map.txx @@ -0,0 +1,65 @@ +// file : xsd/cxx/parser/validating/inheritance-map.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 + +namespace xsd +{ + namespace cxx + { + namespace parser + { + namespace validating + { + template <typename C> + bool inheritance_map<C>:: + check (const C* derived, const ro_string<C>& base) const + { + if (base == derived) + return true; + + typename map::const_iterator i (map_.find (derived)); + + if (i != map_.end ()) + { + if (base == i->second) + return true; + else + return check (i->second, base); + } + + return false; + } + + // inheritance_map_init + // + template<typename C> + inheritance_map_init<C>:: + inheritance_map_init () + { + if (count == 0) + map = new inheritance_map<C>; + + ++count; + } + + template<typename C> + inheritance_map_init<C>:: + ~inheritance_map_init () + { + if (--count == 0) + delete map; + } + + // inheritance_map_entry + // + template<typename C> + inheritance_map_entry<C>:: + inheritance_map_entry (const C* derived, const C* base) + { + inheritance_map_instance<C> ().insert (derived, base); + } + } + } + } +} diff --git a/libxsd/xsd/cxx/parser/validating/parser.hxx b/libxsd/xsd/cxx/parser/validating/parser.hxx new file mode 100644 index 0000000..4feb898 --- /dev/null +++ b/libxsd/xsd/cxx/parser/validating/parser.hxx @@ -0,0 +1,471 @@ +// file : xsd/cxx/parser/validating/parser.hxx +// author : Boris Kolpackov <boris@codesynthesis.com> +// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSD_CXX_PARSER_VALIDATING_PARSER_HXX +#define XSD_CXX_PARSER_VALIDATING_PARSER_HXX + +#include <stack> +#include <cstddef> // std::size_t +#include <cstring> // std::memcpy + +#include <xsd/cxx/ro-string.hxx> +#include <xsd/cxx/parser/elements.hxx> + +namespace xsd +{ + namespace cxx + { + namespace parser + { + namespace validating + { + // + // + template <typename C> + struct empty_content: parser_base<C> + { + // These functions are called when wildcard content + // is encountered. Use them to handle mixed content + // models, any/anyAttribute, and anyType/anySimpleType. + // By default these functions do nothing. + // + + // The type argument is a type name and namespace from the + // xsi:type attribute in the form "<name> <namespace>" with + // the space and namespace part absent if the type does not + // have a namespace or 0 if xsi:type is not present. + // + virtual void + _start_any_element (const ro_string<C>& ns, + const ro_string<C>& name, + const ro_string<C>* type); + + virtual void + _end_any_element (const ro_string<C>& ns, + const ro_string<C>& name); + + virtual void + _any_attribute (const ro_string<C>& ns, + const ro_string<C>& name, + const ro_string<C>& value); + + virtual void + _any_characters (const ro_string<C>&); + + + // + // + virtual bool + _start_element_impl (const ro_string<C>&, + const ro_string<C>&, + const ro_string<C>*); + + virtual bool + _end_element_impl (const ro_string<C>&, + const ro_string<C>&); + + virtual bool + _attribute_impl (const ro_string<C>&, + const ro_string<C>&, + const ro_string<C>&); + + virtual bool + _characters_impl (const ro_string<C>&); + + + // + // + virtual void + _start_element (const ro_string<C>&, + const ro_string<C>&, + const ro_string<C>*); + + virtual void + _end_element (const ro_string<C>&, + const ro_string<C>&); + + virtual void + _attribute (const ro_string<C>&, + const ro_string<C>&, + const ro_string<C>&); + + virtual void + _characters (const ro_string<C>&); + + + // + // + virtual void + _expected_element (const C* expected_ns, + const C* expected_name); + + virtual void + _expected_element (const C* expected_ns, + const C* expected_name, + const ro_string<C>& encountered_ns, + const ro_string<C>& encountered_name); + + virtual void + _unexpected_element (const ro_string<C>& ns, + const ro_string<C>& name); + + virtual void + _expected_attribute (const C* expected_ns, + const C* expected_name); + + virtual void + _unexpected_attribute (const ro_string<C>& ns, + const ro_string<C>& name, + const ro_string<C>& value); + + virtual void + _unexpected_characters (const ro_string<C>&); + }; + + + // + // + template <typename C> + struct simple_content: empty_content<C> + { + // + // + virtual void + _attribute (const ro_string<C>& ns, + const ro_string<C>& name, + const ro_string<C>& value); + + virtual void + _characters (const ro_string<C>&); + + // + // + virtual bool + _attribute_impl (const ro_string<C>&, + const ro_string<C>&, + const ro_string<C>&); + + // + // + virtual void + _pre_impl (); + + virtual void + _post_impl (); + + + // Implementation callbacks. + // + virtual void + _pre_a_validate (); + + virtual void + _post_a_validate (); + + + // Attribute validation: during phase one we are searching for + // matching attributes (Structures, section 3.4.4, clause 2.1). + // During phase two we are searching for attribute wildcards + // (section 3.4.4, clause 2.2). Both phases run across + // inheritance hierarchy from derived to base for extension + // only. Both functions return true if the match was found and + // validation has been performed. + // + virtual bool + _attribute_impl_phase_one (const ro_string<C>& ns, + const ro_string<C>& name, + const ro_string<C>& value); + + virtual bool + _attribute_impl_phase_two (const ro_string<C>& ns, + const ro_string<C>& name, + const ro_string<C>& value); + }; + + + // + // + template <typename C> + struct complex_content: empty_content<C> + { + // + // + virtual void + _start_element (const ro_string<C>& ns, + const ro_string<C>& name, + const ro_string<C>* type); + + virtual void + _end_element (const ro_string<C>& ns, + const ro_string<C>& name); + + virtual void + _attribute (const ro_string<C>& ns, + const ro_string<C>& name, + const ro_string<C>& value); + + virtual void + _characters (const ro_string<C>&); + + // + // + virtual bool + _attribute_impl (const ro_string<C>&, + const ro_string<C>&, + const ro_string<C>&); + + // + // + virtual void + _pre_impl (); + + virtual void + _post_impl (); + + + // Implementation callbacks. + // + virtual void + _pre_e_validate (); + + virtual void + _post_e_validate (); + + virtual void + _pre_a_validate (); + + virtual void + _post_a_validate (); + + + // Attribute validation: during phase one we are searching for + // matching attributes (Structures, section 3.4.4, clause 2.1). + // During phase two we are searching for attribute wildcards + // (section 3.4.4, clause 2.2). Both phases run across + // inheritance hierarchy from derived to base for extension + // only. Both functions return true if the match was found and + // validation has been performed. + // + virtual bool + _attribute_impl_phase_one (const ro_string<C>& ns, + const ro_string<C>& name, + const ro_string<C>& value); + + virtual bool + _attribute_impl_phase_two (const ro_string<C>& ns, + const ro_string<C>& name, + const ro_string<C>& value); + protected: + struct state + { + state () + : any_ (false), depth_ (0), parser_ (0) + { + } + + bool any_; + std::size_t depth_; + parser_base<C>* parser_; + }; + + // Optimized state stack for non-recursive case (one element). + // + struct state_stack + { + state_stack () + : size_ (0) + { + } + + void + push (const state& s) + { + if (size_ > 0) + rest_.push (top_); + + top_ = s; + ++size_; + } + + void + pop () + { + if (size_ > 1) + { + top_ = rest_.top (); + rest_.pop (); + } + + --size_; + } + + const state& + top () const + { + return top_; + } + + state& + top () + { + return top_; + } + + state& + under_top () + { + return rest_.top (); + } + + private: + state top_; + std::stack<state> rest_; + std::size_t size_; + }; + + state_stack context_; + }; + + // Base for xsd:list. + // + template <typename C> + struct list_base: simple_content<C> + { + virtual void + _xsd_parse_item (const ro_string<C>&) = 0; + + virtual void + _pre_impl (); + + virtual void + _characters (const ro_string<C>&); + + virtual void + _post_impl (); + + protected: + std::basic_string<C> buf_; + }; + } + + // POD stack with pre-allocated first element. You may + // need to pad your elements to get the proper alignment. + // + struct pod_stack + { + ~pod_stack () + { + delete[] data_; + } + + pod_stack (std::size_t element_size, void* first_element) + : el_size_ (element_size), first_ (first_element), + data_ (0), size_ (0), capacity_ (0) + { + } + + public: + void + pop () + { + --size_; + } + + void + push () + { + if (size_ > capacity_) + grow (); + + ++size_; + } + + void* + top () + { + return size_ == 1 ? first_ : data_ + (size_ - 1) * el_size_; + } + + void* + under_top () + { + return size_ == 2 ? first_ : data_ + (size_ - 2) * el_size_; + } + + std::size_t + element_size () const + { + return el_size_; + } + + private: + void + grow () + { + std::size_t c (capacity_ ? capacity_ * 2 : 8); + char* d (new char[c * el_size_]); + + if (size_ > 1) + std::memcpy (d, data_, (size_ - 1) * el_size_); + + delete[] data_; + + data_ = d; + capacity_ = c; + } + + private: + std::size_t el_size_; + void* first_; + char* data_; + std::size_t size_; + std::size_t capacity_; + }; + + namespace validating + { + // Validation state stack for the 'all' particle. + // + struct all_stack + { + all_stack (std::size_t n, unsigned char* first) + : stack_ (n, first) + { + } + + void + push () + { + stack_.push (); + + unsigned char* p (static_cast<unsigned char*> (stack_.top ())); + + for (std::size_t i (0); i < stack_.element_size (); ++i) + p[i] = 0; + } + + void + pop () + { + stack_.pop (); + } + + unsigned char* + top () + { + return static_cast<unsigned char*> (stack_.top ()); + } + + private: + pod_stack stack_; + }; + } + } + } +} + +#include <xsd/cxx/parser/validating/parser.txx> + +#endif // XSD_CXX_PARSER_VALIDATING_PARSER_HXX diff --git a/libxsd/xsd/cxx/parser/validating/parser.txx b/libxsd/xsd/cxx/parser/validating/parser.txx new file mode 100644 index 0000000..4cf9b7e --- /dev/null +++ b/libxsd/xsd/cxx/parser/validating/parser.txx @@ -0,0 +1,667 @@ +// file : xsd/cxx/parser/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> +#include <xsd/cxx/parser/validating/exceptions.hxx> + +namespace xsd +{ + namespace cxx + { + namespace parser + { + namespace 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)) + _unexpected_element (ns, name); + } + + 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)) + _unexpected_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)) + _unexpected_attribute (ns, name, value); + } + + template <typename C> + void empty_content<C>:: + _characters (const ro_string<C>& s) + { + if (!_characters_impl (s)) + _unexpected_characters (s); + } + + // + // + template <typename C> + void empty_content<C>:: + _expected_element (const C* ex_ns, const C* ex_name) + { + throw expected_element<C> (ex_ns, ex_name); + } + + template <typename C> + void empty_content<C>:: + _expected_element (const C* ex_ns, + const C* ex_name, + const ro_string<C>& en_ns, + const ro_string<C>& en_name) + { + throw expected_element<C> (ex_ns, ex_name, en_ns, en_name); + } + + template <typename C> + void empty_content<C>:: + _unexpected_element (const ro_string<C>& ns, + const ro_string<C>& name) + { + throw unexpected_element<C> (ns, name); + } + + template <typename C> + void empty_content<C>:: + _expected_attribute (const C* ex_ns, const C* ex_name) + { + throw expected_attribute<C> (ex_ns, ex_name); + } + + template <typename C> + void empty_content<C>:: + _unexpected_attribute (const ro_string<C>& ns, + const ro_string<C>& name, + const ro_string<C>&) + { + throw unexpected_attribute<C> (ns, name); + } + + template <typename C> + void empty_content<C>:: + _unexpected_characters (const ro_string<C>& s) + { + throw unexpected_characters<C> (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)) + _unexpected_attribute (ns, name, value); + } + + template <typename C> + void simple_content<C>:: + _characters (const ro_string<C>& str) + { + if (!_characters_impl (str)) + { + // Mixed content is implemented in the generated code + // by overriding _characters_impl and forwarding to + // _any_characters. + // + + // Scan the string for any non-whitespace characters + // (Structures, section 3.4.4, clause 1.3). + // + for (typename ro_string<C>::size_type i (0), e (str.size ()); + i < e; ++i) + { + C c (str[i]); + + if (c != C (0x20) && // space + c != C (0x0D) && // carriage return + c != C (0x09) && // tab + c != C (0x0A)) + _unexpected_characters (str); + } + } + } + + template <typename C> + void simple_content<C>:: + _pre_impl () + { + this->_pre (); + _pre_a_validate (); + } + + template <typename C> + void simple_content<C>:: + _post_impl () + { + _post_a_validate (); + this->_post (); + } + + template <typename C> + void simple_content<C>:: + _pre_a_validate () + { + } + + template <typename C> + void simple_content<C>:: + _post_a_validate () + { + } + + template <typename C> + bool simple_content<C>:: + _attribute_impl (const ro_string<C>& ns, + const ro_string<C>& name, + const ro_string<C>& value) + { + return _attribute_impl_phase_one (ns, name, value) || + _attribute_impl_phase_two (ns, name, value); + } + + template <typename C> + bool simple_content<C>:: + _attribute_impl_phase_one (const ro_string<C>&, + const ro_string<C>&, + const ro_string<C>&) + { + return false; + } + + template <typename C> + bool simple_content<C>:: + _attribute_impl_phase_two (const ro_string<C>&, + const ro_string<C>&, + const ro_string<C>&) + { + return false; + } + + + // 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)) + _unexpected_element (ns, name); + 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)) + _unexpected_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; + + const 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)) + _unexpected_attribute (ns, name, value); + } + } + + template <typename C> + void complex_content<C>:: + _characters (const ro_string<C>& str) + { + const 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)) + { + // Mixed content is implemented in the generated code + // by overriding _characters_impl and forwarding to + // _any_characters. + // + + // Scan the string for any non-whitespace characters + // (Structures, section 3.4.4, clause 1.3). + // + for (typename ro_string<C>::size_type i (0), e (str.size ()); + i < e; ++i) + { + C c (str[i]); + + if (c != C (0x20) && // space + c != C (0x0D) && // carriage return + c != C (0x09) && // tab + c != C (0x0A)) + _unexpected_characters (str); + } + } + } + } + + template <typename C> + void complex_content<C>:: + _pre_impl () + { + context_.push (state ()); + this->_pre (); + _pre_a_validate (); + _pre_e_validate (); + } + + template <typename C> + void complex_content<C>:: + _post_impl () + { + _post_e_validate (); + _post_a_validate (); + this->_post (); + context_.pop (); + } + + template <typename C> + void complex_content<C>:: + _pre_e_validate () + { + } + + template <typename C> + void complex_content<C>:: + _post_e_validate () + { + } + + template <typename C> + void complex_content<C>:: + _pre_a_validate () + { + } + + template <typename C> + void complex_content<C>:: + _post_a_validate () + { + } + + template <typename C> + bool complex_content<C>:: + _attribute_impl (const ro_string<C>& ns, + const ro_string<C>& name, + const ro_string<C>& value) + { + return _attribute_impl_phase_one (ns, name, value) || + _attribute_impl_phase_two (ns, name, value); + } + + template <typename C> + bool complex_content<C>:: + _attribute_impl_phase_one (const ro_string<C>&, + const ro_string<C>&, + const ro_string<C>&) + { + return false; + } + + template <typename C> + bool complex_content<C>:: + _attribute_impl_phase_two (const ro_string<C>&, + const ro_string<C>&, + const ro_string<C>&) + { + return false; + } + + + // 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 (); + } + } + } + } +} diff --git a/libxsd/xsd/cxx/parser/validating/xml-schema-pimpl.hxx b/libxsd/xsd/cxx/parser/validating/xml-schema-pimpl.hxx new file mode 100644 index 0000000..5f2f03f --- /dev/null +++ b/libxsd/xsd/cxx/parser/validating/xml-schema-pimpl.hxx @@ -0,0 +1,1121 @@ +// file : xsd/cxx/parser/validating/xml-schema-pimpl.hxx +// author : Boris Kolpackov <boris@codesynthesis.com> +// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSD_CXX_PARSER_VALIDATING_XML_SCHEMA_PIMPL_HXX +#define XSD_CXX_PARSER_VALIDATING_XML_SCHEMA_PIMPL_HXX + +#include <string> + +#include <xsd/cxx/parser/validating/xml-schema-pskel.hxx> + +namespace xsd +{ + namespace cxx + { + namespace parser + { + namespace validating + { + // any_type + // + template <typename C> + struct any_type_pimpl: virtual any_type_pskel<C> + { + virtual void + post_any_type (); + }; + + // any_simple_type + // + template <typename C> + struct any_simple_type_pimpl: virtual any_simple_type_pskel<C> + { + virtual void + post_any_simple_type (); + }; + + // boolean + // + template <typename C> + struct boolean_pimpl: virtual boolean_pskel<C> + { + virtual void + _pre (); + + virtual void + _characters (const ro_string<C>&); + + virtual void + _post (); + + virtual bool + post_boolean (); + + protected: + std::basic_string<C> str_; + bool value_; + }; + + + // 8-bit + // + template <typename C> + struct byte_pimpl: virtual byte_pskel<C> + { + virtual void + _pre (); + + virtual void + _characters (const ro_string<C>&); + + virtual void + _post (); + + virtual signed char + post_byte (); + + protected: + std::basic_string<C> str_; + signed char value_; + }; + + + template <typename C> + struct unsigned_byte_pimpl: virtual unsigned_byte_pskel<C> + { + virtual void + _pre (); + + virtual void + _characters (const ro_string<C>&); + + virtual void + _post (); + + virtual unsigned char + post_unsigned_byte (); + + protected: + std::basic_string<C> str_; + unsigned char value_; + }; + + + // 16-bit + // + template <typename C> + struct short_pimpl: virtual short_pskel<C> + { + virtual void + _pre (); + + virtual void + _characters (const ro_string<C>&); + + virtual void + _post (); + + virtual short + post_short (); + + protected: + std::basic_string<C> str_; + short value_; + }; + + + template <typename C> + struct unsigned_short_pimpl: virtual unsigned_short_pskel<C> + { + virtual void + _pre (); + + virtual void + _characters (const ro_string<C>&); + + virtual void + _post (); + + virtual unsigned short + post_unsigned_short (); + + protected: + std::basic_string<C> str_; + unsigned short value_; + }; + + + // 32-bit + // + template <typename C> + struct int_pimpl: virtual int_pskel<C> + { + virtual void + _pre (); + + virtual void + _characters (const ro_string<C>&); + + virtual void + _post (); + + virtual int + post_int (); + + protected: + std::basic_string<C> str_; + int value_; + }; + + + template <typename C> + struct unsigned_int_pimpl: virtual unsigned_int_pskel<C> + { + virtual void + _pre (); + + virtual void + _characters (const ro_string<C>&); + + virtual void + _post (); + + virtual unsigned int + post_unsigned_int (); + + protected: + std::basic_string<C> str_; + unsigned int value_; + }; + + + // 64-bit + // + template <typename C> + struct long_pimpl: virtual long_pskel<C> + { + virtual void + _pre (); + + virtual void + _characters (const ro_string<C>&); + + virtual void + _post (); + + virtual long long + post_long (); + + protected: + std::basic_string<C> str_; + long long value_; + }; + + + template <typename C> + struct unsigned_long_pimpl: virtual unsigned_long_pskel<C> + { + virtual void + _pre (); + + virtual void + _characters (const ro_string<C>&); + + virtual void + _post (); + + virtual unsigned long long + post_unsigned_long (); + + protected: + std::basic_string<C> str_; + unsigned long long value_; + }; + + + // Arbitrary-length integers. + // + template <typename C> + struct integer_pimpl: virtual integer_pskel<C> + { + virtual void + _pre (); + + virtual void + _characters (const ro_string<C>&); + + virtual void + _post (); + + virtual long long + post_integer (); + + protected: + std::basic_string<C> str_; + long long value_; + }; + + template <typename C> + struct negative_integer_pimpl: virtual negative_integer_pskel<C> + { + virtual void + _pre (); + + virtual void + _characters (const ro_string<C>&); + + virtual void + _post (); + + virtual long long + post_negative_integer (); + + protected: + std::basic_string<C> str_; + long long value_; + }; + + template <typename C> + struct non_positive_integer_pimpl: virtual non_positive_integer_pskel<C> + { + virtual void + _pre (); + + virtual void + _characters (const ro_string<C>&); + + virtual void + _post (); + + virtual long long + post_non_positive_integer (); + + protected: + std::basic_string<C> str_; + long long value_; + }; + + template <typename C> + struct positive_integer_pimpl: virtual positive_integer_pskel<C> + { + virtual void + _pre (); + + virtual void + _characters (const ro_string<C>&); + + virtual void + _post (); + + virtual unsigned long long + post_positive_integer (); + + protected: + std::basic_string<C> str_; + unsigned long long value_; + }; + + template <typename C> + struct non_negative_integer_pimpl: virtual non_negative_integer_pskel<C> + { + virtual void + _pre (); + + virtual void + _characters (const ro_string<C>&); + + virtual void + _post (); + + virtual unsigned long long + post_non_negative_integer (); + + protected: + std::basic_string<C> str_; + unsigned long long value_; + }; + + + // Floats. + // + template <typename C> + struct float_pimpl: virtual float_pskel<C> + { + virtual void + _pre (); + + virtual void + _characters (const ro_string<C>&); + + virtual void + _post (); + + virtual float + post_float (); + + protected: + std::basic_string<C> str_; + float value_; + }; + + + template <typename C> + struct double_pimpl: virtual double_pskel<C> + { + virtual void + _pre (); + + virtual void + _characters (const ro_string<C>&); + + virtual void + _post (); + + virtual double + post_double (); + + protected: + std::basic_string<C> str_; + double value_; + }; + + + template <typename C> + struct decimal_pimpl: virtual decimal_pskel<C> + { + virtual void + _pre (); + + virtual void + _characters (const ro_string<C>&); + + virtual void + _post (); + + virtual double + post_decimal (); + + protected: + std::basic_string<C> str_; + double value_; + }; + + + // Strings. + // + template <typename C> + struct string_pimpl: virtual string_pskel<C> + { + virtual void + _pre (); + + virtual void + _characters (const ro_string<C>&); + + virtual std::basic_string<C> + post_string (); + + protected: + std::basic_string<C> str_; + }; + + template <typename C> + struct normalized_string_pimpl: virtual normalized_string_pskel<C> + { + virtual void + _pre (); + + virtual void + _characters (const ro_string<C>&); + + virtual std::basic_string<C> + post_normalized_string (); + + protected: + std::basic_string<C> str_; + }; + + template <typename C> + struct token_pimpl: virtual token_pskel<C> + { + virtual void + _pre (); + + virtual void + _characters (const ro_string<C>&); + + virtual std::basic_string<C> + post_token (); + + protected: + std::basic_string<C> str_; + }; + + template <typename C> + struct name_pimpl: virtual name_pskel<C> + { + virtual void + _pre (); + + virtual void + _characters (const ro_string<C>&); + + virtual void + _post (); + + virtual std::basic_string<C> + post_name (); + + protected: + std::basic_string<C> str_; + }; + + template <typename C> + struct nmtoken_pimpl: virtual nmtoken_pskel<C> + { + virtual void + _pre (); + + virtual void + _characters (const ro_string<C>&); + + virtual void + _post (); + + virtual std::basic_string<C> + post_nmtoken (); + + protected: + std::basic_string<C> str_; + }; + + template <typename C> + struct nmtokens_pimpl: virtual nmtokens_pskel<C> + { + virtual void + _pre (); + + virtual void + _xsd_parse_item (const ro_string<C>&); + + virtual void + _post (); + + virtual string_sequence<C> + post_nmtokens (); + + protected: + string_sequence<C> seq_; + nmtoken_pimpl<C> parser_; + }; + + template <typename C> + struct ncname_pimpl: virtual ncname_pskel<C> + { + virtual void + _pre (); + + virtual void + _characters (const ro_string<C>&); + + virtual void + _post (); + + virtual std::basic_string<C> + post_ncname (); + + protected: + std::basic_string<C> str_; + }; + + template <typename C> + struct id_pimpl: virtual id_pskel<C> + { + virtual void + _pre (); + + virtual void + _characters (const ro_string<C>&); + + virtual void + _post (); + + virtual std::basic_string<C> + post_id (); + + protected: + std::basic_string<C> str_; + }; + + template <typename C> + struct idref_pimpl: virtual idref_pskel<C> + { + virtual void + _pre (); + + virtual void + _characters (const ro_string<C>&); + + virtual void + _post (); + + virtual std::basic_string<C> + post_idref (); + + protected: + std::basic_string<C> str_; + }; + + template <typename C> + struct idrefs_pimpl: virtual idrefs_pskel<C> + { + virtual void + _pre (); + + virtual void + _xsd_parse_item (const ro_string<C>&); + + virtual void + _post (); + + virtual string_sequence<C> + post_idrefs (); + + protected: + string_sequence<C> seq_; + idref_pimpl<C> parser_; + }; + + // language + // + template <typename C> + struct language_pimpl: virtual language_pskel<C> + { + virtual void + _pre (); + + virtual void + _characters (const ro_string<C>&); + + virtual void + _post (); + + virtual std::basic_string<C> + post_language (); + + protected: + std::basic_string<C> str_; + }; + + // anyURI + // + template <typename C> + struct uri_pimpl: virtual uri_pskel<C> + { + virtual void + _pre (); + + virtual void + _characters (const ro_string<C>&); + + virtual std::basic_string<C> + post_uri (); + + protected: + std::basic_string<C> str_; + }; + + // QName + // + template <typename C> + struct qname_pimpl: virtual qname_pskel<C> + { + virtual void + _pre (); + + virtual void + _characters (const ro_string<C>&); + + virtual void + _post (); + + virtual qname<C> + post_qname (); + + protected: + std::basic_string<C> str_; + std::basic_string<C> name_; + std::basic_string<C> prefix_; + }; + + // base64Binary + // + template <typename C> + struct base64_binary_pimpl: virtual base64_binary_pskel<C> + { + virtual void + _pre (); + + virtual void + _characters (const ro_string<C>&); + + virtual void + _post (); + + virtual std::auto_ptr<buffer> + post_base64_binary (); + + protected: + std::basic_string<C> str_; + std::auto_ptr<buffer> buf_; + }; + + // hexBinary + // + template <typename C> + struct hex_binary_pimpl: virtual hex_binary_pskel<C> + { + virtual void + _pre (); + + virtual void + _characters (const ro_string<C>&); + + virtual void + _post (); + + virtual std::auto_ptr<buffer> + post_hex_binary (); + + protected: + std::basic_string<C> str_; + std::auto_ptr<buffer> buf_; + }; + + // gday + // + template <typename C> + struct gday_pimpl: virtual gday_pskel<C> + { + virtual void + _pre (); + + virtual void + _characters (const ro_string<C>&); + + virtual void + _post (); + + virtual gday + post_gday (); + + protected: + std::basic_string<C> str_; + unsigned short day_; + bool z_; + short zh_, zm_; + }; + + // gmonth + // + template <typename C> + struct gmonth_pimpl: virtual gmonth_pskel<C> + { + virtual void + _pre (); + + virtual void + _characters (const ro_string<C>&); + + virtual void + _post (); + + virtual gmonth + post_gmonth (); + + protected: + std::basic_string<C> str_; + unsigned short month_; + bool z_; + short zh_, zm_; + }; + + // gyear + // + template <typename C> + struct gyear_pimpl: virtual gyear_pskel<C> + { + virtual void + _pre (); + + virtual void + _characters (const ro_string<C>&); + + virtual void + _post (); + + virtual gyear + post_gyear (); + + protected: + std::basic_string<C> str_; + int year_; + bool z_; + short zh_, zm_; + }; + + // gmonth_day + // + template <typename C> + struct gmonth_day_pimpl: virtual gmonth_day_pskel<C> + { + virtual void + _pre (); + + virtual void + _characters (const ro_string<C>&); + + virtual void + _post (); + + virtual gmonth_day + post_gmonth_day (); + + protected: + std::basic_string<C> str_; + unsigned short month_; + unsigned short day_; + bool z_; + short zh_, zm_; + }; + + // gyear_month + // + template <typename C> + struct gyear_month_pimpl: virtual gyear_month_pskel<C> + { + virtual void + _pre (); + + virtual void + _characters (const ro_string<C>&); + + virtual void + _post (); + + virtual gyear_month + post_gyear_month (); + + protected: + std::basic_string<C> str_; + int year_; + unsigned short month_; + bool z_; + short zh_, zm_; + }; + + // date + // + template <typename C> + struct date_pimpl: virtual date_pskel<C> + { + virtual void + _pre (); + + virtual void + _characters (const ro_string<C>&); + + virtual void + _post (); + + virtual date + post_date (); + + protected: + std::basic_string<C> str_; + int year_; + unsigned short month_; + unsigned short day_; + bool z_; + short zh_, zm_; + }; + + // time + // + template <typename C> + struct time_pimpl: virtual time_pskel<C> + { + virtual void + _pre (); + + virtual void + _characters (const ro_string<C>&); + + virtual void + _post (); + + virtual time + post_time (); + + protected: + std::basic_string<C> str_; + unsigned short hours_; + unsigned short minutes_; + double seconds_; + bool z_; + short zh_, zm_; + }; + + // date_time + // + template <typename C> + struct date_time_pimpl: virtual date_time_pskel<C> + { + virtual void + _pre (); + + virtual void + _characters (const ro_string<C>&); + + virtual void + _post (); + + virtual date_time + post_date_time (); + + protected: + std::basic_string<C> str_; + int year_; + unsigned short month_; + unsigned short day_; + unsigned short hours_; + unsigned short minutes_; + double seconds_; + bool z_; + short zh_, zm_; + }; + + // duration + // + template <typename C> + struct duration_pimpl: virtual duration_pskel<C> + { + virtual void + _pre (); + + virtual void + _characters (const ro_string<C>&); + + virtual void + _post (); + + virtual duration + post_duration (); + + protected: + std::basic_string<C> str_; + bool negative_; + unsigned int years_; + unsigned int months_; + unsigned int days_; + unsigned int hours_; + unsigned int minutes_; + double seconds_; + }; + + // Literals. + // + namespace bits + { + template<typename C> + const C* + boolean (); + + template<typename C> + const C* + byte (); + + template<typename C> + const C* + unsigned_byte (); + + template<typename C> + const C* + short_ (); + + template<typename C> + const C* + unsigned_short (); + + template<typename C> + const C* + int_ (); + + template<typename C> + const C* + unsigned_int (); + + template<typename C> + const C* + long_ (); + + template<typename C> + const C* + unsigned_long (); + + template<typename C> + const C* + integer (); + + template<typename C> + const C* + negative_integer (); + + template<typename C> + const C* + non_positive_integer (); + + template<typename C> + const C* + non_negative_integer (); + + template<typename C> + const C* + positive_integer (); + + template<typename C> + const C* + float_ (); + + template<typename C> + const C* + double_ (); + + template<typename C> + const C* + decimal (); + + template<typename C> + const C* + name (); + + template<typename C> + const C* + nmtoken (); + + template<typename C> + const C* + nmtokens (); + + template<typename C> + const C* + ncname (); + + template<typename C> + const C* + id (); + + template<typename C> + const C* + idref (); + + template<typename C> + const C* + idrefs (); + + template<typename C> + const C* + language (); + + template<typename C> + const C* + qname (); + + template<typename C> + const C* + base64_binary (); + + template<typename C> + const C* + hex_binary (); + + template<typename C> + const C* + gday (); + + template<typename C> + const C* + gmonth (); + + template<typename C> + const C* + gyear (); + + template<typename C> + const C* + gmonth_day (); + + template<typename C> + const C* + gyear_month (); + + template<typename C> + const C* + date (); + + template<typename C> + const C* + time (); + + template<typename C> + const C* + date_time (); + + template<typename C> + const C* + duration (); + + // float literals: INF -INF NaN + // + template<typename C> + const C* + positive_inf (); + + template<typename C> + const C* + negative_inf (); + + template<typename C> + const C* + nan (); + + // boolean literals + // + template<typename C> + const C* + true_ (); + + template<typename C> + const C* + false_ (); + + template<typename C> + const C* + one (); + + template<typename C> + const C* + zero (); + } + } + } + } +} + +#include <xsd/cxx/parser/validating/xml-schema-pimpl.txx> + +#endif // XSD_CXX_PARSER_VALIDATING_XML_SCHEMA_PIMPL_HXX + +#include <xsd/cxx/parser/validating/xml-schema-pimpl.ixx> diff --git a/libxsd/xsd/cxx/parser/validating/xml-schema-pimpl.ixx b/libxsd/xsd/cxx/parser/validating/xml-schema-pimpl.ixx new file mode 100644 index 0000000..61bbafb --- /dev/null +++ b/libxsd/xsd/cxx/parser/validating/xml-schema-pimpl.ixx @@ -0,0 +1,676 @@ +// file : xsd/cxx/parser/validating/xml-schema-pimpl.ixx +// author : Boris Kolpackov <boris@codesynthesis.com> +// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#if defined(XSD_CXX_PARSER_USE_CHAR) || !defined(XSD_CXX_PARSER_USE_WCHAR) + +#ifndef XSD_CXX_PARSER_VALIDATING_XML_SCHEMA_PIMPL_IXX_CHAR +#define XSD_CXX_PARSER_VALIDATING_XML_SCHEMA_PIMPL_IXX_CHAR + +namespace xsd +{ + namespace cxx + { + namespace parser + { + namespace validating + { + namespace bits + { + template<> + inline const char* + boolean<char> () + { + return "boolean"; + } + + template<> + inline const char* + byte<char> () + { + return "byte"; + } + + template<> + inline const char* + unsigned_byte<char> () + { + return "unsignedByte"; + } + + template<> + inline const char* + short_<char> () + { + return "short"; + } + + template<> + inline const char* + unsigned_short<char> () + { + return "unsignedShort"; + } + + template<> + inline const char* + int_<char> () + { + return "int"; + } + + template<> + inline const char* + unsigned_int<char> () + { + return "unsignedInt"; + } + + template<> + inline const char* + long_<char> () + { + return "long"; + } + + template<> + inline const char* + unsigned_long<char> () + { + return "unsignedLong"; + } + + template<> + inline const char* + integer<char> () + { + return "integer"; + } + + template<> + inline const char* + negative_integer<char> () + { + return "negativeInteger"; + } + + template<> + inline const char* + non_positive_integer<char> () + { + return "nonPositiveInteger"; + } + + template<> + inline const char* + non_negative_integer<char> () + { + return "nonNegativeInteger"; + } + + template<> + inline const char* + positive_integer<char> () + { + return "positiveInteger"; + } + + template<> + inline const char* + float_<char> () + { + return "float"; + } + + template<> + inline const char* + double_<char> () + { + return "double"; + } + + template<> + inline const char* + decimal<char> () + { + return "decimal"; + } + + template<> + inline const char* + name<char> () + { + return "Name"; + } + + template<> + inline const char* + nmtoken<char> () + { + return "NMTOKEN"; + } + + template<> + inline const char* + nmtokens<char> () + { + return "NMTOKENS"; + } + + template<> + inline const char* + ncname<char> () + { + return "NCName"; + } + + template<> + inline const char* + id<char> () + { + return "ID"; + } + + template<> + inline const char* + idref<char> () + { + return "IDREF"; + } + + template<> + inline const char* + idrefs<char> () + { + return "IDREFS"; + } + + template<> + inline const char* + language<char> () + { + return "language"; + } + + template<> + inline const char* + qname<char> () + { + return "QName"; + } + + template<> + inline const char* + base64_binary<char> () + { + return "base64Binary"; + } + + template<> + inline const char* + hex_binary<char> () + { + return "hexBinary"; + } + + template<> + inline const char* + gday<char> () + { + return "gDay"; + } + + template<> + inline const char* + gmonth<char> () + { + return "gMonth"; + } + + template<> + inline const char* + gyear<char> () + { + return "gYear"; + } + + template<> + inline const char* + gmonth_day<char> () + { + return "gMonthDay"; + } + + template<> + inline const char* + gyear_month<char> () + { + return "gYearMonth"; + } + + template<> + inline const char* + date<char> () + { + return "date"; + } + + template<> + inline const char* + time<char> () + { + return "time"; + } + + template<> + inline const char* + date_time<char> () + { + return "dateTime"; + } + + template<> + inline const char* + duration<char> () + { + return "duration"; + } + + // + // + template<> + inline const char* + positive_inf<char> () + { + return "INF"; + } + + template<> + inline const char* + negative_inf<char> () + { + return "-INF"; + } + + template<> + inline const char* + nan<char> () + { + return "NaN"; + } + + // + // + template<> + inline const char* + true_<char> () + { + return "true"; + } + + template<> + inline const char* + false_<char> () + { + return "false"; + } + + template<> + inline const char* + one<char> () + { + return "1"; + } + + template<> + inline const char* + zero<char> () + { + return "0"; + } + } + } + } + } +} + +#endif // XSD_CXX_PARSER_VALIDATING_XML_SCHEMA_PIMPL_IXX_CHAR +#endif // XSD_CXX_PARSER_USE_CHAR + + +#if defined(XSD_CXX_PARSER_USE_WCHAR) || !defined(XSD_CXX_PARSER_USE_CHAR) + +#ifndef XSD_CXX_PARSER_VALIDATING_XML_SCHEMA_PIMPL_IXX_WCHAR +#define XSD_CXX_PARSER_VALIDATING_XML_SCHEMA_PIMPL_IXX_WCHAR + +namespace xsd +{ + namespace cxx + { + namespace parser + { + namespace validating + { + namespace bits + { + template<> + inline const wchar_t* + boolean<wchar_t> () + { + return L"boolean"; + } + + template<> + inline const wchar_t* + byte<wchar_t> () + { + return L"byte"; + } + + template<> + inline const wchar_t* + unsigned_byte<wchar_t> () + { + return L"unsignedByte"; + } + + template<> + inline const wchar_t* + short_<wchar_t> () + { + return L"short"; + } + + template<> + inline const wchar_t* + unsigned_short<wchar_t> () + { + return L"unsignedShort"; + } + + template<> + inline const wchar_t* + int_<wchar_t> () + { + return L"int"; + } + + template<> + inline const wchar_t* + unsigned_int<wchar_t> () + { + return L"unsignedInt"; + } + + template<> + inline const wchar_t* + long_<wchar_t> () + { + return L"long"; + } + + template<> + inline const wchar_t* + unsigned_long<wchar_t> () + { + return L"unsignedLong"; + } + + template<> + inline const wchar_t* + integer<wchar_t> () + { + return L"integer"; + } + + template<> + inline const wchar_t* + negative_integer<wchar_t> () + { + return L"negativeInteger"; + } + + template<> + inline const wchar_t* + non_positive_integer<wchar_t> () + { + return L"nonPositiveInteger"; + } + + template<> + inline const wchar_t* + non_negative_integer<wchar_t> () + { + return L"nonNegativeInteger"; + } + + template<> + inline const wchar_t* + positive_integer<wchar_t> () + { + return L"positiveInteger"; + } + + template<> + inline const wchar_t* + float_<wchar_t> () + { + return L"float"; + } + + template<> + inline const wchar_t* + double_<wchar_t> () + { + return L"double"; + } + + template<> + inline const wchar_t* + decimal<wchar_t> () + { + return L"decimal"; + } + + template<> + inline const wchar_t* + name<wchar_t> () + { + return L"Name"; + } + + template<> + inline const wchar_t* + nmtoken<wchar_t> () + { + return L"NMTOKEN"; + } + + template<> + inline const wchar_t* + nmtokens<wchar_t> () + { + return L"NMTOKENS"; + } + + template<> + inline const wchar_t* + ncname<wchar_t> () + { + return L"NCName"; + } + + template<> + inline const wchar_t* + id<wchar_t> () + { + return L"ID"; + } + + template<> + inline const wchar_t* + idref<wchar_t> () + { + return L"IDREF"; + } + + template<> + inline const wchar_t* + idrefs<wchar_t> () + { + return L"IDREFS"; + } + + template<> + inline const wchar_t* + language<wchar_t> () + { + return L"language"; + } + + template<> + inline const wchar_t* + qname<wchar_t> () + { + return L"QName"; + } + + template<> + inline const wchar_t* + base64_binary<wchar_t> () + { + return L"base64Binary"; + } + + template<> + inline const wchar_t* + hex_binary<wchar_t> () + { + return L"hexBinary"; + } + + template<> + inline const wchar_t* + gday<wchar_t> () + { + return L"gDay"; + } + + template<> + inline const wchar_t* + gmonth<wchar_t> () + { + return L"gMonth"; + } + + template<> + inline const wchar_t* + gyear<wchar_t> () + { + return L"gYear"; + } + + template<> + inline const wchar_t* + gmonth_day<wchar_t> () + { + return L"gMonthDay"; + } + + template<> + inline const wchar_t* + gyear_month<wchar_t> () + { + return L"gYearMonth"; + } + + template<> + inline const wchar_t* + date<wchar_t> () + { + return L"date"; + } + + template<> + inline const wchar_t* + time<wchar_t> () + { + return L"time"; + } + + template<> + inline const wchar_t* + date_time<wchar_t> () + { + return L"dateTime"; + } + + template<> + inline const wchar_t* + duration<wchar_t> () + { + return L"duration"; + } + + + // + // + template<> + inline const wchar_t* + positive_inf<wchar_t> () + { + return L"INF"; + } + + template<> + inline const wchar_t* + negative_inf<wchar_t> () + { + return L"-INF"; + } + + template<> + inline const wchar_t* + nan<wchar_t> () + { + return L"NaN"; + } + + // + // + template<> + inline const wchar_t* + true_<wchar_t> () + { + return L"true"; + } + + template<> + inline const wchar_t* + false_<wchar_t> () + { + return L"false"; + } + + template<> + inline const wchar_t* + one<wchar_t> () + { + return L"1"; + } + + template<> + inline const wchar_t* + zero<wchar_t> () + { + return L"0"; + } + } + } + } + } +} + +#endif // XSD_CXX_PARSER_VALIDATING_XML_SCHEMA_PIMPL_IXX_WCHAR +#endif // XSD_CXX_PARSER_USE_WCHAR diff --git a/libxsd/xsd/cxx/parser/validating/xml-schema-pimpl.txx b/libxsd/xsd/cxx/parser/validating/xml-schema-pimpl.txx new file mode 100644 index 0000000..9dd30a3 --- /dev/null +++ b/libxsd/xsd/cxx/parser/validating/xml-schema-pimpl.txx @@ -0,0 +1,2746 @@ +// file : xsd/cxx/parser/validating/xml-schema-pimpl.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 <limits> +#include <locale> + +#include <xsd/cxx/zc-istream.hxx> +#include <xsd/cxx/parser/validating/exceptions.hxx> + +namespace xsd +{ + namespace cxx + { + namespace parser + { + namespace validating + { + // Note that most of the types implemented here cannot have + // whitespaces in the value. As result we don't need to waste + // time collapsing whitespaces. All we need to do is trim the + // string representation which can be done without copying. + // + + // Character table. + // + namespace bits + { + const unsigned char ncname_mask = 0x1; + const unsigned char name_first_mask = 0x2; + const unsigned char name_mask = 0x4; + + template <typename C> + struct char_table + { + static C table[0x80]; + }; + + template <typename C> + C char_table<C>::table[0x80] = + { + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD8, 0xD0, 0x00, 0x00, 0xD0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xD8, 0x48, 0x58, 0x48, 0x48, 0x48, 0x40, 0x58, 0x48, 0x48, 0x48, 0x48, 0x48, 0x4D, 0x4D, 0x58, + 0x4D, 0x4D, 0x4D, 0x4D, 0x4D, 0x4D, 0x4D, 0x4D, 0x4D, 0x4D, 0x4E, 0x48, 0x50, 0x48, 0x58, 0x48, + 0x48, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, + 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x48, 0x48, 0x40, 0x48, 0x4F, + 0x48, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, + 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x48, 0x48, 0x48, 0x48, 0x48 + }; + } + + // any_type + // + + template <typename C> + void any_type_pimpl<C>:: + post_any_type () + { + } + + // any_simple_type + // + + template <typename C> + void any_simple_type_pimpl<C>:: + post_any_simple_type () + { + } + + // boolean + // + + template <typename C> + void boolean_pimpl<C>:: + _pre () + { + str_.clear (); + } + + template <typename C> + void boolean_pimpl<C>:: + _characters (const ro_string<C>& s) + { + str_ += s; + } + + template <typename C> + void boolean_pimpl<C>:: + _post () + { + ro_string<C> str (str_); + trim (str); + + if (str == bits::true_<C> () || str == bits::one<C> ()) + value_ = true; + else if (str == bits::false_<C> () || str == bits::zero<C> ()) + value_ = false; + else + throw invalid_value<C> (bits::boolean<C> (), str); + } + + template <typename C> + bool boolean_pimpl<C>:: + post_boolean () + { + return value_; + } + + // byte + // + + template <typename C> + void byte_pimpl<C>:: + _pre () + { + str_.clear (); + } + + template <typename C> + void byte_pimpl<C>:: + _characters (const ro_string<C>& s) + { + str_ += s; + } + + template <typename C> + void byte_pimpl<C>:: + _post () + { + ro_string<C> str (str_); + trim (str); + + short t; + zc_istream<C> is (str); + + if (is >> t && is.exhausted () && t >= -128 && t <= 127) + value_ = static_cast<signed char> (t); + else + throw invalid_value<C> (bits::byte<C> (), str); + } + + template <typename C> + signed char byte_pimpl<C>:: + post_byte () + { + return value_; + } + + // unsigned_byte + // + + template <typename C> + void unsigned_byte_pimpl<C>:: + _pre () + { + str_.clear (); + } + + template <typename C> + void unsigned_byte_pimpl<C>:: + _characters (const ro_string<C>& s) + { + str_ += s; + } + + template <typename C> + void unsigned_byte_pimpl<C>:: + _post () + { + ro_string<C> str (str_); + trim (str); + + unsigned short t; + zc_istream<C> is (str); + + if (is >> t && is.exhausted () && t <= 255) + value_ = static_cast<unsigned char> (t); + else + throw invalid_value<C> (bits::unsigned_byte<C> (), str); + } + + template <typename C> + unsigned char unsigned_byte_pimpl<C>:: + post_unsigned_byte () + { + return value_; + } + + // short + // + + template <typename C> + void short_pimpl<C>:: + _pre () + { + str_.clear (); + } + + template <typename C> + void short_pimpl<C>:: + _characters (const ro_string<C>& s) + { + str_ += s; + } + + template <typename C> + void short_pimpl<C>:: + _post () + { + ro_string<C> str (str_); + trim (str); + + zc_istream<C> is (str); + + if (!(is >> value_ && is.exhausted ())) + throw invalid_value<C> (bits::short_<C> (), str); + } + + template <typename C> + short short_pimpl<C>:: + post_short () + { + return value_; + } + + + // unsigned_short + // + + template <typename C> + void unsigned_short_pimpl<C>:: + _pre () + { + str_.clear (); + } + + template <typename C> + void unsigned_short_pimpl<C>:: + _characters (const ro_string<C>& s) + { + str_ += s; + } + + template <typename C> + void unsigned_short_pimpl<C>:: + _post () + { + ro_string<C> str (str_); + trim (str); + + zc_istream<C> is (str); + + if (!(is >> value_ && is.exhausted ())) + throw invalid_value<C> (bits::unsigned_short<C> (), str); + } + + template <typename C> + unsigned short unsigned_short_pimpl<C>:: + post_unsigned_short () + { + return value_; + } + + // int + // + + template <typename C> + void int_pimpl<C>:: + _pre () + { + str_.clear (); + } + + template <typename C> + void int_pimpl<C>:: + _characters (const ro_string<C>& s) + { + str_ += s; + } + + template <typename C> + void int_pimpl<C>:: + _post () + { + ro_string<C> str (str_); + trim (str); + + zc_istream<C> is (str); + + if (!(is >> value_ && is.exhausted ())) + throw invalid_value<C> (bits::int_<C> (), str); + } + + template <typename C> + int int_pimpl<C>:: + post_int () + { + return value_; + } + + + // unsigned_int + // + + template <typename C> + void unsigned_int_pimpl<C>:: + _pre () + { + str_.clear (); + } + + template <typename C> + void unsigned_int_pimpl<C>:: + _characters (const ro_string<C>& s) + { + str_ += s; + } + + template <typename C> + void unsigned_int_pimpl<C>:: + _post () + { + ro_string<C> str (str_); + trim (str); + + zc_istream<C> is (str); + + if (!(is >> value_ && is.exhausted ())) + throw invalid_value<C> (bits::unsigned_int<C> (), str); + } + + template <typename C> + unsigned int unsigned_int_pimpl<C>:: + post_unsigned_int () + { + return value_; + } + + + // long + // + template <typename C> + void long_pimpl<C>:: + _pre () + { + str_.clear (); + } + + template <typename C> + void long_pimpl<C>:: + _characters (const ro_string<C>& s) + { + str_ += s; + } + + template <typename C> + void long_pimpl<C>:: + _post () + { + ro_string<C> str (str_); + trim (str); + + zc_istream<C> is (str); + + if (!(is >> value_ && is.exhausted ())) + throw invalid_value<C> (bits::long_<C> (), str); + } + + template <typename C> + long long long_pimpl<C>:: + post_long () + { + return value_; + } + + // unsigned_long + // + template <typename C> + void unsigned_long_pimpl<C>:: + _pre () + { + str_.clear (); + } + + template <typename C> + void unsigned_long_pimpl<C>:: + _characters (const ro_string<C>& s) + { + str_ += s; + } + + template <typename C> + void unsigned_long_pimpl<C>:: + _post () + { + ro_string<C> str (str_); + trim (str); + + zc_istream<C> is (str); + + if (!(is >> value_ && is.exhausted ())) + throw invalid_value<C> (bits::unsigned_long<C> (), str); + } + + template <typename C> + unsigned long long unsigned_long_pimpl<C>:: + post_unsigned_long () + { + return value_; + } + + + // integer + // + template <typename C> + void integer_pimpl<C>:: + _pre () + { + str_.clear (); + } + + template <typename C> + void integer_pimpl<C>:: + _characters (const ro_string<C>& s) + { + str_ += s; + } + + template <typename C> + void integer_pimpl<C>:: + _post () + { + ro_string<C> str (str_); + trim (str); + + zc_istream<C> is (str); + + if (!(is >> value_ && is.exhausted ())) + throw invalid_value<C> (bits::integer<C> (), str); + } + + template <typename C> + long long integer_pimpl<C>:: + post_integer () + { + return value_; + } + + // negative_integer + // + template <typename C> + void negative_integer_pimpl<C>:: + _pre () + { + str_.clear (); + } + + template <typename C> + void negative_integer_pimpl<C>:: + _characters (const ro_string<C>& s) + { + str_ += s; + } + + template <typename C> + void negative_integer_pimpl<C>:: + _post () + { + ro_string<C> str (str_); + trim (str); + + zc_istream<C> is (str); + + if (!(is >> value_ && is.exhausted () && value_ < 0)) + throw invalid_value<C> (bits::negative_integer<C> (), str); + } + + template <typename C> + long long negative_integer_pimpl<C>:: + post_negative_integer () + { + return value_; + } + + + // non_positive_integer + // + template <typename C> + void non_positive_integer_pimpl<C>:: + _pre () + { + str_.clear (); + } + + template <typename C> + void non_positive_integer_pimpl<C>:: + _characters (const ro_string<C>& s) + { + str_ += s; + } + + template <typename C> + void non_positive_integer_pimpl<C>:: + _post () + { + ro_string<C> str (str_); + trim (str); + + zc_istream<C> is (str); + + if (!(is >> value_ && is.exhausted () && value_ <= 0)) + throw invalid_value<C> (bits::non_positive_integer<C> (), str); + } + + template <typename C> + long long non_positive_integer_pimpl<C>:: + post_non_positive_integer () + { + return value_; + } + + // positive_integer + // + template <typename C> + void positive_integer_pimpl<C>:: + _pre () + { + str_.clear (); + } + + template <typename C> + void positive_integer_pimpl<C>:: + _characters (const ro_string<C>& s) + { + str_ += s; + } + + template <typename C> + void positive_integer_pimpl<C>:: + _post () + { + ro_string<C> str (str_); + trim (str); + + zc_istream<C> is (str); + + if (!(is >> value_ && is.exhausted () && value_ > 0)) + throw invalid_value<C> (bits::positive_integer<C> (), str); + } + + template <typename C> + unsigned long long positive_integer_pimpl<C>:: + post_positive_integer () + { + return value_; + } + + + // non_negative_integer + // + template <typename C> + void non_negative_integer_pimpl<C>:: + _pre () + { + str_.clear (); + } + + template <typename C> + void non_negative_integer_pimpl<C>:: + _characters (const ro_string<C>& s) + { + str_ += s; + } + + template <typename C> + void non_negative_integer_pimpl<C>:: + _post () + { + ro_string<C> str (str_); + trim (str); + + zc_istream<C> is (str); + + if (!(is >> value_ && is.exhausted ())) + throw invalid_value<C> (bits::non_negative_integer<C> (), str); + } + + template <typename C> + unsigned long long non_negative_integer_pimpl<C>:: + post_non_negative_integer () + { + return value_; + } + + + // float + // + template <typename C> + void float_pimpl<C>:: + _pre () + { + str_.clear (); + } + + template <typename C> + void float_pimpl<C>:: + _characters (const ro_string<C>& s) + { + str_ += s; + } + + template <typename C> + void float_pimpl<C>:: + _post () + { + ro_string<C> str (str_); + trim (str); + + if (str == bits::positive_inf<C> ()) + value_ = std::numeric_limits<float>::infinity (); + else if (str == bits::negative_inf<C> ()) + value_ = -std::numeric_limits<float>::infinity (); + else if (str == bits::nan<C> ()) + value_ = std::numeric_limits<float>::quiet_NaN (); + else + { + zc_istream<C> is (str); + is.imbue (std::locale::classic ()); + + if (!(is >> value_ && is.exhausted ())) + throw invalid_value<C> (bits::float_<C> (), str); + } + } + + template <typename C> + float float_pimpl<C>:: + post_float () + { + return value_; + } + + + // double + // + template <typename C> + void double_pimpl<C>:: + _pre () + { + str_.clear (); + } + + template <typename C> + void double_pimpl<C>:: + _characters (const ro_string<C>& s) + { + str_ += s; + } + + template <typename C> + void double_pimpl<C>:: + _post () + { + ro_string<C> str (str_); + trim (str); + + if (str == bits::positive_inf<C> ()) + value_ = std::numeric_limits<double>::infinity (); + else if (str == bits::negative_inf<C> ()) + value_ = -std::numeric_limits<double>::infinity (); + else if (str == bits::nan<C> ()) + value_ = std::numeric_limits<double>::quiet_NaN (); + else + { + zc_istream<C> is (str); + is.imbue (std::locale::classic ()); + + if (!(is >> value_ && is.exhausted ())) + throw invalid_value<C> (bits::double_<C> (), str); + } + } + + template <typename C> + double double_pimpl<C>:: + post_double () + { + return value_; + } + + // decimal + // + template <typename C> + void decimal_pimpl<C>:: + _pre () + { + str_.clear (); + } + + template <typename C> + void decimal_pimpl<C>:: + _characters (const ro_string<C>& s) + { + str_ += s; + } + + template <typename C> + void decimal_pimpl<C>:: + _post () + { + ro_string<C> str (str_); + trim (str); + + zc_istream<C> is (str); + is.imbue (std::locale::classic ()); + + //@@ TODO: now we accept scientific notations and INF/NaN. + // + if (!(is >> value_ && is.exhausted ())) + throw invalid_value<C> (bits::decimal<C> (), str); + } + + template <typename C> + double decimal_pimpl<C>:: + post_decimal () + { + return value_; + } + + // string + // + template <typename C> + void string_pimpl<C>:: + _pre () + { + str_.clear (); + } + + template <typename C> + void string_pimpl<C>:: + _characters (const ro_string<C>& s) + { + str_ += s; + } + + template <typename C> + std::basic_string<C> string_pimpl<C>:: + post_string () + { + std::basic_string<C> r; + r.swap (str_); + return r; + } + + // normalized_string + // + template <typename C> + void normalized_string_pimpl<C>:: + _pre () + { + str_.clear (); + } + + template <typename C> + void normalized_string_pimpl<C>:: + _characters (const ro_string<C>& s) + { + str_ += s; + } + + template <typename C> + std::basic_string<C> normalized_string_pimpl<C>:: + post_normalized_string () + { + typedef typename std::basic_string<C>::size_type size_type; + + size_type size (str_.size ()); + + for (size_type i (0); i < size; ++i) + { + C& c = str_[i]; + + if (c == C (0x0A) || c == C (0x0D) || c == C (0x09)) + c = C (0x20); + } + + std::basic_string<C> r; + r.swap (str_); + return r; + } + + // token + // + template <typename C> + void token_pimpl<C>:: + _pre () + { + str_.clear (); + } + + template <typename C> + void token_pimpl<C>:: + _characters (const ro_string<C>& s) + { + if (str_.size () == 0) + { + ro_string<C> tmp (s.data (), s.size ()); + + if (trim_left (tmp) != 0) + str_ += tmp; + } + else + str_ += s; + } + + template <typename C> + std::basic_string<C> token_pimpl<C>:: + post_token () + { + typedef typename std::basic_string<C>::size_type size_type; + + size_type size (str_.size ()); + size_type j (0); + + bool subs (false); + + for (size_type i (0); i < size; ++i) + { + C c = str_[i]; + + if (c == C (0x20) || c == C (0x0A) || + c == C (0x0D) || c == C (0x09)) + { + subs = true; + } + else + { + if (subs) + { + subs = false; + str_[j++] = C (0x20); + } + + str_[j++] = c; + } + } + + str_.resize (j); + + std::basic_string<C> r; + r.swap (str_); + return r; + } + + // name + // + template <typename C> + void name_pimpl<C>:: + _pre () + { + str_.clear (); + } + + template <typename C> + void name_pimpl<C>:: + _characters (const ro_string<C>& s) + { + if (str_.size () == 0) + { + ro_string<C> tmp (s.data (), s.size ()); + + if (trim_left (tmp) != 0) + str_ += tmp; + } + else + str_ += s; + } + + template <typename C> + void name_pimpl<C>:: + _post () + { + typedef typename ro_string<C>::size_type size_type; + + ro_string<C> tmp (str_); + size_type size (trim_right (tmp)); + + // For now we are only checking the US-ASCII characters. + // + + bool ok (size != 0); + + if (ok) + { + unsigned int c (static_cast<unsigned int> (str_[0])); + + ok = c >= 0x80 || + (bits::char_table<unsigned char>::table[c] & + bits::name_first_mask); + + if (ok) + { + for (size_type i (1); i < size; ++i) + { + c = static_cast<unsigned int> (str_[i]); + + if (c < 0x80 && + !(bits::char_table<unsigned char>::table[c] & + bits::name_mask)) + { + ok = false; + break; + } + } + } + } + + if (!ok) + throw invalid_value<C> (bits::name<C> (), tmp); + + str_.resize (size); + } + + template <typename C> + std::basic_string<C> name_pimpl<C>:: + post_name () + { + std::basic_string<C> r; + r.swap (str_); + return r; + } + + // nmtoken + // + template <typename C> + void nmtoken_pimpl<C>:: + _pre () + { + str_.clear (); + } + + template <typename C> + void nmtoken_pimpl<C>:: + _characters (const ro_string<C>& s) + { + if (str_.size () == 0) + { + ro_string<C> tmp (s.data (), s.size ()); + + if (trim_left (tmp) != 0) + str_ += tmp; + } + else + str_ += s; + } + + template <typename C> + void nmtoken_pimpl<C>:: + _post () + { + typedef typename ro_string<C>::size_type size_type; + + ro_string<C> tmp (str_); + size_type size (trim_right (tmp)); + + // For now we are only checking the US-ASCII characters. + // + + bool ok (size != 0); + + if (ok) + { + for (size_type i (0); i < size; ++i) + { + unsigned int c (static_cast<unsigned int> (str_[i])); + + if (c < 0x80 && + !(bits::char_table<unsigned char>::table[c] & + bits::name_mask)) + { + ok = false; + break; + } + } + } + + if (!ok) + throw invalid_value<C> (bits::nmtoken<C> (), tmp); + + str_.resize (size); + } + + template <typename C> + std::basic_string<C> nmtoken_pimpl<C>:: + post_nmtoken () + { + std::basic_string<C> r; + r.swap (str_); + return r; + } + + // nmtokens + // + template <typename C> + void nmtokens_pimpl<C>:: + _pre () + { + nmtokens_pskel<C>::_pre (); + seq_.clear (); + } + + template <typename C> + void nmtokens_pimpl<C>:: + _post () + { + nmtokens_pskel<C>::_post (); + + // Should have at least one element. + // + if (seq_.size () < 1) + { + ro_string<C> tmp; + throw invalid_value<C> (bits::nmtokens<C> (), tmp); + } + } + + template <typename C> + string_sequence<C> nmtokens_pimpl<C>:: + post_nmtokens () + { + string_sequence<C> r; + r.swap (seq_); + return r; + } + + template <typename C> + void nmtokens_pimpl<C>:: + _xsd_parse_item (const ro_string<C>& s) + { + parser_.pre (); + parser_._pre (); + parser_._characters (s); + parser_._post (); + seq_.push_back (parser_.post_nmtoken ()); + } + + // ncname + // + namespace bits + { + template <typename C> + bool + valid_ncname (const C* s, typename ro_string<C>::size_type size) + { + typedef typename ro_string<C>::size_type size_type; + + // For now we are only checking the US-ASCII characters. + // + bool ok (size != 0); + + if (ok) + { + unsigned int c (static_cast<unsigned int> (s[0])); + + ok = c >= 0x80 || + ((bits::char_table<unsigned char>::table[c] & + bits::name_first_mask) && c != C (':')); + + if (ok) + { + for (size_type i (1); i < size; ++i) + { + c = static_cast<unsigned int> (s[i]); + + if (c < 0x80 && + !(bits::char_table<unsigned char>::table[c] & + bits::ncname_mask)) + { + ok = false; + break; + } + } + } + } + + return ok; + } + } + + template <typename C> + void ncname_pimpl<C>:: + _pre () + { + str_.clear (); + } + + template <typename C> + void ncname_pimpl<C>:: + _characters (const ro_string<C>& s) + { + if (str_.size () == 0) + { + ro_string<C> tmp (s.data (), s.size ()); + + if (trim_left (tmp) != 0) + str_ += tmp; + } + else + str_ += s; + } + + template <typename C> + void ncname_pimpl<C>:: + _post () + { + typedef typename ro_string<C>::size_type size_type; + + ro_string<C> tmp (str_); + size_type size (trim_right (tmp)); + + if (!bits::valid_ncname (tmp.data (), size)) + throw invalid_value<C> (bits::ncname<C> (), tmp); + + str_.resize (size); + } + + template <typename C> + std::basic_string<C> ncname_pimpl<C>:: + post_ncname () + { + std::basic_string<C> r; + r.swap (str_); + return r; + } + + // id + // + template <typename C> + void id_pimpl<C>:: + _pre () + { + str_.clear (); + } + + template <typename C> + void id_pimpl<C>:: + _characters (const ro_string<C>& s) + { + if (str_.size () == 0) + { + ro_string<C> tmp (s.data (), s.size ()); + + if (trim_left (tmp) != 0) + str_ += tmp; + } + else + str_ += s; + } + + template <typename C> + void id_pimpl<C>:: + _post () + { + typedef typename ro_string<C>::size_type size_type; + + ro_string<C> tmp (str_); + size_type size (trim_right (tmp)); + + if (!bits::valid_ncname (tmp.data (), size)) + throw invalid_value<C> (bits::id<C> (), tmp); + + str_.resize (size); + } + + template <typename C> + std::basic_string<C> id_pimpl<C>:: + post_id () + { + std::basic_string<C> r; + r.swap (str_); + return r; + } + + // idref + // + template <typename C> + void idref_pimpl<C>:: + _pre () + { + str_.clear (); + } + + template <typename C> + void idref_pimpl<C>:: + _characters (const ro_string<C>& s) + { + if (str_.size () == 0) + { + ro_string<C> tmp (s.data (), s.size ()); + + if (trim_left (tmp) != 0) + str_ += tmp; + } + else + str_ += s; + } + + template <typename C> + void idref_pimpl<C>:: + _post () + { + typedef typename ro_string<C>::size_type size_type; + + ro_string<C> tmp (str_); + size_type size (trim_right (tmp)); + + if (!bits::valid_ncname (tmp.data (), size)) + throw invalid_value<C> (bits::idref<C> (), tmp); + + str_.resize (size); + } + + template <typename C> + std::basic_string<C> idref_pimpl<C>:: + post_idref () + { + std::basic_string<C> r; + r.swap (str_); + return r; + } + + // idrefs + // + template <typename C> + void idrefs_pimpl<C>:: + _pre () + { + idrefs_pskel<C>::_pre (); + seq_.clear (); + } + + template <typename C> + void idrefs_pimpl<C>:: + _post () + { + idrefs_pskel<C>::_post (); + + // Should have at least one element. + // + if (seq_.size () < 1) + { + ro_string<C> tmp; + throw invalid_value<C> (bits::idrefs<C> (), tmp); + } + } + + template <typename C> + string_sequence<C> idrefs_pimpl<C>:: + post_idrefs () + { + string_sequence<C> r; + r.swap (seq_); + return r; + } + + template <typename C> + void idrefs_pimpl<C>:: + _xsd_parse_item (const ro_string<C>& s) + { + parser_.pre (); + parser_._pre (); + parser_._characters (s); + parser_._post (); + seq_.push_back (parser_.post_idref ()); + } + + // language + // + template <typename C> + void language_pimpl<C>:: + _pre () + { + str_.clear (); + } + + template <typename C> + void language_pimpl<C>:: + _characters (const ro_string<C>& s) + { + if (str_.size () == 0) + { + ro_string<C> tmp (s.data (), s.size ()); + + if (trim_left (tmp) != 0) + str_ += tmp; + } + else + str_ += s; + } + + template <typename C> + void language_pimpl<C>:: + _post () + { + typedef typename ro_string<C>::size_type size_type; + + ro_string<C> tmp (str_); + size_type size (trim_right (tmp)); + + // language := ALPHA{1,8} *(-(ALPHA | DIGIT){1,8}) + // + bool ok (true); + + for (size_type tag (0), i (0); ; ++tag) + { + size_type n (0); + + for (; i < size && n < 8; ++n, ++i) + { + C c (tmp[i]); + + if (!((c >= C ('a') && c <= C ('z')) || + (c >= C ('A') && c <= C ('Z')) || + (tag != 0 && c >= C ('0') && c <= C ('9')))) + break; + } + + if (n == 0) + { + ok = false; + break; + } + + if (i == size) + break; + + if (tmp[i++] != C ('-')) + { + ok = false; + break; + } + } + + if (!ok) + throw invalid_value<C> (bits::language<C> (), tmp); + + str_.resize (size); + } + + template <typename C> + std::basic_string<C> language_pimpl<C>:: + post_language () + { + std::basic_string<C> r; + r.swap (str_); + return r; + } + + // uri + // + template <typename C> + void uri_pimpl<C>:: + _pre () + { + str_.clear (); + } + + template <typename C> + void uri_pimpl<C>:: + _characters (const ro_string<C>& s) + { + if (str_.size () == 0) + { + ro_string<C> tmp (s.data (), s.size ()); + + if (trim_left (tmp) != 0) + str_ += tmp; + } + else + str_ += s; + } + + template <typename C> + std::basic_string<C> uri_pimpl<C>:: + post_uri () + { + // According to Datatypes 3.2.17 and RFC2396 pretty much anything + // can be a URI and conforming processors do not need to figure + // out and verify particular URI schemes. + // + ro_string<C> tmp (str_); + str_.resize (trim_right (tmp)); + + std::basic_string<C> r; + r.swap (str_); + return r; + } + + // qname + // + template <typename C> + void qname_pimpl<C>:: + _pre () + { + str_.clear (); + } + + template <typename C> + void qname_pimpl<C>:: + _characters (const ro_string<C>& s) + { + if (str_.size () == 0) + { + ro_string<C> tmp (s.data (), s.size ()); + + if (trim_left (tmp) != 0) + str_ += tmp; + } + else + str_ += s; + } + + template <typename C> + void qname_pimpl<C>:: + _post () + { + typedef typename ro_string<C>::size_type size_type; + + ro_string<C> tmp (str_); + size_type size (trim_right (tmp)); + size_type pos (tmp.find (C (':'))); + + const C* s (tmp.data ()); + + if (pos != ro_string<C>::npos) + { + if (!bits::valid_ncname (s, pos) || + !bits::valid_ncname (s + pos + 1, size - pos - 1)) + throw invalid_value<C> (bits::qname<C> (), tmp); + + prefix_.assign (s, pos); + name_.assign (s + pos + 1, size - pos - 1); + } + else + { + if (!bits::valid_ncname (s, size)) + throw invalid_value<C> (bits::qname<C> (), tmp); + + prefix_.clear (); + str_.resize (size); + name_.swap (str_); + } + } + + template <typename C> + qname<C> qname_pimpl<C>:: + post_qname () + { + return prefix_.empty () + ? qname<C> (name_) + : qname<C> (prefix_, name_); + } + + // base64_binary + // + template <typename C> + void base64_binary_pimpl<C>:: + _pre () + { + str_.clear (); + } + + template <typename C> + void base64_binary_pimpl<C>:: + _characters (const ro_string<C>& s) + { + if (str_.size () == 0) + { + ro_string<C> tmp (s.data (), s.size ()); + + if (trim_left (tmp) != 0) + str_ += tmp; + } + else + str_ += s; + } + + namespace bits + { + template <typename C> + inline unsigned char + base64_decode (C c) + { + unsigned char r (0xFF); + + if (c >= C('A') && c <= C ('Z')) + r = static_cast<unsigned char> (c - C ('A')); + else if (c >= C('a') && c <= C ('z')) + r = static_cast<unsigned char> (c - C ('a') + 26); + else if (c >= C('0') && c <= C ('9')) + r = static_cast<unsigned char> (c - C ('0') + 52); + else if (c == C ('+')) + r = 62; + else if (c == C ('/')) + r = 63; + + return r; + } + } + + template <typename C> + void base64_binary_pimpl<C>:: + _post () + { + typedef typename std::basic_string<C>::size_type size_type; + + size_type size (str_.size ()); + const C* src (str_.c_str ()); + + // Remove all whitespaces. + // + { + size_type j (0); + + bool subs (false); + + for (size_type i (0); i < size; ++i) + { + C c = str_[i]; + + if (c == C (0x20) || c == C (0x0A) || + c == C (0x0D) || c == C (0x09)) + { + subs = true; + } + else + { + if (subs) + subs = false; + + str_[j++] = c; + } + } + + size = j; + str_.resize (size); + } + + // Our length should be a multiple of four. + // + if (size == 0 || size % 4 != 0) + throw invalid_value<C> (bits::base64_binary<C> (), str_); + + size_type quad_count (size / 4); + size_type capacity (quad_count * 3 + 1); + + buf_.reset (new buffer (capacity, capacity)); + char* dst (buf_->data ()); + + size_type si (0), di (0); // Source and destination indexes. + + // Process all quads except the last one. + // + unsigned char b1, b2, b3, b4; + + for (size_type q (0); q < quad_count - 1; ++q) + { + b1 = bits::base64_decode (src[si++]); + b2 = bits::base64_decode (src[si++]); + b3 = bits::base64_decode (src[si++]); + b4 = bits::base64_decode (src[si++]); + + if (b1 == 0xFF || b2 == 0xFF || b3 == 0xFF || b4 == 0xFF) + throw invalid_value<C> (bits::base64_binary<C> (), str_); + + dst[di++] = (b1 << 2) | (b2 >> 4); + dst[di++] = (b2 << 4) | (b3 >> 2); + dst[di++] = (b3 << 6) | b4; + } + + // Process the last quad. The first two octets are always there. + // + b1 = bits::base64_decode (src[si++]); + b2 = bits::base64_decode (src[si++]); + + if (b1 == 0xFF || b2 == 0xFF) + throw invalid_value<C> (bits::base64_binary<C> (), str_); + + C e3 (src[si++]); + C e4 (src[si++]); + + if (e4 == C ('=')) + { + if (e3 == C ('=')) + { + // Two pads. Last 4 bits in b2 should be zero. + // + if ((b2 & 0x0F) != 0) + throw invalid_value<C> (bits::base64_binary<C> (), str_); + + dst[di++] = (b1 << 2) | (b2 >> 4); + } + else + { + // One pad. Last 2 bits in b3 should be zero. + // + b3 = bits::base64_decode (e3); + + if (b3 == 0xFF || (b3 & 0x03) != 0) + throw invalid_value<C> (bits::base64_binary<C> (), str_); + + dst[di++] = (b1 << 2) | (b2 >> 4); + dst[di++] = (b2 << 4) | (b3 >> 2); + } + } + else + { + // No pads. + // + b3 = bits::base64_decode (e3); + b4 = bits::base64_decode (e4); + + if (b3 == 0xFF || b4 == 0xFF) + throw invalid_value<C> (bits::base64_binary<C> (), str_); + + dst[di++] = (b1 << 2) | (b2 >> 4); + dst[di++] = (b2 << 4) | (b3 >> 2); + dst[di++] = (b3 << 6) | b4; + } + + // Set the real size. + // + buf_->size (di); + } + + template <typename C> + std::auto_ptr<buffer> base64_binary_pimpl<C>:: + post_base64_binary () + { + return buf_; + } + + // hex_binary + // + template <typename C> + void hex_binary_pimpl<C>:: + _pre () + { + str_.clear (); + } + + template <typename C> + void hex_binary_pimpl<C>:: + _characters (const ro_string<C>& s) + { + if (str_.size () == 0) + { + ro_string<C> tmp (s.data (), s.size ()); + + if (trim_left (tmp) != 0) + str_ += tmp; + } + else + str_ += s; + } + + namespace bits + { + template <typename C> + inline unsigned char + hex_decode (C c) + { + unsigned char r (0xFF); + + if (c >= C('0') && c <= C ('9')) + r = static_cast<unsigned char> (c - C ('0')); + else if (c >= C ('A') && c <= C ('F')) + r = static_cast<unsigned char> (10 + (c - C ('A'))); + else if (c >= C ('a') && c <= C ('f')) + r = static_cast<unsigned char> (10 + (c - C ('a'))); + + return r; + } + } + + template <typename C> + void hex_binary_pimpl<C>:: + _post () + { + typedef typename ro_string<C>::size_type size_type; + + ro_string<C> tmp (str_); + size_type size (trim_right (tmp)); + + if (size % 2 != 0) + throw invalid_value<C> (bits::hex_binary<C> (), tmp); + + buffer::size_t n (size / 2); + buf_.reset (new buffer (n)); + + if (n != 0) + { + const C* src (tmp.data ()); + char* dst (buf_->data ()); + buffer::size_t i (0); + + for (; i < n; ++i) + { + unsigned char h (bits::hex_decode (src[2 * i])); + unsigned char l (bits::hex_decode (src[2 * i + 1])); + + if (h == 0xFF || l == 0xFF) + break; + + dst[i] = (h << 4) | l; + } + + if (i != n) + throw invalid_value<C> (bits::hex_binary<C> (), tmp); + } + } + + template <typename C> + std::auto_ptr<buffer> hex_binary_pimpl<C>:: + post_hex_binary () + { + return buf_; + } + + // time_zone + // + namespace bits + { + // Datatypes 3.2.7.3. Return false if time zone is invalid. + // + template <typename C> + bool + parse_tz (const C* s, + typename std::basic_string<C>::size_type n, + short& h, short& m) + { + // time_zone := Z|(+|-)HH:MM + // + if (n == 0) + { + return false; + } + else if (s[0] == 'Z') + { + if (n != 1) + return false; + + h = 0; + m = 0; + } + else + { + if (n != 6 || (s[0] != '-' && s[0] != '+') || s[3] != ':') + return false; + + // Parse hours. + // + char d1 = s[1]; + char d2 = s[2]; + + if (d1 < '0' || d1 > '9' || d2 < '0' || d2 > '9') + return false; + + h = 10 * (d1 - '0') + (d2 - '0'); + + if (h > 14) + return false; + + // Parse minutes. + // + d1 = s[4]; + d2 = s[5]; + + if (d1 < '0' || d1 > '9' || d2 < '0' || d2 > '9') + return false; + + m = 10 * (d1 - '0') + (d2 - '0'); + + if (m > 59 || (h == 14 && m != 0)) + return false; + + if (s[0] == '-') + { + h = -h; + m = -m; + } + } + + return true; + } + } + + // gday + // + template <typename C> + void gday_pimpl<C>:: + _pre () + { + str_.clear (); + } + + template <typename C> + void gday_pimpl<C>:: + _characters (const ro_string<C>& s) + { + if (str_.size () == 0) + { + ro_string<C> tmp (s.data (), s.size ()); + + if (trim_left (tmp) != 0) + str_ += tmp; + } + else + str_ += s; + } + + template <typename C> + void gday_pimpl<C>:: + _post () + { + typedef typename ro_string<C>::size_type size_type; + + ro_string<C> tmp (str_); + size_type size (trim_right (tmp)); + const C* s (tmp.data ()); + + // gday := ---DD[Z|(+|-)HH:MM] + // + if (size < 5 || + s[0] != C ('-') || s[1] != C ('-') || s[2] != C ('-')) + throw invalid_value<C> (bits::gday<C> (), tmp); + + C d1 (s[3]), d2 (s[4]); + + if (d1 < '0' || d1 > '9' || d2 < '0' || d2 > '9') + throw invalid_value<C> (bits::gday<C> (), tmp); + + day_ = 10 * (d1 - '0') + (d2 - '0'); + + if (day_ < 1 || day_ > 31) + throw invalid_value<C> (bits::gday<C> (), tmp); + + if (size > 5) + { + if (!bits::parse_tz (s + 5, size - 5, zh_, zm_)) + throw invalid_value<C> (bits::gday<C> (), tmp); + + z_ = true; + } + else + z_ = false; + } + + template <typename C> + gday gday_pimpl<C>:: + post_gday () + { + return z_ ? gday (day_, zh_, zm_) : gday (day_); + } + + // gmonth + // + template <typename C> + void gmonth_pimpl<C>:: + _pre () + { + str_.clear (); + } + + template <typename C> + void gmonth_pimpl<C>:: + _characters (const ro_string<C>& s) + { + if (str_.size () == 0) + { + ro_string<C> tmp (s.data (), s.size ()); + + if (trim_left (tmp) != 0) + str_ += tmp; + } + else + str_ += s; + } + + template <typename C> + void gmonth_pimpl<C>:: + _post () + { + typedef typename ro_string<C>::size_type size_type; + + ro_string<C> tmp (str_); + size_type size (trim_right (tmp)); + const C* s (tmp.data ()); + + // gmonth := --MM[Z|(+|-)HH:MM] + // + if (size < 4 || s[0] != C ('-') || s[1] != C ('-')) + throw invalid_value<C> (bits::gmonth<C> (), tmp); + + C d1 (s[2]), d2 (s[3]); + + if (d1 < '0' || d1 > '9' || d2 < '0' || d2 > '9') + throw invalid_value<C> (bits::gmonth<C> (), tmp); + + month_ = 10 * (d1 - '0') + (d2 - '0'); + + if (month_ < 1 || month_ > 12) + throw invalid_value<C> (bits::gmonth<C> (), tmp); + + if (size > 4) + { + if (!bits::parse_tz (s + 4, size - 4, zh_, zm_)) + throw invalid_value<C> (bits::gmonth<C> (), tmp); + + z_ = true; + } + else + z_ = false; + } + + template <typename C> + gmonth gmonth_pimpl<C>:: + post_gmonth () + { + return z_ ? gmonth (month_, zh_, zm_) : gmonth (month_); + } + + // gyear + // + template <typename C> + void gyear_pimpl<C>:: + _pre () + { + str_.clear (); + } + + template <typename C> + void gyear_pimpl<C>:: + _characters (const ro_string<C>& s) + { + if (str_.size () == 0) + { + ro_string<C> tmp (s.data (), s.size ()); + + if (trim_left (tmp) != 0) + str_ += tmp; + } + else + str_ += s; + } + + template <typename C> + void gyear_pimpl<C>:: + _post () + { + typedef typename ro_string<C>::size_type size_type; + + ro_string<C> tmp (str_); + size_type size (trim_right (tmp)); + const C* s (tmp.data ()); + + // gyear := [-]CCYY[N]*[Z|(+|-)HH:MM] + // + + if (size < 4 || (s[0] == C ('-') && size < 5)) + throw invalid_value<C> (bits::gyear<C> (), tmp); + + // Find the end of the year token. + // + size_type pos (s[0] == C ('-') ? 5 : 4); + for (; pos < size; ++pos) + { + C c (s[pos]); + + if (c == C ('Z') || c == C ('+') || c == C ('-')) + break; + } + + ro_string<C> year_fragment (s, pos); + zc_istream<C> is (year_fragment); + + if (!(is >> year_ && is.exhausted () && year_ != 0)) + throw invalid_value<C> (bits::gyear<C> (), tmp); + + if (pos < size) + { + if (!bits::parse_tz (s + pos, size - pos, zh_, zm_)) + throw invalid_value<C> (bits::gyear<C> (), tmp); + + z_ = true; + } + else + z_ = false; + } + + template <typename C> + gyear gyear_pimpl<C>:: + post_gyear () + { + return z_ ? gyear (year_, zh_, zm_) : gyear (year_); + } + + // gmonth_day + // + template <typename C> + void gmonth_day_pimpl<C>:: + _pre () + { + str_.clear (); + } + + template <typename C> + void gmonth_day_pimpl<C>:: + _characters (const ro_string<C>& s) + { + if (str_.size () == 0) + { + ro_string<C> tmp (s.data (), s.size ()); + + if (trim_left (tmp) != 0) + str_ += tmp; + } + else + str_ += s; + } + + template <typename C> + void gmonth_day_pimpl<C>:: + _post () + { + typedef typename ro_string<C>::size_type size_type; + + ro_string<C> tmp (str_); + size_type size (trim_right (tmp)); + const C* s (tmp.data ()); + + // gmonth_day := --MM-DD[Z|(+|-)HH:MM] + // + if (size < 7 || + s[0] != C ('-') || s[1] != C ('-') || s[4] != C ('-')) + throw invalid_value<C> (bits::gmonth_day<C> (), tmp); + + // month + // + C d1 (s[2]), d2 (s[3]); + + if (d1 < '0' || d1 > '9' || d2 < '0' || d2 > '9') + throw invalid_value<C> (bits::gmonth_day<C> (), tmp); + + month_ = 10 * (d1 - '0') + (d2 - '0'); + + if (month_ < 1 || month_ > 12) + throw invalid_value<C> (bits::gmonth_day<C> (), tmp); + + // day + // + d1 = s[5]; + d2 = s[6]; + + if (d1 < '0' || d1 > '9' || d2 < '0' || d2 > '9') + throw invalid_value<C> (bits::gmonth_day<C> (), tmp); + + day_ = 10 * (d1 - '0') + (d2 - '0'); + + if (day_ < 1 || day_ > 31) + throw invalid_value<C> (bits::gmonth_day<C> (), tmp); + + // zone + // + if (size > 7) + { + if (!bits::parse_tz (s + 7, size - 7, zh_, zm_)) + throw invalid_value<C> (bits::gmonth_day<C> (), tmp); + + z_ = true; + } + else + z_ = false; + } + + template <typename C> + gmonth_day gmonth_day_pimpl<C>:: + post_gmonth_day () + { + return z_ + ? gmonth_day (month_, day_, zh_, zm_) + : gmonth_day (month_, day_); + } + + // gyear_month + // + template <typename C> + void gyear_month_pimpl<C>:: + _pre () + { + str_.clear (); + } + + template <typename C> + void gyear_month_pimpl<C>:: + _characters (const ro_string<C>& s) + { + if (str_.size () == 0) + { + ro_string<C> tmp (s.data (), s.size ()); + + if (trim_left (tmp) != 0) + str_ += tmp; + } + else + str_ += s; + } + + template <typename C> + void gyear_month_pimpl<C>:: + _post () + { + typedef typename ro_string<C>::size_type size_type; + + ro_string<C> tmp (str_); + size_type size (trim_right (tmp)); + const C* s (tmp.data ()); + + // gyear_month := [-]CCYY[N]*-MM[Z|(+|-)HH:MM] + // + + if (size < 7 || (s[0] == C ('-') && size < 8)) + throw invalid_value<C> (bits::gyear_month<C> (), tmp); + + // Find the end of the year token. + // + size_type pos (tmp.find (C ('-'), s[0] == C ('-') ? 5 : 4)); + + if (pos == ro_string<C>::npos || (size - pos - 1) < 2) + throw invalid_value<C> (bits::gyear_month<C> (), tmp); + + ro_string<C> year_fragment (s, pos); + zc_istream<C> yis (year_fragment); + + if (!(yis >> year_ && yis.exhausted () && year_ != 0)) + throw invalid_value<C> (bits::gyear_month<C> (), tmp); + + // month + // + C d1 (s[pos + 1]), d2 (s[pos + 2]); + + if (d1 < '0' || d1 > '9' || d2 < '0' || d2 > '9') + throw invalid_value<C> (bits::gyear_month<C> (), tmp); + + month_ = 10 * (d1 - '0') + (d2 - '0'); + + if (month_ < 1 || month_ > 12) + throw invalid_value<C> (bits::gyear_month<C> (), tmp); + + // zone + // + pos += 3; + + if (pos < size) + { + if (!bits::parse_tz (s + pos, size - pos, zh_, zm_)) + throw invalid_value<C> (bits::gyear_month<C> (), tmp); + + z_ = true; + } + else + z_ = false; + } + + template <typename C> + gyear_month gyear_month_pimpl<C>:: + post_gyear_month () + { + return z_ + ? gyear_month (year_, month_, zh_, zm_) + : gyear_month (year_, month_); + } + + // date + // + template <typename C> + void date_pimpl<C>:: + _pre () + { + str_.clear (); + } + + template <typename C> + void date_pimpl<C>:: + _characters (const ro_string<C>& s) + { + if (str_.size () == 0) + { + ro_string<C> tmp (s.data (), s.size ()); + + if (trim_left (tmp) != 0) + str_ += tmp; + } + else + str_ += s; + } + + template <typename C> + void date_pimpl<C>:: + _post () + { + typedef typename ro_string<C>::size_type size_type; + + ro_string<C> tmp (str_); + size_type size (trim_right (tmp)); + const C* s (tmp.data ()); + + // date := [-]CCYY[N]*-MM-DD[Z|(+|-)HH:MM] + // + + if (size < 10 || (s[0] == C ('-') && size < 11)) + throw invalid_value<C> (bits::date<C> (), tmp); + + // Find the end of the year token. + // + size_type pos (tmp.find (C ('-'), s[0] == C ('-') ? 5 : 4)); + + if (pos == ro_string<C>::npos + || (size - pos - 1) < 5 + || s[pos + 3] != C ('-')) + throw invalid_value<C> (bits::date<C> (), tmp); + + ro_string<C> year_fragment (s, pos); + zc_istream<C> yis (year_fragment); + + if (!(yis >> year_ && yis.exhausted () && year_ != 0)) + throw invalid_value<C> (bits::date<C> (), tmp); + + // month + // + C d1 (s[pos + 1]), d2 (s[pos + 2]); + + if (d1 < '0' || d1 > '9' || d2 < '0' || d2 > '9') + throw invalid_value<C> (bits::date<C> (), tmp); + + month_ = 10 * (d1 - '0') + (d2 - '0'); + + if (month_ < 1 || month_ > 12) + throw invalid_value<C> (bits::date<C> (), tmp); + + // day + // + d1 = s[pos + 4]; + d2 = s[pos + 5]; + + if (d1 < '0' || d1 > '9' || d2 < '0' || d2 > '9') + throw invalid_value<C> (bits::date<C> (), tmp); + + day_ = 10 * (d1 - '0') + (d2 - '0'); + + if (day_ < 1 || day_ > 31) + throw invalid_value<C> (bits::date<C> (), tmp); + + // zone + // + pos += 6; + + if (pos < size) + { + if (!bits::parse_tz (s + pos, size - pos, zh_, zm_)) + throw invalid_value<C> (bits::date<C> (), tmp); + + z_ = true; + } + else + z_ = false; + } + + template <typename C> + date date_pimpl<C>:: + post_date () + { + return z_ + ? date (year_, month_, day_, zh_, zm_) + : date (year_, month_, day_); + } + + // time + // + template <typename C> + void time_pimpl<C>:: + _pre () + { + str_.clear (); + } + + template <typename C> + void time_pimpl<C>:: + _characters (const ro_string<C>& s) + { + if (str_.size () == 0) + { + ro_string<C> tmp (s.data (), s.size ()); + + if (trim_left (tmp) != 0) + str_ += tmp; + } + else + str_ += s; + } + + template <typename C> + void time_pimpl<C>:: + _post () + { + typedef typename ro_string<C>::size_type size_type; + + ro_string<C> tmp (str_); + size_type size (trim_right (tmp)); + const C* s (tmp.data ()); + + // time := HH:MM:SS[.S+][Z|(+|-)HH:MM] + // + + if (size < 8 || s[2] != C (':') || s[5] != C (':')) + throw invalid_value<C> (bits::time<C> (), tmp); + + // hours + // + C d1 (s[0]), d2 (s[1]); + + if (d1 < '0' || d1 > '9' || d2 < '0' || d2 > '9') + throw invalid_value<C> (bits::time<C> (), tmp); + + hours_ = 10 * (d1 - '0') + (d2 - '0'); + + if (hours_ > 24) + throw invalid_value<C> (bits::time<C> (), tmp); + + // minutes + // + d1 = s[3]; + d2 = s[4]; + + if (d1 < '0' || d1 > '9' || d2 < '0' || d2 > '9') + throw invalid_value<C> (bits::time<C> (), tmp); + + minutes_ = 10 * (d1 - '0') + (d2 - '0'); + + if (minutes_ > 59) + throw invalid_value<C> (bits::time<C> (), tmp); + + // Find the end of the seconds fragment. + // + size_type pos (8); + for (; pos < size; ++pos) + { + C c (s[pos]); + + if (c == C ('Z') || c == C ('+') || c == C ('-')) + break; + } + + // At least one digit should follow the fraction point. + // + if ((pos - 6) == 3) + throw invalid_value<C> (bits::time<C> (), tmp); + + ro_string<C> seconds_fragment (s + 6, pos - 6); + zc_istream<C> sis (seconds_fragment); + + if (!(sis >> seconds_ && sis.exhausted () && seconds_ < 60.0)) + throw invalid_value<C> (bits::time<C> (), tmp); + + if (hours_ == 24 && (minutes_ != 0 || seconds_ != 0.0)) + throw invalid_value<C> (bits::time<C> (), tmp); + + // zone + // + if (pos < size) + { + if (!bits::parse_tz (s + pos, size - pos, zh_, zm_)) + throw invalid_value<C> (bits::time<C> (), tmp); + + z_ = true; + } + else + z_ = false; + } + + template <typename C> + time time_pimpl<C>:: + post_time () + { + return z_ + ? time (hours_, minutes_, seconds_, zh_, zm_) + : time (hours_, minutes_, seconds_); + } + + + // date_time + // + template <typename C> + void date_time_pimpl<C>:: + _pre () + { + str_.clear (); + } + + template <typename C> + void date_time_pimpl<C>:: + _characters (const ro_string<C>& s) + { + if (str_.size () == 0) + { + ro_string<C> tmp (s.data (), s.size ()); + + if (trim_left (tmp) != 0) + str_ += tmp; + } + else + str_ += s; + } + + template <typename C> + void date_time_pimpl<C>:: + _post () + { + typedef typename ro_string<C>::size_type size_type; + + ro_string<C> tmp (str_); + size_type size (trim_right (tmp)); + const C* s (tmp.data ()); + + // date_time := [-]CCYY[N]*-MM-DDTHH:MM:SS[.S+][Z|(+|-)HH:MM] + // + + if (size < 19 || (s[0] == C ('-') && size < 20)) + throw invalid_value<C> (bits::date_time<C> (), tmp); + + // Find the end of the year token. + // + size_type pos (tmp.find (C ('-'), s[0] == C ('-') ? 5 : 4)); + + if (pos == ro_string<C>::npos || (size - pos - 1) < 14 + || s[pos + 3] != C ('-') || s[pos + 6] != C ('T') + || s[pos + 9] != C (':') || s[pos + 12] != C (':')) + throw invalid_value<C> (bits::date_time<C> (), tmp); + + // year + // + ro_string<C> year_fragment (s, pos); + zc_istream<C> yis (year_fragment); + + if (!(yis >> year_ && yis.exhausted () && year_ != 0)) + throw invalid_value<C> (bits::date_time<C> (), tmp); + + // month + // + C d1 (s[pos + 1]), d2 (s[pos + 2]); + + if (d1 < '0' || d1 > '9' || d2 < '0' || d2 > '9') + throw invalid_value<C> (bits::date_time<C> (), tmp); + + month_ = 10 * (d1 - '0') + (d2 - '0'); + + if (month_ < 1 || month_ > 12) + throw invalid_value<C> (bits::date_time<C> (), tmp); + + // day + // + d1 = s[pos + 4]; + d2 = s[pos + 5]; + + if (d1 < '0' || d1 > '9' || d2 < '0' || d2 > '9') + throw invalid_value<C> (bits::date_time<C> (), tmp); + + day_ = 10 * (d1 - '0') + (d2 - '0'); + + if (day_ < 1 || day_ > 31) + throw invalid_value<C> (bits::date_time<C> (), tmp); + + pos += 7; // Point to the first H. + + // hours + // + d1 = s[pos]; + d2 = s[pos + 1]; + + if (d1 < '0' || d1 > '9' || d2 < '0' || d2 > '9') + throw invalid_value<C> (bits::date_time<C> (), tmp); + + hours_ = 10 * (d1 - '0') + (d2 - '0'); + + if (hours_ > 24) + throw invalid_value<C> (bits::date_time<C> (), tmp); + + // minutes + // + d1 = s[pos + 3]; + d2 = s[pos + 4]; + + if (d1 < '0' || d1 > '9' || d2 < '0' || d2 > '9') + throw invalid_value<C> (bits::date_time<C> (), tmp); + + minutes_ = 10 * (d1 - '0') + (d2 - '0'); + + if (minutes_ > 59) + throw invalid_value<C> (bits::date_time<C> (), tmp); + + // Find the end of the seconds fragment. + // + pos += 6; // Point to the first S. + + size_type sec_end (pos + 2); + for (; sec_end < size; ++sec_end) + { + C c (s[sec_end]); + + if (c == C ('Z') || c == C ('+') || c == C ('-')) + break; + } + + // At least one digit should should follow the fraction point. + // + if ((sec_end - pos) == 3) + throw invalid_value<C> (bits::date_time<C> (), tmp); + + ro_string<C> seconds_fragment (s + pos, sec_end - pos); + zc_istream<C> sis (seconds_fragment); + + if (!(sis >> seconds_ && sis.exhausted () && seconds_ < 60.0)) + throw invalid_value<C> (bits::date_time<C> (), tmp); + + if (hours_ == 24 && (minutes_ != 0 || seconds_ != 0.0)) + throw invalid_value<C> (bits::date_time<C> (), tmp); + + // zone + // + if (sec_end < size) + { + if (!bits::parse_tz (s + sec_end, size - sec_end, zh_, zm_)) + throw invalid_value<C> (bits::date_time<C> (), tmp); + + z_ = true; + } + else + z_ = false; + } + + template <typename C> + date_time date_time_pimpl<C>:: + post_date_time () + { + return z_ + ? date_time (year_, month_, day_, hours_, minutes_, seconds_, + zh_, zm_) + : date_time (year_, month_, day_, hours_, minutes_, seconds_); + } + + // duration + // + template <typename C> + void duration_pimpl<C>:: + _pre () + { + str_.clear (); + } + + template <typename C> + void duration_pimpl<C>:: + _characters (const ro_string<C>& s) + { + if (str_.size () == 0) + { + ro_string<C> tmp (s.data (), s.size ()); + + if (trim_left (tmp) != 0) + str_ += tmp; + } + else + str_ += s; + } + + namespace bits + { + template <typename C> + inline typename ro_string<C>::size_type + duration_delim (const C* s, + typename ro_string<C>::size_type pos, + typename ro_string<C>::size_type size) + { + const C* p (s + pos); + for (; p < (s + size); ++p) + { + if (*p == C ('Y') || *p == C ('D') || *p == C ('M') || + *p == C ('H') || *p == C ('M') || *p == C ('S') || + *p == C ('T')) + break; + } + + return p - s; + } + } + + template <typename C> + void duration_pimpl<C>:: + _post () + { + typedef typename ro_string<C>::size_type size_type; + + ro_string<C> tmp (str_); + size_type size (trim_right (tmp)); + + negative_ = false; + years_ = 0; + months_ = 0; + days_ = 0; + hours_ = 0; + minutes_ = 0; + seconds_ = 0.0; + + // duration := [-]P[nY][nM][nD][TnHnMn[.n+]S] + // + const C* s (tmp.data ()); + + if (size < 3 || (s[0] == C ('-') && size < 4)) + throw invalid_value<C> (bits::duration<C> (), tmp); + + size_type pos (0); + + if (s[0] == C ('-')) + { + negative_ = true; + pos++; + } + + if (s[pos++] != C ('P')) + throw invalid_value<C> (bits::duration<C> (), tmp); + + size_type del (bits::duration_delim (s, pos, size)); + + // Duration should contain at least one component. + // + if (del == size) + throw invalid_value<C> (bits::duration<C> (), tmp); + + if (s[del] == C ('Y')) + { + ro_string<C> fragment (s + pos, del - pos); + zc_istream<C> is (fragment); + + if (!(is >> years_ && is.exhausted ())) + throw invalid_value<C> (bits::duration<C> (), tmp); + + pos = del + 1; + del = bits::duration_delim (s, pos, size); + } + + if (del != size && s[del] == C ('M')) + { + ro_string<C> fragment (s + pos, del - pos); + zc_istream<C> is (fragment); + + if (!(is >> months_ && is.exhausted ())) + throw invalid_value<C> (bits::duration<C> (), tmp); + + pos = del + 1; + del = bits::duration_delim (s, pos, size); + } + + if (del != size && s[del] == C ('D')) + { + ro_string<C> fragment (s + pos, del - pos); + zc_istream<C> is (fragment); + + if (!(is >> days_ && is.exhausted ())) + throw invalid_value<C> (bits::duration<C> (), tmp); + + pos = del + 1; + del = bits::duration_delim (s, pos, size); + } + + if (del != size && s[del] == C ('T')) + { + pos = del + 1; + del = bits::duration_delim (s, pos, size); + + // At least one time component should be present. + // + if (del == size) + throw invalid_value<C> (bits::duration<C> (), tmp); + + if (s[del] == C ('H')) + { + ro_string<C> fragment (s + pos, del - pos); + zc_istream<C> is (fragment); + + if (!(is >> hours_ && is.exhausted ())) + throw invalid_value<C> (bits::duration<C> (), tmp); + + pos = del + 1; + del = bits::duration_delim (s, pos, size); + } + + if (del != size && s[del] == C ('M')) + { + ro_string<C> fragment (s + pos, del - pos); + zc_istream<C> is (fragment); + + if (!(is >> minutes_ && is.exhausted ())) + throw invalid_value<C> (bits::duration<C> (), tmp); + + pos = del + 1; + del = bits::duration_delim (s, pos, size); + } + + if (del != size && s[del] == C ('S')) + { + ro_string<C> fragment (s + pos, del - pos); + zc_istream<C> is (fragment); + + if (!(is >> seconds_ && is.exhausted () && seconds_ >= 0.0)) + throw invalid_value<C> (bits::duration<C> (), tmp); + + pos = del + 1; + } + } + + // Something did not match or appeared in the wrong order. + // + if (pos != size) + throw invalid_value<C> (bits::duration<C> (), tmp); + } + + template <typename C> + duration duration_pimpl<C>:: + post_duration () + { + return duration ( + negative_, years_, months_, days_, hours_, minutes_, seconds_); + } + } + } + } +} diff --git a/libxsd/xsd/cxx/parser/validating/xml-schema-pskel.hxx b/libxsd/xsd/cxx/parser/validating/xml-schema-pskel.hxx new file mode 100644 index 0000000..0fca037 --- /dev/null +++ b/libxsd/xsd/cxx/parser/validating/xml-schema-pskel.hxx @@ -0,0 +1,647 @@ +// file : xsd/cxx/parser/validating/xml-schema-pskel.hxx +// author : Boris Kolpackov <boris@codesynthesis.com> +// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSD_CXX_PARSER_VALIDATING_XML_SCHEMA_PSKEL_HXX +#define XSD_CXX_PARSER_VALIDATING_XML_SCHEMA_PSKEL_HXX + +#include <string> +#include <memory> // auto_ptr + +#include <xsd/cxx/parser/xml-schema.hxx> +#include <xsd/cxx/parser/validating/parser.hxx> + +namespace xsd +{ + namespace cxx + { + namespace parser + { + namespace validating + { + // anyType and anySimpleType. All events are routed to the + // _any_* callbacks. + // + template <typename C> + struct any_type_pskel: complex_content<C> + { + virtual bool + _start_element_impl (const ro_string<C>&, + const ro_string<C>&, + const ro_string<C>*); + + virtual bool + _end_element_impl (const ro_string<C>&, + const ro_string<C>&); + + virtual bool + _attribute_impl_phase_two (const ro_string<C>&, + const ro_string<C>&, + const ro_string<C>&); + + virtual bool + _characters_impl (const ro_string<C>&); + + virtual void + post_any_type () = 0; + + static const C* + _static_type (); + + virtual const C* + _dynamic_type () const; + }; + + template <typename C> + struct any_simple_type_pskel: simple_content<C> + { + virtual bool + _characters_impl (const ro_string<C>&); + + virtual void + post_any_simple_type () = 0; + + static const C* + _static_type (); + + virtual const C* + _dynamic_type () const; + }; + + + // Boolean. + // + template <typename C> + struct boolean_pskel: simple_content<C> + { + virtual bool + post_boolean () = 0; + + static const C* + _static_type (); + + virtual const C* + _dynamic_type () const; + }; + + + // 8-bit + // + template <typename C> + struct byte_pskel: simple_content<C> + { + virtual signed char + post_byte () = 0; + + static const C* + _static_type (); + + virtual const C* + _dynamic_type () const; + }; + + template <typename C> + struct unsigned_byte_pskel: simple_content<C> + { + virtual unsigned char + post_unsigned_byte () = 0; + + static const C* + _static_type (); + + virtual const C* + _dynamic_type () const; + }; + + + // 16-bit + // + template <typename C> + struct short_pskel: simple_content<C> + { + virtual short + post_short () = 0; + + static const C* + _static_type (); + + virtual const C* + _dynamic_type () const; + }; + + template <typename C> + struct unsigned_short_pskel: simple_content<C> + { + virtual unsigned short + post_unsigned_short () = 0; + + static const C* + _static_type (); + + virtual const C* + _dynamic_type () const; + }; + + + // 32-bit + // + template <typename C> + struct int_pskel: simple_content<C> + { + virtual int + post_int () = 0; + + static const C* + _static_type (); + + virtual const C* + _dynamic_type () const; + }; + + template <typename C> + struct unsigned_int_pskel: simple_content<C> + { + virtual unsigned int + post_unsigned_int () = 0; + + static const C* + _static_type (); + + virtual const C* + _dynamic_type () const; + }; + + + // 64-bit + // + template <typename C> + struct long_pskel: simple_content<C> + { + virtual long long + post_long () = 0; + + static const C* + _static_type (); + + virtual const C* + _dynamic_type () const; + }; + + template <typename C> + struct unsigned_long_pskel: simple_content<C> + { + virtual unsigned long long + post_unsigned_long () = 0; + + static const C* + _static_type (); + + virtual const C* + _dynamic_type () const; + }; + + + // Arbitrary-length integers. + // + template <typename C> + struct integer_pskel: simple_content<C> + { + virtual long long + post_integer () = 0; + + static const C* + _static_type (); + + virtual const C* + _dynamic_type () const; + }; + + template <typename C> + struct negative_integer_pskel: simple_content<C> + { + virtual long long + post_negative_integer () = 0; + + static const C* + _static_type (); + + virtual const C* + _dynamic_type () const; + }; + + template <typename C> + struct non_positive_integer_pskel: simple_content<C> + { + virtual long long + post_non_positive_integer () = 0; + + static const C* + _static_type (); + + virtual const C* + _dynamic_type () const; + }; + + template <typename C> + struct positive_integer_pskel: simple_content<C> + { + virtual unsigned long long + post_positive_integer () = 0; + + static const C* + _static_type (); + + virtual const C* + _dynamic_type () const; + }; + + template <typename C> + struct non_negative_integer_pskel: simple_content<C> + { + virtual unsigned long long + post_non_negative_integer () = 0; + + static const C* + _static_type (); + + virtual const C* + _dynamic_type () const; + }; + + + // Floats. + // + template <typename C> + struct float_pskel: simple_content<C> + { + virtual float + post_float () = 0; + + static const C* + _static_type (); + + virtual const C* + _dynamic_type () const; + }; + + template <typename C> + struct double_pskel: simple_content<C> + { + virtual double + post_double () = 0; + + static const C* + _static_type (); + + virtual const C* + _dynamic_type () const; + }; + + template <typename C> + struct decimal_pskel: simple_content<C> + { + virtual double + post_decimal () = 0; + + static const C* + _static_type (); + + virtual const C* + _dynamic_type () const; + }; + + + // Strings. + // + template <typename C> + struct string_pskel: simple_content<C> + { + virtual std::basic_string<C> + post_string () = 0; + + static const C* + _static_type (); + + virtual const C* + _dynamic_type () const; + }; + + template <typename C> + struct normalized_string_pskel: simple_content<C> + { + virtual std::basic_string<C> + post_normalized_string () = 0; + + static const C* + _static_type (); + + virtual const C* + _dynamic_type () const; + }; + + template <typename C> + struct token_pskel: simple_content<C> + { + virtual std::basic_string<C> + post_token () = 0; + + static const C* + _static_type (); + + virtual const C* + _dynamic_type () const; + }; + + template <typename C> + struct name_pskel: simple_content<C> + { + virtual std::basic_string<C> + post_name () = 0; + + static const C* + _static_type (); + + virtual const C* + _dynamic_type () const; + }; + + template <typename C> + struct nmtoken_pskel: simple_content<C> + { + virtual std::basic_string<C> + post_nmtoken () = 0; + + static const C* + _static_type (); + + virtual const C* + _dynamic_type () const; + }; + + template <typename C> + struct nmtokens_pskel: list_base<C> + { + virtual string_sequence<C> + post_nmtokens () = 0; + + static const C* + _static_type (); + + virtual const C* + _dynamic_type () const; + }; + + template <typename C> + struct ncname_pskel: simple_content<C> + { + virtual std::basic_string<C> + post_ncname () = 0; + + static const C* + _static_type (); + + virtual const C* + _dynamic_type () const; + }; + + template <typename C> + struct id_pskel: simple_content<C> + { + virtual std::basic_string<C> + post_id () = 0; + + static const C* + _static_type (); + + virtual const C* + _dynamic_type () const; + }; + + template <typename C> + struct idref_pskel: simple_content<C> + { + virtual std::basic_string<C> + post_idref () = 0; + + static const C* + _static_type (); + + virtual const C* + _dynamic_type () const; + }; + + template <typename C> + struct idrefs_pskel: list_base<C> + { + virtual string_sequence<C> + post_idrefs () = 0; + + static const C* + _static_type (); + + virtual const C* + _dynamic_type () const; + }; + + // Language. + // + template <typename C> + struct language_pskel: simple_content<C> + { + virtual std::basic_string<C> + post_language () = 0; + + static const C* + _static_type (); + + virtual const C* + _dynamic_type () const; + }; + + // URI. + // + template <typename C> + struct uri_pskel: simple_content<C> + { + virtual std::basic_string<C> + post_uri () = 0; + + static const C* + _static_type (); + + virtual const C* + _dynamic_type () const; + }; + + // QName. + // + template <typename C> + struct qname_pskel: simple_content<C> + { + virtual qname<C> + post_qname () = 0; + + static const C* + _static_type (); + + virtual const C* + _dynamic_type () const; + }; + + // Base64 and hex binaries. + // + template <typename C> + struct base64_binary_pskel: simple_content<C> + { + virtual std::auto_ptr<buffer> + post_base64_binary () = 0; + + static const C* + _static_type (); + + virtual const C* + _dynamic_type () const; + }; + + template <typename C> + struct hex_binary_pskel: simple_content<C> + { + virtual std::auto_ptr<buffer> + post_hex_binary () = 0; + + static const C* + _static_type (); + + virtual const C* + _dynamic_type () const; + }; + + // Time and date types. + // + template <typename C> + struct gday_pskel: simple_content<C> + { + virtual gday + post_gday () = 0; + + static const C* + _static_type (); + + virtual const C* + _dynamic_type () const; + }; + + template <typename C> + struct gmonth_pskel: simple_content<C> + { + virtual gmonth + post_gmonth () = 0; + + static const C* + _static_type (); + + virtual const C* + _dynamic_type () const; + }; + + template <typename C> + struct gyear_pskel: simple_content<C> + { + virtual gyear + post_gyear () = 0; + + static const C* + _static_type (); + + virtual const C* + _dynamic_type () const; + }; + + template <typename C> + struct gmonth_day_pskel: simple_content<C> + { + virtual gmonth_day + post_gmonth_day () = 0; + + static const C* + _static_type (); + + virtual const C* + _dynamic_type () const; + }; + + template <typename C> + struct gyear_month_pskel: simple_content<C> + { + virtual gyear_month + post_gyear_month () = 0; + + static const C* + _static_type (); + + virtual const C* + _dynamic_type () const; + }; + + template <typename C> + struct date_pskel: simple_content<C> + { + virtual date + post_date () = 0; + + static const C* + _static_type (); + + virtual const C* + _dynamic_type () const; + }; + + template <typename C> + struct time_pskel: simple_content<C> + { + virtual time + post_time () = 0; + + static const C* + _static_type (); + + virtual const C* + _dynamic_type () const; + }; + + template <typename C> + struct date_time_pskel: simple_content<C> + { + virtual date_time + post_date_time () = 0; + + static const C* + _static_type (); + + virtual const C* + _dynamic_type () const; + }; + + template <typename C> + struct duration_pskel: simple_content<C> + { + virtual duration + post_duration () = 0; + + static const C* + _static_type (); + + virtual const C* + _dynamic_type () const; + }; + } + } + } +} + +#include <xsd/cxx/parser/validating/xml-schema-pskel.txx> + +#endif // XSD_CXX_PARSER_VALIDATING_XML_SCHEMA_PSKEL_HXX + +#include <xsd/cxx/parser/validating/xml-schema-pskel.ixx> diff --git a/libxsd/xsd/cxx/parser/validating/xml-schema-pskel.ixx b/libxsd/xsd/cxx/parser/validating/xml-schema-pskel.ixx new file mode 100644 index 0000000..7a9f5e5 --- /dev/null +++ b/libxsd/xsd/cxx/parser/validating/xml-schema-pskel.ixx @@ -0,0 +1,1249 @@ +// file : xsd/cxx/parser/validating/xml-schema-pskel.ixx +// author : Boris Kolpackov <boris@codesynthesis.com> +// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#if defined(XSD_CXX_PARSER_USE_CHAR) || !defined(XSD_CXX_PARSER_USE_WCHAR) + +#ifndef XSD_CXX_PARSER_VALIDATING_XML_SCHEMA_PSKEL_IXX_CHAR +#define XSD_CXX_PARSER_VALIDATING_XML_SCHEMA_PSKEL_IXX_CHAR + +namespace xsd +{ + namespace cxx + { + namespace parser + { + namespace validating + { + template<> + inline const char* any_type_pskel<char>:: + _static_type () + { + return "anyType http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const char* any_type_pskel<char>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const char* any_simple_type_pskel<char>:: + _static_type () + { + return "anySimpleType http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const char* any_simple_type_pskel<char>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const char* boolean_pskel<char>:: + _static_type () + { + return "boolean http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const char* boolean_pskel<char>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const char* byte_pskel<char>:: + _static_type () + { + return "byte http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const char* byte_pskel<char>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const char* unsigned_byte_pskel<char>:: + _static_type () + { + return "unsignedByte http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const char* unsigned_byte_pskel<char>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const char* short_pskel<char>:: + _static_type () + { + return "short http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const char* short_pskel<char>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const char* unsigned_short_pskel<char>:: + _static_type () + { + return "unsignedShort http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const char* unsigned_short_pskel<char>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const char* int_pskel<char>:: + _static_type () + { + return "int http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const char* int_pskel<char>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const char* unsigned_int_pskel<char>:: + _static_type () + { + return "unsignedInt http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const char* unsigned_int_pskel<char>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const char* long_pskel<char>:: + _static_type () + { + return "long http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const char* long_pskel<char>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const char* unsigned_long_pskel<char>:: + _static_type () + { + return "unsignedLong http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const char* unsigned_long_pskel<char>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const char* integer_pskel<char>:: + _static_type () + { + return "integer http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const char* integer_pskel<char>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const char* negative_integer_pskel<char>:: + _static_type () + { + return "negativeInteger http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const char* negative_integer_pskel<char>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const char* non_positive_integer_pskel<char>:: + _static_type () + { + return "nonPositiveInteger http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const char* non_positive_integer_pskel<char>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const char* positive_integer_pskel<char>:: + _static_type () + { + return "positiveInteger http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const char* positive_integer_pskel<char>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const char* non_negative_integer_pskel<char>:: + _static_type () + { + return "nonNegativeInteger http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const char* non_negative_integer_pskel<char>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const char* float_pskel<char>:: + _static_type () + { + return "float http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const char* float_pskel<char>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const char* double_pskel<char>:: + _static_type () + { + return "double http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const char* double_pskel<char>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const char* decimal_pskel<char>:: + _static_type () + { + return "decimal http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const char* decimal_pskel<char>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const char* string_pskel<char>:: + _static_type () + { + return "string http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const char* string_pskel<char>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const char* normalized_string_pskel<char>:: + _static_type () + { + return "normalizedString http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const char* normalized_string_pskel<char>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const char* token_pskel<char>:: + _static_type () + { + return "token http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const char* token_pskel<char>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const char* name_pskel<char>:: + _static_type () + { + return "Name http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const char* name_pskel<char>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const char* nmtoken_pskel<char>:: + _static_type () + { + return "NMTOKEN http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const char* nmtoken_pskel<char>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const char* nmtokens_pskel<char>:: + _static_type () + { + return "NMTOKENS http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const char* nmtokens_pskel<char>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const char* ncname_pskel<char>:: + _static_type () + { + return "NCName http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const char* ncname_pskel<char>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const char* id_pskel<char>:: + _static_type () + { + return "ID http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const char* id_pskel<char>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const char* idref_pskel<char>:: + _static_type () + { + return "IDREF http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const char* idref_pskel<char>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const char* idrefs_pskel<char>:: + _static_type () + { + return "IDREFS http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const char* idrefs_pskel<char>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const char* language_pskel<char>:: + _static_type () + { + return "language http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const char* language_pskel<char>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const char* uri_pskel<char>:: + _static_type () + { + return "anyURI http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const char* uri_pskel<char>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const char* qname_pskel<char>:: + _static_type () + { + return "QName http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const char* qname_pskel<char>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const char* base64_binary_pskel<char>:: + _static_type () + { + return "base64Binary http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const char* base64_binary_pskel<char>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const char* hex_binary_pskel<char>:: + _static_type () + { + return "hexBinary http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const char* hex_binary_pskel<char>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const char* gday_pskel<char>:: + _static_type () + { + return "gDay http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const char* gday_pskel<char>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const char* gmonth_pskel<char>:: + _static_type () + { + return "gMonth http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const char* gmonth_pskel<char>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const char* gyear_pskel<char>:: + _static_type () + { + return "gYear http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const char* gyear_pskel<char>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const char* gmonth_day_pskel<char>:: + _static_type () + { + return "gMonthDay http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const char* gmonth_day_pskel<char>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const char* gyear_month_pskel<char>:: + _static_type () + { + return "gYearMonth http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const char* gyear_month_pskel<char>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const char* date_pskel<char>:: + _static_type () + { + return "date http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const char* date_pskel<char>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const char* time_pskel<char>:: + _static_type () + { + return "time http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const char* time_pskel<char>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const char* date_time_pskel<char>:: + _static_type () + { + return "dateTime http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const char* date_time_pskel<char>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const char* duration_pskel<char>:: + _static_type () + { + return "duration http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const char* duration_pskel<char>:: + _dynamic_type () const + { + return _static_type (); + } + } + } + } +} + +#endif // XSD_CXX_PARSER_VALIDATING_XML_SCHEMA_PSKEL_IXX_CHAR +#endif // XSD_CXX_PARSER_USE_CHAR + + +#if defined(XSD_CXX_PARSER_USE_WCHAR) || !defined(XSD_CXX_PARSER_USE_CHAR) + +#ifndef XSD_CXX_PARSER_VALIDATING_XML_SCHEMA_PSKEL_IXX_WCHAR +#define XSD_CXX_PARSER_VALIDATING_XML_SCHEMA_PSKEL_IXX_WCHAR + +namespace xsd +{ + namespace cxx + { + namespace parser + { + namespace validating + { + template<> + inline const wchar_t* any_type_pskel<wchar_t>:: + _static_type () + { + return L"anyType http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const wchar_t* any_type_pskel<wchar_t>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const wchar_t* any_simple_type_pskel<wchar_t>:: + _static_type () + { + return L"anySimpleType http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const wchar_t* any_simple_type_pskel<wchar_t>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const wchar_t* boolean_pskel<wchar_t>:: + _static_type () + { + return L"boolean http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const wchar_t* boolean_pskel<wchar_t>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const wchar_t* byte_pskel<wchar_t>:: + _static_type () + { + return L"byte http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const wchar_t* byte_pskel<wchar_t>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const wchar_t* unsigned_byte_pskel<wchar_t>:: + _static_type () + { + return L"unsignedByte http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const wchar_t* unsigned_byte_pskel<wchar_t>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const wchar_t* short_pskel<wchar_t>:: + _static_type () + { + return L"short http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const wchar_t* short_pskel<wchar_t>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const wchar_t* unsigned_short_pskel<wchar_t>:: + _static_type () + { + return L"unsignedShort http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const wchar_t* unsigned_short_pskel<wchar_t>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const wchar_t* int_pskel<wchar_t>:: + _static_type () + { + return L"int http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const wchar_t* int_pskel<wchar_t>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const wchar_t* unsigned_int_pskel<wchar_t>:: + _static_type () + { + return L"unsignedInt http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const wchar_t* unsigned_int_pskel<wchar_t>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const wchar_t* long_pskel<wchar_t>:: + _static_type () + { + return L"long http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const wchar_t* long_pskel<wchar_t>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const wchar_t* unsigned_long_pskel<wchar_t>:: + _static_type () + { + return L"unsignedLong http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const wchar_t* unsigned_long_pskel<wchar_t>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const wchar_t* integer_pskel<wchar_t>:: + _static_type () + { + return L"integer http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const wchar_t* integer_pskel<wchar_t>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const wchar_t* negative_integer_pskel<wchar_t>:: + _static_type () + { + return L"negativeInteger http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const wchar_t* negative_integer_pskel<wchar_t>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const wchar_t* non_positive_integer_pskel<wchar_t>:: + _static_type () + { + return L"nonPositiveInteger http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const wchar_t* non_positive_integer_pskel<wchar_t>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const wchar_t* positive_integer_pskel<wchar_t>:: + _static_type () + { + return L"positiveInteger http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const wchar_t* positive_integer_pskel<wchar_t>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const wchar_t* non_negative_integer_pskel<wchar_t>:: + _static_type () + { + return L"nonNegativeInteger http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const wchar_t* non_negative_integer_pskel<wchar_t>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const wchar_t* float_pskel<wchar_t>:: + _static_type () + { + return L"float http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const wchar_t* float_pskel<wchar_t>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const wchar_t* double_pskel<wchar_t>:: + _static_type () + { + return L"double http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const wchar_t* double_pskel<wchar_t>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const wchar_t* decimal_pskel<wchar_t>:: + _static_type () + { + return L"decimal http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const wchar_t* decimal_pskel<wchar_t>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const wchar_t* string_pskel<wchar_t>:: + _static_type () + { + return L"string http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const wchar_t* string_pskel<wchar_t>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const wchar_t* normalized_string_pskel<wchar_t>:: + _static_type () + { + return L"normalizedString http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const wchar_t* normalized_string_pskel<wchar_t>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const wchar_t* token_pskel<wchar_t>:: + _static_type () + { + return L"token http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const wchar_t* token_pskel<wchar_t>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const wchar_t* name_pskel<wchar_t>:: + _static_type () + { + return L"Name http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const wchar_t* name_pskel<wchar_t>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const wchar_t* nmtoken_pskel<wchar_t>:: + _static_type () + { + return L"NMTOKEN http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const wchar_t* nmtoken_pskel<wchar_t>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const wchar_t* nmtokens_pskel<wchar_t>:: + _static_type () + { + return L"NMTOKENS http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const wchar_t* nmtokens_pskel<wchar_t>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const wchar_t* ncname_pskel<wchar_t>:: + _static_type () + { + return L"NCName http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const wchar_t* ncname_pskel<wchar_t>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const wchar_t* id_pskel<wchar_t>:: + _static_type () + { + return L"ID http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const wchar_t* id_pskel<wchar_t>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const wchar_t* idref_pskel<wchar_t>:: + _static_type () + { + return L"IDREF http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const wchar_t* idref_pskel<wchar_t>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const wchar_t* idrefs_pskel<wchar_t>:: + _static_type () + { + return L"IDREFS http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const wchar_t* idrefs_pskel<wchar_t>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const wchar_t* language_pskel<wchar_t>:: + _static_type () + { + return L"language http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const wchar_t* language_pskel<wchar_t>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const wchar_t* uri_pskel<wchar_t>:: + _static_type () + { + return L"anyURI http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const wchar_t* uri_pskel<wchar_t>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const wchar_t* qname_pskel<wchar_t>:: + _static_type () + { + return L"QName http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const wchar_t* qname_pskel<wchar_t>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const wchar_t* base64_binary_pskel<wchar_t>:: + _static_type () + { + return L"base64Binary http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const wchar_t* base64_binary_pskel<wchar_t>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const wchar_t* hex_binary_pskel<wchar_t>:: + _static_type () + { + return L"hexBinary http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const wchar_t* hex_binary_pskel<wchar_t>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const wchar_t* gday_pskel<wchar_t>:: + _static_type () + { + return L"gDay http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const wchar_t* gday_pskel<wchar_t>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const wchar_t* gmonth_pskel<wchar_t>:: + _static_type () + { + return L"gMonth http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const wchar_t* gmonth_pskel<wchar_t>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const wchar_t* gyear_pskel<wchar_t>:: + _static_type () + { + return L"gYear http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const wchar_t* gyear_pskel<wchar_t>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const wchar_t* gmonth_day_pskel<wchar_t>:: + _static_type () + { + return L"gMonthDay http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const wchar_t* gmonth_day_pskel<wchar_t>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const wchar_t* gyear_month_pskel<wchar_t>:: + _static_type () + { + return L"gYearMonth http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const wchar_t* gyear_month_pskel<wchar_t>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const wchar_t* date_pskel<wchar_t>:: + _static_type () + { + return L"date http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const wchar_t* date_pskel<wchar_t>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const wchar_t* time_pskel<wchar_t>:: + _static_type () + { + return L"time http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const wchar_t* time_pskel<wchar_t>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const wchar_t* date_time_pskel<wchar_t>:: + _static_type () + { + return L"dateTime http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const wchar_t* date_time_pskel<wchar_t>:: + _dynamic_type () const + { + return _static_type (); + } + + template<> + inline const wchar_t* duration_pskel<wchar_t>:: + _static_type () + { + return L"duration http://www.w3.org/2001/XMLSchema"; + } + + template<> + inline const wchar_t* duration_pskel<wchar_t>:: + _dynamic_type () const + { + return _static_type (); + } + } + } + } +} + +#endif // XSD_CXX_PARSER_VALIDATING_XML_SCHEMA_PSKEL_IXX_WCHAR +#endif // XSD_CXX_PARSER_USE_WCHAR diff --git a/libxsd/xsd/cxx/parser/validating/xml-schema-pskel.txx b/libxsd/xsd/cxx/parser/validating/xml-schema-pskel.txx new file mode 100644 index 0000000..c5fe5ef --- /dev/null +++ b/libxsd/xsd/cxx/parser/validating/xml-schema-pskel.txx @@ -0,0 +1,69 @@ +// file : xsd/cxx/parser/validating/xml-schema-pskel.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 + +namespace xsd +{ + namespace cxx + { + namespace parser + { + namespace validating + { + // any_type + // + + template <typename C> + bool any_type_pskel<C>:: + _start_element_impl (const ro_string<C>& ns, + const ro_string<C>& name, + const ro_string<C>* type) + { + _start_any_element (ns, name, type); + this->complex_content<C>::context_.top ().any_ = true; + return true; + } + + template <typename C> + bool any_type_pskel<C>:: + _end_element_impl (const ro_string<C>& ns, const ro_string<C>& name) + { + this->complex_content<C>::context_.top ().any_ = false; + _end_any_element (ns, name); + return true; + } + + + template <typename C> + bool any_type_pskel<C>:: + _attribute_impl_phase_two (const ro_string<C>& ns, + const ro_string<C>& name, + const ro_string<C>& value) + { + _any_attribute (ns, name, value); + return true; + } + + template <typename C> + bool any_type_pskel<C>:: + _characters_impl (const ro_string<C>& s) + { + _any_characters (s); + return true; + } + + // any_simple_type + // + + template <typename C> + bool any_simple_type_pskel<C>:: + _characters_impl (const ro_string<C>& s) + { + _any_characters (s); + return true; + } + } + } + } +} diff --git a/libxsd/xsd/cxx/parser/xerces/elements.hxx b/libxsd/xsd/cxx/parser/xerces/elements.hxx new file mode 100644 index 0000000..9d79e61 --- /dev/null +++ b/libxsd/xsd/cxx/parser/xerces/elements.hxx @@ -0,0 +1,462 @@ +// file : xsd/cxx/parser/xerces/elements.hxx +// author : Boris Kolpackov <boris@codesynthesis.com> +// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSD_CXX_PARSER_XERCES_ELEMENTS_HXX +#define XSD_CXX_PARSER_XERCES_ELEMENTS_HXX + +#include <memory> // std::auto_ptr +#include <string> +#include <iosfwd> +#include <vector> + +#include <xercesc/sax/Locator.hpp> +#include <xercesc/sax/InputSource.hpp> +#include <xercesc/sax2/SAX2XMLReader.hpp> +#include <xercesc/sax2/DefaultHandler.hpp> + +#include <xsd/cxx/xml/elements.hxx> +#include <xsd/cxx/xml/error-handler.hxx> + +#include <xsd/cxx/parser/exceptions.hxx> +#include <xsd/cxx/parser/elements.hxx> +#include <xsd/cxx/parser/document.hxx> + +namespace xsd +{ + namespace cxx + { + namespace parser + { + namespace xerces + { + // + // + struct flags + { + // Use the following flags to modify the default behavior + // of the parsing functions. + // + + // Do not try to validate instance documents. + // + static const unsigned long dont_validate = 0x00000001; + + // Do not initialize the Xerces-C++ runtime. + // + static const unsigned long dont_initialize = 0x00000002; + + // Disable handling of subsequent imports for the same namespace + // in Xerces-C++ 3-series. + // + static const unsigned long no_multiple_imports = 0x00000004; + + public: + flags (unsigned long x = 0) + : x_ (x) + { + } + + operator unsigned long () const + { + return x_; + } + + private: + unsigned long x_; + }; + + + // Parsing properties. Refer to xsd/cxx/xml/elements.hxx for + // XML-related properties. + // + template <typename C> + class properties: public xml::properties<C> + { + }; + + // + // + template <typename C> + struct document: cxx::parser::document<C> // VC 7.1 likes it qualified + { + public: + document (parser_base<C>& root, + const C* root_element_name, + bool polymorphic = false); + + document (parser_base<C>& root, + const std::basic_string<C>& root_element_name, + bool polymorphic = false); + + document (parser_base<C>& root, + const C* root_element_namespace, + const C* root_element_name, + bool polymorphic = false); + + document (parser_base<C>& root, + const std::basic_string<C>& root_element_namespace, + const std::basic_string<C>& root_element_name, + bool polymorphic = false); + + protected: + explicit + document (bool polymorphic = false); + + public: + // Parse URI or a local file. We have to overload it for const C* + // bacause xercesc::InputSource has an implicit constructor that + // takes const char*. + // + void + parse (const std::basic_string<C>& uri, + flags = 0, + const properties<C>& = properties<C> ()); + + void + parse (const C* uri, + flags = 0, + const properties<C>& = properties<C> ()); + + + // Parse URI or a local file with a user-provided error_handler + // object. + // + void + parse (const std::basic_string<C>& uri, + xml::error_handler<C>&, + flags = 0, + const properties<C>& = properties<C> ()); + + void + parse (const C* uri, + xml::error_handler<C>&, + flags = 0, + const properties<C>& = properties<C> ()); + + + // Parse URI or a local file with a user-provided ErrorHandler + // object. Note that you must initialize the Xerces-C++ runtime + // before calling these functions. + // + void + parse (const std::basic_string<C>& uri, + xercesc::ErrorHandler&, + flags = 0, + const properties<C>& = properties<C> ()); + + void + parse (const C* uri, + xercesc::ErrorHandler&, + flags = 0, + const properties<C>& = properties<C> ()); + + + // Parse URI or a local file using a user-provided SAX2XMLReader + // object. Note that you must initialize the Xerces-C++ runtime + // before calling these functions. + // + void + parse (const std::basic_string<C>& uri, + xercesc::SAX2XMLReader&, + flags = 0, + const properties<C>& = properties<C> ()); + + void + parse (const C* uri, + xercesc::SAX2XMLReader&, + flags = 0, + const properties<C>& = properties<C> ()); + + + public: + // System id is a "system" identifier of the resources (e.g., + // URI or a full file path). Public id is a "public" identifier + // of the resource (e.g., an application-specific name or a + // relative file path). System id is used to resolve relative + // paths. In diagnostics messages system id is used if public + // id is not available. Otherwise public id is used. + // + + // Parse std::istream. + // + void + parse (std::istream&, + flags = 0, + const properties<C>& = properties<C> ()); + + + // Parse std::istream with a user-provided error_handler object. + // + void + parse (std::istream&, + xml::error_handler<C>&, + flags = 0, + const properties<C>& = properties<C> ()); + + + // Parse std::istream with a user-provided ErrorHandler object. + // Note that you must initialize the Xerces-C++ runtime before + // calling this function. + // + void + parse (std::istream&, + xercesc::ErrorHandler&, + flags = 0, + const properties<C>& = properties<C> ()); + + + // Parse std::istream using a user-provided SAX2XMLReader object. + // Note that you must initialize the Xerces-C++ runtime before + // calling this function. + // + void + parse (std::istream&, + xercesc::SAX2XMLReader&, + flags = 0, + const properties<C>& = properties<C> ()); + + + public: + // Parse std::istream with a system id. + // + void + parse (std::istream&, + const std::basic_string<C>& system_id, + flags = 0, + const properties<C>& = properties<C> ()); + + + // Parse std::istream with a system id and a user-provided + // error_handler object. + // + void + parse (std::istream&, + const std::basic_string<C>& system_id, + xml::error_handler<C>&, + flags = 0, + const properties<C>& = properties<C> ()); + + + // Parse std::istream with a system id and a user-provided + // ErrorHandler object. Note that you must initialize the + // Xerces-C++ runtime before calling this function. + // + void + parse (std::istream&, + const std::basic_string<C>& system_id, + xercesc::ErrorHandler&, + flags = 0, + const properties<C>& = properties<C> ()); + + + // Parse std::istream with a system id using a user-provided + // SAX2XMLReader object. Note that you must initialize the + // Xerces-C++ runtime before calling this function. + // + void + parse (std::istream&, + const std::basic_string<C>& system_id, + xercesc::SAX2XMLReader&, + flags = 0, + const properties<C>& = properties<C> ()); + + + + public: + // Parse std::istream with system and public ids. + // + void + parse (std::istream&, + const std::basic_string<C>& system_id, + const std::basic_string<C>& public_id, + flags = 0, + const properties<C>& = properties<C> ()); + + + // Parse std::istream with system and public ids and a user-provided + // error_handler object. + // + void + parse (std::istream&, + const std::basic_string<C>& system_id, + const std::basic_string<C>& public_id, + xml::error_handler<C>&, + flags = 0, + const properties<C>& = properties<C> ()); + + + // Parse std::istream with system and public ids and a user-provided + // ErrorHandler object. Note that you must initialize the Xerces-C++ + // runtime before calling this function. + // + void + parse (std::istream&, + const std::basic_string<C>& system_id, + const std::basic_string<C>& public_id, + xercesc::ErrorHandler&, + flags = 0, + const properties<C>& = properties<C> ()); + + + // Parse std::istream with system and public ids using a user- + // provided SAX2XMLReader object. Note that you must initialize + // the Xerces-C++ runtime before calling this function. + // + void + parse (std::istream&, + const std::basic_string<C>& system_id, + const std::basic_string<C>& public_id, + xercesc::SAX2XMLReader&, + flags = 0, + const properties<C>& = properties<C> ()); + + + public: + // Parse InputSource. Note that you must initialize the Xerces-C++ + // runtime before calling this function. + // + void + parse (const xercesc::InputSource&, + flags = 0, + const properties<C>& = properties<C> ()); + + + // Parse InputSource with a user-provided error_handler object. + // Note that you must initialize the Xerces-C++ runtime before + // calling this function. + // + void + parse (const xercesc::InputSource&, + xml::error_handler<C>&, + flags = 0, + const properties<C>& = properties<C> ()); + + + // Parse InputSource with a user-provided ErrorHandler object. + // Note that you must initialize the Xerces-C++ runtime before + // calling this function. + // + void + parse (const xercesc::InputSource&, + xercesc::ErrorHandler&, + flags = 0, + const properties<C>& = properties<C> ()); + + + // Parse InputSource using a user-provided SAX2XMLReader object. + // Note that you must initialize the Xerces-C++ runtime before + // calling this function. + // + void + parse (const xercesc::InputSource&, + xercesc::SAX2XMLReader&, + flags = 0, + const properties<C>& = properties<C> ()); + + private: + void + parse (const std::basic_string<C>& uri, + xercesc::ErrorHandler&, + xercesc::SAX2XMLReader&, + flags, + const properties<C>&); + + void + parse (const xercesc::InputSource&, + xercesc::ErrorHandler&, + xercesc::SAX2XMLReader&, + flags, + const properties<C>&); + + private: + std::auto_ptr<xercesc::SAX2XMLReader> + create_sax_ (flags, const properties<C>&); + + private: + bool polymorphic_; + }; + + // + // + template <typename C> + struct event_router: xercesc::DefaultHandler + { + event_router (cxx::parser::document<C>&, bool polymorphic); + + // I know, some of those consts are stupid. But that's what + // Xerces folks put into their interfaces and VC 7.1 thinks + // there are different signatures if one strips this fluff off. + // + virtual void + setDocumentLocator (const xercesc::Locator* const); + + virtual void + startElement (const XMLCh* const uri, + const XMLCh* const lname, + const XMLCh* const qname, + const xercesc::Attributes& attributes); + + virtual void + endElement (const XMLCh* const uri, + const XMLCh* const lname, + const XMLCh* const qname); + +#if _XERCES_VERSION >= 30000 + virtual void + characters (const XMLCh* const s, const XMLSize_t length); +#else + virtual void + characters (const XMLCh* const s, const unsigned int length); +#endif + + virtual void + startPrefixMapping (const XMLCh* const prefix, + const XMLCh* const uri); + + virtual void + endPrefixMapping (const XMLCh* const prefix); + + private: + void + set_location (schema_exception<C>&); + + private: + const xercesc::Locator* loc_; + cxx::parser::document<C>& consumer_; + bool polymorphic_; + + // Last element name cache. + // + bool last_valid_; + std::basic_string<C> last_ns_; + std::basic_string<C> last_name_; + + // Namespace-prefix mapping. Only maintained in the polymorphic + // case. + // + struct ns_decl + { + ns_decl (const std::basic_string<C>& p, + const std::basic_string<C>& n) + : prefix (p), ns (n) + { + } + + std::basic_string<C> prefix; + std::basic_string<C> ns; + }; + + typedef std::vector<ns_decl> ns_decls; + + ns_decls ns_decls_; + }; + } + } + } +} + +#include <xsd/cxx/parser/xerces/elements.txx> + +#endif // XSD_CXX_PARSER_XERCES_ELEMENTS_HXX diff --git a/libxsd/xsd/cxx/parser/xerces/elements.txx b/libxsd/xsd/cxx/parser/xerces/elements.txx new file mode 100644 index 0000000..e09ffc5 --- /dev/null +++ b/libxsd/xsd/cxx/parser/xerces/elements.txx @@ -0,0 +1,964 @@ +// file : xsd/cxx/parser/xerces/elements.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 <istream> +#include <cstddef> // std::size_t +#include <cassert> + +#include <xercesc/sax/SAXParseException.hpp> +#include <xercesc/sax2/Attributes.hpp> +#include <xercesc/sax2/XMLReaderFactory.hpp> +#include <xercesc/validators/schema/SchemaSymbols.hpp> +#include <xercesc/util/XMLUni.hpp> + +#include <xsd/cxx/xml/string.hxx> +#include <xsd/cxx/xml/sax/std-input-source.hxx> +#include <xsd/cxx/xml/sax/bits/error-handler-proxy.hxx> +#include <xsd/cxx/xml/bits/literals.hxx> // xml::bits::{xml_prefix, etc} + +#include <xsd/cxx/parser/error-handler.hxx> +#include <xsd/cxx/parser/schema-exceptions.hxx> + +namespace xsd +{ + namespace cxx + { + namespace parser + { + namespace xerces + { + + // document + // + + template <typename C> + document<C>:: + document (parser_base<C>& parser, + const C* name, + bool polymorphic) + : cxx::parser::document<C> (parser, std::basic_string<C> (), name), + polymorphic_ (polymorphic) + { + } + + template <typename C> + document<C>:: + document (parser_base<C>& parser, + const std::basic_string<C>& name, + bool polymorphic) + : cxx::parser::document<C> (parser, std::basic_string<C> (), name), + polymorphic_ (polymorphic) + { + } + + template <typename C> + document<C>:: + document (parser_base<C>& parser, + const C* ns, + const C* name, + bool polymorphic) + : cxx::parser::document<C> (parser, ns, name), + polymorphic_ (polymorphic) + { + } + + template <typename C> + document<C>:: + document (parser_base<C>& parser, + const std::basic_string<C>& ns, + const std::basic_string<C>& name, + bool polymorphic) + : cxx::parser::document<C> (parser, ns, name), + polymorphic_ (polymorphic) + { + } + + template <typename C> + document<C>:: + document (bool polymorphic) + : polymorphic_ (polymorphic) + { + } + + // parse (uri) + // + template <typename C> + void document<C>:: + parse (const std::basic_string<C>& uri, + flags f, + const properties<C>& p) + { + xml::auto_initializer init ((f & flags::dont_initialize) == 0); + + error_handler<C> eh; + xml::sax::bits::error_handler_proxy<C> eh_proxy (eh); + std::auto_ptr<xercesc::SAX2XMLReader> sax (create_sax_ (f, p)); + + parse (uri, eh_proxy, *sax, f, p); + + eh.throw_if_failed (); + } + + template <typename C> + void document<C>:: + parse (const C* uri, + flags f, + const properties<C>& p) + { + parse (std::basic_string<C> (uri), f, p); + } + + // error_handler + // + + template <typename C> + void document<C>:: + parse (const std::basic_string<C>& uri, + xml::error_handler<C>& eh, + flags f, + const properties<C>& p) + { + xml::auto_initializer init ((f & flags::dont_initialize) == 0); + + xml::sax::bits::error_handler_proxy<C> eh_proxy (eh); + std::auto_ptr<xercesc::SAX2XMLReader> sax (create_sax_ (f, p)); + + parse (uri, eh_proxy, *sax, f, p); + + if (eh_proxy.failed ()) + throw parsing<C> (); + } + + template <typename C> + void document<C>:: + parse (const C* uri, + xml::error_handler<C>& eh, + flags f, + const properties<C>& p) + { + parse (std::basic_string<C> (uri), eh, f, p); + } + + // ErrorHandler + // + + template <typename C> + void document<C>:: + parse (const std::basic_string<C>& uri, + xercesc::ErrorHandler& eh, + flags f, + const properties<C>& p) + { + xml::sax::bits::error_handler_proxy<C> eh_proxy (eh); + std::auto_ptr<xercesc::SAX2XMLReader> sax (create_sax_ (f, p)); + + parse (uri, eh_proxy, *sax, f, p); + + if (eh_proxy.failed ()) + throw parsing<C> (); + } + + template <typename C> + void document<C>:: + parse (const C* uri, + xercesc::ErrorHandler& eh, + flags f, + const properties<C>& p) + { + parse (std::basic_string<C> (uri), eh, f, p); + } + + // SAX2XMLReader + // + + template <typename C> + void document<C>:: + parse (const std::basic_string<C>& uri, + xercesc::SAX2XMLReader& sax, + flags f, + const properties<C>& p) + { + // If there is no error handler, then fall back on the default + // implementation. + // + xercesc::ErrorHandler* eh (sax.getErrorHandler ()); + + if (eh) + { + xml::sax::bits::error_handler_proxy<C> eh_proxy (*eh); + + parse (uri, eh_proxy, sax, f, p); + + if (eh_proxy.failed ()) + throw parsing<C> (); + } + else + { + error_handler<C> fallback_eh; + xml::sax::bits::error_handler_proxy<C> eh_proxy (fallback_eh); + + parse (uri, eh_proxy, sax, f, p); + + fallback_eh.throw_if_failed (); + } + } + + template <typename C> + void document<C>:: + parse (const C* uri, + xercesc::SAX2XMLReader& sax, + flags f, + const properties<C>& p) + { + parse (std::basic_string<C> (uri), sax, f, p); + } + + // parse (istream) + // + + template <typename C> + void document<C>:: + parse (std::istream& is, + flags f, + const properties<C>& p) + { + xml::auto_initializer init ((f & flags::dont_initialize) == 0); + + xml::sax::std_input_source isrc (is); + + parse (isrc, f, p); + } + + template <typename C> + void document<C>:: + parse (std::istream& is, + xml::error_handler<C>& eh, + flags f, + const properties<C>& p) + { + xml::auto_initializer init ((f & flags::dont_initialize) == 0); + xml::sax::std_input_source isrc (is); + parse (isrc, eh, f, p); + } + + template <typename C> + void document<C>:: + parse (std::istream& is, + xercesc::ErrorHandler& eh, + flags f, + const properties<C>& p) + { + xml::sax::std_input_source isrc (is); + parse (isrc, eh, f, p); + } + + template <typename C> + void document<C>:: + parse (std::istream& is, + xercesc::SAX2XMLReader& sax, + flags f, + const properties<C>& p) + { + xml::sax::std_input_source isrc (is); + parse (isrc, sax, f, p); + } + + + // parse (istream, system_id) + // + + + template <typename C> + void document<C>:: + parse (std::istream& is, + const std::basic_string<C>& system_id, + flags f, + const properties<C>& p) + { + xml::auto_initializer init ((f & flags::dont_initialize) == 0); + xml::sax::std_input_source isrc (is, system_id); + parse (isrc, f, p); + } + + template <typename C> + void document<C>:: + parse (std::istream& is, + const std::basic_string<C>& system_id, + xml::error_handler<C>& eh, + flags f, + const properties<C>& p) + { + xml::auto_initializer init ((f & flags::dont_initialize) == 0); + xml::sax::std_input_source isrc (is, system_id); + parse (isrc, eh, f, p); + } + + template <typename C> + void document<C>:: + parse (std::istream& is, + const std::basic_string<C>& system_id, + xercesc::ErrorHandler& eh, + flags f, + const properties<C>& p) + { + xml::sax::std_input_source isrc (is, system_id); + parse (isrc, eh, f, p); + } + + template <typename C> + void document<C>:: + parse (std::istream& is, + const std::basic_string<C>& system_id, + xercesc::SAX2XMLReader& sax, + flags f, + const properties<C>& p) + { + xml::sax::std_input_source isrc (is, system_id); + parse (isrc, sax, f, p); + } + + + // parse (istream, system_id, public_id) + // + + template <typename C> + void document<C>:: + parse (std::istream& is, + const std::basic_string<C>& system_id, + const std::basic_string<C>& public_id, + flags f, + const properties<C>& p) + { + xml::auto_initializer init ((f & flags::dont_initialize) == 0); + xml::sax::std_input_source isrc (is, system_id, public_id); + parse (isrc, f, p); + } + + template <typename C> + void document<C>:: + parse (std::istream& is, + const std::basic_string<C>& system_id, + const std::basic_string<C>& public_id, + xml::error_handler<C>& eh, + flags f, + const properties<C>& p) + { + xml::auto_initializer init ((f & flags::dont_initialize) == 0); + xml::sax::std_input_source isrc (is, system_id, public_id); + parse (isrc, eh, f, p); + } + + template <typename C> + void document<C>:: + parse (std::istream& is, + const std::basic_string<C>& system_id, + const std::basic_string<C>& public_id, + xercesc::ErrorHandler& eh, + flags f, + const properties<C>& p) + { + xml::sax::std_input_source isrc (is, system_id, public_id); + parse (isrc, eh, f, p); + } + + template <typename C> + void document<C>:: + parse (std::istream& is, + const std::basic_string<C>& system_id, + const std::basic_string<C>& public_id, + xercesc::SAX2XMLReader& sax, + flags f, + const properties<C>& p) + { + xml::sax::std_input_source isrc (is, system_id, public_id); + parse (isrc, sax, f, p); + } + + + // parse (InputSource) + // + + + template <typename C> + void document<C>:: + parse (const xercesc::InputSource& is, + flags f, + const properties<C>& p) + { + error_handler<C> eh; + xml::sax::bits::error_handler_proxy<C> eh_proxy (eh); + std::auto_ptr<xercesc::SAX2XMLReader> sax (create_sax_ (f, p)); + + parse (is, eh_proxy, *sax, f, p); + + eh.throw_if_failed (); + } + + template <typename C> + void document<C>:: + parse (const xercesc::InputSource& is, + xml::error_handler<C>& eh, + flags f, + const properties<C>& p) + { + xml::sax::bits::error_handler_proxy<C> eh_proxy (eh); + std::auto_ptr<xercesc::SAX2XMLReader> sax (create_sax_ (f, p)); + + parse (is, eh_proxy, *sax, f, p); + + if (eh_proxy.failed ()) + throw parsing<C> (); + } + + template <typename C> + void document<C>:: + parse (const xercesc::InputSource& is, + xercesc::ErrorHandler& eh, + flags f, + const properties<C>& p) + { + xml::sax::bits::error_handler_proxy<C> eh_proxy (eh); + std::auto_ptr<xercesc::SAX2XMLReader> sax (create_sax_ (f, p)); + + parse (is, eh_proxy, *sax, f, p); + + if (eh_proxy.failed ()) + throw parsing<C> (); + } + + + template <typename C> + void document<C>:: + parse (const xercesc::InputSource& is, + xercesc::SAX2XMLReader& sax, + flags f, + const properties<C>& p) + { + // If there is no error handler, then fall back on the default + // implementation. + // + xercesc::ErrorHandler* eh (sax.getErrorHandler ()); + + if (eh) + { + xml::sax::bits::error_handler_proxy<C> eh_proxy (*eh); + + parse (is, eh_proxy, sax, f, p); + + if (eh_proxy.failed ()) + throw parsing<C> (); + } + else + { + error_handler<C> fallback_eh; + xml::sax::bits::error_handler_proxy<C> eh_proxy (fallback_eh); + + parse (is, eh_proxy, sax, f, p); + + fallback_eh.throw_if_failed (); + } + } + + namespace Bits + { + struct ErrorHandlingController + { + ErrorHandlingController (xercesc::SAX2XMLReader& sax, + xercesc::ErrorHandler& eh) + : sax_ (sax), eh_ (sax_.getErrorHandler ()) + { + sax_.setErrorHandler (&eh); + } + + ~ErrorHandlingController () + { + sax_.setErrorHandler (eh_); + } + + private: + xercesc::SAX2XMLReader& sax_; + xercesc::ErrorHandler* eh_; + }; + + struct ContentHandlingController + { + ContentHandlingController (xercesc::SAX2XMLReader& sax, + xercesc::ContentHandler& ch) + : sax_ (sax), ch_ (sax_.getContentHandler ()) + { + sax_.setContentHandler (&ch); + } + + ~ContentHandlingController () + { + sax_.setContentHandler (ch_); + } + + private: + xercesc::SAX2XMLReader& sax_; + xercesc::ContentHandler* ch_; + }; + }; + + template <typename C> + void document<C>:: + parse (const std::basic_string<C>& uri, + xercesc::ErrorHandler& eh, + xercesc::SAX2XMLReader& sax, + flags, + const properties<C>&) + { + event_router<C> router (*this, polymorphic_); + + Bits::ErrorHandlingController ehc (sax, eh); + Bits::ContentHandlingController chc (sax, router); + + try + { + sax.parse (xml::string (uri).c_str ()); + } + catch (const schema_exception<C>& e) + { + xml::string id (e.id ()); + + xercesc::SAXParseException se ( + xml::string (e.message ()).c_str (), + id.c_str (), + id.c_str (), +#if _XERCES_VERSION >= 30000 + static_cast<XMLFileLoc> (e.line ()), + static_cast<XMLFileLoc> (e.column ()) +#else + static_cast<XMLSSize_t> (e.line ()), + static_cast<XMLSSize_t> (e.column ()) +#endif + ); + + eh.fatalError (se); + } + } + + template <typename C> + void document<C>:: + parse (const xercesc::InputSource& is, + xercesc::ErrorHandler& eh, + xercesc::SAX2XMLReader& sax, + flags, + const properties<C>&) + { + event_router<C> router (*this, polymorphic_); + + Bits::ErrorHandlingController controller (sax, eh); + Bits::ContentHandlingController chc (sax, router); + + try + { + sax.parse (is); + } + catch (const schema_exception<C>& e) + { + xml::string id (e.id ()); + + xercesc::SAXParseException se ( + xml::string (e.message ()).c_str (), + id.c_str (), + id.c_str (), +#if _XERCES_VERSION >= 30000 + static_cast<XMLFileLoc> (e.line ()), + static_cast<XMLFileLoc> (e.column ()) +#else + static_cast<XMLSSize_t> (e.line ()), + static_cast<XMLSSize_t> (e.column ()) +#endif + ); + + eh.fatalError (se); + } + } + + + template <typename C> + std::auto_ptr<xercesc::SAX2XMLReader> document<C>:: + create_sax_ (flags f, const properties<C>& p) + { + // HP aCC cannot handle using namespace xercesc; + // + using xercesc::SAX2XMLReader; + using xercesc::XMLReaderFactory; + using xercesc::XMLUni; + + std::auto_ptr<SAX2XMLReader> sax ( + XMLReaderFactory::createXMLReader ()); + + sax->setFeature (XMLUni::fgSAX2CoreNameSpaces, true); + sax->setFeature (XMLUni::fgSAX2CoreNameSpacePrefixes, true); + sax->setFeature (XMLUni::fgXercesValidationErrorAsFatal, true); + + if (f & flags::dont_validate) + { + sax->setFeature (XMLUni::fgSAX2CoreValidation, false); + sax->setFeature (XMLUni::fgXercesSchema, false); + sax->setFeature (XMLUni::fgXercesSchemaFullChecking, false); + } + else + { + sax->setFeature (XMLUni::fgSAX2CoreValidation, true); + sax->setFeature (XMLUni::fgXercesSchema, true); + +#if _XERCES_VERSION >= 30000 + if (!(f & flags::no_multiple_imports)) + sax->setFeature (XMLUni::fgXercesHandleMultipleImports, true); +#endif + // This feature checks the schema grammar for additional + // errors. We most likely do not need it when validating + // instances (assuming the schema is valid). + // + sax->setFeature (XMLUni::fgXercesSchemaFullChecking, false); + } + + // Transfer properies if any. + // + + if (!p.schema_location ().empty ()) + { + xml::string sl (p.schema_location ()); + const void* v (sl.c_str ()); + + sax->setProperty ( + XMLUni::fgXercesSchemaExternalSchemaLocation, + const_cast<void*> (v)); + } + + if (!p.no_namespace_schema_location ().empty ()) + { + xml::string sl (p.no_namespace_schema_location ()); + const void* v (sl.c_str ()); + + sax->setProperty ( + XMLUni::fgXercesSchemaExternalNoNameSpaceSchemaLocation, + const_cast<void*> (v)); + } + + return sax; + } + + // event_router + // + template <typename C> + event_router<C>:: + event_router (cxx::parser::document<C>& consumer, bool polymorphic) + : loc_ (0), consumer_ (consumer), polymorphic_ (polymorphic) + { + } + + template <typename C> + void event_router<C>:: + setDocumentLocator (const xercesc::Locator* const loc) + { + loc_ = loc; + } + + template <typename C> + void event_router<C>:: + startElement(const XMLCh* const uri, + const XMLCh* const lname, + const XMLCh* const /*qname*/, + const xercesc::Attributes& attributes) + { + typedef std::basic_string<C> string; + + { + last_valid_ = true; + last_ns_ = xml::transcode<C> (uri); + last_name_ = xml::transcode<C> (lname); + + // Without this explicit construction IBM XL C++ complains + // about ro_string's copy ctor being private even though the + // temporary has been eliminated. Note that we cannot + // eliminate ns, name and value since ro_string does not make + // a copy. + // + ro_string<C> ro_ns (last_ns_); + ro_string<C> ro_name (last_name_); + + if (!polymorphic_) + { + try + { + consumer_.start_element (ro_ns, ro_name, 0); + } + catch (schema_exception<C>& e) + { + set_location (e); + throw; + } + } + else + { + // Search for the xsi:type attribute. + // + int i (attributes.getIndex ( + xercesc::SchemaSymbols::fgURI_XSI, + xercesc::SchemaSymbols::fgXSI_TYPE)); + + if (i == -1) + { + try + { + consumer_.start_element (ro_ns, ro_name, 0); + } + catch (schema_exception<C>& e) + { + set_location (e); + throw; + } + } + else + { + try + { + // @@ Probably need proper QName validation. + // + // Get the qualified type name and try to resolve it. + // + string qn (xml::transcode<C> (attributes.getValue (i))); + + ro_string<C> tp, tn; + typename string::size_type pos (qn.find (C (':'))); + + if (pos != string::npos) + { + tp.assign (qn.c_str (), pos); + tn.assign (qn.c_str () + pos + 1); + + if (tp.empty ()) + throw dynamic_type<C> (qn); + } + else + tn.assign (qn); + + if (tn.empty ()) + throw dynamic_type<C> (qn); + + // Search our namespace declaration stack. Sun CC 5.7 + // blows if we use const_reverse_iterator. + // + ro_string<C> tns; + for (typename ns_decls::reverse_iterator + it (ns_decls_.rbegin ()), e (ns_decls_.rend ()); + it != e; ++it) + { + if (it->prefix == tp) + { + tns.assign (it->ns); + break; + } + } + + if (!tp.empty () && tns.empty ()) + { + // The 'xml' prefix requires special handling. + // + if (tp == xml::bits::xml_prefix<C> ()) + tns.assign (xml::bits::xml_namespace<C> ()); + else + throw dynamic_type<C> (qn); + } + + // Construct the compound type id. + // + string id (tn.data (), tn.size ()); + + if (!tns.empty ()) + { + id += C (' '); + id.append (tns.data (), tns.size ()); + } + + ro_string<C> ro_id (id); + consumer_.start_element (ro_ns, ro_name, &ro_id); + } + catch (schema_exception<C>& e) + { + set_location (e); + throw; + } + } + } + } + +#if _XERCES_VERSION >= 30000 + for (XMLSize_t i (0), end (attributes.getLength()); i < end; ++i) +#else + for (unsigned int i (0), end (attributes.getLength()); i < end; ++i) +#endif + { + string ns (xml::transcode<C> (attributes.getURI (i))); + string name (xml::transcode<C> (attributes.getLocalName (i))); + string value (xml::transcode<C> (attributes.getValue (i))); + + // Without this explicit construction IBM XL C++ complains + // about ro_string's copy ctor being private even though the + // temporary has been eliminated. Note that we cannot + // eliminate ns, name and value since ro_string does not make + // a copy. + // + ro_string<C> ro_ns (ns); + ro_string<C> ro_name (name); + ro_string<C> ro_value (value); + + try + { + consumer_.attribute (ro_ns, ro_name, ro_value); + } + catch (schema_exception<C>& e) + { + set_location (e); + throw; + } + } + } + + template <typename C> + void event_router<C>:: + endElement(const XMLCh* const uri, + const XMLCh* const lname, + const XMLCh* const /*qname*/) + { + typedef std::basic_string<C> string; + + try + { + // Without this explicit construction IBM XL C++ complains + // about ro_string's copy ctor being private even though the + // temporary has been eliminated. Note that we cannot + // eliminate ns, name and value since ro_string does not make + // a copy. + // + if (last_valid_) + { + last_valid_ = false; + ro_string<C> ro_ns (last_ns_); + ro_string<C> ro_name (last_name_); + + consumer_.end_element (ro_ns, ro_name); + } + else + { + string ns (xml::transcode<C> (uri)); + string name (xml::transcode<C> (lname)); + + ro_string<C> ro_ns (ns); + ro_string<C> ro_name (name); + + consumer_.end_element (ro_ns, ro_name); + } + } + catch (schema_exception<C>& e) + { + set_location (e); + throw; + } + } + + template <typename C> + void event_router<C>:: +#if _XERCES_VERSION >= 30000 + characters (const XMLCh* const s, const XMLSize_t n) +#else + characters (const XMLCh* const s, const unsigned int n) +#endif + { + typedef std::basic_string<C> string; + + if (n != 0) + { + string str (xml::transcode<C> (s, n)); + + // Without this explicit construction IBM XL C++ complains + // about ro_string's copy ctor being private even though the + // temporary has been eliminated. Note that we cannot + // eliminate str since ro_string does not make a copy. + // + ro_string<C> ro_str (str); + + try + { + consumer_.characters (ro_str); + } + catch (schema_exception<C>& e) + { + set_location (e); + throw; + } + } + } + + template <typename C> + void event_router<C>:: + startPrefixMapping (const XMLCh* const prefix, + const XMLCh* const uri) + { + if (polymorphic_) + { + typedef std::basic_string<C> string; + + string p (xml::transcode<C> (prefix)); + string ns (xml::transcode<C> (uri)); + + ns_decls_.push_back (ns_decl (p, ns)); + } + } + + template <typename C> + void event_router<C>:: + endPrefixMapping (const XMLCh* const prefix) + { + if (polymorphic_) + { + typedef std::basic_string<C> string; + + string p (xml::transcode<C> (prefix)); + + // Here we assume the prefixes are removed in the reverse + // order of them being added. This appears to how every + // sensible implementation works. + // + assert (ns_decls_.back ().prefix == p); + + ns_decls_.pop_back (); + } + } + + template <typename C> + void event_router<C>:: + set_location (schema_exception<C>& e) + { + if (loc_ != 0) + { + const XMLCh* id (loc_->getPublicId ()); + + if (id == 0) + id = loc_->getSystemId (); + + if (id != 0) + e.id (xml::transcode<C> (id)); + +#if _XERCES_VERSION >= 30000 + e.line (static_cast<unsigned long> (loc_->getLineNumber ())); + e.column (static_cast<unsigned long> (loc_->getColumnNumber ())); +#else + XMLSSize_t l (loc_->getLineNumber ()); + XMLSSize_t c (loc_->getColumnNumber ()); + + e.line (l == -1 ? 0 : static_cast<unsigned long> (l)); + e.column (c == -1 ? 0: static_cast<unsigned long> (c)); +#endif + } + } + } + } + } +} diff --git a/libxsd/xsd/cxx/parser/xml-schema.hxx b/libxsd/xsd/cxx/parser/xml-schema.hxx new file mode 100644 index 0000000..b6f9a1b --- /dev/null +++ b/libxsd/xsd/cxx/parser/xml-schema.hxx @@ -0,0 +1,572 @@ +// file : xsd/cxx/parser/xml-schema.hxx +// author : Boris Kolpackov <boris@codesynthesis.com> +// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSD_CXX_PARSER_XML_SCHEMA_HXX +#define XSD_CXX_PARSER_XML_SCHEMA_HXX + +#include <string> +#include <vector> +#include <cstddef> // std::size_t + +namespace xsd +{ + namespace cxx + { + namespace parser + { + // String sequence. Used for the NMTOKENS and IDREFS types. + // + template <typename C> + class string_sequence: public std::vector<std::basic_string<C> > + { + public: + typedef std::basic_string<C> value_type; + typedef std::vector<value_type> base; + typedef typename base::size_type size_type; + + string_sequence (); + + explicit + string_sequence (size_type n, const value_type& x = value_type ()); + + template <typename I> + string_sequence (const I& begin, const I& end); + }; + + template <typename C> + bool + operator== (const string_sequence<C>&, const string_sequence<C>&); + + template <typename C> + bool + operator!= (const string_sequence<C>&, const string_sequence<C>&); + + + // QName + // + template <typename C> + class qname + { + public: + explicit + qname (const std::basic_string<C>& name); + + qname (const std::basic_string<C>& prefix, + const std::basic_string<C>& name); + + void + swap (qname&); + + const std::basic_string<C>& + prefix () const; + + std::basic_string<C>& + prefix (); + + void + prefix (const std::basic_string<C>&); + + const std::basic_string<C>& + name () const; + + std::basic_string<C>& + name (); + + void + name (const std::basic_string<C>&); + + private: + std::basic_string<C> prefix_; + std::basic_string<C> name_; + }; + + template <typename C> + bool + operator== (const qname<C>&, const qname<C>&); + + template <typename C> + bool + operator!= (const qname<C>&, const qname<C>&); + + + // Binary buffer. Used for the base64Binary and hexBinary types. + // + class buffer + { + public: + typedef std::size_t size_t; + + class bounds {}; // Out of bounds exception. + + public: + ~buffer (); + + explicit + buffer (size_t size = 0); + buffer (size_t size, size_t capacity); + buffer (const void* data, size_t size); + buffer (const void* data, size_t size, size_t capacity); + + // If the assume_ownership argument is true, the buffer will + // assume the ownership of the data and will release the memory + // by calling operator delete (). + // + buffer (void* data, + size_t size, + size_t capacity, + bool assume_ownership); + + buffer (const buffer&); + + public: + buffer& + operator= (const buffer&); + + public: + size_t + capacity () const; + + // Returns true if the underlying buffer has moved. + // + bool + capacity (size_t); + + public: + size_t + size () const; + + // Returns true if the underlying buffer has moved. + // + bool + size (size_t); + + public: + const char* + data () const; + + char* + data (); + + const char* + begin () const; + + char* + begin (); + + const char* + end () const; + + char* + end (); + + public: + void + swap (buffer&); + + private: + bool + capacity (size_t capacity, bool copy); + + private: + char* data_; + size_t size_; + size_t capacity_; + }; + + bool + operator== (const buffer&, const buffer&); + + bool + operator!= (const buffer&, const buffer&); + + + // Time and date types. + // + + class time_zone + { + public: + time_zone (); + time_zone (short hours, short minutes); + + // Returns true if time zone is specified. + // + bool + zone_present () const; + + // Resets the time zone to the 'not specified' state. + // + void + zone_reset (); + + short + zone_hours () const; + + void + zone_hours (short); + + short + zone_minutes () const; + + void + zone_minutes (short); + + private: + bool present_; + short hours_; + short minutes_; + }; + + bool + operator== (const time_zone&, const time_zone&); + + bool + operator!= (const time_zone&, const time_zone&); + + + class gday: public time_zone + { + public: + explicit + gday (unsigned short day); + gday (unsigned short day, short zone_hours, short zone_minutes); + + unsigned short + day () const; + + void + day (unsigned short); + + private: + unsigned short day_; + }; + + bool + operator== (const gday&, const gday&); + + bool + operator!= (const gday&, const gday&); + + + class gmonth: public time_zone + { + public: + explicit + gmonth (unsigned short month); + gmonth (unsigned short month, short zone_hours, short zone_minutes); + + unsigned short + month () const; + + void + month (unsigned short); + + private: + unsigned short month_; + }; + + bool + operator== (const gmonth&, const gmonth&); + + bool + operator!= (const gmonth&, const gmonth&); + + + class gyear: public time_zone + { + public: + explicit + gyear (int year); + gyear (int year, short zone_hours, short zone_minutes); + + int + year () const; + + void + year (int); + + private: + int year_; + }; + + bool + operator== (const gyear&, const gyear&); + + bool + operator!= (const gyear&, const gyear&); + + + class gmonth_day: public time_zone + { + public: + gmonth_day (unsigned short month, unsigned short day); + gmonth_day (unsigned short month, unsigned short day, + short zone_hours, short zone_minutes); + + unsigned short + month () const; + + void + month (unsigned short); + + unsigned short + day () const; + + void + day (unsigned short); + + private: + unsigned short month_; + unsigned short day_; + }; + + bool + operator== (const gmonth_day&, const gmonth_day&); + + bool + operator!= (const gmonth_day&, const gmonth_day&); + + + class gyear_month: public time_zone + { + public: + gyear_month (int year, unsigned short month); + gyear_month (int year, unsigned short month, + short zone_hours, short zone_minutes); + + int + year () const; + + void + year (int); + + unsigned short + month () const; + + void + month (unsigned short); + + private: + int year_; + unsigned short month_; + }; + + bool + operator== (const gyear_month&, const gyear_month&); + + bool + operator!= (const gyear_month&, const gyear_month&); + + + class date: public time_zone + { + public: + date (int year, unsigned short month, unsigned short day); + date (int year, unsigned short month, unsigned short day, + short zone_hours, short zone_minutes); + + int + year () const; + + void + year (int); + + unsigned short + month () const; + + void + month (unsigned short); + + unsigned short + day () const; + + void + day (unsigned short); + + private: + int year_; + unsigned short month_; + unsigned short day_; + }; + + bool + operator== (const date&, const date&); + + bool + operator!= (const date&, const date&); + + + class time: public time_zone + { + public: + time (unsigned short hours, unsigned short minutes, double seconds); + time (unsigned short hours, unsigned short minutes, double seconds, + short zone_hours, short zone_minutes); + + unsigned short + hours () const; + + void + hours (unsigned short); + + unsigned short + minutes () const; + + void + minutes (unsigned short); + + double + seconds () const; + + void + seconds (double); + + private: + unsigned short hours_; + unsigned short minutes_; + double seconds_; + }; + + bool + operator== (const time&, const time&); + + bool + operator!= (const time&, const time&); + + + class date_time: public time_zone + { + public: + date_time (int year, unsigned short month, unsigned short day, + unsigned short hours, unsigned short minutes, double seconds); + + date_time (int year, unsigned short month, unsigned short day, + unsigned short hours, unsigned short minutes, double seconds, + short zone_hours, short zone_minutes); + + int + year () const; + + void + year (int); + + unsigned short + month () const; + + void + month (unsigned short); + + unsigned short + day () const; + + void + day (unsigned short); + + unsigned short + hours () const; + + void + hours (unsigned short); + + unsigned short + minutes () const; + + void + minutes (unsigned short); + + double + seconds () const; + + void + seconds (double); + + private: + int year_; + unsigned short month_; + unsigned short day_; + unsigned short hours_; + unsigned short minutes_; + double seconds_; + }; + + bool + operator== (const date_time&, const date_time&); + + bool + operator!= (const date_time&, const date_time&); + + + class duration + { + public: + duration (bool negative, + unsigned int years, unsigned int months, unsigned int days, + unsigned int hours, unsigned int minutes, double seconds); + + bool + negative () const; + + void + negative (bool); + + unsigned int + years () const; + + void + years (unsigned int); + + unsigned int + months () const; + + void + months (unsigned int); + + unsigned int + days () const; + + void + days (unsigned int); + + unsigned int + hours () const; + + void + hours (unsigned int); + + unsigned int + minutes () const; + + void + minutes (unsigned int); + + double + seconds () const; + + void + seconds (double); + + private: + bool negative_; + unsigned int years_; + unsigned int months_; + unsigned int days_; + unsigned int hours_; + unsigned int minutes_; + double seconds_; + }; + + bool + operator== (const duration&, const duration&); + + bool + operator!= (const duration&, const duration&); + } + } +} + +#include <xsd/cxx/parser/xml-schema.ixx> +#include <xsd/cxx/parser/xml-schema.txx> + +#endif // XSD_CXX_PARSER_XML_SCHEMA_HXX diff --git a/libxsd/xsd/cxx/parser/xml-schema.ixx b/libxsd/xsd/cxx/parser/xml-schema.ixx new file mode 100644 index 0000000..5a0922b --- /dev/null +++ b/libxsd/xsd/cxx/parser/xml-schema.ixx @@ -0,0 +1,1022 @@ +// file : xsd/cxx/parser/xml-schema.ixx +// 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 <new> // operator new/delete +#include <cstring> // std::memcpy, std::memcmp + +namespace xsd +{ + namespace cxx + { + namespace parser + { + // string_sequence + // + template <typename C> + string_sequence<C>:: + string_sequence () + { + } + + template <typename C> + string_sequence<C>:: + string_sequence (size_type n, const value_type& x) + : base (n, x) + { + } + + template <typename C> + template <typename I> + string_sequence<C>:: + string_sequence (const I& begin, const I& end) + : base (begin, end) + { + } + + template <typename C> + inline bool + operator!= (const string_sequence<C>& a, const string_sequence<C>& b) + { + return !(a == b); + } + + // qname + // + template <typename C> + inline qname<C>:: + qname (const std::basic_string<C>& name) + : name_ (name) + { + } + + template <typename C> + inline qname<C>:: + qname (const std::basic_string<C>& prefix, + const std::basic_string<C>& name) + : prefix_ (prefix), name_ (name) + { + } + + template <typename C> + void qname<C>:: + swap (qname<C>& x) + { + prefix_.swap (x.prefix_); + name_.swap (x.name_); + } + + template <typename C> + inline const std::basic_string<C>& qname<C>:: + prefix () const + { + return prefix_; + } + + template <typename C> + inline std::basic_string<C>& qname<C>:: + prefix () + { + return prefix_; + } + + template <typename C> + inline void qname<C>:: + prefix (const std::basic_string<C>& prefix) + { + prefix_ = prefix; + } + + template <typename C> + inline const std::basic_string<C>& qname<C>:: + name () const + { + return name_; + } + + template <typename C> + inline std::basic_string<C>& qname<C>:: + name () + { + return name_; + } + + template <typename C> + inline void qname<C>:: + name (const std::basic_string<C>& name) + { + name_ = name; + } + + template <typename C> + inline bool + operator== (const qname<C>& a, const qname<C>& b) + { + return a.prefix () == b.prefix () && a.name () == b.name (); + } + + template <typename C> + inline bool + operator!= (const qname<C>& a, const qname<C>& b) + { + return !(a == b); + } + + // buffer + // + inline buffer:: + ~buffer () + { + if (data_) + operator delete (data_); + } + + inline buffer:: + buffer (size_t size) + : data_ (0), size_ (0), capacity_ (0) + { + capacity (size); + size_ = size; + } + + inline buffer:: + buffer (size_t size, size_t cap) + : data_ (0), size_ (0), capacity_ (0) + { + if (size > cap) + throw bounds (); + + capacity (cap); + size_ = size; + } + + inline buffer:: + buffer (const void* data, size_t size) + : data_ (0), size_ (0), capacity_ (0) + { + capacity (size); + size_ = size; + + if (size_) + std::memcpy (data_, data, size_); + } + + inline buffer:: + buffer (const void* data, size_t size, size_t cap) + : data_ (0), size_ (0), capacity_ (0) + { + if (size > cap) + throw bounds (); + + capacity (cap); + size_ = size; + + if (size_) + std::memcpy (data_, data, size_); + } + + inline buffer:: + buffer (void* data, size_t size, size_t cap, bool own) + : data_ (0), size_ (0), capacity_ (0) + { + if (size > cap) + throw bounds (); + + if (own) + { + data_ = reinterpret_cast<char*> (data); + size_ = size; + capacity_ = cap; + } + else + { + capacity (cap); + size_ = size; + + if (size_) + std::memcpy (data_, data, size_); + } + } + + inline buffer:: + buffer (const buffer& other) + : data_ (0), size_ (0), capacity_ (0) + { + capacity (other.capacity_); + size_ = other.size_; + + if (size_) + std::memcpy (data_, other.data_, size_); + } + + inline buffer& buffer:: + operator= (const buffer& other) + { + if (this != &other) + { + capacity (other.capacity_, false); + size_ = other.size_; + + if (size_) + std::memcpy (data_, other.data_, size_); + } + + return *this; + } + + inline size_t buffer:: + capacity () const + { + return capacity_; + } + + inline bool buffer:: + capacity (size_t cap) + { + return capacity (cap, true); + } + + inline size_t buffer:: + size () const + { + return size_; + } + + inline bool buffer:: + size (size_t size) + { + bool r (false); + + if (size > capacity_) + r = capacity (size); + + size_ = size; + + return r; + } + + inline const char* buffer:: + data () const + { + return data_; + } + + inline char* buffer:: + data () + { + return data_; + } + + inline const char* buffer:: + begin () const + { + return data_; + } + + inline char* buffer:: + begin () + { + return data_; + } + + inline const char* buffer:: + end () const + { + return data_ + size_; + } + + inline char* buffer:: + end () + { + return data_ + size_; + } + + inline void buffer:: + swap (buffer& other) + { + char* tmp_data (data_); + size_t tmp_size (size_); + size_t tmp_capacity (capacity_); + + data_ = other.data_; + size_ = other.size_; + capacity_ = other.capacity_; + + other.data_ = tmp_data; + other.size_ = tmp_size; + other.capacity_ = tmp_capacity; + } + + inline bool buffer:: + capacity (size_t capacity, bool copy) + { + if (size_ > capacity) + throw bounds (); + + if (capacity <= capacity_) + { + return false; // Do nothing if shrinking is requested. + } + else + { + char* data (reinterpret_cast<char*> (operator new (capacity))); + + if (copy && size_ > 0) + std::memcpy (data, data_, size_); + + if (data_) + operator delete (data_); + + data_ = data; + capacity_ = capacity; + + return true; + } + } + + inline bool + operator== (const buffer& a, const buffer& b) + { + return a.size () == b.size () && + std::memcmp (a.data (), b.data (), a.size ()) == 0; + } + + inline bool + operator!= (const buffer& a, const buffer& b) + { + return !(a == b); + } + + // time_zone + // + inline time_zone:: + time_zone () + : present_ (false) + { + } + + inline time_zone:: + time_zone (short h, short m) + : present_ (true), hours_ (h), minutes_ (m) + { + } + + inline bool time_zone:: + zone_present () const + { + return present_; + } + + inline void time_zone:: + zone_reset () + { + present_ = false; + } + + inline short time_zone:: + zone_hours () const + { + return hours_; + } + + inline void time_zone:: + zone_hours (short h) + { + hours_ = h; + present_ = true; + } + + inline short time_zone:: + zone_minutes () const + { + return minutes_; + } + + inline void time_zone:: + zone_minutes (short m) + { + minutes_ = m; + present_ = true; + } + + inline bool + operator== (const time_zone& x, const time_zone& y) + { + return x.zone_present () + ? y.zone_present () && + x.zone_hours () == y.zone_hours () && + x.zone_minutes () == y.zone_minutes () + : !y.zone_present (); + } + + inline bool + operator!= (const time_zone& x, const time_zone& y) + { + return !(x == y); + } + + // gday + // + inline gday:: + gday (unsigned short day) + : day_ (day) + { + } + + inline gday:: + gday (unsigned short day, short zh, short zm) + : time_zone (zh, zm), day_ (day) + { + } + + inline unsigned short gday:: + day () const + { + return day_; + } + + inline void gday:: + day (unsigned short day) + { + day_ = day; + } + + inline bool + operator== (const gday& a, const gday& b) + { + const time_zone& az = a; + const time_zone& bz = b; + + return a.day () == b.day () && az == bz; + } + + inline bool + operator!= (const gday& a, const gday& b) + { + return !(a == b); + } + + // gmonth + // + inline gmonth:: + gmonth (unsigned short month) + : month_ (month) + { + } + + inline gmonth:: + gmonth (unsigned short month, short zh, short zm) + : time_zone (zh, zm), month_ (month) + { + } + + inline unsigned short gmonth:: + month () const + { + return month_; + } + + inline void gmonth:: + month (unsigned short month) + { + month_ = month; + } + + inline bool + operator== (const gmonth& a, const gmonth& b) + { + const time_zone& az = a; + const time_zone& bz = b; + + return a.month () == b.month () && az == bz; + } + + inline bool + operator!= (const gmonth& a, const gmonth& b) + { + return !(a == b); + } + + // gyear + // + inline gyear:: + gyear (int year) + : year_ (year) + { + } + + inline gyear:: + gyear (int year, short zh, short zm) + : time_zone (zh, zm), year_ (year) + { + } + + inline int gyear:: + year () const + { + return year_; + } + + inline void gyear:: + year (int year) + { + year_ = year; + } + + inline bool + operator== (const gyear& a, const gyear& b) + { + const time_zone& az = a; + const time_zone& bz = b; + + return a.year () == b.year () && az == bz; + } + + inline bool + operator!= (const gyear& a, const gyear& b) + { + return !(a == b); + } + + // gmonth_day + // + inline gmonth_day:: + gmonth_day (unsigned short month, unsigned short day) + : month_ (month), day_ (day) + { + } + + inline gmonth_day:: + gmonth_day (unsigned short month, + unsigned short day, + short zh, short zm) + : time_zone (zh, zm), month_ (month), day_ (day) + { + } + + inline unsigned short gmonth_day:: + month () const + { + return month_; + } + + inline void gmonth_day:: + month (unsigned short month) + { + month_ = month; + } + + inline unsigned short gmonth_day:: + day () const + { + return day_; + } + + inline void gmonth_day:: + day (unsigned short day) + { + day_ = day; + } + + inline bool + operator== (const gmonth_day& a, const gmonth_day& b) + { + const time_zone& az = a; + const time_zone& bz = b; + + return a.month () == b.month () && + a.day () == b.day () && + az == bz; + } + + inline bool + operator!= (const gmonth_day& a, const gmonth_day& b) + { + return !(a == b); + } + + // gyear_month + // + inline gyear_month:: + gyear_month (int year, unsigned short month) + : year_ (year), month_ (month) + { + } + + inline gyear_month:: + gyear_month (int year, unsigned short month, + short zh, short zm) + : time_zone (zh, zm), year_ (year), month_ (month) + { + } + + inline int gyear_month:: + year () const + { + return year_; + } + + inline void gyear_month:: + year (int year) + { + year_ = year; + } + + inline unsigned short gyear_month:: + month () const + { + return month_; + } + + inline void gyear_month:: + month (unsigned short month) + { + month_ = month; + } + + inline bool + operator== (const gyear_month& a, const gyear_month& b) + { + const time_zone& az = a; + const time_zone& bz = b; + + return a.year () == b.year () && + a.month () == b.month () && + az == bz; + } + + inline bool + operator!= (const gyear_month& a, const gyear_month& b) + { + return !(a == b); + } + + // date + // + inline date:: + date (int year, unsigned short month, unsigned short day) + : year_ (year), month_ (month), day_ (day) + { + } + + inline date:: + date (int year, unsigned short month, unsigned short day, + short zh, short zm) + : time_zone (zh, zm), year_ (year), month_ (month), day_ (day) + { + } + + inline int date:: + year () const + { + return year_; + } + + inline void date:: + year (int year) + { + year_ = year; + } + + inline unsigned short date:: + month () const + { + return month_; + } + + inline void date:: + month (unsigned short month) + { + month_ = month; + } + + inline unsigned short date:: + day () const + { + return day_; + } + + inline void date:: + day (unsigned short day) + { + day_ = day; + } + + inline bool + operator== (const date& a, const date& b) + { + const time_zone& az = a; + const time_zone& bz = b; + + return a.year () == b.year () && + a.month () == b.month () && + a.day () == b.day () && + az == bz; + } + + inline bool + operator!= (const date& a, const date& b) + { + return !(a == b); + } + + // time + // + inline time:: + time (unsigned short hours, unsigned short minutes, double seconds) + : hours_ (hours), minutes_ (minutes), seconds_ (seconds) + { + } + + inline time:: + time (unsigned short hours, unsigned short minutes, double seconds, + short zh, short zm) + : time_zone (zh, zm), + hours_ (hours), minutes_ (minutes), seconds_ (seconds) + { + } + + inline unsigned short time:: + hours () const + { + return hours_; + } + + inline void time:: + hours (unsigned short hours) + { + hours_ = hours; + } + + inline unsigned short time:: + minutes () const + { + return minutes_; + } + + inline void time:: + minutes (unsigned short minutes) + { + minutes_ = minutes; + } + + inline double time:: + seconds () const + { + return seconds_; + } + + inline void time:: + seconds (double seconds) + { + seconds_ = seconds; + } + + inline bool + operator== (const time& a, const time& b) + { + const time_zone& az = a; + const time_zone& bz = b; + + return a.hours () == b.hours () && + a.minutes () == b.minutes () && + a.seconds () == b.seconds () && + az == bz; + } + + inline bool + operator!= (const time& a, const time& b) + { + return !(a == b); + } + + // date_time + // + inline date_time:: + date_time (int year, unsigned short month, unsigned short day, + unsigned short hours, unsigned short minutes, double seconds) + : year_ (year), month_ (month), day_ (day), + hours_ (hours), minutes_ (minutes), seconds_ (seconds) + { + } + + inline date_time:: + date_time (int year, unsigned short month, unsigned short day, + unsigned short hours, unsigned short minutes, double seconds, + short zh, short zm) + : time_zone (zh, zm), + year_ (year), month_ (month), day_ (day), + hours_ (hours), minutes_ (minutes), seconds_ (seconds) + { + } + + inline int date_time:: + year () const + { + return year_; + } + + inline void date_time:: + year (int year) + { + year_ = year; + } + + inline unsigned short date_time:: + month () const + { + return month_; + } + + inline void date_time:: + month (unsigned short month) + { + month_ = month; + } + + inline unsigned short date_time:: + day () const + { + return day_; + } + + inline void date_time:: + day (unsigned short day) + { + day_ = day; + } + + inline unsigned short date_time:: + hours () const + { + return hours_; + } + + inline void date_time:: + hours (unsigned short hours) + { + hours_ = hours; + } + + inline unsigned short date_time:: + minutes () const + { + return minutes_; + } + + inline void date_time:: + minutes (unsigned short minutes) + { + minutes_ = minutes; + } + + inline double date_time:: + seconds () const + { + return seconds_; + } + + inline void date_time:: + seconds (double seconds) + { + seconds_ = seconds; + } + + inline bool + operator== (const date_time& a, const date_time& b) + { + const time_zone& az = a; + const time_zone& bz = b; + + return a.year () == b.year () && + a.month () == b.month () && + a.day () == b.day () && + a.hours () == b.hours () && + a.minutes () == b.minutes () && + a.seconds () == b.seconds () && + az == bz; + } + + inline bool + operator!= (const date_time& a, const date_time& b) + { + return !(a == b); + } + + // duration + // + inline duration:: + duration (bool negative, + unsigned int years, unsigned int months, unsigned int days, + unsigned int hours, unsigned int minutes, double seconds) + : negative_ (negative), + years_ (years), months_ (months), days_ (days), + hours_ (hours), minutes_ (minutes), seconds_ (seconds) + { + } + + inline bool duration:: + negative () const + { + return negative_; + } + + inline void duration:: + negative (bool negative) + { + negative_ = negative; + } + + inline unsigned int duration:: + years () const + { + return years_; + } + + inline void duration:: + years (unsigned int years) + { + years_ = years; + } + + inline unsigned int duration:: + months () const + { + return months_; + } + + inline void duration:: + months (unsigned int months) + { + months_ = months; + } + + inline unsigned int duration:: + days () const + { + return days_; + } + + inline void duration:: + days (unsigned int days) + { + days_ = days; + } + + inline unsigned int duration:: + hours () const + { + return hours_; + } + + inline void duration:: + hours (unsigned int hours) + { + hours_ = hours; + } + + inline unsigned int duration:: + minutes () const + { + return minutes_; + } + + inline void duration:: + minutes (unsigned int minutes) + { + minutes_ = minutes; + } + + inline double duration:: + seconds () const + { + return seconds_; + } + + inline void duration:: + seconds (double seconds) + { + seconds_ = seconds; + } + + inline bool + operator== (const duration& a, const duration& b) + { + return a.negative () == b.negative () && + a.years () == b.years () && + a.months () == b.months () && + a.days () == b.days () && + a.hours () == b.hours () && + a.minutes () == b.minutes () && + a.seconds () == b.seconds (); + } + + inline bool + operator!= (const duration& a, const duration& b) + { + return !(a == b); + } + } + } +} diff --git a/libxsd/xsd/cxx/parser/xml-schema.txx b/libxsd/xsd/cxx/parser/xml-schema.txx new file mode 100644 index 0000000..c0e2de9 --- /dev/null +++ b/libxsd/xsd/cxx/parser/xml-schema.txx @@ -0,0 +1,34 @@ +// file : xsd/cxx/parser/xml-schema.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 + +namespace xsd +{ + namespace cxx + { + namespace parser + { + // string_sequence + // + template <typename C> + bool + operator== (const string_sequence<C>& a, const string_sequence<C>& b) + { + if (a.size () != b.size ()) + return false; + + for (typename string_sequence<C>::const_iterator + ai (a.begin ()), bi (b.begin ()), ae (a.end ()); + ai != ae; ++ai, ++bi) + { + if (*ai != *bi) + return false; + } + + return true; + } + } + } +} + |