From 7db026e8056914d113ac0bbfd9bdc4908a9e7874 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Fri, 8 Oct 2010 15:35:23 +0200 Subject: Add support for the whiteSpace facet Use the same mechanism to handle whitespace processing for build-in types and enumerations. --- dist/libxsde/xsde/makefile | 1 + dist/libxsde/xsde/nmakefile | 1 + dist/tests/cxx/hybrid/makefile | 6 +- dist/tests/cxx/hybrid/nmakefile | 6 +- libxsde/xsde/cxx/parser/non-validating/id-stl.cxx | 4 +- libxsde/xsde/cxx/parser/non-validating/id.cxx | 4 +- .../xsde/cxx/parser/non-validating/idref-stl.cxx | 4 +- libxsde/xsde/cxx/parser/non-validating/idref.cxx | 4 +- .../cxx/parser/non-validating/language-stl.cxx | 4 +- .../xsde/cxx/parser/non-validating/language.cxx | 4 +- .../xsde/cxx/parser/non-validating/name-stl.cxx | 4 +- libxsde/xsde/cxx/parser/non-validating/name.cxx | 4 +- .../xsde/cxx/parser/non-validating/ncname-stl.cxx | 4 +- libxsde/xsde/cxx/parser/non-validating/ncname.cxx | 4 +- .../xsde/cxx/parser/non-validating/nmtoken-stl.cxx | 4 +- libxsde/xsde/cxx/parser/non-validating/nmtoken.cxx | 4 +- .../non-validating/normalized-string-stl.cxx | 21 +-- .../parser/non-validating/normalized-string.cxx | 37 ++-- .../cxx/parser/non-validating/string-common.cxx | 84 +++++++++ .../cxx/parser/non-validating/string-common.hxx | 43 +++++ .../xsde/cxx/parser/non-validating/string-stl.cxx | 13 +- libxsde/xsde/cxx/parser/non-validating/string.cxx | 25 ++- .../xsde/cxx/parser/non-validating/token-stl.cxx | 28 +-- libxsde/xsde/cxx/parser/non-validating/token.cxx | 31 +--- libxsde/xsde/cxx/parser/non-validating/uri-stl.cxx | 4 +- libxsde/xsde/cxx/parser/non-validating/uri.cxx | 4 +- .../cxx/parser/non-validating/xml-schema-pskel.hxx | 90 +++++++--- .../cxx/parser/non-validating/xml-schema-pskel.ixx | 187 +++++++++++++++++++-- libxsde/xsde/cxx/parser/validating/id-stl.cxx | 14 +- libxsde/xsde/cxx/parser/validating/id.cxx | 14 +- libxsde/xsde/cxx/parser/validating/idref-stl.cxx | 14 +- libxsde/xsde/cxx/parser/validating/idref.cxx | 14 +- .../xsde/cxx/parser/validating/language-stl.cxx | 21 +-- libxsde/xsde/cxx/parser/validating/language.cxx | 21 +-- libxsde/xsde/cxx/parser/validating/name-stl.cxx | 15 +- libxsde/xsde/cxx/parser/validating/name.cxx | 15 +- libxsde/xsde/cxx/parser/validating/ncname-stl.cxx | 14 +- libxsde/xsde/cxx/parser/validating/ncname.cxx | 14 +- libxsde/xsde/cxx/parser/validating/nmtoken-stl.cxx | 17 +- libxsde/xsde/cxx/parser/validating/nmtoken.cxx | 17 +- .../parser/validating/normalized-string-stl.cxx | 23 ++- .../cxx/parser/validating/normalized-string.cxx | 38 +++-- .../xsde/cxx/parser/validating/string-common.cxx | 75 ++++++++- .../xsde/cxx/parser/validating/string-common.hxx | 20 ++- libxsde/xsde/cxx/parser/validating/string-stl.cxx | 13 +- libxsde/xsde/cxx/parser/validating/string.cxx | 26 ++- libxsde/xsde/cxx/parser/validating/token-stl.cxx | 30 +--- libxsde/xsde/cxx/parser/validating/token.cxx | 32 +--- libxsde/xsde/cxx/parser/validating/uri-stl.cxx | 6 +- libxsde/xsde/cxx/parser/validating/uri.cxx | 6 +- .../cxx/parser/validating/xml-schema-pskel.hxx | 29 ++-- .../cxx/parser/validating/xml-schema-pskel.ixx | 79 +++++++-- libxsde/xsde/cxx/string-search.cxx | 5 +- libxsde/xsde/makefile | 1 + tests/cxx/hybrid/makefile | 6 +- xsde/cxx/hybrid/parser-header.cxx | 10 +- xsde/cxx/hybrid/parser-source.cxx | 78 ++++++--- xsde/cxx/parser/elements.cxx | 43 +++++ xsde/cxx/parser/elements.hxx | 5 + xsde/cxx/parser/parser-header.cxx | 38 +---- xsde/cxx/parser/parser-inline.cxx | 162 +++++++++--------- xsde/cxx/serializer/serializer-header.cxx | 3 +- xsde/cxx/serializer/serializer-inline.cxx | 3 +- 63 files changed, 963 insertions(+), 587 deletions(-) create mode 100644 libxsde/xsde/cxx/parser/non-validating/string-common.cxx create mode 100644 libxsde/xsde/cxx/parser/non-validating/string-common.hxx diff --git a/dist/libxsde/xsde/makefile b/dist/libxsde/xsde/makefile index 34e026b..a134d29 100644 --- a/dist/libxsde/xsde/makefile +++ b/dist/libxsde/xsde/makefile @@ -202,6 +202,7 @@ else # validation src += \ cxx/parser/non-validating/parser.cxx \ cxx/parser/non-validating/time-zone.cxx \ +cxx/parser/non-validating/string-common.cxx \ cxx/parser/non-validating/xml-schema-pskel.cxx src += \ diff --git a/dist/libxsde/xsde/nmakefile b/dist/libxsde/xsde/nmakefile index 25625a3..9eb9aea 100644 --- a/dist/libxsde/xsde/nmakefile +++ b/dist/libxsde/xsde/nmakefile @@ -208,6 +208,7 @@ cxx\parser\validating\duration.cxx src = $(src) \ cxx\parser\non-validating\parser.cxx \ cxx\parser\non-validating\time-zone.cxx \ +cxx\parser\non-validating\string-common.cxx \ cxx\parser\non-validating\xml-schema-pskel.cxx src = $(src) \ diff --git a/dist/tests/cxx/hybrid/makefile b/dist/tests/cxx/hybrid/makefile index 7e78d9f..62bbc1e 100644 --- a/dist/tests/cxx/hybrid/makefile +++ b/dist/tests/cxx/hybrid/makefile @@ -21,6 +21,9 @@ ifeq ($(XSDE_ENCODING),iso8859-1) dirs += iso8859-1 endif +ifeq ($(XSDE_PARSER_VALIDATION),y) +dirs += choice recursive clone + ifeq ($(XSDE_CDR),y) dirs += binary/cdr endif @@ -28,9 +31,6 @@ endif ifeq ($(XSDE_XDR),y) dirs += binary/xdr endif - -ifeq ($(XSDE_PARSER_VALIDATION),y) -dirs += choice recursive clone endif endif # XSDE_IOSTREAM diff --git a/dist/tests/cxx/hybrid/nmakefile b/dist/tests/cxx/hybrid/nmakefile index b31619b..61097dd 100644 --- a/dist/tests/cxx/hybrid/nmakefile +++ b/dist/tests/cxx/hybrid/nmakefile @@ -21,6 +21,9 @@ dirs = $(dirs) built-in default enumeration list test-template union dirs = $(dirs) iso8859-1 !endif +!if "$(XSDE_PARSER_VALIDATION)" == "y" +dirs = $(dirs) choice recursive clone + !if "$(XSDE_CDR)" == "y" dirs = $(dirs) binary/cdr !endif @@ -28,9 +31,6 @@ dirs = $(dirs) binary/cdr !if "$(XSDE_XDR)" == "y" dirs = $(dirs) binary/xdr !endif - -!if "$(XSDE_PARSER_VALIDATION)" == "y" -dirs = $(dirs) choice recursive clone !endif !endif # XSDE_IOSTREAM diff --git a/libxsde/xsde/cxx/parser/non-validating/id-stl.cxx b/libxsde/xsde/cxx/parser/non-validating/id-stl.cxx index 2e5ebd7..e3ebad8 100644 --- a/libxsde/xsde/cxx/parser/non-validating/id-stl.cxx +++ b/libxsde/xsde/cxx/parser/non-validating/id-stl.cxx @@ -4,6 +4,7 @@ // license : GNU GPL v2 + exceptions; see accompanying LICENSE file #include +#include namespace xsde { @@ -36,8 +37,7 @@ namespace xsde std::string id_pimpl:: post_id () { - ro_string tmp (str_); - str_.resize (trim_right (tmp)); + string_common::process_facets (str_, _facets ()); std::string r; r.swap (str_); diff --git a/libxsde/xsde/cxx/parser/non-validating/id.cxx b/libxsde/xsde/cxx/parser/non-validating/id.cxx index 8431218..c54f958 100644 --- a/libxsde/xsde/cxx/parser/non-validating/id.cxx +++ b/libxsde/xsde/cxx/parser/non-validating/id.cxx @@ -6,6 +6,7 @@ #include #include +#include namespace xsde { @@ -57,8 +58,7 @@ namespace xsde char* id_pimpl:: post_id () { - ro_string tmp (str_.data (), str_.size ()); - str_.truncate (trim_right (tmp)); + string_common::process_facets (str_, _facets ()); return str_.detach (); } } diff --git a/libxsde/xsde/cxx/parser/non-validating/idref-stl.cxx b/libxsde/xsde/cxx/parser/non-validating/idref-stl.cxx index 77bbc2a..da87469 100644 --- a/libxsde/xsde/cxx/parser/non-validating/idref-stl.cxx +++ b/libxsde/xsde/cxx/parser/non-validating/idref-stl.cxx @@ -4,6 +4,7 @@ // license : GNU GPL v2 + exceptions; see accompanying LICENSE file #include +#include namespace xsde { @@ -36,8 +37,7 @@ namespace xsde std::string idref_pimpl:: post_idref () { - ro_string tmp (str_); - str_.resize (trim_right (tmp)); + string_common::process_facets (str_, _facets ()); std::string r; r.swap (str_); diff --git a/libxsde/xsde/cxx/parser/non-validating/idref.cxx b/libxsde/xsde/cxx/parser/non-validating/idref.cxx index 15a2eea..ce1ef46 100644 --- a/libxsde/xsde/cxx/parser/non-validating/idref.cxx +++ b/libxsde/xsde/cxx/parser/non-validating/idref.cxx @@ -6,6 +6,7 @@ #include #include +#include namespace xsde { @@ -57,8 +58,7 @@ namespace xsde char* idref_pimpl:: post_idref () { - ro_string tmp (str_.data (), str_.size ()); - str_.truncate (trim_right (tmp)); + string_common::process_facets (str_, _facets ()); return str_.detach (); } } diff --git a/libxsde/xsde/cxx/parser/non-validating/language-stl.cxx b/libxsde/xsde/cxx/parser/non-validating/language-stl.cxx index 2c1e357..8edc8fe 100644 --- a/libxsde/xsde/cxx/parser/non-validating/language-stl.cxx +++ b/libxsde/xsde/cxx/parser/non-validating/language-stl.cxx @@ -4,6 +4,7 @@ // license : GNU GPL v2 + exceptions; see accompanying LICENSE file #include +#include namespace xsde { @@ -36,8 +37,7 @@ namespace xsde std::string language_pimpl:: post_language () { - ro_string tmp (str_); - str_.resize (trim_right (tmp)); + string_common::process_facets (str_, _facets ()); std::string r; r.swap (str_); diff --git a/libxsde/xsde/cxx/parser/non-validating/language.cxx b/libxsde/xsde/cxx/parser/non-validating/language.cxx index d4d5c3d..015626d 100644 --- a/libxsde/xsde/cxx/parser/non-validating/language.cxx +++ b/libxsde/xsde/cxx/parser/non-validating/language.cxx @@ -6,6 +6,7 @@ #include #include +#include namespace xsde { @@ -57,8 +58,7 @@ namespace xsde char* language_pimpl:: post_language () { - ro_string tmp (str_); - str_.truncate (trim_right (tmp)); + string_common::process_facets (str_, _facets ()); return str_.detach (); } } diff --git a/libxsde/xsde/cxx/parser/non-validating/name-stl.cxx b/libxsde/xsde/cxx/parser/non-validating/name-stl.cxx index ce071c9..07609ab 100644 --- a/libxsde/xsde/cxx/parser/non-validating/name-stl.cxx +++ b/libxsde/xsde/cxx/parser/non-validating/name-stl.cxx @@ -4,6 +4,7 @@ // license : GNU GPL v2 + exceptions; see accompanying LICENSE file #include +#include namespace xsde { @@ -36,8 +37,7 @@ namespace xsde std::string name_pimpl:: post_name () { - ro_string tmp (str_); - str_.resize (trim_right (tmp)); + string_common::process_facets (str_, _facets ()); std::string r; r.swap (str_); diff --git a/libxsde/xsde/cxx/parser/non-validating/name.cxx b/libxsde/xsde/cxx/parser/non-validating/name.cxx index b11d304..df1ba7b 100644 --- a/libxsde/xsde/cxx/parser/non-validating/name.cxx +++ b/libxsde/xsde/cxx/parser/non-validating/name.cxx @@ -6,6 +6,7 @@ #include #include +#include namespace xsde { @@ -57,8 +58,7 @@ namespace xsde char* name_pimpl:: post_name () { - ro_string tmp (str_.data (), str_.size ()); - str_.truncate (trim_right (tmp)); + string_common::process_facets (str_, _facets ()); return str_.detach (); } } diff --git a/libxsde/xsde/cxx/parser/non-validating/ncname-stl.cxx b/libxsde/xsde/cxx/parser/non-validating/ncname-stl.cxx index 0ab155e..aa35ac2 100644 --- a/libxsde/xsde/cxx/parser/non-validating/ncname-stl.cxx +++ b/libxsde/xsde/cxx/parser/non-validating/ncname-stl.cxx @@ -4,6 +4,7 @@ // license : GNU GPL v2 + exceptions; see accompanying LICENSE file #include +#include namespace xsde { @@ -36,8 +37,7 @@ namespace xsde std::string ncname_pimpl:: post_ncname () { - ro_string tmp (str_); - str_.resize (trim_right (tmp)); + string_common::process_facets (str_, _facets ()); std::string r; r.swap (str_); diff --git a/libxsde/xsde/cxx/parser/non-validating/ncname.cxx b/libxsde/xsde/cxx/parser/non-validating/ncname.cxx index c2603a9..b972fc8 100644 --- a/libxsde/xsde/cxx/parser/non-validating/ncname.cxx +++ b/libxsde/xsde/cxx/parser/non-validating/ncname.cxx @@ -6,6 +6,7 @@ #include #include +#include namespace xsde { @@ -57,8 +58,7 @@ namespace xsde char* ncname_pimpl:: post_ncname () { - ro_string tmp (str_.data (), str_.size ()); - str_.truncate (trim_right (tmp)); + string_common::process_facets (str_, _facets ()); return str_.detach (); } } diff --git a/libxsde/xsde/cxx/parser/non-validating/nmtoken-stl.cxx b/libxsde/xsde/cxx/parser/non-validating/nmtoken-stl.cxx index a3500c2..e76881c 100644 --- a/libxsde/xsde/cxx/parser/non-validating/nmtoken-stl.cxx +++ b/libxsde/xsde/cxx/parser/non-validating/nmtoken-stl.cxx @@ -4,6 +4,7 @@ // license : GNU GPL v2 + exceptions; see accompanying LICENSE file #include +#include namespace xsde { @@ -36,8 +37,7 @@ namespace xsde std::string nmtoken_pimpl:: post_nmtoken () { - ro_string tmp (str_); - str_.resize (trim_right (tmp)); + string_common::process_facets (str_, _facets ()); std::string r; r.swap (str_); diff --git a/libxsde/xsde/cxx/parser/non-validating/nmtoken.cxx b/libxsde/xsde/cxx/parser/non-validating/nmtoken.cxx index acf1ebd..14d4cce 100644 --- a/libxsde/xsde/cxx/parser/non-validating/nmtoken.cxx +++ b/libxsde/xsde/cxx/parser/non-validating/nmtoken.cxx @@ -6,6 +6,7 @@ #include #include +#include namespace xsde { @@ -57,8 +58,7 @@ namespace xsde char* nmtoken_pimpl:: post_nmtoken () { - ro_string tmp (str_.data (), str_.size ()); - str_.truncate (trim_right (tmp)); + string_common::process_facets (str_, _facets ()); return str_.detach (); } } diff --git a/libxsde/xsde/cxx/parser/non-validating/normalized-string-stl.cxx b/libxsde/xsde/cxx/parser/non-validating/normalized-string-stl.cxx index 4070244..9f16cec 100644 --- a/libxsde/xsde/cxx/parser/non-validating/normalized-string-stl.cxx +++ b/libxsde/xsde/cxx/parser/non-validating/normalized-string-stl.cxx @@ -4,6 +4,7 @@ // license : GNU GPL v2 + exceptions; see accompanying LICENSE file #include +#include namespace xsde { @@ -22,21 +23,21 @@ namespace xsde void normalized_string_pimpl:: _characters (const ro_string& s) { - str_ += s; + if (_facets ().whitespace_ == 2 && str_.size () == 0) + { + ro_string tmp (s.data (), s.size ()); + + if (trim_left (tmp) != 0) + str_ += tmp; + } + else + str_ += s; } std::string normalized_string_pimpl:: post_normalized_string () { - std::string::size_type size = str_.size (); - - for (std::string::size_type i = 0; i < size; ++i) - { - char& c = str_[i]; - - if (c == 0x0A || c == 0x0D || c == 0x09) - c = 0x20; - } + string_common::process_facets (str_, _facets ()); std::string r; r.swap (str_); diff --git a/libxsde/xsde/cxx/parser/non-validating/normalized-string.cxx b/libxsde/xsde/cxx/parser/non-validating/normalized-string.cxx index e268d7d..20de4d8 100644 --- a/libxsde/xsde/cxx/parser/non-validating/normalized-string.cxx +++ b/libxsde/xsde/cxx/parser/non-validating/normalized-string.cxx @@ -6,6 +6,7 @@ #include #include +#include namespace xsde { @@ -29,29 +30,35 @@ namespace xsde void normalized_string_pimpl:: _characters (const ro_string& s) { + if (_facets ().whitespace_ == 2 && str_.size () == 0) + { + ro_string tmp (s.data (), s.size ()); + + if (trim_left (tmp) != 0) + { #ifdef XSDE_EXCEPTIONS - str_.append (s.data (), s.size ()); + str_.append (tmp.data (), tmp.size ()); #else - if (str_.append (s.data (), s.size ())) - _sys_error (sys_error::no_memory); + if (str_.append (tmp.data (), tmp.size ())) + _sys_error (sys_error::no_memory); +#endif + } + } + else + { +#ifdef XSDE_EXCEPTIONS + str_.append (s.data (), s.size ()); +#else + if (str_.append (s.data (), s.size ())) + _sys_error (sys_error::no_memory); #endif + } } char* normalized_string_pimpl:: post_normalized_string () { - typedef string::size_type size_type; - - size_type size = str_.size (); - - for (size_type i = 0; i < size; ++i) - { - char& c = str_[i]; - - if (c == 0x0A || c == 0x0D || c == 0x09) - c = 0x20; - } - + string_common::process_facets (str_, _facets ()); return str_.detach (); } } diff --git a/libxsde/xsde/cxx/parser/non-validating/string-common.cxx b/libxsde/xsde/cxx/parser/non-validating/string-common.cxx new file mode 100644 index 0000000..f4ba502 --- /dev/null +++ b/libxsde/xsde/cxx/parser/non-validating/string-common.cxx @@ -0,0 +1,84 @@ +// file : xsde/cxx/parser/non-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 + +namespace xsde +{ + namespace cxx + { + namespace parser + { + namespace non_validating + { + void string_common:: + process_facets ( +#ifdef XSDE_STL + std::string& str, +#else + string& str, +#endif + const string_facets::facets& f) + { +#ifdef XSDE_STL + typedef std::string::size_type size_type; +#else + typedef string::size_type size_type; +#endif + + if (f.whitespace_ == 2) + { + // Collapse. The left trimming has already been performed. + // + size_type size = str.size (); + size_type j = 0; + + bool subs = false; + + for (size_type i = 0; i < size; ++i) + { + char c = str[i]; + + if (c == 0x20 || c == 0x0A || c == 0x0D || c == 0x09) + { + subs = true; + } + else + { + if (subs) + { + subs = false; + str[j++] = 0x20; + } + + str[j++] = c; + } + } + +#ifdef XSDE_STL + str.resize (j); +#else + str.truncate (j); +#endif + } + else if (f.whitespace_ == 1) + { + // Replace. + // + size_type size = str.size (); + + for (size_type i = 0; i < size; ++i) + { + char& c = str[i]; + + if (c == 0x0A || c == 0x0D || c == 0x09) + c = 0x20; + } + } + } + } + } + } +} diff --git a/libxsde/xsde/cxx/parser/non-validating/string-common.hxx b/libxsde/xsde/cxx/parser/non-validating/string-common.hxx new file mode 100644 index 0000000..6935e9f --- /dev/null +++ b/libxsde/xsde/cxx/parser/non-validating/string-common.hxx @@ -0,0 +1,43 @@ +// file : xsde/cxx/parser/non-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_NON_VALIDATING_STRING_COMMON_HXX +#define XSDE_CXX_PARSER_NON_VALIDATING_STRING_COMMON_HXX + +#include + +#ifdef XSDE_STL +#include +#else +#include +#endif + +#include + +namespace xsde +{ + namespace cxx + { + namespace parser + { + namespace non_validating + { + struct string_common + { + static void + process_facets ( +#ifdef XSDE_STL + std::string& str, +#else + string& str, +#endif + const string_facets::facets&); + }; + } + } + } +} + +#endif // XSDE_CXX_PARSER_NON_VALIDATING_STRING_COMMON_HXX diff --git a/libxsde/xsde/cxx/parser/non-validating/string-stl.cxx b/libxsde/xsde/cxx/parser/non-validating/string-stl.cxx index cd82550..4e979d8 100644 --- a/libxsde/xsde/cxx/parser/non-validating/string-stl.cxx +++ b/libxsde/xsde/cxx/parser/non-validating/string-stl.cxx @@ -4,6 +4,7 @@ // license : GNU GPL v2 + exceptions; see accompanying LICENSE file #include +#include namespace xsde { @@ -22,12 +23,22 @@ namespace xsde void string_pimpl:: _characters (const ro_string& s) { - str_ += s; + if (_facets ().whitespace_ == 2 && str_.size () == 0) + { + ro_string tmp (s.data (), s.size ()); + + if (trim_left (tmp) != 0) + str_ += tmp; + } + else + str_ += s; } std::string string_pimpl:: post_string () { + string_common::process_facets (str_, _facets ()); + std::string r; r.swap (str_); return r; diff --git a/libxsde/xsde/cxx/parser/non-validating/string.cxx b/libxsde/xsde/cxx/parser/non-validating/string.cxx index 091f5b6..21b4aaf 100644 --- a/libxsde/xsde/cxx/parser/non-validating/string.cxx +++ b/libxsde/xsde/cxx/parser/non-validating/string.cxx @@ -6,6 +6,7 @@ #include #include +#include namespace xsde { @@ -29,17 +30,35 @@ namespace xsde void string_pimpl:: _characters (const ro_string& s) { + if (_facets ().whitespace_ == 2 && str_.size () == 0) + { + ro_string tmp (s.data (), s.size ()); + + if (trim_left (tmp) != 0) + { #ifdef XSDE_EXCEPTIONS - str_.append (s.data (), s.size ()); + str_.append (tmp.data (), tmp.size ()); #else - if (str_.append (s.data (), s.size ())) - _sys_error (sys_error::no_memory); + if (str_.append (tmp.data (), tmp.size ())) + _sys_error (sys_error::no_memory); +#endif + } + } + else + { +#ifdef XSDE_EXCEPTIONS + str_.append (s.data (), s.size ()); +#else + if (str_.append (s.data (), s.size ())) + _sys_error (sys_error::no_memory); #endif + } } char* string_pimpl:: post_string () { + string_common::process_facets (str_, _facets ()); return str_.detach (); } } diff --git a/libxsde/xsde/cxx/parser/non-validating/token-stl.cxx b/libxsde/xsde/cxx/parser/non-validating/token-stl.cxx index 8977b0f..e2a604d 100644 --- a/libxsde/xsde/cxx/parser/non-validating/token-stl.cxx +++ b/libxsde/xsde/cxx/parser/non-validating/token-stl.cxx @@ -4,6 +4,7 @@ // license : GNU GPL v2 + exceptions; see accompanying LICENSE file #include +#include namespace xsde { @@ -36,32 +37,7 @@ namespace xsde std::string token_pimpl:: post_token () { - std::string::size_type size = str_.size (); - std::string::size_type j = 0; - - bool subs = false; - - for (std::string::size_type i = 0; i < size; ++i) - { - char c = str_[i]; - - if (c == 0x20 || c == 0x0A || c == 0x0D || c == 0x09) - { - subs = true; - } - else - { - if (subs) - { - subs = false; - str_[j++] = 0x20; - } - - str_[j++] = c; - } - } - - str_.resize (j); + string_common::process_facets (str_, _facets ()); std::string r; r.swap (str_); diff --git a/libxsde/xsde/cxx/parser/non-validating/token.cxx b/libxsde/xsde/cxx/parser/non-validating/token.cxx index 056d0f5..4a6f71f 100644 --- a/libxsde/xsde/cxx/parser/non-validating/token.cxx +++ b/libxsde/xsde/cxx/parser/non-validating/token.cxx @@ -6,6 +6,7 @@ #include #include +#include namespace xsde { @@ -57,35 +58,7 @@ namespace xsde char* token_pimpl:: post_token () { - typedef string::size_type size_type; - - size_type size = str_.size (); - size_type j = 0; - - bool subs = false; - - for (size_type i = 0; i < size; ++i) - { - char c = str_[i]; - - if (c == 0x20 || c == 0x0A || c == 0x0D || c == 0x09) - { - subs = true; - } - else - { - if (subs) - { - subs = false; - str_[j++] = 0x20; - } - - str_[j++] = c; - } - } - - str_.truncate (j); - + string_common::process_facets (str_, _facets ()); return str_.detach (); } } diff --git a/libxsde/xsde/cxx/parser/non-validating/uri-stl.cxx b/libxsde/xsde/cxx/parser/non-validating/uri-stl.cxx index 998bc2e..47bd584 100644 --- a/libxsde/xsde/cxx/parser/non-validating/uri-stl.cxx +++ b/libxsde/xsde/cxx/parser/non-validating/uri-stl.cxx @@ -4,6 +4,7 @@ // license : GNU GPL v2 + exceptions; see accompanying LICENSE file #include +#include namespace xsde { @@ -36,8 +37,7 @@ namespace xsde std::string uri_pimpl:: post_uri () { - ro_string tmp (str_); - str_.resize (trim_right (tmp)); + string_common::process_facets (str_, _facets ()); std::string r; r.swap (str_); diff --git a/libxsde/xsde/cxx/parser/non-validating/uri.cxx b/libxsde/xsde/cxx/parser/non-validating/uri.cxx index 0b60501..50ebca8 100644 --- a/libxsde/xsde/cxx/parser/non-validating/uri.cxx +++ b/libxsde/xsde/cxx/parser/non-validating/uri.cxx @@ -6,6 +6,7 @@ #include #include +#include namespace xsde { @@ -57,8 +58,7 @@ namespace xsde char* uri_pimpl:: post_uri () { - ro_string tmp (str_); - str_.truncate (trim_right (tmp)); + string_common::process_facets (str_, _facets ()); return str_.detach (); } } diff --git a/libxsde/xsde/cxx/parser/non-validating/xml-schema-pskel.hxx b/libxsde/xsde/cxx/parser/non-validating/xml-schema-pskel.hxx index 59469c6..6b98277 100644 --- a/libxsde/xsde/cxx/parser/non-validating/xml-schema-pskel.hxx +++ b/libxsde/xsde/cxx/parser/non-validating/xml-schema-pskel.hxx @@ -551,7 +551,29 @@ namespace xsde // string that you have to delete with delete[] (or custom // deallocator if enabled). // - struct string_pskel: simple_content + + struct string_facets + { + string_facets (); + + void + _whitespace_facet (unsigned int); + + public: + struct facets + { + // 0 - preserve + // 1 - replace + // 2 - collapse + // + unsigned int whitespace_: 2; + }; + + protected: + facets facets_; + }; + + struct string_pskel: simple_content, string_facets { #ifdef XSDE_STL virtual std::string @@ -575,9 +597,12 @@ namespace xsde protected: string_pskel* string_impl_; #endif + protected: + const string_facets::facets& + _facets () const; }; - struct normalized_string_pskel: simple_content + struct normalized_string_pskel: simple_content, string_facets { #ifdef XSDE_STL virtual std::string @@ -593,17 +618,20 @@ namespace xsde virtual const char* _dynamic_type () const; #endif + normalized_string_pskel (); #ifdef XSDE_REUSE_STYLE_TIEIN - normalized_string_pskel (); normalized_string_pskel (normalized_string_pskel* impl, void*); protected: normalized_string_pskel* normalized_string_impl_; #endif + protected: + const string_facets::facets& + _facets () const; }; - struct token_pskel: simple_content + struct token_pskel: simple_content, string_facets { #ifdef XSDE_STL virtual std::string @@ -619,17 +647,20 @@ namespace xsde virtual const char* _dynamic_type () const; #endif + token_pskel (); #ifdef XSDE_REUSE_STYLE_TIEIN - token_pskel (); token_pskel (token_pskel* impl, void*); protected: token_pskel* token_impl_; #endif + protected: + const string_facets::facets& + _facets () const; }; - struct name_pskel: simple_content + struct name_pskel: simple_content, string_facets { #ifdef XSDE_STL virtual std::string @@ -645,17 +676,20 @@ namespace xsde virtual const char* _dynamic_type () const; #endif + name_pskel (); #ifdef XSDE_REUSE_STYLE_TIEIN - name_pskel (); name_pskel (name_pskel* impl, void*); protected: name_pskel* name_impl_; #endif + protected: + const string_facets::facets& + _facets () const; }; - struct nmtoken_pskel: simple_content + struct nmtoken_pskel: simple_content, string_facets { #ifdef XSDE_STL virtual std::string @@ -671,14 +705,17 @@ namespace xsde virtual const char* _dynamic_type () const; #endif + nmtoken_pskel (); #ifdef XSDE_REUSE_STYLE_TIEIN - nmtoken_pskel (); nmtoken_pskel (nmtoken_pskel* impl, void*); protected: nmtoken_pskel* nmtoken_impl_; #endif + protected: + const string_facets::facets& + _facets () const; }; struct nmtokens_pskel: list_base @@ -703,7 +740,7 @@ namespace xsde #endif }; - struct ncname_pskel: simple_content + struct ncname_pskel: simple_content, string_facets { #ifdef XSDE_STL virtual std::string @@ -719,17 +756,20 @@ namespace xsde virtual const char* _dynamic_type () const; #endif + ncname_pskel (); #ifdef XSDE_REUSE_STYLE_TIEIN - ncname_pskel (); ncname_pskel (ncname_pskel* impl, void*); protected: ncname_pskel* ncname_impl_; #endif + protected: + const string_facets::facets& + _facets () const; }; - struct id_pskel: simple_content + struct id_pskel: simple_content, string_facets { #ifdef XSDE_STL virtual std::string @@ -745,17 +785,20 @@ namespace xsde virtual const char* _dynamic_type () const; #endif + id_pskel (); #ifdef XSDE_REUSE_STYLE_TIEIN - id_pskel (); id_pskel (id_pskel* impl, void*); protected: id_pskel* id_impl_; #endif + protected: + const string_facets::facets& + _facets () const; }; - struct idref_pskel: simple_content + struct idref_pskel: simple_content, string_facets { #ifdef XSDE_STL virtual std::string @@ -771,14 +814,17 @@ namespace xsde virtual const char* _dynamic_type () const; #endif + idref_pskel (); #ifdef XSDE_REUSE_STYLE_TIEIN - idref_pskel (); idref_pskel (idref_pskel* impl, void*); protected: idref_pskel* idref_impl_; #endif + protected: + const string_facets::facets& + _facets () const; }; struct idrefs_pskel: list_base @@ -803,7 +849,7 @@ namespace xsde #endif }; - struct language_pskel: simple_content + struct language_pskel: simple_content, string_facets { #ifdef XSDE_STL virtual std::string @@ -819,17 +865,20 @@ namespace xsde virtual const char* _dynamic_type () const; #endif + language_pskel (); #ifdef XSDE_REUSE_STYLE_TIEIN - language_pskel (); language_pskel (language_pskel* impl, void*); protected: language_pskel* language_impl_; #endif + protected: + const string_facets::facets& + _facets () const; }; - struct uri_pskel: simple_content + struct uri_pskel: simple_content, string_facets { #ifdef XSDE_STL virtual std::string @@ -845,14 +894,17 @@ namespace xsde virtual const char* _dynamic_type () const; #endif + uri_pskel (); #ifdef XSDE_REUSE_STYLE_TIEIN - uri_pskel (); uri_pskel (uri_pskel* impl, void*); protected: uri_pskel* uri_impl_; #endif + protected: + const string_facets::facets& + _facets () const; }; struct qname_pskel: simple_content diff --git a/libxsde/xsde/cxx/parser/non-validating/xml-schema-pskel.ixx b/libxsde/xsde/cxx/parser/non-validating/xml-schema-pskel.ixx index 95e3258..2be6cbf 100644 --- a/libxsde/xsde/cxx/parser/non-validating/xml-schema-pskel.ixx +++ b/libxsde/xsde/cxx/parser/non-validating/xml-schema-pskel.ixx @@ -315,6 +315,20 @@ namespace xsde } #endif + // string_facets + // + inline string_facets:: + string_facets () + { + facets_.whitespace_ = 0; + } + + inline void string_facets:: + _whitespace_facet (unsigned int v) + { + facets_.whitespace_ = v; + } + // string_pskel // #ifdef XSDE_REUSE_STYLE_TIEIN @@ -330,70 +344,137 @@ namespace xsde { } #endif + inline const string_facets::facets& string_pskel:: + _facets () const + { +#ifdef XSDE_REUSE_STYLE_TIEIN + if (parent_ != 0) + return static_cast (*parent_).facets_; + else +#endif + return facets_; + } // normalized_string_pskel // -#ifdef XSDE_REUSE_STYLE_TIEIN inline normalized_string_pskel:: normalized_string_pskel () - : normalized_string_impl_ (0) { +#ifdef XSDE_REUSE_STYLE_TIEIN + normalized_string_impl_ = 0; +#endif + _whitespace_facet (1); // replace } +#ifdef XSDE_REUSE_STYLE_TIEIN inline normalized_string_pskel:: normalized_string_pskel (normalized_string_pskel* impl, void*) : simple_content (impl, 0), normalized_string_impl_ (impl) { + _whitespace_facet (1); // replace } #endif + inline const string_facets::facets& normalized_string_pskel:: + _facets () const + { +#ifdef XSDE_REUSE_STYLE_TIEIN + if (parent_ != 0) + return static_cast ( + *parent_).facets_; + else +#endif + return facets_; + } // token_pskel // -#ifdef XSDE_REUSE_STYLE_TIEIN inline token_pskel:: token_pskel () - : token_impl_ (0) { +#ifdef XSDE_REUSE_STYLE_TIEIN + token_impl_ = 0; +#endif + _whitespace_facet (2); // collapse } +#ifdef XSDE_REUSE_STYLE_TIEIN inline token_pskel:: token_pskel (token_pskel* impl, void*) : simple_content (impl, 0), token_impl_ (impl) { + _whitespace_facet (2); // collapse } #endif + inline const string_facets::facets& token_pskel:: + _facets () const + { +#ifdef XSDE_REUSE_STYLE_TIEIN + if (parent_ != 0) + return static_cast (*parent_).facets_; + else +#endif + return facets_; + } // name_pskel // -#ifdef XSDE_REUSE_STYLE_TIEIN inline name_pskel:: name_pskel () - : name_impl_ (0) { +#ifdef XSDE_REUSE_STYLE_TIEIN + name_impl_ = 0; +#endif + _whitespace_facet (2); // collapse } +#ifdef XSDE_REUSE_STYLE_TIEIN inline name_pskel:: name_pskel (name_pskel* impl, void*) : simple_content (impl, 0), name_impl_ (impl) { + _whitespace_facet (2); // collapse } #endif + inline const string_facets::facets& name_pskel:: + _facets () const + { +#ifdef XSDE_REUSE_STYLE_TIEIN + if (parent_ != 0) + return static_cast (*parent_).facets_; + else +#endif + return facets_; + } // nmtoken_pskel // -#ifdef XSDE_REUSE_STYLE_TIEIN inline nmtoken_pskel:: nmtoken_pskel () - : nmtoken_impl_ (0) { +#ifdef XSDE_REUSE_STYLE_TIEIN + nmtoken_impl_ = 0; +#endif + _whitespace_facet (2); // collapse } +#ifdef XSDE_REUSE_STYLE_TIEIN inline nmtoken_pskel:: nmtoken_pskel (nmtoken_pskel* impl, void*) : simple_content (impl, 0), nmtoken_impl_ (impl) { + _whitespace_facet (2); // collapse } #endif + inline const string_facets::facets& nmtoken_pskel:: + _facets () const + { +#ifdef XSDE_REUSE_STYLE_TIEIN + if (parent_ != 0) + return static_cast (*parent_).facets_; + else +#endif + return facets_; + } // nmtokens_pskel // @@ -413,51 +494,93 @@ namespace xsde // ncname_pskel // -#ifdef XSDE_REUSE_STYLE_TIEIN inline ncname_pskel:: ncname_pskel () - : ncname_impl_ (0) { +#ifdef XSDE_REUSE_STYLE_TIEIN + ncname_impl_ = 0; +#endif + _whitespace_facet (2); // collapse } +#ifdef XSDE_REUSE_STYLE_TIEIN inline ncname_pskel:: ncname_pskel (ncname_pskel* impl, void*) : simple_content (impl, 0), ncname_impl_ (impl) { + _whitespace_facet (2); // collapse } #endif + inline const string_facets::facets& ncname_pskel:: + _facets () const + { +#ifdef XSDE_REUSE_STYLE_TIEIN + if (parent_ != 0) + return static_cast (*parent_).facets_; + else +#endif + return facets_; + } // id_pskel // -#ifdef XSDE_REUSE_STYLE_TIEIN inline id_pskel:: id_pskel () - : id_impl_ (0) { +#ifdef XSDE_REUSE_STYLE_TIEIN + id_impl_ = 0; +#endif + _whitespace_facet (2); // collapse } +#ifdef XSDE_REUSE_STYLE_TIEIN inline id_pskel:: id_pskel (id_pskel* impl, void*) : simple_content (impl, 0), id_impl_ (impl) { + _whitespace_facet (2); // collapse } #endif + inline const string_facets::facets& id_pskel:: + _facets () const + { +#ifdef XSDE_REUSE_STYLE_TIEIN + if (parent_ != 0) + return static_cast (*parent_).facets_; + else +#endif + return facets_; + } // idref_pskel // -#ifdef XSDE_REUSE_STYLE_TIEIN inline idref_pskel:: idref_pskel () - : idref_impl_ (0) { +#ifdef XSDE_REUSE_STYLE_TIEIN + idref_impl_ = 0; +#endif + _whitespace_facet (2); // collapse } +#ifdef XSDE_REUSE_STYLE_TIEIN inline idref_pskel:: idref_pskel (idref_pskel* impl, void*) : simple_content (impl, 0), idref_impl_ (impl) { + _whitespace_facet (2); // collapse } #endif + inline const string_facets::facets& idref_pskel:: + _facets () const + { +#ifdef XSDE_REUSE_STYLE_TIEIN + if (parent_ != 0) + return static_cast (*parent_).facets_; + else +#endif + return facets_; + } // idrefs_pskel // @@ -477,35 +600,63 @@ namespace xsde // language_pskel // -#ifdef XSDE_REUSE_STYLE_TIEIN inline language_pskel:: language_pskel () - : language_impl_ (0) { +#ifdef XSDE_REUSE_STYLE_TIEIN + language_impl_ = 0; +#endif + _whitespace_facet (2); // collapse } +#ifdef XSDE_REUSE_STYLE_TIEIN inline language_pskel:: language_pskel (language_pskel* impl, void*) : simple_content (impl, 0), language_impl_ (impl) { + _whitespace_facet (2); // collapse } #endif + inline const string_facets::facets& language_pskel:: + _facets () const + { +#ifdef XSDE_REUSE_STYLE_TIEIN + if (parent_ != 0) + return static_cast (*parent_).facets_; + else +#endif + return facets_; + } // uri_pskel // -#ifdef XSDE_REUSE_STYLE_TIEIN inline uri_pskel:: uri_pskel () - : uri_impl_ (0) { +#ifdef XSDE_REUSE_STYLE_TIEIN + uri_impl_ = 0; +#endif + _whitespace_facet (2); // collapse } +#ifdef XSDE_REUSE_STYLE_TIEIN inline uri_pskel:: uri_pskel (uri_pskel* impl, void*) : simple_content (impl, 0), uri_impl_ (impl) { + _whitespace_facet (2); // collapse } #endif + inline const string_facets::facets& uri_pskel:: + _facets () const + { +#ifdef XSDE_REUSE_STYLE_TIEIN + if (parent_ != 0) + return static_cast (*parent_).facets_; + else +#endif + return facets_; + } // qname_pskel // diff --git a/libxsde/xsde/cxx/parser/validating/id-stl.cxx b/libxsde/xsde/cxx/parser/validating/id-stl.cxx index f20fa84..4ac0b63 100644 --- a/libxsde/xsde/cxx/parser/validating/id-stl.cxx +++ b/libxsde/xsde/cxx/parser/validating/id-stl.cxx @@ -39,19 +39,11 @@ namespace xsde void id_pimpl:: _post () { - ro_string tmp (str_); - ro_string::size_type size = trim_right (tmp); - - if (xml::valid_ncname (tmp.data (), size)) - str_.resize (size); - else - { - _schema_error (schema_error::invalid_id_value); + if (!string_common::validate_facets (str_, _facets (), _context ())) return; - } - string_common::validate_facets ( - str_.c_str (), str_.size (), _facets (), _context ()); + if (!xml::valid_ncname (str_.c_str (), str_.size ())) + _schema_error (schema_error::invalid_id_value); } std::string id_pimpl:: diff --git a/libxsde/xsde/cxx/parser/validating/id.cxx b/libxsde/xsde/cxx/parser/validating/id.cxx index d2fb79d..70713be 100644 --- a/libxsde/xsde/cxx/parser/validating/id.cxx +++ b/libxsde/xsde/cxx/parser/validating/id.cxx @@ -60,19 +60,11 @@ namespace xsde void id_pimpl:: _post () { - ro_string tmp (str_.data (), str_.size ()); - ro_string::size_type size = trim_right (tmp); - - if (xml::valid_ncname (tmp.data (), size)) - str_.truncate (size); - else - { - _schema_error (schema_error::invalid_id_value); + if (!string_common::validate_facets (str_, _facets (), _context ())) return; - } - string_common::validate_facets ( - str_.data (), str_.size (), _facets (), _context ()); + if (!xml::valid_ncname (str_.data (), str_.size ())) + _schema_error (schema_error::invalid_id_value); } char* id_pimpl:: diff --git a/libxsde/xsde/cxx/parser/validating/idref-stl.cxx b/libxsde/xsde/cxx/parser/validating/idref-stl.cxx index 93d94dc..73b867b 100644 --- a/libxsde/xsde/cxx/parser/validating/idref-stl.cxx +++ b/libxsde/xsde/cxx/parser/validating/idref-stl.cxx @@ -39,19 +39,11 @@ namespace xsde void idref_pimpl:: _post () { - ro_string tmp (str_); - ro_string::size_type size = trim_right (tmp); - - if (xml::valid_ncname (tmp.data (), size)) - str_.resize (size); - else - { - _schema_error (schema_error::invalid_idref_value); + if (!string_common::validate_facets (str_, _facets (), _context ())) return; - } - string_common::validate_facets ( - str_.c_str (), str_.size (), _facets (), _context ()); + if (!xml::valid_ncname (str_.c_str (), str_.size ())) + _schema_error (schema_error::invalid_idref_value); } std::string idref_pimpl:: diff --git a/libxsde/xsde/cxx/parser/validating/idref.cxx b/libxsde/xsde/cxx/parser/validating/idref.cxx index 58ac4ca..a10da5d 100644 --- a/libxsde/xsde/cxx/parser/validating/idref.cxx +++ b/libxsde/xsde/cxx/parser/validating/idref.cxx @@ -60,19 +60,11 @@ namespace xsde void idref_pimpl:: _post () { - ro_string tmp (str_.data (), str_.size ()); - ro_string::size_type size = trim_right (tmp); - - if (xml::valid_ncname (tmp.data (), size)) - str_.truncate (size); - else - { - _schema_error (schema_error::invalid_idref_value); + if (!string_common::validate_facets (str_, _facets (), _context ())) return; - } - string_common::validate_facets ( - str_.data (), str_.size (), _facets (), _context ()); + if (!xml::valid_ncname (str_.data (), str_.size ())) + _schema_error (schema_error::invalid_idref_value); } char* idref_pimpl:: diff --git a/libxsde/xsde/cxx/parser/validating/language-stl.cxx b/libxsde/xsde/cxx/parser/validating/language-stl.cxx index 61b4a1b..831711f 100644 --- a/libxsde/xsde/cxx/parser/validating/language-stl.cxx +++ b/libxsde/xsde/cxx/parser/validating/language-stl.cxx @@ -37,10 +37,11 @@ namespace xsde void language_pimpl:: _post () { - typedef ro_string::size_type size_type; + if (!string_common::validate_facets (str_, _facets (), _context ())) + return; - ro_string tmp (str_); - size_type size = trim_right (tmp); + typedef std::string::size_type size_type; + size_type size = str_.size (); // language := ALPHA{1,8} *(-(ALPHA | DIGIT){1,8}) // @@ -53,7 +54,7 @@ namespace xsde for (; i < size && n < 8; ++n, ++i) { - char c = tmp[i]; + char c = str_[i]; if (!((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || @@ -70,23 +71,15 @@ namespace xsde if (i == size) break; - if (tmp[i++] != '-') + if (str_[i++] != '-') { ok = false; break; } } - if (ok) - str_.resize (size); - else - { + if (!ok) _schema_error (schema_error::invalid_language_value); - return; - } - - string_common::validate_facets ( - str_.c_str (), str_.size (), _facets (), _context ()); } std::string language_pimpl:: diff --git a/libxsde/xsde/cxx/parser/validating/language.cxx b/libxsde/xsde/cxx/parser/validating/language.cxx index bd39295..196f779 100644 --- a/libxsde/xsde/cxx/parser/validating/language.cxx +++ b/libxsde/xsde/cxx/parser/validating/language.cxx @@ -58,10 +58,11 @@ namespace xsde void language_pimpl:: _post () { - typedef ro_string::size_type size_type; + if (!string_common::validate_facets (str_, _facets (), _context ())) + return; - ro_string tmp (str_); - size_type size = trim_right (tmp); + typedef string::size_type size_type; + size_type size = str_.size (); // language := ALPHA{1,8} *(-(ALPHA | DIGIT){1,8}) // @@ -74,7 +75,7 @@ namespace xsde for (; i < size && n < 8; ++n, ++i) { - char c = tmp[i]; + char c = str_[i]; if (!((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || @@ -91,23 +92,15 @@ namespace xsde if (i == size) break; - if (tmp[i++] != '-') + if (str_[i++] != '-') { ok = false; break; } } - if (ok) - str_.truncate (size); - else - { + if (!ok) _schema_error (schema_error::invalid_language_value); - return; - } - - string_common::validate_facets ( - str_.data (), str_.size (), _facets (), _context ()); } char* language_pimpl:: diff --git a/libxsde/xsde/cxx/parser/validating/name-stl.cxx b/libxsde/xsde/cxx/parser/validating/name-stl.cxx index 942b7cf..945beec 100644 --- a/libxsde/xsde/cxx/parser/validating/name-stl.cxx +++ b/libxsde/xsde/cxx/parser/validating/name-stl.cxx @@ -39,8 +39,11 @@ namespace xsde void name_pimpl:: _post () { - ro_string tmp (str_); - ro_string::size_type size = trim_right (tmp); + if (!string_common::validate_facets (str_, _facets (), _context ())) + return; + + typedef std::string::size_type size_type; + size_type size = str_.size (); // For now we are only checking the US-ASCII characters. // @@ -68,16 +71,8 @@ namespace xsde } } - str_.resize (size); - if (!ok) - { _schema_error (schema_error::invalid_name_value); - return; - } - - string_common::validate_facets ( - str_.c_str (), str_.size (), _facets (), _context ()); } std::string name_pimpl:: diff --git a/libxsde/xsde/cxx/parser/validating/name.cxx b/libxsde/xsde/cxx/parser/validating/name.cxx index 570a6cd..ce73940 100644 --- a/libxsde/xsde/cxx/parser/validating/name.cxx +++ b/libxsde/xsde/cxx/parser/validating/name.cxx @@ -60,8 +60,11 @@ namespace xsde void name_pimpl:: _post () { - ro_string tmp (str_.data (), str_.size ()); - ro_string::size_type size = trim_right (tmp); + if (!string_common::validate_facets (str_, _facets (), _context ())) + return; + + typedef string::size_type size_type; + size_type size = str_.size (); // For now we are only checking the US-ASCII characters. // @@ -89,16 +92,8 @@ namespace xsde } } - str_.truncate (size); - if (!ok) - { _schema_error (schema_error::invalid_name_value); - return; - } - - string_common::validate_facets ( - str_.data (), str_.size (), _facets (), _context ()); } char* name_pimpl:: diff --git a/libxsde/xsde/cxx/parser/validating/ncname-stl.cxx b/libxsde/xsde/cxx/parser/validating/ncname-stl.cxx index 201f463..be42f2f 100644 --- a/libxsde/xsde/cxx/parser/validating/ncname-stl.cxx +++ b/libxsde/xsde/cxx/parser/validating/ncname-stl.cxx @@ -39,19 +39,11 @@ namespace xsde void ncname_pimpl:: _post () { - ro_string tmp (str_); - ro_string::size_type size = trim_right (tmp); - - if (xml::valid_ncname (tmp.data (), size)) - str_.resize (size); - else - { - _schema_error (schema_error::invalid_ncname_value); + if (!string_common::validate_facets (str_, _facets (), _context ())) return; - } - string_common::validate_facets ( - str_.c_str (), str_.size (), _facets (), _context ()); + if (!xml::valid_ncname (str_.c_str (), str_.size ())) + _schema_error (schema_error::invalid_ncname_value); } std::string ncname_pimpl:: diff --git a/libxsde/xsde/cxx/parser/validating/ncname.cxx b/libxsde/xsde/cxx/parser/validating/ncname.cxx index 233ea56..d6af7d6 100644 --- a/libxsde/xsde/cxx/parser/validating/ncname.cxx +++ b/libxsde/xsde/cxx/parser/validating/ncname.cxx @@ -60,19 +60,11 @@ namespace xsde void ncname_pimpl:: _post () { - ro_string tmp (str_.data (), str_.size ()); - ro_string::size_type size = trim_right (tmp); - - if (xml::valid_ncname (tmp.data (), size)) - str_.truncate (size); - else - { - _schema_error (schema_error::invalid_ncname_value); + if (!string_common::validate_facets (str_, _facets (), _context ())) return; - } - string_common::validate_facets ( - str_.data (), str_.size (), _facets (), _context ()); + if (!xml::valid_ncname (str_.data (), str_.size ())) + _schema_error (schema_error::invalid_ncname_value); } char* ncname_pimpl:: diff --git a/libxsde/xsde/cxx/parser/validating/nmtoken-stl.cxx b/libxsde/xsde/cxx/parser/validating/nmtoken-stl.cxx index 62e867b..17ab6a0 100644 --- a/libxsde/xsde/cxx/parser/validating/nmtoken-stl.cxx +++ b/libxsde/xsde/cxx/parser/validating/nmtoken-stl.cxx @@ -39,8 +39,11 @@ namespace xsde void nmtoken_pimpl:: _post () { - ro_string tmp (str_); - ro_string::size_type size = trim_right (tmp); + if (!string_common::validate_facets (str_, _facets (), _context ())) + return; + + typedef std::string::size_type size_type; + size_type size = str_.size (); // For now we are only checking the US-ASCII characters. // @@ -49,7 +52,7 @@ namespace xsde if (ok) { - for (ro_string::size_type i = 0; i < size; ++i) + for (size_type i = 0; i < size; ++i) { unsigned char c = static_cast (str_[i]); @@ -61,16 +64,8 @@ namespace xsde } } - str_.resize (size); - if (!ok) - { _schema_error (schema_error::invalid_nmtoken_value); - return; - } - - string_common::validate_facets ( - str_.c_str (), str_.size (), _facets (), _context ()); } std::string nmtoken_pimpl:: diff --git a/libxsde/xsde/cxx/parser/validating/nmtoken.cxx b/libxsde/xsde/cxx/parser/validating/nmtoken.cxx index cc19602..77da496 100644 --- a/libxsde/xsde/cxx/parser/validating/nmtoken.cxx +++ b/libxsde/xsde/cxx/parser/validating/nmtoken.cxx @@ -60,8 +60,11 @@ namespace xsde void nmtoken_pimpl:: _post () { - ro_string tmp (str_.data (), str_.size ()); - ro_string::size_type size = trim_right (tmp); + if (!string_common::validate_facets (str_, _facets (), _context ())) + return; + + typedef string::size_type size_type; + size_type size = str_.size (); // For now we are only checking the US-ASCII characters. // @@ -70,7 +73,7 @@ namespace xsde if (ok) { - for (ro_string::size_type i = 0; i < size; ++i) + for (size_type i = 0; i < size; ++i) { unsigned char c = static_cast (str_[i]); @@ -82,16 +85,8 @@ namespace xsde } } - str_.truncate (size); - if (!ok) - { _schema_error (schema_error::invalid_nmtoken_value); - return; - } - - string_common::validate_facets ( - str_.data (), str_.size (), _facets (), _context ()); } char* nmtoken_pimpl:: diff --git a/libxsde/xsde/cxx/parser/validating/normalized-string-stl.cxx b/libxsde/xsde/cxx/parser/validating/normalized-string-stl.cxx index f93ecf8..dcbe588 100644 --- a/libxsde/xsde/cxx/parser/validating/normalized-string-stl.cxx +++ b/libxsde/xsde/cxx/parser/validating/normalized-string-stl.cxx @@ -23,24 +23,21 @@ namespace xsde void normalized_string_pimpl:: _characters (const ro_string& s) { - str_ += s; + if (_facets ().whitespace_ == 2 && str_.size () == 0) + { + ro_string tmp (s.data (), s.size ()); + + if (trim_left (tmp) != 0) + str_ += tmp; + } + else + str_ += s; } void normalized_string_pimpl:: _post () { - std::string::size_type size = str_.size (); - - for (std::string::size_type i = 0; i < size; ++i) - { - char& c = str_[i]; - - if (c == 0x0A || c == 0x0D || c == 0x09) - c = 0x20; - } - - string_common::validate_facets ( - str_.c_str (), str_.size (), _facets (), _context ()); + string_common::validate_facets (str_, _facets (), _context ()); } std::string normalized_string_pimpl:: diff --git a/libxsde/xsde/cxx/parser/validating/normalized-string.cxx b/libxsde/xsde/cxx/parser/validating/normalized-string.cxx index 4807846..48af91e 100644 --- a/libxsde/xsde/cxx/parser/validating/normalized-string.cxx +++ b/libxsde/xsde/cxx/parser/validating/normalized-string.cxx @@ -30,31 +30,35 @@ namespace xsde void normalized_string_pimpl:: _characters (const ro_string& s) { + if (_facets ().whitespace_ == 2 && str_.size () == 0) + { + ro_string tmp (s.data (), s.size ()); + + if (trim_left (tmp) != 0) + { #ifdef XSDE_EXCEPTIONS - str_.append (s.data (), s.size ()); + str_.append (tmp.data (), tmp.size ()); #else - if (str_.append (s.data (), s.size ())) - _sys_error (sys_error::no_memory); + if (str_.append (tmp.data (), tmp.size ())) + _sys_error (sys_error::no_memory); +#endif + } + } + else + { +#ifdef XSDE_EXCEPTIONS + str_.append (s.data (), s.size ()); +#else + if (str_.append (s.data (), s.size ())) + _sys_error (sys_error::no_memory); #endif + } } void normalized_string_pimpl:: _post () { - typedef string::size_type size_type; - - size_type size = str_.size (); - - for (size_type i = 0; i < size; ++i) - { - char& c = str_[i]; - - if (c == 0x0A || c == 0x0D || c == 0x09) - c = 0x20; - } - - string_common::validate_facets ( - str_.data (), str_.size (), _facets (), _context ()); + string_common::validate_facets (str_, _facets (), _context ()); } char* normalized_string_pimpl:: diff --git a/libxsde/xsde/cxx/parser/validating/string-common.cxx b/libxsde/xsde/cxx/parser/validating/string-common.cxx index 328f2ce..9558e30 100644 --- a/libxsde/xsde/cxx/parser/validating/string-common.cxx +++ b/libxsde/xsde/cxx/parser/validating/string-common.cxx @@ -15,11 +15,78 @@ namespace xsde namespace validating { bool string_common:: - validate_facets (const char* s, - size_t n, - const string_facets::facets& f, - context& ctx) + validate_facets ( +#ifdef XSDE_STL + std::string& str, +#else + string& str, +#endif + const string_facets::facets& f, + context& ctx) { +#ifdef XSDE_STL + typedef std::string::size_type size_type; +#else + typedef string::size_type size_type; +#endif + + if (f.whitespace_ == 2) + { + // Collapse. The left trimming has already been performed. + // + size_type size = str.size (); + size_type j = 0; + + bool subs = false; + + for (size_type i = 0; i < size; ++i) + { + char c = str[i]; + + if (c == 0x20 || c == 0x0A || c == 0x0D || c == 0x09) + { + subs = true; + } + else + { + if (subs) + { + subs = false; + str[j++] = 0x20; + } + + str[j++] = c; + } + } + +#ifdef XSDE_STL + str.resize (j); +#else + str.truncate (j); +#endif + } + else if (f.whitespace_ == 1) + { + // Replace. + // + size_type size = str.size (); + + for (size_type i = 0; i < size; ++i) + { + char& c = str[i]; + + if (c == 0x0A || c == 0x0D || c == 0x09) + c = 0x20; + } + } + +#ifdef XSDE_STL + const char* s = str.c_str (); +#else + const char* s = str.data (); +#endif + size_t n = str.size (); + if (f.length_set_ && n != f.length_) { ctx.schema_error (schema_error::length_not_equal_prescribed); diff --git a/libxsde/xsde/cxx/parser/validating/string-common.hxx b/libxsde/xsde/cxx/parser/validating/string-common.hxx index 3191a3c..f31fd16 100644 --- a/libxsde/xsde/cxx/parser/validating/string-common.hxx +++ b/libxsde/xsde/cxx/parser/validating/string-common.hxx @@ -6,6 +6,14 @@ #ifndef XSDE_CXX_PARSER_VALIDATING_STRING_COMMON_HXX #define XSDE_CXX_PARSER_VALIDATING_STRING_COMMON_HXX +#include + +#ifdef XSDE_STL +#include +#else +#include +#endif + #include namespace xsde @@ -19,10 +27,14 @@ namespace xsde struct string_common { static bool - validate_facets (const char* s, - size_t n, - const string_facets::facets&, - context&); + validate_facets ( +#ifdef XSDE_STL + std::string& str, +#else + string& str, +#endif + const string_facets::facets&, + context&); }; } } diff --git a/libxsde/xsde/cxx/parser/validating/string-stl.cxx b/libxsde/xsde/cxx/parser/validating/string-stl.cxx index 9e1ad13..e5f8a33 100644 --- a/libxsde/xsde/cxx/parser/validating/string-stl.cxx +++ b/libxsde/xsde/cxx/parser/validating/string-stl.cxx @@ -23,14 +23,21 @@ namespace xsde void string_pimpl:: _characters (const ro_string& s) { - str_ += s; + if (_facets ().whitespace_ == 2 && str_.size () == 0) + { + ro_string tmp (s.data (), s.size ()); + + if (trim_left (tmp) != 0) + str_ += tmp; + } + else + str_ += s; } void string_pimpl:: _post () { - string_common::validate_facets ( - str_.c_str (), str_.size (), _facets (), _context ()); + string_common::validate_facets (str_, _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 3e29a93..73c7edd 100644 --- a/libxsde/xsde/cxx/parser/validating/string.cxx +++ b/libxsde/xsde/cxx/parser/validating/string.cxx @@ -30,19 +30,35 @@ namespace xsde void string_pimpl:: _characters (const ro_string& s) { + if (_facets ().whitespace_ == 2 && str_.size () == 0) + { + ro_string tmp (s.data (), s.size ()); + + if (trim_left (tmp) != 0) + { #ifdef XSDE_EXCEPTIONS - str_.append (s.data (), s.size ()); + str_.append (tmp.data (), tmp.size ()); #else - if (str_.append (s.data (), s.size ())) - _sys_error (sys_error::no_memory); + if (str_.append (tmp.data (), tmp.size ())) + _sys_error (sys_error::no_memory); +#endif + } + } + else + { +#ifdef XSDE_EXCEPTIONS + str_.append (s.data (), s.size ()); +#else + if (str_.append (s.data (), s.size ())) + _sys_error (sys_error::no_memory); #endif + } } void string_pimpl:: _post () { - string_common::validate_facets ( - str_.data (), str_.size (), _facets (), _context ()); + string_common::validate_facets (str_, _facets (), _context ()); } char* string_pimpl:: diff --git a/libxsde/xsde/cxx/parser/validating/token-stl.cxx b/libxsde/xsde/cxx/parser/validating/token-stl.cxx index 5eafe39..8c98e11 100644 --- a/libxsde/xsde/cxx/parser/validating/token-stl.cxx +++ b/libxsde/xsde/cxx/parser/validating/token-stl.cxx @@ -37,35 +37,7 @@ namespace xsde void token_pimpl:: _post () { - std::string::size_type size = str_.size (); - std::string::size_type j = 0; - - bool subs = false; - - for (std::string::size_type i = 0; i < size; ++i) - { - char c = str_[i]; - - if (c == 0x20 || c == 0x0A || c == 0x0D || c == 0x09) - { - subs = true; - } - else - { - if (subs) - { - subs = false; - str_[j++] = 0x20; - } - - str_[j++] = c; - } - } - - str_.resize (j); - - string_common::validate_facets ( - str_.c_str (), str_.size (), _facets (), _context ()); + string_common::validate_facets (str_, _facets (), _context ()); } std::string token_pimpl:: diff --git a/libxsde/xsde/cxx/parser/validating/token.cxx b/libxsde/xsde/cxx/parser/validating/token.cxx index 338fa04..559bb3d 100644 --- a/libxsde/xsde/cxx/parser/validating/token.cxx +++ b/libxsde/xsde/cxx/parser/validating/token.cxx @@ -58,37 +58,7 @@ namespace xsde void token_pimpl:: _post () { - typedef string::size_type size_type; - - size_type size = str_.size (); - size_type j = 0; - - bool subs = false; - - for (size_type i = 0; i < size; ++i) - { - char c = str_[i]; - - if (c == 0x20 || c == 0x0A || c == 0x0D || c == 0x09) - { - subs = true; - } - else - { - if (subs) - { - subs = false; - str_[j++] = 0x20; - } - - str_[j++] = c; - } - } - - str_.truncate (j); - - string_common::validate_facets ( - str_.data (), str_.size (), _facets (), _context ()); + string_common::validate_facets (str_, _facets (), _context ()); } char* token_pimpl:: diff --git a/libxsde/xsde/cxx/parser/validating/uri-stl.cxx b/libxsde/xsde/cxx/parser/validating/uri-stl.cxx index 43538a9..2ec578b 100644 --- a/libxsde/xsde/cxx/parser/validating/uri-stl.cxx +++ b/libxsde/xsde/cxx/parser/validating/uri-stl.cxx @@ -41,11 +41,7 @@ namespace xsde // can be a URI and conforming processors do not need to figure // out and verify particular URI schemes. // - ro_string tmp (str_); - str_.resize (trim_right (tmp)); - - string_common::validate_facets ( - str_.c_str (), str_.size (), _facets (), _context ()); + string_common::validate_facets (str_, _facets (), _context ()); } std::string uri_pimpl:: diff --git a/libxsde/xsde/cxx/parser/validating/uri.cxx b/libxsde/xsde/cxx/parser/validating/uri.cxx index 90f55f2..5acdc41 100644 --- a/libxsde/xsde/cxx/parser/validating/uri.cxx +++ b/libxsde/xsde/cxx/parser/validating/uri.cxx @@ -62,11 +62,7 @@ namespace xsde // can be a URI and conforming processors do not need to figure // out and verify particular URI schemes. // - ro_string tmp (str_); - str_.truncate (trim_right (tmp)); - - string_common::validate_facets ( - str_.data (), str_.size (), _facets (), _context ()); + string_common::validate_facets (str_, _facets (), _context ()); } char* uri_pimpl:: diff --git a/libxsde/xsde/cxx/parser/validating/xml-schema-pskel.hxx b/libxsde/xsde/cxx/parser/validating/xml-schema-pskel.hxx index 4b6b126..1ef1005 100644 --- a/libxsde/xsde/cxx/parser/validating/xml-schema-pskel.hxx +++ b/libxsde/xsde/cxx/parser/validating/xml-schema-pskel.hxx @@ -655,7 +655,7 @@ namespace xsde // // String-based types. If STL is disabled you are getting a C - // string that you have to delete with delete[] (or custom + // string that you have to delete with delete[] (or custom // deallocator if enabled). // @@ -673,6 +673,9 @@ namespace xsde _min_length_facet (size_t); void + _whitespace_facet (unsigned int); + + void _enumeration_facet (const char* const*, size_t count); public: @@ -688,6 +691,12 @@ namespace xsde unsigned int length_set_ : 1; unsigned int min_length_set_ : 1; unsigned int max_length_set_ : 1; + + // 0 - preserve + // 1 - replace + // 2 - collapse + // + unsigned int whitespace_: 2; }; protected: @@ -739,9 +748,9 @@ namespace xsde virtual const char* _dynamic_type () const; #endif + normalized_string_pskel (); #ifdef XSDE_REUSE_STYLE_TIEIN - normalized_string_pskel (); normalized_string_pskel (normalized_string_pskel* impl, void*); protected: @@ -768,9 +777,9 @@ namespace xsde virtual const char* _dynamic_type () const; #endif + token_pskel (); #ifdef XSDE_REUSE_STYLE_TIEIN - token_pskel (); token_pskel (token_pskel* impl, void*); protected: @@ -797,9 +806,9 @@ namespace xsde virtual const char* _dynamic_type () const; #endif + name_pskel (); #ifdef XSDE_REUSE_STYLE_TIEIN - name_pskel (); name_pskel (name_pskel* impl, void*); protected: @@ -826,9 +835,9 @@ namespace xsde virtual const char* _dynamic_type () const; #endif + nmtoken_pskel (); #ifdef XSDE_REUSE_STYLE_TIEIN - nmtoken_pskel (); nmtoken_pskel (nmtoken_pskel* impl, void*); protected: @@ -877,9 +886,9 @@ namespace xsde virtual const char* _dynamic_type () const; #endif + ncname_pskel (); #ifdef XSDE_REUSE_STYLE_TIEIN - ncname_pskel (); ncname_pskel (ncname_pskel* impl, void*); protected: @@ -906,9 +915,9 @@ namespace xsde virtual const char* _dynamic_type () const; #endif + id_pskel (); #ifdef XSDE_REUSE_STYLE_TIEIN - id_pskel (); id_pskel (id_pskel* impl, void*); protected: @@ -935,9 +944,9 @@ namespace xsde virtual const char* _dynamic_type () const; #endif + idref_pskel (); #ifdef XSDE_REUSE_STYLE_TIEIN - idref_pskel (); idref_pskel (idref_pskel* impl, void*); protected: @@ -986,9 +995,9 @@ namespace xsde virtual const char* _dynamic_type () const; #endif + language_pskel (); #ifdef XSDE_REUSE_STYLE_TIEIN - language_pskel (); language_pskel (language_pskel* impl, void*); protected: @@ -1015,9 +1024,9 @@ namespace xsde virtual const char* _dynamic_type () const; #endif + uri_pskel (); #ifdef XSDE_REUSE_STYLE_TIEIN - uri_pskel (); uri_pskel (uri_pskel* impl, void*); protected: diff --git a/libxsde/xsde/cxx/parser/validating/xml-schema-pskel.ixx b/libxsde/xsde/cxx/parser/validating/xml-schema-pskel.ixx index 61a862e..0a8f99a 100644 --- a/libxsde/xsde/cxx/parser/validating/xml-schema-pskel.ixx +++ b/libxsde/xsde/cxx/parser/validating/xml-schema-pskel.ixx @@ -454,6 +454,7 @@ namespace xsde facets_.length_set_ = 0; facets_.min_length_set_ = 0; facets_.max_length_set_ = 0; + facets_.whitespace_ = 0; facets_.enum_ = 0; facets_.enum_count_ = 0; @@ -481,6 +482,12 @@ namespace xsde } inline void string_facets:: + _whitespace_facet (unsigned int v) + { + facets_.whitespace_ = v; + } + + inline void string_facets:: _enumeration_facet (const char* const* e, size_t count) { facets_.enum_ = e; @@ -516,17 +523,21 @@ namespace xsde // normalized_string_pskel // -#ifdef XSDE_REUSE_STYLE_TIEIN inline normalized_string_pskel:: normalized_string_pskel () - : normalized_string_impl_ (0) { +#ifdef XSDE_REUSE_STYLE_TIEIN + normalized_string_impl_ = 0; +#endif + _whitespace_facet (1); // replace } +#ifdef XSDE_REUSE_STYLE_TIEIN inline normalized_string_pskel:: normalized_string_pskel (normalized_string_pskel* impl, void*) : simple_content (impl, 0), normalized_string_impl_ (impl) { + _whitespace_facet (1); // replace } #endif @@ -544,17 +555,21 @@ namespace xsde // token_pskel // -#ifdef XSDE_REUSE_STYLE_TIEIN inline token_pskel:: token_pskel () - : token_impl_ (0) { +#ifdef XSDE_REUSE_STYLE_TIEIN + token_impl_ = 0; +#endif + _whitespace_facet (2); // collapse } +#ifdef XSDE_REUSE_STYLE_TIEIN inline token_pskel:: token_pskel (token_pskel* impl, void*) : simple_content (impl, 0), token_impl_ (impl) { + _whitespace_facet (2); // collapse } #endif inline const string_facets::facets& token_pskel:: @@ -570,17 +585,21 @@ namespace xsde // name_pskel // -#ifdef XSDE_REUSE_STYLE_TIEIN inline name_pskel:: name_pskel () - : name_impl_ (0) { +#ifdef XSDE_REUSE_STYLE_TIEIN + name_impl_ = 0; +#endif + _whitespace_facet (2); // collapse } +#ifdef XSDE_REUSE_STYLE_TIEIN inline name_pskel:: name_pskel (name_pskel* impl, void*) : simple_content (impl, 0), name_impl_ (impl) { + _whitespace_facet (2); // collapse } #endif inline const string_facets::facets& name_pskel:: @@ -596,17 +615,21 @@ namespace xsde // nmtoken_pskel // -#ifdef XSDE_REUSE_STYLE_TIEIN inline nmtoken_pskel:: nmtoken_pskel () - : nmtoken_impl_ (0) { +#ifdef XSDE_REUSE_STYLE_TIEIN + nmtoken_impl_ = 0; +#endif + _whitespace_facet (2); // collapse } +#ifdef XSDE_REUSE_STYLE_TIEIN inline nmtoken_pskel:: nmtoken_pskel (nmtoken_pskel* impl, void*) : simple_content (impl, 0), nmtoken_impl_ (impl) { + _whitespace_facet (2); // collapse } #endif inline const string_facets::facets& nmtoken_pskel:: @@ -638,17 +661,21 @@ namespace xsde // ncname_pskel // -#ifdef XSDE_REUSE_STYLE_TIEIN inline ncname_pskel:: ncname_pskel () - : ncname_impl_ (0) { +#ifdef XSDE_REUSE_STYLE_TIEIN + ncname_impl_ = 0; +#endif + _whitespace_facet (2); // collapse } +#ifdef XSDE_REUSE_STYLE_TIEIN inline ncname_pskel:: ncname_pskel (ncname_pskel* impl, void*) : simple_content (impl, 0), ncname_impl_ (impl) { + _whitespace_facet (2); // collapse } #endif inline const string_facets::facets& ncname_pskel:: @@ -664,17 +691,21 @@ namespace xsde // id_pskel // -#ifdef XSDE_REUSE_STYLE_TIEIN inline id_pskel:: id_pskel () - : id_impl_ (0) { +#ifdef XSDE_REUSE_STYLE_TIEIN + id_impl_ = 0; +#endif + _whitespace_facet (2); // collapse } +#ifdef XSDE_REUSE_STYLE_TIEIN inline id_pskel:: id_pskel (id_pskel* impl, void*) : simple_content (impl, 0), id_impl_ (impl) { + _whitespace_facet (2); // collapse } #endif inline const string_facets::facets& id_pskel:: @@ -690,17 +721,21 @@ namespace xsde // idref_pskel // -#ifdef XSDE_REUSE_STYLE_TIEIN inline idref_pskel:: idref_pskel () - : idref_impl_ (0) { +#ifdef XSDE_REUSE_STYLE_TIEIN + idref_impl_ = 0; +#endif + _whitespace_facet (2); // collapse } +#ifdef XSDE_REUSE_STYLE_TIEIN inline idref_pskel:: idref_pskel (idref_pskel* impl, void*) : simple_content (impl, 0), idref_impl_ (impl) { + _whitespace_facet (2); // collapse } #endif inline const string_facets::facets& idref_pskel:: @@ -732,17 +767,21 @@ namespace xsde // language_pskel // -#ifdef XSDE_REUSE_STYLE_TIEIN inline language_pskel:: language_pskel () - : language_impl_ (0) { +#ifdef XSDE_REUSE_STYLE_TIEIN + language_impl_ = 0; +#endif + _whitespace_facet (2); // collapse } +#ifdef XSDE_REUSE_STYLE_TIEIN inline language_pskel:: language_pskel (language_pskel* impl, void*) : simple_content (impl, 0), language_impl_ (impl) { + _whitespace_facet (2); // collapse } #endif inline const string_facets::facets& language_pskel:: @@ -758,17 +797,21 @@ namespace xsde // uri_pskel // -#ifdef XSDE_REUSE_STYLE_TIEIN inline uri_pskel:: uri_pskel () - : uri_impl_ (0) { +#ifdef XSDE_REUSE_STYLE_TIEIN + uri_impl_ = 0; +#endif + _whitespace_facet (2); // collapse } +#ifdef XSDE_REUSE_STYLE_TIEIN inline uri_pskel:: uri_pskel (uri_pskel* impl, void*) : simple_content (impl, 0), uri_impl_ (impl) { + _whitespace_facet (2); // collapse } #endif inline const string_facets::facets& uri_pskel:: diff --git a/libxsde/xsde/cxx/string-search.cxx b/libxsde/xsde/cxx/string-search.cxx index 10da5f0..bb72a91 100644 --- a/libxsde/xsde/cxx/string-search.cxx +++ b/libxsde/xsde/cxx/string-search.cxx @@ -24,15 +24,16 @@ namespace xsde while (l <= h) { m = l + (h - l) / 2; + r = strcmp (array[m], s); - if (r == 0) + if (r == 0 || l == h) break; if (r < 0) l = m + 1; else - h = m - 1; + h = (m == 0 ? 0 : m - 1); } return r == 0 ? m : size; diff --git a/libxsde/xsde/makefile b/libxsde/xsde/makefile index 2ec1c41..51edf31 100644 --- a/libxsde/xsde/makefile +++ b/libxsde/xsde/makefile @@ -208,6 +208,7 @@ else # validation cxx_tun += \ cxx/parser/non-validating/parser.cxx \ cxx/parser/non-validating/time-zone.cxx \ +cxx/parser/non-validating/string-common.cxx \ cxx/parser/non-validating/xml-schema-pskel.cxx cxx_tun += \ diff --git a/tests/cxx/hybrid/makefile b/tests/cxx/hybrid/makefile index 88d89a2..cef5ffc 100644 --- a/tests/cxx/hybrid/makefile +++ b/tests/cxx/hybrid/makefile @@ -32,6 +32,9 @@ ifeq ($(xsde_encoding),iso8859-1) build_tests += iso8859-1 endif +ifeq ($(xsde_parser_validation),y) +build_tests += choice recursive clone + ifeq ($(xsde_cdr),y) build_tests += binary/cdr endif @@ -39,9 +42,6 @@ endif ifeq ($(xsde_xdr),y) build_tests += binary/xdr endif - -ifeq ($(xsde_parser_validation),y) -build_tests += choice recursive clone endif endif # xsde_iostream diff --git a/xsde/cxx/hybrid/parser-header.cxx b/xsde/cxx/hybrid/parser-header.cxx index d67cdca..e64ac63 100644 --- a/xsde/cxx/hybrid/parser-header.cxx +++ b/xsde/cxx/hybrid/parser-header.cxx @@ -135,13 +135,9 @@ namespace CXX // _post // - if (!options.value () && - !options.value ()) - { - os << "virtual void" << endl - << "_post ();" - << endl; - } + os << "virtual void" << endl + << "_post ();" + << endl; } diff --git a/xsde/cxx/hybrid/parser-source.cxx b/xsde/cxx/hybrid/parser-source.cxx index 94f05df..64d12d6 100644 --- a/xsde/cxx/hybrid/parser-source.cxx +++ b/xsde/cxx/hybrid/parser-source.cxx @@ -335,13 +335,39 @@ namespace CXX // os << "void " << name << "::" << endl << "_characters (const " << string_type << "& s)" + << "{" + << "if (this->_facets ().whitespace_ == 2 &&" << endl + << "this->" << state << ".str_.size () == 0)" + << "{" + << string_type << " tmp (s.data (), s.size ());" + << endl + << "if (::xsde::cxx::trim_left (tmp) != 0)" << "{"; if (stl) - os << "this->" << state << ".str_.append (s.data (), s.size ());"; + os << "this->" << state << ".str_ += tmp;" + << "}" + << "}" + << "else" << endl + << "this->" << state << ".str_ += s;"; else { if (exceptions) + os << "this->" << state << ".str_.append (tmp.data (), " << + "tmp.size ());"; + else + { + os << "if (this->" << state << ".str_.append (" << + "tmp.data (), tmp.size ()))" << endl + << "this->_sys_error (::xsde::cxx::sys_error::no_memory);"; + } + + os << "}" + << "}" + << "else" + << "{"; + + if (exceptions) os << "this->" << state << ".str_.append (s.data (), s.size ());"; else { @@ -349,34 +375,37 @@ namespace CXX "s.data (), s.size ()))" << endl << "this->_sys_error (::xsde::cxx::sys_error::no_memory);"; } + + os << "}"; } os << "}"; // _post // + os << "void " << name << "::" << endl + << "_post ()" + << "{"; + if (!options.value () && !options.value ()) { - // Do facet validation. - // - os << "void " << name << "::" << endl - << "_post ()" - << "{" - << "::xsde::cxx::parser::validating::string_common::" << - "validate_facets (" << endl; - - if (stl) - os << "this->" << state << ".str_.c_str ()," << endl - << "this->" << state << ".str_.size ()," << endl; - else - os << "this->" << state << ".str_.data ()," << endl - << "this->" << state << ".str_.size ()," << endl; + os << "::xsde::cxx::parser::validating::string_common::" << + "validate_facets (" << endl + << "this->" << state << ".str_," << endl + << "this->_facets ()," << endl + << "this->_context ());"; + } + else + { - os << "this->_facets ()," << endl - << "this->_context ());" - << "}"; + os << "::xsde::cxx::parser::non_validating::string_common::" << + "process_facets (" << endl + << "this->" << state << ".str_," << endl + << "this->_facets ());"; } + + os << "}"; } // post @@ -2073,14 +2102,17 @@ namespace CXX Void generate_parser_source (Context& ctx) { - if (ctx.enum_ && - !ctx.options.value () && - !ctx.options.value ()) + if (ctx.enum_) { // We need this functionality for enum mapping. // - ctx.os << "#include " << endl - << endl; + if (!ctx.options.value () && + !ctx.options.value ()) + ctx.os << "#include " << endl + << endl; + else + ctx.os << "#include " << endl + << endl; } { diff --git a/xsde/cxx/parser/elements.cxx b/xsde/cxx/parser/elements.cxx index 7cf1fec..2c138ce 100644 --- a/xsde/cxx/parser/elements.cxx +++ b/xsde/cxx/parser/elements.cxx @@ -193,6 +193,49 @@ namespace CXX return t.context ().get ("p:impl"); } + Boolean Context:: + has_facets (SemanticGraph::Complex& c) + { + if (restriction_p (c)) + { + using SemanticGraph::Restricts; + Restricts& r (dynamic_cast (c.inherits ())); + + if (r.facet_empty ()) + return false; + + SemanticGraph::Type& ub (ultimate_base (c)); + Restricts::FacetIterator end (r.facet_end ()); + + if ((ub.is_a () || + ub.is_a ()) && + r.facet_find (L"whiteSpace") != end) + return true; + + if (validation) + { + if (ub.is_a () || + ub.is_a () || + ub.is_a () || + ub.is_a () || + ub.is_a () || + ub.is_a ()) + { + if (r.facet_find (L"length") != end || + r.facet_find (L"minLength") != end || + r.facet_find (L"maxLength") != end || + r.facet_find (L"minInclusive") != end || + r.facet_find (L"minExclusive") != end || + r.facet_find (L"maxInclusive") != end || + r.facet_find (L"maxExclusive") != end) + return true; + } + } + } + + return false; + } + // Includes // Void TypeForward:: diff --git a/xsde/cxx/parser/elements.hxx b/xsde/cxx/parser/elements.hxx index 4af395f..497577f 100644 --- a/xsde/cxx/parser/elements.hxx +++ b/xsde/cxx/parser/elements.hxx @@ -163,6 +163,11 @@ namespace CXX static String const& eimpl (SemanticGraph::Type&); + + public: + Boolean + has_facets (SemanticGraph::Complex& c); + public: CLI::Options const& options; String& xml_parser; diff --git a/xsde/cxx/parser/parser-header.cxx b/xsde/cxx/parser/parser-header.cxx index f03d588..11176f9 100644 --- a/xsde/cxx/parser/parser-header.cxx +++ b/xsde/cxx/parser/parser-header.cxx @@ -28,13 +28,15 @@ namespace CXX SemanticGraph::Type& base (e.inherits ().base ()); String fq_base (fq_name (base)); - Boolean facets (false); // Whether we need to set facets. + Boolean enum_facets (false); // Whether we need to set enum facets. if (validation) { - StringBasedType t (facets); + StringBasedType t (enum_facets); t.dispatch (e); } + Boolean facets (enum_facets || has_facets (e)); + os << "class " << name << ": public " << (mixin ? "virtual " : "") << fq_base << "{" @@ -101,7 +103,7 @@ namespace CXX << name << " (" << name << "*, void*);"; } - if (facets) + if (enum_facets) { UnsignedLong enum_count (0); @@ -737,6 +739,7 @@ namespace CXX // Boolean hb (c.inherits_p ()); Boolean restriction (restriction_p (c)); + Boolean facets (has_facets (c)); Boolean he (has (c)); Boolean ha (has (c)); @@ -752,35 +755,6 @@ namespace CXX names (c, names_test); } - Boolean facets (false); // Defines facets. - if (validation && restriction) - { - SemanticGraph::Type& ub (ultimate_base (c)); - - if (ub.is_a () || - ub.is_a () || - ub.is_a () || - ub.is_a () || - ub.is_a ()) - { - using SemanticGraph::Restricts; - Restricts& r (dynamic_cast (c.inherits ())); - - if (!r.facet_empty ()) - { - Restricts::FacetIterator end (r.facet_end ()); - facets = - r.facet_find (L"length") != end || - r.facet_find (L"minLength") != end || - r.facet_find (L"maxLength") != end || - r.facet_find (L"minInclusive") != end || - r.facet_find (L"minExclusive") != end || - r.facet_find (L"maxInclusive") != end || - r.facet_find (L"maxExclusive") != end; - } - } - } - // // os << "class " << name << ": public "; diff --git a/xsde/cxx/parser/parser-inline.cxx b/xsde/cxx/parser/parser-inline.cxx index 528ff86..984eca6 100644 --- a/xsde/cxx/parser/parser-inline.cxx +++ b/xsde/cxx/parser/parser-inline.cxx @@ -14,6 +14,61 @@ namespace CXX { namespace { + Void + facet_calls (SemanticGraph::Complex& c, Context& ctx) + { + std::wostream& os (ctx.os); + + using SemanticGraph::Restricts; + Restricts& r (dynamic_cast (c.inherits ())); + + for (Restricts::FacetIterator i (r.facet_begin ()); + i != r.facet_end (); ++i) + { + if (i->first == L"length") + { + os << "this->_length_facet (" << i->second << "UL);"; + } + else if (i->first == L"minLength") + { + os << "this->_min_length_facet (" << i->second << "UL);"; + } + else if (i->first == L"maxLength") + { + os << "this->_max_length_facet (" << i->second << "UL);"; + } + else if (i->first == L"minInclusive") + { + os << "this->_min_facet (" << i->second << ", true);"; + } + else if (i->first == L"minExclusive") + { + os << "this->_min_facet (" << i->second << ", false);"; + } + else if (i->first == L"maxInclusive") + { + os << "this->_max_facet (" << i->second << ", true);"; + } + else if (i->first == L"maxExclusive") + { + os << "this->_max_facet (" << i->second << ", false);"; + } + else if (i->first == L"whiteSpace") + { + os << "this->_whitespace_facet ("; + + if (i->second == L"preserve") + os << "0"; + else if (i->second == L"replace") + os << "1"; + else if (i->second == L"collapse") + os << "2"; + + os << ");"; + } + } + } + struct Enumeration: Traversal::Enumeration, Context { Enumeration (Context& c) @@ -26,21 +81,23 @@ namespace CXX { String const& name (ename (e)); - Boolean facets (false); // Whether we need to set facets. + Boolean enum_facets (false); // Whether we need to set enum facets. if (validation) { - StringBasedType t (facets); + StringBasedType t (enum_facets); t.dispatch (e); } UnsignedLong enum_count (0); - if (facets) + if (enum_facets) { for (Type::NamesIterator i (e.names_begin ()), end (e.names_end ()); i != end; ++i) ++enum_count; } + Boolean facets (enum_facets || has_facets (e)); + if (facets || tiein) os << "// " << name << endl << "//" << endl @@ -51,10 +108,9 @@ namespace CXX os << inl << name << "::" << endl << name << " ()" << endl - << "{" - << "this->_enumeration_facet (_xsde_" << name << "_enums_, " << - enum_count << "UL);" - << "}"; + << "{"; + facet_calls (e, enum_count); + os << "}"; } if (tiein) @@ -76,8 +132,7 @@ namespace CXX << "{"; if (facets) - os << "this->_enumeration_facet (_xsde_" << name << - "_enums_, " << enum_count << "UL);"; + facet_calls (e, enum_count); os << "}"; @@ -89,12 +144,22 @@ namespace CXX << "{"; if (facets) - os << "this->_enumeration_facet (_xsde_" << name << - "_enums_, " << enum_count << "UL);"; + facet_calls (e, enum_count); os << "}"; } } + + private: + Void + facet_calls (Type& e, UnsignedLong enum_count) + { + Parser::facet_calls (e, *this); + + if (enum_count != 0) + os << "this->_enumeration_facet (_xsde_" << ename (e) << + "_enums_, " << enum_count << "UL);"; + } }; // @@ -454,6 +519,7 @@ namespace CXX traverse (Type& c) { Boolean hb (c.inherits_p ()); + Boolean facets (has_facets (c)); Boolean he (has (c)); Boolean ha (has (c)); @@ -469,35 +535,6 @@ namespace CXX Boolean restriction (restriction_p (c)); - Boolean facets (false); // Defines facets. - if (validation && restriction) - { - SemanticGraph::Type& ub (ultimate_base (c)); - - if (ub.is_a () || - ub.is_a () || - ub.is_a () || - ub.is_a () || - ub.is_a ()) - { - using SemanticGraph::Restricts; - Restricts& r (dynamic_cast (c.inherits ())); - - if (!r.facet_empty ()) - { - Restricts::FacetIterator end (r.facet_end ()); - facets = - r.facet_find (L"length") != end || - r.facet_find (L"minLength") != end || - r.facet_find (L"maxLength") != end || - r.facet_find (L"minInclusive") != end || - r.facet_find (L"minExclusive") != end || - r.facet_find (L"maxInclusive") != end || - r.facet_find (L"maxExclusive") != end; - } - } - } - if (!(tiein || facets || (!restriction && (he || ha)) || (validation && (he || hae || hra)))) @@ -643,7 +680,7 @@ namespace CXX os << "{"; if (facets) - facet_calls (c); + facet_calls (c, *this); os << "}"; @@ -721,54 +758,13 @@ namespace CXX os << "{"; if (facets) - facet_calls (c); + facet_calls (c, *this); os << "}"; } } private: - Void - facet_calls (Type& c) - { - using SemanticGraph::Restricts; - Restricts& r (dynamic_cast (c.inherits ())); - - for (Restricts::FacetIterator i (r.facet_begin ()); - i != r.facet_end (); ++i) - { - if (i->first == L"length") - { - os << "this->_length_facet (" << i->second << "UL);"; - } - else if (i->first == L"minLength") - { - os << "this->_min_length_facet (" << i->second << "UL);"; - } - else if (i->first == L"maxLength") - { - os << "this->_max_length_facet (" << i->second << "UL);"; - } - else if (i->first == L"minInclusive") - { - os << "this->_min_facet (" << i->second << ", true);"; - } - else if (i->first == L"minExclusive") - { - os << "this->_min_facet (" << i->second << ", false);"; - } - else if (i->first == L"maxInclusive") - { - os << "this->_max_facet (" << i->second << ", true);"; - } - else if (i->first == L"maxExclusive") - { - os << "this->_max_facet (" << i->second << ", false);"; - } - } - } - - private: // // Traversal::Compositor compositor_accessor_; diff --git a/xsde/cxx/serializer/serializer-header.cxx b/xsde/cxx/serializer/serializer-header.cxx index 3a10942..550d742 100644 --- a/xsde/cxx/serializer/serializer-header.cxx +++ b/xsde/cxx/serializer/serializer-header.cxx @@ -1066,7 +1066,8 @@ namespace CXX ub.is_a () || ub.is_a () || ub.is_a () || - ub.is_a ()) + ub.is_a () || + ub.is_a ()) { using SemanticGraph::Restricts; Restricts& r (dynamic_cast (c.inherits ())); diff --git a/xsde/cxx/serializer/serializer-inline.cxx b/xsde/cxx/serializer/serializer-inline.cxx index e14680e..fe36e4a 100644 --- a/xsde/cxx/serializer/serializer-inline.cxx +++ b/xsde/cxx/serializer/serializer-inline.cxx @@ -441,7 +441,8 @@ namespace CXX ub.is_a () || ub.is_a () || ub.is_a () || - ub.is_a ()) + ub.is_a () || + ub.is_a ()) { using SemanticGraph::Restricts; Restricts& r (dynamic_cast (c.inherits ())); -- cgit v1.1