// file : xsd/cxx/parser/expat/elements.hxx // copyright : Copyright (c) 2005-2014 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 // XSD_CXX11 #include #include #include // std::size_t #include #ifdef XSD_CXX11 # include // std::unique_ptr #endif #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 { #ifdef XSD_CXX11 struct parser_deleter { void operator() (XML_Parser p) const { if (p != 0) XML_ParserFree (p); } }; typedef std::unique_ptr parser_auto_ptr; #else // 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; } XML_Parser get () const { return parser_; } private: parser_auto_ptr (const parser_auto_ptr&); parser_auto_ptr& operator= (const parser_auto_ptr&); private: XML_Parser parser_; }; #endif // XSD_CXX11 // // template struct document: cxx::parser::document // VC 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