From 4332a60585a14ff51bc54d29a4a81d37b3b1df81 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Sun, 28 Mar 2010 16:53:35 +0200 Subject: Validate enumerations in the xsd:string parser/serializer --- .../xsde/cxx/parser/validating/string-common.cxx | 61 ++++++++++++ .../xsde/cxx/parser/validating/string-common.hxx | 32 +++++++ libxsde/xsde/cxx/parser/validating/string-stl.cxx | 24 +---- libxsde/xsde/cxx/parser/validating/string.cxx | 24 +---- .../cxx/parser/validating/xml-schema-pskel.hxx | 67 +++++++------ .../cxx/parser/validating/xml-schema-pskel.ixx | 52 +++++++---- libxsde/xsde/cxx/schema-error.cxx | 1 + libxsde/xsde/cxx/schema-error.hxx | 1 + .../cxx/serializer/validating/string-common.cxx | 69 ++++++++++++++ .../cxx/serializer/validating/string-common.hxx | 35 +++++++ .../xsde/cxx/serializer/validating/string-stl.cxx | 24 +---- libxsde/xsde/cxx/serializer/validating/string.cxx | 28 +----- .../cxx/serializer/validating/xml-schema-sskel.hxx | 67 +++++++------ .../cxx/serializer/validating/xml-schema-sskel.ixx | 50 ++++++---- libxsde/xsde/makefile | 2 + xsde/cxx/parser/elements.hxx | 102 ++++++++++++++++++++ xsde/cxx/parser/parser-header.cxx | 38 +++++++- xsde/cxx/parser/parser-inline.cxx | 56 +++++++++-- xsde/cxx/parser/parser-source.cxx | 31 +++++- xsde/cxx/serializer/elements.hxx | 104 +++++++++++++++++++++ xsde/cxx/serializer/serializer-header.cxx | 41 ++++++-- xsde/cxx/serializer/serializer-inline.cxx | 56 +++++++++-- xsde/cxx/serializer/serializer-source.cxx | 29 ++++++ 23 files changed, 779 insertions(+), 215 deletions(-) create mode 100644 libxsde/xsde/cxx/parser/validating/string-common.cxx create mode 100644 libxsde/xsde/cxx/parser/validating/string-common.hxx create mode 100644 libxsde/xsde/cxx/serializer/validating/string-common.cxx create mode 100644 libxsde/xsde/cxx/serializer/validating/string-common.hxx diff --git a/libxsde/xsde/cxx/parser/validating/string-common.cxx b/libxsde/xsde/cxx/parser/validating/string-common.cxx new file mode 100644 index 0000000..15956f6 --- /dev/null +++ b/libxsde/xsde/cxx/parser/validating/string-common.cxx @@ -0,0 +1,61 @@ +// file : xsde/cxx/parser/validating/string-common.cxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#include // strcmp +#include + +namespace xsde +{ + namespace cxx + { + namespace parser + { + namespace validating + { + void string_common:: + validate_facets (const char* s, + size_t n, + const string_facets::facets& f, + context& ctx) + { + if (f.length_set_ && n != f.length_) + { + ctx.schema_error (schema_error::length_not_equal_prescribed); + return; + } + + if (f.min_length_set_ && n < f.min_length_) + { + ctx.schema_error (schema_error::length_less_than_min); + return; + } + + if (f.max_length_set_ && n > f.max_length_) + { + ctx.schema_error (schema_error::length_greater_than_max); + return; + } + + if (f.enum_count_ != 0) + { + size_t i = 0; + + for (; i < f.enum_count_; ++i) + { + if (strcmp (s, f.enum_[i]) == 0) + break; + } + + if (i == f.enum_count_) + { + ctx.schema_error (schema_error::value_not_in_enumeration); + return; + } + } + } + } + } + } +} diff --git a/libxsde/xsde/cxx/parser/validating/string-common.hxx b/libxsde/xsde/cxx/parser/validating/string-common.hxx new file mode 100644 index 0000000..52ea0c5 --- /dev/null +++ b/libxsde/xsde/cxx/parser/validating/string-common.hxx @@ -0,0 +1,32 @@ +// file : xsde/cxx/parser/validating/string-common.hxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSDE_CXX_PARSER_VALIDATING_STRING_COMMON_HXX +#define XSDE_CXX_PARSER_VALIDATING_STRING_COMMON_HXX + +#include + +namespace xsde +{ + namespace cxx + { + namespace parser + { + namespace validating + { + struct string_common + { + static void + validate_facets (const char* s, + size_t n, + const string_facets::facets&, + context&); + }; + } + } + } +} + +#endif // XSDE_CXX_PARSER_VALIDATING_STRING_COMMON_HXX diff --git a/libxsde/xsde/cxx/parser/validating/string-stl.cxx b/libxsde/xsde/cxx/parser/validating/string-stl.cxx index d0d0e14..9e1ad13 100644 --- a/libxsde/xsde/cxx/parser/validating/string-stl.cxx +++ b/libxsde/xsde/cxx/parser/validating/string-stl.cxx @@ -4,6 +4,7 @@ // license : GNU GPL v2 + exceptions; see accompanying LICENSE file #include +#include namespace xsde { @@ -28,27 +29,8 @@ namespace xsde void string_pimpl:: _post () { - // Check facets. - // - const facets& f = _facets (); - - if (f.length_set_ && str_.size () != f.length_) - { - _schema_error (schema_error::length_not_equal_prescribed); - return; - } - - if (f.min_length_set_ && str_.size () < f.min_length_) - { - _schema_error (schema_error::length_less_than_min); - return; - } - - if (f.max_length_set_ && str_.size () > f.max_length_) - { - _schema_error (schema_error::length_greater_than_max); - return; - } + string_common::validate_facets ( + str_.c_str (), str_.size (), _facets (), _context ()); } std::string string_pimpl:: diff --git a/libxsde/xsde/cxx/parser/validating/string.cxx b/libxsde/xsde/cxx/parser/validating/string.cxx index c40a7c9..3e29a93 100644 --- a/libxsde/xsde/cxx/parser/validating/string.cxx +++ b/libxsde/xsde/cxx/parser/validating/string.cxx @@ -6,6 +6,7 @@ #include #include +#include namespace xsde { @@ -40,27 +41,8 @@ namespace xsde void string_pimpl:: _post () { - // Check facets. - // - const facets& f = _facets (); - - if (f.length_set_ && str_.size () != f.length_) - { - _schema_error (schema_error::length_not_equal_prescribed); - return; - } - - if (f.min_length_set_ && str_.size () < f.min_length_) - { - _schema_error (schema_error::length_less_than_min); - return; - } - - if (f.max_length_set_ && str_.size () > f.max_length_) - { - _schema_error (schema_error::length_greater_than_max); - return; - } + string_common::validate_facets ( + str_.data (), str_.size (), _facets (), _context ()); } char* string_pimpl:: diff --git a/libxsde/xsde/cxx/parser/validating/xml-schema-pskel.hxx b/libxsde/xsde/cxx/parser/validating/xml-schema-pskel.hxx index 1e05778..ed0ff4f 100644 --- a/libxsde/xsde/cxx/parser/validating/xml-schema-pskel.hxx +++ b/libxsde/xsde/cxx/parser/validating/xml-schema-pskel.hxx @@ -653,10 +653,47 @@ namespace xsde }; + // // String-based types. If STL is disabled you are getting a C // string that you have to delete with delete[]. // - struct string_pskel: simple_content + + struct string_facets + { + string_facets (); + + void + _length_facet (size_t); + + void + _max_length_facet (size_t); + + void + _min_length_facet (size_t); + + void + _enumeration_facet (const char* const*, size_t count); + + public: + struct facets + { + size_t length_; + size_t min_length_; + size_t max_length_; + + const char* const* enum_; + size_t enum_count_; + + unsigned int length_set_ : 1; + unsigned int min_length_set_ : 1; + unsigned int max_length_set_ : 1; + }; + + protected: + facets facets_; + }; + + struct string_pskel: simple_content, string_facets { #ifdef XSDE_STL virtual std::string @@ -673,9 +710,8 @@ namespace xsde _dynamic_type () const; #endif - string_pskel (); - #ifdef XSDE_REUSE_STYLE_TIEIN + string_pskel (); string_pskel (string_pskel* impl, void*); protected: @@ -683,33 +719,8 @@ namespace xsde #endif // Facets. // - public: - void - _length_facet (size_t); - - void - _max_length_facet (size_t); - - void - _min_length_facet (size_t); - - protected: - struct facets - { - size_t length_; - size_t min_length_; - size_t max_length_; - - unsigned int length_set_ : 1; - unsigned int min_length_set_ : 1; - unsigned int max_length_set_ : 1; - }; - const facets& _facets () const; - - private: - facets facets_; }; struct normalized_string_pskel: simple_content diff --git a/libxsde/xsde/cxx/parser/validating/xml-schema-pskel.ixx b/libxsde/xsde/cxx/parser/validating/xml-schema-pskel.ixx index 3d69e15..c08fb09 100644 --- a/libxsde/xsde/cxx/parser/validating/xml-schema-pskel.ixx +++ b/libxsde/xsde/cxx/parser/validating/xml-schema-pskel.ixx @@ -446,51 +446,63 @@ namespace xsde } #endif - // string_pskel + // string_facets // - inline string_pskel:: - string_pskel () + inline string_facets:: + string_facets () { -#ifdef XSDE_REUSE_STYLE_TIEIN - string_impl_ = 0; -#endif facets_.length_set_ = 0; facets_.min_length_set_ = 0; facets_.max_length_set_ = 0; - } -#ifdef XSDE_REUSE_STYLE_TIEIN - inline string_pskel:: - string_pskel (string_pskel* impl, void*) - : simple_content (impl, 0), string_impl_ (impl) - { - facets_.length_set_ = 0; - facets_.min_length_set_ = 0; - facets_.max_length_set_ = 0; + facets_.enum_ = 0; + facets_.enum_count_ = 0; } -#endif - inline void string_pskel:: + inline void string_facets:: _length_facet (size_t v) { facets_.length_ = v; facets_.length_set_ = 1; } - inline void string_pskel:: + inline void string_facets:: _max_length_facet (size_t v) { facets_.max_length_ = v; facets_.max_length_set_ = 1; } - inline void string_pskel:: + inline void string_facets:: _min_length_facet (size_t v) { facets_.min_length_ = v; facets_.min_length_set_ = 1; } + inline void string_facets:: + _enumeration_facet (const char* const* e, size_t count) + { + facets_.enum_ = e; + facets_.enum_count_ = count; + } + + // string_pskel + // +#ifdef XSDE_REUSE_STYLE_TIEIN + inline string_pskel:: + string_pskel () + : string_impl_ (0) + { + } + + inline string_pskel:: + string_pskel (string_pskel* impl, void*) + : simple_content (impl, 0), string_impl_ (impl) + { + } +#endif + inline const string_pskel::facets& string_pskel:: _facets () const { @@ -499,7 +511,7 @@ namespace xsde return static_cast (*parent_).facets_; else #endif - return facets_; + return facets_; } // normalized_string_pskel diff --git a/libxsde/xsde/cxx/schema-error.cxx b/libxsde/xsde/cxx/schema-error.cxx index c347fa1..a37ea28 100644 --- a/libxsde/xsde/cxx/schema-error.cxx +++ b/libxsde/xsde/cxx/schema-error.cxx @@ -58,6 +58,7 @@ namespace xsde "invalid duration value", "value is greater than maximum allowed", "value is less than minimum allowed", + "value is not in enumeration", "length is greater than maximum allowed", "length is less than minimum allowed", "length is not equal to prescribed length", diff --git a/libxsde/xsde/cxx/schema-error.hxx b/libxsde/xsde/cxx/schema-error.hxx index 8569e49..f442bf6 100644 --- a/libxsde/xsde/cxx/schema-error.hxx +++ b/libxsde/xsde/cxx/schema-error.hxx @@ -61,6 +61,7 @@ namespace xsde invalid_duration_value, value_greater_than_max, value_less_than_min, + value_not_in_enumeration, length_greater_than_max, length_less_than_min, length_not_equal_prescribed, diff --git a/libxsde/xsde/cxx/serializer/validating/string-common.cxx b/libxsde/xsde/cxx/serializer/validating/string-common.cxx new file mode 100644 index 0000000..20a1b34 --- /dev/null +++ b/libxsde/xsde/cxx/serializer/validating/string-common.cxx @@ -0,0 +1,69 @@ +// file : xsde/cxx/serializer/validating/string-common.cxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#include // strlen, strcmp +#include + +namespace xsde +{ + namespace cxx + { + namespace serializer + { + namespace validating + { + void string_common:: + validate_facets (const char* s, +#ifdef XSDE_STL + size_t n, +#endif + const string_facets::facets& f, + context& ctx) + { +#ifndef XSDE_STL + size_t n; + if (f.length_set_ || f.min_length_set_ || f.max_length_set_) + n = strlen (s); +#endif + + if (f.length_set_ && n != f.length_) + { + ctx.schema_error (schema_error::length_not_equal_prescribed); + return; + } + + if (f.min_length_set_ && n < f.min_length_) + { + ctx.schema_error (schema_error::length_less_than_min); + return; + } + + if (f.max_length_set_ && n > f.max_length_) + { + ctx.schema_error (schema_error::length_greater_than_max); + return; + } + + if (f.enum_count_ != 0) + { + size_t i = 0; + + for (; i < f.enum_count_; ++i) + { + if (strcmp (s, f.enum_[i]) == 0) + break; + } + + if (i == f.enum_count_) + { + ctx.schema_error (schema_error::value_not_in_enumeration); + return; + } + } + } + } + } + } +} diff --git a/libxsde/xsde/cxx/serializer/validating/string-common.hxx b/libxsde/xsde/cxx/serializer/validating/string-common.hxx new file mode 100644 index 0000000..d7f221d --- /dev/null +++ b/libxsde/xsde/cxx/serializer/validating/string-common.hxx @@ -0,0 +1,35 @@ +// file : xsde/cxx/serializer/validating/string-common.hxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSDE_CXX_SERIALIZER_VALIDATING_STRING_COMMON_HXX +#define XSDE_CXX_SERIALIZER_VALIDATING_STRING_COMMON_HXX + +#include +#include + +namespace xsde +{ + namespace cxx + { + namespace serializer + { + namespace validating + { + struct string_common + { + static void + validate_facets (const char* s, +#ifdef XSDE_STL + size_t n, +#endif + const string_facets::facets&, + context&); + }; + } + } + } +} + +#endif // XSDE_CXX_SERIALIZER_VALIDATING_STRING_COMMON_HXX diff --git a/libxsde/xsde/cxx/serializer/validating/string-stl.cxx b/libxsde/xsde/cxx/serializer/validating/string-stl.cxx index 1e9a37b..ef13746 100644 --- a/libxsde/xsde/cxx/serializer/validating/string-stl.cxx +++ b/libxsde/xsde/cxx/serializer/validating/string-stl.cxx @@ -4,6 +4,7 @@ // license : GNU GPL v2 + exceptions; see accompanying LICENSE file #include +#include namespace xsde { @@ -22,27 +23,8 @@ namespace xsde void string_simpl:: _serialize_content () { - // Check facets. - // - const facets& f = _facets (); - - if (f.length_set_ && value_.size () != f.length_) - { - _schema_error (schema_error::length_not_equal_prescribed); - return; - } - - if (f.min_length_set_ && value_.size () < f.min_length_) - { - _schema_error (schema_error::length_less_than_min); - return; - } - - if (f.max_length_set_ && value_.size () > f.max_length_) - { - _schema_error (schema_error::length_greater_than_max); - return; - } + string_common::validate_facets ( + value_.c_str (), value_.size (), _facets (), _context ()); // Make sure we don't hold any references to the string. // diff --git a/libxsde/xsde/cxx/serializer/validating/string.cxx b/libxsde/xsde/cxx/serializer/validating/string.cxx index 0def094..befe450 100644 --- a/libxsde/xsde/cxx/serializer/validating/string.cxx +++ b/libxsde/xsde/cxx/serializer/validating/string.cxx @@ -3,8 +3,8 @@ // copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC // license : GNU GPL v2 + exceptions; see accompanying LICENSE file -#include // strlen #include +#include namespace xsde { @@ -30,31 +30,7 @@ namespace xsde void string_simpl:: _serialize_content () { - // Check facets. - // - if (length_set_ || min_length_set_ || max_length_set_) - { - size_t n = strlen (value_); - const facets& f = _facets (); - - if (f.length_set_ && n != f.length_) - { - _schema_error (schema_error::length_not_equal_prescribed); - return; - } - - if (f.min_length_set_ && n < f.min_length_) - { - _schema_error (schema_error::length_less_than_min); - return; - } - - if (f.max_length_set_ && n > f.max_length_) - { - _schema_error (schema_error::length_greater_than_max); - return; - } - } + string_common::validate_facets (value_, _facets (), _context ()); _characters (value_); diff --git a/libxsde/xsde/cxx/serializer/validating/xml-schema-sskel.hxx b/libxsde/xsde/cxx/serializer/validating/xml-schema-sskel.hxx index 940f256..c206e78 100644 --- a/libxsde/xsde/cxx/serializer/validating/xml-schema-sskel.hxx +++ b/libxsde/xsde/cxx/serializer/validating/xml-schema-sskel.hxx @@ -636,9 +636,46 @@ namespace xsde #endif }; + // // String-based types. // - struct string_sskel: simple_content + + struct string_facets + { + string_facets (); + + void + _length_facet (size_t); + + void + _max_length_facet (size_t); + + void + _min_length_facet (size_t); + + void + _enumeration_facet (const char* const*, size_t count); + + public: + struct facets + { + size_t length_; + size_t min_length_; + size_t max_length_; + + const char* const* enum_; + size_t enum_count_; + + unsigned int length_set_ : 1; + unsigned int min_length_set_ : 1; + unsigned int max_length_set_ : 1; + }; + + protected: + facets facets_; + }; + + struct string_sskel: simple_content, string_facets { virtual void #ifdef XSDE_STL @@ -655,9 +692,8 @@ namespace xsde _dynamic_type () const; #endif - string_sskel (); - #ifdef XSDE_REUSE_STYLE_TIEIN + string_sskel (); string_sskel (string_sskel* impl, void*); protected: @@ -665,33 +701,8 @@ namespace xsde #endif // Facets. // - public: - void - _length_facet (size_t); - - void - _max_length_facet (size_t); - - void - _min_length_facet (size_t); - - protected: - struct facets - { - size_t length_; - size_t min_length_; - size_t max_length_; - - unsigned int length_set_ : 1; - unsigned int min_length_set_ : 1; - unsigned int max_length_set_ : 1; - }; - const facets& _facets () const; - - private: - facets facets_; }; #ifdef XSDE_REUSE_STYLE_MIXIN diff --git a/libxsde/xsde/cxx/serializer/validating/xml-schema-sskel.ixx b/libxsde/xsde/cxx/serializer/validating/xml-schema-sskel.ixx index fd84bf0..b2eb40f 100644 --- a/libxsde/xsde/cxx/serializer/validating/xml-schema-sskel.ixx +++ b/libxsde/xsde/cxx/serializer/validating/xml-schema-sskel.ixx @@ -447,51 +447,63 @@ namespace xsde } #endif - // string_sskel + // string_facets // - inline string_sskel:: - string_sskel () + inline string_facets:: + string_facets () { -#ifdef XSDE_REUSE_STYLE_TIEIN - string_impl_ = 0; -#endif facets_.length_set_ = 0; facets_.min_length_set_ = 0; facets_.max_length_set_ = 0; - } -#ifdef XSDE_REUSE_STYLE_TIEIN - inline string_sskel:: - string_sskel (string_sskel* impl, void*) - : simple_content (impl, 0), string_impl_ (impl) - { - facets_.length_set_ = 0; - facets_.min_length_set_ = 0; - facets_.max_length_set_ = 0; + facets_.enum_ = 0; + facets_.enum_count_ = 0; } -#endif - inline void string_sskel:: + inline void string_facets:: _length_facet (size_t v) { facets_.length_ = v; facets_.length_set_ = 1; } - inline void string_sskel:: + inline void string_facets:: _max_length_facet (size_t v) { facets_.max_length_ = v; facets_.max_length_set_ = 1; } - inline void string_sskel:: + inline void string_facets:: _min_length_facet (size_t v) { facets_.min_length_ = v; facets_.min_length_set_ = 1; } + inline void string_facets:: + _enumeration_facet (const char* const* e, size_t count) + { + facets_.enum_ = e; + facets_.enum_count_ = count; + } + + // string_sskel + // +#ifdef XSDE_REUSE_STYLE_TIEIN + inline string_sskel:: + string_sskel () + : string_impl_ (0) + { + } + + inline string_sskel:: + string_sskel (string_sskel* impl, void*) + : simple_content (impl, 0), string_impl_ (impl) + { + } +#endif + inline const string_sskel::facets& string_sskel:: _facets () const { diff --git a/libxsde/xsde/makefile b/libxsde/xsde/makefile index 3a0465c..fc1355d 100644 --- a/libxsde/xsde/makefile +++ b/libxsde/xsde/makefile @@ -103,6 +103,7 @@ ifeq ($(xsde_parser_validation),y) cxx_tun += \ cxx/parser/validating/parser.cxx \ cxx/parser/validating/time-zone.cxx \ +cxx/parser/validating/string-common.cxx \ cxx/parser/validating/xml-schema-pskel.cxx ifeq ($(xsde_polymorphic),y) @@ -296,6 +297,7 @@ ifeq ($(xsde_serializer_validation),y) cxx_tun += \ cxx/serializer/validating/serializer.cxx \ cxx/serializer/validating/time-zone.cxx \ +cxx/serializer/validating/string-common.cxx \ cxx/serializer/validating/xml-schema-sskel.cxx ifeq ($(xsde_polymorphic),y) diff --git a/xsde/cxx/parser/elements.hxx b/xsde/cxx/parser/elements.hxx index 954b13b..f603400 100644 --- a/xsde/cxx/parser/elements.hxx +++ b/xsde/cxx/parser/elements.hxx @@ -191,6 +191,108 @@ namespace CXX String parser_map_; }; + // Check whether this is a string-based type (including ID, IDFER, + // anyURI, and ENTITY). + // + struct StringBasedType: Traversal::Complex, + Traversal::Fundamental::String, + Traversal::Fundamental::NormalizedString, + Traversal::Fundamental::Token, + Traversal::Fundamental::Name, + Traversal::Fundamental::NameToken, + Traversal::Fundamental::NCName, + Traversal::Fundamental::Language, + Traversal::Fundamental::Id, + Traversal::Fundamental::IdRef, + Traversal::Fundamental::AnyURI, + Traversal::Fundamental::Entity + + { + StringBasedType (Boolean& r) + : r_ (r) + { + *this >> inherits_ >> *this; + } + + virtual Void + traverse (SemanticGraph::Complex& c) + { + inherits (c, inherits_); + } + + // Strings. + // + virtual Void + traverse (SemanticGraph::Fundamental::String&) + { + r_ = true; + } + + virtual Void + traverse (SemanticGraph::Fundamental::NormalizedString&) + { + r_ = true; + } + + virtual Void + traverse (SemanticGraph::Fundamental::Token&) + { + r_ = true; + } + + virtual Void + traverse (SemanticGraph::Fundamental::NameToken&) + { + r_ = true; + } + + virtual Void + traverse (SemanticGraph::Fundamental::Name&) + { + r_ = true; + } + + virtual Void + traverse (SemanticGraph::Fundamental::NCName&) + { + r_ = true; + } + + virtual Void + traverse (SemanticGraph::Fundamental::Language&) + { + r_ = true; + } + + virtual Void + traverse (SemanticGraph::Fundamental::Id&) + { + r_ = true; + } + + virtual Void + traverse (SemanticGraph::Fundamental::IdRef&) + { + r_ = true; + } + + virtual Void + traverse (SemanticGraph::Fundamental::AnyURI&) + { + r_ = true; + } + + virtual Void + traverse (SemanticGraph::Fundamental::Entity&) + { + r_ = true; + } + + private: + Boolean& r_; + Traversal::Inherits inherits_; + }; + // // struct RequiredAttributeTest: Traversal::Attribute diff --git a/xsde/cxx/parser/parser-header.cxx b/xsde/cxx/parser/parser-header.cxx index 34f2119..5bc9cb7 100644 --- a/xsde/cxx/parser/parser-header.cxx +++ b/xsde/cxx/parser/parser-header.cxx @@ -28,6 +28,13 @@ namespace CXX SemanticGraph::Type& base (e.inherits ().base ()); String fq_base (fq_name (base)); + Boolean facets (false); // Whether we need to set facets. + if (validation) + { + StringBasedType t (facets); + t.dispatch (e); + } + os << "class " << name << ": public " << (mixin ? "virtual " : "") << fq_base << "{" @@ -60,15 +67,22 @@ namespace CXX << "_dynamic_type () const;"; } - if (tiein) + if (facets || tiein) { os << endl << "// Constructor." << endl - << "//" << endl - << name << " (" << fq_base << "* tiein);" - << endl; + << "//" << endl; - os << "// Implementation details." << endl + if (tiein) + os << name << " (" << fq_base << "* tiein);"; + else + os << name << " ();"; + } + + if (tiein) + { + os << endl + << "// Implementation details." << endl << "//" << endl; // If our base has pure virtual post, override it here. @@ -87,6 +101,20 @@ namespace CXX << name << " (" << name << "*, void*);"; } + if (facets) + { + UnsignedLong enum_count (0); + + for (Type::NamesIterator i (e.names_begin ()), end (e.names_end ()); + i != end; ++i) + ++enum_count; + + os << endl + << "protected:" << endl + << "static const char* const _xsde_" << name << "_enums_[" << + enum_count << "UL];"; + } + os << "};"; } }; diff --git a/xsde/cxx/parser/parser-inline.cxx b/xsde/cxx/parser/parser-inline.cxx index def8434..528ff86 100644 --- a/xsde/cxx/parser/parser-inline.cxx +++ b/xsde/cxx/parser/parser-inline.cxx @@ -24,9 +24,41 @@ namespace CXX virtual Void traverse (Type& e) { + String const& name (ename (e)); + + Boolean facets (false); // Whether we need to set facets. + if (validation) + { + StringBasedType t (facets); + t.dispatch (e); + } + + UnsignedLong enum_count (0); + if (facets) + { + for (Type::NamesIterator i (e.names_begin ()), end (e.names_end ()); + i != end; ++i) + ++enum_count; + } + + if (facets || tiein) + os << "// " << name << endl + << "//" << endl + << endl; + + if (facets && !tiein) + { + os << inl + << name << "::" << endl + << name << " ()" << endl + << "{" + << "this->_enumeration_facet (_xsde_" << name << "_enums_, " << + enum_count << "UL);" + << "}"; + } + if (tiein) { - String const& name (ename (e)); String const& impl (etiein (e)); // We have to use "real" (non-typedef) base name in base @@ -36,25 +68,31 @@ namespace CXX String fq_base (fq_name (base)); String real_fq_base (real_fq_name (base)); - os << "// " << name << endl - << "//" << endl - << endl; - os << inl << name << "::" << endl << name << " (" << fq_base << "* tiein)" << endl << ": " << real_fq_base << " (tiein, 0)," << endl << " " << impl << " (0)" - << "{" - << "}"; + << "{"; + + if (facets) + os << "this->_enumeration_facet (_xsde_" << name << + "_enums_, " << enum_count << "UL);"; + + os << "}"; os << inl << name << "::" << endl << name << " (" << name << "* impl, void*)" << endl << ": " << real_fq_base << " (impl, 0)," << endl << " " << impl << " (impl)" - << "{" - << "}"; + << "{"; + + if (facets) + os << "this->_enumeration_facet (_xsde_" << name << + "_enums_, " << enum_count << "UL);"; + + os << "}"; } } }; diff --git a/xsde/cxx/parser/parser-source.cxx b/xsde/cxx/parser/parser-source.cxx index 83b79f8..f4da879 100644 --- a/xsde/cxx/parser/parser-source.cxx +++ b/xsde/cxx/parser/parser-source.cxx @@ -5,6 +5,8 @@ #include +#include + #include #include @@ -34,7 +36,14 @@ namespace CXX base.inherits_p () && base_ret == ret_type (base.inherits ().base ())); - if (same || ret == L"void" || poly_code || + Boolean facets (false); // Whether we need to set facets. + if (validation) + { + StringBasedType t (facets); + t.dispatch (e); + } + + if (facets || same || ret == L"void" || poly_code || (tiein && !(base_same || base_ret == L"void"))) { os << "// " << name << endl @@ -145,6 +154,26 @@ namespace CXX << "return this->" << impl << "->" << base_post << " ();" << "}"; } + + if (facets) + { + typedef Cult::Containers::Set Enums; + Enums enums; + + for (Type::NamesIterator i (e.names_begin ()), + end (e.names_end ()); i != end; ++i) + enums.insert (i->name ()); + + os << "const char* const " << name << "::" << "_xsde_" << name << + "_enums_[" << enums.size () << "UL] = " + << "{"; + + for (Enums::Iterator b (enums.begin ()), i (b), end (enums.end ()); + i != end; ++i) + os << (i != b ? ",\n" : "") << strlit (*i); + + os << "};"; + } } }; diff --git a/xsde/cxx/serializer/elements.hxx b/xsde/cxx/serializer/elements.hxx index 50a54eb..470d6c4 100644 --- a/xsde/cxx/serializer/elements.hxx +++ b/xsde/cxx/serializer/elements.hxx @@ -203,6 +203,110 @@ namespace CXX String serializer_map_; }; + + // Check whether this is a string-based type (including ID, IDFER, + // anyURI, and ENTITY). + // + struct StringBasedType: Traversal::Complex, + Traversal::Fundamental::String, + Traversal::Fundamental::NormalizedString, + Traversal::Fundamental::Token, + Traversal::Fundamental::Name, + Traversal::Fundamental::NameToken, + Traversal::Fundamental::NCName, + Traversal::Fundamental::Language, + Traversal::Fundamental::Id, + Traversal::Fundamental::IdRef, + Traversal::Fundamental::AnyURI, + Traversal::Fundamental::Entity + + { + StringBasedType (Boolean& r) + : r_ (r) + { + *this >> inherits_ >> *this; + } + + virtual Void + traverse (SemanticGraph::Complex& c) + { + inherits (c, inherits_); + } + + // Strings. + // + virtual Void + traverse (SemanticGraph::Fundamental::String&) + { + r_ = true; + } + + virtual Void + traverse (SemanticGraph::Fundamental::NormalizedString&) + { + r_ = true; + } + + virtual Void + traverse (SemanticGraph::Fundamental::Token&) + { + r_ = true; + } + + virtual Void + traverse (SemanticGraph::Fundamental::NameToken&) + { + r_ = true; + } + + virtual Void + traverse (SemanticGraph::Fundamental::Name&) + { + r_ = true; + } + + virtual Void + traverse (SemanticGraph::Fundamental::NCName&) + { + r_ = true; + } + + virtual Void + traverse (SemanticGraph::Fundamental::Language&) + { + r_ = true; + } + + virtual Void + traverse (SemanticGraph::Fundamental::Id&) + { + r_ = true; + } + + virtual Void + traverse (SemanticGraph::Fundamental::IdRef&) + { + r_ = true; + } + + virtual Void + traverse (SemanticGraph::Fundamental::AnyURI&) + { + r_ = true; + } + + virtual Void + traverse (SemanticGraph::Fundamental::Entity&) + { + r_ = true; + } + + private: + Boolean& r_; + Traversal::Inherits inherits_; + }; + + // // struct RequiredAttributeTest: Traversal::Attribute diff --git a/xsde/cxx/serializer/serializer-header.cxx b/xsde/cxx/serializer/serializer-header.cxx index 5459b51..b432f15 100644 --- a/xsde/cxx/serializer/serializer-header.cxx +++ b/xsde/cxx/serializer/serializer-header.cxx @@ -275,6 +275,13 @@ namespace CXX SemanticGraph::Type& base (e.inherits ().base ()); String fq_base (fq_name (base)); + Boolean facets (false); // Whether we need to set facets. + if (validation) + { + StringBasedType t (facets); + t.dispatch (e); + } + os << "class " << name << ": public " << (mixin ? "virtual " : "") << fq_base << "{" @@ -328,15 +335,22 @@ namespace CXX << "_dynamic_type () const;"; } - if (tiein) + if (facets || tiein) { os << endl << "// Constructor." << endl - << "//" << endl - << name << " (" << fq_base << "* tiein);" - << endl; + << "//" << endl; - os << "// Implementation details." << endl + if (tiein) + os << name << " (" << fq_base << "* tiein);"; + else + os << name << " ();"; + } + + if (tiein) + { + os << endl + << "// Implementation details." << endl << "//" << endl; // If our base has pure virtual functions, override them here. @@ -345,8 +359,21 @@ namespace CXX os << "protected:" << endl << name << "* " << etiein (e) << ";" - << name << " (" << name << "*, void*);" - << endl; + << name << " (" << name << "*, void*);"; + } + + if (facets) + { + UnsignedLong enum_count (0); + + for (Type::NamesIterator i (e.names_begin ()), end (e.names_end ()); + i != end; ++i) + ++enum_count; + + os << endl + << "protected:" << endl + << "static const char* const _xsde_" << name << "_enums_[" << + enum_count << "UL];"; } os << "};"; diff --git a/xsde/cxx/serializer/serializer-inline.cxx b/xsde/cxx/serializer/serializer-inline.cxx index 3ff9bab..e14680e 100644 --- a/xsde/cxx/serializer/serializer-inline.cxx +++ b/xsde/cxx/serializer/serializer-inline.cxx @@ -24,9 +24,41 @@ namespace CXX virtual Void traverse (Type& e) { + String const& name (ename (e)); + + Boolean facets (false); // Whether we need to set facets. + if (validation) + { + StringBasedType t (facets); + t.dispatch (e); + } + + UnsignedLong enum_count (0); + if (facets) + { + for (Type::NamesIterator i (e.names_begin ()), end (e.names_end ()); + i != end; ++i) + ++enum_count; + } + + if (facets || tiein) + os << "// " << name << endl + << "//" << endl + << endl; + + if (facets && !tiein) + { + os << inl + << name << "::" << endl + << name << " ()" << endl + << "{" + << "this->_enumeration_facet (_xsde_" << name << "_enums_, " << + enum_count << "UL);" + << "}"; + } + if (tiein) { - String const& name (ename (e)); String const& impl (etiein (e)); // We have to use "real" (non-typedef) base name in base @@ -36,25 +68,31 @@ namespace CXX String fq_base (fq_name (base)); String real_fq_base (real_fq_name (base)); - os << "// " << name << endl - << "//" << endl - << endl; - os << inl << name << "::" << endl << name << " (" << fq_base << "* tiein)" << endl << ": " << real_fq_base << " (tiein, 0)," << endl << " " << impl << " (0)" - << "{" - << "}"; + << "{"; + + if (facets) + os << "this->_enumeration_facet (_xsde_" << name << + "_enums_, " << enum_count << "UL);"; + + os << "}"; os << inl << name << "::" << endl << name << " (" << name << "* impl, void*)" << endl << ": " << real_fq_base << " (impl, 0)," << endl << " " << impl << " (impl)" - << "{" - << "}"; + << "{"; + + if (facets) + os << "this->_enumeration_facet (_xsde_" << name << + "_enums_, " << enum_count << "UL);"; + + os << "}"; } } }; diff --git a/xsde/cxx/serializer/serializer-source.cxx b/xsde/cxx/serializer/serializer-source.cxx index 509acf4..e4fd239 100644 --- a/xsde/cxx/serializer/serializer-source.cxx +++ b/xsde/cxx/serializer/serializer-source.cxx @@ -5,6 +5,8 @@ #include +#include + #include #include @@ -382,6 +384,13 @@ namespace CXX String const& arg (arg_type (e)); SemanticGraph::Type& base (e.inherits ().base ()); + Boolean facets (false); // Whether we need to set facets. + if (validation) + { + StringBasedType t (facets); + t.dispatch (e); + } + os << "// " << name << endl << "//" << endl << endl; @@ -470,6 +479,26 @@ namespace CXX BaseOverride t (*this, name); t.dispatch (base); } + + if (facets) + { + typedef Cult::Containers::Set Enums; + Enums enums; + + for (Type::NamesIterator i (e.names_begin ()), + end (e.names_end ()); i != end; ++i) + enums.insert (i->name ()); + + os << "const char* const " << name << "::" << "_xsde_" << name << + "_enums_[" << enums.size () << "UL] = " + << "{"; + + for (Enums::Iterator b (enums.begin ()), i (b), end (enums.end ()); + i != end; ++i) + os << (i != b ? ",\n" : "") << strlit (*i); + + os << "};"; + } } }; -- cgit v1.1