diff options
Diffstat (limited to 'xsd/libxsd/xsd/cxx/xml')
34 files changed, 4108 insertions, 0 deletions
diff --git a/xsd/libxsd/xsd/cxx/xml/bits/literals.hxx b/xsd/libxsd/xsd/cxx/xml/bits/literals.hxx new file mode 100644 index 0000000..5b9fe99 --- /dev/null +++ b/xsd/libxsd/xsd/cxx/xml/bits/literals.hxx @@ -0,0 +1,83 @@ +// file : xsd/cxx/xml/bits/literals.hxx +// author : Boris Kolpackov <boris@codesynthesis.com> +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSD_CXX_XML_BITS_LITERALS_HXX +#define XSD_CXX_XML_BITS_LITERALS_HXX + +namespace xsd +{ + namespace cxx + { + namespace xml + { + namespace bits + { + template <typename C> + const C* + xml_prefix (); + + template <typename C> + const C* + xml_namespace (); + + template <typename C> + const C* + xmlns_prefix (); + + template <typename C> + const C* + xmlns_namespace (); + + template <typename C> + const C* + xsi_prefix (); + + template <typename C> + const C* + xsi_namespace (); + + template <typename C> + const C* + type (); + + template <typename C> + const C* + nil_lit (); + + template <typename C> + const C* + schema_location (); + + template <typename C> + const C* + no_namespace_schema_location (); + + template <typename C> + const C* + first_prefix (); + + template <typename C> + const C* + second_prefix (); + + template <typename C> + const C* + third_prefix (); + + template <typename C> + const C* + fourth_prefix (); + + template <typename C> + const C* + fifth_prefix (); + } + } + } +} + +#endif // XSD_CXX_XML_BITS_LITERALS_HXX + +#include <xsd/cxx/xml/bits/literals.ixx> diff --git a/xsd/libxsd/xsd/cxx/xml/bits/literals.ixx b/xsd/libxsd/xsd/cxx/xml/bits/literals.ixx new file mode 100644 index 0000000..f0ec6eb --- /dev/null +++ b/xsd/libxsd/xsd/cxx/xml/bits/literals.ixx @@ -0,0 +1,261 @@ +// file : xsd/cxx/xml/bits/literals.ixx +// author : Boris Kolpackov <boris@codesynthesis.com> +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSD_CXX_XML_BITS_LITERALS_IXX +#define XSD_CXX_XML_BITS_LITERALS_IXX + +#endif // XSD_CXX_XML_BITS_LITERALS_IXX + + +#if defined(XSD_USE_CHAR) || !defined(XSD_USE_WCHAR) + +#ifndef XSD_CXX_XML_BITS_LITERALS_IXX_CHAR +#define XSD_CXX_XML_BITS_LITERALS_IXX_CHAR + +namespace xsd +{ + namespace cxx + { + namespace xml + { + namespace bits + { + template <> + inline const char* + xml_prefix<char> () + { + return "xml"; + } + + template <> + inline const char* + xml_namespace<char> () + { + return "http://www.w3.org/XML/1998/namespace"; + } + + template <> + inline const char* + xmlns_prefix<char> () + { + return "xmlns"; + } + + template <> + inline const char* + xmlns_namespace<char> () + { + return "http://www.w3.org/2000/xmlns/"; + } + + template <> + inline const char* + xsi_prefix<char> () + { + return "xsi"; + } + + template <> + inline const char* + xsi_namespace<char> () + { + return "http://www.w3.org/2001/XMLSchema-instance"; + } + + template <> + inline const char* + type<char> () + { + return "type"; + } + + template <> + inline const char* + nil_lit<char> () + { + return "nil"; + } + + template <> + inline const char* + schema_location<char> () + { + return "schemaLocation"; + } + + template <> + inline const char* + no_namespace_schema_location<char> () + { + return "noNamespaceSchemaLocation"; + } + + template <> + inline const char* + first_prefix<char> () + { + return "p1"; + } + + template <> + inline const char* + second_prefix<char> () + { + return "p2"; + } + + template <> + inline const char* + third_prefix<char> () + { + return "p3"; + } + + template <> + inline const char* + fourth_prefix<char> () + { + return "p4"; + } + + template <> + inline const char* + fifth_prefix<char> () + { + return "p5"; + } + } + } + } +} + +#endif // XSD_CXX_XML_BITS_LITERALS_IXX_CHAR +#endif // XSD_USE_CHAR + + +#if defined(XSD_USE_WCHAR) || !defined(XSD_USE_CHAR) + +#ifndef XSD_CXX_XML_BITS_LITERALS_IXX_WCHAR +#define XSD_CXX_XML_BITS_LITERALS_IXX_WCHAR + +namespace xsd +{ + namespace cxx + { + namespace xml + { + namespace bits + { + template <> + inline const wchar_t* + xml_prefix<wchar_t> () + { + return L"xml"; + } + + template <> + inline const wchar_t* + xml_namespace<wchar_t> () + { + return L"http://www.w3.org/XML/1998/namespace"; + } + + template <> + inline const wchar_t* + xmlns_prefix<wchar_t> () + { + return L"xmlns"; + } + + template <> + inline const wchar_t* + xmlns_namespace<wchar_t> () + { + return L"http://www.w3.org/2000/xmlns/"; + } + + template <> + inline const wchar_t* + xsi_prefix<wchar_t> () + { + return L"xsi"; + } + + template <> + inline const wchar_t* + xsi_namespace<wchar_t> () + { + return L"http://www.w3.org/2001/XMLSchema-instance"; + } + + template <> + inline const wchar_t* + type<wchar_t> () + { + return L"type"; + } + + template <> + inline const wchar_t* + nil_lit<wchar_t> () + { + return L"nil"; + } + + template <> + inline const wchar_t* + schema_location<wchar_t> () + { + return L"schemaLocation"; + } + + template <> + inline const wchar_t* + no_namespace_schema_location<wchar_t> () + { + return L"noNamespaceSchemaLocation"; + } + + template <> + inline const wchar_t* + first_prefix<wchar_t> () + { + return L"p1"; + } + + template <> + inline const wchar_t* + second_prefix<wchar_t> () + { + return L"p2"; + } + + template <> + inline const wchar_t* + third_prefix<wchar_t> () + { + return L"p3"; + } + + template <> + inline const wchar_t* + fourth_prefix<wchar_t> () + { + return L"p4"; + } + + template <> + inline const wchar_t* + fifth_prefix<wchar_t> () + { + return L"p5"; + } + } + } + } +} + +#endif // XSD_CXX_XML_BITS_LITERALS_IXX_WCHAR +#endif // XSD_USE_WCHAR diff --git a/xsd/libxsd/xsd/cxx/xml/char-iso8859-1.hxx b/xsd/libxsd/xsd/cxx/xml/char-iso8859-1.hxx new file mode 100644 index 0000000..c8ab507 --- /dev/null +++ b/xsd/libxsd/xsd/cxx/xml/char-iso8859-1.hxx @@ -0,0 +1,72 @@ +// file : xsd/cxx/xml/char-iso8859-1.hxx +// author : Boris Kolpackov <boris@codesynthesis.com> +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSD_CXX_XML_TRANSCODER +#define XSD_CXX_XML_TRANSCODER +#define XSD_CXX_XML_TRANSCODER_CHAR_ISO8859_1 + +#include <string> +#include <cstddef> // std::size_t + +#include <xercesc/util/XercesDefs.hpp> // XMLCh + +#include <xsd/cxx/xml/exceptions.hxx> // invalid_utf16_string + +namespace xsd +{ + namespace cxx + { + namespace xml + { + struct iso8859_1_unrepresentable {}; + + // UTF-16 to/from ISO-8859-1 transcoder. + // + template <typename C> + struct char_iso8859_1_transcoder + { + static std::basic_string<C> + to (const XMLCh* s, std::size_t length); + + static XMLCh* + from (const C* s, std::size_t length); + + // Get/set a replacement for unrepresentable characters. If set to + // 0 (the default value), throw iso8859_1_unrepresentable instead. + // + static C + unrep_char () + { + return unrep_char_; + } + + static void + unrep_char (C c) + { + unrep_char_ = c; + } + + private: + static C unrep_char_; + }; + + typedef char_iso8859_1_transcoder<char> char_transcoder; + } + } +} + +#include <xsd/cxx/xml/char-iso8859-1.txx> + +#else +# ifndef XSD_CXX_XML_TRANSCODER_CHAR_ISO8859_1 + // + // If you get this error, it usually means that either you compiled + // your schemas with different --char-encoding values or you included + // some of the libxsd headers (e.g., xsd/cxx/xml/string.hxx) directly + // without first including the correct xsd/cxx/xml/char-*.hxx header. + // +# error conflicting character encoding detected +# endif +#endif // XSD_CXX_XML_TRANSCODER diff --git a/xsd/libxsd/xsd/cxx/xml/char-iso8859-1.txx b/xsd/libxsd/xsd/cxx/xml/char-iso8859-1.txx new file mode 100644 index 0000000..cbf7cd8 --- /dev/null +++ b/xsd/libxsd/xsd/cxx/xml/char-iso8859-1.txx @@ -0,0 +1,101 @@ +// file : xsd/cxx/xml/char-iso8859-1.txx +// author : Boris Kolpackov <boris@codesynthesis.com> +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#include <xsd/cxx/auto-array.hxx> + +namespace xsd +{ + namespace cxx + { + namespace xml + { + template <typename C> + C char_iso8859_1_transcoder<C>::unrep_char_ = 0; + + template <typename C> + std::basic_string<C> char_iso8859_1_transcoder<C>:: + to (const XMLCh* s, std::size_t len) + { + const XMLCh* end (s + len); + + // Find what the resulting buffer size will be. + // + std::size_t rl (0); + unsigned int u (0); // Four byte UCS-4 char. + + bool valid (true); + const XMLCh* p (s); + + for (; p < end; ++p) + { + if (*p >= 0xD800 && *p <= 0xDBFF) + { + // Make sure we have one more char and it has a valid + // value for the second char in a surrogate pair. + // + if (++p == end || !((*p >= 0xDC00) && (*p <= 0xDFFF))) + { + valid = false; + break; + } + } + + rl++; + } + + if (!valid) + throw invalid_utf16_string (); + + std::basic_string<C> r; + r.reserve (rl + 1); + r.resize (rl); + C* rs (const_cast<C*> (r.c_str ())); + std::size_t i (0); + + p = s; + + // Tight first loop for the common case. + // + for (; p < end && *p < 0x100; ++p) + rs[i++] = C (*p); + + if (p < end && unrep_char_ == 0) + throw iso8859_1_unrepresentable (); + + for (; p < end; ++p) + { + XMLCh x (*p); + + if ((x >= 0xD800) && (x <= 0xDBFF)) + { + u = ((x - 0xD800) << 10) + (*++p - 0xDC00) + 0x10000; + } + else + u = x; + + rs[i++] = u < 0x100 ? C (u) : unrep_char_; + } + + return r; + } + + template <typename C> + XMLCh* char_iso8859_1_transcoder<C>:: + from (const C* s, std::size_t len) + { + const C* end (s + len); + + auto_array<XMLCh> r (new XMLCh[len + 1]); + XMLCh* ir (r.get ()); + + for (const C* p (s); p < end; ++p) + *ir++ = static_cast<unsigned char> (*p); + + *ir = XMLCh (0); + return r.release (); + } + } + } +} diff --git a/xsd/libxsd/xsd/cxx/xml/char-lcp.hxx b/xsd/libxsd/xsd/cxx/xml/char-lcp.hxx new file mode 100644 index 0000000..c100bab --- /dev/null +++ b/xsd/libxsd/xsd/cxx/xml/char-lcp.hxx @@ -0,0 +1,56 @@ +// file : xsd/cxx/xml/char-lcp.hxx +// author : Boris Kolpackov <boris@codesynthesis.com> +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSD_CXX_XML_TRANSCODER +#define XSD_CXX_XML_TRANSCODER +#define XSD_CXX_XML_TRANSCODER_CHAR_LCP + +#include <string> +#include <cstddef> // std::size_t + +#include <xercesc/util/XercesDefs.hpp> // XMLCh + +namespace xsd +{ + namespace cxx + { + namespace xml + { + // UTF-16 to/from Xerces-C++ local code page (LCP) transcoder. + // + // Note that this transcoder has a custom interface due to Xerces-C++ + // idiosyncrasies. Don't use it as a base for your custom transcoder. + // + template <typename C> + struct char_lcp_transcoder + { + static std::basic_string<C> + to (const XMLCh* s); + + static std::basic_string<C> + to (const XMLCh* s, std::size_t length); + + static XMLCh* + from (const C* s); + }; + + typedef char_lcp_transcoder<char> char_transcoder; + } + } +} + +#include <xsd/cxx/xml/char-lcp.txx> + +#else +# ifndef XSD_CXX_XML_TRANSCODER_CHAR_LCP + // + // If you get this error, it usually means that either you compiled + // your schemas with different --char-encoding values or you included + // some of the libxsd headers (e.g., xsd/cxx/xml/string.hxx) directly + // without first including the correct xsd/cxx/xml/char-*.hxx header. + // +# error conflicting character encoding detected +# endif +#endif // XSD_CXX_XML_TRANSCODER diff --git a/xsd/libxsd/xsd/cxx/xml/char-lcp.txx b/xsd/libxsd/xsd/cxx/xml/char-lcp.txx new file mode 100644 index 0000000..4603537 --- /dev/null +++ b/xsd/libxsd/xsd/cxx/xml/char-lcp.txx @@ -0,0 +1,55 @@ +// file : xsd/cxx/xml/char-lcp.txx +// author : Boris Kolpackov <boris@codesynthesis.com> +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#include <cstring> // std::memcpy + +#include <xercesc/util/XMLString.hpp> + +#include <xsd/cxx/auto-array.hxx> +#include <xsd/cxx/xml/std-memory-manager.hxx> + +namespace xsd +{ + namespace cxx + { + namespace xml + { + template <typename C> + std::basic_string<C> char_lcp_transcoder<C>:: + to (const XMLCh* s) + { + std_memory_manager mm; + auto_array<C, std_memory_manager> r ( + xercesc::XMLString::transcode (s, &mm), mm); + return std::basic_string<C> (r.get ()); + } + + template <typename C> + std::basic_string<C> char_lcp_transcoder<C>:: + to (const XMLCh* s, std::size_t len) + { + auto_array<XMLCh> tmp (new XMLCh[len + 1]); + std::memcpy (tmp.get (), s, len * sizeof (XMLCh)); + tmp[len] = XMLCh (0); + + std_memory_manager mm; + auto_array<C, std_memory_manager> r ( + xercesc::XMLString::transcode (tmp.get (), &mm), mm); + + tmp.reset (); + + return std::basic_string<C> (r.get ()); + } + + template <typename C> + XMLCh* char_lcp_transcoder<C>:: + from (const C* s) + { + std_memory_manager mm; + return xercesc::XMLString::transcode (s, &mm); + } + } + } +} diff --git a/xsd/libxsd/xsd/cxx/xml/char-utf8.hxx b/xsd/libxsd/xsd/cxx/xml/char-utf8.hxx new file mode 100644 index 0000000..719881b --- /dev/null +++ b/xsd/libxsd/xsd/cxx/xml/char-utf8.hxx @@ -0,0 +1,57 @@ +// file : xsd/cxx/xml/char-utf8.hxx +// author : Boris Kolpackov <boris@codesynthesis.com> +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSD_CXX_XML_TRANSCODER +#define XSD_CXX_XML_TRANSCODER +#define XSD_CXX_XML_TRANSCODER_CHAR_UTF8 + +#include <string> +#include <cstddef> // std::size_t + +#include <xercesc/util/XercesDefs.hpp> // XMLCh + +#include <xsd/cxx/xml/exceptions.hxx> // invalid_utf16_string + +namespace xsd +{ + namespace cxx + { + namespace xml + { + struct invalid_utf8_string {}; + + // UTF-16 to/from UTF-8 transcoder. + // + template <typename C> + struct char_utf8_transcoder + { + static std::basic_string<C> + to (const XMLCh* s, std::size_t length); + + static XMLCh* + from (const C* s, std::size_t length); + + private: + static const unsigned char first_byte_mask_[5]; + }; + + typedef char_utf8_transcoder<char> char_transcoder; + } + } +} + +#include <xsd/cxx/xml/char-utf8.txx> + +#else +# ifndef XSD_CXX_XML_TRANSCODER_CHAR_UTF8 + // + // If you get this error, it usually means that either you compiled + // your schemas with different --char-encoding values or you included + // some of the libxsd headers (e.g., xsd/cxx/xml/string.hxx) directly + // without first including the correct xsd/cxx/xml/char-*.hxx header. + // +# error conflicting character encoding detected +# endif +#endif // XSD_CXX_XML_TRANSCODER diff --git a/xsd/libxsd/xsd/cxx/xml/char-utf8.txx b/xsd/libxsd/xsd/cxx/xml/char-utf8.txx new file mode 100644 index 0000000..9935daf --- /dev/null +++ b/xsd/libxsd/xsd/cxx/xml/char-utf8.txx @@ -0,0 +1,293 @@ +// file : xsd/cxx/xml/char-utf8.txx +// author : Boris Kolpackov <boris@codesynthesis.com> +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#include <xsd/cxx/auto-array.hxx> + +namespace xsd +{ + namespace cxx + { + namespace xml + { + template <typename C> + const unsigned char char_utf8_transcoder<C>::first_byte_mask_[5] = + { + 0x00, 0x00, 0xC0, 0xE0, 0xF0 + }; + + template <typename C> + std::basic_string<C> char_utf8_transcoder<C>:: + to (const XMLCh* s, std::size_t len) + { + const XMLCh* end (s + len); + + // Find what the resulting buffer size will be. + // + std::size_t rl (0); + unsigned int u (0); // Four byte UCS-4 char. + + bool valid (true); + const XMLCh* p (s); + + for (; p < end; ++p) + { + XMLCh x (*p); + + if (x < 0xD800 || x > 0xDBFF) + u = x; + else + { + // Make sure we have one more char and it has a valid + // value for the second char in a surrogate pair. + // + if (++p == end || !((*p >= 0xDC00) && (*p <= 0xDFFF))) + { + valid = false; + break; + } + + u = ((x - 0xD800) << 10) + (*p - 0xDC00) + 0x10000; + } + + if (u < 0x80) + rl++; + else if (u < 0x800) + rl += 2; + else if (u < 0x10000) + rl += 3; + else if (u < 0x110000) + rl += 4; + else + { + valid = false; + break; + } + } + + if (!valid) + throw invalid_utf16_string (); + + std::basic_string<C> r; + r.reserve (rl + 1); + r.resize (rl); + C* rs (const_cast<C*> (r.c_str ())); + + std::size_t i (0); + unsigned int count (0); + + p = s; + + // Tight first loop for the common case. + // + for (; p < end && *p < 0x80; ++p) + rs[i++] = C (*p); + + for (; p < end; ++p) + { + XMLCh x (*p); + + if ((x >= 0xD800) && (x <= 0xDBFF)) + { + u = ((x - 0xD800) << 10) + (*++p - 0xDC00) + 0x10000; + } + else + u = x; + + if (u < 0x80) + count = 1; + else if (u < 0x800) + count = 2; + else if (u < 0x10000) + count = 3; + else if (u < 0x110000) + count = 4; + + switch(count) + { + case 4: + { + rs[i + 3] = C ((u | 0x80UL) & 0xBFUL); + u >>= 6; + } + case 3: + { + rs[i + 2] = C ((u | 0x80UL) & 0xBFUL); + u >>= 6; + } + case 2: + { + rs[i + 1] = C ((u | 0x80UL) & 0xBFUL); + u >>= 6; + } + case 1: + { + rs[i] = C (u | first_byte_mask_[count]); + } + } + + i += count; + } + + return r; + } + + template <typename C> + XMLCh* char_utf8_transcoder<C>:: + from (const C* s, std::size_t len) + { + bool valid (true); + const C* end (s + len); + + // Find what the resulting buffer size will be. + // + std::size_t rl (0); + unsigned int count (0); + + for (const C* p (s); p < end; ++p) + { + unsigned char c (*p); + + if (c < 0x80) + { + // Fast path. + // + rl += 1; + continue; + } + else if ((c >> 5) == 0x06) + count = 2; + else if ((c >> 4) == 0x0E) + count = 3; + else if ((c >> 3) == 0x1E) + count = 4; + else + { + valid = false; + break; + } + + p += count - 1; // One will be added in the for loop + + if (p + 1 > end) + { + valid = false; + break; + } + + // BMP is represented by up to 3 code points in UTF-8. + // + rl += count > 3 ? 2 : 1; + } + + if (!valid) + throw invalid_utf8_string (); + + auto_array<XMLCh> r (new XMLCh[rl + 1]); + XMLCh* ir (r.get ()); + + unsigned int u (0); // Four byte UCS-4 char. + + for (const C* p (s); p < end; ++p) + { + unsigned char c (*p); + + if (c < 0x80) + { + // Fast path. + // + *ir++ = static_cast<XMLCh> (c); + continue; + } + else if ((c >> 5) == 0x06) + { + // UTF-8: 110yyyyy 10zzzzzz + // Unicode: 00000yyy yyzzzzzz + // + u = (c & 0x1F) << 6; + + c = *++p; + if ((c >> 6) != 2) + { + valid = false; + break; + } + u |= c & 0x3F; + } + else if ((c >> 4) == 0x0E) + { + // UTF-8: 1110xxxx 10yyyyyy 10zzzzzz + // Unicode: xxxxyyyy yyzzzzzz + // + u = (c & 0x0F) << 6; + + c = *++p; + if ((c >> 6) != 2) + { + valid = false; + break; + } + u = (u | (c & 0x3F)) << 6; + + c = *++p; + if ((c >> 6) != 2) + { + valid = false; + break; + } + u |= c & 0x3F; + } + else if ((c >> 3) == 0x1E) + { + // UTF-8: 000wwwxx xxxxyyyy yyzzzzzz + // Unicode: 11110www 10xxxxxx 10yyyyyy 10zzzzzz + // + u = (c & 0x07) << 6; + + c = *++p; + if ((c >> 6) != 2) + { + valid = false; + break; + } + u = (u | (c & 0x3F)) << 6; + + c = *++p; + if ((c >> 6) != 2) + { + valid = false; + break; + } + u = (u | (c & 0x3F)) << 6; + + c = *++p; + if ((c >> 6) != 2) + { + valid = false; + break; + } + u |= c & 0x3F; + } + + if (u & 0xFFFF0000) + { + // Surrogate pair. + // + *ir++ = static_cast<XMLCh> (((u - 0x10000) >> 10) + 0xD800); + *ir++ = static_cast<XMLCh> ((u & 0x3FF) + 0xDC00); + } + else + *ir++ = static_cast<XMLCh> (u); + } + + if (!valid) + throw invalid_utf8_string (); + + *ir = XMLCh (0); + + return r.release (); + } + } + } +} diff --git a/xsd/libxsd/xsd/cxx/xml/dom/auto-ptr.hxx b/xsd/libxsd/xsd/cxx/xml/dom/auto-ptr.hxx new file mode 100644 index 0000000..f22e652 --- /dev/null +++ b/xsd/libxsd/xsd/cxx/xml/dom/auto-ptr.hxx @@ -0,0 +1,158 @@ +// file : xsd/cxx/xml/dom/auto-ptr.hxx +// author : Boris Kolpackov <boris@codesynthesis.com> +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSD_CXX_XML_DOM_AUTO_PTR_HXX +#define XSD_CXX_XML_DOM_AUTO_PTR_HXX + +namespace xsd +{ + namespace cxx + { + namespace xml + { + namespace dom + { + // Simple auto_ptr version that calls release() instead of delete. + // + + template <typename T> + struct remove_c + { + typedef T r; + }; + + template <typename T> + struct remove_c<const T> + { + typedef T r; + }; + + template <typename T> + struct auto_ptr_ref + { + T* x_; + + explicit + auto_ptr_ref (T* x) + : x_ (x) + { + } + }; + + template <typename T> + struct auto_ptr + { + ~auto_ptr () + { + reset (); + } + + explicit + auto_ptr (T* x = 0) + : x_ (x) + { + } + + auto_ptr (auto_ptr& y) + : x_ (y.release ()) + { + } + + template <typename T2> + auto_ptr (auto_ptr<T2>& y) + : x_ (y.release ()) + { + } + + auto_ptr (auto_ptr_ref<T> r) + : x_ (r.x_) + { + } + + auto_ptr& + operator= (auto_ptr& y) + { + if (x_ != y.x_) + reset (y.release ()); + + return *this; + } + + template <typename T2> + auto_ptr& + operator= (auto_ptr<T2>& y) + { + if (x_ != y.x_) + reset (y.release ()); + + return *this; + } + + auto_ptr& + operator= (auto_ptr_ref<T> r) + { + if (r.x_ != x_) + reset (r.x_); + + return *this; + } + + template <typename T2> + operator auto_ptr_ref<T2> () + { + return auto_ptr_ref<T2> (release ()); + } + + template <typename T2> + operator auto_ptr<T2> () + { + return auto_ptr<T2> (release ()); + } + + public: + T& + operator* () const + { + return *x_; + } + + T* + operator-> () const + { + return x_; + } + + T* + get () const + { + return x_; + } + + T* + release () + { + T* x (x_); + x_ = 0; + return x; + } + + void + reset (T* x = 0) + { + if (x_) + const_cast<typename remove_c<T>::r*> (x_)->release (); + + x_ = x; + } + + private: + T* x_; + }; + } + } + } +} + +#endif // XSD_CXX_XML_DOM_AUTO_PTR_HXX diff --git a/xsd/libxsd/xsd/cxx/xml/dom/bits/error-handler-proxy.hxx b/xsd/libxsd/xsd/cxx/xml/dom/bits/error-handler-proxy.hxx new file mode 100644 index 0000000..83e9a7e --- /dev/null +++ b/xsd/libxsd/xsd/cxx/xml/dom/bits/error-handler-proxy.hxx @@ -0,0 +1,61 @@ +// file : xsd/cxx/xml/dom/bits/error-handler-proxy.hxx +// author : Boris Kolpackov <boris@codesynthesis.com> +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSD_CXX_XML_DOM_BITS_ERROR_HANDLER_PROXY_HXX +#define XSD_CXX_XML_DOM_BITS_ERROR_HANDLER_PROXY_HXX + +#include <xercesc/dom/DOMError.hpp> +#include <xercesc/dom/DOMLocator.hpp> +#include <xercesc/dom/DOMErrorHandler.hpp> + +#include <xsd/cxx/xml/error-handler.hxx> + +namespace xsd +{ + namespace cxx + { + namespace xml + { + namespace dom + { + namespace bits + { + template <typename C> + class error_handler_proxy: public xercesc::DOMErrorHandler + { + public: + error_handler_proxy (error_handler<C>& eh) + : failed_ (false), eh_ (&eh), native_eh_ (0) + { + } + + error_handler_proxy (xercesc::DOMErrorHandler& eh) + : failed_ (false), eh_ (0), native_eh_ (&eh) + { + } + + virtual bool + handleError (const xercesc::DOMError& e); + + bool + failed () const + { + return failed_; + } + + private: + bool failed_; + error_handler<C>* eh_; + xercesc::DOMErrorHandler* native_eh_; + }; + } + } + } + } +} + +#include <xsd/cxx/xml/dom/bits/error-handler-proxy.txx> + +#endif // XSD_CXX_XML_DOM_BITS_ERROR_HANDLER_PROXY_HXX diff --git a/xsd/libxsd/xsd/cxx/xml/dom/bits/error-handler-proxy.txx b/xsd/libxsd/xsd/cxx/xml/dom/bits/error-handler-proxy.txx new file mode 100644 index 0000000..23e71cd --- /dev/null +++ b/xsd/libxsd/xsd/cxx/xml/dom/bits/error-handler-proxy.txx @@ -0,0 +1,80 @@ +// file : xsd/cxx/xml/dom/bits/error-handler-proxy.txx +// author : Boris Kolpackov <boris@codesynthesis.com> +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#include <xsd/cxx/xml/string.hxx> + +namespace xsd +{ + namespace cxx + { + namespace xml + { + namespace dom + { + namespace bits + { + template <typename C> + bool error_handler_proxy<C>:: + handleError (const xercesc::DOMError& e) + { + using xercesc::DOMError; + + if (e.getSeverity() != DOMError::DOM_SEVERITY_WARNING) + failed_ = true; + + if (native_eh_) + return native_eh_->handleError (e); + else + { + typedef typename error_handler<C>::severity severity; + + severity s (severity::error); + + switch (e.getSeverity()) + { + case DOMError::DOM_SEVERITY_WARNING: + { + s = severity::warning; + break; + } + case DOMError::DOM_SEVERITY_ERROR: + { + s = severity::error; + break; + } + case DOMError::DOM_SEVERITY_FATAL_ERROR: + { + s = severity::fatal; + break; + } + } + + xercesc::DOMLocator* loc (e.getLocation ()); + +#if _XERCES_VERSION >= 30000 + return eh_->handle ( + transcode<C> (loc->getURI ()), + static_cast<unsigned long> (loc->getLineNumber ()), + static_cast<unsigned long> (loc->getColumnNumber ()), + s, + transcode<C> (e.getMessage ())); +#else + XMLSSize_t l (loc->getLineNumber ()); + XMLSSize_t c (loc->getColumnNumber ()); + + return eh_->handle ( + transcode<C> (loc->getURI ()), + (l == -1 ? 0 : static_cast<unsigned long> (l)), + (c == -1 ? 0 : static_cast<unsigned long> (c)), + s, + transcode<C> (e.getMessage ())); +#endif + } + } + } + } + } + } +} diff --git a/xsd/libxsd/xsd/cxx/xml/dom/elements.hxx b/xsd/libxsd/xsd/cxx/xml/dom/elements.hxx new file mode 100644 index 0000000..e8ce8d2 --- /dev/null +++ b/xsd/libxsd/xsd/cxx/xml/dom/elements.hxx @@ -0,0 +1,36 @@ +// file : xsd/cxx/xml/dom/elements.hxx +// author : Boris Kolpackov <boris@codesynthesis.com> +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSD_CXX_XML_DOM_ELEMENTS_HXX +#define XSD_CXX_XML_DOM_ELEMENTS_HXX + +#include <xercesc/dom/DOMAttr.hpp> +#include <xercesc/dom/DOMElement.hpp> + +#include <xsd/cxx/xml/qualified-name.hxx> + +namespace xsd +{ + namespace cxx + { + namespace xml + { + namespace dom + { + template <typename C> + qualified_name<C> + name (const xercesc::DOMAttr&); + + template <typename C> + qualified_name<C> + name (const xercesc::DOMElement&); + } + } + } +} + +#include <xsd/cxx/xml/dom/elements.txx> + +#endif // XSD_CXX_XML_DOM_ELEMENTS_HXX diff --git a/xsd/libxsd/xsd/cxx/xml/dom/elements.txx b/xsd/libxsd/xsd/cxx/xml/dom/elements.txx new file mode 100644 index 0000000..540d0fb --- /dev/null +++ b/xsd/libxsd/xsd/cxx/xml/dom/elements.txx @@ -0,0 +1,57 @@ +// file : xsd/cxx/xml/dom/elements.txx +// author : Boris Kolpackov <boris@codesynthesis.com> +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#include <xsd/cxx/xml/string.hxx> + +namespace xsd +{ + namespace cxx + { + namespace xml + { + namespace dom + { + template <typename C> + qualified_name<C> + name (const xercesc::DOMAttr& a) + { + const XMLCh* n (a.getLocalName ()); + + // If this DOM doesn't support namespaces then use getName. + // + if (n != 0) + { + if (const XMLCh* ns = a.getNamespaceURI ()) + return qualified_name<C> (transcode<C> (n), transcode<C> (ns)); + else + return qualified_name<C> (transcode<C> (n)); + } + else + return qualified_name<C> (transcode<C> (a.getName ())); + } + + + template <typename C> + qualified_name<C> + name (const xercesc::DOMElement& e) + { + const XMLCh* n (e.getLocalName ()); + + // If this DOM doesn't support namespaces then use getTagName. + // + if (n != 0) + { + if (const XMLCh* ns = e.getNamespaceURI ()) + return qualified_name<C> (transcode<C> (n), transcode<C> (ns)); + else + return qualified_name<C> (transcode<C> (n)); + } + else + return qualified_name<C> (transcode<C> (e.getTagName ())); + } + } + } + } +} diff --git a/xsd/libxsd/xsd/cxx/xml/dom/parsing-header.hxx b/xsd/libxsd/xsd/cxx/xml/dom/parsing-header.hxx new file mode 100644 index 0000000..d9a3695 --- /dev/null +++ b/xsd/libxsd/xsd/cxx/xml/dom/parsing-header.hxx @@ -0,0 +1,24 @@ +// file : xsd/cxx/xml/dom/parsing-header.hxx +// author : Boris Kolpackov <boris@codesynthesis.com> +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSD_CXX_XML_DOM_PARSING_HEADER_HXX +#define XSD_CXX_XML_DOM_PARSING_HEADER_HXX + +namespace xsd +{ + namespace cxx + { + namespace xml + { + namespace dom + { + template <typename C> + class parser; + } + } + } +} + +#endif // XSD_CXX_XML_DOM_PARSING_HEADER_HXX diff --git a/xsd/libxsd/xsd/cxx/xml/dom/parsing-source.hxx b/xsd/libxsd/xsd/cxx/xml/dom/parsing-source.hxx new file mode 100644 index 0000000..2c90cf3 --- /dev/null +++ b/xsd/libxsd/xsd/cxx/xml/dom/parsing-source.hxx @@ -0,0 +1,138 @@ +// file : xsd/cxx/xml/dom/parsing-source.hxx +// author : Boris Kolpackov <boris@codesynthesis.com> +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSD_CXX_XML_DOM_PARSING_SOURCE_HXX +#define XSD_CXX_XML_DOM_PARSING_SOURCE_HXX + +#include <string> + +#include <xercesc/dom/DOMNode.hpp> +#include <xercesc/dom/DOMAttr.hpp> +#include <xercesc/dom/DOMElement.hpp> +#include <xercesc/dom/DOMDocument.hpp> +#include <xercesc/dom/DOMNamedNodeMap.hpp> +#include <xercesc/dom/DOMErrorHandler.hpp> + +#include <xercesc/sax/InputSource.hpp> + +#include <xsd/cxx/xml/elements.hxx> // properies +#include <xsd/cxx/xml/error-handler.hxx> + +#include <xsd/cxx/xml/dom/auto-ptr.hxx> +#include <xsd/cxx/xml/dom/elements.hxx> // name +#include <xsd/cxx/xml/dom/parsing-header.hxx> + +namespace xsd +{ + namespace cxx + { + namespace xml + { + namespace dom + { + // Parser state object. Can be used for parsing element, attributes, + // or both. + // + template <typename C> + class parser + { + public: + parser (const xercesc::DOMElement& e, bool ep, bool ap); + + bool + more_elements () + { + return next_element_ != 0; + } + + const xercesc::DOMElement& + cur_element () + { + return *static_cast<const xercesc::DOMElement*> (next_element_); + } + + void + next_element (); + + bool + more_attributes () + { + return as_ > ai_; + } + + const xercesc::DOMAttr& + next_attribute () + { + return *static_cast<const xercesc::DOMAttr*> (a_->item (ai_++)); + } + + void + reset_attributes () + { + ai_ = 0; + } + + const xercesc::DOMElement& + element () const + { + return element_; + } + + private: + parser (const parser&); + + parser& + operator= (const parser&); + + private: + const xercesc::DOMElement& element_; + const xercesc::DOMNode* next_element_; + + const xercesc::DOMNamedNodeMap* a_; + XMLSize_t ai_; // Index of the next DOMAttr. + XMLSize_t as_; // Cached size of a_. + }; + + + // Parsing flags. + // + const unsigned long dont_validate = 0x00000400UL; + const unsigned long no_muliple_imports = 0x00000800UL; + + template <typename C> + xml::dom::auto_ptr<xercesc::DOMDocument> + parse (xercesc::InputSource&, + error_handler<C>&, + const properties<C>&, + unsigned long flags); + + template <typename C> + xml::dom::auto_ptr<xercesc::DOMDocument> + parse (xercesc::InputSource&, + xercesc::DOMErrorHandler&, + const properties<C>&, + unsigned long flags); + + template <typename C> + xml::dom::auto_ptr<xercesc::DOMDocument> + parse (const std::basic_string<C>& uri, + error_handler<C>&, + const properties<C>&, + unsigned long flags); + + template <typename C> + xml::dom::auto_ptr<xercesc::DOMDocument> + parse (const std::basic_string<C>& uri, + xercesc::DOMErrorHandler&, + const properties<C>&, + unsigned long flags); + } + } + } +} + +#include <xsd/cxx/xml/dom/parsing-source.txx> + +#endif // XSD_CXX_XML_DOM_PARSING_SOURCE_HXX diff --git a/xsd/libxsd/xsd/cxx/xml/dom/parsing-source.txx b/xsd/libxsd/xsd/cxx/xml/dom/parsing-source.txx new file mode 100644 index 0000000..50fa285 --- /dev/null +++ b/xsd/libxsd/xsd/cxx/xml/dom/parsing-source.txx @@ -0,0 +1,510 @@ +// file : xsd/cxx/xml/dom/parsing-source.txx +// author : Boris Kolpackov <boris@codesynthesis.com> +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#if _XERCES_VERSION >= 30000 +# include <xercesc/dom/DOMLSParser.hpp> +# include <xercesc/dom/DOMLSException.hpp> +#else +# include <xercesc/dom/DOMBuilder.hpp> +#endif +#include <xercesc/dom/DOMNamedNodeMap.hpp> +#include <xercesc/dom/DOMImplementation.hpp> +#include <xercesc/dom/DOMImplementationRegistry.hpp> + +#include <xercesc/util/XMLUni.hpp> // xercesc::fg* +#include <xercesc/util/XMLUniDefs.hpp> // chLatin_L, etc + +#include <xercesc/framework/Wrapper4InputSource.hpp> + +#include <xsd/cxx/xml/string.hxx> +#include <xsd/cxx/xml/dom/bits/error-handler-proxy.hxx> + +namespace xsd +{ + namespace cxx + { + namespace xml + { + namespace dom + { + // parser + // + template <typename C> + parser<C>:: + parser (const xercesc::DOMElement& e, bool ep, bool ap) + : element_ (e), + next_element_ (0), + a_ (0), + ai_ (0) + { + using xercesc::DOMNode; + + if (ep) + { + for (next_element_ = e.getFirstChild (); + next_element_ != 0 && + next_element_->getNodeType () != DOMNode::ELEMENT_NODE; + next_element_ = next_element_->getNextSibling ()) /*noop*/; + } + + if (ap) + { + a_ = e.getAttributes (); + as_ = a_->getLength (); + } + } + + template <typename C> + void parser<C>:: + next_element () + { + using xercesc::DOMNode; + + for (next_element_ = next_element_->getNextSibling (); + next_element_ != 0 && + next_element_->getNodeType () != DOMNode::ELEMENT_NODE; + next_element_ = next_element_->getNextSibling ())/*noop*/; + } + + // parse() + // + template <typename C> + xml::dom::auto_ptr<xercesc::DOMDocument> + parse (xercesc::InputSource& is, + error_handler<C>& eh, + const properties<C>& prop, + unsigned long flags) + { + bits::error_handler_proxy<C> ehp (eh); + return xml::dom::parse (is, ehp, prop, flags); + } + + template <typename C> + auto_ptr<xercesc::DOMDocument> + parse (xercesc::InputSource& is, + xercesc::DOMErrorHandler& eh, + const properties<C>& prop, + unsigned long flags) + { + // HP aCC cannot handle using namespace xercesc; + // + using xercesc::DOMImplementationRegistry; + using xercesc::DOMImplementationLS; + using xercesc::DOMImplementation; + using xercesc::DOMDocument; +#if _XERCES_VERSION >= 30000 + using xercesc::DOMLSParser; + using xercesc::DOMConfiguration; +#else + using xercesc::DOMBuilder; +#endif + + using xercesc::Wrapper4InputSource; + using xercesc::XMLUni; + + + // Instantiate the DOM parser. + // + const XMLCh ls_id[] = {xercesc::chLatin_L, + xercesc::chLatin_S, + xercesc::chNull}; + + // Get an implementation of the Load-Store (LS) interface. + // + DOMImplementation* impl ( + DOMImplementationRegistry::getDOMImplementation (ls_id)); + +#if _XERCES_VERSION >= 30000 + auto_ptr<DOMLSParser> parser ( + impl->createLSParser (DOMImplementationLS::MODE_SYNCHRONOUS, 0)); + + DOMConfiguration* conf (parser->getDomConfig ()); + + // Discard comment nodes in the document. + // + conf->setParameter (XMLUni::fgDOMComments, false); + + // Enable datatype normalization. + // + conf->setParameter (XMLUni::fgDOMDatatypeNormalization, true); + + // Do not create EntityReference nodes in the DOM tree. No + // EntityReference nodes will be created, only the nodes + // corresponding to their fully expanded substitution text + // will be created. + // + conf->setParameter (XMLUni::fgDOMEntities, false); + + // Perform namespace processing. + // + conf->setParameter (XMLUni::fgDOMNamespaces, true); + + // Do not include ignorable whitespace in the DOM tree. + // + conf->setParameter (XMLUni::fgDOMElementContentWhitespace, false); + + if (flags & dont_validate) + { + conf->setParameter (XMLUni::fgDOMValidate, false); + conf->setParameter (XMLUni::fgXercesSchema, false); + conf->setParameter (XMLUni::fgXercesSchemaFullChecking, false); + } + else + { + conf->setParameter (XMLUni::fgDOMValidate, true); + conf->setParameter (XMLUni::fgXercesSchema, true); + + // Xerces-C++ 3.1.0 is the first version with working multi import + // support. + // +#if _XERCES_VERSION >= 30100 + if (!(flags & no_muliple_imports)) + conf->setParameter (XMLUni::fgXercesHandleMultipleImports, true); +#endif + + // This feature checks the schema grammar for additional + // errors. We most likely do not need it when validating + // instances (assuming the schema is valid). + // + conf->setParameter (XMLUni::fgXercesSchemaFullChecking, false); + } + + // We will release DOM ourselves. + // + conf->setParameter (XMLUni::fgXercesUserAdoptsDOMDocument, true); + + + // Transfer properies if any. + // + + if (!prop.schema_location ().empty ()) + { + xml::string sl (prop.schema_location ()); + const void* v (sl.c_str ()); + + conf->setParameter ( + XMLUni::fgXercesSchemaExternalSchemaLocation, + const_cast<void*> (v)); + } + + if (!prop.no_namespace_schema_location ().empty ()) + { + xml::string sl (prop.no_namespace_schema_location ()); + const void* v (sl.c_str ()); + + conf->setParameter ( + XMLUni::fgXercesSchemaExternalNoNameSpaceSchemaLocation, + const_cast<void*> (v)); + } + + // If external schema location was specified, disable loading + // schemas via the schema location attributes in the document. + // +#if _XERCES_VERSION >= 30100 + if (!prop.schema_location ().empty () || + !prop.no_namespace_schema_location ().empty ()) + { + conf->setParameter (XMLUni::fgXercesLoadSchema, false); + } +#endif + // Set error handler. + // + bits::error_handler_proxy<C> ehp (eh); + conf->setParameter (XMLUni::fgDOMErrorHandler, &ehp); + +#else // _XERCES_VERSION >= 30000 + + // Same as above but for Xerces-C++ 2 series. + // + auto_ptr<DOMBuilder> parser ( + impl->createDOMBuilder (DOMImplementationLS::MODE_SYNCHRONOUS, 0)); + + parser->setFeature (XMLUni::fgDOMComments, false); + parser->setFeature (XMLUni::fgDOMDatatypeNormalization, true); + parser->setFeature (XMLUni::fgDOMEntities, false); + parser->setFeature (XMLUni::fgDOMNamespaces, true); + parser->setFeature (XMLUni::fgDOMWhitespaceInElementContent, false); + + if (flags & dont_validate) + { + parser->setFeature (XMLUni::fgDOMValidation, false); + parser->setFeature (XMLUni::fgXercesSchema, false); + parser->setFeature (XMLUni::fgXercesSchemaFullChecking, false); + } + else + { + parser->setFeature (XMLUni::fgDOMValidation, true); + parser->setFeature (XMLUni::fgXercesSchema, true); + parser->setFeature (XMLUni::fgXercesSchemaFullChecking, false); + } + + parser->setFeature (XMLUni::fgXercesUserAdoptsDOMDocument, true); + + if (!prop.schema_location ().empty ()) + { + xml::string sl (prop.schema_location ()); + const void* v (sl.c_str ()); + + parser->setProperty ( + XMLUni::fgXercesSchemaExternalSchemaLocation, + const_cast<void*> (v)); + } + + if (!prop.no_namespace_schema_location ().empty ()) + { + xml::string sl (prop.no_namespace_schema_location ()); + const void* v (sl.c_str ()); + + parser->setProperty ( + XMLUni::fgXercesSchemaExternalNoNameSpaceSchemaLocation, + const_cast<void*> (v)); + } + + bits::error_handler_proxy<C> ehp (eh); + parser->setErrorHandler (&ehp); + +#endif // _XERCES_VERSION >= 30000 + + xercesc::Wrapper4InputSource wrap (&is, false); + +#if _XERCES_VERSION >= 30000 + auto_ptr<DOMDocument> doc; + + try + { + doc.reset (parser->parse (&wrap)); + } + catch (const xercesc::DOMLSException&) + { + } +#else + auto_ptr<DOMDocument> doc (parser->parse (wrap)); +#endif + if (ehp.failed ()) + doc.reset (); + + return doc; + } + + template <typename C> + xml::dom::auto_ptr<xercesc::DOMDocument> + parse (const std::basic_string<C>& uri, + error_handler<C>& eh, + const properties<C>& prop, + unsigned long flags) + { + bits::error_handler_proxy<C> ehp (eh); + return xml::dom::parse (uri, ehp, prop, flags); + } + + template <typename C> + auto_ptr<xercesc::DOMDocument> + parse (const std::basic_string<C>& uri, + xercesc::DOMErrorHandler& eh, + const properties<C>& prop, + unsigned long flags) + { + // HP aCC cannot handle using namespace xercesc; + // + using xercesc::DOMImplementationRegistry; + using xercesc::DOMImplementationLS; + using xercesc::DOMImplementation; + using xercesc::DOMDocument; +#if _XERCES_VERSION >= 30000 + using xercesc::DOMLSParser; + using xercesc::DOMConfiguration; +#else + using xercesc::DOMBuilder; +#endif + using xercesc::XMLUni; + + + // Instantiate the DOM parser. + // + const XMLCh ls_id[] = {xercesc::chLatin_L, + xercesc::chLatin_S, + xercesc::chNull}; + + // Get an implementation of the Load-Store (LS) interface. + // + DOMImplementation* impl ( + DOMImplementationRegistry::getDOMImplementation (ls_id)); + +#if _XERCES_VERSION >= 30000 + auto_ptr<DOMLSParser> parser ( + impl->createLSParser(DOMImplementationLS::MODE_SYNCHRONOUS, 0)); + + DOMConfiguration* conf (parser->getDomConfig ()); + + // Discard comment nodes in the document. + // + conf->setParameter (XMLUni::fgDOMComments, false); + + // Enable datatype normalization. + // + conf->setParameter (XMLUni::fgDOMDatatypeNormalization, true); + + // Do not create EntityReference nodes in the DOM tree. No + // EntityReference nodes will be created, only the nodes + // corresponding to their fully expanded substitution text + // will be created. + // + conf->setParameter (XMLUni::fgDOMEntities, false); + + // Perform namespace processing. + // + conf->setParameter (XMLUni::fgDOMNamespaces, true); + + // Do not include ignorable whitespace in the DOM tree. + // + conf->setParameter (XMLUni::fgDOMElementContentWhitespace, false); + + if (flags & dont_validate) + { + conf->setParameter (XMLUni::fgDOMValidate, false); + conf->setParameter (XMLUni::fgXercesSchema, false); + conf->setParameter (XMLUni::fgXercesSchemaFullChecking, false); + } + else + { + conf->setParameter (XMLUni::fgDOMValidate, true); + conf->setParameter (XMLUni::fgXercesSchema, true); + + // Xerces-C++ 3.1.0 is the first version with working multi import + // support. + // +#if _XERCES_VERSION >= 30100 + if (!(flags & no_muliple_imports)) + conf->setParameter (XMLUni::fgXercesHandleMultipleImports, true); +#endif + + // This feature checks the schema grammar for additional + // errors. We most likely do not need it when validating + // instances (assuming the schema is valid). + // + conf->setParameter (XMLUni::fgXercesSchemaFullChecking, false); + } + + // We will release DOM ourselves. + // + conf->setParameter (XMLUni::fgXercesUserAdoptsDOMDocument, true); + + + // Transfer properies if any. + // + + if (!prop.schema_location ().empty ()) + { + xml::string sl (prop.schema_location ()); + const void* v (sl.c_str ()); + + conf->setParameter ( + XMLUni::fgXercesSchemaExternalSchemaLocation, + const_cast<void*> (v)); + } + + if (!prop.no_namespace_schema_location ().empty ()) + { + xml::string sl (prop.no_namespace_schema_location ()); + const void* v (sl.c_str ()); + + conf->setParameter ( + XMLUni::fgXercesSchemaExternalNoNameSpaceSchemaLocation, + const_cast<void*> (v)); + } + + // If external schema location was specified, disable loading + // schemas via the schema location attributes in the document. + // +#if _XERCES_VERSION >= 30100 + if (!prop.schema_location ().empty () || + !prop.no_namespace_schema_location ().empty ()) + { + conf->setParameter (XMLUni::fgXercesLoadSchema, false); + } +#endif + // Set error handler. + // + bits::error_handler_proxy<C> ehp (eh); + conf->setParameter (XMLUni::fgDOMErrorHandler, &ehp); + +#else // _XERCES_VERSION >= 30000 + + // Same as above but for Xerces-C++ 2 series. + // + auto_ptr<DOMBuilder> parser ( + impl->createDOMBuilder(DOMImplementationLS::MODE_SYNCHRONOUS, 0)); + + parser->setFeature (XMLUni::fgDOMComments, false); + parser->setFeature (XMLUni::fgDOMDatatypeNormalization, true); + parser->setFeature (XMLUni::fgDOMEntities, false); + parser->setFeature (XMLUni::fgDOMNamespaces, true); + parser->setFeature (XMLUni::fgDOMWhitespaceInElementContent, false); + + if (flags & dont_validate) + { + parser->setFeature (XMLUni::fgDOMValidation, false); + parser->setFeature (XMLUni::fgXercesSchema, false); + parser->setFeature (XMLUni::fgXercesSchemaFullChecking, false); + } + else + { + parser->setFeature (XMLUni::fgDOMValidation, true); + parser->setFeature (XMLUni::fgXercesSchema, true); + parser->setFeature (XMLUni::fgXercesSchemaFullChecking, false); + } + + parser->setFeature (XMLUni::fgXercesUserAdoptsDOMDocument, true); + + if (!prop.schema_location ().empty ()) + { + xml::string sl (prop.schema_location ()); + const void* v (sl.c_str ()); + + parser->setProperty ( + XMLUni::fgXercesSchemaExternalSchemaLocation, + const_cast<void*> (v)); + } + + if (!prop.no_namespace_schema_location ().empty ()) + { + xml::string sl (prop.no_namespace_schema_location ()); + const void* v (sl.c_str ()); + + parser->setProperty ( + XMLUni::fgXercesSchemaExternalNoNameSpaceSchemaLocation, + const_cast<void*> (v)); + } + + bits::error_handler_proxy<C> ehp (eh); + parser->setErrorHandler (&ehp); + +#endif // _XERCES_VERSION >= 30000 + + +#if _XERCES_VERSION >= 30000 + auto_ptr<DOMDocument> doc; + + try + { + doc.reset (parser->parseURI (string (uri).c_str ())); + } + catch (const xercesc::DOMLSException&) + { + } +#else + auto_ptr<DOMDocument> doc ( + parser->parseURI (string (uri).c_str ())); +#endif + + if (ehp.failed ()) + doc.reset (); + + return doc; + } + } + } + } +} diff --git a/xsd/libxsd/xsd/cxx/xml/dom/serialization-header.hxx b/xsd/libxsd/xsd/cxx/xml/dom/serialization-header.hxx new file mode 100644 index 0000000..3b879b1 --- /dev/null +++ b/xsd/libxsd/xsd/cxx/xml/dom/serialization-header.hxx @@ -0,0 +1,81 @@ +// file : xsd/cxx/xml/dom/serialization-header.hxx +// author : Boris Kolpackov <boris@codesynthesis.com> +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSD_CXX_XML_DOM_SERIALIZATION_HEADER_HXX +#define XSD_CXX_XML_DOM_SERIALIZATION_HEADER_HXX + +#include <map> +#include <string> + +#include <xercesc/dom/DOMElement.hpp> + +namespace xsd +{ + namespace cxx + { + namespace xml + { + namespace dom + { + // Find an existing prefix or establish a new one. Try to use + // hint if provided and available. + // + template <typename C> + std::basic_string<C> + prefix (const C* ns, xercesc::DOMElement&, const C* hint = 0); + + template <typename C> + inline std::basic_string<C> + prefix (const std::basic_string<C>& ns, + xercesc::DOMElement& e, + const C* hint = 0) + { + return prefix (ns.c_str (), e, hint); + } + + // + // + template <typename C> + void + clear (xercesc::DOMElement&); + + // + // + template <typename C> + class namespace_info + { + public: + typedef std::basic_string<C> string; + + namespace_info () + { + } + + namespace_info (const string& name_, const string& schema_) + : name (name_), + schema (schema_) + { + } + + std::basic_string<C> name; + std::basic_string<C> schema; + }; + + + // Map of namespace prefix to namespace_info. + // + template <typename C> + class namespace_infomap: + public std::map<std::basic_string<C>, namespace_info<C> > + { + }; + } + } + } +} + +#include <xsd/cxx/xml/dom/serialization-header.txx> + +#endif // XSD_CXX_XML_DOM_SERIALIZATION_HEADER_HXX diff --git a/xsd/libxsd/xsd/cxx/xml/dom/serialization-header.txx b/xsd/libxsd/xsd/cxx/xml/dom/serialization-header.txx new file mode 100644 index 0000000..3052b7e --- /dev/null +++ b/xsd/libxsd/xsd/cxx/xml/dom/serialization-header.txx @@ -0,0 +1,192 @@ +// file : xsd/cxx/xml/dom/serialization-header.txx +// author : Boris Kolpackov <boris@codesynthesis.com> +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#include <vector> +#include <sstream> +#include <cstddef> // std::size_t + +#include <xercesc/dom/DOMNode.hpp> +#include <xercesc/dom/DOMAttr.hpp> +#include <xercesc/dom/DOMNamedNodeMap.hpp> + +#include <xercesc/util/XMLUni.hpp> // xercesc::fg* +#include <xercesc/util/XMLString.hpp> +#include <xercesc/validators/schema/SchemaSymbols.hpp> + +#include <xsd/cxx/xml/string.hxx> +#include <xsd/cxx/xml/bits/literals.hxx> + +namespace xsd +{ + namespace cxx + { + namespace xml + { + namespace dom + { + // + // + template <typename C> + std::basic_string<C> + prefix (const C* ns, xercesc::DOMElement& e, const C* hint) + { + string xns (ns); + +#if _XERCES_VERSION >= 30000 + const XMLCh* p (e.lookupPrefix (xns.c_str ())); +#else + const XMLCh* p (e.lookupNamespacePrefix (xns.c_str (), false)); +#endif + if (p != 0) + return transcode<C> (p); + + if (e.isDefaultNamespace (xns.c_str ())) + return std::basic_string<C> (); + + // 'xml' prefix requires special handling and Xerces folks + // refuse to handle this in DOM so I have to do it myself. + // + if (std::basic_string<C> (ns) == xml::bits::xml_namespace<C> ()) + return xml::bits::xml_prefix<C> (); + + // No prefix for this namespace. Will need to establish one. + // + std::basic_string<C> prefix; + + if (hint != 0 && + e.lookupNamespaceURI (xml::string (hint).c_str ()) == 0) + { + prefix = hint; + } + else + { + for (unsigned long n (1);; ++n) + { + // Make finding the first few prefixes fast. + // + switch (n) + { + case 1: + { + prefix = xml::bits::first_prefix<C> (); + break; + } + case 2: + { + prefix = xml::bits::second_prefix<C> (); + break; + } + case 3: + { + prefix = xml::bits::third_prefix<C> (); + break; + } + case 4: + { + prefix = xml::bits::fourth_prefix<C> (); + break; + } + case 5: + { + prefix = xml::bits::fifth_prefix<C> (); + break; + } + default: + { + std::basic_ostringstream<C> ostr; + ostr << C ('p') << n; + prefix = ostr.str (); + break; + } + } + + if (e.lookupNamespaceURI (xml::string (prefix).c_str ()) == 0) + break; + } + } + + std::basic_string<C> name (xml::bits::xmlns_prefix<C> ()); + name += C(':'); + name += prefix; + + e.setAttributeNS ( + xercesc::XMLUni::fgXMLNSURIName, + xml::string (name).c_str (), + xns.c_str ()); + + return prefix; + } + + // + // + template <typename C> + void + clear (xercesc::DOMElement& e) + { + // HP aCC cannot handle using namespace xercesc; + // + using xercesc::DOMNode; + using xercesc::DOMAttr; + using xercesc::DOMNamedNodeMap; + using xercesc::XMLString; + using xercesc::SchemaSymbols; + + // Remove child nodes. + // + while (xercesc::DOMNode* n = e.getFirstChild ()) + { + e.removeChild (n); + n->release (); + } + + // Remove attributes. + // + DOMNamedNodeMap* att_map (e.getAttributes ()); + XMLSize_t n (att_map->getLength ()); + + if (n != 0) + { + std::vector<DOMAttr*> atts; + + // Collect all attributes to be removed while filtering + // out special cases (xmlns & xsi). + // + for (XMLSize_t i (0); i != n; ++i) + { + DOMAttr* a (static_cast<DOMAttr*> (att_map->item (i))); + const XMLCh* ns (a->getNamespaceURI ()); + + if (ns != 0) + { + if (XMLString::equals (ns, xercesc::XMLUni::fgXMLNSURIName)) + continue; + + if (XMLString::equals (ns, SchemaSymbols::fgURI_XSI)) + { + const XMLCh* name (a->getLocalName ()); + + if (XMLString::equals ( + name, SchemaSymbols::fgXSI_SCHEMALOCACTION) || + XMLString::equals ( + name, SchemaSymbols::fgXSI_NONAMESPACESCHEMALOCACTION)) + continue; + } + } + + atts.push_back (a); + } + + for (std::vector<DOMAttr*>::iterator i (atts.begin ()), + end (atts.end ()); i != end; ++i) + { + e.removeAttributeNode (*i); + (*i)->release (); + } + } + } + } + } + } +} diff --git a/xsd/libxsd/xsd/cxx/xml/dom/serialization-source.hxx b/xsd/libxsd/xsd/cxx/xml/dom/serialization-source.hxx new file mode 100644 index 0000000..325c1ec --- /dev/null +++ b/xsd/libxsd/xsd/cxx/xml/dom/serialization-source.hxx @@ -0,0 +1,181 @@ +// file : xsd/cxx/xml/dom/serialization-source.hxx +// author : Boris Kolpackov <boris@codesynthesis.com> +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSD_CXX_XML_DOM_SERIALIZATION_SOURCE_HXX +#define XSD_CXX_XML_DOM_SERIALIZATION_SOURCE_HXX + +#include <string> +#include <cstring> // std::memcpy +#include <ostream> + +#include <xercesc/dom/DOMAttr.hpp> +#include <xercesc/dom/DOMElement.hpp> +#include <xercesc/dom/DOMDocument.hpp> +#include <xercesc/dom/DOMErrorHandler.hpp> +#include <xercesc/framework/XMLFormatter.hpp> // XMLFormatTarget, XMLFormatter + +#include <xsd/cxx/xml/error-handler.hxx> +#include <xsd/cxx/xml/dom/auto-ptr.hxx> +#include <xsd/cxx/xml/dom/elements.hxx> // name +#include <xsd/cxx/xml/dom/serialization-header.hxx> + +namespace xsd +{ + namespace cxx + { + namespace xml + { + namespace dom + { + // + // + template <typename C> + xercesc::DOMAttr& + create_attribute (const C* name, xercesc::DOMElement&); + + template <typename C> + xercesc::DOMAttr& + create_attribute (const C* name, const C* ns, xercesc::DOMElement&); + + template <typename C> + xercesc::DOMElement& + create_element (const C* name, xercesc::DOMElement&); + + template <typename C> + xercesc::DOMElement& + create_element (const C* name, const C* ns, xercesc::DOMElement&); + + // Serialization flags. + // + const unsigned long no_xml_declaration = 0x00010000UL; + const unsigned long dont_pretty_print = 0x00020000UL; + + template <typename C> + xml::dom::auto_ptr<xercesc::DOMDocument> + serialize (const std::basic_string<C>& root_element, + const std::basic_string<C>& root_element_namespace, + const namespace_infomap<C>& map, + unsigned long flags); + + // This one helps Sun C++ to overcome its fears. + // + template <typename C> + inline xml::dom::auto_ptr<xercesc::DOMDocument> + serialize (const C* root_element, + const C* root_element_namespace, + const namespace_infomap<C>& map, + unsigned long flags) + { + return serialize (std::basic_string<C> (root_element), + std::basic_string<C> (root_element_namespace), + map, + flags); + } + + // + // + template <typename C> + bool + serialize (xercesc::XMLFormatTarget& target, + const xercesc::DOMDocument& doc, + const std::basic_string<C>& enconding, + error_handler<C>& eh, + unsigned long flags); + + template <typename C> + bool + serialize (xercesc::XMLFormatTarget& target, + const xercesc::DOMDocument& doc, + const std::basic_string<C>& enconding, + xercesc::DOMErrorHandler& eh, + unsigned long flags); + + + class ostream_format_target: public xercesc::XMLFormatTarget + { + public: + ostream_format_target (std::ostream& os) + : n_ (0), os_ (os) + { + } + + public: + // I know, some of those consts are stupid. But that's what + // Xerces folks put into their interfaces and VC-7.1 thinks + // there are different signatures if one strips this fluff off. + // + virtual void + writeChars (const XMLByte* const buf, +#if _XERCES_VERSION >= 30000 + const XMLSize_t size, +#else + const unsigned int size, +#endif + xercesc::XMLFormatter* const) + { + // Ignore the write request if there was a stream failure and the + // stream is not using exceptions. + // + if (os_.fail ()) + return; + + // Flush the buffer if the block is too large or if we don't have + // any space left. + // + if ((size >= buf_size_ / 8 || n_ + size > buf_size_) && n_ != 0) + { + os_.write (buf_, static_cast<std::streamsize> (n_)); + n_ = 0; + + if (os_.fail ()) + return; + } + + if (size < buf_size_ / 8) + { + std::memcpy (buf_ + n_, reinterpret_cast<const char*> (buf), size); + n_ += size; + } + else + os_.write (reinterpret_cast<const char*> (buf), + static_cast<std::streamsize> (size)); + } + + + virtual void + flush () + { + // Ignore the flush request if there was a stream failure + // and the stream is not using exceptions. + // + if (!os_.fail ()) + { + if (n_ != 0) + { + os_.write (buf_, static_cast<std::streamsize> (n_)); + n_ = 0; + + if (os_.fail ()) + return; + } + + os_.flush (); + } + } + + private: + static const std::size_t buf_size_ = 1024; + char buf_[buf_size_]; + std::size_t n_; + std::ostream& os_; + }; + } + } + } +} + +#include <xsd/cxx/xml/dom/serialization-source.txx> + +#endif // XSD_CXX_XML_DOM_SERIALIZATION_SOURCE_HXX diff --git a/xsd/libxsd/xsd/cxx/xml/dom/serialization-source.txx b/xsd/libxsd/xsd/cxx/xml/dom/serialization-source.txx new file mode 100644 index 0000000..2b27dd5 --- /dev/null +++ b/xsd/libxsd/xsd/cxx/xml/dom/serialization-source.txx @@ -0,0 +1,394 @@ +// file : xsd/cxx/xml/dom/serialization-source.txx +// author : Boris Kolpackov <boris@codesynthesis.com> +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#include <xercesc/util/XMLUni.hpp> // xercesc::fg* +#include <xercesc/util/XMLUniDefs.hpp> // chLatin_L, etc +#include <xercesc/validators/schema/SchemaSymbols.hpp> + +#if _XERCES_VERSION >= 30000 +# include <xercesc/dom/DOMLSOutput.hpp> +# include <xercesc/dom/DOMLSSerializer.hpp> +#else +# include <xercesc/dom/DOMWriter.hpp> +#endif +#include <xercesc/dom/DOMElement.hpp> +#include <xercesc/dom/DOMImplementation.hpp> +#include <xercesc/dom/DOMImplementationRegistry.hpp> + +#include <xsd/cxx/xml/string.hxx> +#include <xsd/cxx/xml/bits/literals.hxx> +#include <xsd/cxx/xml/dom/bits/error-handler-proxy.hxx> + +namespace xsd +{ + namespace cxx + { + namespace xml + { + namespace dom + { + // + // + template <typename C> + xercesc::DOMAttr& + create_attribute (const C* name, xercesc::DOMElement& parent) + { + xercesc::DOMDocument* doc (parent.getOwnerDocument ()); + xercesc::DOMAttr* a (doc->createAttribute (string (name).c_str ())); + parent.setAttributeNode (a); + return *a; + } + + template <typename C> + xercesc::DOMAttr& + create_attribute (const C* name, + const C* ns, + xercesc::DOMElement& parent) + { + if (ns[0] == C ('\0')) + return create_attribute (name, parent); + + xercesc::DOMDocument* doc (parent.getOwnerDocument ()); + + xercesc::DOMAttr* a; + std::basic_string<C> p (prefix<C> (ns, parent)); + + if (!p.empty ()) + { + p += ':'; + p += name; + a = doc->createAttributeNS (string (ns).c_str (), + string (p).c_str ()); + } + else + a = doc->createAttributeNS (string (ns).c_str (), + string (name).c_str ()); + + parent.setAttributeNodeNS (a); + return *a; + } + + template <typename C> + xercesc::DOMElement& + create_element (const C* name, xercesc::DOMElement& parent) + { + xercesc::DOMDocument* doc (parent.getOwnerDocument ()); + xercesc::DOMElement* e (doc->createElement (string (name).c_str ())); + parent.appendChild (e); + return *e; + } + + template <typename C> + xercesc::DOMElement& + create_element (const C* name, + const C* ns, + xercesc::DOMElement& parent) + { + if (ns[0] == C ('\0')) + return create_element (name, parent); + + xercesc::DOMDocument* doc (parent.getOwnerDocument ()); + + xercesc::DOMElement* e; + std::basic_string<C> p (prefix<C> (ns, parent)); + + if (!p.empty ()) + { + p += ':'; + p += name; + e = doc->createElementNS (string (ns).c_str (), + string (p).c_str ()); + } + else + e = doc->createElementNS (string (ns).c_str (), + string (name).c_str ()); + + parent.appendChild (e); + return *e; + } + + + // + // + template <typename C> + auto_ptr<xercesc::DOMDocument> + serialize (const std::basic_string<C>& el, + const std::basic_string<C>& ns, + const namespace_infomap<C>& map, + unsigned long) + { + // HP aCC cannot handle using namespace xercesc; + // + using xercesc::DOMImplementationRegistry; + using xercesc::DOMImplementation; + using xercesc::DOMDocument; + using xercesc::DOMElement; + + // + // + typedef std::basic_string<C> string; + typedef namespace_infomap<C> infomap; + typedef typename infomap::const_iterator infomap_iterator; + + C colon (':'), space (' '); + + string prefix; + + if (!ns.empty ()) + { + infomap_iterator i (map.begin ()), e (map.end ()); + + for ( ;i != e; ++i) + { + if (i->second.name == ns) + { + prefix = i->first; + break; + } + } + + // Since this is the first namespace in document we don't + // need to worry about conflicts. + // + if (i == e) + prefix = xml::bits::first_prefix<C> (); + } + + const XMLCh ls[] = {xercesc::chLatin_L, + xercesc::chLatin_S, + xercesc::chNull}; + + DOMImplementation* impl ( + DOMImplementationRegistry::getDOMImplementation (ls)); + + auto_ptr<DOMDocument> doc ( + impl->createDocument ( + (ns.empty () ? 0 : xml::string (ns).c_str ()), + xml::string ((prefix.empty () + ? el + : prefix + colon + el)).c_str (), + 0)); + + DOMElement* root (doc->getDocumentElement ()); + + // Check if we need to provide xsi mapping. + // + bool xsi (false); + string xsi_prefix; + string xmlns_prefix (xml::bits::xmlns_prefix<C> ()); + + for (infomap_iterator i (map.begin ()), e (map.end ()); i != e; ++i) + { + if (!i->second.schema.empty ()) + { + xsi = true; + break; + } + } + + // Check if we were told to provide xsi mapping. + // + if (xsi) + { + for (infomap_iterator i (map.begin ()), e (map.end ()); + i != e; + ++i) + { + if (i->second.name == xml::bits::xsi_namespace<C> ()) + { + xsi_prefix = i->first; + xsi = false; + break; + } + } + } + + // Create user-defined mappings. + // + for (infomap_iterator i (map.begin ()), e (map.end ()); i != e; ++i) + { + if (i->first.empty ()) + { + // Empty prefix. + // + if (!i->second.name.empty ()) + root->setAttributeNS ( + xercesc::XMLUni::fgXMLNSURIName, + xml::string (xmlns_prefix).c_str (), + xml::string (i->second.name).c_str ()); + } + else + { + root->setAttributeNS ( + xercesc::XMLUni::fgXMLNSURIName, + xml::string (xmlns_prefix + colon + i->first).c_str (), + xml::string (i->second.name).c_str ()); + } + } + + // If we were not told to provide xsi mapping but we need it + // then we will have to add it ourselves. + // + if (xsi) + xsi_prefix = dom::prefix (xml::bits::xsi_namespace<C> (), + *root, + xml::bits::xsi_prefix<C> ()); + + // Create xsi:schemaLocation and xsi:noNamespaceSchemaLocation + // attributes. + // + string schema_location; + string no_namespace_schema_location; + + for (infomap_iterator i (map.begin ()), e (map.end ()); i != e; ++i) + { + if (!i->second.schema.empty ()) + { + if (i->second.name.empty ()) + { + if (!no_namespace_schema_location.empty ()) + no_namespace_schema_location += space; + + no_namespace_schema_location += i->second.schema; + } + else + { + if (!schema_location.empty ()) + schema_location += space; + + schema_location += i->second.name + space + i->second.schema; + } + } + } + + if (!schema_location.empty ()) + { + root->setAttributeNS ( + xercesc::SchemaSymbols::fgURI_XSI, + xml::string (xsi_prefix + colon + + xml::bits::schema_location<C> ()).c_str (), + xml::string (schema_location).c_str ()); + } + + if (!no_namespace_schema_location.empty ()) + { + root->setAttributeNS ( + xercesc::SchemaSymbols::fgURI_XSI, + xml::string ( + xsi_prefix + colon + + xml::bits::no_namespace_schema_location<C> ()).c_str (), + xml::string (no_namespace_schema_location).c_str ()); + } + + return doc; + } + + + template <typename C> + bool + serialize (xercesc::XMLFormatTarget& target, + const xercesc::DOMDocument& doc, + const std::basic_string<C>& encoding, + xercesc::DOMErrorHandler& eh, + unsigned long flags) + { + // HP aCC cannot handle using namespace xercesc; + // + using xercesc::DOMImplementationRegistry; + using xercesc::DOMImplementation; +#if _XERCES_VERSION >= 30000 + using xercesc::DOMLSSerializer; + using xercesc::DOMConfiguration; + using xercesc::DOMLSOutput; +#else + using xercesc::DOMWriter; +#endif + using xercesc::XMLUni; + + const XMLCh ls[] = {xercesc::chLatin_L, + xercesc::chLatin_S, + xercesc::chNull}; + + DOMImplementation* impl ( + DOMImplementationRegistry::getDOMImplementation (ls)); + + bits::error_handler_proxy<C> ehp (eh); + +#if _XERCES_VERSION >= 30000 + xml::dom::auto_ptr<DOMLSSerializer> writer ( + impl->createLSSerializer ()); + + DOMConfiguration* conf (writer->getDomConfig ()); + + conf->setParameter (XMLUni::fgDOMErrorHandler, &ehp); + + // Set some nice features if the serializer supports them. + // + if (conf->canSetParameter ( + XMLUni::fgDOMWRTDiscardDefaultContent, true)) + conf->setParameter (XMLUni::fgDOMWRTDiscardDefaultContent, true); + + if (!(flags & dont_pretty_print) && + conf->canSetParameter (XMLUni::fgDOMWRTFormatPrettyPrint, true)) + conf->setParameter (XMLUni::fgDOMWRTFormatPrettyPrint, true); + + // See if we need to write XML declaration. + // + if ((flags & no_xml_declaration) && + conf->canSetParameter (XMLUni::fgDOMXMLDeclaration, false)) + conf->setParameter (XMLUni::fgDOMXMLDeclaration, false); + + xml::dom::auto_ptr<DOMLSOutput> out (impl->createLSOutput ()); + + out->setEncoding (xml::string (encoding).c_str ()); + out->setByteStream (&target); + + bool r (writer->write (&doc, out.get ())); +#else + xml::dom::auto_ptr<DOMWriter> writer (impl->createDOMWriter ()); + + writer->setErrorHandler (&ehp); + writer->setEncoding (xml::string (encoding).c_str ()); + + // Set some nice features if the serializer supports them. + // + if (writer->canSetFeature ( + XMLUni::fgDOMWRTDiscardDefaultContent, true)) + writer->setFeature (XMLUni::fgDOMWRTDiscardDefaultContent, true); + + if (!(flags & dont_pretty_print) && + writer->canSetFeature (XMLUni::fgDOMWRTFormatPrettyPrint, true)) + writer->setFeature (XMLUni::fgDOMWRTFormatPrettyPrint, true); + + // See if we need to write XML declaration. + // + if ((flags & no_xml_declaration) && + writer->canSetFeature (XMLUni::fgDOMXMLDeclaration, false)) + writer->setFeature (XMLUni::fgDOMXMLDeclaration, false); + + bool r (writer->writeNode (&target, doc)); +#endif + + if (!r || ehp.failed ()) + return false; + + return true; + } + + template <typename C> + bool + serialize (xercesc::XMLFormatTarget& target, + const xercesc::DOMDocument& doc, + const std::basic_string<C>& enconding, + error_handler<C>& eh, + unsigned long flags) + { + bits::error_handler_proxy<C> ehp (eh); + return serialize (target, doc, enconding, ehp, flags); + } + } + } + } +} diff --git a/xsd/libxsd/xsd/cxx/xml/dom/wildcard-source.hxx b/xsd/libxsd/xsd/cxx/xml/dom/wildcard-source.hxx new file mode 100644 index 0000000..11d7114 --- /dev/null +++ b/xsd/libxsd/xsd/cxx/xml/dom/wildcard-source.hxx @@ -0,0 +1,31 @@ +// file : xsd/cxx/xml/dom/wildcard-source.hxx +// author : Boris Kolpackov <boris@codesynthesis.com> +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSD_CXX_XML_DOM_WILDCARD_SOURCE_HXX +#define XSD_CXX_XML_DOM_WILDCARD_SOURCE_HXX + +#include <xercesc/dom/DOMDocument.hpp> + +#include <xsd/cxx/xml/dom/auto-ptr.hxx> + +namespace xsd +{ + namespace cxx + { + namespace xml + { + namespace dom + { + template <typename C> + xml::dom::auto_ptr<xercesc::DOMDocument> + create_document (); + } + } + } +} + +#include <xsd/cxx/xml/dom/wildcard-source.txx> + +#endif // XSD_CXX_XML_DOM_WILDCARD_SOURCE_HXX diff --git a/xsd/libxsd/xsd/cxx/xml/dom/wildcard-source.txx b/xsd/libxsd/xsd/cxx/xml/dom/wildcard-source.txx new file mode 100644 index 0000000..32043c0 --- /dev/null +++ b/xsd/libxsd/xsd/cxx/xml/dom/wildcard-source.txx @@ -0,0 +1,38 @@ +// file : xsd/cxx/xml/dom/wildcard-source.txx +// author : Boris Kolpackov <boris@codesynthesis.com> +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#include <xercesc/util/XMLUniDefs.hpp> // chLatin_L, etc + +#include <xercesc/dom/DOMImplementation.hpp> +#include <xercesc/dom/DOMImplementationRegistry.hpp> + +namespace xsd +{ + namespace cxx + { + namespace xml + { + namespace dom + { + template <typename C> + xml::dom::auto_ptr<xercesc::DOMDocument> + create_document () + { + const XMLCh ls[] = {xercesc::chLatin_L, + xercesc::chLatin_S, + xercesc::chNull}; + + // Get an implementation of the Load-Store (LS) interface. + // + xercesc::DOMImplementation* impl ( + xercesc::DOMImplementationRegistry::getDOMImplementation (ls)); + + return xml::dom::auto_ptr<xercesc::DOMDocument> ( + impl->createDocument ()); + } + } + } + } +} diff --git a/xsd/libxsd/xsd/cxx/xml/elements.hxx b/xsd/libxsd/xsd/cxx/xml/elements.hxx new file mode 100644 index 0000000..d9f8a50 --- /dev/null +++ b/xsd/libxsd/xsd/cxx/xml/elements.hxx @@ -0,0 +1,113 @@ +// file : xsd/cxx/xml/elements.hxx +// author : Boris Kolpackov <boris@codesynthesis.com> +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSD_CXX_XML_ELEMENTS_HXX +#define XSD_CXX_XML_ELEMENTS_HXX + +#include <string> + +#include <xercesc/util/PlatformUtils.hpp> + +namespace xsd +{ + namespace cxx + { + namespace xml + { + template <typename C> + class properties + { + public: + struct argument {}; + + + // Schema location properties. Note that all locations are + // relative to an instance document unless they are full + // URIs. For example if you want to use a local schema then + // you will need to use 'file:///absolute/path/to/your/schema'. + // + + // Add a location for a schema with a target namespace. + // + void + schema_location (const std::basic_string<C>& namespace_, + const std::basic_string<C>& location); + + // Add a location for a schema without a target namespace. + // + void + no_namespace_schema_location (const std::basic_string<C>& location); + + public: + const std::basic_string<C>& + schema_location () const + { + return schema_location_; + } + + const std::basic_string<C>& + no_namespace_schema_location () const + { + return no_namespace_schema_location_; + } + + private: + std::basic_string<C> schema_location_; + std::basic_string<C> no_namespace_schema_location_; + }; + + + // + // + + template <typename C> + std::basic_string<C> + prefix (const std::basic_string<C>& n); + + template <typename C> + std::basic_string<C> + uq_name (const std::basic_string<C>& n); + + + // + // + + inline void + initialize () + { + xercesc::XMLPlatformUtils::Initialize (); + } + + inline void + terminate () + { + xercesc::XMLPlatformUtils::Terminate (); + } + + struct auto_initializer + { + auto_initializer (bool initialize = true, bool terminate = true) + : terminate_ (initialize && terminate) + { + if (initialize) + xml::initialize (); + } + + ~auto_initializer () + { + if (terminate_) + terminate (); + } + + private: + bool terminate_; + }; + } + } +} + +#include <xsd/cxx/xml/elements.txx> + +#endif // XSD_CXX_XML_ELEMENTS_HXX diff --git a/xsd/libxsd/xsd/cxx/xml/elements.txx b/xsd/libxsd/xsd/cxx/xml/elements.txx new file mode 100644 index 0000000..8ba07df --- /dev/null +++ b/xsd/libxsd/xsd/cxx/xml/elements.txx @@ -0,0 +1,73 @@ +// file : xsd/cxx/xml/elements.txx +// author : Boris Kolpackov <boris@codesynthesis.com> +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +namespace xsd +{ + namespace cxx + { + namespace xml + { + // properties + // + + template <typename C> + void properties<C>:: + schema_location (const std::basic_string<C>& ns, + const std::basic_string<C>& loc) + { + if (ns.empty () || loc.empty ()) + throw argument (); + + if (!schema_location_.empty ()) + schema_location_ += C (' '); + + schema_location_ += ns + C (' ') + loc; + } + + template <typename C> + void properties<C>:: + no_namespace_schema_location (const std::basic_string<C>& loc) + { + if (loc.empty ()) + throw argument (); + + if (!no_namespace_schema_location_.empty ()) + no_namespace_schema_location_ += C (' '); + + no_namespace_schema_location_ += loc; + } + + + // + // + + template <typename C> + std::basic_string<C> + prefix (const std::basic_string<C>& n) + { + std::size_t i (0); + + while (i < n.length () && n[i] != ':') + ++i; + + return std::basic_string<C> (n, i == n.length () ? i : 0, i); + } + + template <typename C> + std::basic_string<C> + uq_name (const std::basic_string<C>& n) + { + std::size_t i (0); + + while (i < n.length () && n[i] != ':') + ++i; + + return std::basic_string<C> ( + n.c_str () + (i == n.length () ? 0 : i + 1)); + } + } + } +} + diff --git a/xsd/libxsd/xsd/cxx/xml/error-handler.hxx b/xsd/libxsd/xsd/cxx/xml/error-handler.hxx new file mode 100644 index 0000000..bf0b3d7 --- /dev/null +++ b/xsd/libxsd/xsd/cxx/xml/error-handler.hxx @@ -0,0 +1,59 @@ +// file : xsd/cxx/xml/error-handler.hxx +// author : Boris Kolpackov <boris@codesynthesis.com> +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSD_CXX_XML_ERROR_HANDLER_HXX +#define XSD_CXX_XML_ERROR_HANDLER_HXX + +#include <string> + +namespace xsd +{ + namespace cxx + { + namespace xml + { + template <typename C> + class error_handler + { + public: + virtual + ~error_handler () + { + } + + public: + + // The fatal severity level results in termination + // of the parsing process no matter what is returned + // from handle. + // + struct severity + { + enum value + { + warning, + error, + fatal + }; + + severity (value v) : v_ (v) {} + operator value () const { return v_; } + + private: + value v_; + }; + + virtual bool + handle (const std::basic_string<C>& id, + unsigned long line, + unsigned long column, + severity, + const std::basic_string<C>& message) = 0; + }; + } + } +} + +#endif // XSD_CXX_XML_ERROR_HANDLER_HXX diff --git a/xsd/libxsd/xsd/cxx/xml/exceptions.hxx b/xsd/libxsd/xsd/cxx/xml/exceptions.hxx new file mode 100644 index 0000000..1ed93d8 --- /dev/null +++ b/xsd/libxsd/xsd/cxx/xml/exceptions.hxx @@ -0,0 +1,20 @@ +// file : xsd/cxx/xml/exceptions.hxx +// author : Boris Kolpackov <boris@codesynthesis.com> +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSD_CXX_XML_EXCEPTIONS_HXX +#define XSD_CXX_XML_EXCEPTIONS_HXX + +namespace xsd +{ + namespace cxx + { + namespace xml + { + struct invalid_utf16_string {}; + } + } +} + +#endif // XSD_CXX_XML_EXCEPTIONS_HXX diff --git a/xsd/libxsd/xsd/cxx/xml/qualified-name.hxx b/xsd/libxsd/xsd/cxx/xml/qualified-name.hxx new file mode 100644 index 0000000..1a0e032 --- /dev/null +++ b/xsd/libxsd/xsd/cxx/xml/qualified-name.hxx @@ -0,0 +1,84 @@ +// file : xsd/cxx/xml/qualified-name.hxx +// author : Boris Kolpackov <boris@codesynthesis.com> +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSD_CXX_XML_QUALIFIED_NAME_HXX +#define XSD_CXX_XML_QUALIFIED_NAME_HXX + +#include <string> + +namespace xsd +{ + namespace cxx + { + namespace xml + { + template <typename C> + struct qualified_name + { + qualified_name (const C* name, + const C* namespace_) + : name_ (name), namespace__ (namespace_) + { + } + + qualified_name (const std::basic_string<C>& name, + const std::basic_string<C>& namespace_) + : name_ (name), namespace__ (namespace_) + { + } + + qualified_name (const C* name) + : name_ (name) + { + } + + qualified_name (const std::basic_string<C>& name) + : name_ (name) + { + } + + const std::basic_string<C>& + name () const + { + return name_; + } + + const std::basic_string<C>& + namespace_ () const + { + return namespace__; + } + + private: + std::basic_string<C> name_; + std::basic_string<C> namespace__; + }; + + template <typename C> + inline bool + operator== (const qualified_name<C>& x, const qualified_name<C>& y) + { + return x.name () == y.name () && x.namespace_ () == y.namespace_ (); + } + + template <typename C> + inline bool + operator!= (const qualified_name<C>& x, const qualified_name<C>& y) + { + return !(x == y); + } + + template <typename C> + inline bool + operator< (const qualified_name<C>& x, const qualified_name<C>& y) + { + int r (x.name ().compare (y.name ())); + return (r < 0) || (r == 0 && x.namespace_ () < y.namespace_ ()); + } + } + } +} + +#endif // XSD_CXX_XML_QUALIFIED_NAME_HXX diff --git a/xsd/libxsd/xsd/cxx/xml/sax/bits/error-handler-proxy.hxx b/xsd/libxsd/xsd/cxx/xml/sax/bits/error-handler-proxy.hxx new file mode 100644 index 0000000..f92b6ab --- /dev/null +++ b/xsd/libxsd/xsd/cxx/xml/sax/bits/error-handler-proxy.hxx @@ -0,0 +1,80 @@ +// file : xsd/cxx/xml/sax/bits/error-handler-proxy.hxx +// author : Boris Kolpackov <boris@codesynthesis.com> +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSD_CXX_XML_SAX_ERROR_HANDLER_PROXY_HXX +#define XSD_CXX_XML_SAX_ERROR_HANDLER_PROXY_HXX + +#include <xercesc/sax/ErrorHandler.hpp> +#include <xercesc/sax/SAXParseException.hpp> + +#include <xsd/cxx/xml/error-handler.hxx> + +namespace xsd +{ + namespace cxx + { + namespace xml + { + namespace sax + { + namespace bits + { + template <typename C> + class error_handler_proxy: public xercesc::ErrorHandler + { + public: + error_handler_proxy (error_handler<C>& eh) + : failed_ (false), eh_ (&eh), native_eh_ (0) + { + } + + error_handler_proxy (xercesc::ErrorHandler& eh) + : failed_ (false), eh_ (0), native_eh_ (&eh) + { + } + + public: + virtual void + warning (const xercesc::SAXParseException& e); + + virtual void + error (const xercesc::SAXParseException& e); + + virtual void + fatalError (const xercesc::SAXParseException& e); + + public: + bool + failed () const + { + return failed_; + } + + virtual void + resetErrors() + { + failed_ = false; + } + + private: + typedef typename error_handler<C>::severity severity; + + void + handle (const xercesc::SAXParseException&, severity); + + private: + bool failed_; + error_handler<C>* eh_; + xercesc::ErrorHandler* native_eh_; + }; + } + } + } + } +} + +#include <xsd/cxx/xml/sax/bits/error-handler-proxy.txx> + +#endif // XSD_CXX_XML_SAX_ERROR_HANDLER_PROXY_HXX diff --git a/xsd/libxsd/xsd/cxx/xml/sax/bits/error-handler-proxy.txx b/xsd/libxsd/xsd/cxx/xml/sax/bits/error-handler-proxy.txx new file mode 100644 index 0000000..f8ca26d --- /dev/null +++ b/xsd/libxsd/xsd/cxx/xml/sax/bits/error-handler-proxy.txx @@ -0,0 +1,89 @@ +// file : xsd/cxx/xml/sax/bits/error-handler-proxy.txx +// author : Boris Kolpackov <boris@codesynthesis.com> +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#include <xsd/cxx/xml/string.hxx> + +namespace xsd +{ + namespace cxx + { + namespace xml + { + namespace sax + { + namespace bits + { + template <typename C> + void error_handler_proxy<C>:: + warning (const xercesc::SAXParseException& e) + { + if (native_eh_) + native_eh_->warning (e); + else + handle (e, severity::warning); + } + + + template <typename C> + void error_handler_proxy<C>:: + error (const xercesc::SAXParseException& e) + { + failed_ = true; + + if (native_eh_) + native_eh_->error (e); + else + handle (e, severity::error); + } + + + template <typename C> + void error_handler_proxy<C>:: + fatalError (const xercesc::SAXParseException& e) + { + failed_ = true; + + if (native_eh_) + native_eh_->fatalError (e); + else + handle (e, severity::fatal); + } + + + template <typename C> + void error_handler_proxy<C>:: + handle (const xercesc::SAXParseException& e, severity s) + { + //@@ I do not honor return values from the handler. This + // is not too bad at the moment because I set + // all-errors-are-fatal flag on the parser. + // + const XMLCh* id (e.getPublicId ()); + + if (id == 0) + id = e.getSystemId (); + +#if _XERCES_VERSION >= 30000 + eh_->handle (transcode<C> (id), + static_cast<unsigned long> (e.getLineNumber ()), + static_cast<unsigned long> (e.getColumnNumber ()), + s, + transcode<C> (e.getMessage ())); +#else + XMLSSize_t l (e.getLineNumber ()); + XMLSSize_t c (e.getColumnNumber ()); + + eh_->handle (transcode<C> (id), + (l == -1 ? 0 : static_cast<unsigned long> (l)), + (c == -1 ? 0 : static_cast<unsigned long> (c)), + s, + transcode<C> (e.getMessage ())); +#endif + } + } + } + } + } +} diff --git a/xsd/libxsd/xsd/cxx/xml/sax/std-input-source.hxx b/xsd/libxsd/xsd/cxx/xml/sax/std-input-source.hxx new file mode 100644 index 0000000..71760a9 --- /dev/null +++ b/xsd/libxsd/xsd/cxx/xml/sax/std-input-source.hxx @@ -0,0 +1,174 @@ +// file : xsd/cxx/xml/sax/std-input-source.hxx +// author : Boris Kolpackov <boris@codesynthesis.com> +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSD_CXX_XML_SAX_STD_INPUT_SOURCE_HXX +#define XSD_CXX_XML_SAX_STD_INPUT_SOURCE_HXX + +#include <istream> + +#include <xsd/cxx/xml/string.hxx> + +#include <xercesc/sax/InputSource.hpp> +#include <xercesc/util/BinInputStream.hpp> + +namespace xsd +{ + namespace cxx + { + namespace xml + { + namespace sax + { + class std_input_stream: public xercesc::BinInputStream + { + public: + std_input_stream (std::istream& is) + : is_ (is) + { + } + +#if _XERCES_VERSION >= 30000 + virtual XMLFilePos + curPos () const + { + return static_cast<XMLFilePos> (is_.tellg ()); + } +#else + virtual unsigned int + curPos () const + { + return static_cast<unsigned int> (is_.tellg ()); + } +#endif + +#if _XERCES_VERSION >= 30000 + virtual XMLSize_t + readBytes (XMLByte* const buf, const XMLSize_t size) +#else + virtual unsigned int + readBytes (XMLByte* const buf, const unsigned int size) +#endif + { + // Some implementations don't clear gcount if you + // call read() on a stream that is in the eof state. + // + if (is_.eof ()) + return 0; + + // Unset the exception failbit while we are working + // with the stream. + // + std::ios_base::iostate old (is_.exceptions ()); + is_.exceptions (old & ~std::ios_base::failbit); + + is_.read (reinterpret_cast<char*> (buf), + static_cast<std::streamsize> (size)); + + // Clear the fail bit if it was caused by eof and restore + // the original exception state. If there are any pending + // errors then the exception will be thrown now. + // + if (is_.fail () && is_.eof ()) + is_.clear (is_.rdstate () & ~std::ios_base::failbit); + + is_.exceptions (old); + + // Make sure that if we failed, readBytes won't be called + // again. + // + if (!is_.fail ()) + { +#if _XERCES_VERSION >= 30000 + return static_cast<XMLSize_t> (is_.gcount ()); +#else + return static_cast<unsigned int> (is_.gcount ()); +#endif + } + else + return 0; + } + +#if _XERCES_VERSION >= 30000 + virtual const XMLCh* + getContentType () const + { + return 0; + } +#endif + private: + std::istream& is_; + }; + + + class std_input_source: public xercesc::InputSource + { + public: + std_input_source (std::istream& is) + : is_ (&is) + { + } + + template <typename C> + std_input_source (std::istream& is, const C* system_id) + : xercesc::InputSource (xml::string (system_id).c_str ()), + is_ (&is) + { + } + + template <typename C> + std_input_source (std::istream& is, + const std::basic_string<C>& system_id) + : xercesc::InputSource (xml::string (system_id).c_str ()), + is_ (&is) + { + } + + template <typename C> + std_input_source (std::istream& is, + const C* system_id, + const C* public_id) + : xercesc::InputSource (xml::string (system_id).c_str (), + xml::string (public_id).c_str ()), + is_ (&is) + { + } + + template <typename C> + std_input_source (std::istream& is, + const std::basic_string<C>& system_id, + const std::basic_string<C>& public_id) + : xercesc::InputSource (xml::string (system_id).c_str (), + xml::string (public_id).c_str ()), + is_ (&is) + { + } + + struct copy {}; + + // Throws the copy exception if this function is called more + // than once. + // + virtual xercesc::BinInputStream* + makeStream () const + { + if (is_ == 0) + throw copy (); + + std::istream& is (*is_); + + is_ = 0; + + return new std_input_stream (is); + } + + private: + mutable std::istream* is_; + }; + } + } + } +} + +#endif // XSD_CXX_XML_SAX_STD_INPUT_SOURCE_HXX diff --git a/xsd/libxsd/xsd/cxx/xml/std-memory-manager.hxx b/xsd/libxsd/xsd/cxx/xml/std-memory-manager.hxx new file mode 100644 index 0000000..b5cfaf9 --- /dev/null +++ b/xsd/libxsd/xsd/cxx/xml/std-memory-manager.hxx @@ -0,0 +1,50 @@ +// file : xsd/cxx/xml/std-memory-manager.hxx +// author : Boris Kolpackov <boris@codesynthesis.com> +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSD_CXX_XML_STD_MEMORY_MANAGER_HXX +#define XSD_CXX_XML_STD_MEMORY_MANAGER_HXX + +#include <new> // operator new, delete +#include <xercesc/framework/MemoryManager.hpp> + +namespace xsd +{ + namespace cxx + { + namespace xml + { + class std_memory_manager: public xercesc::MemoryManager + { + public: + virtual void* +#if _XERCES_VERSION >= 30000 + allocate(XMLSize_t size) +#else + allocate(size_t size) +#endif + { + return operator new (size); + } + + virtual void + deallocate(void* p) + { + if (p) + operator delete (p); + } + +#if _XERCES_VERSION >= 30000 + virtual xercesc::MemoryManager* + getExceptionMemoryManager() + { + return xercesc::XMLPlatformUtils::fgMemoryManager; + } +#endif + }; + } + } +} + +#endif // XSD_CXX_XML_STD_MEMORY_MANAGER_HXX diff --git a/xsd/libxsd/xsd/cxx/xml/string.hxx b/xsd/libxsd/xsd/cxx/xml/string.hxx new file mode 100644 index 0000000..f79e66e --- /dev/null +++ b/xsd/libxsd/xsd/cxx/xml/string.hxx @@ -0,0 +1,85 @@ +// file : xsd/cxx/xml/string.hxx +// author : Boris Kolpackov <boris@codesynthesis.com> +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSD_CXX_XML_STRING_HXX +#define XSD_CXX_XML_STRING_HXX + +#include <string> +#include <cstddef> // std::size_t + +#include <xsd/cxx/auto-array.hxx> +#include <xercesc/util/XercesDefs.hpp> // XMLCh + +namespace xsd +{ + namespace cxx + { + namespace xml + { + // Transcode a null-terminated string. + // + template <typename C> + std::basic_string<C> + transcode (const XMLCh* s); + + // Transcode a potentially non-null-terminated string. + // + template <typename C> + std::basic_string<C> + transcode (const XMLCh* s, std::size_t length); + + + // For VC7.1 wchar_t and XMLCh are the same type so we cannot + // overload the transcode name. You should not use these functions + // anyway and instead use the xml::string class below. + // + template <typename C> + XMLCh* + transcode_to_xmlch (const C*); + + template <typename C> + XMLCh* + transcode_to_xmlch (const std::basic_string<C>& s); + + // + // + class string + { + public : + template <typename C> + string (const std::basic_string<C>& s) + : s_ (transcode_to_xmlch<C> (s)) + { + } + + template <typename C> + string (const C* s) + : s_ (transcode_to_xmlch<C> (s)) + { + } + + const XMLCh* + c_str () const + { + return s_.get (); + } + + private: + string (const string&); + + string& + operator= (const string&); + + private: + auto_array<XMLCh> s_; + }; + } + } +} + +#endif // XSD_CXX_XML_STRING_HXX + +#include <xsd/cxx/xml/string.ixx> +#include <xsd/cxx/xml/string.txx> diff --git a/xsd/libxsd/xsd/cxx/xml/string.ixx b/xsd/libxsd/xsd/cxx/xml/string.ixx new file mode 100644 index 0000000..0f46f4d --- /dev/null +++ b/xsd/libxsd/xsd/cxx/xml/string.ixx @@ -0,0 +1,171 @@ +// file : xsd/cxx/xml/string.ixx +// author : Boris Kolpackov <boris@codesynthesis.com> +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSD_CXX_XML_STRING_IXX +#define XSD_CXX_XML_STRING_IXX + +#include <xercesc/util/XMLString.hpp> + +// If no transcoder has been included, use the default UTF-8. +// +#ifndef XSD_CXX_XML_TRANSCODER +# include <xsd/cxx/xml/char-utf8.hxx> +#endif + +// We sometimes need this functionality even if we are building for +// wchar_t. +// +namespace xsd +{ + namespace cxx + { + namespace xml + { + template <> + inline std::basic_string<char> + transcode<char> (const XMLCh* s) + { + if (s == 0 || *s == XMLCh (0)) + return std::basic_string<char> (); + +#ifndef XSD_CXX_XML_TRANSCODER_CHAR_LCP + return char_transcoder::to (s, xercesc::XMLString::stringLen (s)); +#else + return char_transcoder::to (s); +#endif + } + + template <> + inline std::basic_string<char> + transcode<char> (const XMLCh* s, std::size_t len) + { + if (s == 0 || len == 0) + return std::basic_string<char> (); + + return char_transcoder::to (s, len); + } + + template <> + inline XMLCh* + transcode_to_xmlch (const char* s) + { +#ifndef XSD_CXX_XML_TRANSCODER_CHAR_LCP + return char_transcoder::from (s, std::char_traits<char>::length (s)); +#else + return char_transcoder::from (s); +#endif + } + + template <> + inline XMLCh* + transcode_to_xmlch (const std::basic_string<char>& s) + { +#ifndef XSD_CXX_XML_TRANSCODER_CHAR_LCP + return char_transcoder::from (s.c_str (), s.length ()); +#else + return char_transcoder::from (s.c_str ()); +#endif + } + } + } +} + +#endif // XSD_CXX_XML_STRING_IXX + + +#if defined(XSD_USE_CHAR) || !defined(XSD_USE_WCHAR) + +#ifndef XSD_CXX_XML_STRING_IXX_CHAR +#define XSD_CXX_XML_STRING_IXX_CHAR + +#endif // XSD_CXX_XML_STRING_IXX_CHAR +#endif // XSD_USE_CHAR + + +#if defined(XSD_USE_WCHAR) || !defined(XSD_USE_CHAR) + +#ifndef XSD_CXX_XML_STRING_IXX_WCHAR +#define XSD_CXX_XML_STRING_IXX_WCHAR + +namespace xsd +{ + namespace cxx + { + namespace xml + { + namespace bits + { + template <typename W, std::size_t S> + struct wchar_transcoder; + + // Specialization for 2-byte wchar_t (resulting encoding is UTF-16). + // + template <typename W> + struct wchar_transcoder<W, 2> + { + static std::basic_string<W> + to (const XMLCh* s, std::size_t length); + + static XMLCh* + from (const W* s, std::size_t length); + }; + + + // Specialization for 4-byte wchar_t (resulting encoding is UCS-4). + // + template <typename W> + struct wchar_transcoder<W, 4> + { + static std::basic_string<W> + to (const XMLCh* s, std::size_t length); + + static XMLCh* + from (const W* s, std::size_t length); + }; + } + + template <> + inline std::basic_string<wchar_t> + transcode<wchar_t> (const XMLCh* s) + { + if (s == 0) + return std::basic_string<wchar_t> (); + + return bits::wchar_transcoder<wchar_t, sizeof (wchar_t)>::to ( + s, xercesc::XMLString::stringLen (s)); + } + + template <> + inline std::basic_string<wchar_t> + transcode<wchar_t> (const XMLCh* s, std::size_t len) + { + if (s == 0 || len == 0) + return std::basic_string<wchar_t> (); + + return bits::wchar_transcoder<wchar_t, sizeof (wchar_t)>::to ( + s, len); + } + + template <> + inline XMLCh* + transcode_to_xmlch (const wchar_t* s) + { + return bits::wchar_transcoder<wchar_t, sizeof (wchar_t)>::from ( + s, std::char_traits<wchar_t>::length (s)); + } + + template <> + inline XMLCh* + transcode_to_xmlch (const std::basic_string<wchar_t>& s) + { + return bits::wchar_transcoder<wchar_t, sizeof (wchar_t)>::from ( + s.c_str (), s.length ()); + } + } + } +} + +#endif // XSD_CXX_XML_STRING_IXX_WCHAR +#endif // XSD_USE_WCHAR diff --git a/xsd/libxsd/xsd/cxx/xml/string.txx b/xsd/libxsd/xsd/cxx/xml/string.txx new file mode 100644 index 0000000..df0fb74 --- /dev/null +++ b/xsd/libxsd/xsd/cxx/xml/string.txx @@ -0,0 +1,151 @@ +// file : xsd/cxx/xml/string.txx +// author : Boris Kolpackov <boris@codesynthesis.com> +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSD_CXX_XML_STRING_TXX +#define XSD_CXX_XML_STRING_TXX + + +#endif // XSD_CXX_XML_STRING_TXX + +#if defined(XSD_USE_WCHAR) || !defined(XSD_USE_CHAR) + +#ifndef XSD_CXX_XML_STRING_TXX_WCHAR +#define XSD_CXX_XML_STRING_TXX_WCHAR + +#include <xsd/cxx/xml/exceptions.hxx> + +namespace xsd +{ + namespace cxx + { + namespace xml + { + namespace bits + { + // wchar_transcoder (specialization for 2-byte wchar_t) + // + template <typename W> + std::basic_string<W> wchar_transcoder<W, 2>:: + to (const XMLCh* s, std::size_t length) + { + std::basic_string<W> r; + r.reserve (length + 1); + r.resize (length); + W* rs (const_cast<W*> (r.c_str ())); + + for (std::size_t i (0); i < length; ++s, ++i) + { + rs[i] = *s; + } + + return r; + } + + template <typename W> + XMLCh* wchar_transcoder<W, 2>:: + from (const W* s, std::size_t length) + { + auto_array<XMLCh> r (new XMLCh[length + 1]); + XMLCh* ir (r.get ()); + + for (std::size_t i (0); i < length; ++ir, ++i) + { + *ir = static_cast<XMLCh> (s[i]); + } + + *ir = XMLCh (0); + + return r.release (); + } + + + // wchar_transcoder (specialization for 4-byte wchar_t) + // + template <typename W> + std::basic_string<W> wchar_transcoder<W, 4>:: + to (const XMLCh* s, std::size_t length) + { + const XMLCh* end (s + length); + + // Find what the resulting buffer size will be. + // + std::size_t rl (0); + + for (const XMLCh* p (s); p < end; ++p) + { + rl++; + + if ((*p >= 0xD800) && (*p <= 0xDBFF)) + { + // Make sure we have one more char and it has a valid + // value for the second char in a surrogate pair. + // + if (++p == end || !((*p >= 0xDC00) && (*p <= 0xDFFF))) + throw invalid_utf16_string (); + } + } + + std::basic_string<W> r; + r.reserve (rl + 1); + r.resize (rl); + W* rs (const_cast<W*> (r.c_str ())); + + std::size_t i (0); + + for (const XMLCh* p (s); p < end; ++p) + { + XMLCh x (*p); + + if (x < 0xD800 || x > 0xDBFF) + rs[i++] = W (x); + else + rs[i++] = ((x - 0xD800) << 10) + (*++p - 0xDC00) + 0x10000; + } + + return r; + } + + template <typename W> + XMLCh* wchar_transcoder<W, 4>:: + from (const W* s, std::size_t length) + { + // Find what the resulting buffer size will be. + // + std::size_t rl (0); + + for (const W* p (s); p < s + length; ++p) + { + rl += (*p & 0xFFFF0000) ? 2 : 1; + } + + auto_array<XMLCh> r (new XMLCh[rl + 1]); + XMLCh* ir (r.get ()); + + for (const W* p (s); p < s + length; ++p) + { + W w (*p); + + if (w & 0xFFFF0000) + { + // Surrogate pair. + // + *ir++ = static_cast<XMLCh> (((w - 0x10000) >> 10) + 0xD800); + *ir++ = static_cast<XMLCh> ((w & 0x3FF) + 0xDC00); + } + else + *ir++ = static_cast<XMLCh> (w); + } + + *ir = XMLCh (0); + + return r.release (); + } + } + } + } +} + +#endif // XSD_CXX_XML_STRING_TXX_WCHAR +#endif // XSD_USE_WCHAR |