/* * 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 * */ // 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 #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__