summaryrefslogtreecommitdiff
path: root/libs/pbd
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2012-03-20 18:01:07 +0000
committerPaul Davis <paul@linuxaudiosystems.com>2012-03-20 18:01:07 +0000
commit71b3c8cfe12fad319af00ba03f7746761a90b568 (patch)
tree2baac377928e0ce08fb914f17ed2485daa7818a1 /libs/pbd
parent2b7d17e9041363e19d71d9a2dd9425d045536eb8 (diff)
some deep changes to xml++ in which we retain a C-level xmlDocPtr as a member of an XMLTree objects. this allows us to do repeated XPATH searches (as in the midnam parser of libmidi++) without constantly rewriting an entire tree into memory to recreate a new xmlDocPtr with which we can search. Since XMLTree objects don't typically stay around for very long, just when serializing to/from disk, this is not anticipated to have much (if any) impact on memory consumption
git-svn-id: svn://localhost/ardour2/branches/3.0@11733 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs/pbd')
-rw-r--r--libs/pbd/pbd/xml++.h4
-rw-r--r--libs/pbd/xml++.cc51
2 files changed, 38 insertions, 17 deletions
diff --git a/libs/pbd/pbd/xml++.h b/libs/pbd/pbd/xml++.h
index 6b6ba34f6d..9c3782e3c2 100644
--- a/libs/pbd/pbd/xml++.h
+++ b/libs/pbd/pbd/xml++.h
@@ -60,11 +60,14 @@ public:
const std::string& write_buffer() const;
+ boost::shared_ptr<XMLSharedNodeList> find(const std::string xpath, XMLNode* = 0) const;
+
private:
bool read_internal(bool validate);
std::string _filename;
XMLNode* _root;
+ xmlDocPtr _doc;
int _compression;
};
@@ -90,7 +93,6 @@ public:
XMLNode* add_child_copy(const XMLNode&);
void add_child_nocopy(XMLNode&);
- boost::shared_ptr<XMLSharedNodeList> find(const std::string xpath) const;
std::string attribute_value();
const XMLPropertyList& properties() const { return _proplist; }
diff --git a/libs/pbd/xml++.cc b/libs/pbd/xml++.cc
index b97310eea5..e2ccd67738 100644
--- a/libs/pbd/xml++.cc
+++ b/libs/pbd/xml++.cc
@@ -22,6 +22,7 @@ static XMLSharedNodeList* find_impl(xmlXPathContext* ctxt, const string& xpath);
XMLTree::XMLTree()
: _filename()
, _root(0)
+ , _doc (0)
, _compression(0)
{
}
@@ -29,6 +30,7 @@ XMLTree::XMLTree()
XMLTree::XMLTree(const string& fn, bool validate)
: _filename(fn)
, _root(0)
+ , _doc (0)
, _compression(0)
{
read_internal(validate);
@@ -37,13 +39,19 @@ XMLTree::XMLTree(const string& fn, bool validate)
XMLTree::XMLTree(const XMLTree* from)
: _filename(from->filename())
, _root(new XMLNode(*from->root()))
+ , _doc (xmlCopyDoc (from->_doc, 1))
, _compression(from->compression())
{
+
}
XMLTree::~XMLTree()
{
delete _root;
+
+ if (_doc) {
+ xmlFreeDoc (_doc);
+ }
}
int
@@ -69,8 +77,12 @@ XMLTree::read_internal(bool validate)
delete _root;
_root = 0;
+ if (_doc) {
+ xmlFreeDoc (_doc);
+ _doc = 0;
+ }
+
xmlParserCtxtPtr ctxt = NULL; /* the parser context */
- xmlDocPtr doc; /* the resulting document tree */
xmlKeepBlanksDefault(0);
/* parse the file, activating the DTD validation option */
@@ -80,13 +92,13 @@ XMLTree::read_internal(bool validate)
if (ctxt == NULL) {
return false;
}
- doc = xmlCtxtReadFile(ctxt, _filename.c_str(), NULL, XML_PARSE_DTDVALID);
+ _doc = xmlCtxtReadFile(ctxt, _filename.c_str(), NULL, XML_PARSE_DTDVALID);
} else {
- doc = xmlParseFile(_filename.c_str());
+ _doc = xmlParseFile(_filename.c_str());
}
-
+
/* check if parsing suceeded */
- if (doc == NULL) {
+ if (_doc == NULL) {
if (validate) {
xmlFreeParserCtxt(ctxt);
}
@@ -95,19 +107,17 @@ XMLTree::read_internal(bool validate)
/* check if validation suceeded */
if (validate && ctxt->valid == 0) {
xmlFreeParserCtxt(ctxt);
- xmlFreeDoc(doc);
throw XMLException("Failed to validate document " + _filename);
}
}
- _root = readnode(xmlDocGetRootElement(doc));
+ _root = readnode(xmlDocGetRootElement(_doc));
/* free up the parser context */
if (validate) {
xmlFreeParserCtxt(ctxt);
}
- xmlFreeDoc(doc);
-
+
return true;
}
@@ -342,17 +352,26 @@ XMLNode::add_child_copy(const XMLNode& n)
}
boost::shared_ptr<XMLSharedNodeList>
-XMLNode::find(const string xpath) const
+XMLTree::find(const string xpath, XMLNode* node) const
{
- xmlDocPtr doc = xmlNewDoc((xmlChar*) XML_VERSION);
- writenode(doc, (XMLNode*)this, doc->children, 1);
- xmlXPathContext* ctxt = xmlXPathNewContext(doc);
+ xmlXPathContext* ctxt;
+ xmlDocPtr doc = 0;
+ if (node) {
+ doc = xmlNewDoc((xmlChar*) XML_VERSION);
+ writenode(doc, node, doc->children, 1);
+ ctxt = xmlXPathNewContext(doc);
+ } else {
+ ctxt = xmlXPathNewContext(_doc);
+ }
+
boost::shared_ptr<XMLSharedNodeList> result =
- boost::shared_ptr<XMLSharedNodeList>(find_impl(ctxt, xpath));
-
+ boost::shared_ptr<XMLSharedNodeList>(find_impl(ctxt, xpath));
+
xmlXPathFreeContext(ctxt);
- xmlFreeDoc(doc);
+ if (doc) {
+ xmlFreeDoc (doc);
+ }
return result;
}