diff options
author | Paul Davis <paul@linuxaudiosystems.com> | 2012-03-20 18:01:07 +0000 |
---|---|---|
committer | Paul Davis <paul@linuxaudiosystems.com> | 2012-03-20 18:01:07 +0000 |
commit | 71b3c8cfe12fad319af00ba03f7746761a90b568 (patch) | |
tree | 2baac377928e0ce08fb914f17ed2485daa7818a1 /libs/pbd | |
parent | 2b7d17e9041363e19d71d9a2dd9425d045536eb8 (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++.h | 4 | ||||
-rw-r--r-- | libs/pbd/xml++.cc | 51 |
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; } |