diff --git a/libs/pbd/pbd/xml++.h b/libs/pbd/pbd/xml++.h index 1aae15bbc3..c3fb513dfe 100644 --- a/libs/pbd/pbd/xml++.h +++ b/libs/pbd/pbd/xml++.h @@ -12,6 +12,7 @@ #include #include +#include #ifndef __XML_H #define __XML_H @@ -25,6 +26,7 @@ class XMLNode; class XMLProperty; typedef list XMLNodeList; +typedef list > XMLSharedNodeList; typedef XMLNodeList::iterator XMLNodeIterator; typedef XMLNodeList::const_iterator XMLNodeConstIterator; typedef list XMLPropertyList; @@ -93,7 +95,7 @@ public: XMLNode *child (const char*) const; void add_child_nocopy (XMLNode&); - XMLNodeList *find(const std::string xpath) const; + boost::shared_ptr find(const std::string xpath) const; const XMLPropertyList & properties() const { return _proplist; }; XMLProperty *property(const char * ); diff --git a/libs/pbd/tests/xpath.cc b/libs/pbd/tests/xpath.cc index 7d7c1a39b4..968bbd9b5f 100644 --- a/libs/pbd/tests/xpath.cc +++ b/libs/pbd/tests/xpath.cc @@ -10,12 +10,12 @@ int main() cout << "Test 1: Find all banks in the file" << endl; XMLTree doc("./rosegardenpatchfile.xml"); // "//bank" gives as last element an empty element libxml bug???? - XMLNodeList* result = doc.root()->find("//bank[@name]"); + boost::shared_ptr result = doc.root()->find("//bank[@name]"); cout << "Found " << result->size() << " banks" << endl; assert(result->size() == 8); int counter = 1; - for(XMLNodeList::const_iterator i = result->begin(); i != result->end(); ++i) { + for(XMLSharedNodeList::const_iterator i = result->begin(); i != result->end(); ++i) { assert((*i)->name() == "bank"); assert((*i)->property("name")); cout << "Found bank number " << counter++ << " with name: " << (*i)->property("name")->value() << endl; @@ -23,25 +23,17 @@ int main() cout << "\t found program " << (*j)->property("id")->value() << " with name: " << (*j)->property("name")->value() << endl; } - - delete *i; } - delete result; - cout << endl << endl << "Test 2: Find all programs whose program name contains 'Latin'" << endl; result = doc.root()->find("/rosegarden-data/studio/device/bank/program[contains(@name, 'Latin')]"); assert(result->size() == 5); - for(XMLNodeList::const_iterator i = result->begin(); i != result->end(); ++i) { + for(XMLSharedNodeList::const_iterator i = result->begin(); i != result->end(); ++i) { cout << "\t found program " << (*i)->property("id")->value() << " with name: " << (*i)->property("name")->value() << endl; - - delete *i; } - - delete result; cout << endl << endl << "Test 3: find all Sources where captured-for contains the string 'Guitar'" << endl; @@ -49,28 +41,20 @@ int main() result = doc2.root()->find("/Session/Sources/Source[contains(@captured-for, 'Guitar')]"); assert(result->size() == 16); - for(XMLNodeList::const_iterator i = result->begin(); i != result->end(); ++i) { + for(XMLSharedNodeList::const_iterator i = result->begin(); i != result->end(); ++i) { cout << "\t found source '" << (*i)->property("name")->value() << "' with id: " << (*i)->property("id")->value() << endl; - - delete *i; } - delete result; - cout << endl << endl << "Test 4: Find all elements with an 'id' and 'name' attribute" << endl; result = doc2.root()->find("//*[@id and @name]"); - for(XMLNodeList::const_iterator i = result->begin(); i != result->end(); ++i) { + for(XMLSharedNodeList::const_iterator i = result->begin(); i != result->end(); ++i) { assert((*i)->property("id")); assert((*i)->property("name")); cout << "\t found element '" << (*i)->name() << "' with id: " << (*i)->property("id")->value() << "' and name: " << (*i)->property("name")->value() << endl; - - delete *i; } - - delete result; } diff --git a/libs/pbd/xml++.cc b/libs/pbd/xml++.cc index 9881dc5bee..8dff34c678 100644 --- a/libs/pbd/xml++.cc +++ b/libs/pbd/xml++.cc @@ -13,7 +13,7 @@ static XMLNode *readnode(xmlNodePtr); static void writenode(xmlDocPtr, XMLNode *, xmlNodePtr, int); -static XMLNodeList *find_impl(xmlXPathContext* ctxt, const string xpath); +static XMLSharedNodeList* find_impl(xmlXPathContext* ctxt, const string xpath); XMLTree::XMLTree() : _filename(), @@ -285,14 +285,15 @@ XMLNode::add_child_copy(const XMLNode& n) return copy; } -XMLNodeList* +boost::shared_ptr XMLNode::find(const string xpath) const { xmlDocPtr doc = xmlNewDoc((xmlChar *) XML_VERSION); writenode(doc, (XMLNode *) this, doc->children, 1); xmlXPathContext* ctxt = xmlXPathNewContext(doc); - XMLNodeList* result = find_impl(ctxt, xpath); + boost::shared_ptr result = + boost::shared_ptr(find_impl(ctxt, xpath)); xmlXPathFreeContext(ctxt); xmlFreeDoc(doc); @@ -497,7 +498,7 @@ writenode(xmlDocPtr doc, XMLNode * n, xmlNodePtr p, int root = 0) } } -static XMLNodeList* find_impl(xmlXPathContext* ctxt, const string xpath) +static XMLSharedNodeList* find_impl(xmlXPathContext* ctxt, const string xpath) { xmlXPathObject* result = xmlXPathEval((const xmlChar*)xpath.c_str(), ctxt); @@ -519,12 +520,12 @@ static XMLNodeList* find_impl(xmlXPathContext* ctxt, const string xpath) } xmlNodeSet* nodeset = result->nodesetval; - XMLNodeList* nodes = new XMLNodeList(); + XMLSharedNodeList* nodes = new XMLSharedNodeList(); if( nodeset ) { for (int i = 0; i < nodeset->nodeNr; ++i) { XMLNode* node = readnode(nodeset->nodeTab[i]); - nodes->push_back(node); + nodes->push_back(boost::shared_ptr(node)); } } else