summaryrefslogtreecommitdiff
path: root/libxsd/libxsd/cxx/xml
diff options
context:
space:
mode:
authorKaren Arutyunov <karen@codesynthesis.com>2020-12-18 18:48:46 +0300
committerKaren Arutyunov <karen@codesynthesis.com>2021-01-13 22:32:43 +0300
commit2615896faa646e5830abf2c269150e1165c66515 (patch)
tree7d95978ec0a83094c9462ed4e1f59d42f4ff8ddb /libxsd/libxsd/cxx/xml
parent7420f85ea19b0562ffdd8123442f32bc8bac1267 (diff)
Switch to build2
Diffstat (limited to 'libxsd/libxsd/cxx/xml')
-rw-r--r--libxsd/libxsd/cxx/xml/bits/literals.hxx81
-rw-r--r--libxsd/libxsd/cxx/xml/bits/literals.ixx259
-rw-r--r--libxsd/libxsd/cxx/xml/char-iso8859-1.hxx70
-rw-r--r--libxsd/libxsd/cxx/xml/char-iso8859-1.txx110
-rw-r--r--libxsd/libxsd/cxx/xml/char-lcp.hxx54
-rw-r--r--libxsd/libxsd/cxx/xml/char-lcp.txx73
-rw-r--r--libxsd/libxsd/cxx/xml/char-utf8.hxx55
-rw-r--r--libxsd/libxsd/cxx/xml/char-utf8.txx306
-rw-r--r--libxsd/libxsd/cxx/xml/dom/auto-ptr.hxx232
-rw-r--r--libxsd/libxsd/cxx/xml/dom/bits/error-handler-proxy.hxx59
-rw-r--r--libxsd/libxsd/cxx/xml/dom/bits/error-handler-proxy.txx66
-rw-r--r--libxsd/libxsd/cxx/xml/dom/elements.hxx34
-rw-r--r--libxsd/libxsd/cxx/xml/dom/elements.txx55
-rw-r--r--libxsd/libxsd/cxx/xml/dom/parsing-header.hxx22
-rw-r--r--libxsd/libxsd/cxx/xml/dom/parsing-source.hxx152
-rw-r--r--libxsd/libxsd/cxx/xml/dom/parsing-source.txx379
-rw-r--r--libxsd/libxsd/cxx/xml/dom/serialization-header.hxx79
-rw-r--r--libxsd/libxsd/cxx/xml/dom/serialization-header.txx188
-rw-r--r--libxsd/libxsd/cxx/xml/dom/serialization-source.hxx181
-rw-r--r--libxsd/libxsd/cxx/xml/dom/serialization-source.txx362
-rw-r--r--libxsd/libxsd/cxx/xml/dom/wildcard-source.hxx29
-rw-r--r--libxsd/libxsd/cxx/xml/dom/wildcard-source.txx36
-rw-r--r--libxsd/libxsd/cxx/xml/elements.hxx116
-rw-r--r--libxsd/libxsd/cxx/xml/elements.txx71
-rw-r--r--libxsd/libxsd/cxx/xml/error-handler.hxx57
-rw-r--r--libxsd/libxsd/cxx/xml/exceptions.hxx18
-rw-r--r--libxsd/libxsd/cxx/xml/qualified-name.hxx82
-rw-r--r--libxsd/libxsd/cxx/xml/sax/bits/error-handler-proxy.hxx78
-rw-r--r--libxsd/libxsd/cxx/xml/sax/bits/error-handler-proxy.txx76
-rw-r--r--libxsd/libxsd/cxx/xml/sax/std-input-source.hxx151
-rw-r--r--libxsd/libxsd/cxx/xml/std-memory-manager.hxx53
-rw-r--r--libxsd/libxsd/cxx/xml/string.hxx89
-rw-r--r--libxsd/libxsd/cxx/xml/string.ixx169
-rw-r--r--libxsd/libxsd/cxx/xml/string.txx161
34 files changed, 4003 insertions, 0 deletions
diff --git a/libxsd/libxsd/cxx/xml/bits/literals.hxx b/libxsd/libxsd/cxx/xml/bits/literals.hxx
new file mode 100644
index 0000000..cc100af
--- /dev/null
+++ b/libxsd/libxsd/cxx/xml/bits/literals.hxx
@@ -0,0 +1,81 @@
+// file : libxsd/cxx/xml/bits/literals.hxx
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef LIBXSD_CXX_XML_BITS_LITERALS_HXX
+#define LIBXSD_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 // LIBXSD_CXX_XML_BITS_LITERALS_HXX
+
+#include <libxsd/cxx/xml/bits/literals.ixx>
diff --git a/libxsd/libxsd/cxx/xml/bits/literals.ixx b/libxsd/libxsd/cxx/xml/bits/literals.ixx
new file mode 100644
index 0000000..f09d9f2
--- /dev/null
+++ b/libxsd/libxsd/cxx/xml/bits/literals.ixx
@@ -0,0 +1,259 @@
+// file : libxsd/cxx/xml/bits/literals.ixx
+// 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/libxsd/libxsd/cxx/xml/char-iso8859-1.hxx b/libxsd/libxsd/cxx/xml/char-iso8859-1.hxx
new file mode 100644
index 0000000..0577dc8
--- /dev/null
+++ b/libxsd/libxsd/cxx/xml/char-iso8859-1.hxx
@@ -0,0 +1,70 @@
+// file : libxsd/cxx/xml/char-iso8859-1.hxx
+// 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 <libxsd/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 <libxsd/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/libxsd/libxsd/cxx/xml/char-iso8859-1.txx b/libxsd/libxsd/cxx/xml/char-iso8859-1.txx
new file mode 100644
index 0000000..01bda43
--- /dev/null
+++ b/libxsd/libxsd/cxx/xml/char-iso8859-1.txx
@@ -0,0 +1,110 @@
+// file : libxsd/cxx/xml/char-iso8859-1.txx
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <libxsd/cxx/config.hxx> // XSD_CXX11
+
+#ifdef XSD_CXX11
+# include <memory> // std::unique_ptr
+#else
+# include <libxsd/cxx/auto-array.hxx>
+#endif
+
+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);
+
+#ifdef XSD_CXX11
+ std::unique_ptr<XMLCh[]> r (
+#else
+ auto_array<XMLCh> r (
+#endif
+ 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/libxsd/libxsd/cxx/xml/char-lcp.hxx b/libxsd/libxsd/cxx/xml/char-lcp.hxx
new file mode 100644
index 0000000..33e421f
--- /dev/null
+++ b/libxsd/libxsd/cxx/xml/char-lcp.hxx
@@ -0,0 +1,54 @@
+// file : libxsd/cxx/xml/char-lcp.hxx
+// 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 <libxsd/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/libxsd/libxsd/cxx/xml/char-lcp.txx b/libxsd/libxsd/cxx/xml/char-lcp.txx
new file mode 100644
index 0000000..46ce034
--- /dev/null
+++ b/libxsd/libxsd/cxx/xml/char-lcp.txx
@@ -0,0 +1,73 @@
+// file : libxsd/cxx/xml/char-lcp.txx
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <cstring> // std::memcpy
+
+#include <xercesc/util/XMLString.hpp>
+
+#include <libxsd/cxx/config.hxx> // XSD_CXX11
+
+#ifdef XSD_CXX11
+# include <memory> // std::unique_ptr
+#else
+# include <libxsd/cxx/auto-array.hxx>
+#endif
+
+#include <libxsd/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;
+#ifdef XSD_CXX11
+ std::unique_ptr<C[], std_memory_manager&> r (
+#else
+ auto_array<C, std_memory_manager> r (
+#endif
+ 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)
+ {
+#ifdef XSD_CXX11
+ std::unique_ptr<XMLCh[]> tmp (
+#else
+ auto_array<XMLCh> tmp (
+#endif
+ new XMLCh[len + 1]);
+ std::memcpy (tmp.get (), s, len * sizeof (XMLCh));
+ tmp[len] = XMLCh (0);
+
+ std_memory_manager mm;
+#ifdef XSD_CXX11
+ std::unique_ptr<C[], std_memory_manager&> r (
+#else
+ auto_array<C, std_memory_manager> r (
+#endif
+ 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/libxsd/libxsd/cxx/xml/char-utf8.hxx b/libxsd/libxsd/cxx/xml/char-utf8.hxx
new file mode 100644
index 0000000..0541100
--- /dev/null
+++ b/libxsd/libxsd/cxx/xml/char-utf8.hxx
@@ -0,0 +1,55 @@
+// file : libxsd/cxx/xml/char-utf8.hxx
+// 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 <libxsd/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 <libxsd/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/libxsd/libxsd/cxx/xml/char-utf8.txx b/libxsd/libxsd/cxx/xml/char-utf8.txx
new file mode 100644
index 0000000..961a8c8
--- /dev/null
+++ b/libxsd/libxsd/cxx/xml/char-utf8.txx
@@ -0,0 +1,306 @@
+// file : libxsd/cxx/xml/char-utf8.txx
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <libxsd/cxx/config.hxx> // XSD_CXX11
+
+#ifdef XSD_CXX11
+# include <memory> // std::unique_ptr
+#else
+# include <libxsd/cxx/auto-array.hxx>
+#endif
+
+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;
+ }
+ // Fall through.
+ case 3:
+ {
+ rs[i + 2] = C ((u | 0x80UL) & 0xBFUL);
+ u >>= 6;
+ }
+ // Fall through.
+ case 2:
+ {
+ rs[i + 1] = C ((u | 0x80UL) & 0xBFUL);
+ u >>= 6;
+ }
+ // Fall through.
+ case 1:
+ {
+ rs[i] = C (u | first_byte_mask_[count]);
+ }
+ // Fall through.
+ }
+
+ 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 (static_cast<unsigned char> (*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 ();
+
+#ifdef XSD_CXX11
+ std::unique_ptr<XMLCh[]> r (
+#else
+ auto_array<XMLCh> r (
+#endif
+ 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 (static_cast<unsigned char> (*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/libxsd/libxsd/cxx/xml/dom/auto-ptr.hxx b/libxsd/libxsd/cxx/xml/dom/auto-ptr.hxx
new file mode 100644
index 0000000..4e19547
--- /dev/null
+++ b/libxsd/libxsd/cxx/xml/dom/auto-ptr.hxx
@@ -0,0 +1,232 @@
+// file : libxsd/cxx/xml/dom/auto-ptr.hxx
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef LIBXSD_CXX_XML_DOM_AUTO_PTR_HXX
+#define LIBXSD_CXX_XML_DOM_AUTO_PTR_HXX
+
+#include <libxsd/cxx/config.hxx> // XSD_CXX11_*
+
+#ifdef XSD_CXX11
+# include <memory> // std::unique_ptr
+# include <utility> // std::move
+# include <type_traits> // std::remove_const
+#endif
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace xml
+ {
+ namespace dom
+ {
+#ifdef XSD_CXX11
+ template <typename T>
+ struct deleter
+ {
+ void
+ operator() (T* p) const
+ {
+ if (p != 0)
+ const_cast<typename std::remove_const<T>::type*> (p)->release ();
+ }
+ };
+
+#ifdef XSD_CXX11_TEMPLATE_ALIAS
+ template <typename T>
+ using unique_ptr = std::unique_ptr<T, deleter<T>>;
+#else
+ template <typename T>
+ class unique_ptr: public std::unique_ptr<T, deleter<T>>
+ {
+ public:
+ typedef std::unique_ptr<T, deleter<T>> base;
+
+ typedef typename base::pointer pointer;
+ typedef T element_type;
+ typedef deleter<T> deleter_type;
+
+ unique_ptr (): base () {}
+ explicit unique_ptr (pointer p): base (p) {}
+ unique_ptr (pointer p, const deleter_type& d): base (p, d) {}
+ unique_ptr (pointer p, deleter_type&& d): base (p, std::move (d)) {}
+ unique_ptr (unique_ptr&& p): base (std::move (p)) {}
+ template <class T1>
+ unique_ptr (unique_ptr<T1>&& p): base (std::move (p)) {}
+ template <class T1>
+ unique_ptr (std::auto_ptr<T1>&& p): base (std::move (p)) {}
+
+ unique_ptr& operator= (unique_ptr&& p)
+ {
+ static_cast<base&> (*this) = std::move (p);
+ return *this;
+ }
+
+ template <class T1>
+ unique_ptr& operator= (unique_ptr<T1>&& p)
+ {
+ static_cast<base&> (*this) = std::move (p);
+ return *this;
+ }
+
+#ifdef XSD_CXX11_NULLPTR
+ unique_ptr (std::nullptr_t p): base (p) {}
+
+ unique_ptr& operator= (std::nullptr_t p)
+ {
+ static_cast<base&> (*this) = p;
+ return *this;
+ }
+#endif
+ };
+#endif // XSD_CXX11_TEMPLATE_ALIAS
+
+#define XSD_DOM_AUTO_PTR xsd::cxx::xml::dom::unique_ptr
+
+#else
+ // Simple auto_ptr version for C++98 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_;
+ };
+
+#define XSD_DOM_AUTO_PTR xsd::cxx::xml::dom::auto_ptr
+
+#endif // XSD_CXX11
+ }
+ }
+ }
+}
+
+#endif // LIBXSD_CXX_XML_DOM_AUTO_PTR_HXX
diff --git a/libxsd/libxsd/cxx/xml/dom/bits/error-handler-proxy.hxx b/libxsd/libxsd/cxx/xml/dom/bits/error-handler-proxy.hxx
new file mode 100644
index 0000000..5ebc112
--- /dev/null
+++ b/libxsd/libxsd/cxx/xml/dom/bits/error-handler-proxy.hxx
@@ -0,0 +1,59 @@
+// file : libxsd/cxx/xml/dom/bits/error-handler-proxy.hxx
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef LIBXSD_CXX_XML_DOM_BITS_ERROR_HANDLER_PROXY_HXX
+#define LIBXSD_CXX_XML_DOM_BITS_ERROR_HANDLER_PROXY_HXX
+
+#include <xercesc/dom/DOMError.hpp>
+#include <xercesc/dom/DOMLocator.hpp>
+#include <xercesc/dom/DOMErrorHandler.hpp>
+
+#include <libxsd/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 <libxsd/cxx/xml/dom/bits/error-handler-proxy.txx>
+
+#endif // LIBXSD_CXX_XML_DOM_BITS_ERROR_HANDLER_PROXY_HXX
diff --git a/libxsd/libxsd/cxx/xml/dom/bits/error-handler-proxy.txx b/libxsd/libxsd/cxx/xml/dom/bits/error-handler-proxy.txx
new file mode 100644
index 0000000..8ebc51a
--- /dev/null
+++ b/libxsd/libxsd/cxx/xml/dom/bits/error-handler-proxy.txx
@@ -0,0 +1,66 @@
+// file : libxsd/cxx/xml/dom/bits/error-handler-proxy.txx
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <libxsd/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 ());
+
+ return eh_->handle (
+ transcode<C> (loc->getURI ()),
+ static_cast<unsigned long> (loc->getLineNumber ()),
+ static_cast<unsigned long> (loc->getColumnNumber ()),
+ s,
+ transcode<C> (e.getMessage ()));
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/libxsd/libxsd/cxx/xml/dom/elements.hxx b/libxsd/libxsd/cxx/xml/dom/elements.hxx
new file mode 100644
index 0000000..07913d7
--- /dev/null
+++ b/libxsd/libxsd/cxx/xml/dom/elements.hxx
@@ -0,0 +1,34 @@
+// file : libxsd/cxx/xml/dom/elements.hxx
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef LIBXSD_CXX_XML_DOM_ELEMENTS_HXX
+#define LIBXSD_CXX_XML_DOM_ELEMENTS_HXX
+
+#include <xercesc/dom/DOMAttr.hpp>
+#include <xercesc/dom/DOMElement.hpp>
+
+#include <libxsd/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 <libxsd/cxx/xml/dom/elements.txx>
+
+#endif // LIBXSD_CXX_XML_DOM_ELEMENTS_HXX
diff --git a/libxsd/libxsd/cxx/xml/dom/elements.txx b/libxsd/libxsd/cxx/xml/dom/elements.txx
new file mode 100644
index 0000000..517b8c9
--- /dev/null
+++ b/libxsd/libxsd/cxx/xml/dom/elements.txx
@@ -0,0 +1,55 @@
+// file : libxsd/cxx/xml/dom/elements.txx
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <libxsd/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/libxsd/libxsd/cxx/xml/dom/parsing-header.hxx b/libxsd/libxsd/cxx/xml/dom/parsing-header.hxx
new file mode 100644
index 0000000..5b3822a
--- /dev/null
+++ b/libxsd/libxsd/cxx/xml/dom/parsing-header.hxx
@@ -0,0 +1,22 @@
+// file : libxsd/cxx/xml/dom/parsing-header.hxx
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef LIBXSD_CXX_XML_DOM_PARSING_HEADER_HXX
+#define LIBXSD_CXX_XML_DOM_PARSING_HEADER_HXX
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace xml
+ {
+ namespace dom
+ {
+ template <typename C>
+ class parser;
+ }
+ }
+ }
+}
+
+#endif // LIBXSD_CXX_XML_DOM_PARSING_HEADER_HXX
diff --git a/libxsd/libxsd/cxx/xml/dom/parsing-source.hxx b/libxsd/libxsd/cxx/xml/dom/parsing-source.hxx
new file mode 100644
index 0000000..9016014
--- /dev/null
+++ b/libxsd/libxsd/cxx/xml/dom/parsing-source.hxx
@@ -0,0 +1,152 @@
+// file : libxsd/cxx/xml/dom/parsing-source.hxx
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef LIBXSD_CXX_XML_DOM_PARSING_SOURCE_HXX
+#define LIBXSD_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 <libxsd/cxx/xml/elements.hxx> // properies
+#include <libxsd/cxx/xml/error-handler.hxx>
+#include <libxsd/cxx/xml/dom/auto-ptr.hxx>
+#include <libxsd/cxx/xml/dom/elements.hxx> // name
+#include <libxsd/cxx/xml/dom/parsing-header.hxx>
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace xml
+ {
+ namespace dom
+ {
+ // Parser state object. Can be used for parsing elements (and
+ // optionally text), attributes, or both.
+ //
+ template <typename C>
+ class parser
+ {
+ public:
+ parser (const xercesc::DOMElement& e, bool ep, bool tp, bool ap);
+
+ // Content parsing.
+ //
+ bool
+ more_content ()
+ {
+ return next_content_ != 0;
+ }
+
+ const xercesc::DOMElement&
+ cur_element ()
+ {
+ return *static_cast<const xercesc::DOMElement*> (next_content_);
+ }
+
+ const xercesc::DOMText&
+ cur_text ()
+ {
+ return *static_cast<const xercesc::DOMText*> (next_content_);
+ }
+
+ bool
+ cur_is_text ()
+ {
+ return next_content_->getNodeType () !=
+ xercesc::DOMNode::ELEMENT_NODE;
+ }
+
+ void
+ next_content (bool text);
+
+ // Attribute parsing.
+ //
+ 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_content_;
+
+ 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>
+ XSD_DOM_AUTO_PTR<xercesc::DOMDocument>
+ parse (xercesc::InputSource&,
+ error_handler<C>&,
+ const properties<C>&,
+ unsigned long flags);
+
+ template <typename C>
+ XSD_DOM_AUTO_PTR<xercesc::DOMDocument>
+ parse (xercesc::InputSource&,
+ xercesc::DOMErrorHandler&,
+ const properties<C>&,
+ unsigned long flags);
+
+ template <typename C>
+ XSD_DOM_AUTO_PTR<xercesc::DOMDocument>
+ parse (const std::basic_string<C>& uri,
+ error_handler<C>&,
+ const properties<C>&,
+ unsigned long flags);
+
+ template <typename C>
+ XSD_DOM_AUTO_PTR<xercesc::DOMDocument>
+ parse (const std::basic_string<C>& uri,
+ xercesc::DOMErrorHandler&,
+ const properties<C>&,
+ unsigned long flags);
+ }
+ }
+ }
+}
+
+#include <libxsd/cxx/xml/dom/parsing-source.txx>
+
+#endif // LIBXSD_CXX_XML_DOM_PARSING_SOURCE_HXX
diff --git a/libxsd/libxsd/cxx/xml/dom/parsing-source.txx b/libxsd/libxsd/cxx/xml/dom/parsing-source.txx
new file mode 100644
index 0000000..9a62fed
--- /dev/null
+++ b/libxsd/libxsd/cxx/xml/dom/parsing-source.txx
@@ -0,0 +1,379 @@
+// file : libxsd/cxx/xml/dom/parsing-source.txx
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <xercesc/dom/DOMLSParser.hpp>
+#include <xercesc/dom/DOMLSException.hpp>
+
+#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 <libxsd/cxx/xml/string.hxx>
+#include <libxsd/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 tp, bool ap)
+ : element_ (e),
+ next_content_ (0),
+ a_ (0),
+ ai_ (0)
+ {
+ using xercesc::DOMNode;
+
+ if (ep)
+ {
+ for (next_content_ = e.getFirstChild ();;
+ next_content_ = next_content_->getNextSibling ())
+ {
+ if (next_content_ == 0)
+ break;
+
+ DOMNode::NodeType t (next_content_->getNodeType ());
+
+ if (t == DOMNode::ELEMENT_NODE)
+ break;
+
+ if (tp && (t == DOMNode::TEXT_NODE ||
+ t == DOMNode::CDATA_SECTION_NODE))
+ break;
+ }
+ }
+
+ if (ap)
+ {
+ a_ = e.getAttributes ();
+ as_ = a_->getLength ();
+ }
+ }
+
+ template <typename C>
+ void parser<C>::
+ next_content (bool tp)
+ {
+ using xercesc::DOMNode;
+
+ for (next_content_ = next_content_->getNextSibling ();;
+ next_content_ = next_content_->getNextSibling ())
+ {
+ if (next_content_ == 0)
+ break;
+
+ DOMNode::NodeType t (next_content_->getNodeType ());
+
+ if (t == DOMNode::ELEMENT_NODE)
+ break;
+
+ if (tp && (t == DOMNode::TEXT_NODE ||
+ t == DOMNode::CDATA_SECTION_NODE))
+ break;
+ }
+ }
+
+ // parse()
+ //
+ template <typename C>
+ XSD_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>
+ XSD_DOM_AUTO_PTR<xercesc::DOMDocument>
+ parse (xercesc::InputSource& is,
+ xercesc::DOMErrorHandler& eh,
+ const properties<C>& prop,
+ unsigned long flags)
+ {
+ using namespace xercesc;
+
+ // 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));
+
+ XSD_DOM_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);
+
+ xercesc::Wrapper4InputSource wrap (&is, false);
+
+ XSD_DOM_AUTO_PTR<DOMDocument> doc;
+ try
+ {
+ doc.reset (parser->parse (&wrap));
+ }
+ catch (const xercesc::DOMLSException&)
+ {
+ }
+
+ if (ehp.failed ())
+ doc.reset ();
+
+ return doc;
+ }
+
+ template <typename C>
+ XSD_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>
+ XSD_DOM_AUTO_PTR<xercesc::DOMDocument>
+ parse (const std::basic_string<C>& uri,
+ xercesc::DOMErrorHandler& eh,
+ const properties<C>& prop,
+ unsigned long flags)
+ {
+ using namespace xercesc;
+
+ // 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));
+
+ XSD_DOM_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);
+
+ XSD_DOM_AUTO_PTR<DOMDocument> doc;
+ try
+ {
+ doc.reset (parser->parseURI (string (uri).c_str ()));
+ }
+ catch (const xercesc::DOMLSException&)
+ {
+ }
+
+ if (ehp.failed ())
+ doc.reset ();
+
+ return doc;
+ }
+ }
+ }
+ }
+}
diff --git a/libxsd/libxsd/cxx/xml/dom/serialization-header.hxx b/libxsd/libxsd/cxx/xml/dom/serialization-header.hxx
new file mode 100644
index 0000000..bd18808
--- /dev/null
+++ b/libxsd/libxsd/cxx/xml/dom/serialization-header.hxx
@@ -0,0 +1,79 @@
+// file : libxsd/cxx/xml/dom/serialization-header.hxx
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef LIBXSD_CXX_XML_DOM_SERIALIZATION_HEADER_HXX
+#define LIBXSD_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 <libxsd/cxx/xml/dom/serialization-header.txx>
+
+#endif // LIBXSD_CXX_XML_DOM_SERIALIZATION_HEADER_HXX
diff --git a/libxsd/libxsd/cxx/xml/dom/serialization-header.txx b/libxsd/libxsd/cxx/xml/dom/serialization-header.txx
new file mode 100644
index 0000000..bd08496
--- /dev/null
+++ b/libxsd/libxsd/cxx/xml/dom/serialization-header.txx
@@ -0,0 +1,188 @@
+// file : libxsd/cxx/xml/dom/serialization-header.txx
+// 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 <libxsd/cxx/xml/string.hxx>
+#include <libxsd/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);
+ const XMLCh* p (e.lookupPrefix (xns.c_str ()));
+
+ 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)
+ {
+ // Cannot use 'using namespace' because of MSXML conflict.
+ //
+ using xercesc::XMLUni;
+ using xercesc::XMLString;
+ using xercesc::SchemaSymbols;
+
+ using xercesc::DOMNode;
+ using xercesc::DOMAttr;
+ using xercesc::DOMNamedNodeMap;
+
+ // Remove child nodes.
+ //
+ while (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, 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/libxsd/libxsd/cxx/xml/dom/serialization-source.hxx b/libxsd/libxsd/cxx/xml/dom/serialization-source.hxx
new file mode 100644
index 0000000..135aa28
--- /dev/null
+++ b/libxsd/libxsd/cxx/xml/dom/serialization-source.hxx
@@ -0,0 +1,181 @@
+// file : libxsd/cxx/xml/dom/serialization-source.hxx
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef LIBXSD_CXX_XML_DOM_SERIALIZATION_SOURCE_HXX
+#define LIBXSD_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 <libxsd/cxx/xml/error-handler.hxx>
+#include <libxsd/cxx/xml/dom/auto-ptr.hxx>
+#include <libxsd/cxx/xml/dom/elements.hxx> // name
+#include <libxsd/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&);
+
+ // Add namespace declarations and schema locations.
+ //
+ template <typename C>
+ void
+ add_namespaces (xercesc::DOMElement&, const namespace_infomap<C>&);
+
+ // Serialization flags.
+ //
+ const unsigned long no_xml_declaration = 0x00010000UL;
+ const unsigned long dont_pretty_print = 0x00020000UL;
+
+ template <typename C>
+ XSD_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 XSD_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 thinks there
+ // are different signatures if one strips this fluff off.
+ //
+ virtual void
+ writeChars (const XMLByte* const buf,
+ const XMLSize_t size,
+ 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 <libxsd/cxx/xml/dom/serialization-source.txx>
+
+#endif // LIBXSD_CXX_XML_DOM_SERIALIZATION_SOURCE_HXX
diff --git a/libxsd/libxsd/cxx/xml/dom/serialization-source.txx b/libxsd/libxsd/cxx/xml/dom/serialization-source.txx
new file mode 100644
index 0000000..1718327
--- /dev/null
+++ b/libxsd/libxsd/cxx/xml/dom/serialization-source.txx
@@ -0,0 +1,362 @@
+// file : libxsd/cxx/xml/dom/serialization-source.txx
+// 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>
+
+#include <xercesc/dom/DOMLSOutput.hpp>
+#include <xercesc/dom/DOMLSSerializer.hpp>
+
+#include <xercesc/dom/DOMElement.hpp>
+#include <xercesc/dom/DOMImplementation.hpp>
+#include <xercesc/dom/DOMImplementationRegistry.hpp>
+
+#include <libxsd/cxx/xml/string.hxx>
+#include <libxsd/cxx/xml/bits/literals.hxx>
+#include <libxsd/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>
+ void
+ add_namespaces (xercesc::DOMElement& el,
+ const namespace_infomap<C>& map)
+ {
+ using namespace xercesc;
+
+ typedef std::basic_string<C> string;
+ typedef namespace_infomap<C> infomap;
+ typedef typename infomap::const_iterator infomap_iterator;
+
+ C colon (':'), space (' ');
+
+ // 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 ())
+ el.setAttributeNS (
+ xercesc::XMLUni::fgXMLNSURIName,
+ xml::string (xmlns_prefix).c_str (),
+ xml::string (i->second.name).c_str ());
+ }
+ else
+ {
+ el.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> (),
+ el,
+ 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 ())
+ {
+ el.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 ())
+ {
+ el.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 ());
+ }
+ }
+
+ //
+ //
+ template <typename C>
+ XSD_DOM_AUTO_PTR<xercesc::DOMDocument>
+ serialize (const std::basic_string<C>& el,
+ const std::basic_string<C>& ns,
+ const namespace_infomap<C>& map,
+ unsigned long)
+ {
+ using namespace xercesc;
+
+ typedef std::basic_string<C> string;
+ typedef namespace_infomap<C> infomap;
+ typedef typename infomap::const_iterator infomap_iterator;
+
+ 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));
+
+ XSD_DOM_AUTO_PTR<DOMDocument> doc (
+ impl->createDocument (
+ (ns.empty () ? 0 : xml::string (ns).c_str ()),
+ xml::string ((prefix.empty ()
+ ? el
+ : prefix + C (':') + el)).c_str (),
+ 0));
+
+ add_namespaces (*doc->getDocumentElement (), map);
+
+ 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)
+ {
+ using namespace xercesc;
+
+ const XMLCh ls[] = {xercesc::chLatin_L,
+ xercesc::chLatin_S,
+ xercesc::chNull};
+
+ DOMImplementation* impl (
+ DOMImplementationRegistry::getDOMImplementation (ls));
+
+ bits::error_handler_proxy<C> ehp (eh);
+
+ XSD_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);
+
+ // Don't add extra new lines between first-level elements.
+ //
+ if (conf->canSetParameter (XMLUni::fgDOMWRTXercesPrettyPrint, true))
+ conf->setParameter (XMLUni::fgDOMWRTXercesPrettyPrint, false);
+ }
+
+ // See if we need to write XML declaration.
+ //
+ if ((flags & no_xml_declaration) &&
+ conf->canSetParameter (XMLUni::fgDOMXMLDeclaration, false))
+ conf->setParameter (XMLUni::fgDOMXMLDeclaration, false);
+
+ XSD_DOM_AUTO_PTR<DOMLSOutput> out (impl->createLSOutput ());
+
+ out->setEncoding (xml::string (encoding).c_str ());
+ out->setByteStream (&target);
+
+ if (!writer->write (&doc, out.get ()) || 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/libxsd/libxsd/cxx/xml/dom/wildcard-source.hxx b/libxsd/libxsd/cxx/xml/dom/wildcard-source.hxx
new file mode 100644
index 0000000..3d9c7d8
--- /dev/null
+++ b/libxsd/libxsd/cxx/xml/dom/wildcard-source.hxx
@@ -0,0 +1,29 @@
+// file : libxsd/cxx/xml/dom/wildcard-source.hxx
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef LIBXSD_CXX_XML_DOM_WILDCARD_SOURCE_HXX
+#define LIBXSD_CXX_XML_DOM_WILDCARD_SOURCE_HXX
+
+#include <xercesc/dom/DOMDocument.hpp>
+
+#include <libxsd/cxx/xml/dom/auto-ptr.hxx>
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace xml
+ {
+ namespace dom
+ {
+ template <typename C>
+ XSD_DOM_AUTO_PTR<xercesc::DOMDocument>
+ create_document ();
+ }
+ }
+ }
+}
+
+#include <libxsd/cxx/xml/dom/wildcard-source.txx>
+
+#endif // LIBXSD_CXX_XML_DOM_WILDCARD_SOURCE_HXX
diff --git a/libxsd/libxsd/cxx/xml/dom/wildcard-source.txx b/libxsd/libxsd/cxx/xml/dom/wildcard-source.txx
new file mode 100644
index 0000000..a064003
--- /dev/null
+++ b/libxsd/libxsd/cxx/xml/dom/wildcard-source.txx
@@ -0,0 +1,36 @@
+// file : libxsd/cxx/xml/dom/wildcard-source.txx
+// 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>
+ XSD_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 XSD_DOM_AUTO_PTR<xercesc::DOMDocument> (
+ impl->createDocument ());
+ }
+ }
+ }
+ }
+}
diff --git a/libxsd/libxsd/cxx/xml/elements.hxx b/libxsd/libxsd/cxx/xml/elements.hxx
new file mode 100644
index 0000000..a62e11a
--- /dev/null
+++ b/libxsd/libxsd/cxx/xml/elements.hxx
@@ -0,0 +1,116 @@
+// file : libxsd/cxx/xml/elements.hxx
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef LIBXSD_CXX_XML_ELEMENTS_HXX
+#define LIBXSD_CXX_XML_ELEMENTS_HXX
+
+#include <string>
+
+#include <xercesc/util/XercesVersion.hpp>
+#include <xercesc/util/PlatformUtils.hpp>
+
+#if _XERCES_VERSION < 30000
+# error Xerces-C++ 2-series is not supported
+#endif
+
+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 <libxsd/cxx/xml/elements.txx>
+
+#endif // LIBXSD_CXX_XML_ELEMENTS_HXX
diff --git a/libxsd/libxsd/cxx/xml/elements.txx b/libxsd/libxsd/cxx/xml/elements.txx
new file mode 100644
index 0000000..7ef2855
--- /dev/null
+++ b/libxsd/libxsd/cxx/xml/elements.txx
@@ -0,0 +1,71 @@
+// file : libxsd/cxx/xml/elements.txx
+// 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/libxsd/libxsd/cxx/xml/error-handler.hxx b/libxsd/libxsd/cxx/xml/error-handler.hxx
new file mode 100644
index 0000000..97b6c58
--- /dev/null
+++ b/libxsd/libxsd/cxx/xml/error-handler.hxx
@@ -0,0 +1,57 @@
+// file : libxsd/cxx/xml/error-handler.hxx
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef LIBXSD_CXX_XML_ERROR_HANDLER_HXX
+#define LIBXSD_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 // LIBXSD_CXX_XML_ERROR_HANDLER_HXX
diff --git a/libxsd/libxsd/cxx/xml/exceptions.hxx b/libxsd/libxsd/cxx/xml/exceptions.hxx
new file mode 100644
index 0000000..fbd80d5
--- /dev/null
+++ b/libxsd/libxsd/cxx/xml/exceptions.hxx
@@ -0,0 +1,18 @@
+// file : libxsd/cxx/xml/exceptions.hxx
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef LIBXSD_CXX_XML_EXCEPTIONS_HXX
+#define LIBXSD_CXX_XML_EXCEPTIONS_HXX
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace xml
+ {
+ struct invalid_utf16_string {};
+ }
+ }
+}
+
+#endif // LIBXSD_CXX_XML_EXCEPTIONS_HXX
diff --git a/libxsd/libxsd/cxx/xml/qualified-name.hxx b/libxsd/libxsd/cxx/xml/qualified-name.hxx
new file mode 100644
index 0000000..38661f2
--- /dev/null
+++ b/libxsd/libxsd/cxx/xml/qualified-name.hxx
@@ -0,0 +1,82 @@
+// file : libxsd/cxx/xml/qualified-name.hxx
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef LIBXSD_CXX_XML_QUALIFIED_NAME_HXX
+#define LIBXSD_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 // LIBXSD_CXX_XML_QUALIFIED_NAME_HXX
diff --git a/libxsd/libxsd/cxx/xml/sax/bits/error-handler-proxy.hxx b/libxsd/libxsd/cxx/xml/sax/bits/error-handler-proxy.hxx
new file mode 100644
index 0000000..e730ee3
--- /dev/null
+++ b/libxsd/libxsd/cxx/xml/sax/bits/error-handler-proxy.hxx
@@ -0,0 +1,78 @@
+// file : libxsd/cxx/xml/sax/bits/error-handler-proxy.hxx
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef LIBXSD_CXX_XML_SAX_ERROR_HANDLER_PROXY_HXX
+#define LIBXSD_CXX_XML_SAX_ERROR_HANDLER_PROXY_HXX
+
+#include <xercesc/sax/ErrorHandler.hpp>
+#include <xercesc/sax/SAXParseException.hpp>
+
+#include <libxsd/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 <libxsd/cxx/xml/sax/bits/error-handler-proxy.txx>
+
+#endif // LIBXSD_CXX_XML_SAX_ERROR_HANDLER_PROXY_HXX
diff --git a/libxsd/libxsd/cxx/xml/sax/bits/error-handler-proxy.txx b/libxsd/libxsd/cxx/xml/sax/bits/error-handler-proxy.txx
new file mode 100644
index 0000000..5809c30
--- /dev/null
+++ b/libxsd/libxsd/cxx/xml/sax/bits/error-handler-proxy.txx
@@ -0,0 +1,76 @@
+// file : libxsd/cxx/xml/sax/bits/error-handler-proxy.txx
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <libxsd/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 ();
+
+ eh_->handle (transcode<C> (id),
+ static_cast<unsigned long> (e.getLineNumber ()),
+ static_cast<unsigned long> (e.getColumnNumber ()),
+ s,
+ transcode<C> (e.getMessage ()));
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/libxsd/libxsd/cxx/xml/sax/std-input-source.hxx b/libxsd/libxsd/cxx/xml/sax/std-input-source.hxx
new file mode 100644
index 0000000..c51577f
--- /dev/null
+++ b/libxsd/libxsd/cxx/xml/sax/std-input-source.hxx
@@ -0,0 +1,151 @@
+// file : libxsd/cxx/xml/sax/std-input-source.hxx
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef LIBXSD_CXX_XML_SAX_STD_INPUT_SOURCE_HXX
+#define LIBXSD_CXX_XML_SAX_STD_INPUT_SOURCE_HXX
+
+#include <istream>
+
+#include <libxsd/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)
+ {
+ }
+
+ virtual XMLFilePos
+ curPos () const
+ {
+ return static_cast<XMLFilePos> (is_.tellg ());
+ }
+
+ virtual XMLSize_t
+ readBytes (XMLByte* const buf, const XMLSize_t size)
+ {
+ // 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.
+ //
+ return !is_.fail ()
+ ? static_cast<XMLSize_t> (is_.gcount ())
+ : 0;
+ }
+
+ virtual const XMLCh*
+ getContentType () const
+ {
+ return 0;
+ }
+
+ 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 // LIBXSD_CXX_XML_SAX_STD_INPUT_SOURCE_HXX
diff --git a/libxsd/libxsd/cxx/xml/std-memory-manager.hxx b/libxsd/libxsd/cxx/xml/std-memory-manager.hxx
new file mode 100644
index 0000000..9d4e339
--- /dev/null
+++ b/libxsd/libxsd/cxx/xml/std-memory-manager.hxx
@@ -0,0 +1,53 @@
+// file : libxsd/cxx/xml/std-memory-manager.hxx
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef LIBXSD_CXX_XML_STD_MEMORY_MANAGER_HXX
+#define LIBXSD_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:
+ // Xerces-C++ MemoryManager interface.
+ //
+ virtual void*
+ allocate(XMLSize_t size)
+ {
+ return operator new (size);
+ }
+
+ virtual void
+ deallocate(void* p)
+ {
+ if (p)
+ operator delete (p);
+ }
+
+ virtual xercesc::MemoryManager*
+ getExceptionMemoryManager()
+ {
+ return xercesc::XMLPlatformUtils::fgMemoryManager;
+ }
+
+ // Standard deleter interface.
+ //
+ void
+ operator() (void* p) const
+ {
+ if (p)
+ operator delete (p);
+ }
+ };
+ }
+ }
+}
+
+#endif // LIBXSD_CXX_XML_STD_MEMORY_MANAGER_HXX
diff --git a/libxsd/libxsd/cxx/xml/string.hxx b/libxsd/libxsd/cxx/xml/string.hxx
new file mode 100644
index 0000000..8b9e69d
--- /dev/null
+++ b/libxsd/libxsd/cxx/xml/string.hxx
@@ -0,0 +1,89 @@
+// file : libxsd/cxx/xml/string.hxx
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef LIBXSD_CXX_XML_STRING_HXX
+#define LIBXSD_CXX_XML_STRING_HXX
+
+#include <string>
+#include <cstddef> // std::size_t
+
+#include <xercesc/util/XercesDefs.hpp> // XMLCh
+
+#include <libxsd/cxx/config.hxx> // XSD_CXX11
+
+#ifdef XSD_CXX11
+# include <memory> // std::unique_ptr
+#else
+# include <libxsd/cxx/auto-array.hxx>
+#endif
+
+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 VC 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 ();}
+
+ XMLCh*
+ release () {return s_.release ();}
+
+ private:
+ string (const string&);
+
+ string&
+ operator= (const string&);
+
+ private:
+#ifdef XSD_CXX11
+ std::unique_ptr<XMLCh[]> s_;
+#else
+ auto_array<XMLCh> s_;
+#endif
+ };
+ }
+ }
+}
+
+#endif // LIBXSD_CXX_XML_STRING_HXX
+
+#include <libxsd/cxx/xml/string.ixx>
+#include <libxsd/cxx/xml/string.txx>
diff --git a/libxsd/libxsd/cxx/xml/string.ixx b/libxsd/libxsd/cxx/xml/string.ixx
new file mode 100644
index 0000000..39b120a
--- /dev/null
+++ b/libxsd/libxsd/cxx/xml/string.ixx
@@ -0,0 +1,169 @@
+// file : libxsd/cxx/xml/string.ixx
+// 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 <libxsd/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/libxsd/libxsd/cxx/xml/string.txx b/libxsd/libxsd/cxx/xml/string.txx
new file mode 100644
index 0000000..7902d8a
--- /dev/null
+++ b/libxsd/libxsd/cxx/xml/string.txx
@@ -0,0 +1,161 @@
+// file : libxsd/cxx/xml/string.txx
+// 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 <libxsd/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)
+ {
+#ifdef XSD_CXX11
+ std::unique_ptr<XMLCh[]> r (
+#else
+ auto_array<XMLCh> r (
+#endif
+ 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;
+ }
+
+#ifdef XSD_CXX11
+ std::unique_ptr<XMLCh[]> r (
+#else
+ auto_array<XMLCh> r (
+#endif
+ 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