NodeImpl.cpp
上传用户:zhuqijet
上传日期:2013-06-25
资源大小:10074k
文件大小:17k
源码类别:

词法分析

开发平台:

Visual C++

  1. /*
  2.  * The Apache Software License, Version 1.1
  3.  *
  4.  * Copyright (c) 1999-2002 The Apache Software Foundation.  All rights
  5.  * reserved.
  6.  *
  7.  * Redistribution and use in source and binary forms, with or without
  8.  * modification, are permitted provided that the following conditions
  9.  * are met:
  10.  *
  11.  * 1. Redistributions of source code must retain the above copyright
  12.  *    notice, this list of conditions and the following disclaimer.
  13.  *
  14.  * 2. Redistributions in binary form must reproduce the above copyright
  15.  *    notice, this list of conditions and the following disclaimer in
  16.  *    the documentation and/or other materials provided with the
  17.  *    distribution.
  18.  *
  19.  * 3. The end-user documentation included with the redistribution,
  20.  *    if any, must include the following acknowledgment:
  21.  *       "This product includes software developed by the
  22.  *        Apache Software Foundation (http://www.apache.org/)."
  23.  *    Alternately, this acknowledgment may appear in the software itself,
  24.  *    if and wherever such third-party acknowledgments normally appear.
  25.  *
  26.  * 4. The names "Xerces" and "Apache Software Foundation" must
  27.  *    not be used to endorse or promote products derived from this
  28.  *    software without prior written permission. For written
  29.  *    permission, please contact apache@apache.org.
  30.  *
  31.  * 5. Products derived from this software may not be called "Apache",
  32.  *    nor may "Apache" appear in their name, without prior written
  33.  *    permission of the Apache Software Foundation.
  34.  *
  35.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
  36.  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  37.  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  38.  * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
  39.  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  40.  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  41.  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  42.  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  43.  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  44.  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  45.  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  46.  * SUCH DAMAGE.
  47.  * ====================================================================
  48.  *
  49.  * This software consists of voluntary contributions made by many
  50.  * individuals on behalf of the Apache Software Foundation, and was
  51.  * originally based on software copyright (c) 1999, International
  52.  * Business Machines, Inc., http://www.ibm.com .  For more information
  53.  * on the Apache Software Foundation, please see
  54.  * <http://www.apache.org/>.
  55.  */
  56. /*
  57.  * $Id: NodeImpl.cpp,v 1.3 2002/11/04 15:04:44 tng Exp $
  58.  */
  59. // This class doesn't support having any children, and implements the behavior
  60. // of an empty NodeList as far getChildNodes is concerned.
  61. // The ParentNode subclass overrides this behavior.
  62. #include "NodeImpl.hpp"
  63. #include "AttrImpl.hpp"
  64. #include "DOM_DOMException.hpp"
  65. #include "DOM_Node.hpp"
  66. #include "DOM_DOMImplementation.hpp"
  67. #include "DOMString.hpp"
  68. #include "DStringPool.hpp"
  69. #include "DocumentImpl.hpp"
  70. #include "NodeIDMap.hpp"
  71. #include "stdio.h"
  72. #include "TextImpl.hpp"
  73. XERCES_CPP_NAMESPACE_BEGIN
  74. static DOMString *s_xml = null;
  75. static DOMString *s_xmlURI = null;
  76. static DOMString *s_xmlns = null;
  77. static DOMString *s_xmlnsURI = null;
  78. static XMLRegisterCleanup nodeImplCleanup;
  79. const unsigned short NodeImpl::READONLY     = 0x1<<0;
  80. const unsigned short NodeImpl::SYNCDATA     = 0x1<<1;
  81. const unsigned short NodeImpl::SYNCCHILDREN = 0x1<<2;
  82. const unsigned short NodeImpl::OWNED        = 0x1<<3;
  83. const unsigned short NodeImpl::FIRSTCHILD   = 0x1<<4;
  84. const unsigned short NodeImpl::SPECIFIED    = 0x1<<5;
  85. const unsigned short NodeImpl::IGNORABLEWS  = 0x1<<6;
  86. const unsigned short NodeImpl::SETVALUE     = 0x1<<7;
  87. const unsigned short NodeImpl::ID_ATTR      = 0x1<<8;
  88. const unsigned short NodeImpl::USERDATA     = 0x1<<9;
  89. const unsigned short NodeImpl::HASSTRING    = 0x1<<10;
  90. NodeImpl::NodeImpl(DocumentImpl *ownerDoc)
  91. {
  92.     this->flags = 0;
  93.     // as long as we do not have any owner, ownerNode is our ownerDocument
  94.     this->ownerNode  = ownerDoc;
  95.     this->nodeRefCount = 0;
  96.     NodeImpl::gLiveNodeImpls++;
  97.     NodeImpl::gTotalNodeImpls++;
  98. };
  99. // This only makes a shallow copy, cloneChildren must also be called for a
  100. // deep clone
  101. NodeImpl::NodeImpl(const NodeImpl &other) {
  102.     this->flags = other.flags;
  103.     this->isReadOnly(false);
  104.     this->nodeRefCount = 0;
  105.     NodeImpl::gLiveNodeImpls++;
  106.     NodeImpl::gTotalNodeImpls++;
  107.     // Need to break the association w/ original parent
  108.     //    this->ownerNode = other.getOwnerDocument(); this doesn't work???
  109.     this->ownerNode = ((NodeImpl*)&other)->getOwnerDocument();
  110.     this->isOwned(false);
  111. };
  112. int  NodeImpl::gLiveNodeImpls = 0;         // Counters for debug & tuning.
  113. int  NodeImpl::gTotalNodeImpls= 0;
  114. NodeImpl::~NodeImpl() {
  115. if (hasUserData())
  116. {
  117. setUserData(null);
  118. }
  119.     NodeImpl::gLiveNodeImpls--;
  120. };
  121. // Dynamic Cast substitute functions
  122. bool NodeImpl::isAttrImpl()              {return false;};
  123. bool NodeImpl::isCDATASectionImpl()      {return false;};
  124. bool NodeImpl::isDocumentFragmentImpl()  {return false;};
  125. bool NodeImpl::isDocumentImpl()          {return false;};
  126. bool NodeImpl::isDocumentTypeImpl()      {return false;};
  127. bool NodeImpl::isElementImpl()           {return false;};
  128. bool NodeImpl::isEntityReference()       {return false;};
  129. bool NodeImpl::isTextImpl()              {return false;};
  130. void NodeImpl::changed() {
  131.     // we do not actually store this information on every node, we only
  132.     // have a global indicator on the Document. Doing otherwise cost us too
  133.     // much for little gain.
  134.     getDocument()->changed();
  135. }
  136. int NodeImpl::changes()
  137. {
  138.     // we do not actually store this information on every node, we only
  139.     // have a global indicator on the Document. Doing otherwise cost us too
  140.     // much for little gain.
  141.     return getDocument()->changes();
  142. };
  143. NodeImpl * NodeImpl::appendChild(NodeImpl *newChild)
  144. {
  145.     return insertBefore(newChild, null);
  146. };
  147. //  NodeImpl::deleteIf is called when a node's reference count goes
  148. //  to 0.  It is separate function from removeRef because removeRef
  149. //  is likely to be in-lined.
  150. //
  151. //  See comments at RefCountedImpl::removeRef().
  152. //
  153. void NodeImpl::deleteIf(NodeImpl *thisNode)
  154. {
  155.     if (thisNode == 0)
  156.         return;
  157.     if (thisNode->isOwned())
  158.         return;
  159.     // Delete this node.  There should be no siblings, as the DOM
  160.     //  supports no node operations that would detach a node from
  161.     //  its parent while retaining siblings.
  162.     //  The target node may have children, in which case they must
  163.     //  be removed from this node before deleting this node.
  164.     // First, if this node is an ID attribute, we need to remove it
  165.     // from the hashtable of element IDs before removing the Attrs
  166.     //   children.  This is because the Attr's children Text nodes
  167.     //   contain the attr's value, which is the hash table key.
  168.     //
  169.     if (thisNode->isAttrImpl() && ((AttrImpl *)thisNode->isIdAttr()))
  170.     {
  171.         ((AttrImpl *)thisNode)->getOwnerDocument() ->
  172.             getNodeIDMap()->remove((AttrImpl *)thisNode);
  173.     }
  174.     thisNode->isReadOnly(false);   // removeChild requires node not be readonly.
  175.     NodeImpl *theNextChild;
  176.     for (NodeImpl *child = thisNode->getFirstChild(); child != 0;
  177.          child=theNextChild)
  178.     {
  179.         theNextChild = child->getNextSibling();
  180.         thisNode->removeChild(child);
  181.         if (child->nodeRefCount == 0)
  182.             deleteIf(child);
  183.     }
  184.     delete thisNode;
  185. };
  186. NamedNodeMapImpl * NodeImpl::getAttributes() {
  187.     return 0;                   // overridden in ElementImpl
  188. };
  189. NodeListImpl *NodeImpl::getChildNodes() {
  190.     return this;                // overridden in ParentNode
  191. };
  192. NodeImpl * NodeImpl::getFirstChild() {
  193.     return 0;                   // overridden in ParentNode
  194. };
  195. NodeImpl * NodeImpl::getLastChild()
  196. {
  197.     return 0;                   // overridden in ParentNode
  198. };
  199. unsigned int NodeImpl::getLength() {
  200.     return 0;                   // overridden in ParentNode
  201. };
  202. NodeImpl * NodeImpl::getNextSibling() {
  203.     return null;                // overridden in ChildNode
  204. };
  205. DOMString NodeImpl::getNodeValue()
  206. {
  207.     return null;                // overridden in some subclasses
  208. };
  209. DocumentImpl *NodeImpl::getOwnerDocument()
  210. {
  211.     // if we have an owner simply forward the request
  212.     // otherwise ownerNode is our ownerDocument
  213.     if (isOwned()) {
  214.         return ownerNode->getDocument();
  215.     } else {
  216.         return (DocumentImpl *) ownerNode;
  217.     }
  218. };
  219. // unlike getOwnerDocument this is not overriden by DocumentImpl to return null
  220. DocumentImpl *NodeImpl::getDocument()
  221. {
  222.     // if we have an owner simply forward the request
  223.     // otherwise ownerNode is our ownerDocument
  224.     if (isOwned()) {
  225.         return ownerNode->getDocument();
  226.     } else {
  227.         return (DocumentImpl *) ownerNode;
  228.     }
  229. };
  230. void NodeImpl::setOwnerDocument(DocumentImpl *doc) {
  231.     // if we have an owner we rely on it to have it right
  232.     // otherwise ownerNode is our ownerDocument
  233.     if (!isOwned()) {
  234.         ownerNode = doc;
  235.     }
  236. }
  237. NodeImpl * NodeImpl::getParentNode()
  238. {
  239.     return null;                // overridden in ChildNode
  240. };
  241. NodeImpl*  NodeImpl::getPreviousSibling()
  242. {
  243.     return null;                // overridden in ChildNode
  244. };
  245. void *NodeImpl::getUserData()
  246. {
  247. return (hasUserData()) ? getOwnerDocument()->getUserData(this) : null;
  248. };
  249. bool NodeImpl::hasChildNodes()
  250. {
  251.     return false;
  252. };
  253. NodeImpl *NodeImpl::insertBefore(NodeImpl *newChild, NodeImpl *refChild) {
  254.     throw DOM_DOMException(DOM_DOMException::HIERARCHY_REQUEST_ERR,null);
  255.     return 0;
  256. };
  257. NodeImpl *NodeImpl::item(unsigned int index) {
  258.     return 0;
  259. };
  260. NodeImpl *NodeImpl::removeChild(NodeImpl *oldChild)
  261. {
  262.     throw DOM_DOMException(DOM_DOMException::NOT_FOUND_ERR, null);
  263.     return 0;
  264. };
  265. NodeImpl *NodeImpl::replaceChild(NodeImpl *newChild, NodeImpl *oldChild)
  266. {
  267.     throw DOM_DOMException(DOM_DOMException::HIERARCHY_REQUEST_ERR,null);
  268.     return 0;
  269. };
  270.   void NodeImpl::referenced()
  271.   {
  272.       RefCountedImpl::addRef(this->getOwnerDocument());
  273.   };
  274.   //
  275.   //    unreferenced  will be called whenever the refernce count on
  276.   //            this node goes from 1 to 0.  This node will only be
  277.   //            directly deleted here  (by deleteIf) if it is outside
  278.   //            of the document tree.
  279.   //
  280.   void NodeImpl::unreferenced()
  281.   {
  282.       DocumentImpl *doc = this->getOwnerDocument();
  283.       deleteIf(this);       // This gets nodes outside of the document -
  284.       //   deleteIf() deletes only if the parent
  285.       //   node is null.
  286.       // If this was the last external reference within the document,
  287.       //    the entire document will be deleted as well.
  288.       RefCountedImpl::removeRef(doc);
  289.   };
  290. void NodeImpl::setNodeValue(const DOMString &val)
  291. {
  292.     // Default behavior is to do nothing, overridden in some subclasses
  293. };
  294. void NodeImpl::setReadOnly(bool readOnl, bool deep)
  295. {
  296.     this->isReadOnly(readOnl);
  297.     // by default we do not have children, so deep is meaningless
  298.     // this is overridden by ParentNode
  299. }
  300. void NodeImpl::setUserData(void * val)
  301. {
  302. getOwnerDocument()->setUserData(this, val);
  303. if (val)
  304. hasUserData(true);
  305. else
  306. hasUserData(false);
  307. };
  308. DOMString NodeImpl::toString()
  309. {
  310. return DOMString("[")+getNodeName()+": "+getNodeValue()+"]";
  311. // return getNodeName();
  312. };
  313. //Introduced in DOM Level 2
  314. void NodeImpl::normalize()
  315. {
  316.     // does nothing by default, overridden by subclasses
  317. };
  318. bool NodeImpl::isSupported(const DOMString &feature, const DOMString &version)
  319. {
  320.     return DOM_DOMImplementation::getImplementation().hasFeature(feature, version);
  321. }
  322. DOMString NodeImpl::getNamespaceURI()
  323. {
  324.     return 0;
  325. }
  326. DOMString NodeImpl::getPrefix()
  327. {
  328.     return 0;
  329. }
  330. DOMString NodeImpl::getLocalName()
  331. {
  332.     return 0;
  333. }
  334. void NodeImpl::setPrefix(const DOMString &fPrefix)
  335. {
  336.     throw DOM_DOMException(DOM_DOMException::NAMESPACE_ERR,null);
  337. }
  338. bool NodeImpl::hasAttributes() {
  339.     return 0;                   // overridden in ElementImpl
  340. };
  341. DOMString NodeImpl::getXmlnsString() {
  342.     return DStringPool::getStaticString("xmlns"
  343.                                       , &s_xmlns
  344.                                       , reinitNodeImpl
  345.                                       , nodeImplCleanup
  346.                                       );
  347. }
  348. DOMString NodeImpl::getXmlnsURIString() {
  349.     return DStringPool::getStaticString("http://www.w3.org/2000/xmlns/"
  350.                                       , &s_xmlnsURI
  351.                                       , reinitNodeImpl
  352.                                       , nodeImplCleanup
  353.                                         );
  354. }
  355. DOMString NodeImpl::getXmlString() {
  356.     return DStringPool::getStaticString("xml"
  357.                                       , &s_xml
  358.                                       , reinitNodeImpl
  359.                                       , nodeImplCleanup
  360.                                       );
  361. }
  362. DOMString NodeImpl::getXmlURIString() {
  363.     return DStringPool::getStaticString("http://www.w3.org/XML/1998/namespace"
  364.                                       , &s_xmlURI
  365.                                       , reinitNodeImpl
  366.                                       , nodeImplCleanup
  367.                                         );
  368. }
  369. //Return a URI mapped from the given prefix and namespaceURI as below
  370. // prefix   namespaceURI output
  371. //---------------------------------------------------
  372. // "xml"      xmlURI            xmlURI
  373. // "xml"    otherwise         NAMESPACE_ERR
  374. // "xmlns"    xmlnsURI          xmlnsURI (nType = ATTRIBUTE_NODE only)
  375. // "xmlns"    otherwise         NAMESPACE_ERR (nType = ATTRIBUTE_NODE only)
  376. //   != null   null or ""        NAMESPACE_ERR
  377. // else       any      namesapceURI
  378. const DOMString& NodeImpl::mapPrefix(const DOMString &prefix,
  379.                                      const DOMString &namespaceURI, short nType)
  380. {
  381.     DOMString xml = DStringPool::getStaticString("xml"
  382.                                                , &s_xml
  383.                                                , reinitNodeImpl
  384.                                                , nodeImplCleanup
  385.                                                );
  386.     DOMString xmlURI = DStringPool::getStaticString("http://www.w3.org/XML/1998/namespace"
  387.                                                   , &s_xmlURI
  388.                                                   , reinitNodeImpl
  389.                                                   , nodeImplCleanup
  390.                                                   );
  391.     DOMString xmlns = DStringPool::getStaticString("xmlns"
  392.                                                  , &s_xmlns
  393.                                                  , reinitNodeImpl
  394.                                                  , nodeImplCleanup
  395.                                                  );
  396.     DOMString xmlnsURI = DStringPool::getStaticString("http://www.w3.org/2000/xmlns/"
  397.                                                     , &s_xmlnsURI
  398.                                                     , reinitNodeImpl
  399.                                                     , nodeImplCleanup
  400.                                                     );
  401.     if (prefix == null)
  402.         return namespaceURI;
  403.     if (prefix.equals(xml)) {
  404.         if (namespaceURI.equals(xmlURI))
  405.             return *s_xmlURI;
  406.         throw DOM_DOMException(DOM_DOMException::NAMESPACE_ERR, null);
  407.     } else if (nType == DOM_Node::ATTRIBUTE_NODE && prefix.equals(xmlns)) {
  408.         if (namespaceURI.equals(xmlnsURI))
  409.             return *s_xmlnsURI;
  410.         throw DOM_DOMException(DOM_DOMException::NAMESPACE_ERR, null);
  411.     } else if (namespaceURI == null || namespaceURI.length() == 0) {
  412.         throw DOM_DOMException(DOM_DOMException::NAMESPACE_ERR, null);
  413.     } else
  414.         return namespaceURI;
  415.     return namespaceURI;
  416. }
  417. // -----------------------------------------------------------------------
  418. //  Notification that lazy data has been deleted
  419. // -----------------------------------------------------------------------
  420. void NodeImpl::reinitNodeImpl() {
  421.     delete s_xml;
  422.     s_xml = 0;
  423.     delete s_xmlURI;
  424.     s_xmlURI = 0;
  425.     delete s_xmlns;
  426.     s_xmlns = 0;
  427.     delete s_xmlnsURI;
  428.     s_xmlnsURI = 0;
  429. }
  430. XERCES_CPP_NAMESPACE_END