You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xerces.apache.org by am...@apache.org on 2004/03/08 14:18:57 UTC

cvs commit: xml-xerces/c/src/xercesc/dom/impl DOMAttrMapImpl.cpp DOMAttrMapImpl.hpp DOMNamedNodeMapImpl.cpp DOMNamedNodeMapImpl.hpp

amassari    2004/03/08 05:18:57

  Modified:    c/src/xercesc/dom/impl DOMAttrMapImpl.cpp DOMAttrMapImpl.hpp
                        DOMNamedNodeMapImpl.cpp DOMNamedNodeMapImpl.hpp
  Log:
  The implementation for DOMNamedNodeMap used by the DTD to hold the element definitions is optimized for speed vs. space (attribute maps are still optimized for space)
  
  Revision  Changes    Path
  1.6       +247 -12   xml-xerces/c/src/xercesc/dom/impl/DOMAttrMapImpl.cpp
  
  Index: DOMAttrMapImpl.cpp
  ===================================================================
  RCS file: /home/cvs/xml-xerces/c/src/xercesc/dom/impl/DOMAttrMapImpl.cpp,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- DOMAttrMapImpl.cpp	4 Nov 2002 15:07:34 -0000	1.5
  +++ DOMAttrMapImpl.cpp	8 Mar 2004 13:18:57 -0000	1.6
  @@ -61,25 +61,27 @@
   
   #include "DOMAttrMapImpl.hpp"
   #include "DOMAttrImpl.hpp"
  -#include "DOMNamedNodeMapImpl.hpp"
   #include "DOMNodeImpl.hpp"
   #include "DOMElementImpl.hpp"
  -#include <xercesc/dom/DOMAttr.hpp>
   #include "DOMCasts.hpp"
  -#include "DOMDocumentImpl.hpp"
  +#include "DOMNodeVector.hpp"
  +
  +#include <xercesc/dom/DOMAttr.hpp>
   #include <xercesc/dom/DOMException.hpp>
   
   XERCES_CPP_NAMESPACE_BEGIN
   
   DOMAttrMapImpl::DOMAttrMapImpl(DOMNode *ownerNod)
  -	: DOMNamedNodeMapImpl(ownerNod)
   {
  +    this->fOwnerNode=ownerNod;
  +    this->fNodes = 0;
   	hasDefaults(false);
   }
   
  -DOMAttrMapImpl::DOMAttrMapImpl(DOMNode *ownerNod, const DOMNamedNodeMapImpl *defaults)
  -	: DOMNamedNodeMapImpl(ownerNod)
  +DOMAttrMapImpl::DOMAttrMapImpl(DOMNode *ownerNod, const DOMAttrMapImpl *defaults)
   {
  +    this->fOwnerNode=ownerNod;
  +    this->fNodes = 0;
   	hasDefaults(false);
   	if (defaults != 0)
   	{
  @@ -95,6 +97,33 @@
   {
   }
   
  +void DOMAttrMapImpl::cloneContent(const DOMAttrMapImpl *srcmap)
  +{
  +    if ((srcmap != 0) && (srcmap->fNodes != 0))
  +    {
  +        if (fNodes != 0)
  +            fNodes->reset();
  +        else
  +        {
  +            XMLSize_t size = srcmap->fNodes->size();
  +            if(size > 0) {
  +                DOMDocument *doc = fOwnerNode->getOwnerDocument();
  +                fNodes = new (doc) DOMNodeVector(doc, size);
  +            }
  +        }
  +
  +        for (XMLSize_t i = 0; i < srcmap->fNodes->size(); i++)
  +        {
  +            DOMNode *n = srcmap->fNodes->elementAt(i);
  +            DOMNode *clone = n->cloneNode(true);
  +            castToNodeImpl(clone)->isSpecified(castToNodeImpl(n)->isSpecified());
  +            castToNodeImpl(clone)->fOwnerNode = fOwnerNode;
  +            castToNodeImpl(clone)->isOwned(true);
  +            fNodes->addElement(clone);
  +        }
  +    }
  +}
  +
   DOMAttrMapImpl *DOMAttrMapImpl::cloneAttrMap(DOMNode *ownerNode_p)
   {
   	DOMAttrMapImpl *newmap = new (castToNodeImpl(ownerNode_p)->getOwnerDocument()) DOMAttrMapImpl(ownerNode_p);
  @@ -103,13 +132,146 @@
   	return newmap;
   }
   
  +void DOMAttrMapImpl::setReadOnly(bool readOnl, bool deep)
  +{
  +    // this->fReadOnly=readOnl;
  +    if(deep && fNodes!=0)
  +    {
  +        int sz = fNodes->size();
  +        for (int i=0; i<sz; ++i) {
  +            castToNodeImpl(fNodes->elementAt(i))->setReadOnly(readOnl, deep);
  +        }
  +    }
  +}
  +
  +bool DOMAttrMapImpl::readOnly() {
  +    return castToNodeImpl(fOwnerNode)->isReadOnly();
  +}
  +
  +int DOMAttrMapImpl::findNamePoint(const XMLCh *name) const
  +{
  +
  +    // Binary search
  +    int i=0;
  +    if(fNodes!=0)
  +    {
  +        int first=0,last=fNodes->size()-1;
  +
  +        while(first<=last)
  +        {
  +            i=(first+last)/2;
  +            int test = XMLString::compareString(name, fNodes->elementAt(i)->getNodeName());
  +            if(test==0)
  +                return i; // Name found
  +            else if(test<0)
  +                last=i-1;
  +            else
  +                first=i+1;
  +        }
  +        if(first>i) i=first;
  +    }
  +    /********************
  +    // Linear search
  +    int i = 0;
  +    if (fNodes != 0)
  +    for (i = 0; i < fNodes.size(); ++i)
  +    {
  +    int test = name.compareTo(((NodeImpl *) (fNodes.elementAt(i))).getNodeName());
  +    if (test == 0)
  +    return i;
  +    else
  +    if (test < 0)
  +    {
  +    break; // Found insertpoint
  +    }
  +    }
  +
  +    *******************/
  +    return -1 - i; // not-found has to be encoded.
  +}
  +
  +DOMNode * DOMAttrMapImpl::getNamedItem(const XMLCh *name) const
  +{
  +    int i=findNamePoint(name);
  +    return (i<0) ? 0 : fNodes->elementAt(i);
  +}
   
   DOMNode *DOMAttrMapImpl::setNamedItem(DOMNode *arg)
   {
       if (arg->getNodeType() != DOMNode::ATTRIBUTE_NODE)
           throw DOMException(DOMException::HIERARCHY_REQUEST_ERR, 0);
   
  -    return DOMNamedNodeMapImpl::setNamedItem(arg);
  +    DOMDocument *doc = fOwnerNode->getOwnerDocument();
  +    DOMNodeImpl *argImpl = castToNodeImpl(arg);
  +    if(argImpl->getOwnerDocument() != doc)
  +        throw DOMException(DOMException::WRONG_DOCUMENT_ERR,0);
  +    if (this->readOnly())
  +        throw DOMException(DOMException::NO_MODIFICATION_ALLOWED_ERR, 0);
  +    if ((arg->getNodeType() == DOMNode::ATTRIBUTE_NODE) && argImpl->isOwned() && (argImpl->fOwnerNode != fOwnerNode))
  +        throw DOMException(DOMException::INUSE_ATTRIBUTE_ERR,0);
  +
  +    argImpl->fOwnerNode = fOwnerNode;
  +    argImpl->isOwned(true);
  +    int i=findNamePoint(arg->getNodeName());
  +    DOMNode * previous=0;
  +    if(i>=0)
  +    {
  +        previous = fNodes->elementAt(i);
  +        fNodes->setElementAt(arg,i);
  +    }
  +    else
  +    {
  +        i=-1-i; // Insert point (may be end of list)
  +        if(0==fNodes)
  +        {
  +            fNodes=new (doc) DOMNodeVector(doc);
  +        }
  +        fNodes->insertElementAt(arg,i);
  +    }
  +    if (previous != 0) {
  +        castToNodeImpl(previous)->fOwnerNode = fOwnerNode->getOwnerDocument();
  +        castToNodeImpl(previous)->isOwned(false);
  +    }
  +
  +    return previous;
  +}
  +
  +//Introduced in DOM Level 2
  +
  +int DOMAttrMapImpl::findNamePoint(const XMLCh *namespaceURI,
  +	const XMLCh *localName) const
  +{
  +    if (fNodes == 0)
  +	return -1;
  +    // This is a linear search through the same fNodes Vector.
  +    // The Vector is sorted on the DOM Level 1 nodename.
  +    // The DOM Level 2 NS keys are namespaceURI and Localname,
  +    // so we must linear search thru it.
  +    // In addition, to get this to work with fNodes without any namespace
  +    // (namespaceURI and localNames are both 0) we then use the nodeName
  +    // as a secondary key.
  +    int i, len = fNodes -> size();
  +    for (i = 0; i < len; ++i) {
  +        DOMNode *node = fNodes -> elementAt(i);
  +        const XMLCh * nNamespaceURI = node->getNamespaceURI();
  +        const XMLCh * nLocalName = node->getLocalName();
  +        if (!XMLString::equals(nNamespaceURI, namespaceURI))    //URI not match
  +            continue;
  +        else {
  +            if (XMLString::equals(localName, nLocalName)
  +                ||
  +                (nLocalName == 0 && XMLString::equals(localName, node->getNodeName())))
  +                return i;
  +        }
  +    }
  +    return -1;	//not found
  +}
  +
  +DOMNode *DOMAttrMapImpl::getNamedItemNS(const XMLCh *namespaceURI,
  +	const XMLCh *localName) const
  +{
  +    int i = findNamePoint(namespaceURI, localName);
  +    return i < 0 ? 0 : fNodes -> elementAt(i);
   }
   
   DOMNode *DOMAttrMapImpl::setNamedItemNS(DOMNode* arg)
  @@ -117,12 +279,53 @@
       if (arg->getNodeType() != DOMNode::ATTRIBUTE_NODE)
           throw DOMException(DOMException::HIERARCHY_REQUEST_ERR, 0);
   
  -    return DOMNamedNodeMapImpl::setNamedItemNS(arg);
  +    DOMDocument *doc = fOwnerNode->getOwnerDocument();
  +    DOMNodeImpl *argImpl = castToNodeImpl(arg);
  +    if (argImpl->getOwnerDocument() != doc)
  +        throw DOMException(DOMException::WRONG_DOCUMENT_ERR,0);
  +    if (this->readOnly())
  +        throw DOMException(DOMException::NO_MODIFICATION_ALLOWED_ERR, 0);
  +    if (argImpl->isOwned())
  +        throw DOMException(DOMException::INUSE_ATTRIBUTE_ERR,0);
  +
  +    argImpl->fOwnerNode = fOwnerNode;
  +    argImpl->isOwned(true);
  +    int i=findNamePoint(arg->getNamespaceURI(), arg->getLocalName());
  +    DOMNode *previous=0;
  +    if(i>=0) {
  +        previous = fNodes->elementAt(i);
  +        fNodes->setElementAt(arg,i);
  +    } else {
  +        i=findNamePoint(arg->getNodeName()); // Insert point (may be end of list)
  +        if (i<0)
  +          i = -1 - i;
  +        if(0==fNodes)
  +            fNodes=new (doc) DOMNodeVector(doc);
  +        fNodes->insertElementAt(arg,i);
  +    }
  +    if (previous != 0) {
  +        castToNodeImpl(previous)->fOwnerNode = fOwnerNode->getOwnerDocument();
  +        castToNodeImpl(previous)->isOwned(false);
  +    }
  +
  +    return previous;
   }
   
   DOMNode *DOMAttrMapImpl::removeNamedItem(const XMLCh *name)
   {
  -    DOMNode* removed = DOMNamedNodeMapImpl::removeNamedItem(name);
  +    if (this->readOnly())
  +        throw DOMException(
  +            DOMException::NO_MODIFICATION_ALLOWED_ERR, 0);
  +    int i=findNamePoint(name);
  +    DOMNode *removed = 0;
  +
  +    if(i<0)
  +        throw DOMException(DOMException::NOT_FOUND_ERR, 0);
  +
  +    removed = fNodes->elementAt(i);
  +    fNodes->removeElementAt(i);
  +    castToNodeImpl(removed)->fOwnerNode = fOwnerNode->getOwnerDocument();
  +    castToNodeImpl(removed)->isOwned(false);
   
       // Replace it if it had a default value
       // (DOM spec level 1 - Element Interface)
  @@ -142,7 +345,17 @@
   
   DOMNode *DOMAttrMapImpl::removeNamedItemNS(const XMLCh *namespaceURI, const XMLCh *localName)
   {
  -    DOMNode* removed = DOMNamedNodeMapImpl::removeNamedItemNS(namespaceURI, localName);
  +    if (this->readOnly())
  +        throw DOMException(
  +        DOMException::NO_MODIFICATION_ALLOWED_ERR, 0);
  +    int i = findNamePoint(namespaceURI, localName);
  +    if (i < 0)
  +        throw DOMException(DOMException::NOT_FOUND_ERR, 0);
  +
  +    DOMNode * removed = fNodes -> elementAt(i);
  +    fNodes -> removeElementAt(i);	//remove n from nodes
  +    castToNodeImpl(removed)->fOwnerNode = fOwnerNode->getOwnerDocument();
  +    castToNodeImpl(removed)->isOwned(false);
   
       // Replace it if it had a default value
       // (DOM spec level 2 - Element Interface)
  @@ -165,7 +378,17 @@
   // avoid calling findNamePoint again if the index is already known
   DOMNode * DOMAttrMapImpl::removeNamedItemAt(XMLSize_t index)
   {
  -    DOMNode* removed = DOMNamedNodeMapImpl::removeNamedItemAt(index);
  +    if (this->readOnly())
  +        throw DOMException(
  +            DOMException::NO_MODIFICATION_ALLOWED_ERR, 0);
  +
  +    DOMNode *removed = item(index);
  +    if(!removed)
  +        throw DOMException(DOMException::NOT_FOUND_ERR, 0);
  +
  +    fNodes->removeElementAt(index);
  +    castToNodeImpl(removed)->fOwnerNode = fOwnerNode->getOwnerDocument();
  +    castToNodeImpl(removed)->isOwned(false);
   
       // Replace it if it had a default value
       // (DOM spec level 1 - Element Interface)
  @@ -247,6 +470,18 @@
               setNamedItem(attr);
       }
   } // moveSpecifiedAttributes(AttributeMap):void
  +
  +XMLSize_t DOMAttrMapImpl::getLength() const
  +{
  +    return (fNodes != 0) ? fNodes->size() : 0;
  +}
  +
  +DOMNode * DOMAttrMapImpl::item(XMLSize_t index) const
  +{
  +    return (fNodes != 0 && index < fNodes->size()) ?
  +        fNodes->elementAt(index) : 0;
  +}
  +
   
   XERCES_CPP_NAMESPACE_END
   
  
  
  
  1.7       +31 -12    xml-xerces/c/src/xercesc/dom/impl/DOMAttrMapImpl.hpp
  
  Index: DOMAttrMapImpl.hpp
  ===================================================================
  RCS file: /home/cvs/xml-xerces/c/src/xercesc/dom/impl/DOMAttrMapImpl.hpp,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- DOMAttrMapImpl.hpp	29 Jan 2004 11:44:26 -0000	1.6
  +++ DOMAttrMapImpl.hpp	8 Mar 2004 13:18:57 -0000	1.7
  @@ -72,16 +72,23 @@
   //
   
   #include <xercesc/util/XercesDefs.hpp>
  -#include "DOMNamedNodeMapImpl.hpp"
  +#include <xercesc/dom/DOMNamedNodeMap.hpp>
   
   XERCES_CPP_NAMESPACE_BEGIN
   
  -
  +class DOMNodeVector;
   class DOMNode;
  -class DOMNamedNodeMap;
   
  -class CDOM_EXPORT DOMAttrMapImpl : public DOMNamedNodeMapImpl
  +class CDOM_EXPORT DOMAttrMapImpl : public DOMNamedNodeMap
   {
  +protected:
  +    DOMNodeVector*    fNodes;
  +    DOMNode*          fOwnerNode;       // the node this map belongs to
  +
  +    virtual void	cloneContent(const DOMAttrMapImpl *srcmap);
  +
  +    bool            readOnly();  // revisit.  Look at owner node read-only.
  +
   private:
       bool attrDefaults;
   
  @@ -91,19 +98,31 @@
       // revisit.  This "copy" constructor is used for cloning an Element with Attributes,
       //                and for setting up default attributes.  It's probably not right
       //                for one or the other or both.
  -    DOMAttrMapImpl(DOMNode *ownerNod, const DOMNamedNodeMapImpl *defaults);
  +    DOMAttrMapImpl(DOMNode *ownerNod, const DOMAttrMapImpl *defaults);
       DOMAttrMapImpl();
   
       virtual ~DOMAttrMapImpl();
       virtual DOMAttrMapImpl *cloneAttrMap(DOMNode *ownerNode);
       virtual bool hasDefaults();
       virtual void hasDefaults(bool value);
  -
  -    virtual DOMNode *setNamedItem(DOMNode *arg);
  -    virtual DOMNode *setNamedItemNS(DOMNode *arg);
  -    virtual DOMNode *removeNamedItem(const XMLCh *name);
  -    virtual DOMNode *removeNamedItemNS(const XMLCh *namespaceURI, const XMLCh *localName);
  -    virtual DOMNode *removeNamedItemAt(XMLSize_t index);
  +    virtual int             findNamePoint(const XMLCh *name) const;
  +    virtual int             findNamePoint(const XMLCh *namespaceURI,
  +	                                       const XMLCh *localName) const;
  +    virtual DOMNode*        removeNamedItemAt(XMLSize_t index);
  +    virtual void            setReadOnly(bool readOnly, bool deep);
  +
  +
  +    virtual XMLSize_t       getLength() const;
  +    virtual DOMNode*        item(XMLSize_t index) const;
  +
  +    virtual DOMNode*        getNamedItem(const XMLCh *name) const;
  +    virtual DOMNode*        setNamedItem(DOMNode *arg);
  +    virtual DOMNode*        removeNamedItem(const XMLCh *name);
  +    
  +    virtual DOMNode*        getNamedItemNS(const XMLCh *namespaceURI,
  +	                                        const XMLCh *localName) const;
  +    virtual DOMNode*        setNamedItemNS(DOMNode *arg);
  +    virtual DOMNode*        removeNamedItemNS(const XMLCh *namespaceURI, const XMLCh *localName);
   
       void reconcileDefaultAttributes(const DOMAttrMapImpl* defaults);
       void moveSpecifiedAttributes(DOMAttrMapImpl* srcmap);
  
  
  
  1.11      +158 -235  xml-xerces/c/src/xercesc/dom/impl/DOMNamedNodeMapImpl.cpp
  
  Index: DOMNamedNodeMapImpl.cpp
  ===================================================================
  RCS file: /home/cvs/xml-xerces/c/src/xercesc/dom/impl/DOMNamedNodeMapImpl.cpp,v
  retrieving revision 1.10
  retrieving revision 1.11
  diff -u -r1.10 -r1.11
  --- DOMNamedNodeMapImpl.cpp	29 Jan 2004 11:44:26 -0000	1.10
  +++ DOMNamedNodeMapImpl.cpp	8 Mar 2004 13:18:57 -0000	1.11
  @@ -75,17 +75,16 @@
   
   DOMNamedNodeMapImpl::DOMNamedNodeMapImpl(DOMNode *ownerNod)
   {
  -    this->fOwnerNode=ownerNod;
  -    this->fNodes = 0;
  +    fOwnerNode=ownerNod;
  +    memset(fBuckets,0,MAP_SIZE*sizeof(DOMNodeVector*));
   }
   
  -
  -
   DOMNamedNodeMapImpl::~DOMNamedNodeMapImpl()
   {
   }
   
  -bool DOMNamedNodeMapImpl::readOnly() {
  +bool DOMNamedNodeMapImpl::readOnly() 
  +{
       return castToNodeImpl(fOwnerNode)->isReadOnly();
   }
   
  @@ -94,118 +93,61 @@
       DOMDocumentImpl *doc = (DOMDocumentImpl *)(castToNodeImpl(ownerNod)->getOwnerDocument());
       DOMNamedNodeMapImpl *newmap = new (doc) DOMNamedNodeMapImpl(ownerNod);
   	
  -    if (fNodes != 0)
  -    {
  -        newmap->fNodes = new (doc) DOMNodeVector(doc, fNodes->size());
  -        for (XMLSize_t i = 0; i < fNodes->size(); ++i)
  -        {
  -            DOMNode *n = fNodes->elementAt(i)->cloneNode(true);
  -			castToNodeImpl(n)->isSpecified(castToNodeImpl(fNodes->elementAt(i))->isSpecified());
  -            castToNodeImpl(n)->fOwnerNode = ownerNod;
  -            castToNodeImpl(n)->isOwned(true);
  -            newmap->fNodes->addElement(n);
  +    for(int index=0;index<MAP_SIZE;index++)
  +        if (fBuckets[index] != 0) {
  +            XMLSize_t size=fBuckets[index]->size();
  +            newmap->fBuckets[index] = new (doc) DOMNodeVector(doc, size);
  +            for (XMLSize_t i = 0; i < size; ++i) {
  +                DOMNode *s = fBuckets[index]->elementAt(i);
  +                DOMNode *n = s->cloneNode(true);
  +			    castToNodeImpl(n)->isSpecified(castToNodeImpl(s)->isSpecified());
  +                castToNodeImpl(n)->fOwnerNode = ownerNod;
  +                castToNodeImpl(n)->isOwned(true);
  +                newmap->fBuckets[index]->addElement(n);
  +            }
           }
  -    }
   
       return newmap;
   }
   
   
  -//
  -//  removeAll - This function removes all elements from a named node map.
  -//              It is called from the destructors for Elements and DocumentTypes,
  -//              to remove the contents when the owning Element or DocType goes
  -//              away.  The empty NamedNodeMap may persist if the user code
  -//              has a reference to it.
  -//
  -//              AH Revist - the empty map should be made read-only, since
  -//              adding it was logically part of the [Element, DocumentType]
  -//              that has been deleted, and adding anything new to it would
  -//              be meaningless, and almost certainly an error.
  -//
  -void DOMNamedNodeMapImpl::removeAll()
  +XMLSize_t DOMNamedNodeMapImpl::getLength() const
   {
  -    if (fNodes)
  -    {
  -
  -        for (int i=fNodes->size()-1; i>=0; i--)
  -        {
  -            DOMNode *n = fNodes->elementAt(i);
  -            castToNodeImpl(n)->fOwnerNode = fOwnerNode->getOwnerDocument();
  -            castToNodeImpl(n)->isOwned(false);
  -        }
  -        // We have no way to delete fNodes.  Leave it around; we can re-use
  -        //  it if the owner node ever adds new attributes (or whatevers)
  -    }
  +    XMLSize_t count=0;
  +    for(int index=0;index<MAP_SIZE;index++)
  +        count+=(fBuckets[index]==0?0:fBuckets[index]->size());
  +    return count;
   }
   
  -
  -
  -int DOMNamedNodeMapImpl::findNamePoint(const XMLCh *name) const
  +DOMNode * DOMNamedNodeMapImpl::item(XMLSize_t index) const
   {
  -
  -    // Binary search
  -    int i=0;
  -    if(fNodes!=0)
  -    {
  -        int first=0,last=fNodes->size()-1;
  -
  -        while(first<=last)
  -        {
  -            i=(first+last)/2;
  -            int test = XMLString::compareString(name, fNodes->elementAt(i)->getNodeName());
  -            if(test==0)
  -                return i; // Name found
  -            else if(test<0)
  -                last=i-1;
  -            else
  -                first=i+1;
  -        }
  -        if(first>i) i=first;
  -    }
  -    /********************
  -    // Linear search
  -    int i = 0;
  -    if (fNodes != 0)
  -    for (i = 0; i < fNodes.size(); ++i)
  -    {
  -    int test = name.compareTo(((NodeImpl *) (fNodes.elementAt(i))).getNodeName());
  -    if (test == 0)
  -    return i;
  -    else
  -    if (test < 0)
  -    {
  -    break; // Found insertpoint
  -    }
  +    XMLSize_t count=0;
  +    for(XMLSize_t i=0;i<MAP_SIZE;i++) {
  +        if(fBuckets[i]==0)
  +            continue;
  +        XMLSize_t thisBucket=fBuckets[i]->size();
  +        if(index>=count && index<(count+thisBucket))
  +            return fBuckets[i]->elementAt(index-count);
       }
  -
  -    *******************/
  -    return -1 - i; // not-found has to be encoded.
  -}
  -
  -
  -
  -
  -
  -XMLSize_t DOMNamedNodeMapImpl::getLength() const
  -{
  -    return (fNodes != 0) ? fNodes->size() : 0;
  +    return NULL;
   }
   
   
  -
   DOMNode * DOMNamedNodeMapImpl::getNamedItem(const XMLCh *name) const
   {
  -    int i=findNamePoint(name);
  -    return (i<0) ? 0 : fNodes->elementAt(i);
  -}
  -
  +    unsigned int hash=XMLString::hash(name,MAP_SIZE);
  +    if(fBuckets[hash]==0)
  +        return 0;
   
  +    int i = 0;
  +    int size = fBuckets[hash]->size();
  +    for (i = 0; i < size; ++i) {
  +        DOMNode *n=fBuckets[hash]->elementAt(i);
  +        if(XMLString::equals(name,n->getNodeName()))
  +            return n;
  +    }
   
  -DOMNode * DOMNamedNodeMapImpl::item(XMLSize_t index) const
  -{
  -    return (fNodes != 0 && index < fNodes->size()) ?
  -        fNodes->elementAt(index) : 0;
  +    return 0;
   }
   
   
  @@ -221,17 +163,25 @@
       if (this->readOnly())
           throw DOMException(
               DOMException::NO_MODIFICATION_ALLOWED_ERR, 0);
  -    int i=findNamePoint(name);
  -    DOMNode *n = 0;
  -
  -    if(i<0)
  +    
  +    unsigned int hash=XMLString::hash(name,MAP_SIZE);
  +    if(fBuckets[hash]==0)
           throw DOMException(DOMException::NOT_FOUND_ERR, 0);
   
  -    n = fNodes->elementAt(i);
  -    fNodes->removeElementAt(i);
  -    castToNodeImpl(n)->fOwnerNode = fOwnerNode->getOwnerDocument();
  -    castToNodeImpl(n)->isOwned(false);
  -    return n;
  +    int i = 0;
  +    int size = fBuckets[hash]->size();
  +    for (i = 0; i < size; ++i) {
  +        DOMNode *n=fBuckets[hash]->elementAt(i);
  +        if(XMLString::equals(name,n->getNodeName())) {
  +            fBuckets[hash]->removeElementAt(i);
  +            castToNodeImpl(n)->fOwnerNode = fOwnerNode->getOwnerDocument();
  +            castToNodeImpl(n)->isOwned(false);
  +            return n;
  +        }
  +    }
  +
  +    throw DOMException(DOMException::NOT_FOUND_ERR, 0);
  +    return 0;
   }
   
   
  @@ -258,39 +208,38 @@
   
       argImpl->fOwnerNode = fOwnerNode;
       argImpl->isOwned(true);
  -    int i=findNamePoint(arg->getNodeName());
  -    DOMNode * previous=0;
  -    if(i>=0)
  -    {
  -        previous = fNodes->elementAt(i);
  -        fNodes->setElementAt(arg,i);
  -    }
  -    else
  -    {
  -        i=-1-i; // Insert point (may be end of list)
  -        if(0==fNodes)
  -        {
  -            fNodes=new (doc) DOMNodeVector(doc);
  +
  +    const XMLCh* name=arg->getNodeName();
  +    unsigned int hash=XMLString::hash(name,MAP_SIZE);
  +    if(fBuckets[hash]==0)
  +        fBuckets[hash] = new (doc) DOMNodeVector(doc, 3);
  +
  +    int i = 0;
  +    int size = fBuckets[hash]->size();
  +    for (i = 0; i < size; ++i) {
  +        DOMNode *n=fBuckets[hash]->elementAt(i);
  +        if(XMLString::equals(name,n->getNodeName())) {
  +            fBuckets[hash]->setElementAt(arg,i);
  +            castToNodeImpl(n)->fOwnerNode = fOwnerNode->getOwnerDocument();
  +            castToNodeImpl(n)->isOwned(false);
  +            return n;
           }
  -        fNodes->insertElementAt(arg,i);
  -    }
  -    if (previous != 0) {
  -        castToNodeImpl(previous)->fOwnerNode = fOwnerNode->getOwnerDocument();
  -        castToNodeImpl(previous)->isOwned(false);
       }
  -
  -    return previous;
  +    fBuckets[hash]->addElement(arg);
  +    return 0;
   }
   
   
   void DOMNamedNodeMapImpl::setReadOnly(bool readOnl, bool deep)
   {
       // this->fReadOnly=readOnl;
  -    if(deep && fNodes!=0)
  -    {
  -        int sz = fNodes->size();
  -        for (int i=0; i<sz; ++i) {
  -            castToNodeImpl(fNodes->elementAt(i))->setReadOnly(readOnl, deep);
  +    if(deep) {
  +        for (int index = 0; index < MAP_SIZE; index++) {
  +            if(fBuckets[index]==0)
  +                continue;
  +            int sz = fBuckets[index]->size();
  +            for (int i=0; i<sz; ++i)
  +                castToNodeImpl(fBuckets[index]->elementAt(i))->setReadOnly(readOnl, deep);
           }
       }
   }
  @@ -298,41 +247,31 @@
   
   //Introduced in DOM Level 2
   
  -int DOMNamedNodeMapImpl::findNamePoint(const XMLCh *namespaceURI,
  -	const XMLCh *localName) const
  +DOMNode *DOMNamedNodeMapImpl::getNamedItemNS(const XMLCh *namespaceURI, const XMLCh *localName) const
   {
  -    if (fNodes == 0)
  -	return -1;
  -    // This is a linear search through the same fNodes Vector.
  -    // The Vector is sorted on the DOM Level 1 nodename.
  -    // The DOM Level 2 NS keys are namespaceURI and Localname,
  -    // so we must linear search thru it.
  -    // In addition, to get this to work with fNodes without any namespace
  -    // (namespaceURI and localNames are both 0) we then use the nodeName
  -    // as a secondary key.
  -    int i, len = fNodes -> size();
  -    for (i = 0; i < len; ++i) {
  -        DOMNode *node = fNodes -> elementAt(i);
  -        const XMLCh * nNamespaceURI = node->getNamespaceURI();
  -        const XMLCh * nLocalName = node->getLocalName();
  -        if (!XMLString::equals(nNamespaceURI, namespaceURI))    //URI not match
  +    // the map is indexed using the full name of nodes; to search given a namespace and a local name
  +    // we have to do a linear search
  +    for (int index = 0; index < MAP_SIZE; index++) {
  +        if(fBuckets[index]==0)
               continue;
  -        else {
  -            if (XMLString::equals(localName, nLocalName)
  -                ||
  -                (nLocalName == 0 && XMLString::equals(localName, node->getNodeName())))
  -                return i;
  +
  +        int i = 0;
  +        int size = fBuckets[index]->size();
  +        for (i = 0; i < size; ++i) {
  +            DOMNode *n=fBuckets[index]->elementAt(i);
  +            const XMLCh * nNamespaceURI = n->getNamespaceURI();
  +            const XMLCh * nLocalName = n->getLocalName();
  +            if (!XMLString::equals(nNamespaceURI, namespaceURI))    //URI not match
  +                continue;
  +            else {
  +                if (XMLString::equals(localName, nLocalName)
  +                    ||
  +                    (nLocalName == 0 && XMLString::equals(localName, n->getNodeName())))
  +                    return n;
  +            }
           }
       }
  -    return -1;	//not found
  -}
  -
  -
  -DOMNode *DOMNamedNodeMapImpl::getNamedItemNS(const XMLCh *namespaceURI,
  -	const XMLCh *localName) const
  -{
  -    int i = findNamePoint(namespaceURI, localName);
  -    return i < 0 ? 0 : fNodes -> elementAt(i);
  +    return 0;
   }
   
   
  @@ -358,25 +297,37 @@
   
       argImpl->fOwnerNode = fOwnerNode;
       argImpl->isOwned(true);
  -    int i=findNamePoint(arg->getNamespaceURI(), arg->getLocalName());
  -    DOMNode *previous=0;
  -    if(i>=0) {
  -        previous = fNodes->elementAt(i);
  -        fNodes->setElementAt(arg,i);
  -    } else {
  -        i=findNamePoint(arg->getNodeName()); // Insert point (may be end of list)
  -        if (i<0)
  -          i = -1 - i;
  -        if(0==fNodes)
  -            fNodes=new (doc) DOMNodeVector(doc);
  -        fNodes->insertElementAt(arg,i);
  -    }
  -    if (previous != 0) {
  -        castToNodeImpl(previous)->fOwnerNode = fOwnerNode->getOwnerDocument();
  -        castToNodeImpl(previous)->isOwned(false);
  -    }
   
  -    return previous;
  +    const XMLCh* namespaceURI=arg->getNamespaceURI();
  +    const XMLCh* localName=arg->getLocalName();
  +    // the map is indexed using the full name of nodes; to search given a namespace and a local name
  +    // we have to do a linear search
  +    for (int index = 0; index < MAP_SIZE; index++) {
  +        if(fBuckets[index]==0)
  +            continue;
  +
  +        int i = 0;
  +        int size = fBuckets[index]->size();
  +        for (i = 0; i < size; ++i) {
  +            DOMNode *n=fBuckets[index]->elementAt(i);
  +            const XMLCh * nNamespaceURI = n->getNamespaceURI();
  +            const XMLCh * nLocalName = n->getLocalName();
  +            if (!XMLString::equals(nNamespaceURI, namespaceURI))    //URI not match
  +                continue;
  +            else {
  +                if (XMLString::equals(localName, nLocalName)
  +                    ||
  +                    (nLocalName == 0 && XMLString::equals(localName, n->getNodeName()))) {
  +                    fBuckets[index]->setElementAt(arg,i);
  +                    castToNodeImpl(n)->fOwnerNode = fOwnerNode->getOwnerDocument();
  +                    castToNodeImpl(n)->isOwned(false);
  +                    return n;
  +                }
  +            }
  +        }
  +    }
  +    // if not found, add it using the full name as key
  +    return setNamedItem(arg);
   }
   
   
  @@ -391,63 +342,35 @@
       if (this->readOnly())
           throw DOMException(
           DOMException::NO_MODIFICATION_ALLOWED_ERR, 0);
  -    int i = findNamePoint(namespaceURI, localName);
  -    if (i < 0)
  -        throw DOMException(DOMException::NOT_FOUND_ERR, 0);
  -
  -    DOMNode * n = fNodes -> elementAt(i);
  -    fNodes -> removeElementAt(i);	//remove n from nodes
  -    castToNodeImpl(n)->fOwnerNode = fOwnerNode->getOwnerDocument();
  -    castToNodeImpl(n)->isOwned(false);
  -    return n;
  -}
  -
   
  +    // the map is indexed using the full name of nodes; to search given a namespace and a local name
  +    // we have to do a linear search
  +    for (int index = 0; index < MAP_SIZE; index++) {
  +        if(fBuckets[index]==0)
  +            continue;
   
  -void DOMNamedNodeMapImpl::cloneContent(const DOMNamedNodeMapImpl *srcmap)
  -{
  -    if ((srcmap != 0) && (srcmap->fNodes != 0))
  -    {
  -        if (fNodes != 0)
  -            fNodes->reset();
  -        else
  -        {
  -            XMLSize_t size = srcmap->fNodes->size();
  -            if(size > 0) {
  -                DOMDocument *doc = fOwnerNode->getOwnerDocument();
  -                fNodes = new (doc) DOMNodeVector(doc, size);
  +        int i = 0;
  +        int size = fBuckets[index]->size();
  +        for (i = 0; i < size; ++i) {
  +            DOMNode *n=fBuckets[index]->elementAt(i);
  +            const XMLCh * nNamespaceURI = n->getNamespaceURI();
  +            const XMLCh * nLocalName = n->getLocalName();
  +            if (!XMLString::equals(nNamespaceURI, namespaceURI))    //URI not match
  +                continue;
  +            else {
  +                if (XMLString::equals(localName, nLocalName)
  +                    ||
  +                    (nLocalName == 0 && XMLString::equals(localName, n->getNodeName()))) {
  +                    fBuckets[index]->removeElementAt(i);
  +                    castToNodeImpl(n)->fOwnerNode = fOwnerNode->getOwnerDocument();
  +                    castToNodeImpl(n)->isOwned(false);
  +                    return n;
  +                }
               }
           }
  -
  -        for (XMLSize_t i = 0; i < srcmap->fNodes->size(); i++)
  -        {
  -            DOMNode *n = srcmap->fNodes->elementAt(i);
  -            DOMNode *clone = n->cloneNode(true);
  -            castToNodeImpl(clone)->isSpecified(castToNodeImpl(n)->isSpecified());
  -            castToNodeImpl(clone)->fOwnerNode = fOwnerNode;
  -            castToNodeImpl(clone)->isOwned(true);
  -            fNodes->addElement(clone);
  -        }
       }
  -}
  -
  -
  -// remove the name using index
  -// avoid calling findNamePoint again if the index is already known
  -DOMNode * DOMNamedNodeMapImpl::removeNamedItemAt(XMLSize_t index)
  -{
  -    if (this->readOnly())
  -        throw DOMException(
  -            DOMException::NO_MODIFICATION_ALLOWED_ERR, 0);
  -
  -    DOMNode *n = item(index);
  -    if(!n)
  -        throw DOMException(DOMException::NOT_FOUND_ERR, 0);
  -
  -    fNodes->removeElementAt(index);
  -    castToNodeImpl(n)->fOwnerNode = fOwnerNode->getOwnerDocument();
  -    castToNodeImpl(n)->isOwned(false);
  -    return n;
  +    throw DOMException(DOMException::NOT_FOUND_ERR, 0);
  +    return 0;
   }
   
   XERCES_CPP_NAMESPACE_END
  
  
  
  1.6       +7 -16     xml-xerces/c/src/xercesc/dom/impl/DOMNamedNodeMapImpl.hpp
  
  Index: DOMNamedNodeMapImpl.hpp
  ===================================================================
  RCS file: /home/cvs/xml-xerces/c/src/xercesc/dom/impl/DOMNamedNodeMapImpl.hpp,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- DOMNamedNodeMapImpl.hpp	29 Jan 2004 11:44:26 -0000	1.5
  +++ DOMNamedNodeMapImpl.hpp	8 Mar 2004 13:18:57 -0000	1.6
  @@ -78,20 +78,15 @@
   
   class       DOMNodeVector;
   class       DOMNode;
  -class       DOMDocument;
  -
   
  +#define MAP_SIZE    193
   
   class CDOM_EXPORT DOMNamedNodeMapImpl: public DOMNamedNodeMap {
   protected:
  -    DOMNodeVector*    fNodes;
  +    DOMNodeVector*    fBuckets[MAP_SIZE];
       DOMNode*          fOwnerNode;       // the node this map belongs to
       //bool             fReadOnly;     // revisit - flag on owner node instead?
   
  -    friend class DOMDocumentImpl;
  -
  -    virtual void	cloneContent(const DOMNamedNodeMapImpl *srcmap);
  -
       bool            readOnly();  // revisit.  Look at owner node read-only.
   
   public:
  @@ -99,19 +94,15 @@
   
       virtual                 ~DOMNamedNodeMapImpl();
       virtual DOMNamedNodeMapImpl *cloneMap(DOMNode *ownerNode);
  -    virtual int             findNamePoint(const XMLCh *name) const;
  +    virtual void            setReadOnly(bool readOnly, bool deep);
  +
       virtual XMLSize_t       getLength() const;
  -    virtual DOMNode*        getNamedItem(const XMLCh *name) const;
       virtual DOMNode*        item(XMLSize_t index) const;
  -    virtual void            removeAll();
  -    virtual DOMNode*        removeNamedItem(const XMLCh *name);
  -    virtual DOMNode*        removeNamedItemAt(XMLSize_t index);
  +    virtual DOMNode*        getNamedItem(const XMLCh *name) const;
       virtual DOMNode*        setNamedItem(DOMNode *arg);
  -    virtual void            setReadOnly(bool readOnly, bool deep);
  +    virtual DOMNode*        removeNamedItem(const XMLCh *name);
   
       //Introduced in DOM Level 2
  -    virtual int             findNamePoint(const XMLCh *namespaceURI,
  -	                                       const XMLCh *localName) const;
       virtual DOMNode*        getNamedItemNS(const XMLCh *namespaceURI,
   	                                        const XMLCh *localName) const;
       virtual DOMNode*        setNamedItemNS(DOMNode *arg);
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: xerces-cvs-unsubscribe@xml.apache.org
For additional commands, e-mail: xerces-cvs-help@xml.apache.org