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: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]