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!
This commit is contained in:
jez_higgins 2005-12-09 11:49:03 +00:00
parent 03661daaf8
commit 9fc4a8b000
5 changed files with 64 additions and 45 deletions

View file

@ -20,7 +20,7 @@ class AttrImpl : public DOM::Attr_impl<stringT>,
AttrImpl(DocumentImpl<stringT, string_adaptorT>* ownerDoc, const stringT& name) :
DOM::Attr_impl<stringT>(),
NodeImplWithChildren<stringT, string_adaptorT>(ownerDoc),
name_(name),
name_(ownerDoc->stringPool(name)),
ownerElement_(0),
specified_(true)
{
@ -29,7 +29,7 @@ class AttrImpl : public DOM::Attr_impl<stringT>,
AttrImpl(DocumentImpl<stringT, string_adaptorT>* ownerDoc, const stringT& name, const stringT& value) :
DOM::Attr_impl<stringT>(),
NodeImplWithChildren<stringT, string_adaptorT>(ownerDoc),
name_(name),
name_(ownerDoc->stringPool(name)),
ownerElement_(0),
specified_(true)
{
@ -68,7 +68,7 @@ class AttrImpl : public DOM::Attr_impl<stringT>,
virtual DOM::Node_impl<stringT>* cloneNode(bool deep) const
{
AttrImpl* a = dynamic_cast<AttrImpl*>(NodeT::ownerDoc_->createAttribute(name_));
AttrImpl* a = dynamic_cast<AttrImpl*>(NodeT::ownerDoc_->createAttribute(*name_));
cloneChildren(a);
a->setSpecified(getSpecified());
return a;
@ -76,7 +76,7 @@ class AttrImpl : public DOM::Attr_impl<stringT>,
virtual stringT getNodeName() const
{
return name_;
return *name_;
} // getNodeName
virtual stringT getNodeValue() const
@ -113,7 +113,7 @@ class AttrImpl : public DOM::Attr_impl<stringT>,
if(!docType || docType->getElementIds()->empty())
return;
std::vector<stringT>* 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<stringT>,
} // checkChildType
protected:
stringT name_;
stringT const* name_;
ElementImpl<stringT, string_adaptorT>* ownerElement_;
bool specified_;
}; // class CDATAImpl

View file

@ -27,25 +27,25 @@ class AttrNSImpl : public AttrImpl<stringT, string_adaptorT>
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<bool, stringT> mappedURI =
checkPrefixAndNamespace<stringT, string_adaptorT>(hasPrefix, prefix, hasNamespaceURI, namespaceURI, DOM::Node<stringT>::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<stringT, string_adaptorT>
// DOM::Node methods
virtual DOM::Node_impl<stringT>* cloneNode(bool deep) const
{
AttrNSImpl* clone = dynamic_cast<AttrNSImpl*>(AttrT::ownerDoc_->createAttributeNS(namespaceURI_, AttrT::name_));
AttrNSImpl* clone = dynamic_cast<AttrNSImpl*>(AttrT::ownerDoc_->createAttributeNS(*namespaceURI_, *AttrT::name_));
AttrT::cloneChildren(clone);
clone->setSpecified(AttrT::getSpecified());
return clone;
@ -62,13 +62,13 @@ class AttrNSImpl : public AttrImpl<stringT, string_adaptorT>
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<stringT, string_adaptorT>
return;
} // empty prefix
checkPrefixAndNamespace<stringT, string_adaptorT>(true, prefix, true, namespaceURI_, DOM::Node<stringT>::ATTRIBUTE_NODE);
checkPrefixAndNamespace<stringT, string_adaptorT>(true, prefix, true, *namespaceURI_, DOM::Node<stringT>::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<stringT, string_adaptorT>
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

View file

@ -17,6 +17,8 @@
#include <DOM/Simple/NodeImpl.h>
#include <set>
#include <list>
#include <algorithm>
namespace SimpleDOM
{
@ -129,7 +131,8 @@ class DocumentImpl : public DOM::Document_impl<stringT>,
virtual DOM::Element_impl<stringT>* createElement(const stringT& tagName) const
{
ElementImpl<stringT, string_adaptorT>* n = new ElementImpl<stringT, string_adaptorT>(const_cast<DocumentImpl*>(this), tagName);
ElementImpl<stringT, string_adaptorT>* n =
new ElementImpl<stringT, string_adaptorT>(const_cast<DocumentImpl*>(this), tagName);
orphaned(n);
return n;
} // createElement
@ -296,7 +299,8 @@ class DocumentImpl : public DOM::Document_impl<stringT>,
virtual DOM::Element_impl<stringT>* createElementNS(const stringT& namespaceURI, const stringT& qualifiedName) const
{
ElementNSImpl<stringT, string_adaptorT>* n = new ElementNSImpl<stringT, string_adaptorT>(const_cast<DocumentImpl*>(this), namespaceURI, !string_adaptorT::empty(namespaceURI), qualifiedName);
ElementNSImpl<stringT, string_adaptorT>* n =
new ElementNSImpl<stringT, string_adaptorT>(const_cast<DocumentImpl*>(this), namespaceURI, !string_adaptorT::empty(namespaceURI), qualifiedName);
orphaned(n);
return n;
} // createElementNS
@ -438,6 +442,7 @@ class DocumentImpl : public DOM::Document_impl<stringT>,
{
idNodes_.insert(attr);
} // setElementId
void removeElementId(AttrImplT* attr)
{
typename std::set<AttrImplT*>::iterator n = idNodes_.find(attr);
@ -445,8 +450,17 @@ class DocumentImpl : public DOM::Document_impl<stringT>,
idNodes_.erase(n);
} // removeElementId
stringT const* const stringPool(const stringT& str) const
{
std::list<stringT>::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<stringT>* child)
void checkChildType(typename DOM::Node_impl<stringT>* child)
{
typename DOM::Node<stringT>::Type type = child->getNodeType();
if((type != DOM::Node<stringT>::ELEMENT_NODE) &&
@ -467,6 +481,7 @@ class DocumentImpl : public DOM::Document_impl<stringT>,
mutable std::set<NodeImplT*> orphans_;
std::set<AttrImplT*> idNodes_;
mutable std::list<stringT> stringPool_;
}; // class DocumentImpl

View file

@ -21,7 +21,7 @@ class ElementImpl : public DOM::Element_impl<stringT>,
DOM::Element_impl<stringT>(),
NodeImplWithChildren<stringT, string_adaptorT>(ownerDoc),
attributes_(ownerDoc),
tagName_(tagName)
tagName_(ownerDoc->stringPool(tagName))
{
attributes_.setOwnerElement(this);
} // ElementImpl
@ -122,7 +122,7 @@ class ElementImpl : public DOM::Element_impl<stringT>,
virtual stringT getNodeName() const
{
return tagName_;
return *tagName_;
} // getNodeName
virtual DOM::NamedNodeMap_impl<stringT>* getAttributes() const
@ -132,7 +132,7 @@ class ElementImpl : public DOM::Element_impl<stringT>,
virtual DOM::Node_impl<stringT>* cloneNode(bool deep) const
{
ElementImpl* clone = dynamic_cast<ElementImpl*>(NodeT::ownerDoc_->createElement(tagName_));
ElementImpl* clone = dynamic_cast<ElementImpl*>(NodeT::ownerDoc_->createElement(*tagName_));
cloneChildren(clone, deep);
return clone;
} // cloneNode
@ -190,7 +190,7 @@ class ElementImpl : public DOM::Element_impl<stringT>,
AttrMap<stringT, string_adaptorT> attributes_;
protected:
stringT tagName_;
stringT const* tagName_;
}; // class ElementImpl

View file

@ -26,20 +26,20 @@ class ElementNSImpl : public ElementImpl<stringT, string_adaptorT>
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<bool, stringT> mappedURI =
checkPrefixAndNamespace<stringT, string_adaptorT>(hasPrefix, prefix, hasNamespaceURI, namespaceURI, DOM::Node<stringT>::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<stringT, string_adaptorT>
// DOM::Node methods
virtual DOM::Node_impl<stringT>* cloneNode(bool deep) const
{
ElementNSImpl* clone = dynamic_cast<ElementNSImpl*>(ElementImplT::ownerDoc_->createElementNS(namespaceURI_, ElementImplT::tagName_));
ElementNSImpl* clone = dynamic_cast<ElementNSImpl*>(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<stringT, string_adaptorT>
return;
} // empty prefix
checkPrefixAndNamespace<stringT, string_adaptorT>(true, prefix, true, namespaceURI_, DOM::Node<stringT>::ELEMENT_NODE);
checkPrefixAndNamespace<stringT, string_adaptorT>(true, prefix, true, *namespaceURI_, DOM::Node<stringT>::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<stringT, string_adaptorT>
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