From e897aa91a2a5c68a2f795f6a0a995600f13a85f8 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Wed, 14 May 2014 21:29:29 -0700 Subject: Convert to extension-less headers for API --- xml/Makefile.am | 7 + xml/content | 35 ++++ xml/content.hxx | 35 ---- xml/exception | 21 +++ xml/exception.hxx | 21 --- xml/forward | 19 +++ xml/forward.hxx | 19 --- xml/makefile | 9 +- xml/parser | 473 +++++++++++++++++++++++++++++++++++++++++++++++++++ xml/parser.cxx | 2 +- xml/parser.hxx | 473 --------------------------------------------------- xml/parser.ixx | 2 +- xml/parser.txx | 2 +- xml/qname | 87 ++++++++++ xml/qname.cxx | 2 +- xml/qname.hxx | 87 ---------- xml/serializer | 227 ++++++++++++++++++++++++ xml/serializer.cxx | 2 +- xml/serializer.hxx | 227 ------------------------ xml/serializer.ixx | 2 +- xml/value-traits | 53 ++++++ xml/value-traits.cxx | 2 +- xml/value-traits.hxx | 53 ------ xml/value-traits.txx | 4 +- 24 files changed, 939 insertions(+), 925 deletions(-) create mode 100644 xml/content delete mode 100644 xml/content.hxx create mode 100644 xml/exception delete mode 100644 xml/exception.hxx create mode 100644 xml/forward delete mode 100644 xml/forward.hxx create mode 100644 xml/parser delete mode 100644 xml/parser.hxx create mode 100644 xml/qname delete mode 100644 xml/qname.hxx create mode 100644 xml/serializer delete mode 100644 xml/serializer.hxx create mode 100644 xml/value-traits delete mode 100644 xml/value-traits.hxx (limited to 'xml') diff --git a/xml/Makefile.am b/xml/Makefile.am index ebe357e..46be59f 100644 --- a/xml/Makefile.am +++ b/xml/Makefile.am @@ -20,5 +20,12 @@ endif libstudxml_la_SOURCES += __path__(genx_sources) nobase_studxmlinclude_HEADERS += __path__(genx_headers) +nobase_studxmlinclude_HEADERS += __path__(xml_headers) + +# Make sure make doesn't try to build the no-extension headers +# thinking that they are executable. +# +__foreach_w__(__f,__path__(xml_headers),__f $(top_srcdir)/xml/__f ): ; @: + AM_CPPFLAGS = -I$(top_builddir) -I$(top_srcdir) -DLIBSTUDXML_DYNAMIC_LIB AM_LDFLAGS = -release __value__(interface_version) -no-undefined diff --git a/xml/content b/xml/content new file mode 100644 index 0000000..e37607f --- /dev/null +++ b/xml/content @@ -0,0 +1,35 @@ +// file : xml/content -*- C++ -*- +// copyright : Copyright (c) 2013-2014 Code Synthesis Tools CC +// license : MIT; see accompanying LICENSE file + +#ifndef XML_CONTENT +#define XML_CONTENT + +#include + +namespace xml +{ + // XML content model. C++11 enum class emulated for C++98. + // + struct content + { + enum value + { + // element characters whitespaces notes + empty, // no no ignored + simple, // no yes preserved content accumulated + complex, // yes no ignored + mixed // yes yes preserved + }; + + content (value v): v_ (v) {}; + operator value () const {return v_;} + + private: + value v_; + }; +} + +#include + +#endif // XML_CONTENT diff --git a/xml/content.hxx b/xml/content.hxx deleted file mode 100644 index 575ef1d..0000000 --- a/xml/content.hxx +++ /dev/null @@ -1,35 +0,0 @@ -// file : xml/content.hxx -// copyright : Copyright (c) 2013-2014 Code Synthesis Tools CC -// license : MIT; see accompanying LICENSE file - -#ifndef XML_CONTENT_HXX -#define XML_CONTENT_HXX - -#include - -namespace xml -{ - // XML content model. C++11 enum class emulated for C++98. - // - struct content - { - enum value - { - // element characters whitespaces notes - empty, // no no ignored - simple, // no yes preserved content accumulated - complex, // yes no ignored - mixed // yes yes preserved - }; - - content (value v): v_ (v) {}; - operator value () const {return v_;} - - private: - value v_; - }; -} - -#include - -#endif // XML_CONTENT_HXX diff --git a/xml/exception b/xml/exception new file mode 100644 index 0000000..1fe1eb2 --- /dev/null +++ b/xml/exception @@ -0,0 +1,21 @@ +// file : xml/exception -*- C++ -*- +// copyright : Copyright (c) 2013-2014 Code Synthesis Tools CC +// license : MIT; see accompanying LICENSE file + +#ifndef XML_EXCEPTION +#define XML_EXCEPTION + +#include + +#include + +#include + +namespace xml +{ + struct LIBSTUDXML_EXPORT exception: std::exception {}; +} + +#include + +#endif // XML_EXCEPTION diff --git a/xml/exception.hxx b/xml/exception.hxx deleted file mode 100644 index c9895bb..0000000 --- a/xml/exception.hxx +++ /dev/null @@ -1,21 +0,0 @@ -// file : xml/exception.hxx -// copyright : Copyright (c) 2013-2014 Code Synthesis Tools CC -// license : MIT; see accompanying LICENSE file - -#ifndef XML_EXCEPTION_HXX -#define XML_EXCEPTION_HXX - -#include - -#include - -#include - -namespace xml -{ - struct LIBSTUDXML_EXPORT exception: std::exception {}; -} - -#include - -#endif // XML_EXCEPTION_HXX diff --git a/xml/forward b/xml/forward new file mode 100644 index 0000000..8d474c7 --- /dev/null +++ b/xml/forward @@ -0,0 +1,19 @@ +// file : xml/forward -*- C++ -*- +// copyright : Copyright (c) 2013-2014 Code Synthesis Tools CC +// license : MIT; see accompanying LICENSE file + +#ifndef XML_FORWARD +#define XML_FORWARD + +#include + +namespace xml +{ + class qname; + class parser; + class serializer; +} + +#include + +#endif // XML_FORWARD diff --git a/xml/forward.hxx b/xml/forward.hxx deleted file mode 100644 index bacd5f5..0000000 --- a/xml/forward.hxx +++ /dev/null @@ -1,19 +0,0 @@ -// file : xml/forward.hxx -// copyright : Copyright (c) 2013-2014 Code Synthesis Tools CC -// license : MIT; see accompanying LICENSE file - -#ifndef XML_FORWARD_HXX -#define XML_FORWARD_HXX - -#include - -namespace xml -{ - class qname; - class parser; - class serializer; -} - -#include - -#endif // XML_FORWARD_HXX diff --git a/xml/makefile b/xml/makefile index 6c8f3b9..52203aa 100644 --- a/xml/makefile +++ b/xml/makefile @@ -5,6 +5,7 @@ include $(dir $(lastword $(MAKEFILE_LIST)))../build/bootstrap.make sources := qname.cxx parser.cxx serializer.cxx value-traits.cxx +xml_headers := content exception forward qname parser serializer value-traits # Expat. # @@ -72,6 +73,12 @@ $(out_base)/: $(studxml.l) # Dist. # + +# Set it for the out_root so that it is visible in examples/tests. See +# Makefile.am for why we need it there. +# +$(our_root)/%.dist: export xml_headers := $(xml_headers) + $(dist): export sources := $(sources) $(dist): export expat_sources := $(expat_sources) $(dist): export expat_headers := $(expat_headers) @@ -89,7 +96,7 @@ $(dist): export interface_version = $(shell sed -e \ $(dist): $(call dist-data,$(sources) $(expat_sources) $(genx_sources)) - $(call dist-data,$(headers) $(expat_headers) $(genx_headers)) + $(call dist-data,$(headers) $(xml_headers) $(expat_headers) $(genx_headers)) $(call dist-data,$(data_dist) details/config.h.in) $(call meta-vc9proj,libstudxml-vc9.vcproj) $(call meta-vc10proj,libstudxml-vc10.vcxproj) diff --git a/xml/parser b/xml/parser new file mode 100644 index 0000000..a1b6250 --- /dev/null +++ b/xml/parser @@ -0,0 +1,473 @@ +// file : xml/parser -*- C++ -*- +// copyright : Copyright (c) 2013-2014 Code Synthesis Tools CC +// license : MIT; see accompanying LICENSE file + +#ifndef XML_PARSER +#define XML_PARSER + +#include + +#include +#include +#include +#include +#include // std::size_t + +#include // LIBSTUDXML_EXTERNAL_EXPAT + +#ifndef LIBSTUDXML_EXTERNAL_EXPAT +# include +#else +# include +#endif + +// We only support UTF-8 Expat. +// +#ifdef XML_UNICODE +# error UTF-16 expat (XML_UNICODE defined) is not supported +#endif + +#include +#include +#include +#include + +#include + +namespace xml +{ + class parser; + + struct LIBSTUDXML_EXPORT parsing: exception + { + virtual + ~parsing () throw (); + + parsing (const std::string& name, + unsigned long long line, + unsigned long long column, + const std::string& description); + + parsing (const parser&, const std::string& description); + + const std::string& + name () const {return name_;} + + unsigned long long + line () const {return line_;} + + unsigned long long + column () const {return column_;} + + const std::string& + description () const {return description_;} + + virtual const char* + what () const throw (); + + private: + void + init (); + + private: + std::string name_; + unsigned long long line_; + unsigned long long column_; + std::string description_; + std::string what_; + }; + + class LIBSTUDXML_EXPORT parser + { + public: + typedef xml::qname qname_type; + typedef xml::content content_type; + + typedef unsigned short feature_type; + + // If both receive_attributes_event and receive_attributes_map are + // specified, then receive_attributes_event is assumed. + // + static const feature_type receive_elements = 0x0001; + static const feature_type receive_characters = 0x0002; + static const feature_type receive_attributes_map = 0x0004; + static const feature_type receive_attributes_event = 0x0008; + static const feature_type receive_namespace_decls = 0x0010; + + static const feature_type receive_default = receive_elements | + receive_characters | + receive_attributes_map; + + // Parse std::istream. Input name is used in diagnostics to identify + // the document being parsed. + // + // If stream exceptions are enabled then std::ios_base::failure + // exception is used to report io errors (badbit and failbit). + // Otherwise, those are reported as the parsing exception. + // + parser (std::istream&, + const std::string& input_name, + feature_type = receive_default); + + // Parse memory buffer that contains the whole document. Input name + // is used in diagnostics to identify the document being parsed. + // + parser (const void* data, + std::size_t size, + const std::string& input_name, + feature_type = receive_default); + + const std::string& + input_name () const {return iname_;} + + ~parser (); + + private: + parser (const parser&); + parser& operator= (const parser&); + + // Parsing events. + // + public: + enum event_type + { + // If adding new events, also update the stream insertion operator. + // + start_element, + end_element, + start_attribute, + end_attribute, + characters, + start_namespace_decl, + end_namespace_decl, + eof + }; + + event_type + next (); + + // Get the next event and make sure that it's what's expected. If it + // is not, then throw an appropriate parsing exception. + // + void + next_expect (event_type); + + void + next_expect (event_type, const std::string& name); + + void + next_expect (event_type, const qname_type& qname); + + void + next_expect (event_type, const std::string& ns, const std::string& name); + + event_type + peek (); + + // Return the even that was last returned by the call to next() or + // peek(). + // + event_type + event () {return event_;} + + // Event data. + // + public: + const qname_type& qname () const {return *pqname_;} + + const std::string& namespace_ () const {return pqname_->namespace_ ();} + const std::string& name () const {return pqname_->name ();} + const std::string& prefix () const {return pqname_->prefix ();} + + std::string& value () {return *pvalue_;} + const std::string& value () const {return *pvalue_;} + template T value () const; + + unsigned long long line () const {return line_;} + unsigned long long column () const {return column_;} + + // Attribute map lookup. If attribute is not found, then the version + // without the default value throws an appropriate parsing exception + // while the version with the default value returns that value. + // + // Note also that there is no attribute(ns,name) version since it + // would conflict with attribute(name,dv) (qualified attributes + // are not very common). + // + // Attribute map is valid throughout at the "element level" until + // end_element and not just during start_element. As a special case, + // the map is still valid after peek() that returned end_element until + // this end_element event is retrieved with next(). + // + const std::string& + attribute (const std::string& name) const; + + template + T + attribute (const std::string& name) const; + + std::string + attribute (const std::string& name, + const std::string& default_value) const; + + template + T + attribute (const std::string& name, const T& default_value) const; + + const std::string& + attribute (const qname_type& qname) const; + + template + T + attribute (const qname_type& qname) const; + + std::string + attribute (const qname_type& qname, + const std::string& default_value) const; + + template + T + attribute (const qname_type& qname, const T& default_value) const; + + bool + attribute_present (const std::string& name) const; + + bool + attribute_present (const qname_type& qname) const; + + // Low-level attribute map access. Note that this API assumes + // all attributes are handled. + // + struct attribute_value_type + { + std::string value; + mutable bool handled; + }; + + typedef std::map attribute_map_type; + + const attribute_map_type& + attribute_map () const; + + // Optional content processing. + // + public: + // Note that you cannot get/set content while peeking. + // + void + content (content_type); + + content_type + content () const; + + // Versions that also set the content. Event type must be start_element. + // + void + next_expect (event_type, const std::string& name, content_type); + + void + next_expect (event_type, const qname_type& qname, content_type); + + void + next_expect (event_type, + const std::string& ns, const std::string& name, + content_type); + + // Helpers for parsing elements with simple content. The first two + // functions assume that start_element has already been parsed. The + // rest parse the complete element, from start to end. + // + // Note also that as with attribute(), there is no (namespace,name) + // overload since it would conflicts with (namespace,default_value). + // + public: + std::string + element (); + + template + T + element (); + + std::string + element (const std::string& name); + + std::string + element (const qname_type& qname); + + template + T + element (const std::string& name); + + template + T + element (const qname_type& qname); + + std::string + element (const std::string& name, const std::string& default_value); + + std::string + element (const qname_type& qname, const std::string& default_value); + + template + T + element (const std::string& name, const T& default_value); + + template + T + element (const qname_type& qname, const T& default_value); + + // C++11 range-based for support. Generally, the iterator interface + // doesn't make much sense for the parser so for now we have an + // implementation that is just enough to the range-based for. + // + public: + struct iterator + { + typedef event_type value_type; + + iterator (parser* p = 0, event_type e = eof): p_ (p), e_ (e) {} + value_type operator* () const {return e_;} + iterator& operator++ () {e_ = p_->next (); return *this;} + + // Comparison only makes sense when comparing to end (eof). + // + bool operator== (iterator y) const {return e_ == eof && y.e_ == eof;} + bool operator!= (iterator y) const {return !(*this == y);} + + private: + parser* p_; + event_type e_; + }; + + iterator begin () {return iterator (this, next ());} + iterator end () {return iterator (this, eof);} + + private: + static void XMLCALL + start_element_ (void*, const XML_Char*, const XML_Char**); + + static void XMLCALL + end_element_ (void*, const XML_Char*); + + static void XMLCALL + characters_ (void*, const XML_Char*, int); + + static void XMLCALL + start_namespace_decl_ (void*, const XML_Char*, const XML_Char*); + + static void XMLCALL + end_namespace_decl_ (void*, const XML_Char*); + + private: + void + init (); + + event_type + next_ (bool peek); + + event_type + next_body (); + + void + handle_error (); + + private: + // If size_ is 0, then data is std::istream. Otherwise, it is a buffer. + // + union + { + std::istream* is; + const void* buf; + } data_; + + std::size_t size_; + + const std::string iname_; + feature_type feature_; + + XML_Parser p_; + std::size_t depth_; + bool accumulate_; // Whether we are accumulating character content. + enum {state_next, state_peek} state_; + event_type event_; + event_type queue_; + + qname_type qname_; + std::string value_; + + // These are used to avoid copying when we are handling attributes + // and namespace decls. + // + const qname_type* pqname_; + std::string* pvalue_; + + unsigned long long line_; + unsigned long long column_; + + // Attributes as events. + // + struct attribute_type + { + qname_type qname; + std::string value; + }; + + typedef std::vector attributes; + + attributes attr_; + attributes::size_type attr_i_; // Index of the current attribute. + + // Namespace declarations. + // + typedef std::vector namespace_decls; + + namespace_decls start_ns_; + namespace_decls::size_type start_ns_i_; // Index of the current decl. + + namespace_decls end_ns_; + namespace_decls::size_type end_ns_i_; // Index of the current decl. + + // Element state consisting of the content model and attribute map. + // + struct element_entry + { + element_entry (std::size_t d, content_type c = content_type::mixed) + : depth (d), content (c), attr_unhandled_ (0) {} + + std::size_t depth; + content_type content; + attribute_map_type attr_map_; + mutable attribute_map_type::size_type attr_unhandled_; + }; + + typedef std::vector element_state; + std::vector element_state_; + + // Empty attribute map to return when an element has no attributes. + // + const attribute_map_type empty_attr_map_; + + // Return the element entry corresponding to the current depth, if + // exists, and NULL otherwise. + // + const element_entry* + get_element () const; + + const element_entry* + get_element_ () const; + + void + pop_element (); + }; + + LIBSTUDXML_EXPORT + std::ostream& + operator<< (std::ostream&, parser::event_type); +} + +#include +#include + +#include + +#endif // XML_PARSER diff --git a/xml/parser.cxx b/xml/parser.cxx index 37f9f76..5e117b9 100644 --- a/xml/parser.cxx +++ b/xml/parser.cxx @@ -9,7 +9,7 @@ #include #include -#include +#include using namespace std; diff --git a/xml/parser.hxx b/xml/parser.hxx deleted file mode 100644 index 6f90522..0000000 --- a/xml/parser.hxx +++ /dev/null @@ -1,473 +0,0 @@ -// file : xml/parser.hxx -// copyright : Copyright (c) 2013-2014 Code Synthesis Tools CC -// license : MIT; see accompanying LICENSE file - -#ifndef XML_PARSER_HXX -#define XML_PARSER_HXX - -#include - -#include -#include -#include -#include -#include // std::size_t - -#include // LIBSTUDXML_EXTERNAL_EXPAT - -#ifndef LIBSTUDXML_EXTERNAL_EXPAT -# include -#else -# include -#endif - -// We only support UTF-8 Expat. -// -#ifdef XML_UNICODE -# error UTF-16 expat (XML_UNICODE defined) is not supported -#endif - -#include -#include -#include -#include - -#include - -namespace xml -{ - class parser; - - struct LIBSTUDXML_EXPORT parsing: exception - { - virtual - ~parsing () throw (); - - parsing (const std::string& name, - unsigned long long line, - unsigned long long column, - const std::string& description); - - parsing (const parser&, const std::string& description); - - const std::string& - name () const {return name_;} - - unsigned long long - line () const {return line_;} - - unsigned long long - column () const {return column_;} - - const std::string& - description () const {return description_;} - - virtual const char* - what () const throw (); - - private: - void - init (); - - private: - std::string name_; - unsigned long long line_; - unsigned long long column_; - std::string description_; - std::string what_; - }; - - class LIBSTUDXML_EXPORT parser - { - public: - typedef xml::qname qname_type; - typedef xml::content content_type; - - typedef unsigned short feature_type; - - // If both receive_attributes_event and receive_attributes_map are - // specified, then receive_attributes_event is assumed. - // - static const feature_type receive_elements = 0x0001; - static const feature_type receive_characters = 0x0002; - static const feature_type receive_attributes_map = 0x0004; - static const feature_type receive_attributes_event = 0x0008; - static const feature_type receive_namespace_decls = 0x0010; - - static const feature_type receive_default = receive_elements | - receive_characters | - receive_attributes_map; - - // Parse std::istream. Input name is used in diagnostics to identify - // the document being parsed. - // - // If stream exceptions are enabled then std::ios_base::failure - // exception is used to report io errors (badbit and failbit). - // Otherwise, those are reported as the parsing exception. - // - parser (std::istream&, - const std::string& input_name, - feature_type = receive_default); - - // Parse memory buffer that contains the whole document. Input name - // is used in diagnostics to identify the document being parsed. - // - parser (const void* data, - std::size_t size, - const std::string& input_name, - feature_type = receive_default); - - const std::string& - input_name () const {return iname_;} - - ~parser (); - - private: - parser (const parser&); - parser& operator= (const parser&); - - // Parsing events. - // - public: - enum event_type - { - // If adding new events, also update the stream insertion operator. - // - start_element, - end_element, - start_attribute, - end_attribute, - characters, - start_namespace_decl, - end_namespace_decl, - eof - }; - - event_type - next (); - - // Get the next event and make sure that it's what's expected. If it - // is not, then throw an appropriate parsing exception. - // - void - next_expect (event_type); - - void - next_expect (event_type, const std::string& name); - - void - next_expect (event_type, const qname_type& qname); - - void - next_expect (event_type, const std::string& ns, const std::string& name); - - event_type - peek (); - - // Return the even that was last returned by the call to next() or - // peek(). - // - event_type - event () {return event_;} - - // Event data. - // - public: - const qname_type& qname () const {return *pqname_;} - - const std::string& namespace_ () const {return pqname_->namespace_ ();} - const std::string& name () const {return pqname_->name ();} - const std::string& prefix () const {return pqname_->prefix ();} - - std::string& value () {return *pvalue_;} - const std::string& value () const {return *pvalue_;} - template T value () const; - - unsigned long long line () const {return line_;} - unsigned long long column () const {return column_;} - - // Attribute map lookup. If attribute is not found, then the version - // without the default value throws an appropriate parsing exception - // while the version with the default value returns that value. - // - // Note also that there is no attribute(ns,name) version since it - // would conflict with attribute(name,dv) (qualified attributes - // are not very common). - // - // Attribute map is valid throughout at the "element level" until - // end_element and not just during start_element. As a special case, - // the map is still valid after peek() that returned end_element until - // this end_element event is retrieved with next(). - // - const std::string& - attribute (const std::string& name) const; - - template - T - attribute (const std::string& name) const; - - std::string - attribute (const std::string& name, - const std::string& default_value) const; - - template - T - attribute (const std::string& name, const T& default_value) const; - - const std::string& - attribute (const qname_type& qname) const; - - template - T - attribute (const qname_type& qname) const; - - std::string - attribute (const qname_type& qname, - const std::string& default_value) const; - - template - T - attribute (const qname_type& qname, const T& default_value) const; - - bool - attribute_present (const std::string& name) const; - - bool - attribute_present (const qname_type& qname) const; - - // Low-level attribute map access. Note that this API assumes - // all attributes are handled. - // - struct attribute_value_type - { - std::string value; - mutable bool handled; - }; - - typedef std::map attribute_map_type; - - const attribute_map_type& - attribute_map () const; - - // Optional content processing. - // - public: - // Note that you cannot get/set content while peeking. - // - void - content (content_type); - - content_type - content () const; - - // Versions that also set the content. Event type must be start_element. - // - void - next_expect (event_type, const std::string& name, content_type); - - void - next_expect (event_type, const qname_type& qname, content_type); - - void - next_expect (event_type, - const std::string& ns, const std::string& name, - content_type); - - // Helpers for parsing elements with simple content. The first two - // functions assume that start_element has already been parsed. The - // rest parse the complete element, from start to end. - // - // Note also that as with attribute(), there is no (namespace,name) - // overload since it would conflicts with (namespace,default_value). - // - public: - std::string - element (); - - template - T - element (); - - std::string - element (const std::string& name); - - std::string - element (const qname_type& qname); - - template - T - element (const std::string& name); - - template - T - element (const qname_type& qname); - - std::string - element (const std::string& name, const std::string& default_value); - - std::string - element (const qname_type& qname, const std::string& default_value); - - template - T - element (const std::string& name, const T& default_value); - - template - T - element (const qname_type& qname, const T& default_value); - - // C++11 range-based for support. Generally, the iterator interface - // doesn't make much sense for the parser so for now we have an - // implementation that is just enough to the range-based for. - // - public: - struct iterator - { - typedef event_type value_type; - - iterator (parser* p = 0, event_type e = eof): p_ (p), e_ (e) {} - value_type operator* () const {return e_;} - iterator& operator++ () {e_ = p_->next (); return *this;} - - // Comparison only makes sense when comparing to end (eof). - // - bool operator== (iterator y) const {return e_ == eof && y.e_ == eof;} - bool operator!= (iterator y) const {return !(*this == y);} - - private: - parser* p_; - event_type e_; - }; - - iterator begin () {return iterator (this, next ());} - iterator end () {return iterator (this, eof);} - - private: - static void XMLCALL - start_element_ (void*, const XML_Char*, const XML_Char**); - - static void XMLCALL - end_element_ (void*, const XML_Char*); - - static void XMLCALL - characters_ (void*, const XML_Char*, int); - - static void XMLCALL - start_namespace_decl_ (void*, const XML_Char*, const XML_Char*); - - static void XMLCALL - end_namespace_decl_ (void*, const XML_Char*); - - private: - void - init (); - - event_type - next_ (bool peek); - - event_type - next_body (); - - void - handle_error (); - - private: - // If size_ is 0, then data is std::istream. Otherwise, it is a buffer. - // - union - { - std::istream* is; - const void* buf; - } data_; - - std::size_t size_; - - const std::string iname_; - feature_type feature_; - - XML_Parser p_; - std::size_t depth_; - bool accumulate_; // Whether we are accumulating character content. - enum {state_next, state_peek} state_; - event_type event_; - event_type queue_; - - qname_type qname_; - std::string value_; - - // These are used to avoid copying when we are handling attributes - // and namespace decls. - // - const qname_type* pqname_; - std::string* pvalue_; - - unsigned long long line_; - unsigned long long column_; - - // Attributes as events. - // - struct attribute_type - { - qname_type qname; - std::string value; - }; - - typedef std::vector attributes; - - attributes attr_; - attributes::size_type attr_i_; // Index of the current attribute. - - // Namespace declarations. - // - typedef std::vector namespace_decls; - - namespace_decls start_ns_; - namespace_decls::size_type start_ns_i_; // Index of the current decl. - - namespace_decls end_ns_; - namespace_decls::size_type end_ns_i_; // Index of the current decl. - - // Element state consisting of the content model and attribute map. - // - struct element_entry - { - element_entry (std::size_t d, content_type c = content_type::mixed) - : depth (d), content (c), attr_unhandled_ (0) {} - - std::size_t depth; - content_type content; - attribute_map_type attr_map_; - mutable attribute_map_type::size_type attr_unhandled_; - }; - - typedef std::vector element_state; - std::vector element_state_; - - // Empty attribute map to return when an element has no attributes. - // - const attribute_map_type empty_attr_map_; - - // Return the element entry corresponding to the current depth, if - // exists, and NULL otherwise. - // - const element_entry* - get_element () const; - - const element_entry* - get_element_ () const; - - void - pop_element (); - }; - - LIBSTUDXML_EXPORT - std::ostream& - operator<< (std::ostream&, parser::event_type); -} - -#include -#include - -#include - -#endif // XML_PARSER_HXX diff --git a/xml/parser.ixx b/xml/parser.ixx index e5656d4..b0bffab 100644 --- a/xml/parser.ixx +++ b/xml/parser.ixx @@ -4,7 +4,7 @@ #include -#include +#include namespace xml { diff --git a/xml/parser.txx b/xml/parser.txx index 0167522..86d9ed7 100644 --- a/xml/parser.txx +++ b/xml/parser.txx @@ -2,7 +2,7 @@ // copyright : Copyright (c) 2013-2014 Code Synthesis Tools CC // license : MIT; see accompanying LICENSE file -#include +#include namespace xml { diff --git a/xml/qname b/xml/qname new file mode 100644 index 0000000..85d6424 --- /dev/null +++ b/xml/qname @@ -0,0 +1,87 @@ +// file : xml/qname -*- C++ -*- +// copyright : Copyright (c) 2013-2014 Code Synthesis Tools CC +// license : MIT; see accompanying LICENSE file + +#ifndef XML_QNAME +#define XML_QNAME + +#include + +#include +#include + +#include + +#include + +namespace xml +{ + // Note that the optional prefix is just a "syntactic sugar". In + // particular, it is ignored by the comparison operators and the + // std::ostream insertion operator. + // + class LIBSTUDXML_EXPORT qname + { + public: + qname () {} + qname (const std::string& name): name_ (name) {} + qname (const std::string& ns, const std::string& name) + : ns_ (ns), name_ (name) {} + qname (const std::string& ns, + const std::string& name, + const std::string& prefix) + : ns_ (ns), name_ (name), prefix_ (prefix) {} + + const std::string& namespace_ () const {return ns_;} + const std::string& name () const {return name_;} + const std::string& prefix () const {return prefix_;} + + std::string& namespace_ () {return ns_;} + std::string& name () {return name_;} + std::string& prefix () {return prefix_;} + + bool + empty () const {return name_.empty () && ns_.empty ();} + + // String representation in the [#] form. + // + std::string + string () const; + + // Note that comparison operators ignore prefixes. + // + public: + friend bool + operator< (const qname& x, const qname& y) + { + return x.ns_ < y.ns_ || (x.ns_ == y.ns_ && x.name_ < y.name_); + } + + friend bool + operator== (const qname& x, const qname& y) + { + return x.ns_ == y.ns_ && x.name_ == y.name_; + } + + friend bool + operator!= (const qname& x, const qname& y) + { + return !(x == y); + } + + private: + std::string ns_; + std::string name_; + std::string prefix_; + }; + + // Print the string representation ([#]). + // + LIBSTUDXML_EXPORT + std::ostream& + operator<< (std::ostream&, const qname&); +} + +#include + +#endif // XML_QNAME diff --git a/xml/qname.cxx b/xml/qname.cxx index 2261ab8..de24e57 100644 --- a/xml/qname.cxx +++ b/xml/qname.cxx @@ -4,7 +4,7 @@ #include -#include +#include using namespace std; diff --git a/xml/qname.hxx b/xml/qname.hxx deleted file mode 100644 index 7ffd215..0000000 --- a/xml/qname.hxx +++ /dev/null @@ -1,87 +0,0 @@ -// file : xml/qname.hxx -// copyright : Copyright (c) 2013-2014 Code Synthesis Tools CC -// license : MIT; see accompanying LICENSE file - -#ifndef XML_QNAME_HXX -#define XML_QNAME_HXX - -#include - -#include -#include - -#include - -#include - -namespace xml -{ - // Note that the optional prefix is just a "syntactic sugar". In - // particular, it is ignored by the comparison operators and the - // std::ostream insertion operator. - // - class LIBSTUDXML_EXPORT qname - { - public: - qname () {} - qname (const std::string& name): name_ (name) {} - qname (const std::string& ns, const std::string& name) - : ns_ (ns), name_ (name) {} - qname (const std::string& ns, - const std::string& name, - const std::string& prefix) - : ns_ (ns), name_ (name), prefix_ (prefix) {} - - const std::string& namespace_ () const {return ns_;} - const std::string& name () const {return name_;} - const std::string& prefix () const {return prefix_;} - - std::string& namespace_ () {return ns_;} - std::string& name () {return name_;} - std::string& prefix () {return prefix_;} - - bool - empty () const {return name_.empty () && ns_.empty ();} - - // String representation in the [#] form. - // - std::string - string () const; - - // Note that comparison operators ignore prefixes. - // - public: - friend bool - operator< (const qname& x, const qname& y) - { - return x.ns_ < y.ns_ || (x.ns_ == y.ns_ && x.name_ < y.name_); - } - - friend bool - operator== (const qname& x, const qname& y) - { - return x.ns_ == y.ns_ && x.name_ == y.name_; - } - - friend bool - operator!= (const qname& x, const qname& y) - { - return !(x == y); - } - - private: - std::string ns_; - std::string name_; - std::string prefix_; - }; - - // Print the string representation ([#]). - // - LIBSTUDXML_EXPORT - std::ostream& - operator<< (std::ostream&, const qname&); -} - -#include - -#endif // XML_QNAME_HXX diff --git a/xml/serializer b/xml/serializer new file mode 100644 index 0000000..6c55d51 --- /dev/null +++ b/xml/serializer @@ -0,0 +1,227 @@ +// file : xml/serializer -*- C++ -*- +// copyright : Copyright (c) 2013-2014 Code Synthesis Tools CC +// license : MIT; see accompanying LICENSE file + +#ifndef XML_SERIALIZER +#define XML_SERIALIZER + +#include + +#include +#include +#include // std::size_t + +#include + +#include +#include +#include + +#include + +namespace xml +{ + class serializer; + + struct LIBSTUDXML_EXPORT serialization: exception + { + virtual + ~serialization () throw (); + + serialization (const std::string& name, + const std::string& description); + + serialization (const serializer&, const std::string& description); + + const std::string& + name () const {return name_;} + + const std::string& + description () const {return description_;} + + virtual const char* + what () const throw (); + + private: + void + init (); + + private: + std::string name_; + std::string description_; + std::string what_; + }; + + class LIBSTUDXML_EXPORT serializer + { + public: + typedef xml::qname qname_type; + + // Serialize to std::ostream. Output name is used in diagnostics to + // identify the document being serialized. The indentation argument + // specifies the number of indentation spaces that should be used for + // pretty-printing. If 0 is passed, no pretty-printing is performed. + // + // If stream exceptions are enabled then std::ios_base::failure + // exception is used to report io errors (badbit and failbit). + // Otherwise, those are reported as the serialization exception. + // + serializer (std::ostream&, + const std::string& output_name, + unsigned short indentation = 2); + + const std::string& + output_name () const {return oname_;} + + ~serializer (); + + private: + serializer (const serializer&); + serializer& operator= (const serializer&); + + // Serialization functions. + // + public: + + // Elements. + // + void + start_element (const qname_type& qname); + + void + start_element (const std::string& name); + + void + start_element (const std::string& ns, const std::string& name); + + void + end_element (); + + // Helpers for serializing elements with simple content. The first two + // functions assume that start_element() has already been called. The + // other two serialize the complete element, from start to end. + // + void + element (const std::string& value); + + template + void + element (const T& value); + + void + element (const std::string& name, const std::string& value); + + template + void + element (const std::string& name, const T& value); + + void + element (const qname_type& qname, const std::string& value); + + template + void + element (const qname_type& qname, const T& value); + + void + element (const std::string& namespace_, + const std::string& name, + const std::string& value); + + template + void + element (const std::string& namespace_, + const std::string& name, + const T& value); + + // Attributes. + // + void + start_attribute (const qname_type& qname); + + void + start_attribute (const std::string& name); + + void + start_attribute (const std::string& ns, const std::string& name); + + void + end_attribute (); + + void + attribute (const qname_type& qname, const std::string& value); + + template + void + attribute (const qname_type& qname, const T& value); + + void + attribute (const std::string& name, const std::string& value); + + template + void + attribute (const std::string& name, const T& value); + + void + attribute (const std::string& ns, + const std::string& name, + const std::string& value); + + template + void + attribute (const std::string& ns, + const std::string& name, + const T& value); + + // Characters. + // + void + characters (const std::string& value); + + template + void + characters (const T& value); + + // Namespaces declaration. If prefix is empty, then the default + // namespace is declared. If both prefix and namespace are empty, + // then the default namespace declaration is cleared (xmlns=""). + // + void + namespace_decl (const std::string& ns, const std::string& prefix); + + // XML declaration. If encoding or standalone are not specified, + // then these attributes are omitted from the output. + // + void + xml_decl (const std::string& version = "1.0", + const std::string& encoding = "UTF-8", + const std::string& standalone = ""); + + // Utility functions. + // + public: + // Return true if there is a mapping. In this case, prefix contains + // the mapped prefix. + // + bool + lookup_namespace_prefix (const std::string& ns, std::string& prefix); + + private: + void + handle_error (genxStatus); + + private: + std::ostream& os_; + std::ostream::iostate os_state_; // Original exception state. + const std::string oname_; + + genxWriter s_; + genxSender sender_; + std::size_t depth_; + }; +} + +#include + +#include + +#endif // XML_SERIALIZER diff --git a/xml/serializer.cxx b/xml/serializer.cxx index a6afcca..4d1da5b 100644 --- a/xml/serializer.cxx +++ b/xml/serializer.cxx @@ -5,7 +5,7 @@ #include // std::bad_alloc #include // std::strlen -#include +#include using namespace std; diff --git a/xml/serializer.hxx b/xml/serializer.hxx deleted file mode 100644 index 4f57e48..0000000 --- a/xml/serializer.hxx +++ /dev/null @@ -1,227 +0,0 @@ -// file : xml/serializer.hxx -// copyright : Copyright (c) 2013-2014 Code Synthesis Tools CC -// license : MIT; see accompanying LICENSE file - -#ifndef XML_SERIALIZER_HXX -#define XML_SERIALIZER_HXX - -#include - -#include -#include -#include // std::size_t - -#include - -#include -#include -#include - -#include - -namespace xml -{ - class serializer; - - struct LIBSTUDXML_EXPORT serialization: exception - { - virtual - ~serialization () throw (); - - serialization (const std::string& name, - const std::string& description); - - serialization (const serializer&, const std::string& description); - - const std::string& - name () const {return name_;} - - const std::string& - description () const {return description_;} - - virtual const char* - what () const throw (); - - private: - void - init (); - - private: - std::string name_; - std::string description_; - std::string what_; - }; - - class LIBSTUDXML_EXPORT serializer - { - public: - typedef xml::qname qname_type; - - // Serialize to std::ostream. Output name is used in diagnostics to - // identify the document being serialized. The indentation argument - // specifies the number of indentation spaces that should be used for - // pretty-printing. If 0 is passed, no pretty-printing is performed. - // - // If stream exceptions are enabled then std::ios_base::failure - // exception is used to report io errors (badbit and failbit). - // Otherwise, those are reported as the serialization exception. - // - serializer (std::ostream&, - const std::string& output_name, - unsigned short indentation = 2); - - const std::string& - output_name () const {return oname_;} - - ~serializer (); - - private: - serializer (const serializer&); - serializer& operator= (const serializer&); - - // Serialization functions. - // - public: - - // Elements. - // - void - start_element (const qname_type& qname); - - void - start_element (const std::string& name); - - void - start_element (const std::string& ns, const std::string& name); - - void - end_element (); - - // Helpers for serializing elements with simple content. The first two - // functions assume that start_element() has already been called. The - // other two serialize the complete element, from start to end. - // - void - element (const std::string& value); - - template - void - element (const T& value); - - void - element (const std::string& name, const std::string& value); - - template - void - element (const std::string& name, const T& value); - - void - element (const qname_type& qname, const std::string& value); - - template - void - element (const qname_type& qname, const T& value); - - void - element (const std::string& namespace_, - const std::string& name, - const std::string& value); - - template - void - element (const std::string& namespace_, - const std::string& name, - const T& value); - - // Attributes. - // - void - start_attribute (const qname_type& qname); - - void - start_attribute (const std::string& name); - - void - start_attribute (const std::string& ns, const std::string& name); - - void - end_attribute (); - - void - attribute (const qname_type& qname, const std::string& value); - - template - void - attribute (const qname_type& qname, const T& value); - - void - attribute (const std::string& name, const std::string& value); - - template - void - attribute (const std::string& name, const T& value); - - void - attribute (const std::string& ns, - const std::string& name, - const std::string& value); - - template - void - attribute (const std::string& ns, - const std::string& name, - const T& value); - - // Characters. - // - void - characters (const std::string& value); - - template - void - characters (const T& value); - - // Namespaces declaration. If prefix is empty, then the default - // namespace is declared. If both prefix and namespace are empty, - // then the default namespace declaration is cleared (xmlns=""). - // - void - namespace_decl (const std::string& ns, const std::string& prefix); - - // XML declaration. If encoding or standalone are not specified, - // then these attributes are omitted from the output. - // - void - xml_decl (const std::string& version = "1.0", - const std::string& encoding = "UTF-8", - const std::string& standalone = ""); - - // Utility functions. - // - public: - // Return true if there is a mapping. In this case, prefix contains - // the mapped prefix. - // - bool - lookup_namespace_prefix (const std::string& ns, std::string& prefix); - - private: - void - handle_error (genxStatus); - - private: - std::ostream& os_; - std::ostream::iostate os_state_; // Original exception state. - const std::string oname_; - - genxWriter s_; - genxSender sender_; - std::size_t depth_; - }; -} - -#include - -#include - -#endif // XML_SERIALIZER_HXX diff --git a/xml/serializer.ixx b/xml/serializer.ixx index 81631f2..ea3dcf0 100644 --- a/xml/serializer.ixx +++ b/xml/serializer.ixx @@ -2,7 +2,7 @@ // copyright : Copyright (c) 2013-2014 Code Synthesis Tools CC // license : MIT; see accompanying LICENSE file -#include +#include namespace xml { diff --git a/xml/value-traits b/xml/value-traits new file mode 100644 index 0000000..3bf10e0 --- /dev/null +++ b/xml/value-traits @@ -0,0 +1,53 @@ +// file : xml/value-traits -*- C++ -*- +// copyright : Copyright (c) 2013-2014 Code Synthesis Tools CC +// license : MIT; see accompanying LICENSE file + +#ifndef XML_VALUE_TRAITS +#define XML_VALUE_TRAITS + +#include + +#include +#include // std::size_t + +#include + +#include + +namespace xml +{ + template + struct default_value_traits + { + static T + parse (std::string, const parser&); + + static std::string + serialize (const T&, const serializer&); + }; + + template <> + struct LIBSTUDXML_EXPORT default_value_traits + { + static bool + parse (std::string, const parser&); + + static std::string + serialize (bool v, const serializer&) + { + return v ? "true" : "false"; + } + }; + + template + struct value_traits: default_value_traits {}; + + template + struct value_traits: default_value_traits {}; +} + +#include + +#include + +#endif // XML_VALUE_TRAITS diff --git a/xml/value-traits.cxx b/xml/value-traits.cxx index 65aa1b6..3530c91 100644 --- a/xml/value-traits.cxx +++ b/xml/value-traits.cxx @@ -2,7 +2,7 @@ // copyright : Copyright (c) 2013-2014 Code Synthesis Tools CC // license : MIT; see accompanying LICENSE file -#include +#include using namespace std; diff --git a/xml/value-traits.hxx b/xml/value-traits.hxx deleted file mode 100644 index ca86382..0000000 --- a/xml/value-traits.hxx +++ /dev/null @@ -1,53 +0,0 @@ -// file : xml/value-traits.hxx -// copyright : Copyright (c) 2013-2014 Code Synthesis Tools CC -// license : MIT; see accompanying LICENSE file - -#ifndef XML_VALUE_TRAITS_HXX -#define XML_VALUE_TRAITS_HXX - -#include - -#include -#include // std::size_t - -#include - -#include - -namespace xml -{ - template - struct default_value_traits - { - static T - parse (std::string, const parser&); - - static std::string - serialize (const T&, const serializer&); - }; - - template <> - struct LIBSTUDXML_EXPORT default_value_traits - { - static bool - parse (std::string, const parser&); - - static std::string - serialize (bool v, const serializer&) - { - return v ? "true" : "false"; - } - }; - - template - struct value_traits: default_value_traits {}; - - template - struct value_traits: default_value_traits {}; -} - -#include - -#include - -#endif // XML_VALUE_TRAITS_HXX diff --git a/xml/value-traits.txx b/xml/value-traits.txx index b76b8a3..3947a99 100644 --- a/xml/value-traits.txx +++ b/xml/value-traits.txx @@ -4,8 +4,8 @@ #include -#include -#include +#include +#include namespace xml { -- cgit v1.1