summaryrefslogtreecommitdiff
path: root/src/sablo.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/sablo.h')
-rw-r--r--src/sablo.h2139
1 files changed, 2139 insertions, 0 deletions
diff --git a/src/sablo.h b/src/sablo.h
new file mode 100644
index 0000000..99cfc40
--- /dev/null
+++ b/src/sablo.h
@@ -0,0 +1,2139 @@
+//
+// AUTHOR
+// N. Nielsen
+//
+// LICENSE
+// This software is in the public domain.
+//
+// The software is provided "as is", without warranty of any kind,
+// express or implied, including but not limited to the warranties
+// of merchantability, fitness for a particular purpose, and
+// noninfringement. In no event shall the author(s) be liable for any
+// claim, damages, or other liability, whether in an action of
+// contract, tort, or otherwise, arising from, out of, or in connection
+// with the software or the use or other dealings in the software.
+//
+// SUPPORT
+// Send bug reports to: <nielsen@memberwebs.com>
+//
+// SITE
+// http://memberwebs.com/nielsen/
+//
+
+// SABLOTRON C++ WRAPPER
+//
+// This wrapper tries to emulate the W3C DOM as much as possible.
+// Objects returned can be copied liberally. When copied they still
+// refer to the original Sablotron classes.
+// Almost all classes are "light" wrappers, and shouldn't be more
+// than 4 to 8 bytes a piece, with no additional memory allocation.
+// Certain objects (NodeList, NamedNodeMap implementations) are
+// heavier, and are reference counted.
+//
+// Salbotron uses UTF8 exclusively internally. This wrapper
+// supports on the fly conversions from UTF16. Define the following
+// constants to enable conversions:
+//
+// USE_UTF16
+// Convert all data values from UTF16 to UTF8.
+//
+// DOM_UTF16
+// Convert all DOM names from UTF16 to UTF8.
+//
+// If either of the above two constants are enabled you must include
+// salbotr.cpp in your build.
+//
+// Everything is in the DOM namespace.
+//
+// Objects of type Document and DOMImplementation must be manually
+// freed with their 'release' member function.
+//
+//
+
+#ifndef __SABLO_H__
+#define __SABLO_H__
+
+#define USE_UTF16
+// #define DOM_UTF16
+
+#include <stdio.h>
+#include <wchar.h>
+#include <exception>
+#include <string>
+
+namespace DOM
+{
+ namespace S
+ {
+ extern "C"
+ {
+ #include <sablot.h>
+ #include <sdom.h>
+ }
+ };
+
+ bool transcode16to8(const std::basic_string<wchar_t>& data,
+ std::basic_string<char>& ret);
+ bool transcode8to16(const std::basic_string<char>& data,
+ std::basic_string<wchar_t>& ret);
+
+ namespace INT
+ {
+ typedef std::basic_string<char> _8str;
+ typedef std::basic_string<wchar_t> _16str;
+ }
+
+#ifdef ASSERT
+ #define DOM_ASSERT ASSERT
+#else
+ #include "assert.h"
+ #define ASSERT assert
+#endif
+
+#ifdef USE_UTF16
+ #ifdef DOM_UTF16
+ typedef INT::_16str data_str;
+ typedef INT::_16str dom_str;
+ #define FROM_V(v) _16to8(v)
+ #define FROM_D(v) _16to8(v)
+ #define TO_V(v) _8to16(v)
+ #define TO_D(v) _8to16(v)
+ #else
+ typedef INT::_16str data_str;
+ typedef INT::_8str dom_str;
+ #define FROM_V(v) _16to8(v)
+ #define FROM_D(v) v
+ #define TO_V(v) _8to16(v)
+ #define TO_D(v) v
+ #endif
+#else
+ typedef INT::_8str data_str;
+ typedef INT::_8str dom_str;
+ #define FROM_V(v) v
+ #define FROM_D(v) v
+ #define TO_V(v) v
+ #define TO_D(v) v
+#endif
+
+ namespace INT
+ {
+ template<typename C>
+ class Ref
+ {
+ public:
+ Ref()
+ { m_ptr = NULL; }
+
+ Ref(C* ptr)
+ {
+ m_ptr = ptr;
+ addref();
+ }
+
+ Ref(C* ptr, bool addref)
+ {
+ m_ptr = ptr;
+ if(addref)
+ addref();
+ }
+
+ ~Ref()
+ {
+ release();
+ }
+
+ Ref(const Ref& orig)
+ {
+ m_ptr = orig.m_ptr;
+ addref();
+ }
+
+ Ref& operator=(const C* ptr)
+ {
+ C* old = m_ptr;
+ m_ptr = (C*)ptr;
+ addref();
+ if(old)
+ old->release();
+ return *this;
+ }
+
+ Ref& operator=(const Ref& orig)
+ { return operator=(orig.m_ptr); }
+
+#ifdef COMPARE_REF
+ bool operator==(const C* ptr)
+ {
+ if(m_ptr == NULL && ptr == NULL)
+ return true;
+ else if(m_ptr == NULL || ptr == NULL)
+ return false;
+
+ return *ptr == *m_ptr;
+ }
+
+ bool operator==(const Ref& orig)
+ { return operator==(orig.m_ptr); }
+#else
+ bool operator==(const C* ptr)
+ {
+ ASSERT(ptr == NULL);
+ return m_ptr == NULL;
+ }
+#endif
+ operator C*() const
+ { return m_ptr; }
+
+ operator C&() const
+ { return &m_ptr; }
+
+ C* operator->() const
+ { return m_ptr; }
+
+ protected:
+ void release()
+ {
+ if(m_ptr)
+ m_ptr->release();
+ m_ptr = NULL;
+ }
+
+ void addref()
+ {
+ if(m_ptr)
+ m_ptr->addref();
+ }
+
+ private:
+ C* m_ptr;
+ };
+
+ class Inst
+ {
+ public:
+ Inst()
+ { m_x = 0; }
+ virtual ~Inst()
+ { }
+ void addref()
+ { m_x++; }
+ void release()
+ {
+ if((--m_x) <= 0)
+ delete this;
+ }
+
+ private:
+ int m_x;
+ };
+
+ class Base;
+ };
+
+ #define ASSERT_VALID() \
+ ASSERT(isValid());
+ #define ASSERT_VALID_NODE(node) \
+ ASSERT(node.isValid());
+ #define ASSERT_TYPE(t) \
+ ASSERT(getNodeType() == t)
+ #define ASSERT_NODE_TYPE(n, t) \
+ ASSERT(n.getNodeType() == t)
+
+ class DOMException
+ {
+ public:
+ typedef enum
+ {
+ INDEX_SIZE_ERR = S::SDOM_INDEX_SIZE_ERR,
+ DOMSTRING_SIZE_ERR = S::SDOM_DOMSTRING_SIZE_ERR,
+ HIERARCHY_REQUEST_ERR = S::SDOM_HIERARCHY_REQUEST_ERR,
+ WRONG_DOCUMENT_ERR = S::SDOM_WRONG_DOCUMENT_ERR,
+ INVALID_CHARACTER_ERR = S::SDOM_INVALID_CHARACTER_ERR,
+ NO_DATA_ALLOWED_ERR = S::SDOM_NO_DATA_ALLOWED_ERR,
+ NO_MODIFICATION_ALLOWED_ERR = S::SDOM_NO_MODIFICATION_ALLOWED_ERR,
+ NOT_FOUND_ERR = S::SDOM_NOT_FOUND_ERR,
+ NOT_SUPPORTED_ERR = S::SDOM_NOT_SUPPORTED_ERR,
+ INUSE_ATTRIBUTE_ERR = S::SDOM_INUSE_ATTRIBUTE_ERR,
+ INVALID_STATE_ERR = S::SDOM_INVALID_STATE_ERR,
+ SYNTAX_ERR = S::SDOM_SYNTAX_ERR,
+ INVALID_MODIFICATION_ERR = S::SDOM_INVALID_MODIFICATION_ERR,
+ NAMESPACE_ERR = S::SDOM_NAMESPACE_ERR,
+ INVALID_ACCESS_ERR = S::SDOM_INVALID_ACCESS_ERR,
+ /* not in spec below this point: */
+ INVALID_NODE_TYPE = S::SDOM_INVALID_NODE_TYPE,
+ QUERY_PARSE_ERR = S::SDOM_QUERY_PARSE_ERR,
+ QUERY_EXECUTION_ERR = S::SDOM_QUERY_EXECUTION_ERR,
+ NOT_OK = S::SDOM_NOT_OK
+ } CODES;
+
+ int getCode()
+ { return code; }
+ char* getMessage()
+ { return S::SDOM_getExceptionMessage(m_sit); }
+ void getDetails(int* code, char** message,
+ char** documentUri, int* fileLine)
+ { S::SDOM_getExceptionDetails(m_sit, code, message, documentUri, fileLine); }
+
+ short code;
+
+ protected:
+ DOMException(S::SDOM_Exception e, S::SablotSituation s)
+ {
+ code = e;
+ m_sit = s;
+ }
+
+ S::SablotSituation m_sit;
+
+ friend class INT::Base;
+ };
+
+ namespace INT
+ {
+ /**
+ * The base class that keeps references to sablo
+ */
+ class Base
+ {
+ public:
+ bool operator==(const Base& other) const
+ { return m_sit == other.m_sit; }
+ bool operator==(const void* null) const
+ { ASSERT(null == NULL); return m_sit == NULL; };
+ bool operator!=(const Base& other) const
+ { return !operator==(other); }
+ bool operator!=(const void* null) const
+ { return !operator==(null); }
+
+ protected:
+ Base(S::SablotSituation sit)
+ { m_sit = sit; }
+ Base(const Base& base)
+ { m_sit = base.m_sit; }
+ Base& operator=(const Base& other)
+ { m_sit = other.m_sit; return *this; }
+ Base& operator=(const void* null)
+ { ASSERT(null == NULL); m_sit = NULL; return *this; }
+ inline bool isValid() const
+ { return m_sit != NULL; }
+
+ inline S::SDOM_Exception _try_(S::SDOM_Exception e) const
+ throw(DOMException)
+ {
+ if(e != S::SDOM_OK)
+ throw DOMException(e, m_sit);
+ return e;
+ }
+
+#ifdef USE_UTF16
+ inline _16str _8to16(const _8str& d) const
+ throw(DOMException)
+ {
+ _16str s;
+ if(!transcode8to16(d, s))
+ throw DOMException(S::SDOM_INVALID_CHARACTER_ERR, m_sit);
+ return s;
+ }
+
+ inline _8str _16to8(const _16str& d) const
+ throw(DOMException)
+ {
+ _8str s;
+ if(!transcode16to8(d, s))
+ throw DOMException(S::SDOM_INVALID_CHARACTER_ERR, m_sit);
+ return s;
+ }
+#endif
+
+ S::SablotSituation m_sit;
+ };
+
+ class NamedNodeMap;
+ class NodeList;
+ class ChildNodeList;
+ class AttrNodeList;
+ class DOMNodeList;
+ class AttrNamedNodeMap;
+ }
+
+ class Element;
+ class Document;
+ class DOMImplementation;
+
+ typedef INT::Ref<INT::NamedNodeMap> NamedNodeMap;
+ typedef INT::Ref<INT::NodeList> NodeList;
+
+ /**
+ * Thin wrapper class for a DOM Node
+ */
+ class Node :
+ public INT::Base
+ {
+ public:
+ enum TYPES
+ {
+ ELEMENT_NODE = S::SDOM_ELEMENT_NODE,
+ ATTRIBUTE_NODE = S::SDOM_ATTRIBUTE_NODE,
+ TEXT_NODE = S::SDOM_TEXT_NODE,
+ CDATA_SECTION_NODE = S::SDOM_CDATA_SECTION_NODE,
+ ENTITY_REFERENCE_NODE = S::SDOM_ENTITY_REFERENCE_NODE,
+ ENTITY_NODE = S::SDOM_ENTITY_NODE,
+ PROCESSING_INSTRUCTION_NODE = S::SDOM_PROCESSING_INSTRUCTION_NODE,
+ COMMENT_NODE = S::SDOM_COMMENT_NODE,
+ DOCUMENT_NODE = S::SDOM_DOCUMENT_NODE,
+ DOCUMENT_TYPE_NODE = S::SDOM_DOCUMENT_TYPE_NODE,
+ DOCUMENT_FRAGMENT_NODE = S::SDOM_DOCUMENT_FRAGMENT_NODE,
+ NOTATION_NODE = S::SDOM_NOTATION_NODE
+ };
+
+ Node() : INT::Base(NULL)
+ {
+ m_node = NULL;
+ }
+
+ Node(const Node& node)
+ : INT::Base(node)
+ {
+ m_node = node.m_node;
+ }
+
+ Node& operator=(const Node& other)
+ {
+ Base::operator=(other);
+ m_node = other.m_node;
+ return *this;
+ }
+
+ Node& operator=(const void* null)
+ {
+ ASSERT(null == NULL);
+ Base::operator=(null);
+ m_node = NULL;
+ return *this;
+ }
+
+ bool operator==(const Node& other) const
+ {
+ return Base::operator==(other) &&
+ m_node == other.m_node;
+ }
+
+ bool operator==(const void* null) const
+ {
+ ASSERT(null == NULL);
+ return Base::operator==(null) ||
+ m_node == NULL;
+ }
+
+ bool operator!=(const Node& other) const
+ { return !operator==(other); }
+
+ bool operator!=(const void* null) const
+ { return !operator==(null); }
+
+ const Node* operator->() const
+ { return (const Node*)this; }
+ Node* operator->()
+ { return this; }
+
+ dom_str getNodeName() const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ S::SDOM_char* name;
+ _try_(S::SDOM_getNodeName(m_sit, m_node, &name));
+ return TO_D(INT::_8str(name));
+ }
+
+ data_str getNodeValue() const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ S::SDOM_char* value;
+ _try_(S::SDOM_getNodeValue(m_sit, m_node, &value));
+ return TO_V(INT::_8str(value));
+ }
+
+ void setNodeValue(const data_str& value)
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ _try_(S::SDOM_setNodeValue(m_sit, m_node, FROM_V(value).c_str()));
+ }
+
+ short getNodeType() const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ S::SDOM_NodeType type;
+ _try_(S::SDOM_getNodeType(m_sit, m_node, &type));
+ return (short)type;
+ }
+
+ Node getParentNode() const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ S::SDOM_Node parent;
+ _try_(S::SDOM_getParentNode(m_sit, m_node, &parent));
+ return Node(m_sit, parent);
+ }
+
+ NodeList getChildNodes() const
+ throw(DOMException);
+
+ Node getFirstChild() const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ S::SDOM_Node child;
+ _try_(S::SDOM_getFirstChild(m_sit, m_node, &child));
+ return Node(m_sit, child);
+ }
+
+ Node getLastChild() const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ S::SDOM_Node child;
+ _try_(S::SDOM_getLastChild(m_sit, m_node, &child));
+ return Node(m_sit, child);
+ }
+
+ Node getPreviousSibling() const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ S::SDOM_Node sib;
+ _try_(S::SDOM_getPreviousSibling(m_sit, m_node, &sib));
+ return Node(m_sit, sib);
+ }
+
+ Node getNextSibling() const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ S::SDOM_Node sib;
+ _try_(S::SDOM_getNextSibling(m_sit, m_node, &sib));
+ return Node(m_sit, sib);
+ }
+
+ NamedNodeMap getAttributes() const
+ throw(DOMException);
+
+ Document getOwnerDocument() const
+ throw(DOMException);
+
+ Node insertBefore(const Node& newChild, const Node& refChild)
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT_VALID_NODE(newChild);
+ ASSERT_VALID_NODE(refChild);
+ _try_(S::SDOM_insertBefore(m_sit, m_node, newChild.m_node, refChild.m_node));
+ return newChild;
+ }
+
+ Node replaceChild(const Node& newChild, const Node& refChild)
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT_VALID_NODE(newChild);
+ ASSERT_VALID_NODE(refChild);
+ _try_(S::SDOM_replaceChild(m_sit, m_node, newChild.m_node, refChild.m_node));
+ return newChild;
+ }
+
+ Node removeChild(const Node& oldChild)
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT_VALID_NODE(oldChild);
+ _try_(S::SDOM_removeChild(m_sit, m_node, oldChild.m_node));
+ return oldChild;
+ }
+
+ Node appendChild(const Node& newChild)
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT_VALID_NODE(newChild);
+ _try_(S::SDOM_appendChild(m_sit, m_node, newChild.m_node));
+ return newChild;
+ }
+
+ bool hasChildNodes() const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ int count = 0;
+ _try_(S::SDOM_getChildNodeCount(m_sit, m_node, &count));
+ return count != 0;
+ }
+
+ Node cloneNode(bool deep) const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ S::SDOM_Node node;
+ _try_(S::SDOM_cloneNode(m_sit, m_node, deep ? 1 : 0, &node));
+ return Node(m_sit, node);
+ }
+
+ void normalize()
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ _try_(S::SDOM_NOT_SUPPORTED_ERR);
+ }
+
+ bool isSupported(const dom_str& feature,
+ const dom_str& version) const
+ {
+ ASSERT_VALID();
+ return false;
+ }
+
+ dom_str getNamespaceURI() const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ S::SDOM_char* uri;
+ _try_(S::SDOM_getNodeNSUri(m_sit, m_node, &uri));
+ return TO_D(INT::_8str(uri));
+ }
+
+ dom_str getPrefix() const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ S::SDOM_char* prefix;
+ _try_(S::SDOM_getNodePrefix(m_sit, m_node, &prefix));
+ return TO_D(INT::_8str(prefix));
+ }
+
+ void setPrefix(const dom_str& prefix)
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ _try_(S::SDOM_NOT_SUPPORTED_ERR);
+ }
+
+ dom_str getLocalName() const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ S::SDOM_char* name;
+ _try_(S::SDOM_getNodeLocalName(m_sit, m_node, &name));
+ return TO_D(INT::_8str(name));
+ }
+
+ bool hasAttributes() const
+ throw (DOMException)
+ {
+ ASSERT_VALID();
+
+ if(getNodeType() != ELEMENT_NODE)
+ return false;
+
+ int count = 0;
+ _try_(S::SDOM_getAttributeNodeCount(m_sit, m_node, &count));
+ return count != 0;
+ }
+
+ void* setUserData(void* data)
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ void* old = S::SDOM_getNodeInstanceData(m_node);
+ S::SDOM_setNodeInstanceData(m_node, data);
+ return old;
+ }
+
+ void* getUserData() const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ return S::SDOM_getNodeInstanceData(m_node);
+ }
+
+ std::string serialize() const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ S::SDOM_Document doc;
+ _try_(S::SDOM_getOwnerDocument(m_sit, m_node, &doc));
+ S::SDOM_char* serialized;
+ _try_(S::SDOM_nodeToString(m_sit, doc, m_node, &serialized));
+ std::string ret(serialized);
+ S::SablotFree(serialized);
+ return ret;
+ }
+
+ bool isValid() const
+ {
+ return Base::isValid() &&
+ m_node != NULL;
+ }
+
+ protected:
+ Node(S::SablotSituation sit, S::SDOM_Node node) :
+ INT::Base(sit) { m_node = node; }
+
+ protected:
+ S::SDOM_Node m_node;
+
+ friend class Document;
+ friend class INT::ChildNodeList;
+ friend class INT::AttrNodeList;
+ friend class INT::DOMNodeList;
+ friend class INT::AttrNamedNodeMap;
+ };
+
+ class Attr :
+ public Node
+ {
+ public:
+ Attr() { }
+ Attr(const Attr& node) :
+ Node(node) { }
+
+ Attr& operator=(const Attr& other)
+ { Node::operator=(other); return *this; }
+ Attr& operator=(const void* null)
+ { Node::operator=(null); return *this; }
+ const Attr* operator->() const
+ { return (const Attr*)this; }
+ Attr* operator->()
+ { return this; }
+
+ dom_str getName() const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT_TYPE(ATTRIBUTE_NODE);
+ return getNodeName();
+ }
+
+ Element getOwnerElement() const
+ throw(DOMException);
+
+ bool getSpecified() const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT_TYPE(ATTRIBUTE_NODE);
+ return true;
+ }
+
+ data_str getValue() const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT_TYPE(ATTRIBUTE_NODE);
+ return getNodeValue();
+ }
+
+ void setValue(const data_str& value)
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT_TYPE(ATTRIBUTE_NODE);
+ setNodeValue(value);
+ }
+
+ protected:
+ Attr(S::SablotSituation sit, S::SDOM_Node node) :
+ Node(sit, node) { }
+
+ friend class Element;
+ friend class Document;
+ };
+
+ /**
+ * This wrapper class for an element
+ */
+ class Element :
+ public Node
+ {
+ public:
+ Element() { }
+ Element(const Element& node) :
+ Node(node) {}
+
+ Element& operator=(const Element& other)
+ { Node::operator=(other); return *this; }
+ Element& operator=(const void* null)
+ { Node::operator=(null); return *this; }
+ const Element* operator->() const
+ { return (const Element*)this; }
+ Element* operator->()
+ { return this; }
+
+ dom_str getTagName() const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT_TYPE(ELEMENT_NODE);
+ return getNodeName();
+ }
+
+ data_str getAttribute(const dom_str& name) const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT_TYPE(ELEMENT_NODE);
+ S::SDOM_char* value;
+ _try_(S::SDOM_getAttribute(m_sit, m_node, FROM_D(name).c_str(), &value));
+ return TO_V(INT::_8str(value));
+ }
+
+ void setAttribute(const dom_str& name, const data_str& value)
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT_TYPE(ELEMENT_NODE);
+ _try_(S::SDOM_setAttribute(m_sit, m_node, FROM_D(name).c_str(),
+ FROM_V(value).c_str()));
+ }
+
+ void removeAttribute(const dom_str& name)
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT_TYPE(ELEMENT_NODE);
+ _try_(S::SDOM_removeAttribute(m_sit, m_node, FROM_D(name).c_str()));
+ }
+
+ Attr getAttributeNode(const dom_str& name) const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT_TYPE(ELEMENT_NODE);
+ S::SDOM_Node attr;
+ _try_(S::SDOM_getAttributeNode(m_sit, m_node, FROM_D(name).c_str(), &attr));
+ return Attr(m_sit, attr);
+ }
+
+ Attr setAttributeNode(const Attr& attr)
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT_VALID_NODE(attr);
+ ASSERT_TYPE(ELEMENT_NODE);
+ S::SDOM_Node repl;
+ _try_(S::SDOM_setAttributeNode(m_sit, m_node, attr.m_node, &repl));
+ return Attr(m_sit, repl);
+ }
+
+ Attr removeAttributeNode(const Attr& attr)
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT_VALID_NODE(attr);
+ ASSERT_TYPE(ELEMENT_NODE);
+ S::SDOM_Node rem;
+ _try_(S::SDOM_removeAttributeNode(m_sit, m_node, attr.m_node, &rem));
+ return Attr(m_sit, rem);
+ }
+
+ NodeList getElementsByTagName(const dom_str& name) const
+ throw(DOMException);
+
+ data_str getAttributeNS(const dom_str& uri, const dom_str& name) const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT_TYPE(ELEMENT_NODE);
+ S::SDOM_char* value;
+ _try_(S::SDOM_getAttributeNS(m_sit, m_node, (char*)FROM_D(uri).c_str(),
+ (char*)FROM_D(name).c_str(), &value));
+ return TO_V(INT::_8str(value));
+ }
+
+ void setAttributeNS(const dom_str& uri, const dom_str& name,
+ const data_str& value)
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT_TYPE(ELEMENT_NODE);
+ _try_(S::SDOM_setAttributeNS(m_sit, m_node, FROM_D(uri).c_str(),
+ FROM_D(name).c_str(), FROM_V(value).c_str()));
+ }
+
+ void removeAttributeNS(const dom_str& uri, const dom_str& name)
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT_TYPE(ELEMENT_NODE);
+ DOM::Attr attr = getAttributeNodeNS(uri, name);
+ if(attr != NULL)
+ removeAttributeNode(attr);
+ }
+
+ Attr getAttributeNodeNS(const dom_str& uri, const dom_str& name) const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT_TYPE(ELEMENT_NODE);
+ S::SDOM_Node attr;
+ _try_(S::SDOM_getAttributeNodeNS(m_sit, m_node, (char*)FROM_D(uri).c_str(),
+ (char*)FROM_D(name).c_str(), &attr));
+ return Attr(m_sit, attr);
+ }
+
+ Attr setAttributeNodeNS(const Attr& attr)
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT_VALID_NODE(attr);
+ ASSERT_TYPE(ELEMENT_NODE);
+ S::SDOM_Node repl;
+ _try_(S::SDOM_setAttributeNodeNS(m_sit, m_node, attr.m_node, &repl));
+ return Attr(m_sit, repl);
+ }
+
+ NodeList getElementsByTagNameNS(const dom_str& uri,
+ const dom_str& name) const
+ throw(DOMException);
+
+ bool hasAttribute(const dom_str& name) const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT_TYPE(ELEMENT_NODE);
+ return getAttributeNode(name) != NULL;
+ }
+
+ bool hasAttributeNS(const dom_str& uri, const dom_str& name) const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT_TYPE(ELEMENT_NODE);
+ return getAttributeNodeNS(uri, name) != NULL;
+ }
+
+ protected:
+ Element(S::SablotSituation sit, S::SDOM_Node node) :
+ Node(sit, node) { }
+
+ friend class Attr;
+ friend class Document;
+ };
+
+
+ class CharacterData :
+ public Node
+ {
+ public:
+ CharacterData() { }
+ CharacterData(const Node& node) :
+ Node(node) { }
+
+ CharacterData& operator=(const CharacterData& other)
+ { Node::operator=(other); return *this; }
+ CharacterData& operator=(const void* null)
+ { Node::operator=(null); return *this; }
+ const CharacterData* operator->() const
+ { return (const CharacterData*)this; }
+ CharacterData* operator->()
+ { return this; }
+
+ void appendData(const data_str& data)
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT(getNodeType() == TEXT_NODE ||
+ getNodeType() == CDATA_SECTION_NODE ||
+ getNodeType() == COMMENT_NODE);
+ data_str val = getNodeValue();
+ val.append(data);
+ setNodeValue(val);
+ }
+
+ void deleteData(int offset, int count)
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT(getNodeType() == TEXT_NODE ||
+ getNodeType() == CDATA_SECTION_NODE ||
+ getNodeType() == COMMENT_NODE);
+ data_str val = getNodeValue();
+ val.erase(offset, count);
+ setNodeValue(val);
+ }
+
+ data_str getData() const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT(getNodeType() == TEXT_NODE ||
+ getNodeType() == CDATA_SECTION_NODE ||
+ getNodeType() == COMMENT_NODE);
+ return getNodeValue();
+ }
+
+ int getLength() const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT(getNodeType() == TEXT_NODE ||
+ getNodeType() == CDATA_SECTION_NODE ||
+ getNodeType() == COMMENT_NODE);
+ return getNodeValue().size();
+ }
+
+ void insertData(int offset, const data_str& data)
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT(getNodeType() == TEXT_NODE ||
+ getNodeType() == CDATA_SECTION_NODE ||
+ getNodeType() == COMMENT_NODE);
+ data_str val = getNodeValue();
+ val.insert(offset, data);
+ setNodeValue(val);
+ }
+
+ void replaceData(int offset, int count, const data_str& arg)
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT(getNodeType() == TEXT_NODE ||
+ getNodeType() == CDATA_SECTION_NODE ||
+ getNodeType() == COMMENT_NODE);
+ data_str val = getNodeValue();
+ val.erase(offset, count);
+ val.insert(offset, arg);
+ setNodeValue(val);
+ }
+
+ void setData(const data_str& data)
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT(getNodeType() == TEXT_NODE ||
+ getNodeType() == CDATA_SECTION_NODE ||
+ getNodeType() == COMMENT_NODE);
+ setNodeValue(data);
+ }
+
+ data_str substringData(int offset, int count) const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT(getNodeType() == TEXT_NODE ||
+ getNodeType() == CDATA_SECTION_NODE ||
+ getNodeType() == COMMENT_NODE);
+ data_str val = getNodeValue();
+ return val.substr(offset, count);
+ }
+
+ protected:
+ CharacterData(S::SablotSituation sit, S::SDOM_Node node) :
+ Node(sit, node) { }
+ };
+
+ class Text :
+ public CharacterData
+ {
+ public:
+ Text() { }
+ Text(const Node& node) :
+ CharacterData(node) { }
+
+ Text& operator=(const Text& other)
+ { CharacterData::operator=(other); return *this; }
+ Text& operator=(const void* null)
+ { CharacterData::operator=(null); return *this; }
+ const Text* operator->() const
+ { return (const Text*)this; }
+ Text* operator->()
+ { return this; }
+
+ Text splitText(int offset)
+ throw(DOMException);
+
+ protected:
+ Text(S::SablotSituation sit, S::SDOM_Node node) :
+ CharacterData(sit, node) { }
+
+ friend class Document;
+ };
+
+ class CDATASection :
+ public Text
+ {
+ public:
+ CDATASection() { }
+ CDATASection(const CDATASection& node) :
+ Text(node) { }
+
+ CDATASection& operator=(const CDATASection& other)
+ { Text::operator=(other); return *this; }
+ CDATASection& operator=(void* null)
+ { Text::operator=(null); return *this; }
+ const CDATASection* operator->() const
+ { return (const CDATASection*)this; }
+ CDATASection* operator->()
+ { return this; }
+
+ protected:
+ CDATASection(S::SablotSituation sit, S::SDOM_Node node) :
+ Text(sit, node) { }
+
+ friend class Document;
+ };
+
+ class Comment :
+ public CharacterData
+ {
+ public:
+ Comment() { }
+ Comment(const Comment& node) :
+ CharacterData(node) { }
+
+ Comment& operator=(const Comment& other)
+ { CharacterData::operator=(other); return *this; }
+ Comment& operator=(void* null)
+ { CharacterData::operator=(null); return *this; }
+ const Comment* operator->() const
+ { return (const Comment*)this; }
+ Comment* operator->()
+ { return this; }
+
+ protected:
+ Comment(S::SablotSituation sit, S::SDOM_Node node) :
+ CharacterData(sit, node) { }
+
+ friend class Document;
+ };
+
+ class ProcessingInstruction :
+ public Node
+ {
+ public:
+ ProcessingInstruction() { }
+ ProcessingInstruction(const ProcessingInstruction& node) :
+ Node(node) { }
+
+ ProcessingInstruction& operator=(const ProcessingInstruction& other)
+ { Node::operator=(other); return *this; }
+ ProcessingInstruction& operator=(void* null)
+ { Node::operator=(null); return *this; }
+ const ProcessingInstruction* operator->() const
+ { return (const ProcessingInstruction*)this; }
+ ProcessingInstruction* operator->()
+ { return this; }
+
+ data_str getData() const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT_TYPE(PROCESSING_INSTRUCTION_NODE);
+ return getNodeValue();
+ }
+
+ dom_str getTarget() const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT_TYPE(PROCESSING_INSTRUCTION_NODE);
+ _try_(S::SDOM_NOT_SUPPORTED_ERR);
+ return dom_str();
+ }
+
+ void setData(const data_str& data)
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT_TYPE(PROCESSING_INSTRUCTION_NODE);
+ setNodeValue(data);
+ }
+
+ protected:
+ ProcessingInstruction(S::SablotSituation sit, S::SDOM_Node node) :
+ Node(sit, node) { }
+
+ friend class Document;
+ };
+
+ class DocumentFragment :
+ public Node
+ {
+ public:
+ DocumentFragment() { }
+ DocumentFragment(const DocumentFragment& node) :
+ Node(node) { }
+
+ DocumentFragment& operator=(const DocumentFragment& other)
+ { Node::operator=(other); return *this; }
+ DocumentFragment& operator=(void* null)
+ { Node::operator=(null); return *this; }
+ const DocumentFragment* operator->() const
+ { return (const DocumentFragment*)this; }
+ DocumentFragment* operator->()
+ { return this; }
+ };
+
+ class Entity :
+ public Node
+ {
+ public:
+ Entity() { }
+ Entity(const Entity& node) :
+ Node(node) { }
+
+ Entity& operator=(const Entity& other)
+ { Node::operator=(other); return *this; }
+ Entity& operator=(void* null)
+ { Node::operator=(null); return *this; }
+ const Entity* operator->() const
+ { return (const Entity*)this; }
+ Entity* operator->()
+ { return this; }
+
+ dom_str getNotationName() const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT_TYPE(ENTITY_NODE);
+ _try_(S::SDOM_NOT_SUPPORTED_ERR);
+ return dom_str();
+ }
+
+ dom_str getPublicId() const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT_TYPE(ENTITY_NODE);
+ _try_(S::SDOM_NOT_SUPPORTED_ERR);
+ return dom_str();
+ }
+
+ dom_str getSystemId() const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT_TYPE(ENTITY_NODE);
+ _try_(S::SDOM_NOT_SUPPORTED_ERR);
+ return dom_str();
+ }
+ };
+
+ class EntityReference :
+ public Node
+ {
+ public:
+ EntityReference() { }
+ EntityReference(const EntityReference& node) :
+ Node(node) { }
+
+ EntityReference& operator=(const EntityReference& other)
+ { Node::operator=(other); return *this; }
+ EntityReference& operator=(void* null)
+ { Node::operator=(null); return *this; }
+ const EntityReference* operator->() const
+ { return (const EntityReference*)this; }
+ EntityReference* operator->()
+ { return this; }
+ };
+
+ class Notation :
+ public Node
+ {
+ public:
+ Notation() { }
+ Notation(const Notation& node) :
+ Node(node) { }
+
+ Notation& operator=(const Notation& other)
+ { Node::operator=(other); return *this; }
+ Notation& operator=(void* null)
+ { Node::operator=(null); return *this; }
+ const Notation* operator->() const
+ { return (const Notation*)this; }
+ Notation* operator->()
+ { return this; }
+
+ dom_str getPublicId() const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT_TYPE(NOTATION_NODE);
+ _try_(S::SDOM_NOT_SUPPORTED_ERR);
+ return dom_str();
+ }
+
+ dom_str getSystemId() const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT_TYPE(NOTATION_NODE);
+ _try_(S::SDOM_NOT_SUPPORTED_ERR);
+ return dom_str();
+ }
+ };
+
+ class DocumentType :
+ public Node
+ {
+ public:
+ DocumentType() { }
+ DocumentType(const DocumentType& node) :
+ Node(node) { }
+
+ DocumentType& operator=(const DocumentType& other)
+ { Node::operator=(other); return *this; }
+ DocumentType& operator=(void* null)
+ { Node::operator=(null); return *this; }
+ const DocumentType* operator->() const
+ { return (const DocumentType*)this; }
+ DocumentType* operator->()
+ { return this; }
+
+ NamedNodeMap getEntities() const
+ throw(DOMException);
+
+ dom_str getInternalSubset() const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ _try_(S::SDOM_NOT_SUPPORTED_ERR);
+ return dom_str();
+ }
+
+ dom_str getName() const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ _try_(S::SDOM_NOT_SUPPORTED_ERR);
+ return dom_str();
+ }
+
+ NamedNodeMap getNotations() const
+ throw(DOMException);
+ };
+
+
+ class Document :
+ public Node
+ {
+ public:
+ Document() { }
+ Document(const Document& doc) :
+ Node(doc) { }
+ Document(S::SablotSituation sit, S::SDOM_Document doc) :
+ Node(sit, NULL) { m_node = doc; }
+
+ Document& operator=(const Document& other)
+ { Node::operator=(other); return *this; }
+ Document& operator=(void* null)
+ { Node::operator=(null); return *this; }
+ const Document* operator->() const
+ { return (const Document*)this; }
+ Document* operator->()
+ { return this; }
+
+ DocumentType getDocType() const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT_TYPE(DOCUMENT_NODE);
+ return DocumentType();
+ }
+
+ DOMImplementation getImplementation() const
+ throw(DOMException);
+
+ Element getDocumentElement() const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT_TYPE(DOCUMENT_NODE);
+ S::SDOM_Node child;
+ _try_(S::SDOM_getFirstChild(m_sit, m_node, &child));
+ return Element(m_sit, child);
+ }
+
+ Element createElement(const dom_str& tag) const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT_TYPE(DOCUMENT_NODE);
+ S::SDOM_Node el;
+ _try_(S::SDOM_createElement(m_sit, (S::SDOM_Document)m_node,
+ &el, FROM_D(tag).c_str()));
+ return Element(m_sit, el);
+ }
+
+ DocumentFragment createDocumentFragment() const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT_TYPE(DOCUMENT_NODE);
+ _try_(S::SDOM_NOT_SUPPORTED_ERR);
+ return DocumentFragment();
+ }
+
+ Text createTextNode(const data_str& data) const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT_TYPE(DOCUMENT_NODE);
+ S::SDOM_Node text;
+ _try_(S::SDOM_createTextNode(m_sit, (S::SDOM_Document)m_node,
+ &text, FROM_V(data).c_str()));
+ return Text(m_sit, text);
+ }
+
+ Comment createComment(const data_str& data) const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT_TYPE(DOCUMENT_NODE);
+ S::SDOM_Node comment;
+ _try_(S::SDOM_createComment(m_sit, (S::SDOM_Document)m_node,
+ &comment, FROM_V(data).c_str()));
+ return Comment(m_sit, comment);
+ }
+
+ CDATASection createCDATASection(const data_str& data) const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT_TYPE(DOCUMENT_NODE);
+ S::SDOM_Node cdata;
+ _try_(S::SDOM_createCDATASection(m_sit, (S::SDOM_Document)m_node,
+ &cdata, FROM_V(data).c_str()));
+ return CDATASection(m_sit, cdata);
+ }
+
+ ProcessingInstruction createProcessingInstruction(const dom_str& targ,
+ const data_str& data) const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT_TYPE(DOCUMENT_NODE);
+ S::SDOM_Node pi;
+ _try_(S::SDOM_createProcessingInstruction(m_sit,
+ (S::SDOM_Document)m_node,
+ &pi, FROM_D(targ).c_str(),
+ FROM_V(data).c_str()));
+ return ProcessingInstruction(m_sit, pi);
+ }
+
+ Attr createAttribute(const dom_str& name) const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT_TYPE(DOCUMENT_NODE);
+ S::SDOM_Node attr;
+ _try_(S::SDOM_createAttribute(m_sit, (S::SDOM_Document)m_node,
+ &attr, FROM_D(name).c_str()));
+ return Attr(m_sit, attr);
+ }
+
+ EntityReference createEntityReference()
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT_TYPE(DOCUMENT_NODE);
+ _try_(S::SDOM_NOT_SUPPORTED_ERR);
+ return EntityReference();
+ }
+
+ NodeList getElementsByTagName(const dom_str& name) const
+ throw(DOMException);
+
+ Node importNode(const Node& import, bool deep) const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT_TYPE(DOCUMENT_NODE);
+ ASSERT_VALID_NODE(import);
+ S::SDOM_Node imported;
+ _try_(S::SDOM_cloneForeignNode(m_sit, (S::SDOM_Document)m_node,
+ import.m_node, deep ? 1 : 0, &imported));
+ return Node(m_sit, imported);
+ }
+
+ Element createElementNS(const dom_str& uri, const dom_str& tag) const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT_TYPE(DOCUMENT_NODE);
+ S::SDOM_Node el;
+ _try_(S::SDOM_createElementNS(m_sit, (S::SDOM_Document)m_node,
+ &el, FROM_D(uri).c_str(), FROM_D(tag).c_str()));
+ return Element(m_sit, el);
+ }
+
+ Attr createAttributeNS(const dom_str& uri, const dom_str& name) const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT_TYPE(DOCUMENT_NODE);
+ S::SDOM_Node attr;
+ _try_(S::SDOM_createAttributeNS(m_sit, (S::SDOM_Document)m_node,
+ &attr, FROM_D(uri).c_str(), FROM_D(name).c_str()));
+ return Attr(m_sit, attr);
+ }
+
+ NodeList getElementsByTagNameNS(const dom_str& uri,
+ const dom_str& name) const
+ throw(DOMException);
+
+ Element getElementById(const dom_str& id) const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT_TYPE(DOCUMENT_NODE);
+ dom_str query = "//*[id('" + id + "')]";
+ S::SDOM_NodeList result;
+ _try_(S::SDOM_xql(m_sit, FROM_D(query).c_str(), m_node, &result));
+
+ int length;
+ _try_(S::SDOM_getNodeListLength(m_sit, result, &length));
+
+ Element ret;
+ if(length != 1)
+ {
+ ret = Element();
+ }
+ else
+ {
+ S::SDOM_Node el;
+ _try_(S::SDOM_getNodeListItem(m_sit, result, 0, &el));
+ ret = Element(m_sit, el);
+ }
+
+ S::SDOM_disposeNodeList(m_sit, result);
+ return ret;
+ }
+
+ std::string serialize() const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT_TYPE(DOCUMENT_NODE);
+ S::SDOM_char* serialized;
+ _try_(S::SDOM_docToString(m_sit, (S::SDOM_Document)m_node, &serialized));
+ std::string ret(serialized);
+ S::SablotFree(serialized);
+ return ret;
+ }
+
+ void release()
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT_TYPE(DOCUMENT_NODE);
+ S::SDOM_tmpListDump((S::SDOM_Document)m_node, 0);
+ if(S::SablotDestroyDocument(m_sit, (S::SDOM_Document)m_node))
+ _try_(S::SDOM_NOT_OK);
+ *this = NULL;
+ }
+
+ protected:
+
+ friend class Node;
+ friend class DOMImplementation;
+ };
+
+
+ class DOMImplementation :
+ public INT::Base
+ {
+ public:
+ DOMImplementation()
+ throw(DOMException) : INT::Base(NULL)
+ {
+ if(S::SablotCreateSituation(&m_sit))
+ _try_(S::SDOM_NOT_OK);
+ }
+ DOMImplementation(S::SablotSituation sit)
+ throw(DOMException) : INT::Base(sit) { }
+ DOMImplementation(const DOMImplementation& impl) :
+ INT::Base(impl) { }
+
+ DOMImplementation& operator=(const DOMImplementation& other)
+ { Base::operator=(other); return *this; }
+ DOMImplementation& operator=(void* null)
+ { Base::operator=(null); return *this; }
+ const DOMImplementation* operator->() const
+ { return (const DOMImplementation*)this; }
+ DOMImplementation* operator->()
+ { return this; }
+
+ Document createDocument(const dom_str& uri, const dom_str& qname,
+ const DocumentType& type) const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ S::SDOM_Document doc;
+ if(S::SablotCreateDocument(m_sit, &doc))
+ _try_(S::SDOM_NOT_OK);
+
+ Document document(m_sit, doc);
+
+ if(!qname.empty())
+ {
+ if(!uri.empty())
+ document.appendChild(document.createElementNS(uri, qname));
+ else
+ document.appendChild(document.createElement(qname));
+ }
+
+ return document;
+ }
+
+ DocumentType createDocumentType(const dom_str& qname,
+ const dom_str& publicId,
+ const dom_str& systemId) const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ _try_(S::SDOM_NOT_SUPPORTED_ERR);
+ return DocumentType();
+ }
+
+ bool hasFeature(const dom_str& feature, const dom_str& version) const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ return false;
+ }
+
+ void release()
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ if(S::SablotDestroySituation(m_sit))
+ _try_(S::SDOM_NOT_OK);
+ }
+ };
+
+ namespace INT
+ {
+ class NodeList :
+ public INT::Base,
+ public INT::Inst
+ {
+ public:
+#ifdef COMPARE_REF
+ virtual bool operator==(const NodeList& other) const
+ { return Base::operator==(other); }
+#endif
+ virtual int getLength() const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ _try_(S::SDOM_NOT_SUPPORTED_ERR);
+ return 0;
+ }
+
+ virtual Node item(int index) const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ _try_(S::SDOM_NOT_SUPPORTED_ERR);
+ return Node();
+ }
+
+ protected:
+ NodeList(S::SablotSituation sit) :
+ INT::Base(sit) { }
+
+ virtual bool isValid() const
+ {
+ return false;
+ }
+
+ private:
+ NodeList(const NodeList& list) : INT::Base(list) { }
+ };
+
+ class ChildNodeList :
+ public NodeList
+ {
+ public:
+#ifdef COMPARE_REF
+ virtual bool operator==(const NodeList& other) const
+ { return m_el == ((ChildNodeList)other).m_el; }
+#endif
+ virtual int getLength() const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ int length;
+ _try_(S::SDOM_getChildNodeCount(m_sit, m_el, &length));
+ return length;
+ }
+
+ virtual Node item(int index) const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ S::SDOM_Node attr;
+ _try_(S::SDOM_getChildNodeIndex(m_sit, m_el, index, &attr));
+ return Node(m_sit, attr);
+ }
+
+ protected:
+ ChildNodeList(S::SablotSituation sit, S::SDOM_Node node) :
+ NodeList(sit) { m_el = node; }
+
+ virtual bool isValid() const
+ {
+ return m_el != NULL;
+ }
+
+ protected:
+ S::SDOM_Node m_el;
+
+ friend class Node;
+ };
+
+ class AttrNodeList :
+ public NodeList
+ {
+ public:
+#ifdef COMPARE_REF
+ virtual bool operator==(const NodeList& other) const
+ { return m_el == ((AttrNodeList)other).m_el; }
+#endif
+ virtual int getLength() const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ int length;
+ _try_(S::SDOM_getAttributeNodeCount(m_sit, m_el, &length));
+ return length;
+ }
+
+ virtual Node item(int index) const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ S::SDOM_Node attr;
+ _try_(S::SDOM_getAttributeNodeIndex(m_sit, m_el, index, &attr));
+ return Node(m_sit, attr);
+ }
+
+ protected:
+ AttrNodeList(S::SablotSituation sit, S::SDOM_Node el) :
+ NodeList(sit) { m_el = el; }
+
+ virtual bool isValid() const
+ {
+ return m_el != NULL;
+ }
+
+ protected:
+ S::SDOM_Node m_el;
+ };
+
+
+ class DOMNodeList :
+ public NodeList
+ {
+ public:
+#ifdef COMPARE_REF
+ virtual bool operator==(const NodeList& other) const
+ { return m_list == ((DOMNodeList&)other).m_list; }
+#endif
+ virtual int getLength() const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ int length;
+ _try_(S::SDOM_getNodeListLength(m_sit, m_list, &length));
+ return length;
+ }
+
+ virtual Node item(int index) const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ S::SDOM_Node it;
+ _try_(S::SDOM_getNodeListItem(m_sit, m_list, index, &it));
+ return Node(m_sit, it);
+ }
+
+ protected:
+ DOMNodeList(S::SablotSituation sit, S::SDOM_NodeList list) :
+ NodeList(sit)
+ {
+ m_list = list;
+ }
+
+ ~DOMNodeList()
+ {
+ if(m_list != NULL)
+ S::SDOM_disposeNodeList(m_sit, m_list);
+ m_list = NULL;
+ }
+
+ virtual bool isValid() const
+ {
+ return m_list != NULL;
+ }
+
+ protected:
+ S::SDOM_NodeList m_list;
+
+ friend class Element;
+ friend class Document;
+ };
+
+
+ class NamedNodeMap :
+ public INT::Base,
+ public INT::Inst
+ {
+ public:
+#ifdef COMPARE_REF
+ virtual bool operator==(const NamedNodeMap& other) const
+ { Base::operator==(other); }
+#endif
+ virtual int getLength() const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ _try_(S::SDOM_NOT_SUPPORTED_ERR);
+ return 0;
+ }
+
+ virtual Node getNamedItem(const dom_str& name) const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ _try_(S::SDOM_NOT_SUPPORTED_ERR);
+ return Node();
+ }
+
+ virtual Node getNamedItemNS(const dom_str& uri, const dom_str& name) const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ _try_(S::SDOM_NOT_SUPPORTED_ERR);
+ return Node();
+ }
+
+ virtual Node item(int index) const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ _try_(S::SDOM_NOT_SUPPORTED_ERR);
+ return Node();
+ }
+
+ virtual Node removeNamedItem(const dom_str& name)
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ _try_(S::SDOM_NOT_SUPPORTED_ERR);
+ return Node();
+ }
+
+ virtual Node removeNamedItemNS(const dom_str& uri, const dom_str& name)
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ _try_(S::SDOM_NOT_SUPPORTED_ERR);
+ return Node();
+ }
+
+ virtual Node setNamedItem(const Node& arg)
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT_VALID_NODE(arg);
+ _try_(S::SDOM_NOT_SUPPORTED_ERR);
+ return Node();
+ }
+
+ virtual Node setNamedItemNS(const Node& arg)
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT_VALID_NODE(arg);
+ _try_(S::SDOM_NOT_SUPPORTED_ERR);
+ return Node();
+ }
+
+ protected:
+ NamedNodeMap(S::SablotSituation sit) :
+ INT::Base(sit) { }
+
+ virtual bool isValid() const
+ {
+ return false;
+ }
+
+ private:
+ NamedNodeMap(const NamedNodeMap& map) : INT::Base(map) { }
+ };
+
+ class AttrNamedNodeMap :
+ public NamedNodeMap
+ {
+ public:
+#ifdef COMPARE_REF
+ virtual bool operator==(const NamedNodeMap& other) const
+ { return m_el == ((AttrNamedNodeMap)other).m_el; }
+#endif
+ virtual int getLength() const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT_VALID_NODE(m_el);
+ int length;
+ _try_(S::SDOM_getAttributeNodeCount(m_sit, m_el.m_node, &length));
+ return length;
+ }
+
+ virtual Node getNamedItem(const dom_str& name) const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT_VALID_NODE(m_el);
+ return m_el.getAttributeNode(name);
+ }
+
+ virtual Node getNamedItemNS(const dom_str& uri, const dom_str& name) const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT_VALID_NODE(m_el);
+ return m_el.getAttributeNodeNS(uri, name);
+ }
+
+ virtual Node item(int index) const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ S::SDOM_Node attr;
+ _try_(S::SDOM_getAttributeNodeIndex(m_sit, m_el.m_node, index, &attr));
+ return Node(m_sit, attr);
+ }
+
+ virtual Node removeNamedItem(const dom_str& name)
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT_VALID_NODE(m_el);
+ Node node = getNamedItem(name);
+ if(node != NULL)
+ m_el.removeAttributeNode((Attr&)node);
+ return node;
+ }
+
+ virtual Node removeNamedItemNS(const dom_str& uri, const dom_str& name)
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT_VALID_NODE(m_el);
+ Node node = getNamedItemNS(uri, name);
+ if(node != NULL)
+ m_el.removeAttributeNode((Attr&)node);
+ return node;
+ }
+
+ virtual Node setNamedItem(const Node& arg)
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT_VALID_NODE(m_el);
+ return m_el.setAttributeNode((Attr&)arg);
+ }
+
+ virtual Node setNamedItemNS(const Node& arg)
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT_VALID_NODE(m_el);
+ return m_el.setAttributeNodeNS((Attr&)arg);
+ }
+
+ protected:
+ AttrNamedNodeMap(S::SablotSituation sit, const Node& el) :
+ NamedNodeMap(sit)
+ {
+ ASSERT_VALID_NODE(el);
+ ASSERT_NODE_TYPE(el, Node::ELEMENT_NODE);
+ m_el = (Element&)el;
+ }
+
+ virtual bool isValid() const
+ {
+ return m_el.isValid();
+ }
+
+
+ protected:
+ Element m_el;
+
+ friend class Node;
+ };
+ };
+
+
+ inline NodeList Node::getChildNodes() const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ return NodeList(new INT::ChildNodeList(m_sit, m_node));
+ }
+
+ inline NamedNodeMap Node::getAttributes() const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ if(getNodeType() != ELEMENT_NODE)
+ return NamedNodeMap(NULL);
+
+ return NamedNodeMap(new INT::AttrNamedNodeMap(m_sit, *this));
+ }
+
+ inline Document Node::getOwnerDocument() const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ S::SDOM_Document doc;
+ _try_(S::SDOM_getOwnerDocument(m_sit, m_node, &doc));
+ return Document(m_sit, doc);
+ }
+
+ inline Element Attr::getOwnerElement() const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT_TYPE(ATTRIBUTE_NODE);
+ S::SDOM_Node el;
+ _try_(S::SDOM_getAttributeElement(m_sit, m_node, &el));
+ return Element(m_sit, el);
+ }
+
+ inline NodeList Element::getElementsByTagName(const dom_str& name) const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT_TYPE(ELEMENT_NODE);
+ dom_str query = "descendant::" + name;
+ S::SDOM_NodeList result;
+ _try_(S::SDOM_xql(m_sit, FROM_D(query).c_str(), m_node, &result));
+ return NodeList(new INT::DOMNodeList(m_sit, result));
+ }
+
+ inline NodeList Element::getElementsByTagNameNS(const dom_str& uri,
+ const dom_str& name) const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT_TYPE(ELEMENT_NODE);
+ dom_str query = "descendant::*[namespace-uri()='" + uri + "'";
+ if(name != "*")
+ query += " and local-name()='" + name + "']";
+ S::SDOM_NodeList result;
+ _try_(S::SDOM_xql(m_sit, FROM_D(query).c_str(), m_node, &result));
+ return NodeList(new INT::DOMNodeList(m_sit, result));
+ }
+
+ inline NodeList Document::getElementsByTagName(const dom_str& name) const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT_TYPE(DOCUMENT_NODE);
+ dom_str query = "descendant::" + name;
+ S::SDOM_NodeList result;
+ _try_(S::SDOM_xql(m_sit, FROM_D(query).c_str(), m_node, &result));
+ return NodeList(new INT::DOMNodeList(m_sit, result));
+ }
+
+ inline NodeList Document::getElementsByTagNameNS(const dom_str& uri,
+ const dom_str& name) const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT_TYPE(DOCUMENT_NODE);
+ dom_str query = "descendant::*[namespace-uri()='" + uri + "'";
+ if(name != "*")
+ query += " and local-name()='" + name + "']";
+ S::SDOM_NodeList result;
+ _try_(S::SDOM_xql(m_sit, FROM_D(query).c_str(), m_node, &result));
+ return NodeList(new INT::DOMNodeList(m_sit, result));
+ }
+
+ inline DOMImplementation Document::getImplementation() const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT_TYPE(DOCUMENT_NODE);
+ return DOMImplementation(m_sit);
+ }
+
+ inline Text Text::splitText(int offset)
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT(getNodeType() == TEXT_NODE ||
+ getNodeType() == CDATA_SECTION_NODE);
+
+ data_str val = getNodeValue();
+ setNodeValue(val.substr(0, offset));
+
+ Document doc = getOwnerDocument();
+ ASSERT(doc != NULL);
+
+ Text split(m_sit, NULL);
+ val = val.substr(0, offset);
+
+ switch(getNodeType())
+ {
+ case TEXT_NODE:
+ split = doc.createTextNode(val);
+ break;
+
+ case CDATA_SECTION_NODE:
+ split = doc.createCDATASection(val);
+ break;
+
+ default:
+ ASSERT(false);
+ };
+
+ Node parent = getParentNode();
+ if(parent != NULL)
+ {
+ Node next = getNextSibling();
+ if(next != NULL)
+ parent.insertBefore(split, next);
+ else
+ parent.appendChild(split);
+ }
+
+ return split;
+ }
+
+ inline NamedNodeMap DocumentType::getEntities() const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ _try_(S::SDOM_NOT_SUPPORTED_ERR);
+ return NamedNodeMap(NULL);
+ }
+
+ inline NamedNodeMap DocumentType::getNotations() const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ _try_(S::SDOM_NOT_SUPPORTED_ERR);
+ return NamedNodeMap(NULL);
+ }
+
+}; // namespace DOM
+
+
+#endif //__SABLO_H__ \ No newline at end of file