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

词法分析

开发平台:

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: NamedNodeMapImpl.cpp,v 1.4 2003/05/22 02:26:50 knoaman Exp $
  58.  */
  59. #include "NamedNodeMapImpl.hpp"
  60. #include "NodeVector.hpp"
  61. #include "AttrImpl.hpp"
  62. #include "DOM_DOMException.hpp"
  63. #include "DocumentImpl.hpp"
  64. XERCES_CPP_NAMESPACE_BEGIN
  65. int        NamedNodeMapImpl::gLiveNamedNodeMaps  = 0;
  66. int        NamedNodeMapImpl::gTotalNamedNodeMaps = 0;
  67. NamedNodeMapImpl::NamedNodeMapImpl(NodeImpl *ownerNod)
  68. {
  69.     this->ownerNode=ownerNod;
  70.     this->nodes = null;
  71.     this->readOnly = false;
  72.     this->refCount = 1;
  73.     gLiveNamedNodeMaps++;
  74.     gTotalNamedNodeMaps++;
  75. };
  76. NamedNodeMapImpl::~NamedNodeMapImpl()
  77. {
  78.     if (nodes)
  79.     {
  80.         // It is the responsibility of whoever was using the named node
  81.         // map to do any cleanup on the nodes contained in the map
  82.         //  before deleting it.
  83.         delete nodes;
  84.         nodes = 0;
  85.     }
  86.     gLiveNamedNodeMaps--;
  87. };
  88. void NamedNodeMapImpl::addRef(NamedNodeMapImpl *This)
  89. {
  90.     if (This)
  91.         ++This->refCount;
  92. };
  93. NamedNodeMapImpl *NamedNodeMapImpl::cloneMap(NodeImpl *ownerNod)
  94. {
  95.     MemoryManager* manager = ownerNod->getDocument()->getMemoryManager();
  96.     NamedNodeMapImpl *newmap = new (manager) NamedNodeMapImpl(ownerNod);
  97.     if (nodes != null)
  98.     {
  99.         newmap->nodes = new (manager) NodeVector(nodes->size(), manager);
  100.         for (unsigned int i = 0; i < nodes->size(); ++i)
  101.         {
  102.             NodeImpl *n = nodes->elementAt(i)->cloneNode(true);
  103. n->isSpecified(nodes->elementAt(i)->isSpecified());
  104.             n->ownerNode = ownerNod;
  105.             n->isOwned(true);
  106.             newmap->nodes->addElement(n);
  107.         }
  108.     }
  109.     return newmap;
  110. };
  111. //
  112. //  removeAll - This function removes all elements from a named node map.
  113. //              It is called from the destructors for Elements and DocumentTypes,
  114. //              to remove the contents when the owning Element or DocType goes
  115. //              away.  The empty NamedNodeMap may persist if the user code
  116. //              has a reference to it.
  117. //
  118. //              AH Revist - the empty map should be made read-only, since
  119. //              adding it was logically part of the [Element, DocumentType]
  120. //              that has been deleted, and adding anything new to it would
  121. //              be meaningless, and almost certainly an error.
  122. //
  123. void NamedNodeMapImpl::removeAll()
  124. {
  125.     if (nodes)
  126.     {
  127.         for (int i=nodes->size()-1; i>=0; i--)
  128.         {
  129.             NodeImpl *n = nodes->elementAt(i);
  130.             n->ownerNode = ownerNode->getOwnerDocument();
  131.             n->isOwned(false);
  132.             if (n->nodeRefCount == 0)
  133.                 NodeImpl::deleteIf(n);
  134.         }
  135.         delete nodes;
  136.         nodes = null;
  137.     }
  138. }
  139. int NamedNodeMapImpl::findNamePoint(const DOMString &name)
  140. {
  141.     // Binary search
  142.     int i=0;
  143.     if(nodes!=null)
  144.     {
  145.         int first=0,last=nodes->size()-1;
  146.         while(first<=last)
  147.         {
  148.             i=(first+last)/2;
  149.             int test = name.compareString(nodes->elementAt(i)->getNodeName());
  150.             if(test==0)
  151.                 return i; // Name found
  152.             else if(test<0)
  153.                 last=i-1;
  154.             else
  155.                 first=i+1;
  156.         }
  157.         if(first>i) i=first;
  158.     }
  159.     /********************
  160.     // Linear search
  161.     int i = 0;
  162.     if (nodes != null)
  163.     for (i = 0; i < nodes.size(); ++i)
  164.     {
  165.     int test = name.compareTo(((NodeImpl *) (nodes.elementAt(i))).getNodeName());
  166.     if (test == 0)
  167.     return i;
  168.     else
  169.     if (test < 0)
  170.     {
  171.     break; // Found insertpoint
  172.     }
  173.     }
  174.     *******************/
  175.     return -1 - i; // not-found has to be encoded.
  176. };
  177. unsigned int NamedNodeMapImpl::getLength()
  178. {
  179.     return (nodes != null) ? nodes->size() : 0;
  180. };
  181. NodeImpl * NamedNodeMapImpl::getNamedItem(const DOMString &name)
  182. {
  183.     int i=findNamePoint(name);
  184.     return (i<0) ? null : (NodeImpl *)(nodes->elementAt(i));
  185. };
  186. NodeImpl * NamedNodeMapImpl::item(unsigned int index)
  187. {
  188.     return (nodes != null && index < nodes->size()) ?
  189.         (NodeImpl *) (nodes->elementAt(index)) : null;
  190. };
  191. //
  192. // removeNamedItem() - Remove the named item, and return it.
  193. //                      The caller must arrange for deletion of the
  194. //                      returned item if its refcount has gone to zero -
  195. //                      we can't do it here because the caller would
  196. //                      never see the returned node.
  197. //
  198. NodeImpl * NamedNodeMapImpl::removeNamedItem(const DOMString &name)
  199. {
  200.     if (readOnly)
  201.         throw DOM_DOMException(
  202.             DOM_DOMException::NO_MODIFICATION_ALLOWED_ERR, null);
  203.     int i=findNamePoint(name);
  204.     NodeImpl *n = null;
  205.     if(i<0)
  206.         throw DOM_DOMException(DOM_DOMException::NOT_FOUND_ERR, null);
  207.     n = (NodeImpl *) (nodes->elementAt(i));
  208.     nodes->removeElementAt(i);
  209.     n->ownerNode = ownerNode->getOwnerDocument();
  210.     n->isOwned(false);
  211.     return n;
  212. };
  213. void NamedNodeMapImpl::removeRef(NamedNodeMapImpl *This)
  214. {
  215.     if (This && --This->refCount == 0)
  216.         delete This;
  217. };
  218. //
  219. // setNamedItem()  Put the item into the NamedNodeList by name.
  220. //                  If an item with the same name already was
  221. //                  in the list, replace it.  Return the old
  222. //                  item, if there was one.
  223. //                  Caller is responsible for arranging for
  224. //                  deletion of the old item if its ref count is
  225. //                  zero.
  226. //
  227. NodeImpl * NamedNodeMapImpl::setNamedItem(NodeImpl * arg)
  228. {
  229.     if(arg->getOwnerDocument() != ownerNode->getOwnerDocument())
  230.         throw DOM_DOMException(DOM_DOMException::WRONG_DOCUMENT_ERR,null);
  231.     if (readOnly)
  232.         throw DOM_DOMException(DOM_DOMException::NO_MODIFICATION_ALLOWED_ERR, null);
  233.     if ((arg->getNodeType() == DOM_Node::ATTRIBUTE_NODE) && arg->isOwned() && (arg->ownerNode != ownerNode))
  234.         throw DOM_DOMException(DOM_DOMException::INUSE_ATTRIBUTE_ERR,null);
  235.     arg->ownerNode = ownerNode;
  236.     arg->isOwned(true);
  237.     int i=findNamePoint(arg->getNodeName());
  238.     NodeImpl * previous=null;
  239.     if(i>=0)
  240.     {
  241.         previous = nodes->elementAt(i);
  242.         nodes->setElementAt(arg,i);
  243.     }
  244.     else
  245.     {
  246.         i=-1-i; // Insert point (may be end of list)
  247.         if(null==nodes) {
  248.             MemoryManager* manager = ownerNode->getDocument()->getMemoryManager();
  249.             nodes=new (manager) NodeVector(manager);
  250.         }
  251.         nodes->insertElementAt(arg,i);
  252.     }
  253.     if (previous != null) {
  254.         previous->ownerNode = ownerNode->getOwnerDocument();
  255.         previous->isOwned(false);
  256.     }
  257.     return previous;
  258. };
  259. void NamedNodeMapImpl::setReadOnly(bool readOnl, bool deep)
  260. {
  261.     this->readOnly=readOnl;
  262.     if(deep && nodes!=null)
  263.     {
  264.         //Enumeration e=nodes->elements();
  265.         //while(e->hasMoreElements())
  266.         //      ((NodeImpl)e->nextElement())->setReadOnly(readOnl,deep);
  267.         int sz = nodes->size();
  268.         for (int i=0; i<sz; ++i) {
  269.             nodes->elementAt(i)->setReadOnly(readOnl, deep);
  270.         }
  271.     }
  272. };
  273. //Introduced in DOM Level 2
  274. int NamedNodeMapImpl::findNamePoint(const DOMString &namespaceURI,
  275. const DOMString &localName)
  276. {
  277.     if (nodes == null)
  278. return -1;
  279.     // This is a linear search through the same nodes Vector.
  280.     // The Vector is sorted on the DOM Level 1 nodename.
  281.     // The DOM Level 2 NS keys are namespaceURI and Localname,
  282.     // so we must linear search thru it.
  283.     // In addition, to get this to work with nodes without any namespace
  284.     // (namespaceURI and localNames are both null) we then use the nodeName
  285.     // as a secondary key.
  286.     int i, len = nodes -> size();
  287.     for (i = 0; i < len; ++i) {
  288. NodeImpl *node = nodes -> elementAt(i);
  289. if (! node -> getNamespaceURI().equals(namespaceURI)) //URI not match
  290.     continue;
  291.         DOMString nNamespaceURI = node->getNamespaceURI();
  292.         DOMString nLocalName = node->getLocalName();
  293.         if (namespaceURI == null) {
  294.             if (nNamespaceURI == null
  295.                 &&
  296.                 (localName.equals(nLocalName)
  297.                  ||
  298.                  (nLocalName == null && localName.equals(node->getNodeName()))))
  299.                 return i;
  300.         } else {
  301.             if (namespaceURI.equals(nNamespaceURI)
  302.                 &&
  303.                 localName.equals(nLocalName))
  304.                 return i;
  305.         }
  306.     }
  307.     return -1; //not found
  308. }
  309. NodeImpl *NamedNodeMapImpl::getNamedItemNS(const DOMString &namespaceURI,
  310. const DOMString &localName)
  311. {
  312.     int i = findNamePoint(namespaceURI, localName);
  313.     return i < 0 ? null : nodes -> elementAt(i);
  314. }
  315. //
  316. // setNamedItemNS()  Put the item into the NamedNodeList by name.
  317. //                  If an item with the same name already was
  318. //                  in the list, replace it.  Return the old
  319. //                  item, if there was one.
  320. //                  Caller is responsible for arranging for
  321. //                  deletion of the old item if its ref count is
  322. //                  zero.
  323. //
  324. NodeImpl * NamedNodeMapImpl::setNamedItemNS(NodeImpl *arg)
  325. {
  326.     if (arg->getOwnerDocument() != ownerNode->getOwnerDocument())
  327.         throw DOM_DOMException(DOM_DOMException::WRONG_DOCUMENT_ERR,null);
  328.     if (readOnly)
  329.         throw DOM_DOMException(DOM_DOMException::NO_MODIFICATION_ALLOWED_ERR, null);
  330.     if (arg->isOwned())
  331.         throw DOM_DOMException(DOM_DOMException::INUSE_ATTRIBUTE_ERR,null);
  332.     arg->ownerNode = ownerNode;
  333.     arg->isOwned(true);
  334.     int i=findNamePoint(arg->getNamespaceURI(), arg->getLocalName());
  335.     NodeImpl *previous=null;
  336.     if(i>=0) {
  337.         previous = nodes->elementAt(i);
  338.         nodes->setElementAt(arg,i);
  339.     } else {
  340.         i=findNamePoint(arg->getNodeName()); // Insert point (may be end of list)
  341.         if (i<0)
  342.           i = -1 - i;
  343.         if(null==nodes) {
  344.             MemoryManager* manager = ownerNode->getDocument()->getMemoryManager();
  345.             nodes=new (manager) NodeVector(manager);
  346.         }
  347.         nodes->insertElementAt(arg,i);
  348.     }
  349.     if (previous != null) {
  350.         previous->ownerNode = ownerNode->getOwnerDocument();
  351.         previous->isOwned(false);
  352.     }
  353.     return previous;
  354. };
  355. // removeNamedItemNS() - Remove the named item, and return it.
  356. //                      The caller must arrange for deletion of the
  357. //                      returned item if its refcount has gone to zero -
  358. //                      we can't do it here because the caller would
  359. //                      never see the returned node.
  360. NodeImpl *NamedNodeMapImpl::removeNamedItemNS(const DOMString &namespaceURI,
  361. const DOMString &localName)
  362. {
  363.     if (readOnly)
  364.         throw DOM_DOMException(
  365.         DOM_DOMException::NO_MODIFICATION_ALLOWED_ERR, null);
  366.     int i = findNamePoint(namespaceURI, localName);
  367.     if (i < 0)
  368.         throw DOM_DOMException(DOM_DOMException::NOT_FOUND_ERR, null);
  369.     NodeImpl * n = nodes -> elementAt(i);
  370.     nodes -> removeElementAt(i); //remove n from nodes
  371.     n->ownerNode = ownerNode->getOwnerDocument();
  372.     n->isOwned(false);
  373.     return n;
  374. }
  375. /**
  376.  * NON-DOM
  377.  * set the ownerDocument of this node, its children, and its attributes
  378.  */
  379. void NamedNodeMapImpl::setOwnerDocument(DocumentImpl *doc) {
  380.     if (nodes != null) {
  381.         for (unsigned int i = 0; i < nodes->size(); i++) {
  382.             item(i)->setOwnerDocument(doc);
  383.         }
  384.     }
  385. }
  386. void NamedNodeMapImpl::cloneContent(NamedNodeMapImpl *srcmap) {
  387.    if ((srcmap != null) && (srcmap->nodes != null) && (srcmap->nodes->size() > 0))
  388. {
  389. if (nodes != null) {
  390. delete nodes;
  391. }
  392.         MemoryManager* manager = ownerNode->getDocument()->getMemoryManager();
  393.         nodes = new (manager) NodeVector(srcmap->nodes->size(), manager);
  394. for (unsigned int i = 0; i < srcmap->nodes->size(); i++)
  395. {
  396. NodeImpl *n = srcmap->nodes->elementAt(i);
  397.   NodeImpl *clone = n->cloneNode(true);
  398. clone->isSpecified(n->isSpecified());
  399. clone->ownerNode = ownerNode;
  400. clone->isOwned(true);
  401. nodes->addElement(clone);
  402. // n = null;
  403. // clone = null;
  404. }
  405. }
  406. }
  407. XERCES_CPP_NAMESPACE_END