diff --git a/src/dom/DOM_NamedNodeMap.cpp b/src/dom/DOM_NamedNodeMap.cpp index 9a7ad9a0fc3b76373034c23b357ed290785c3787..f3c0b478c69522c684eec7d786dfa7ef5f9628ab 100644 --- a/src/dom/DOM_NamedNodeMap.cpp +++ b/src/dom/DOM_NamedNodeMap.cpp @@ -56,6 +56,10 @@ /* * $Log$ + * Revision 1.8 2000/06/07 22:49:40 andyh + * Memory usage reduction: DOM NamedNodeMaps for attributes are allocated + * only for elements that actually have attributes. By Joe Polastre. + * * Revision 1.7 2000/03/11 03:19:12 chchou * Fix bug # 19, add const keyword to API * @@ -87,32 +91,49 @@ #include "DOM_Node.hpp" #include "DOM_NamedNodeMap.hpp" #include "NamedNodeMapImpl.hpp" +#include "ElementImpl.hpp" + + +const unsigned short DOM_NamedNodeMap::NNM_ELEMENT = 0; +const unsigned short DOM_NamedNodeMap::NNM_OTHER = 1; DOM_NamedNodeMap::DOM_NamedNodeMap() { - fImpl = null; + fImpl = 0; + flagElem = NNM_OTHER; }; DOM_NamedNodeMap::DOM_NamedNodeMap(const DOM_NamedNodeMap & other) { this->fImpl = other.fImpl; - NamedNodeMapImpl::addRef(fImpl); + this->flagElem = other.flagElem; + (other.flagElem == NNM_ELEMENT) ? NodeImpl::addRef((NodeImpl *)fImpl) : + NamedNodeMapImpl::addRef((NamedNodeMapImpl *)fImpl); }; DOM_NamedNodeMap::DOM_NamedNodeMap(NamedNodeMapImpl *impl) { - fImpl = impl; - NamedNodeMapImpl::addRef(fImpl); + fImpl = impl; + flagElem = NNM_OTHER; + if (impl != null) + NamedNodeMapImpl::addRef((NamedNodeMapImpl *)fImpl); }; +DOM_NamedNodeMap::DOM_NamedNodeMap(NodeImpl *impl) +{ + fImpl = impl; + flagElem = NNM_ELEMENT; + NodeImpl::addRef((NodeImpl *)fImpl); +} DOM_NamedNodeMap::~DOM_NamedNodeMap() { - NamedNodeMapImpl::removeRef(fImpl); + (flagElem == NNM_OTHER) ? NamedNodeMapImpl::removeRef((NamedNodeMapImpl *)fImpl) : + NodeImpl::removeRef((NodeImpl *)fImpl); }; bool DOM_NamedNodeMap::operator == (const DOM_NamedNodeMap &other) const @@ -143,9 +164,13 @@ DOM_NamedNodeMap & DOM_NamedNodeMap::operator = (const DOM_NamedNodeMap & other) { if (this->fImpl != other.fImpl) { - NamedNodeMapImpl::removeRef(fImpl); + // update reference counts and change pointers + (flagElem == NNM_OTHER) ? NamedNodeMapImpl::removeRef((NamedNodeMapImpl *)fImpl) : NodeImpl::removeRef((NodeImpl *)fImpl); + this->fImpl = other.fImpl; - NamedNodeMapImpl::addRef(fImpl); + this->flagElem = other.flagElem; + + (flagElem == NNM_OTHER) ? NamedNodeMapImpl::addRef((NamedNodeMapImpl *)fImpl) : NodeImpl::addRef((NodeImpl *)fImpl); } return *this; }; @@ -153,39 +178,46 @@ DOM_NamedNodeMap & DOM_NamedNodeMap::operator = (const DOM_NamedNodeMap & other) DOM_NamedNodeMap & DOM_NamedNodeMap::operator = (const DOM_NullPtr *other) { - NamedNodeMapImpl::removeRef(fImpl); + + (flagElem == NNM_OTHER) ? NamedNodeMapImpl::removeRef((NamedNodeMapImpl *)fImpl) : NodeImpl::removeRef((NodeImpl *)fImpl); this->fImpl = 0; + this->flagElem = NNM_OTHER; return *this; }; DOM_Node DOM_NamedNodeMap::getNamedItem(const DOMString &name) const { - return DOM_Node(fImpl->getNamedItem(name)); + return (flagElem == NNM_OTHER) ? DOM_Node(((NamedNodeMapImpl *)fImpl)->getNamedItem(name)) : + DOM_Node(((ElementImpl *)fImpl)->NNM_getNamedItem(name)); }; DOM_Node DOM_NamedNodeMap::setNamedItem(DOM_Node arg) { - return DOM_Node(fImpl->setNamedItem(arg.fImpl)); + return (flagElem == NNM_OTHER) ? DOM_Node(((NamedNodeMapImpl *)fImpl)->setNamedItem(arg.fImpl)) : + DOM_Node(((ElementImpl *)fImpl)->NNM_setNamedItem(arg.fImpl)); }; DOM_Node DOM_NamedNodeMap::removeNamedItem(const DOMString &name) { - return DOM_Node(fImpl->removeNamedItem(name)); + return (flagElem == NNM_OTHER) ? DOM_Node(((NamedNodeMapImpl *)fImpl)->removeNamedItem(name)) : + DOM_Node(((ElementImpl *)fImpl)->NNM_removeNamedItem(name)); }; DOM_Node DOM_NamedNodeMap::item(unsigned int index) const { - return DOM_Node(fImpl->item(index)); + return (flagElem == NNM_OTHER) ? DOM_Node(((NamedNodeMapImpl *)fImpl)->item(index)) : + DOM_Node(((ElementImpl *)fImpl)->NNM_item(index)); }; unsigned int DOM_NamedNodeMap::getLength() const { - return fImpl->getLength(); + return (flagElem == NNM_OTHER) ? ((NamedNodeMapImpl *)fImpl)->getLength() : + ((ElementImpl *)fImpl)->NNM_getLength(); }; @@ -194,16 +226,19 @@ unsigned int DOM_NamedNodeMap::getLength() const DOM_Node DOM_NamedNodeMap::getNamedItemNS(const DOMString &namespaceURI, const DOMString &localName) { - return DOM_Node(fImpl->getNamedItemNS(namespaceURI, localName)); + return (flagElem == NNM_OTHER) ? DOM_Node(((NamedNodeMapImpl *)fImpl)->getNamedItemNS(namespaceURI, localName)) : + DOM_Node(((ElementImpl *)fImpl)->NNM_getNamedItemNS(namespaceURI, localName)); } DOM_Node DOM_NamedNodeMap::setNamedItemNS(DOM_Node arg) { - return DOM_Node(fImpl->setNamedItemNS(arg.fImpl)); + return (flagElem == NNM_OTHER) ? DOM_Node(((NamedNodeMapImpl *)fImpl)->setNamedItemNS(arg.fImpl)) : + DOM_Node(((ElementImpl *)fImpl)->NNM_setNamedItemNS(arg.fImpl)); } DOM_Node DOM_NamedNodeMap::removeNamedItemNS(const DOMString &namespaceURI, const DOMString &localName) { - return DOM_Node(fImpl->removeNamedItemNS(namespaceURI, localName)); + return (flagElem == NNM_OTHER) ? DOM_Node(((NamedNodeMapImpl *)fImpl)->removeNamedItemNS(namespaceURI, localName)) : + DOM_Node(((ElementImpl *)fImpl)->NNM_removeNamedItemNS(namespaceURI, localName)); } diff --git a/src/dom/DOM_NamedNodeMap.hpp b/src/dom/DOM_NamedNodeMap.hpp index 9c8ae74f0d2acb53b8c089e6b7adf0915422ad2e..9752ec4961e453f1cd9daa5db3c64026e3c31f57 100644 --- a/src/dom/DOM_NamedNodeMap.hpp +++ b/src/dom/DOM_NamedNodeMap.hpp @@ -56,6 +56,10 @@ /* * $Log$ + * Revision 1.13 2000/06/07 22:49:40 andyh + * Memory usage reduction: DOM NamedNodeMaps for attributes are allocated + * only for elements that actually have attributes. By Joe Polastre. + * * Revision 1.12 2000/03/11 03:19:13 chchou * Fix bug # 19, add const keyword to API * @@ -124,7 +128,11 @@ class NamedNodeMapImpl; */ class CDOM_EXPORT DOM_NamedNodeMap { private: - NamedNodeMapImpl *fImpl; + void *fImpl; + short flagElem; + + static const unsigned short NNM_ELEMENT; + static const unsigned short NNM_OTHER; public: /** @name Constructors and assignment operator */ @@ -384,6 +392,7 @@ public: protected: DOM_NamedNodeMap(NamedNodeMapImpl *impl); + DOM_NamedNodeMap(NodeImpl *impl); friend class DOM_DocumentType; friend class DOM_Node; diff --git a/src/dom/DOM_Node.cpp b/src/dom/DOM_Node.cpp index a17e6b698dbdbe91d1d3cfce3e0c0f504df3f7a9..95eab62438f475cd0ee177566ae3dc68f7f8f4e7 100644 --- a/src/dom/DOM_Node.cpp +++ b/src/dom/DOM_Node.cpp @@ -56,6 +56,10 @@ /* * $Log$ + * Revision 1.6 2000/06/07 22:49:40 andyh + * Memory usage reduction: DOM NamedNodeMaps for attributes are allocated + * only for elements that actually have attributes. By Joe Polastre. + * * Revision 1.5 2000/03/02 19:53:56 roddey * This checkin includes many changes done while waiting for the * 1.1.0 code to be finished. I can't list them all here, but a list is @@ -239,7 +243,7 @@ void *DOM_Node::getUserData() const DOM_NamedNodeMap DOM_Node::getAttributes() const { - return DOM_NamedNodeMap(fImpl->getAttributes()); + return (fImpl->getAttributes() == null) ? DOM_NamedNodeMap(fImpl) : DOM_NamedNodeMap(fImpl->getAttributes()); }; diff --git a/src/dom/ElementImpl.cpp b/src/dom/ElementImpl.cpp index a125c2e80a0c5ba7ab2312fc1c61335c8cac6c6c..de3ff2eb1651fa1fa9ab63b4ddd019f235e0296e 100644 --- a/src/dom/ElementImpl.cpp +++ b/src/dom/ElementImpl.cpp @@ -73,7 +73,7 @@ ElementImpl::ElementImpl(DocumentImpl *ownerDoc, const DOMString &eName) : ChildAndParentNode(ownerDoc) { name = eName.clone(); - attributes = new NamedNodeMapImpl(this); + attributes = null; }; @@ -81,9 +81,11 @@ ElementImpl::ElementImpl(const ElementImpl &other, bool deep) : ChildAndParentNode(other) { name = other.name.clone(); + attributes = null; if (deep) cloneChildren(other); - attributes = other.attributes->cloneMap(this); + if (other.attributes != null) + attributes = other.attributes->cloneMap(this); }; @@ -109,7 +111,8 @@ NodeImpl *ElementImpl::cloneNode(bool deep) */ void ElementImpl::setOwnerDocument(DocumentImpl *doc) { ChildAndParentNode::setOwnerDocument(doc); - attributes->setOwnerDocument(doc); + if (attributes != null) + attributes->setOwnerDocument(doc); } @@ -134,7 +137,7 @@ DOMString ElementImpl::getAttribute(const DOMString &nam) AttrImpl *ElementImpl::getAttributeNode(const DOMString &nam) { - return (AttrImpl *)(attributes->getNamedItem(nam)); + return (attributes == null) ? null : (AttrImpl *)(attributes->getNamedItem(nam)); }; @@ -212,6 +215,8 @@ AttrImpl *ElementImpl::setAttribute(const DOMString &nam, const DOMString &val) AttrImpl* newAttr = (AttrImpl*)getAttributeNode(nam); if (!newAttr) { + if (attributes == null) + attributes = new NamedNodeMapImpl(this); newAttr = (AttrImpl*)ownerDocument->createAttribute(nam); attributes->setNamedItem(newAttr); } @@ -232,6 +237,8 @@ AttrImpl * ElementImpl::setAttributeNode(AttrImpl *newAttr) if (!(newAttr->isAttrImpl())) throw DOM_DOMException(DOM_DOMException::WRONG_DOCUMENT_ERR, null); + if (attributes == null) + attributes = new NamedNodeMapImpl(this); AttrImpl *oldAttr = (AttrImpl *) attributes->getNamedItem(newAttr->getName()); // This will throw INUSE if necessary @@ -285,6 +292,8 @@ AttrImpl *ElementImpl::setAttributeNS(const DOMString &fNamespaceURI, (AttrImpl *) ownerDocument->createAttributeNS(fNamespaceURI, qualifiedName); newAttr->setNodeValue(fValue); + if (attributes == null) + attributes = new NamedNodeMapImpl(this); AttrImpl *oldAttr = (AttrImpl *)attributes->setNamedItem(newAttr); if (oldAttr) { @@ -328,8 +337,9 @@ AttrImpl *ElementImpl::setAttributeNodeNS(AttrImpl *newAttr) if (newAttr -> getOwnerDocument() != this -> getOwnerDocument()) throw DOM_DOMException(DOM_DOMException::WRONG_DOCUMENT_ERR, null); - AttrImpl *oldAttr = (AttrImpl *) attributes->getNamedItemNS( - newAttr->getNamespaceURI(), newAttr->getLocalName()); + if (attributes == null) + attributes = new NamedNodeMapImpl(this); + AttrImpl *oldAttr = (AttrImpl *) attributes->getNamedItemNS(newAttr->getNamespaceURI(), newAttr->getLocalName()); // This will throw INUSE if necessary attributes->setNamedItemNS(newAttr); @@ -353,3 +363,88 @@ DeepNodeListImpl *ElementImpl::getElementsByTagNameNS(const DOMString &fNamespac return new DeepNodeListImpl(this,fNamespaceURI, fLocalName); } +// DOM_NamedNodeMap UTILITIES +NamedNodeMapImpl *ElementImpl::NNM_cloneMap(NodeImpl *ownerNode) +{ + return (getAttributes() == null) ? null : ownerNode->getAttributes()->cloneMap(ownerNode); +} + +int ElementImpl::NNM_findNamePoint(const DOMString &name) +{ + return (getAttributes() == null) ? -1 : getAttributes()->findNamePoint(name); +} + +unsigned int ElementImpl::NNM_getLength() +{ + return (getAttributes() == null) ? 0 : getAttributes()->getLength(); +} + +NodeImpl *ElementImpl::NNM_getNamedItem(const DOMString &name) +{ + return (getAttributes() == null) ? null : getAttributes()->getNamedItem(name); +} + +NodeImpl *ElementImpl::NNM_item(unsigned int index) +{ + return (getAttributes() == null) ? null : getAttributes()->item(index); +} + +void ElementImpl::NNM_removeAll() +{ + if (getAttributes() != null) + getAttributes()->removeAll(); +} + +NodeImpl *ElementImpl::NNM_removeNamedItem(const DOMString &name) +{ + if (getAttributes() == null) + throw DOM_DOMException(DOM_DOMException::NOT_FOUND_ERR, null); + else + return getAttributes()->removeNamedItem(name); + return null; +} + +NodeImpl *ElementImpl::NNM_setNamedItem(NodeImpl *arg) +{ + if (getAttributes() == null) + attributes = new NamedNodeMapImpl(this); + return attributes->setNamedItem(arg); +} + +void ElementImpl::NNM_setReadOnly(bool readOnly, bool deep) +{ + if (getAttributes() != null) + getAttributes()->setReadOnly(readOnly, deep); +} + +int ElementImpl::NNM_findNamePoint(const DOMString &namespaceURI, const DOMString &localName) +{ + return (getAttributes() == null) ? -1 : getAttributes()->findNamePoint(namespaceURI, localName); +} + +NodeImpl *ElementImpl::NNM_getNamedItemNS(const DOMString &namespaceURI, const DOMString &localName) +{ + return (getAttributes() == null) ? null : getAttributes()->getNamedItemNS(namespaceURI, localName); +} + +NodeImpl *ElementImpl::NNM_setNamedItemNS(NodeImpl *arg) +{ + if (getAttributes() == null) + attributes = new NamedNodeMapImpl(this); + return getAttributes()->setNamedItemNS(arg); +} + +NodeImpl *ElementImpl::NNM_removeNamedItemNS(const DOMString &namespaceURI, const DOMString &localName) +{ + if (getAttributes() == null) + throw DOM_DOMException(DOM_DOMException::NOT_FOUND_ERR, null); + else + return getAttributes()->removeNamedItemNS(namespaceURI, localName); + return null; +} + +void ElementImpl::NNM_setOwnerDocument(DocumentImpl *doc) +{ + if (getAttributes() != null) + getAttributes()->setOwnerDocument(doc); +} diff --git a/src/dom/ElementImpl.hpp b/src/dom/ElementImpl.hpp index b4d340468c968ec49770778d01f85fe5dccead48..38879c90bfc7eb6a40faf126f154fa22135a629a 100644 --- a/src/dom/ElementImpl.hpp +++ b/src/dom/ElementImpl.hpp @@ -117,6 +117,28 @@ public: const DOMString &localName); virtual void setOwnerDocument(DocumentImpl *doc); + + //Utils for the DOM_NamedNodeMap wrapper class + //All NamedNodeMap utils begin with NNM + virtual NamedNodeMapImpl *NNM_cloneMap(NodeImpl *ownerNode); +// static void NNM_addRef(NamedNodeMapImpl *); + virtual int NNM_findNamePoint(const DOMString &name); + virtual unsigned int NNM_getLength(); + virtual NodeImpl *NNM_getNamedItem(const DOMString &name); + virtual NodeImpl *NNM_item(unsigned int index); + virtual void NNM_removeAll(); + virtual NodeImpl *NNM_removeNamedItem(const DOMString &name); +// static void NNM_removeRef(NamedNodeMapImpl *); + virtual NodeImpl *NNM_setNamedItem(NodeImpl *arg); + virtual void NNM_setReadOnly(bool readOnly, bool deep); + //Introduced in DOM Level 2 + virtual int NNM_findNamePoint(const DOMString &namespaceURI, const DOMString &localName); + virtual NodeImpl *NNM_getNamedItemNS(const DOMString &namespaceURI, const DOMString &localName); + virtual NodeImpl *NNM_setNamedItemNS(NodeImpl *arg); + virtual NodeImpl *NNM_removeNamedItemNS(const DOMString &namespaceURI, const DOMString &localName); + virtual void NNM_setOwnerDocument(DocumentImpl *doc); + + }; #endif