From 1a4099b78717b16f632b0e7e0980a27811221e52 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Thu, 3 Jul 2014 09:57:09 +0200 Subject: Implement anyType and anySimpleType content representation anyType as a DOM fragment, similar to wildcards. anySimpleType as a text string. --- libxsd/xsd/cxx/tree/comparison-map.txx | 19 +- libxsd/xsd/cxx/tree/containers-wildcard.hxx | 2 +- libxsd/xsd/cxx/tree/containers.hxx | 256 +---------------- libxsd/xsd/cxx/tree/elements.hxx | 386 +++++++++++++++++++++++--- libxsd/xsd/cxx/tree/elements.ixx | 213 +++++++++++++- libxsd/xsd/cxx/tree/elements.txx | 8 +- libxsd/xsd/cxx/tree/iterator-adapter.hxx | 270 ++++++++++++++++++ libxsd/xsd/cxx/tree/list.hxx | 2 +- libxsd/xsd/cxx/tree/parsing.txx | 62 +++-- libxsd/xsd/cxx/tree/serialization.txx | 41 ++- libxsd/xsd/cxx/tree/std-ostream-map.txx | 2 +- libxsd/xsd/cxx/tree/std-ostream-operators.hxx | 6 +- libxsd/xsd/cxx/tree/stream-extraction-map.txx | 2 +- libxsd/xsd/cxx/tree/stream-extraction.hxx | 16 +- libxsd/xsd/cxx/tree/stream-insertion-map.txx | 2 +- libxsd/xsd/cxx/tree/stream-insertion.hxx | 8 +- libxsd/xsd/cxx/tree/type-factory-map.txx | 2 +- libxsd/xsd/cxx/tree/type-serializer-map.txx | 2 +- libxsd/xsd/cxx/tree/types.hxx | 166 +++++++++++ libxsd/xsd/cxx/xml/string.hxx | 17 +- 20 files changed, 1117 insertions(+), 365 deletions(-) create mode 100644 libxsd/xsd/cxx/tree/iterator-adapter.hxx (limited to 'libxsd') diff --git a/libxsd/xsd/cxx/tree/comparison-map.txx b/libxsd/xsd/cxx/tree/comparison-map.txx index e996aec..af23d64 100644 --- a/libxsd/xsd/cxx/tree/comparison-map.txx +++ b/libxsd/xsd/cxx/tree/comparison-map.txx @@ -19,18 +19,17 @@ namespace xsd // anyType and anySimpleType. // - //register_type ( - // typeid (type), - // &comparator_impl, - // false); - - typedef simple_type simple_type; + register_type ( + typeid (type), + &comparator_impl, + false); - //register_type ( - // typeid (simple_type), - // &comparator_impl, - // false); + typedef simple_type simple_type; + register_type ( + typeid (simple_type), + &comparator_impl, + false); // Strings // diff --git a/libxsd/xsd/cxx/tree/containers-wildcard.hxx b/libxsd/xsd/cxx/tree/containers-wildcard.hxx index f4d3be2..549df73 100644 --- a/libxsd/xsd/cxx/tree/containers-wildcard.hxx +++ b/libxsd/xsd/cxx/tree/containers-wildcard.hxx @@ -15,7 +15,7 @@ #include -#include // iterator_adapter +#include namespace xsd { diff --git a/libxsd/xsd/cxx/tree/containers.hxx b/libxsd/xsd/cxx/tree/containers.hxx index c89218f..cafd79d 100644 --- a/libxsd/xsd/cxx/tree/containers.hxx +++ b/libxsd/xsd/cxx/tree/containers.hxx @@ -5,17 +5,15 @@ #ifndef XSD_CXX_TREE_CONTAINERS_HXX #define XSD_CXX_TREE_CONTAINERS_HXX -#include // std::ptrdiff_t -#include #include #include // std::auto_ptr/unique_ptr -#include // std::iterator_traits #include // std::equal, std::lexicographical_compare #include #include // XSD_AUTO_PTR #include +#include namespace xsd { @@ -515,7 +513,7 @@ namespace xsd return !(a < b); } - // Provide an ostream insertion opretaor to prevent confusion from + // Provide an ostream insertion operator to prevent confusion from // the implicit bool conversion. // template @@ -528,256 +526,6 @@ namespace xsd template ::r> class sequence; - // Sun CC's does not have iterator_traits. To overcome - // this, we will wrap std::iterator_traits into our own and also - // specialize it for pointer types. Since Sun CC uses pointer - // for vector::iterator, it will use the specialization and won't - // notice the std::iterator_traits. - // -#ifndef _RWSTD_NO_CLASS_PARTIAL_SPEC - template - struct iterator_traits - { - typedef - typename std::iterator_traits::iterator_category - iterator_category; - - typedef - typename std::iterator_traits::value_type - value_type; - - typedef - typename std::iterator_traits::difference_type - difference_type; - }; -#else - // The Pointer specialization does not work for reverse and - // set iterators. But these iterators are user-dfined types - // and have suitable typedefs that we can use. - // - template - struct iterator_traits - { - typedef typename I::iterator_category iterator_category; - typedef typename I::value_type value_type; - typedef typename I::difference_type difference_type; - }; - - template - struct iterator_traits - { - typedef std::random_access_iterator_tag iterator_category; - typedef T value_type; - typedef std::ptrdiff_t difference_type; - }; -#endif - - // Iterator adapter for complex types. It expects I to point to - // a smart pointer-like object that has operator*() that returns - // a refernce to a type static_cast'able to T and get() that - // returns a pointer to a type static_cast'able to T. - // - - template - struct iterator_adapter - { - typedef T value_type; - typedef value_type& reference; - typedef value_type* pointer; - - typedef - typename iterator_traits::iterator_category - iterator_category; - - typedef - typename iterator_traits::difference_type - difference_type; - - - public: - iterator_adapter () - : i_ () // i_ can be of a pointer type. - { - } - - // Allow iterator to const_iterator conversion. - // - template - iterator_adapter (const iterator_adapter& j) - : i_ (j.base ()) - { - } - - explicit - iterator_adapter (const I& i) - : i_ (i) - { - } - - public: - // Forward iterator requirements. - // - reference - operator* () const - { - return static_cast (**i_); - } - - pointer - operator-> () const - { - return static_cast (i_->get ()); - } - - iterator_adapter& - operator++ () - { - ++i_; - return *this; - } - - iterator_adapter - operator++ (int) - { - iterator_adapter r (*this); - ++i_; - return r; - } - - // Bidirectional iterator requirements. - // - iterator_adapter& - operator-- () - { - --i_; - return *this; - } - - iterator_adapter - operator-- (int) - { - iterator_adapter r (*this); - --i_; - return r; - } - - // Random access iterator requirements. - // - reference - operator[] (difference_type n) const - { - return static_cast (*(i_[n])); - } - - iterator_adapter& - operator+= (difference_type n) - { - i_ += n; - return *this; - } - - iterator_adapter - operator+ (difference_type n) const - { - return iterator_adapter (i_ + n); - } - - iterator_adapter& - operator-= (difference_type n) - { - i_ -= n; - return *this; - } - - iterator_adapter - operator- (difference_type n) const - { - return iterator_adapter (i_ - n); - } - - public: - const I& - base () const - { - return i_; - } - - private: - I i_; - }; - - // Note: We use different types for left- and right-hand-side - // arguments to allow comparison between iterator and const_iterator. - // - - // Forward iterator requirements. - // - template - inline bool - operator== (const iterator_adapter& i, - const iterator_adapter& j) - { - return i.base () == j.base (); - } - - template - inline bool - operator!= (const iterator_adapter& i, - const iterator_adapter& j) - { - return i.base () != j.base (); - } - - // Random access iterator requirements - // - template - inline bool - operator< (const iterator_adapter& i, - const iterator_adapter& j) - { - return i.base () < j.base (); - } - - template - inline bool - operator> (const iterator_adapter& i, - const iterator_adapter& j) - { - return i.base () > j.base (); - } - - template - inline bool - operator<= (const iterator_adapter& i, - const iterator_adapter& j) - { - return i.base () <= j.base (); - } - - template - inline bool - operator>= (const iterator_adapter& i, - const iterator_adapter& j) - { - return i.base () >= j.base (); - } - - template - inline typename iterator_adapter::difference_type - operator- (const iterator_adapter& i, - const iterator_adapter& j) - { - return i.base () - j.base (); - } - - template - inline iterator_adapter - operator+ (typename iterator_adapter::difference_type n, - const iterator_adapter& i) - { - return iterator_adapter (i.base () + n); - } - // // class sequence_common diff --git a/libxsd/xsd/cxx/tree/elements.hxx b/libxsd/xsd/cxx/tree/elements.hxx index 89be61e..ee32a62 100644 --- a/libxsd/xsd/cxx/tree/elements.hxx +++ b/libxsd/xsd/cxx/tree/elements.hxx @@ -40,10 +40,12 @@ #include // xml::properties #include // dom::auto_ptr/unique_ptr +#include // dom::create_document() #include #include #include +#include #if _XERCES_VERSION < 30000 # error Xerces-C++ 2-series is not supported @@ -101,6 +103,12 @@ namespace xsd static const unsigned long dont_validate = 0x00000400UL; /** + * @brief Extract XML content for anyType or anySimpleType. + * Normally you don't need to specify this flag explicitly. + */ + static const unsigned long extract_content = 0x00000800UL; + + /** * @brief Do not initialize the Xerces-C++ runtime. */ static const unsigned long dont_initialize = 0x00000001UL; @@ -330,9 +338,14 @@ namespace xsd _type (); /** - * @brief Create an instance from a string. + * @brief Create an instance from a C string. * * @param s A string to initialize the instance with. + * + * Note that this constructor ignores the string and creates an + * empty anyType instance. In particular, it will not convert the + * string into DOM content. The purpose of such a strange constructor + * is to allow statically-initialized default values of anyType type. */ template _type (const C* s); @@ -387,7 +400,9 @@ namespace xsd * @param c A pointer to the object that will contain the new * instance. */ - _type (const xercesc::DOMElement& e, flags f = 0, container* c = 0); + _type (const xercesc::DOMElement& e, + flags f = flags::extract_content, + container* c = 0); /** * @brief Create an instance from a DOM Attribute. @@ -427,6 +442,11 @@ namespace xsd { if (this != &x) { + if (x.content_.get () == 0) + content_.reset (); + else + content_ = x.content_->clone (); + // Drop DOM association. // dom_info_.reset (); @@ -435,6 +455,135 @@ namespace xsd return *this; } + // anyType content API. + // + public: + typedef element_optional dom_content_optional; + + /** + * @brief Return a read-only (constant) reference to the anyType + * DOM content. + * + * @return A constant reference to the optional container. + * + * The DOM content is returned as an optional element container, + * the same container as used for optional element wildcards. + */ + const dom_content_optional& + dom_content () const; + + /** + * @brief Return a read-write reference to the anyType DOM content. + * + * @return A reference to the optional container. + * + * The DOM content is returned as an optional element container, + * the same container as used for optional element wildcards. + */ + dom_content_optional& + dom_content (); + + /** + * @brief Set the anyType DOM content. + * + * @param e A new element to set. + * + * This function makes a copy of its argument and sets it as the + * new DOM content. + */ + void + dom_content (const xercesc::DOMElement& e); + + /** + * @brief Set the anyType DOM content. + * + * @param e A new element to use. + * + * This function will use the passed element directly instead + * of making a copy. For this to work the element should belong + * to the DOM document associated with this anyType instance. + * + * @see dom_content_document + */ + void + dom_content (xercesc::DOMElement* e); + + /** + * @brief Set the anyType DOM content. + * + * @param d An optional container with the new element to set. + * + * If the element is present in @a d then this function makes a + * copy of this element and sets it as the new wildcard content. + * Otherwise the element container is set the 'not present' state. + */ + void + dom_content (const dom_content_optional& d); + + /** + * @brief Return a read-only (constant) reference to the DOM + * document associated with this anyType instance. + * + * @return A constant reference to the DOM document. + * + * The DOM document returned by this function is used to store + * the raw XML content corresponding to the anyType instance. + */ + const xercesc::DOMDocument& + dom_content_document () const; + + /** + * @brief Return a read-write reference to the DOM document + * associated with this anyType instance. + * + * @return A reference to the DOM document. + * + * The DOM document returned by this function is used to store + * the raw XML content corresponding to the anyType instance. + */ + xercesc::DOMDocument& + dom_content_document (); + + /** + * @brief Check for absence of DOM (anyType) and text (anySimpleType) + * content. + * + * @return True if there is no content and false otherwise. + * + * This is an optimization function that allows us to check for the + * lack of content without actually creating its empty representation + * (that is, empty DOM document for DOM or empty string for text). + */ + bool + null_content () const; + + // + // + public: + /** + * @brief Comparison operator. It uses DOM (anyType) or text + * (anySimpleType) content if present. If the content is missing + * then the types are assumed unequal. + * + * @return True if the instances are equal, false otherwise. + */ + friend bool + operator== (const type& x, const type& y) + { + return x.content_.get () != 0 && + x.content_->compare (y.content_.get ()); + } + + /** + * @brief Comparison operator. It uses DOM (anyType) or text + * (anySimpleType) content if present. If the content is missing + * then the types are assumed unequal. + * + * @return True if the instances are not equal, false otherwise. + */ + friend bool + operator!= (const type& x, const type& y) {return !(x == y);} + // Container API. // public: @@ -738,13 +887,9 @@ namespace xsd struct dom_info { virtual - ~dom_info () - { - } + ~dom_info () {} - dom_info () - { - } + dom_info () {} virtual XSD_AUTO_PTR clone (type& tree_node, container*) const = 0; @@ -754,12 +899,9 @@ namespace xsd private: dom_info (const dom_info&); - - dom_info& - operator= (const dom_info&); + dom_info& operator= (const dom_info&); }; - struct dom_element_info: public dom_info { dom_element_info (xercesc::DOMElement& e, type& n, bool root) @@ -994,20 +1136,75 @@ namespace xsd XSD_AUTO_PTR map_; - private: - container* container_; - }; + // anyType and anySimpleType content. + // + protected: - inline _type:: - _type (const type& x, flags f, container* c) - : container_ (c) - { - if (x.dom_info_.get () != 0 && (f & flags::keep_dom)) + //@cond + + struct content_type { - dom_info_ = x.dom_info_->clone (*this, c); - } - } + virtual + ~content_type () {} + + content_type () {} + + virtual XSD_AUTO_PTR + clone () const = 0; + + virtual bool + compare (const content_type*) const = 0; + + private: + content_type (const content_type&); + content_type& operator= (const content_type&); + }; + + struct dom_content_type: content_type + { + dom_content_type () + : doc (xml::dom::create_document ()), dom (*doc) {} + explicit + dom_content_type (const xercesc::DOMElement& e) + : doc (xml::dom::create_document ()), dom (e, *doc) {} + + explicit + dom_content_type (xercesc::DOMElement* e) + : doc (xml::dom::create_document ()), dom (e, *doc) {} + + explicit + dom_content_type (const dom_content_optional& d) + : doc (xml::dom::create_document ()), dom (d, *doc) {} + + virtual XSD_AUTO_PTR + clone () const + { + return XSD_AUTO_PTR (new dom_content_type (dom)); + } + + virtual bool + compare (const content_type* c) const + { + if (const dom_content_type* dc = + dynamic_cast (c)) + return dom == dc->dom; + + return false; + } + + public: + XSD_DOM_AUTO_PTR doc; + dom_content_optional dom; + }; + + //@endcond + + mutable XSD_AUTO_PTR content_; + + private: + container* container_; + }; /** * @brief Class corresponding to the XML Schema anySimpleType built-in @@ -1015,7 +1212,7 @@ namespace xsd * * @nosubgrouping */ - template + template class simple_type: public B { public: @@ -1030,13 +1227,19 @@ namespace xsd simple_type (); /** - * @brief Create an instance from a string. + * @brief Create an instance from a C string. * * @param s A string to initialize the instance with. */ - template simple_type (const C* s); + /** + * @brief Create an instance from a string. + * + * @param s A string to initialize the instance with. + */ + simple_type (const std::basic_string& s); + public: /** * @brief Copy constructor. @@ -1074,7 +1277,9 @@ namespace xsd * instance. */ template - simple_type (istream& s, flags f = 0, container* c = 0); + simple_type (istream& s, + flags f = flags::extract_content, + container* c = 0); /** * @brief Create an instance from a DOM element. @@ -1085,7 +1290,7 @@ namespace xsd * instance. */ simple_type (const xercesc::DOMElement& e, - flags f = 0, + flags f = flags::extract_content, container* c = 0); /** @@ -1097,7 +1302,7 @@ namespace xsd * instance. */ simple_type (const xercesc::DOMAttr& a, - flags f = 0, + flags f = flags::extract_content, container* c = 0); /** @@ -1109,12 +1314,82 @@ namespace xsd * @param c A pointer to the object that will contain the new * instance. */ - template simple_type (const std::basic_string& s, const xercesc::DOMElement* e, - flags f = 0, + flags f = flags::extract_content, container* c = 0); //@} + + // anySimpleType content API. + // + public: + /** + * @brief Return a read-only (constant) reference to the anySimpleType + * text content. + * + * @return A constant reference to the text string. + */ + const std::basic_string& + text_content () const; + + /** + * @brief Return a read-write reference to the anySimpleType text + * content. + * + * @return A reference to the text string. + */ + std::basic_string& + text_content (); + + /** + * @brief Set the anySimpleType text content. + * + * @param e A new text string to set. + */ + void + text_content (const std::basic_string& t); + + protected: + //@cond + + typedef typename B::content_type content_type; + + struct text_content_type: content_type + { + text_content_type () {} + + explicit + text_content_type (const std::basic_string& t): text (t) {} + + explicit + text_content_type (const C* t): text (t) {} + + virtual XSD_AUTO_PTR + clone () const + { + return XSD_AUTO_PTR (new text_content_type (text)); + } + + virtual bool + compare (const content_type* c) const + { + if (const text_content_type* tc = + dynamic_cast (c)) + return text == tc->text; + + return false; + } + + public: + // It would have been more elegant to store text content as DOMText. + // However, that would require Xerces-C++ initialization. Also + // having a separate DOMDocument for each text node seems like + // an overkill. + // + std::basic_string text; + }; + + //@endcond }; @@ -1233,8 +1508,57 @@ namespace xsd { return XSD_AUTO_PTR (new T (s, e, f, c)); } + + // For now for istream we only go through traits for non- + // fundamental types. + // + template + static XSD_AUTO_PTR + create (istream& s, flags f, container* c) + { + return XSD_AUTO_PTR (new T (s, f, c)); + } }; + template + struct traits, C, ST> + { + typedef simple_type type; + + static XSD_AUTO_PTR + create (const xercesc::DOMElement& e, flags f, container* c) + { + return XSD_AUTO_PTR ( + new type (e, f | flags::extract_content, c)); + } + + static XSD_AUTO_PTR + create (const xercesc::DOMAttr& a, flags f, container* c) + { + return XSD_AUTO_PTR ( + new type (a, f | flags::extract_content, c)); + } + + static XSD_AUTO_PTR + create (const std::basic_string& s, + const xercesc::DOMElement* e, + flags f, + container* c) + { + return XSD_AUTO_PTR ( + new type (s, e, f | flags::extract_content, c)); + } + + template + static XSD_AUTO_PTR + create (istream& s, flags f, container* c) + { + return XSD_AUTO_PTR ( + new type (s, f | flags::extract_content, c)); + } + }; //@endcond diff --git a/libxsd/xsd/cxx/tree/elements.ixx b/libxsd/xsd/cxx/tree/elements.ixx index da8a83e..844ccf7 100644 --- a/libxsd/xsd/cxx/tree/elements.ixx +++ b/libxsd/xsd/cxx/tree/elements.ixx @@ -45,20 +45,221 @@ namespace xsd { } + inline _type:: + _type (const type& x, flags f, container* c) + : container_ (c) + { + if (x.content_.get () != 0) + content_ = x.content_->clone (); + + if (x.dom_info_.get () != 0 && (f & flags::keep_dom)) + { + dom_info_ = x.dom_info_->clone (*this, c); + } + } + + inline const _type::dom_content_optional& _type:: + dom_content () const + { + const content_type* c (content_.get ()); + + if (c == 0) + { + content_.reset (new dom_content_type); + c = content_.get (); + } + + // Accessing non-DOM content via the DOM API. + // + assert (dynamic_cast (c) != 0); + + return static_cast (c)->dom; + } + + inline _type::dom_content_optional& _type:: + dom_content () + { + content_type* c (content_.get ()); + + if (c == 0) + { + content_.reset (new dom_content_type); + c = content_.get (); + } + + // Accessing non-DOM content via the DOM API. + // + assert (dynamic_cast (c) != 0); + + return static_cast (c)->dom; + } + + inline void _type:: + dom_content (const xercesc::DOMElement& e) + { + content_type* c (content_.get ()); + + if (c == 0) + content_.reset (new dom_content_type (e)); + else + { + // Accessing non-DOM content via the DOM API. + // + assert (dynamic_cast (c) != 0); + static_cast (c)->dom.set (e); + } + } + + inline void _type:: + dom_content (xercesc::DOMElement* e) + { + content_type* c (content_.get ()); + + if (c == 0) + content_.reset (new dom_content_type (e)); + else + { + // Accessing non-DOM content via the DOM API. + // + assert (dynamic_cast (c) != 0); + static_cast (c)->dom.set (e); + } + } + + inline void _type:: + dom_content (const dom_content_optional& d) + { + content_type* c (content_.get ()); + + if (c == 0) + content_.reset (new dom_content_type (d)); + else + { + // Accessing non-DOM content via the DOM API. + // + assert (dynamic_cast (c) != 0); + static_cast (c)->dom = d; + } + } + + inline const xercesc::DOMDocument& _type:: + dom_content_document () const + { + const content_type* c (content_.get ()); + + if (c == 0) + { + content_.reset (new dom_content_type); + c = content_.get (); + } + + // Accessing non-DOM content via the DOM API. + // + assert (dynamic_cast (c) != 0); + + return *static_cast (c)->doc; + } + + inline xercesc::DOMDocument& _type:: + dom_content_document () + { + content_type* c (content_.get ()); + + if (c == 0) + { + content_.reset (new dom_content_type); + c = content_.get (); + } + + // Accessing non-DOM content via the DOM API. + // + assert (dynamic_cast (c) != 0); + + return *static_cast (c)->doc; + } + + inline bool _type:: + null_content () const + { + return content_.get () == 0; + } + // simple_type // - template - inline simple_type:: + template + inline simple_type:: simple_type () { } - template - template - inline simple_type:: - simple_type (const C*) + template + inline simple_type:: + simple_type (const C* s) + { + this->content_.reset (new text_content_type (s)); + } + + template + inline simple_type:: + simple_type (const std::basic_string& s) { + this->content_.reset (new text_content_type (s)); + } + + template + inline const std::basic_string& simple_type:: + text_content () const + { + const content_type* c (this->content_.get ()); + + if (c == 0) + { + this->content_.reset (new text_content_type); + c = this->content_.get (); + } + + // Accessing non-text content via the text API. + // + assert (dynamic_cast (c) != 0); + + return static_cast (c)->text; + } + + template + inline std::basic_string& simple_type:: + text_content () + { + content_type* c (this->content_.get ()); + + if (c == 0) + { + this->content_.reset (new text_content_type); + c = this->content_.get (); + } + + // Accessing non-text content via the text API. + // + assert (dynamic_cast (c) != 0); + + return static_cast (c)->text; + } + + template + inline void simple_type:: + text_content (const std::basic_string& t) + { + content_type* c (this->content_.get ()); + + if (c == 0) + this->content_.reset (new text_content_type (t)); + else + { + // Accessing non-text content via the text API. + // + assert (dynamic_cast (c) != 0); + static_cast (c)->text = t; + } } } } diff --git a/libxsd/xsd/cxx/tree/elements.txx b/libxsd/xsd/cxx/tree/elements.txx index 7389a86..4a8ca6e 100644 --- a/libxsd/xsd/cxx/tree/elements.txx +++ b/libxsd/xsd/cxx/tree/elements.txx @@ -27,8 +27,8 @@ namespace xsd // simple_type // - template - simple_type:: + template + simple_type:: simple_type (const simple_type& other, flags f, container* c) @@ -36,8 +36,8 @@ namespace xsd { } - template - simple_type* simple_type:: + template + simple_type* simple_type:: _clone (flags f, container* c) const { return new simple_type (*this, f, c); diff --git a/libxsd/xsd/cxx/tree/iterator-adapter.hxx b/libxsd/xsd/cxx/tree/iterator-adapter.hxx new file mode 100644 index 0000000..0a54604 --- /dev/null +++ b/libxsd/xsd/cxx/tree/iterator-adapter.hxx @@ -0,0 +1,270 @@ +// file : xsd/cxx/tree/iterator-adapter.hxx +// copyright : Copyright (c) 2005-2014 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSD_CXX_TREE_ITERATOR_ADAPTER_HXX +#define XSD_CXX_TREE_ITERATOR_ADAPTER_HXX + +#include // std::ptrdiff_t +#include // std::iterator_traits + +namespace xsd +{ + namespace cxx + { + namespace tree + { + // Sun CC's does not have iterator_traits. To overcome + // this, we will wrap std::iterator_traits into our own and also + // specialize it for pointer types. Since Sun CC uses pointer + // for vector::iterator, it will use the specialization and won't + // notice the std::iterator_traits. + // +#ifndef _RWSTD_NO_CLASS_PARTIAL_SPEC + template + struct iterator_traits + { + typedef + typename std::iterator_traits::iterator_category + iterator_category; + + typedef + typename std::iterator_traits::value_type + value_type; + + typedef + typename std::iterator_traits::difference_type + difference_type; + }; +#else + // The Pointer specialization does not work for reverse and + // set iterators. But these iterators are user-dfined types + // and have suitable typedefs that we can use. + // + template + struct iterator_traits + { + typedef typename I::iterator_category iterator_category; + typedef typename I::value_type value_type; + typedef typename I::difference_type difference_type; + }; + + template + struct iterator_traits + { + typedef std::random_access_iterator_tag iterator_category; + typedef T value_type; + typedef std::ptrdiff_t difference_type; + }; +#endif + + // Iterator adapter for complex types. It expects I to point to + // a smart pointer-like object that has operator*() that returns + // a refernce to a type static_cast'able to T and get() that + // returns a pointer to a type static_cast'able to T. + // + + template + struct iterator_adapter + { + typedef T value_type; + typedef value_type& reference; + typedef value_type* pointer; + + typedef + typename iterator_traits::iterator_category + iterator_category; + + typedef + typename iterator_traits::difference_type + difference_type; + + + public: + iterator_adapter () + : i_ () // i_ can be of a pointer type. + { + } + + // Allow iterator to const_iterator conversion. + // + template + iterator_adapter (const iterator_adapter& j) + : i_ (j.base ()) + { + } + + explicit + iterator_adapter (const I& i) + : i_ (i) + { + } + + public: + // Forward iterator requirements. + // + reference + operator* () const + { + return static_cast (**i_); + } + + pointer + operator-> () const + { + return static_cast (i_->get ()); + } + + iterator_adapter& + operator++ () + { + ++i_; + return *this; + } + + iterator_adapter + operator++ (int) + { + iterator_adapter r (*this); + ++i_; + return r; + } + + // Bidirectional iterator requirements. + // + iterator_adapter& + operator-- () + { + --i_; + return *this; + } + + iterator_adapter + operator-- (int) + { + iterator_adapter r (*this); + --i_; + return r; + } + + // Random access iterator requirements. + // + reference + operator[] (difference_type n) const + { + return static_cast (*(i_[n])); + } + + iterator_adapter& + operator+= (difference_type n) + { + i_ += n; + return *this; + } + + iterator_adapter + operator+ (difference_type n) const + { + return iterator_adapter (i_ + n); + } + + iterator_adapter& + operator-= (difference_type n) + { + i_ -= n; + return *this; + } + + iterator_adapter + operator- (difference_type n) const + { + return iterator_adapter (i_ - n); + } + + public: + const I& + base () const + { + return i_; + } + + private: + I i_; + }; + + // Note: We use different types for left- and right-hand-side + // arguments to allow comparison between iterator and const_iterator. + // + + // Forward iterator requirements. + // + template + inline bool + operator== (const iterator_adapter& i, + const iterator_adapter& j) + { + return i.base () == j.base (); + } + + template + inline bool + operator!= (const iterator_adapter& i, + const iterator_adapter& j) + { + return i.base () != j.base (); + } + + // Random access iterator requirements + // + template + inline bool + operator< (const iterator_adapter& i, + const iterator_adapter& j) + { + return i.base () < j.base (); + } + + template + inline bool + operator> (const iterator_adapter& i, + const iterator_adapter& j) + { + return i.base () > j.base (); + } + + template + inline bool + operator<= (const iterator_adapter& i, + const iterator_adapter& j) + { + return i.base () <= j.base (); + } + + template + inline bool + operator>= (const iterator_adapter& i, + const iterator_adapter& j) + { + return i.base () >= j.base (); + } + + template + inline typename iterator_adapter::difference_type + operator- (const iterator_adapter& i, + const iterator_adapter& j) + { + return i.base () - j.base (); + } + + template + inline iterator_adapter + operator+ (typename iterator_adapter::difference_type n, + const iterator_adapter& i) + { + return iterator_adapter (i.base () + n); + } + } + } +} + +#endif // XSD_CXX_TREE_ITERATOR_ADAPTER_HXX diff --git a/libxsd/xsd/cxx/tree/list.hxx b/libxsd/xsd/cxx/tree/list.hxx index 2b3b71e..d1fe907 100644 --- a/libxsd/xsd/cxx/tree/list.hxx +++ b/libxsd/xsd/cxx/tree/list.hxx @@ -10,7 +10,7 @@ #include #include -#include // tree::istream +#include #include // tree::istream #include // fundamental_p, sequence diff --git a/libxsd/xsd/cxx/tree/parsing.txx b/libxsd/xsd/cxx/tree/parsing.txx index 628b7fd..02aeda1 100644 --- a/libxsd/xsd/cxx/tree/parsing.txx +++ b/libxsd/xsd/cxx/tree/parsing.txx @@ -36,6 +36,9 @@ namespace xsd _type (const xercesc::DOMElement& e, flags f, container* c) : container_ (c) { + if (f & flags::extract_content) + content_.reset (new dom_content_type (e)); + if (f & flags::keep_dom) dom_info_ = dom_info_factory::create (e, *this, c == 0); } @@ -44,6 +47,8 @@ namespace xsd _type (const xercesc::DOMAttr& a, flags f, container* c) : container_ (c) { + // anyType cannot be an attribute type so no content extraction. + if (f & flags::keep_dom) dom_info_ = dom_info_factory::create (a, *this); } @@ -56,33 +61,41 @@ namespace xsd container* c) : container_ (c) // List elements don't have associated DOM nodes. { + // anyType cannot be a list element type so no content extraction. } // simple_type // - template - inline simple_type:: + template + inline simple_type:: simple_type (const xercesc::DOMElement& e, flags f, container* c) - : B (e, f, c) + : B (e, (f & ~flags::extract_content), c) { + if (f & flags::extract_content) + this->content_.reset ( + new text_content_type (tree::text_content (e))); } - template - inline simple_type:: + template + inline simple_type:: simple_type (const xercesc::DOMAttr& a, flags f, container* c) - : B (a, f, c) + : B (a, (f & ~flags::extract_content), c) { + if (f & flags::extract_content) + this->content_.reset (new text_content_type ( + xml::transcode (a.getValue ()))); } - template - template - inline simple_type:: + template + inline simple_type:: simple_type (const std::basic_string& s, const xercesc::DOMElement* e, flags f, container* c) - : B (s, e, f, c) + : B (s, e, (f & ~flags::extract_content), c) { + if (f & flags::extract_content) + this->content_.reset (new text_content_type (s)); } // fundamental_base @@ -161,7 +174,7 @@ namespace xsd } // Individual items of the list have no DOM association. Therefore - // I clear keep_dom from flags. + // we clear keep_dom from flags. // template @@ -203,7 +216,6 @@ namespace xsd return; using std::basic_string; - typedef typename sequence::ptr ptr; typedef typename basic_string::size_type size_type; const C* data (s.c_str ()); @@ -218,13 +230,12 @@ namespace xsd if (j != basic_string::npos) { - ptr r ( - new T (basic_string (data + i, j - i), - parent, - f, - this->container_)); - - this->v_.push_back (r); + this->push_back ( + traits::create ( + basic_string (data + i, j - i), + parent, + f, + this->container_)); i = bits::find_ns (data, size, j); } @@ -232,13 +243,12 @@ namespace xsd { // Last element. // - ptr r ( - new T (basic_string (data + i, size - i), - parent, - f, - this->container_)); - - this->v_.push_back (r); + this->push_back ( + traits::create ( + basic_string (data + i, size - i), + parent, + f, + this->container_)); break; } diff --git a/libxsd/xsd/cxx/tree/serialization.txx b/libxsd/xsd/cxx/tree/serialization.txx index e6fea1f..055f603 100644 --- a/libxsd/xsd/cxx/tree/serialization.txx +++ b/libxsd/xsd/cxx/tree/serialization.txx @@ -91,9 +91,29 @@ namespace xsd // Insertion operators for type. // inline void - operator<< (xercesc::DOMElement& e, const type&) + operator<< (xercesc::DOMElement& e, const type& x) { xml::dom::clear (e); + + if (!x.null_content () && x.dom_content ().present ()) + { + // Clone the contents of the element. + // + using namespace xercesc; + + DOMDocument& doc (*e.getOwnerDocument ()); + const DOMElement& se (x.dom_content ().get ()); + DOMNamedNodeMap& sa (*se.getAttributes ()); + + for (XMLSize_t i (0), n (sa.getLength ()); i != n; ++i) + e.setAttributeNode ( + static_cast (doc.importNode (sa.item (i), true))); + + for (DOMNode* sn (se.getFirstChild ()); + sn != 0; + sn = sn->getNextSibling ()) + e.appendChild (doc.importNode (sn, true)); + } } inline void @@ -109,23 +129,30 @@ namespace xsd // Insertion operators for simple_type. // - template + template inline void - operator<< (xercesc::DOMElement& e, const simple_type&) + operator<< (xercesc::DOMElement& e, const simple_type& x) { - xml::dom::clear (e); + if (x.null_content ()) + xml::dom::clear (e); + else + e << x.text_content (); } - template + template inline void - operator<< (xercesc::DOMAttr&, const simple_type&) + operator<< (xercesc::DOMAttr& a, const simple_type& x) { + if (!x.null_content ()) + a << x.text_content (); } template inline void - operator<< (list_stream&, const simple_type&) + operator<< (list_stream& ls, const simple_type& x) { + if (!x.null_content ()) + ls << x.text_content (); } // Insertion operators for list. diff --git a/libxsd/xsd/cxx/tree/std-ostream-map.txx b/libxsd/xsd/cxx/tree/std-ostream-map.txx index c79cdb6..ef65ef2 100644 --- a/libxsd/xsd/cxx/tree/std-ostream-map.txx +++ b/libxsd/xsd/cxx/tree/std-ostream-map.txx @@ -24,7 +24,7 @@ namespace xsd &inserter_impl, false); - typedef simple_type simple_type; + typedef simple_type simple_type; register_type ( typeid (simple_type), &inserter_impl, diff --git a/libxsd/xsd/cxx/tree/std-ostream-operators.hxx b/libxsd/xsd/cxx/tree/std-ostream-operators.hxx index 071d186..9a8f976 100644 --- a/libxsd/xsd/cxx/tree/std-ostream-operators.hxx +++ b/libxsd/xsd/cxx/tree/std-ostream-operators.hxx @@ -24,6 +24,7 @@ namespace xsd inline std::basic_ostream& operator<< (std::basic_ostream& os, const type&) { + // Not printing DOM content even if it's there. return os; } @@ -32,8 +33,11 @@ namespace xsd // template inline std::basic_ostream& - operator<< (std::basic_ostream& os, const simple_type&) + operator<< (std::basic_ostream& os, const simple_type& x) { + if (!x.null_content ()) + os << x.text_content (); + return os; } diff --git a/libxsd/xsd/cxx/tree/stream-extraction-map.txx b/libxsd/xsd/cxx/tree/stream-extraction-map.txx index 646ef83..61dd306 100644 --- a/libxsd/xsd/cxx/tree/stream-extraction-map.txx +++ b/libxsd/xsd/cxx/tree/stream-extraction-map.txx @@ -30,7 +30,7 @@ namespace xsd &extractor_impl, false); - typedef simple_type simple_type; + typedef simple_type simple_type; register_type ( qualified_name (bits::any_simple_type (), xsd), &extractor_impl, diff --git a/libxsd/xsd/cxx/tree/stream-extraction.hxx b/libxsd/xsd/cxx/tree/stream-extraction.hxx index b55afa0..ee39bcc 100644 --- a/libxsd/xsd/cxx/tree/stream-extraction.hxx +++ b/libxsd/xsd/cxx/tree/stream-extraction.hxx @@ -28,12 +28,18 @@ namespace xsd // simple_type // - template + template template - inline simple_type:: + inline simple_type:: simple_type (istream& s, flags f, container* c) - : type (s, f, c) + : type (s, f & ~flags::extract_content, c) { + if (f & flags::extract_content) + { + std::basic_string t; + s >> t; + this->content_.reset (new text_content_type (t)); + } } // fundamental_base @@ -65,9 +71,7 @@ namespace xsd this->reserve (size); while (size--) - { - this->push_back (XSD_AUTO_PTR (new T (s, f, c))); - } + this->push_back (traits::create (s, f, c)); } } diff --git a/libxsd/xsd/cxx/tree/stream-insertion-map.txx b/libxsd/xsd/cxx/tree/stream-insertion-map.txx index 1550826..78fbacb 100644 --- a/libxsd/xsd/cxx/tree/stream-insertion-map.txx +++ b/libxsd/xsd/cxx/tree/stream-insertion-map.txx @@ -31,7 +31,7 @@ namespace xsd &inserter_impl, false); - typedef simple_type simple_type; + typedef simple_type simple_type; register_type ( typeid (simple_type), qualified_name (bits::any_simple_type (), xsd), diff --git a/libxsd/xsd/cxx/tree/stream-insertion.hxx b/libxsd/xsd/cxx/tree/stream-insertion.hxx index 7f1f5df..b04846f 100644 --- a/libxsd/xsd/cxx/tree/stream-insertion.hxx +++ b/libxsd/xsd/cxx/tree/stream-insertion.hxx @@ -23,15 +23,19 @@ namespace xsd inline ostream& operator<< (ostream& s, const type&) { + // Not saving DOM content even if it's there. return s; } // simple_type // - template + template inline ostream& - operator<< (ostream& s, const simple_type&) + operator<< (ostream& s, const simple_type& x) { + if (!x.null_content ()) + s << x.text_content (); + return s; } diff --git a/libxsd/xsd/cxx/tree/type-factory-map.txx b/libxsd/xsd/cxx/tree/type-factory-map.txx index 8ccbc63..e1fe0cc 100644 --- a/libxsd/xsd/cxx/tree/type-factory-map.txx +++ b/libxsd/xsd/cxx/tree/type-factory-map.txx @@ -37,7 +37,7 @@ namespace xsd &factory_impl, false); - typedef simple_type simple_type; + typedef simple_type simple_type; register_type ( qualified_name (bits::any_simple_type (), xsd), &factory_impl, diff --git a/libxsd/xsd/cxx/tree/type-serializer-map.txx b/libxsd/xsd/cxx/tree/type-serializer-map.txx index 353ccae..dd47a00 100644 --- a/libxsd/xsd/cxx/tree/type-serializer-map.txx +++ b/libxsd/xsd/cxx/tree/type-serializer-map.txx @@ -38,7 +38,7 @@ namespace xsd &serializer_impl, false); - typedef simple_type simple_type; + typedef simple_type simple_type; register_type ( typeid (simple_type), qualified_name (bits::any_simple_type (), xsd), diff --git a/libxsd/xsd/cxx/tree/types.hxx b/libxsd/xsd/cxx/tree/types.hxx index 61a1e1a..288a291 100644 --- a/libxsd/xsd/cxx/tree/types.hxx +++ b/libxsd/xsd/cxx/tree/types.hxx @@ -271,6 +271,29 @@ namespace xsd } }; + /** + * @brief %string comparison operator. + * + * @return True if the strings are equal, false otherwise. + */ + template + inline bool + operator== (const string& a, const string& b) + { + return static_cast&> (a) == b; + } + + /** + * @brief %string comparison operator. + * + * @return True if the strings are not equal, false otherwise. + */ + template + inline bool + operator!= (const string& a, const string& b) + { + return !(a == b); + } /** * @brief Class corresponding to the XML Schema normalizedString @@ -1119,6 +1142,31 @@ namespace xsd //@} }; + /** + * @brief %nmtokens comparison operator. + * + * @return True if the lists of nmtokens are equal, false otherwise. + */ + template + inline bool + operator== (const nmtokens& a, + const nmtokens& b) + { + return static_cast&> (a) == b; + } + + /** + * @brief %nmtokens comparison operator. + * + * @return True if the lists of nmtokens are not equal, false otherwise. + */ + template + inline bool + operator!= (const nmtokens& a, + const nmtokens& b) + { + return !(a == b); + } /** * @brief Class corresponding to the XML Schema Name built-in @@ -2575,6 +2623,29 @@ namespace xsd //@} }; + /** + * @brief %idrefs comparison operator. + * + * @return True if the lists of idrefs are equal, false otherwise. + */ + template + inline bool + operator== (const idrefs& a, const idrefs& b) + { + return static_cast&> (a) == b; + } + + /** + * @brief %idrefs comparison operator. + * + * @return True if the lists of idrefs are not equal, false otherwise. + */ + template + inline bool + operator!= (const idrefs& a, const idrefs& b) + { + return !(a == b); + } /** * @brief Class corresponding to the XML Schema anyURI built-in @@ -2811,6 +2882,29 @@ namespace xsd friend class qname; }; + /** + * @brief %uri comparison operator. + * + * @return True if the uris are equal, false otherwise. + */ + template + inline bool + operator== (const uri& a, const uri& b) + { + return static_cast&> (a) == b; + } + + /** + * @brief %uri comparison operator. + * + * @return True if the uris are not equal, false otherwise. + */ + template + inline bool + operator!= (const uri& a, const uri& b) + { + return !(a == b); + } /** * @brief Class corresponding to the XML Schema QName built-in @@ -3211,6 +3305,29 @@ namespace xsd decode (const XMLCh*); }; + /** + * @brief %base64_binary comparison operator. + * + * @return True if the binaries are equal, false otherwise. + */ + template + inline bool + operator== (const base64_binary& a, const base64_binary& b) + { + return static_cast&> (a) == b; + } + + /** + * @brief %base64_binary comparison operator. + * + * @return True if the binaries are not equal, false otherwise. + */ + template + inline bool + operator!= (const base64_binary& a, const base64_binary& b) + { + return !(a == b); + } /** * @brief Class corresponding to the XML Schema hexBinary @@ -3404,6 +3521,29 @@ namespace xsd decode (const XMLCh*); }; + /** + * @brief %hex_binary comparison operator. + * + * @return True if the binaries are equal, false otherwise. + */ + template + inline bool + operator== (const hex_binary& a, const hex_binary& b) + { + return static_cast&> (a) == b; + } + + /** + * @brief %hex_binary comparison operator. + * + * @return True if the binaries are not equal, false otherwise. + */ + template + inline bool + operator!= (const hex_binary& a, const hex_binary& b) + { + return !(a == b); + } /** * @brief Class corresponding to the XML Schema ENTITY built-in @@ -3768,6 +3908,32 @@ namespace xsd container* c = 0); //@} }; + + /** + * @brief %entities comparison operator. + * + * @return True if the lists of entities are equal, false otherwise. + */ + template + inline bool + operator== (const entities& a, + const entities& b) + { + return static_cast&> (a) == b; + } + + /** + * @brief %entities comparison operator. + * + * @return True if the lists of entities are not equal, false otherwise. + */ + template + inline bool + operator!= (const entities& a, + const entities& b) + { + return !(a == b); + } } } } diff --git a/libxsd/xsd/cxx/xml/string.hxx b/libxsd/xsd/cxx/xml/string.hxx index dbc78b4..9f4767b 100644 --- a/libxsd/xsd/cxx/xml/string.hxx +++ b/libxsd/xsd/cxx/xml/string.hxx @@ -56,21 +56,16 @@ namespace xsd public : template string (const std::basic_string& s) - : s_ (transcode_to_xmlch (s)) - { - } + : s_ (transcode_to_xmlch (s)) {} template - string (const C* s) - : s_ (transcode_to_xmlch (s)) - { - } + string (const C* s): s_ (transcode_to_xmlch (s)) {} const XMLCh* - c_str () const - { - return s_.get (); - } + c_str () const {return s_.get ();} + + XMLCh* + release () {return s_.release ();} private: string (const string&); -- cgit v1.1