From 53914f770f1e1dc1ab4342c64846fd995825b7e6 Mon Sep 17 00:00:00 2001 From: Stef Date: Wed, 17 Sep 2003 18:34:42 +0000 Subject: Initial Import --- src/sablo.h | 2139 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 2139 insertions(+) create mode 100644 src/sablo.h (limited to 'src/sablo.h') 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: +// +// 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 +#include +#include +#include + +namespace DOM +{ + namespace S + { + extern "C" + { + #include + #include + } + }; + + bool transcode16to8(const std::basic_string& data, + std::basic_string& ret); + bool transcode8to16(const std::basic_string& data, + std::basic_string& ret); + + namespace INT + { + typedef std::basic_string _8str; + typedef std::basic_string _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 + 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 NamedNodeMap; + typedef INT::Ref 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 -- cgit v1.2.3