nodeimpl.cpp
来自「IBM的解析xml的工具Xerces的源代码」· C++ 代码 · 共 500 行
CPP
500 行
/* * Copyright 1999-2002,2004 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *//* * $Id: NodeImpl.cpp,v 1.5 2004/09/28 10:56:04 amassari Exp $ */// This class doesn't support having any children, and implements the behavior// of an empty NodeList as far getChildNodes is concerned.// The ParentNode subclass overrides this behavior.#include "NodeImpl.hpp"#include "AttrImpl.hpp"#include "DOM_DOMException.hpp"#include "DOM_Node.hpp"#include "DOM_DOMImplementation.hpp"#include "DOMString.hpp"#include "DStringPool.hpp"#include "DocumentImpl.hpp"#include "NodeIDMap.hpp"#include "stdio.h"#include "TextImpl.hpp"XERCES_CPP_NAMESPACE_BEGINstatic DOMString *s_xml = null;static DOMString *s_xmlURI = null;static DOMString *s_xmlns = null;static DOMString *s_xmlnsURI = null;static XMLRegisterCleanup nodeImplCleanup;const unsigned short NodeImpl::READONLY = 0x1<<0;const unsigned short NodeImpl::SYNCDATA = 0x1<<1;const unsigned short NodeImpl::SYNCCHILDREN = 0x1<<2;const unsigned short NodeImpl::OWNED = 0x1<<3;const unsigned short NodeImpl::FIRSTCHILD = 0x1<<4;const unsigned short NodeImpl::SPECIFIED = 0x1<<5;const unsigned short NodeImpl::IGNORABLEWS = 0x1<<6;const unsigned short NodeImpl::SETVALUE = 0x1<<7;const unsigned short NodeImpl::ID_ATTR = 0x1<<8;const unsigned short NodeImpl::USERDATA = 0x1<<9;const unsigned short NodeImpl::HASSTRING = 0x1<<10;int NodeImpl::gLiveNodeImpls = 0; // Counters for debug & tuning.int NodeImpl::gTotalNodeImpls= 0;NodeImpl::NodeImpl(DocumentImpl *ownerDoc){ this->flags = 0; // as long as we do not have any owner, ownerNode is our ownerDocument this->ownerNode = ownerDoc; this->nodeRefCount = 0; NodeImpl::gLiveNodeImpls++; NodeImpl::gTotalNodeImpls++;};// This only makes a shallow copy, cloneChildren must also be called for a// deep cloneNodeImpl::NodeImpl(const NodeImpl &other) { this->flags = other.flags; this->isReadOnly(false); this->nodeRefCount = 0; NodeImpl::gLiveNodeImpls++; NodeImpl::gTotalNodeImpls++; // Need to break the association w/ original parent // this->ownerNode = other.getOwnerDocument(); this doesn't work??? this->ownerNode = ((NodeImpl*)&other)->getOwnerDocument(); this->isOwned(false);};NodeImpl::~NodeImpl() { if (hasUserData()) { setUserData(null); } NodeImpl::gLiveNodeImpls--;};// Dynamic Cast substitute functionsbool NodeImpl::isAttrImpl() {return false;};bool NodeImpl::isCDATASectionImpl() {return false;};bool NodeImpl::isDocumentFragmentImpl() {return false;};bool NodeImpl::isDocumentImpl() {return false;};bool NodeImpl::isDocumentTypeImpl() {return false;};bool NodeImpl::isElementImpl() {return false;};bool NodeImpl::isEntityReference() {return false;};bool NodeImpl::isTextImpl() {return false;};void NodeImpl::changed() { // we do not actually store this information on every node, we only // have a global indicator on the Document. Doing otherwise cost us too // much for little gain. getDocument()->changed();}int NodeImpl::changes(){ // we do not actually store this information on every node, we only // have a global indicator on the Document. Doing otherwise cost us too // much for little gain. return getDocument()->changes();};NodeImpl * NodeImpl::appendChild(NodeImpl *newChild){ return insertBefore(newChild, null);};// NodeImpl::deleteIf is called when a node's reference count goes// to 0. It is separate function from removeRef because removeRef// is likely to be in-lined.//// See comments at RefCountedImpl::removeRef().//void NodeImpl::deleteIf(NodeImpl *thisNode){ if (thisNode == 0) return; if (thisNode->isOwned()) return; // Delete this node. There should be no siblings, as the DOM // supports no node operations that would detach a node from // its parent while retaining siblings. // The target node may have children, in which case they must // be removed from this node before deleting this node. // First, if this node is an ID attribute, we need to remove it // from the hashtable of element IDs before removing the Attrs // children. This is because the Attr's children Text nodes // contain the attr's value, which is the hash table key. // if (thisNode->isAttrImpl() && ((AttrImpl *)thisNode->isIdAttr())) { ((AttrImpl *)thisNode)->getOwnerDocument() -> getNodeIDMap()->remove((AttrImpl *)thisNode); } thisNode->isReadOnly(false); // removeChild requires node not be readonly. NodeImpl *theNextChild; for (NodeImpl *child = thisNode->getFirstChild(); child != 0; child=theNextChild) { theNextChild = child->getNextSibling(); thisNode->removeChild(child); if (child->nodeRefCount == 0) deleteIf(child); } delete thisNode;};NamedNodeMapImpl * NodeImpl::getAttributes() { return 0; // overridden in ElementImpl};NodeListImpl *NodeImpl::getChildNodes() { return this; // overridden in ParentNode};NodeImpl * NodeImpl::getFirstChild() { return 0; // overridden in ParentNode};NodeImpl * NodeImpl::getLastChild(){ return 0; // overridden in ParentNode};unsigned int NodeImpl::getLength() { return 0; // overridden in ParentNode};NodeImpl * NodeImpl::getNextSibling() { return null; // overridden in ChildNode};DOMString NodeImpl::getNodeValue(){ return null; // overridden in some subclasses};DocumentImpl *NodeImpl::getOwnerDocument(){ // if we have an owner simply forward the request // otherwise ownerNode is our ownerDocument if (isOwned()) { return ownerNode->getDocument(); } else { return (DocumentImpl *) ownerNode; }};// unlike getOwnerDocument this is not overriden by DocumentImpl to return nullDocumentImpl *NodeImpl::getDocument(){ // if we have an owner simply forward the request // otherwise ownerNode is our ownerDocument if (isOwned()) { return ownerNode->getDocument(); } else { return (DocumentImpl *) ownerNode; }};void NodeImpl::setOwnerDocument(DocumentImpl *doc) { // if we have an owner we rely on it to have it right // otherwise ownerNode is our ownerDocument if (!isOwned()) { ownerNode = doc; }}NodeImpl * NodeImpl::getParentNode(){ return null; // overridden in ChildNode};NodeImpl* NodeImpl::getPreviousSibling(){ return null; // overridden in ChildNode};void *NodeImpl::getUserData(){ return (hasUserData()) ? getOwnerDocument()->getUserData(this) : null;};bool NodeImpl::hasChildNodes(){ return false;};NodeImpl *NodeImpl::insertBefore(NodeImpl *newChild, NodeImpl *refChild) { throw DOM_DOMException(DOM_DOMException::HIERARCHY_REQUEST_ERR,null); return 0;};NodeImpl *NodeImpl::item(unsigned int index) { return 0;};NodeImpl *NodeImpl::removeChild(NodeImpl *oldChild){ throw DOM_DOMException(DOM_DOMException::NOT_FOUND_ERR, null); return 0;};NodeImpl *NodeImpl::replaceChild(NodeImpl *newChild, NodeImpl *oldChild){ throw DOM_DOMException(DOM_DOMException::HIERARCHY_REQUEST_ERR,null); return 0;}; void NodeImpl::referenced() { RefCountedImpl::addRef(this->getOwnerDocument()); }; // // unreferenced will be called whenever the refernce count on // this node goes from 1 to 0. This node will only be // directly deleted here (by deleteIf) if it is outside // of the document tree. // void NodeImpl::unreferenced() { DocumentImpl *doc = this->getOwnerDocument(); deleteIf(this); // This gets nodes outside of the document - // deleteIf() deletes only if the parent // node is null. // If this was the last external reference within the document, // the entire document will be deleted as well. RefCountedImpl::removeRef(doc); };void NodeImpl::setNodeValue(const DOMString &val){ // Default behavior is to do nothing, overridden in some subclasses};void NodeImpl::setReadOnly(bool readOnl, bool deep){ this->isReadOnly(readOnl); // by default we do not have children, so deep is meaningless // this is overridden by ParentNode}void NodeImpl::setUserData(void * val){ getOwnerDocument()->setUserData(this, val); if (val) hasUserData(true); else hasUserData(false);};DOMString NodeImpl::toString(){ return DOMString("[")+getNodeName()+": "+getNodeValue()+"]"; // return getNodeName();};//Introduced in DOM Level 2void NodeImpl::normalize(){ // does nothing by default, overridden by subclasses};bool NodeImpl::isSupported(const DOMString &feature, const DOMString &version){ return DOM_DOMImplementation::getImplementation().hasFeature(feature, version);}DOMString NodeImpl::getNamespaceURI(){ return 0;}DOMString NodeImpl::getPrefix(){ return 0;}DOMString NodeImpl::getLocalName(){ return 0;}void NodeImpl::setPrefix(const DOMString &fPrefix){ throw DOM_DOMException(DOM_DOMException::NAMESPACE_ERR,null);}bool NodeImpl::hasAttributes() { return 0; // overridden in ElementImpl};DOMString NodeImpl::getXmlnsString() { return DStringPool::getStaticString("xmlns" , &s_xmlns , reinitNodeImpl , nodeImplCleanup );}DOMString NodeImpl::getXmlnsURIString() { return DStringPool::getStaticString("http://www.w3.org/2000/xmlns/" , &s_xmlnsURI , reinitNodeImpl , nodeImplCleanup );}DOMString NodeImpl::getXmlString() { return DStringPool::getStaticString("xml" , &s_xml , reinitNodeImpl , nodeImplCleanup );}DOMString NodeImpl::getXmlURIString() { return DStringPool::getStaticString("http://www.w3.org/XML/1998/namespace" , &s_xmlURI , reinitNodeImpl , nodeImplCleanup );}//Return a URI mapped from the given prefix and namespaceURI as below// prefix namespaceURI output//---------------------------------------------------// "xml" xmlURI xmlURI// "xml" otherwise NAMESPACE_ERR// "xmlns" xmlnsURI xmlnsURI (nType = ATTRIBUTE_NODE only)// "xmlns" otherwise NAMESPACE_ERR (nType = ATTRIBUTE_NODE only)// != null null or "" NAMESPACE_ERR// else any namesapceURIconst DOMString& NodeImpl::mapPrefix(const DOMString &prefix, const DOMString &namespaceURI, short nType){ DOMString xml = DStringPool::getStaticString("xml" , &s_xml , reinitNodeImpl , nodeImplCleanup ); DOMString xmlURI = DStringPool::getStaticString("http://www.w3.org/XML/1998/namespace" , &s_xmlURI , reinitNodeImpl , nodeImplCleanup ); DOMString xmlns = DStringPool::getStaticString("xmlns" , &s_xmlns , reinitNodeImpl , nodeImplCleanup ); DOMString xmlnsURI = DStringPool::getStaticString("http://www.w3.org/2000/xmlns/" , &s_xmlnsURI , reinitNodeImpl , nodeImplCleanup ); if (prefix == null) return namespaceURI; if (prefix.equals(xml)) { if (namespaceURI.equals(xmlURI)) return *s_xmlURI; throw DOM_DOMException(DOM_DOMException::NAMESPACE_ERR, null); } else if (nType == DOM_Node::ATTRIBUTE_NODE && prefix.equals(xmlns)) { if (namespaceURI.equals(xmlnsURI)) return *s_xmlnsURI; throw DOM_DOMException(DOM_DOMException::NAMESPACE_ERR, null); } else if (namespaceURI == null || namespaceURI.length() == 0) { throw DOM_DOMException(DOM_DOMException::NAMESPACE_ERR, null); } else return namespaceURI; return namespaceURI;}// -----------------------------------------------------------------------// Notification that lazy data has been deleted// -----------------------------------------------------------------------void NodeImpl::reinitNodeImpl() { delete s_xml; s_xml = 0; delete s_xmlURI; s_xmlURI = 0; delete s_xmlns; s_xmlns = 0; delete s_xmlnsURI; s_xmlnsURI = 0;}XERCES_CPP_NAMESPACE_END
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?