From 9fc4a8b000fa94f0ed1e871d6b35777c1030f267 Mon Sep 17 00:00:00 2001 From: jez_higgins <> Date: Fri, 9 Dec 2005 11:49:03 +0000 Subject: [PATCH] Element & attribute names and namespace URIs are now held in a string pool attached the owning document. The string pool is just a std::list, because it gives us stable pointers into the contents. Easy! --- DOM/Simple/AttrImpl.h | 12 ++++++------ DOM/Simple/AttrNSImpl.h | 36 +++++++++++++++++++----------------- DOM/Simple/DocumentImpl.h | 21 ++++++++++++++++++--- DOM/Simple/ElementImpl.h | 8 ++++---- DOM/Simple/ElementNSImpl.h | 32 +++++++++++++++++--------------- 5 files changed, 64 insertions(+), 45 deletions(-) diff --git a/DOM/Simple/AttrImpl.h b/DOM/Simple/AttrImpl.h index 0a2c8038..b1e8f9e1 100644 --- a/DOM/Simple/AttrImpl.h +++ b/DOM/Simple/AttrImpl.h @@ -20,7 +20,7 @@ class AttrImpl : public DOM::Attr_impl, AttrImpl(DocumentImpl* ownerDoc, const stringT& name) : DOM::Attr_impl(), NodeImplWithChildren(ownerDoc), - name_(name), + name_(ownerDoc->stringPool(name)), ownerElement_(0), specified_(true) { @@ -29,7 +29,7 @@ class AttrImpl : public DOM::Attr_impl, AttrImpl(DocumentImpl* ownerDoc, const stringT& name, const stringT& value) : DOM::Attr_impl(), NodeImplWithChildren(ownerDoc), - name_(name), + name_(ownerDoc->stringPool(name)), ownerElement_(0), specified_(true) { @@ -68,7 +68,7 @@ class AttrImpl : public DOM::Attr_impl, virtual DOM::Node_impl* cloneNode(bool deep) const { - AttrImpl* a = dynamic_cast(NodeT::ownerDoc_->createAttribute(name_)); + AttrImpl* a = dynamic_cast(NodeT::ownerDoc_->createAttribute(*name_)); cloneChildren(a); a->setSpecified(getSpecified()); return a; @@ -76,7 +76,7 @@ class AttrImpl : public DOM::Attr_impl, virtual stringT getNodeName() const { - return name_; + return *name_; } // getNodeName virtual stringT getNodeValue() const @@ -113,7 +113,7 @@ class AttrImpl : public DOM::Attr_impl, if(!docType || docType->getElementIds()->empty()) return; std::vector* elemIds = docType->getElementIds(); - if(std::find(elemIds->begin(), elemIds->end(), name_) != elemIds->end()) + if(std::find(elemIds->begin(), elemIds->end(), *name_) != elemIds->end()) NodeT::ownerDoc_->setElementId(this); } // if(ownerDoc_) } // setOwnerElement @@ -137,7 +137,7 @@ class AttrImpl : public DOM::Attr_impl, } // checkChildType protected: - stringT name_; + stringT const* name_; ElementImpl* ownerElement_; bool specified_; }; // class CDATAImpl diff --git a/DOM/Simple/AttrNSImpl.h b/DOM/Simple/AttrNSImpl.h index 0a670bde..950c52fd 100644 --- a/DOM/Simple/AttrNSImpl.h +++ b/DOM/Simple/AttrNSImpl.h @@ -27,25 +27,25 @@ class AttrNSImpl : public AttrImpl if(index == string_adaptorT::npos) { //qualifiedName contains no ':' - localName_ = qualifiedName; - if(localName_ == string_adaptorT::construct_from_utf8("xmlns")) + localName_ = AttrT::ownerDoc_->stringPool(qualifiedName); + if(*localName_ == string_adaptorT::construct_from_utf8("xmlns")) { hasPrefix = true; - prefix = localName_; + prefix = *localName_; } // if ... } else { hasPrefix = true; prefix = string_adaptorT::substr(qualifiedName, 0, index); - localName_ = string_adaptorT::substr(qualifiedName, index+1); + localName_ = AttrT::ownerDoc_->stringPool(string_adaptorT::substr(qualifiedName, index+1)); } // if(index == string_adaptorT::npos) std::pair mappedURI = checkPrefixAndNamespace(hasPrefix, prefix, hasNamespaceURI, namespaceURI, DOM::Node::ATTRIBUTE_NODE); hasNamespaceURI_ = mappedURI.first; - namespaceURI_ = mappedURI.second; + namespaceURI_ = AttrT::ownerDoc_->stringPool(mappedURI.second); } // AttrImpl virtual ~AttrNSImpl() { } @@ -54,7 +54,7 @@ class AttrNSImpl : public AttrImpl // DOM::Node methods virtual DOM::Node_impl* cloneNode(bool deep) const { - AttrNSImpl* clone = dynamic_cast(AttrT::ownerDoc_->createAttributeNS(namespaceURI_, AttrT::name_)); + AttrNSImpl* clone = dynamic_cast(AttrT::ownerDoc_->createAttributeNS(*namespaceURI_, *AttrT::name_)); AttrT::cloneChildren(clone); clone->setSpecified(AttrT::getSpecified()); return clone; @@ -62,13 +62,13 @@ class AttrNSImpl : public AttrImpl virtual stringT getNamespaceURI() const { - return namespaceURI_; + return *namespaceURI_; } // getNamespaceURI virtual stringT getPrefix() const { - size_type index = string_adaptorT::find(AttrT::name_, string_adaptorT::construct_from_utf8(":")); - return (index != string_adaptorT::npos) ? string_adaptorT::substr(AttrT::name_, 0, index) : stringT(); + size_type index = string_adaptorT::find(*AttrT::name_, string_adaptorT::construct_from_utf8(":")); + return (index != string_adaptorT::npos) ? string_adaptorT::substr(*AttrT::name_, 0, index) : stringT(); } // getPrefix virtual void setPrefix(const stringT& prefix) @@ -82,16 +82,18 @@ class AttrNSImpl : public AttrImpl return; } // empty prefix - checkPrefixAndNamespace(true, prefix, true, namespaceURI_, DOM::Node::ATTRIBUTE_NODE); + checkPrefixAndNamespace(true, prefix, true, *namespaceURI_, DOM::Node::ATTRIBUTE_NODE); - AttrT::name_ = prefix; - string_adaptorT::append(AttrT::name_, string_adaptorT::construct_from_utf8(":")); - string_adaptorT::append(AttrT::name_, localName_); + stringT newName = prefix; + string_adaptorT::append(newName, string_adaptorT::construct_from_utf8(":")); + string_adaptorT::append(newName, *localName_); + + AttrT::name_ = AttrT::ownerDoc_->stringPool(newName); } // setPrefix virtual stringT getLocalName() const { - return localName_; + return *localName_; } // getLocalName // additional three methods - since C++ std::string (and by implication @@ -107,12 +109,12 @@ class AttrNSImpl : public AttrImpl virtual bool hasPrefix() const { - return (string_adaptorT::find(AttrT::name_, string_adaptorT::construct_from_utf8(":")) != string_adaptorT::npos); + return (string_adaptorT::find(*AttrT::name_, string_adaptorT::construct_from_utf8(":")) != string_adaptorT::npos); } // hasPrefix private: - stringT namespaceURI_; - stringT localName_; + stringT const* namespaceURI_; + stringT const* localName_; bool hasNamespaceURI_; }; // class AttrNSImpl diff --git a/DOM/Simple/DocumentImpl.h b/DOM/Simple/DocumentImpl.h index 8914afcc..bb75f025 100644 --- a/DOM/Simple/DocumentImpl.h +++ b/DOM/Simple/DocumentImpl.h @@ -17,6 +17,8 @@ #include #include +#include +#include namespace SimpleDOM { @@ -129,7 +131,8 @@ class DocumentImpl : public DOM::Document_impl, virtual DOM::Element_impl* createElement(const stringT& tagName) const { - ElementImpl* n = new ElementImpl(const_cast(this), tagName); + ElementImpl* n = + new ElementImpl(const_cast(this), tagName); orphaned(n); return n; } // createElement @@ -296,7 +299,8 @@ class DocumentImpl : public DOM::Document_impl, virtual DOM::Element_impl* createElementNS(const stringT& namespaceURI, const stringT& qualifiedName) const { - ElementNSImpl* n = new ElementNSImpl(const_cast(this), namespaceURI, !string_adaptorT::empty(namespaceURI), qualifiedName); + ElementNSImpl* n = + new ElementNSImpl(const_cast(this), namespaceURI, !string_adaptorT::empty(namespaceURI), qualifiedName); orphaned(n); return n; } // createElementNS @@ -438,6 +442,7 @@ class DocumentImpl : public DOM::Document_impl, { idNodes_.insert(attr); } // setElementId + void removeElementId(AttrImplT* attr) { typename std::set::iterator n = idNodes_.find(attr); @@ -445,8 +450,17 @@ class DocumentImpl : public DOM::Document_impl, idNodes_.erase(n); } // removeElementId + stringT const* const stringPool(const stringT& str) const + { + std::list::const_iterator i = std::find(stringPool_.begin(), stringPool_.end(), str); + if(i != stringPool_.end()) + return &(*i); + stringPool_.push_back(str); + return &(stringPool_.back()); + } // stringPool + private: - virtual void checkChildType(typename DOM::Node_impl* child) + void checkChildType(typename DOM::Node_impl* child) { typename DOM::Node::Type type = child->getNodeType(); if((type != DOM::Node::ELEMENT_NODE) && @@ -467,6 +481,7 @@ class DocumentImpl : public DOM::Document_impl, mutable std::set orphans_; std::set idNodes_; + mutable std::list stringPool_; }; // class DocumentImpl diff --git a/DOM/Simple/ElementImpl.h b/DOM/Simple/ElementImpl.h index 5f8ca679..326096d8 100644 --- a/DOM/Simple/ElementImpl.h +++ b/DOM/Simple/ElementImpl.h @@ -21,7 +21,7 @@ class ElementImpl : public DOM::Element_impl, DOM::Element_impl(), NodeImplWithChildren(ownerDoc), attributes_(ownerDoc), - tagName_(tagName) + tagName_(ownerDoc->stringPool(tagName)) { attributes_.setOwnerElement(this); } // ElementImpl @@ -122,7 +122,7 @@ class ElementImpl : public DOM::Element_impl, virtual stringT getNodeName() const { - return tagName_; + return *tagName_; } // getNodeName virtual DOM::NamedNodeMap_impl* getAttributes() const @@ -132,7 +132,7 @@ class ElementImpl : public DOM::Element_impl, virtual DOM::Node_impl* cloneNode(bool deep) const { - ElementImpl* clone = dynamic_cast(NodeT::ownerDoc_->createElement(tagName_)); + ElementImpl* clone = dynamic_cast(NodeT::ownerDoc_->createElement(*tagName_)); cloneChildren(clone, deep); return clone; } // cloneNode @@ -190,7 +190,7 @@ class ElementImpl : public DOM::Element_impl, AttrMap attributes_; protected: - stringT tagName_; + stringT const* tagName_; }; // class ElementImpl diff --git a/DOM/Simple/ElementNSImpl.h b/DOM/Simple/ElementNSImpl.h index 0550e680..14abb4b0 100644 --- a/DOM/Simple/ElementNSImpl.h +++ b/DOM/Simple/ElementNSImpl.h @@ -26,20 +26,20 @@ class ElementNSImpl : public ElementImpl if(index == string_adaptorT::npos) { //qualifiedName contains no ':' - localName_ = qualifiedName; + localName_ = ElementImplT::ownerDoc_->stringPool(qualifiedName); } else { hasPrefix = true; prefix = string_adaptorT::substr(qualifiedName, 0, index); - localName_ = string_adaptorT::substr(qualifiedName, index+1); + localName_ = ElementImplT::ownerDoc_->stringPool(string_adaptorT::substr(qualifiedName, index+1)); } std::pair mappedURI = checkPrefixAndNamespace(hasPrefix, prefix, hasNamespaceURI, namespaceURI, DOM::Node::ELEMENT_NODE); hasNamespaceURI_ = mappedURI.first; - namespaceURI_ = mappedURI.second; + namespaceURI_ = ElementImplT::ownerDoc_->stringPool(mappedURI.second); } // ElementImpl virtual ~ElementNSImpl() { } @@ -48,20 +48,20 @@ class ElementNSImpl : public ElementImpl // DOM::Node methods virtual DOM::Node_impl* cloneNode(bool deep) const { - ElementNSImpl* clone = dynamic_cast(ElementImplT::ownerDoc_->createElementNS(namespaceURI_, ElementImplT::tagName_)); + ElementNSImpl* clone = dynamic_cast(ElementImplT::ownerDoc_->createElementNS(*namespaceURI_, ElementImplT::getNodeName())); ElementImplT::cloneChildren(clone, deep); return clone; } // cloneNode virtual stringT getNamespaceURI() const { - return namespaceURI_; + return *namespaceURI_; } // getNamespaceURI virtual stringT getPrefix() const { - size_type index = string_adaptorT::find(ElementImplT::tagName_, string_adaptorT::construct_from_utf8(":")); - return (index != string_adaptorT::npos) ? string_adaptorT::substr(ElementImplT::tagName_, 0, index) : stringT(); + size_type index = string_adaptorT::find(ElementImplT::getNodeName(), string_adaptorT::construct_from_utf8(":")); + return (index != string_adaptorT::npos) ? string_adaptorT::substr(ElementImplT::getNodeName(), 0, index) : stringT(); } // getPrefix virtual void setPrefix(const stringT& prefix) @@ -77,16 +77,18 @@ class ElementNSImpl : public ElementImpl return; } // empty prefix - checkPrefixAndNamespace(true, prefix, true, namespaceURI_, DOM::Node::ELEMENT_NODE); + checkPrefixAndNamespace(true, prefix, true, *namespaceURI_, DOM::Node::ELEMENT_NODE); - ElementImplT::tagName_ = prefix; - string_adaptorT::append(ElementImplT::tagName_, string_adaptorT::construct_from_utf8(":")); - string_adaptorT::append(ElementImplT::tagName_, localName_); + stringT newTagName = prefix; + string_adaptorT::append(newTagName, string_adaptorT::construct_from_utf8(":")); + string_adaptorT::append(newTagName, *localName_); + + ElementImplT::tagName_ = ElementImplT::ownerDoc_->stringPool(newTagName); } // setPrefix virtual stringT getLocalName() const { - return localName_; + return *localName_; } // getLocalName // additional three methods - since C++ std::string (and by implication @@ -102,12 +104,12 @@ class ElementNSImpl : public ElementImpl virtual bool hasPrefix() const { - return (string_adaptorT::find(ElementImplT::tagName_, string_adaptorT::construct_from_utf8(":")) != string_adaptorT::npos); + return (string_adaptorT::find(ElementImplT::getNodeName(), string_adaptorT::construct_from_utf8(":")) != string_adaptorT::npos); } // hasPrefix private: - stringT namespaceURI_; - stringT localName_; + stringT const* namespaceURI_; + stringT const* localName_; bool hasNamespaceURI_; }; // class ElementImpl