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/xerces/elements.txx | 964 ++++++++++++++++++++++++++++++ 1 file changed, 964 insertions(+) create mode 100644 libxsd/xsd/cxx/parser/xerces/elements.txx (limited to 'libxsd/xsd/cxx/parser/xerces/elements.txx') 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 +// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#include +#include // std::size_t +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include // xml::bits::{xml_prefix, etc} + +#include +#include + +namespace xsd +{ + namespace cxx + { + namespace parser + { + namespace xerces + { + + // document + // + + template + document:: + document (parser_base& parser, + const C* name, + bool polymorphic) + : cxx::parser::document (parser, std::basic_string (), name), + polymorphic_ (polymorphic) + { + } + + template + document:: + document (parser_base& parser, + const std::basic_string& name, + bool polymorphic) + : cxx::parser::document (parser, std::basic_string (), name), + polymorphic_ (polymorphic) + { + } + + template + document:: + document (parser_base& parser, + const C* ns, + const C* name, + bool polymorphic) + : cxx::parser::document (parser, ns, name), + polymorphic_ (polymorphic) + { + } + + template + document:: + document (parser_base& parser, + const std::basic_string& ns, + const std::basic_string& name, + bool polymorphic) + : cxx::parser::document (parser, ns, name), + polymorphic_ (polymorphic) + { + } + + template + document:: + document (bool polymorphic) + : polymorphic_ (polymorphic) + { + } + + // parse (uri) + // + template + void document:: + parse (const std::basic_string& uri, + flags f, + const properties& p) + { + xml::auto_initializer init ((f & flags::dont_initialize) == 0); + + error_handler eh; + xml::sax::bits::error_handler_proxy eh_proxy (eh); + std::auto_ptr sax (create_sax_ (f, p)); + + parse (uri, eh_proxy, *sax, f, p); + + eh.throw_if_failed (); + } + + template + void document:: + parse (const C* uri, + flags f, + const properties& p) + { + parse (std::basic_string (uri), f, p); + } + + // error_handler + // + + template + void document:: + parse (const std::basic_string& uri, + xml::error_handler& eh, + flags f, + const properties& p) + { + xml::auto_initializer init ((f & flags::dont_initialize) == 0); + + xml::sax::bits::error_handler_proxy eh_proxy (eh); + std::auto_ptr sax (create_sax_ (f, p)); + + parse (uri, eh_proxy, *sax, f, p); + + if (eh_proxy.failed ()) + throw parsing (); + } + + template + void document:: + parse (const C* uri, + xml::error_handler& eh, + flags f, + const properties& p) + { + parse (std::basic_string (uri), eh, f, p); + } + + // ErrorHandler + // + + template + void document:: + parse (const std::basic_string& uri, + xercesc::ErrorHandler& eh, + flags f, + const properties& p) + { + xml::sax::bits::error_handler_proxy eh_proxy (eh); + std::auto_ptr sax (create_sax_ (f, p)); + + parse (uri, eh_proxy, *sax, f, p); + + if (eh_proxy.failed ()) + throw parsing (); + } + + template + void document:: + parse (const C* uri, + xercesc::ErrorHandler& eh, + flags f, + const properties& p) + { + parse (std::basic_string (uri), eh, f, p); + } + + // SAX2XMLReader + // + + template + void document:: + parse (const std::basic_string& uri, + xercesc::SAX2XMLReader& sax, + flags f, + const properties& 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 eh_proxy (*eh); + + parse (uri, eh_proxy, sax, f, p); + + if (eh_proxy.failed ()) + throw parsing (); + } + else + { + error_handler fallback_eh; + xml::sax::bits::error_handler_proxy eh_proxy (fallback_eh); + + parse (uri, eh_proxy, sax, f, p); + + fallback_eh.throw_if_failed (); + } + } + + template + void document:: + parse (const C* uri, + xercesc::SAX2XMLReader& sax, + flags f, + const properties& p) + { + parse (std::basic_string (uri), sax, f, p); + } + + // parse (istream) + // + + template + void document:: + parse (std::istream& is, + flags f, + const properties& p) + { + xml::auto_initializer init ((f & flags::dont_initialize) == 0); + + xml::sax::std_input_source isrc (is); + + parse (isrc, f, p); + } + + template + void document:: + parse (std::istream& is, + xml::error_handler& eh, + flags f, + const properties& p) + { + xml::auto_initializer init ((f & flags::dont_initialize) == 0); + xml::sax::std_input_source isrc (is); + parse (isrc, eh, f, p); + } + + template + void document:: + parse (std::istream& is, + xercesc::ErrorHandler& eh, + flags f, + const properties& p) + { + xml::sax::std_input_source isrc (is); + parse (isrc, eh, f, p); + } + + template + void document:: + parse (std::istream& is, + xercesc::SAX2XMLReader& sax, + flags f, + const properties& p) + { + xml::sax::std_input_source isrc (is); + parse (isrc, sax, f, p); + } + + + // parse (istream, system_id) + // + + + template + void document:: + parse (std::istream& is, + const std::basic_string& system_id, + flags f, + const properties& p) + { + xml::auto_initializer init ((f & flags::dont_initialize) == 0); + xml::sax::std_input_source isrc (is, system_id); + parse (isrc, f, p); + } + + template + void document:: + parse (std::istream& is, + const std::basic_string& system_id, + xml::error_handler& eh, + flags f, + const properties& 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 + void document:: + parse (std::istream& is, + const std::basic_string& system_id, + xercesc::ErrorHandler& eh, + flags f, + const properties& p) + { + xml::sax::std_input_source isrc (is, system_id); + parse (isrc, eh, f, p); + } + + template + void document:: + parse (std::istream& is, + const std::basic_string& system_id, + xercesc::SAX2XMLReader& sax, + flags f, + const properties& p) + { + xml::sax::std_input_source isrc (is, system_id); + parse (isrc, sax, f, p); + } + + + // parse (istream, system_id, public_id) + // + + template + void document:: + parse (std::istream& is, + const std::basic_string& system_id, + const std::basic_string& public_id, + flags f, + const properties& 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 + void document:: + parse (std::istream& is, + const std::basic_string& system_id, + const std::basic_string& public_id, + xml::error_handler& eh, + flags f, + const properties& 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 + void document:: + parse (std::istream& is, + const std::basic_string& system_id, + const std::basic_string& public_id, + xercesc::ErrorHandler& eh, + flags f, + const properties& p) + { + xml::sax::std_input_source isrc (is, system_id, public_id); + parse (isrc, eh, f, p); + } + + template + void document:: + parse (std::istream& is, + const std::basic_string& system_id, + const std::basic_string& public_id, + xercesc::SAX2XMLReader& sax, + flags f, + const properties& p) + { + xml::sax::std_input_source isrc (is, system_id, public_id); + parse (isrc, sax, f, p); + } + + + // parse (InputSource) + // + + + template + void document:: + parse (const xercesc::InputSource& is, + flags f, + const properties& p) + { + error_handler eh; + xml::sax::bits::error_handler_proxy eh_proxy (eh); + std::auto_ptr sax (create_sax_ (f, p)); + + parse (is, eh_proxy, *sax, f, p); + + eh.throw_if_failed (); + } + + template + void document:: + parse (const xercesc::InputSource& is, + xml::error_handler& eh, + flags f, + const properties& p) + { + xml::sax::bits::error_handler_proxy eh_proxy (eh); + std::auto_ptr sax (create_sax_ (f, p)); + + parse (is, eh_proxy, *sax, f, p); + + if (eh_proxy.failed ()) + throw parsing (); + } + + template + void document:: + parse (const xercesc::InputSource& is, + xercesc::ErrorHandler& eh, + flags f, + const properties& p) + { + xml::sax::bits::error_handler_proxy eh_proxy (eh); + std::auto_ptr sax (create_sax_ (f, p)); + + parse (is, eh_proxy, *sax, f, p); + + if (eh_proxy.failed ()) + throw parsing (); + } + + + template + void document:: + parse (const xercesc::InputSource& is, + xercesc::SAX2XMLReader& sax, + flags f, + const properties& 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 eh_proxy (*eh); + + parse (is, eh_proxy, sax, f, p); + + if (eh_proxy.failed ()) + throw parsing (); + } + else + { + error_handler fallback_eh; + xml::sax::bits::error_handler_proxy 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 + void document:: + parse (const std::basic_string& uri, + xercesc::ErrorHandler& eh, + xercesc::SAX2XMLReader& sax, + flags, + const properties&) + { + event_router 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& 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 (e.line ()), + static_cast (e.column ()) +#else + static_cast (e.line ()), + static_cast (e.column ()) +#endif + ); + + eh.fatalError (se); + } + } + + template + void document:: + parse (const xercesc::InputSource& is, + xercesc::ErrorHandler& eh, + xercesc::SAX2XMLReader& sax, + flags, + const properties&) + { + event_router router (*this, polymorphic_); + + Bits::ErrorHandlingController controller (sax, eh); + Bits::ContentHandlingController chc (sax, router); + + try + { + sax.parse (is); + } + catch (const schema_exception& 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 (e.line ()), + static_cast (e.column ()) +#else + static_cast (e.line ()), + static_cast (e.column ()) +#endif + ); + + eh.fatalError (se); + } + } + + + template + std::auto_ptr document:: + create_sax_ (flags f, const properties& p) + { + // HP aCC cannot handle using namespace xercesc; + // + using xercesc::SAX2XMLReader; + using xercesc::XMLReaderFactory; + using xercesc::XMLUni; + + std::auto_ptr 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 (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 (v)); + } + + return sax; + } + + // event_router + // + template + event_router:: + event_router (cxx::parser::document& consumer, bool polymorphic) + : loc_ (0), consumer_ (consumer), polymorphic_ (polymorphic) + { + } + + template + void event_router:: + setDocumentLocator (const xercesc::Locator* const loc) + { + loc_ = loc; + } + + template + void event_router:: + startElement(const XMLCh* const uri, + const XMLCh* const lname, + const XMLCh* const /*qname*/, + const xercesc::Attributes& attributes) + { + typedef std::basic_string string; + + { + last_valid_ = true; + last_ns_ = xml::transcode (uri); + last_name_ = xml::transcode (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 ro_ns (last_ns_); + ro_string ro_name (last_name_); + + if (!polymorphic_) + { + try + { + consumer_.start_element (ro_ns, ro_name, 0); + } + catch (schema_exception& 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& 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 (attributes.getValue (i))); + + ro_string 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 (qn); + } + else + tn.assign (qn); + + if (tn.empty ()) + throw dynamic_type (qn); + + // Search our namespace declaration stack. Sun CC 5.7 + // blows if we use const_reverse_iterator. + // + ro_string 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 ()) + tns.assign (xml::bits::xml_namespace ()); + else + throw dynamic_type (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 ro_id (id); + consumer_.start_element (ro_ns, ro_name, &ro_id); + } + catch (schema_exception& 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 (attributes.getURI (i))); + string name (xml::transcode (attributes.getLocalName (i))); + string value (xml::transcode (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 ro_ns (ns); + ro_string ro_name (name); + ro_string ro_value (value); + + try + { + consumer_.attribute (ro_ns, ro_name, ro_value); + } + catch (schema_exception& e) + { + set_location (e); + throw; + } + } + } + + template + void event_router:: + endElement(const XMLCh* const uri, + const XMLCh* const lname, + const XMLCh* const /*qname*/) + { + typedef std::basic_string 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 ro_ns (last_ns_); + ro_string ro_name (last_name_); + + consumer_.end_element (ro_ns, ro_name); + } + else + { + string ns (xml::transcode (uri)); + string name (xml::transcode (lname)); + + ro_string ro_ns (ns); + ro_string ro_name (name); + + consumer_.end_element (ro_ns, ro_name); + } + } + catch (schema_exception& e) + { + set_location (e); + throw; + } + } + + template + void event_router:: +#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 string; + + if (n != 0) + { + string str (xml::transcode (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 ro_str (str); + + try + { + consumer_.characters (ro_str); + } + catch (schema_exception& e) + { + set_location (e); + throw; + } + } + } + + template + void event_router:: + startPrefixMapping (const XMLCh* const prefix, + const XMLCh* const uri) + { + if (polymorphic_) + { + typedef std::basic_string string; + + string p (xml::transcode (prefix)); + string ns (xml::transcode (uri)); + + ns_decls_.push_back (ns_decl (p, ns)); + } + } + + template + void event_router:: + endPrefixMapping (const XMLCh* const prefix) + { + if (polymorphic_) + { + typedef std::basic_string string; + + string p (xml::transcode (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 + void event_router:: + set_location (schema_exception& e) + { + if (loc_ != 0) + { + const XMLCh* id (loc_->getPublicId ()); + + if (id == 0) + id = loc_->getSystemId (); + + if (id != 0) + e.id (xml::transcode (id)); + +#if _XERCES_VERSION >= 30000 + e.line (static_cast (loc_->getLineNumber ())); + e.column (static_cast (loc_->getColumnNumber ())); +#else + XMLSSize_t l (loc_->getLineNumber ()); + XMLSSize_t c (loc_->getColumnNumber ()); + + e.line (l == -1 ? 0 : static_cast (l)); + e.column (c == -1 ? 0: static_cast (c)); +#endif + } + } + } + } + } +} -- cgit v1.1