diff options
author | Stef Walter <stef@memberwebs.com> | 2004-07-29 22:52:30 +0000 |
---|---|---|
committer | Stef Walter <stef@memberwebs.com> | 2004-07-29 22:52:30 +0000 |
commit | 740d8a6bcb6521e188361befa7f5636c880bf63b (patch) | |
tree | f269a5d492d712be73d840fdefeb6ad247ee03db /src/domcxx.h | |
parent | 0105af34f6977c51619bf1060e74e3c249932c68 (diff) |
- Moved to DOMC
Diffstat (limited to 'src/domcxx.h')
-rw-r--r-- | src/domcxx.h | 1659 |
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__ |