summaryrefslogtreecommitdiff
path: root/src/domcxx.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/domcxx.h')
-rw-r--r--src/domcxx.h1659
1 files changed, 1659 insertions, 0 deletions
diff --git a/src/domcxx.h b/src/domcxx.h
new file mode 100644
index 0000000..bd96078
--- /dev/null
+++ b/src/domcxx.h
@@ -0,0 +1,1659 @@
+/*
+ * Copyright (c) 2004, Nate Nielsen
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer.
+ * * Redistributions in binary form must reproduce the
+ * above copyright notice, this list of conditions and
+ * the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ * * The names of contributors to this software may not be
+ * used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ *
+ * CONTRIBUTORS
+ * Nate Nielsen <nielsen@memberwebs.com>
+ *
+ */
+
+// TODO: UPDATE these comments once done
+// DOMC C++ WRAPPER
+//
+// Everything is in the DOM namespace.
+//
+
+#ifndef __DOMCXX_H__
+#define __DOMCXX_H__
+
+#include <stdio.h>
+#include <exception>
+#include <string>
+
+namespace DOM
+{
+ extern "C"
+ {
+ #define this _this
+ #include <domc.h>
+ #include <dom.h>
+ #undef this
+ }
+
+#ifdef ASSERT
+ #define DOM_ASSERT ASSERT
+#else
+ #include <assert.h>
+ #define ASSERT assert
+#endif
+
+ typedef std::basic_string<char> data_str;
+ typedef std::basic_string<char> dom_str;
+
+ #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)
+ #define RESET_ERR() \
+ DOM_Exception = 0;
+ #define CHECK_ERR() \
+ if(DOM_Exception != 0) throw DOMException(DOM_Exception);
+ #define NO_REFCNT 0xFFFFFFFF
+ #define FROM_D(s) \
+ ((DOM_String*)((s).c_str()))
+ #define FROM_V(s) \
+ ((DOM_String*)((s).c_str()))
+
+ class DOMException
+ {
+ public:
+ DOMException(int e)
+ {
+ ASSERT(e != 0);
+ code = (short)e;
+ }
+
+ typedef enum
+ {
+ INDEX_SIZE_ERR = 1,
+ DOMSTRING_SIZE_ERR = 2,
+ HIERARCHY_REQUEST_ERR = 3,
+ WRONG_DOCUMENT_ERR = 4,
+ INVALID_CHARACTER_ERR = 5,
+ NO_DATA_ALLOWED_ERR = 6,
+ NO_MODIFICATION_ALLOWED_ERR = 7,
+ NOT_FOUND_ERR = 8,
+ NOT_SUPPORTED_ERR = 9,
+ INUSE_ATTRIBUTE_ERR = 10
+ } CODES;
+
+ int getCode()
+ { return code; }
+ char* getMessage()
+ { /* TODO: Get from the domc library */ return NULL; }
+ void getDetails(int* cde, char** message,
+ char** documentUri, int* fileLine)
+ {
+ *cde = code;
+ *message = NULL; // TODO: Get from domc library
+ *documentUri = NULL;
+ *fileLine = 0;
+ }
+
+ short code;
+ };
+
+ class NodeList;
+ class NamedNodeMap;
+ class Element;
+ class Document;
+ class DOMImplementation;
+
+ /* We only perform ref counting on nodes outside the tree */
+ #define INC_NODE_REF(n) \
+ if((n).m_node != NULL && ((n).m_node)->parentNode == NULL) incref((n).m_node)
+ #define DEC_NODE_REF(n) \
+ if((n).m_node != NULL && ((n).m_node)->parentNode == NULL) decref((n).m_node)
+
+ /**
+ * Thin wrapper class for a DOM Node
+ */
+ class Node
+ {
+ public:
+ enum TYPES
+ {
+ ELEMENT_NODE = DOM_ELEMENT_NODE,
+ ATTRIBUTE_NODE = DOM_ATTRIBUTE_NODE,
+ TEXT_NODE = DOM_TEXT_NODE,
+ CDATA_SECTION_NODE = DOM_CDATA_SECTION_NODE,
+ ENTITY_REFERENCE_NODE = DOM_ENTITY_REFERENCE_NODE,
+ ENTITY_NODE = DOM_ENTITY_NODE,
+ PROCESSING_INSTRUCTION_NODE = DOM_PROCESSING_INSTRUCTION_NODE,
+ COMMENT_NODE = DOM_COMMENT_NODE,
+ DOCUMENT_NODE = DOM_DOCUMENT_NODE,
+ DOCUMENT_TYPE_NODE = DOM_DOCUMENT_TYPE_NODE,
+ DOCUMENT_FRAGMENT_NODE = DOM_DOCUMENT_FRAGMENT_NODE,
+ NOTATION_NODE = DOM_NOTATION_NODE
+ };
+
+ Node()
+ { m_node = NULL; }
+
+ Node(const Node& node)
+ {
+ INC_NODE_REF(node);
+ m_node = node.m_node;
+ }
+
+ Node& operator=(const Node& other)
+ {
+ INC_NODE_REF(other);
+ DEC_NODE_REF(*this);
+ m_node = other.m_node;
+ return *this;
+ }
+
+ Node& operator=(const void* null)
+ {
+ ASSERT(null == NULL);
+ DEC_NODE_REF(*this);
+ m_node = NULL;
+ return *this;
+ }
+
+ ~Node()
+ { DEC_NODE_REF(*this); }
+
+ bool operator==(const Node& other) const
+ { return m_node == other.m_node; }
+ bool operator==(const void* null) const
+ { ASSERT(null == NULL); return 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();
+ DOM_String* name = m_node->nodeName;
+ return dom_str(name);
+ }
+
+ data_str getNodeValue() const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ // TODO: Check on memory management
+ DOM_String* value = DOM_Node_getNodeValue(m_node);
+ return data_str(value);
+ }
+
+ void setNodeValue(const data_str& value)
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ RESET_ERR();
+ DOM_Node_setNodeValue(m_node, FROM_V(value));
+ CHECK_ERR();
+ }
+
+ short getNodeType() const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ return (short)(m_node->nodeType);
+ }
+
+ Node getParentNode() const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ return Node(m_node->parentNode);
+ }
+
+ NodeList getChildNodes() const
+ throw(DOMException);
+
+ Node getFirstChild() const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ return Node(m_node->firstChild);
+ }
+
+ Node getLastChild() const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ return Node(m_node->lastChild);
+ }
+
+ Node getPreviousSibling() const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ return Node(m_node->previousSibling);
+ }
+
+ Node getNextSibling() const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ return Node(m_node->nextSibling);
+ }
+
+ 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);
+ RESET_ERR();
+ Node node(DOM_Node_insertBefore(m_node, newChild.m_node, refChild.m_node));
+ CHECK_ERR();
+ return node;
+ }
+
+ Node replaceChild(const Node& newChild, const Node& refChild)
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT_VALID_NODE(newChild);
+ ASSERT_VALID_NODE(refChild);
+ RESET_ERR();
+ Node node(DOM_Node_replaceChild(m_node, newChild.m_node, refChild.m_node));
+ CHECK_ERR();
+ return node;
+ }
+
+ Node removeChild(const Node& oldChild)
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT_VALID_NODE(oldChild);
+ RESET_ERR();
+ Node node(DOM_Node_removeChild(m_node, oldChild.m_node));
+ CHECK_ERR();
+ return node;
+ }
+
+ Node appendChild(const Node& newChild)
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT_VALID_NODE(newChild);
+ RESET_ERR();
+ Node node(DOM_Node_appendChild(m_node, newChild.m_node));
+ CHECK_ERR();
+ return node;
+ }
+
+ bool hasChildNodes() const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ return DOM_Node_hasChildNodes(m_node) ? true : false;
+ }
+
+ Node cloneNode(bool deep) const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ RESET_ERR();
+ Node node(DOM_Node_cloneNode(m_node, deep ? 1 : 0));
+ CHECK_ERR();
+ return node;
+ }
+
+ void normalize()
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ if(m_node->nodeType == DOM_ELEMENT_NODE)
+ {
+ RESET_ERR();
+ DOM_Element_normalize(m_node);
+ CHECK_ERR();
+ }
+ }
+
+ bool isSupported(const dom_str& feature,
+ const dom_str& version) const
+ {
+ ASSERT_VALID();
+ return false;
+ }
+
+#if INCOMPLETE
+ dom_str getNamespaceURI() const
+ throw(DOMException)
+ {
+ }
+
+ dom_str getPrefix() const
+ throw(DOMException)
+ {
+ }
+
+ void setPrefix(const dom_str& prefix)
+ throw(DOMException)
+ {
+ }
+
+ dom_str getLocalName() const
+ throw(DOMException)
+ {
+ }
+#endif
+
+ bool hasAttributes() const
+ throw (DOMException)
+ {
+ ASSERT_VALID();
+
+ if(getNodeType() != ELEMENT_NODE)
+ return false;
+
+ return m_node->attributes != NULL &&
+ m_node->attributes->length > 0;
+ }
+
+ void* setUserData(void* data)
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ m_node->userData = data;
+ }
+
+ void* getUserData() const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ return m_node->userData;
+ }
+
+ bool isValid() const
+ { return m_node != NULL; }
+
+ protected:
+ Node(DOM_Node* node)
+ {
+ m_node = node;
+ INC_NODE_REF(*this);
+ }
+
+ protected:
+ DOM_Node* m_node;
+
+ friend class Document;
+ friend class NodeList;
+ friend class NamedNodeMap;
+
+ private:
+ inline void incref(DOM_Node* node)
+ { ASSERT(node); ++(node->rtfxRefCount); }
+
+ inline void decref(DOM_Node* node)
+ {
+ ASSERT(node);
+ ASSERT(node->parentNode == NULL);
+ --(node->rtfxRefCount);
+ if(node->rtfxRefCount <= 0)
+ {
+ ASSERT(node->ownerDocument);
+ DOM_Document_destroyNode(node->ownerDocument, node);
+ }
+ }
+ };
+
+ 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(DOM_Node* node) :
+ Node(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 Node& other)
+ { Node::operator=(other); return *this; }
+ 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);
+ RESET_ERR();
+ // TODO: Check on memory management
+ DOM_String* value = DOM_Element_getAttribute(m_node, FROM_D(name));
+ CHECK_ERR();
+ return data_str(value);
+ }
+
+ void setAttribute(const dom_str& name, const data_str& value)
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT_TYPE(ELEMENT_NODE);
+ RESET_ERR();
+ DOM_Element_setAttribute(m_node, FROM_D(name), FROM_V(value));
+ CHECK_ERR();
+ }
+
+ void removeAttribute(const dom_str& name)
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT_TYPE(ELEMENT_NODE);
+ RESET_ERR();
+ DOM_Element_removeAttribute(m_node, FROM_D(name));
+ CHECK_ERR();
+ }
+
+ Attr getAttributeNode(const dom_str& name) const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT_TYPE(ELEMENT_NODE);
+ RESET_ERR();
+ Attr attr(DOM_Element_getAttributeNode(m_node, FROM_D(name)));
+ CHECK_ERR();
+ return attr;
+ }
+
+ Attr setAttributeNode(const Attr& attr)
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT_VALID_NODE(attr);
+ ASSERT_TYPE(ELEMENT_NODE);
+ RESET_ERR();
+ Attr att(DOM_Element_setAttributeNode(m_node, attr.m_node));
+ CHECK_ERR();
+ return att;
+ }
+
+ Attr removeAttributeNode(const Attr& attr)
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT_VALID_NODE(attr);
+ ASSERT_TYPE(ELEMENT_NODE);
+ RESET_ERR();
+ Attr att(DOM_Element_removeAttributeNode(m_node, attr.m_node));
+ CHECK_ERR();
+ return att;
+ }
+
+ NodeList getElementsByTagName(const dom_str& name) const
+ throw(DOMException);
+
+#ifdef INCOMPLETE
+ data_str getAttributeNS(const dom_str& uri, const dom_str& name) const
+ throw(DOMException)
+ {
+ }
+
+ void setAttributeNS(const dom_str& uri, const dom_str& name,
+ const data_str& value)
+ throw(DOMException)
+ {
+ }
+
+ void removeAttributeNS(const dom_str& uri, const dom_str& name)
+ throw(DOMException)
+ {
+ }
+
+ Attr getAttributeNodeNS(const dom_str& uri, const dom_str& name) const
+ throw(DOMException)
+ {
+ }
+
+ Attr setAttributeNodeNS(const Attr& attr)
+ throw(DOMException)
+ {
+ }
+
+ NodeList getElementsByTagNameNS(const dom_str& uri,
+ const dom_str& name) const
+ throw(DOMException);
+#endif
+
+ bool hasAttribute(const dom_str& name) const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT_TYPE(ELEMENT_NODE);
+ RESET_ERR();
+ bool ret = (DOM_Element_getAttributeNode(m_node, FROM_D(name)) != NULL);
+ CHECK_ERR();
+ return ret;
+ }
+
+#ifdef INCOMPLETE
+ bool hasAttributeNS(const dom_str& uri, const dom_str& name) const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT_TYPE(ELEMENT_NODE);
+ return getAttributeNodeNS(uri, name) != NULL;
+ }
+#endif
+
+ protected:
+ Element(DOM_Node* node) :
+ Node(node) { }
+
+ friend class Attr;
+ friend class Document;
+ };
+
+
+ class CharacterData :
+ public Node
+ {
+ public:
+ CharacterData() { }
+ CharacterData(const Node& node) :
+ Node(node) { }
+
+ CharacterData& operator=(const Node& other)
+ { Node::operator=(other); return *this; }
+ 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);
+ RESET_ERR();
+ DOM_CharacterData_appendData(m_node, FROM_D(data));
+ CHECK_ERR();
+ }
+
+ void deleteData(int offset, int count)
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT(getNodeType() == TEXT_NODE ||
+ getNodeType() == CDATA_SECTION_NODE ||
+ getNodeType() == COMMENT_NODE);
+ RESET_ERR();
+ DOM_CharacterData_deleteData(m_node, offset, count);
+ CHECK_ERR();
+ }
+
+ 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);
+ RESET_ERR();
+ int len = DOM_CharacterData_getLength(m_node);
+ CHECK_ERR();
+ return len;
+ }
+
+ void insertData(int offset, const data_str& data)
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT(getNodeType() == TEXT_NODE ||
+ getNodeType() == CDATA_SECTION_NODE ||
+ getNodeType() == COMMENT_NODE);
+ RESET_ERR();
+ DOM_CharacterData_insertData(m_node, offset, FROM_V(data));
+ CHECK_ERR();
+ }
+
+ void replaceData(int offset, int count, const data_str& data)
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT(getNodeType() == TEXT_NODE ||
+ getNodeType() == CDATA_SECTION_NODE ||
+ getNodeType() == COMMENT_NODE);
+ RESET_ERR();
+ DOM_CharacterData_replaceData(m_node, offset, count, FROM_V(data));
+ CHECK_ERR();
+ }
+
+ 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);
+ RESET_ERR();
+ DOM_String* value = DOM_CharacterData_substringData(m_node, offset, count);
+ CHECK_ERR();
+ return data_str(value);
+ }
+
+ protected:
+ CharacterData(DOM_Node* node) :
+ Node(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)
+ {
+ ASSERT_VALID();
+ ASSERT_TYPE(TEXT_NODE);
+ RESET_ERR();
+ Text text(DOM_Text_splitText(m_node, offset));
+ CHECK_ERR();
+ return text;
+ }
+
+ protected:
+ Text(DOM_Node* node) :
+ CharacterData(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(DOM_Node* node) :
+ Text(node) { }
+
+ friend class Document;
+ };
+
+ class Comment :
+ public CharacterData
+ {
+ public:
+ Comment() { }
+ Comment(const Comment& node) :
+ CharacterData(node) { }
+
+ Comment& operator=(const Node& other)
+ { Node::operator=(other); return *this; }
+ 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(DOM_Node* node) :
+ CharacterData(node) { }
+
+ friend class Document;
+ };
+
+ class ProcessingInstruction :
+ public Node
+ {
+ public:
+ ProcessingInstruction() { }
+ ProcessingInstruction(const ProcessingInstruction& node) :
+ Node(node) { }
+
+ ProcessingInstruction& operator=(const Node& other)
+ { Node::operator=(other); return *this; }
+ 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);
+ return getNodeName();
+ }
+
+ void setData(const data_str& data)
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT_TYPE(PROCESSING_INSTRUCTION_NODE);
+ setNodeValue(data);
+ }
+
+ protected:
+ ProcessingInstruction(DOM_Node* node) :
+ Node(node) { }
+
+ friend class Document;
+ };
+
+ class DocumentFragment :
+ public Node
+ {
+ public:
+ DocumentFragment() { }
+ DocumentFragment(const DocumentFragment& node) :
+ Node(node) { }
+
+ DocumentFragment& operator=(const Node& other)
+ { Node::operator=(other); return *this; }
+ 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; }
+
+ protected:
+ DocumentFragment(DOM_Node* node) :
+ Node(node) { }
+
+ friend class Document;
+ };
+
+ class Entity :
+ public Node
+ {
+ public:
+ Entity() { }
+ Entity(const Entity& node) :
+ Node(node) { }
+
+ Entity& operator=(const Node& other)
+ { Node::operator=(other); return *this; }
+ 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);
+ return getNodeName();
+ }
+
+ dom_str getPublicId() const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT_TYPE(ENTITY_NODE);
+ return dom_str(m_node->u.Entity.publicId);
+ }
+
+ dom_str getSystemId() const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT_TYPE(ENTITY_NODE);
+ return dom_str(m_node->u.Entity.systemId);
+ }
+
+ protected:
+ Entity(DOM_Node* node) :
+ Node(node) { }
+
+ friend class DocumentType;
+ };
+
+ class EntityReference :
+ public Node
+ {
+ public:
+ EntityReference() { }
+ EntityReference(const EntityReference& node) :
+ Node(node) { }
+
+ EntityReference& operator=(const Node& other)
+ { Node::operator=(other); return *this; }
+ 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; }
+
+ protected:
+ EntityReference(DOM_Node* node) :
+ Node(node) { }
+
+ friend class DocumentType;
+ friend class Document;
+ };
+
+ class Notation :
+ public Node
+ {
+ public:
+ Notation() { }
+ Notation(const Notation& node) :
+ Node(node) { }
+
+ Notation& operator=(const Node& other)
+ { Node::operator=(other); return *this; }
+ 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);
+ return dom_str(m_node->u.Notation.publicId);
+ }
+
+ dom_str getSystemId() const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT_TYPE(NOTATION_NODE);
+ return dom_str(m_node->u.Notation.systemId);
+ }
+
+ protected:
+ Notation(DOM_Node* node) :
+ Node(node) { }
+
+ friend class DocumentType;
+ };
+
+ class DocumentType :
+ public Node
+ {
+ public:
+ DocumentType() { }
+ DocumentType(const DocumentType& node) :
+ Node(node) { }
+
+ DocumentType& operator=(const Node& other)
+ { Node::operator=(other); return *this; }
+ 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);
+
+ NamedNodeMap getNotations() const
+ throw(DOMException);
+
+ dom_str getInternalSubset() const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT_TYPE(DOCUMENT_TYPE_NODE);
+ return dom_str(m_node->u.DocumentType.internalSubset);
+ }
+
+ dom_str getName() const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT_TYPE(DOCUMENT_TYPE_NODE);
+ return getNodeName();
+ }
+
+ protected:
+ DocumentType(DOM_Node* node) :
+ Node(node) { }
+
+ friend class Document;
+ friend class DOMImplementation;
+ };
+
+
+ class Document :
+ public Node
+ {
+ public:
+ Document() { }
+ Document(const Document& doc) :
+ 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);
+ RESET_ERR();
+ DocumentType dt(DOM_Document_getDoctype(m_node));
+ CHECK_ERR();
+ return dt;
+ }
+
+ DOMImplementation getImplementation() const
+ throw(DOMException);
+
+ Element getDocumentElement() const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT_TYPE(DOCUMENT_NODE);
+ RESET_ERR();
+ Element el(DOM_Document_getDocumentElement(m_node));
+ CHECK_ERR();
+ return el;
+ }
+
+ Element createElement(const dom_str& tag) const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT_TYPE(DOCUMENT_NODE);
+ RESET_ERR();
+ Element el(DOM_Document_createElement(m_node, FROM_D(tag)));
+ CHECK_ERR();
+ return el;
+ }
+
+ DocumentFragment createDocumentFragment() const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT_TYPE(DOCUMENT_NODE);
+ RESET_ERR();
+ DocumentFragment df(DOM_Document_createDocumentFragment(m_node));
+ CHECK_ERR();
+ return df;
+ }
+
+ Text createTextNode(const data_str& data) const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT_TYPE(DOCUMENT_NODE);
+ RESET_ERR();
+ Text text(DOM_Document_createTextNode(m_node, FROM_V(data)));
+ CHECK_ERR();
+ return text;
+ }
+
+ Comment createComment(const data_str& data) const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT_TYPE(DOCUMENT_NODE);
+ RESET_ERR();
+ Comment comment(DOM_Document_createComment(m_node, FROM_V(data)));
+ CHECK_ERR();
+ return comment;
+ }
+
+ CDATASection createCDATASection(const data_str& data) const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT_TYPE(DOCUMENT_NODE);
+ RESET_ERR();
+ CDATASection cdata(DOM_Document_createCDATASection(m_node, FROM_V(data)));
+ CHECK_ERR();
+ return cdata;
+ }
+
+ ProcessingInstruction createProcessingInstruction(const dom_str& targ,
+ const data_str& data) const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT_TYPE(DOCUMENT_NODE);
+ RESET_ERR();
+ ProcessingInstruction pi(DOM_Document_createProcessingInstruction
+ (m_node, FROM_D(targ), FROM_V(data)));
+ CHECK_ERR();
+ return pi;
+ }
+
+ Attr createAttribute(const dom_str& name) const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT_TYPE(DOCUMENT_NODE);
+ RESET_ERR();
+ Attr attr(DOM_Document_createAttribute(m_node, FROM_D(name)));
+ CHECK_ERR();
+ return attr;
+ }
+
+ EntityReference createEntityReference(const dom_str& name)
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT_TYPE(DOCUMENT_NODE);
+ RESET_ERR();
+ EntityReference er(DOM_Document_createEntityReference(m_node, FROM_D(name)));
+ CHECK_ERR();
+ return er;
+ }
+
+ NodeList getElementsByTagName(const dom_str& name) const
+ throw(DOMException);
+
+#ifdef INCOMPLETE
+ Node importNode(const Node& import, bool deep) const
+ throw(DOMException)
+ {
+ }
+
+ Element createElementNS(const dom_str& uri, const dom_str& tag) const
+ throw(DOMException)
+ {
+ }
+
+ Attr createAttributeNS(const dom_str& uri, const dom_str& name) const
+ throw(DOMException)
+ {
+ }
+
+ NodeList getElementsByTagNameNS(const dom_str& uri,
+ const dom_str& name) const
+ throw(DOMException);
+
+ Element getElementById(const dom_str& id) const
+ throw(DOMException)
+ {
+ }
+#endif
+ void serialize(FILE* f)
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ RESET_ERR();
+ DOM_DocumentLS_fwrite(m_node, f);
+ CHECK_ERR();
+ }
+
+ protected:
+ Document(DOM_Document* doc) :
+ Node(doc) { }
+
+ friend class Node;
+ friend class DOMImplementation;
+ };
+
+ class DOMImplementation
+ {
+ public:
+ DOMImplementation() { }
+ DOMImplementation(const DOMImplementation& impl) { }
+
+ DOMImplementation& operator=(const DOMImplementation& other)
+ { return *this; }
+ DOMImplementation& operator=(void* 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)
+ {
+ RESET_ERR();
+ Document doc(DOM_Implementation_createDocument
+ (FROM_D(uri), FROM_D(qname), type.m_node));
+ CHECK_ERR();
+ return doc;
+ }
+
+ DocumentType createDocumentType(const dom_str& qname,
+ const dom_str& publicId,
+ const dom_str& systemId) const
+ throw(DOMException)
+ {
+ RESET_ERR();
+ DocumentType doctype(DOM_Implementation_createDocumentType
+ (FROM_D(qname), FROM_D(publicId), FROM_D(systemId)));
+ CHECK_ERR();
+ return doctype;
+ }
+
+ bool hasFeature(const dom_str& feature, const dom_str& version) const
+ throw(DOMException)
+ {
+ RESET_ERR();
+ int ret = DOM_Implementation_hasFeature(FROM_D(feature), FROM_D(version));
+ CHECK_ERR();
+ return ret == 0 ? false : true;
+ }
+ };
+
+ /* We only perform ref counting on lists marked that way */
+ #define INC_NODELIST_REF(l) \
+ if((l).m_list != NULL && ((l).m_list->rtfxRefCount) != NO_REFCNT) incref((l).m_list)
+ #define DEC_NODELIST_REF(l) \
+ if((l).m_list != NULL && ((l).m_list->rtfxRefCount) != NO_REFCNT) decref((l).m_list)
+
+ class NodeList
+ {
+ public:
+ NodeList()
+ { m_list = NULL; }
+
+ NodeList(const NodeList& list)
+ {
+ INC_NODELIST_REF(list);
+ m_list = list.m_list;
+ }
+
+ NodeList& operator=(const NodeList& other)
+ {
+ INC_NODELIST_REF(other);
+ DEC_NODELIST_REF(*this);
+ m_list = other.m_list;
+ return *this;
+ }
+
+ NodeList& operator=(const void* null)
+ {
+ ASSERT(null == NULL);
+ DEC_NODELIST_REF(*this);
+ m_list = NULL;
+ return *this;
+ }
+
+ ~NodeList()
+ { DEC_NODELIST_REF(*this); }
+
+ bool operator==(const NodeList& other) const
+ { return m_list == other.m_list; }
+ bool operator==(const void* null) const
+ { ASSERT(null == NULL); return m_list == NULL; }
+ bool operator!=(const NodeList& other) const
+ { return !operator==(other); }
+ bool operator!=(const void* null) const
+ { return !operator==(null); }
+
+ const NodeList* operator->() const
+ { return (const NodeList*)this; }
+ NodeList* operator->()
+ { return this; }
+
+#ifdef COMPARE_REF
+ bool operator==(const NodeList& other) const
+ { return m_list == ((NodeList&)other).m_list; }
+#endif
+
+ virtual int getLength() const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ return m_list->length;
+ }
+
+ virtual Node item(int index) const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ RESET_ERR();
+ Node node(DOM_NodeList_item(m_list, index));
+ CHECK_ERR();
+ return node;
+ }
+
+ protected:
+ NodeList(DOM_NodeList* list, bool refcnt)
+ {
+ m_list = list;
+
+ if(m_list != NULL)
+ {
+ if(refcnt)
+ INC_NODELIST_REF(*this);
+ else
+ m_list->rtfxRefCount = NO_REFCNT;
+ }
+ }
+
+ bool isValid() const
+ {
+ return m_list != NULL;
+ }
+
+ protected:
+ DOM_NodeList* m_list;
+
+ friend class Element;
+ friend class Document;
+
+ private:
+ inline void incref(DOM_NodeList* list)
+ { ASSERT(list && (list->rtfxRefCount) != NO_REFCNT); ++(list->rtfxRefCount); }
+
+ inline void decref(DOM_NodeList* list)
+ {
+ ASSERT(list->rtfxRefCount != NO_REFCNT);
+ --(list->rtfxRefCount);
+ if(list->rtfxRefCount <= 0)
+ {
+ ASSERT(list->_ownerDocument != NULL);
+ DOM_Document_destroyNodeList(list->_ownerDocument, list, 0);
+ }
+ }
+
+ friend class Node;
+ };
+
+
+ class NamedNodeMap :
+ public NodeList
+ {
+ public:
+ NamedNodeMap()
+ { }
+
+ NamedNodeMap(const NamedNodeMap& list) :
+ NodeList(list) { }
+
+ NamedNodeMap& operator=(const NamedNodeMap& other)
+ { NodeList::operator=(other); return *this; }
+ NamedNodeMap& operator=(void* null)
+ { NodeList::operator=(null); return *this; }
+ const NamedNodeMap* operator->() const
+ { return (const NamedNodeMap*)this; }
+ NamedNodeMap* operator->()
+ { return this; }
+
+ virtual int getLength() const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ return NodeList::getLength();
+ }
+
+ virtual Node getNamedItem(const dom_str& name) const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ RESET_ERR();
+ Node node(DOM_NamedNodeMap_getNamedItem(m_list, FROM_D(name)));
+ CHECK_ERR();
+ return node;
+ }
+
+#ifdef INCOMPLETE
+ virtual Node getNamedItemNS(const dom_str& uri, const dom_str& name) const
+ throw(DOMException)
+ {
+ }
+#endif
+
+ virtual Node item(int index) const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ RESET_ERR();
+ Node node(DOM_NodeList_item(m_list, index));
+ CHECK_ERR();
+ return node;
+ }
+
+ virtual Node removeNamedItem(const dom_str& name)
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ RESET_ERR();
+ Node node(DOM_NamedNodeMap_removeNamedItem(m_list, FROM_D(name)));
+ CHECK_ERR();
+ return node;
+ }
+
+#ifdef INCOMPLETE
+ virtual Node removeNamedItemNS(const dom_str& uri, const dom_str& name)
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ _try_(S::SDOM_NOT_SUPPORTED_ERR);
+ return Node();
+ }
+#endif
+
+ virtual Node setNamedItem(const Node& arg)
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT_VALID_NODE(arg);
+ RESET_ERR();
+ Node node(DOM_NamedNodeMap_setNamedItem(m_list, arg.m_node));
+ CHECK_ERR();
+ return node;
+ }
+
+#ifdef INCOMPLETE
+ virtual Node setNamedItemNS(const Node& arg)
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT_VALID_NODE(arg);
+ _try_(S::SDOM_NOT_SUPPORTED_ERR);
+ return Node();
+ }
+#endif
+
+ protected:
+ NamedNodeMap(DOM_NodeList* list, bool refcnt) :
+ NodeList(list, refcnt) { }
+
+ friend class Node;
+ friend class DocumentType;
+ };
+
+
+ inline NodeList Node::getChildNodes() const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ return NodeList(m_node->childNodes, false);
+ }
+
+ inline NamedNodeMap Node::getAttributes() const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ if(getNodeType() != ELEMENT_NODE)
+ return NamedNodeMap();
+
+ return NamedNodeMap(m_node->attributes, false);
+ }
+
+ inline Document Node::getOwnerDocument() const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ return Document(m_node->ownerDocument);
+ }
+
+ inline Element Attr::getOwnerElement() const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT_TYPE(ATTRIBUTE_NODE);
+ return Element(m_node->u.Attr.ownerElement);
+ }
+
+ inline NodeList Element::getElementsByTagName(const dom_str& name) const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT_TYPE(ELEMENT_NODE);
+ RESET_ERR();
+ NodeList list(DOM_Element_getElementsByTagName(m_node, FROM_D(name)), true);
+ CHECK_ERR();
+ return list;
+ }
+
+#ifdef INCOMPLETE
+ inline NodeList Element::getElementsByTagNameNS(const dom_str& uri,
+ const dom_str& name) const
+ throw(DOMException)
+ {
+ }
+#endif
+
+ inline NodeList Document::getElementsByTagName(const dom_str& name) const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT_TYPE(DOCUMENT_NODE);
+ RESET_ERR();
+ NodeList list(DOM_Document_getElementsByTagName(m_node, FROM_D(name)), true);
+ CHECK_ERR();
+ return list;
+ }
+
+#ifdef INCOMPLETE
+ inline NodeList Document::getElementsByTagNameNS(const dom_str& uri,
+ const dom_str& name) const
+ throw(DOMException)
+ {
+ }
+#endif
+
+ inline DOMImplementation Document::getImplementation() const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT_TYPE(DOCUMENT_NODE);
+ return DOMImplementation();
+ }
+
+ inline NamedNodeMap DocumentType::getEntities() const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT_TYPE(DOCUMENT_TYPE_NODE);
+ return NamedNodeMap(m_node->u.DocumentType.entities, false);
+ }
+
+ inline NamedNodeMap DocumentType::getNotations() const
+ throw(DOMException)
+ {
+ ASSERT_VALID();
+ ASSERT_TYPE(DOCUMENT_TYPE_NODE);
+ return NamedNodeMap(m_node->u.DocumentType.notations, false);
+ }
+
+}; // namespace DOM
+
+
+#endif //__DOMCXX_H__