From f0510d2f90467de8e8f260b47d79a9baaf9bef17 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Thu, 17 Sep 2009 07:15:29 +0200 Subject: Start tracking XSD with git --- libxsd/xsd/cxx/parser/expat/elements.hxx | 344 +++++++++++++++++++++++++++++++ 1 file changed, 344 insertions(+) create mode 100644 libxsd/xsd/cxx/parser/expat/elements.hxx (limited to 'libxsd/xsd/cxx/parser/expat/elements.hxx') 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 +// 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 +#include +#include // std::size_t +#include + +#include + +// We only support UTF-8 expat for now. +// +#ifdef XML_UNICODE +#error UTF-16 expat (XML_UNICODE defined) is not supported +#endif + +#include + +#include +#include +#include +#include +#include + +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 + struct document: cxx::parser::document // VC 7.1 likes it qualified + { + public: + document (parser_base&, + const C* root_element_name, + bool polymorphic = false); + + document (parser_base&, + const std::basic_string& root_element_name, + bool polymorphic = false); + + document (parser_base&, + const C* root_element_namespace, + const C* root_element_name, + bool polymorphic = false); + + document (parser_base&, + const std::basic_string& root_element_namespace, + const std::basic_string& 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& 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& file, xml::error_handler&); + + 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&); + + // Parse std::istream with a system id. + // + void + parse (std::istream&, const std::basic_string& system_id); + + // Parse std::istream with a system id and a user-provided + // error_handler object. + // + void + parse (std::istream&, + const std::basic_string& system_id, + xml::error_handler&); + + // Parse std::istream with system and public ids. + // + void + parse (std::istream&, + const std::basic_string& system_id, + const std::basic_string& 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& system_id, + const std::basic_string& public_id, + xml::error_handler&); + + 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&); + + void + parse (const void* data, std::size_t size, bool last, + const std::basic_string& system_id); + + void + parse (const void* data, std::size_t size, bool last, + const std::basic_string& system_id, + xml::error_handler&); + + void + parse (const void* data, std::size_t size, bool last, + const std::basic_string& system_id, + const std::basic_string& public_id); + + void + parse (const void* data, std::size_t size, bool last, + const std::basic_string& system_id, + const std::basic_string& public_id, + xml::error_handler&); + + 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& public_id); + + void + parse_begin (XML_Parser, xml::error_handler&); + + void + parse_begin (XML_Parser, + const std::basic_string& public_id, + xml::error_handler&); + 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* system_id, + const std::basic_string* public_id, + xml::error_handler&); + + bool + parse (const void* data, std::size_t size, bool last, + const std::basic_string* system_id, + const std::basic_string* public_id, + xml::error_handler&); + + + void + translate_schema_exception (const schema_exception& e); + + protected: + XML_Parser xml_parser_; + parser_auto_ptr auto_xml_parser_; + + xml::error_handler* eh_; + error_handler default_eh_; + std::basic_string public_id_; + + bool polymorphic_; + + // Namespace-prefix mapping. Only maintained in the polymorphic + // case. + // + struct ns_decl + { + ns_decl (const std::basic_string& p, + const std::basic_string& n) + : prefix (p), ns (n) + { + } + + std::basic_string prefix; + std::basic_string ns; + }; + + typedef std::vector ns_decls; + + ns_decls ns_decls_; + }; + } + } + } +} + +#include + +#endif // XSD_CXX_PARSER_EXPAT_ELEMENTS_HXX -- cgit v1.1