mirror of
https://github.com/jezhiggins/arabica
synced 2025-01-17 18:12:04 +01:00
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:
parent
03661daaf8
commit
9fc4a8b000
5 changed files with 64 additions and 45 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in a new issue