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