X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fpbd%2Fxml%2B%2B.cc;h=23ecfabc9146e7e8a87d76159d582f55af85e65b;hb=c4fcb12d128857a0eaab7d2093d38fdf4cc641cc;hp=b12eb69252c06e69ea84e2683b2fbde97ac42e88;hpb=4b2987d0f2937c1d7c2e63ad573b7e8d4abf6614;p=ardour.git diff --git a/libs/pbd/xml++.cc b/libs/pbd/xml++.cc index b12eb69252..23ecfabc91 100644 --- a/libs/pbd/xml++.cc +++ b/libs/pbd/xml++.cc @@ -120,7 +120,7 @@ XMLTree::read_internal(bool validate) } bool -XMLTree::read_buffer(const string& buffer) +XMLTree::read_buffer(const string& buffer, bool to_tree_doc) { xmlDocPtr doc; @@ -135,7 +135,14 @@ XMLTree::read_buffer(const string& buffer) } _root = readnode(xmlDocGetRootElement(doc)); - xmlFreeDoc(doc); + if (to_tree_doc) { + if (_doc) { + xmlFreeDoc (_doc); + } + _doc = doc; + } else { + xmlFreeDoc (doc); + } return true; } @@ -215,10 +222,13 @@ XMLTree::write_buffer() const return retval; } +static const int PROPERTY_RESERVE_COUNT = 16; + XMLNode::XMLNode(const string& n) : _name(n) , _is_content(false) { + _proplist.reserve (PROPERTY_RESERVE_COUNT); } XMLNode::XMLNode(const string& n, const string& c) @@ -226,10 +236,12 @@ XMLNode::XMLNode(const string& n, const string& c) , _is_content(true) , _content(c) { + _proplist.reserve (PROPERTY_RESERVE_COUNT); } XMLNode::XMLNode(const XMLNode& from) { + _proplist.reserve (PROPERTY_RESERVE_COUNT); *this = from; } @@ -245,7 +257,6 @@ XMLNode::clear_lists () XMLPropertyIterator curprop; _selected_children.clear (); - _propmap.clear (); for (curchild = _children.begin(); curchild != _children.end(); ++curchild) { delete *curchild; @@ -263,27 +274,24 @@ XMLNode::clear_lists () XMLNode& XMLNode::operator= (const XMLNode& from) { - if (&from != this) { + if (&from == this) { + return *this; + } - XMLPropertyList props; - XMLPropertyIterator curprop; - XMLNodeList nodes; - XMLNodeIterator curnode; + clear_lists (); - clear_lists (); + _name = from.name (); + set_content (from.content ()); - _name = from.name(); - set_content(from.content()); + const XMLPropertyList& props = from.properties (); - props = from.properties(); - for (curprop = props.begin(); curprop != props.end(); ++curprop) { - add_property((*curprop)->name().c_str(), (*curprop)->value()); - } + for (XMLPropertyConstIterator prop_iter = props.begin (); prop_iter != props.end (); ++prop_iter) { + set_property ((*prop_iter)->name ().c_str (), (*prop_iter)->value ()); + } - nodes = from.children(); - for (curnode = nodes.begin(); curnode != nodes.end(); ++curnode) { - add_child_copy(**curnode); - } + const XMLNodeList& nodes = from.children (); + for (XMLNodeConstIterator child_iter = nodes.begin (); child_iter != nodes.end (); ++child_iter) { + add_child_copy (**child_iter); } return *this; @@ -472,115 +480,126 @@ XMLNode::add_content(const string& c) } XMLProperty const * -XMLNode::property(const char* n) const +XMLNode::property(const char* name) const { - string ns(n); - map::const_iterator iter; + XMLPropertyConstIterator iter = _proplist.begin(); - if ((iter = _propmap.find(ns)) != _propmap.end()) { - return iter->second; + while (iter != _proplist.end()) { + if ((*iter)->name() == name) { + return *iter; + } + ++iter; } return 0; } XMLProperty const * -XMLNode::property(const string& ns) const +XMLNode::property(const string& name) const { - map::const_iterator iter; + XMLPropertyConstIterator iter = _proplist.begin(); - if ((iter = _propmap.find(ns)) != _propmap.end()) { - return iter->second; + while (iter != _proplist.end()) { + if ((*iter)->name() == name) { + return *iter; + } + ++iter; } - return 0; } XMLProperty * -XMLNode::property(const char* n) +XMLNode::property(const char* name) { - string ns(n); - map::iterator iter; + XMLPropertyIterator iter = _proplist.begin(); - if ((iter = _propmap.find(ns)) != _propmap.end()) { - return iter->second; + while (iter != _proplist.end()) { + if ((*iter)->name() == name) { + return *iter; + } + ++iter; } - return 0; } XMLProperty * -XMLNode::property(const string& ns) +XMLNode::property(const string& name) { - map::iterator iter; + XMLPropertyIterator iter = _proplist.begin(); - if ((iter = _propmap.find(ns)) != _propmap.end()) { - return iter->second; + while (iter != _proplist.end()) { + if ((*iter)->name() == name) { + return *iter; + } + ++iter; } return 0; } bool -XMLNode::has_property_with_value (const string& key, const string& value) const +XMLNode::has_property_with_value (const string& name, const string& value) const { - map::const_iterator iter = _propmap.find(key); - if (iter != _propmap.end()) { - const XMLProperty* p = (iter->second); - return (p && p->value() == value); + XMLPropertyConstIterator iter = _proplist.begin(); + + while (iter != _proplist.end()) { + if ((*iter)->name() == name && (*iter)->value() == value) { + return true; + } + ++iter; } return false; } -XMLProperty* -XMLNode::add_property(const char* n, const string& v) +bool +XMLNode::set_property(const char* name, const string& value) { - string ns(n); - map::iterator iter; + XMLPropertyIterator iter = _proplist.begin(); - if ((iter = _propmap.find(ns)) != _propmap.end()) { - iter->second->set_value (v); - return iter->second; + while (iter != _proplist.end()) { + if ((*iter)->name() == name) { + (*iter)->set_value (value); + return *iter; + } + ++iter; } - XMLProperty* tmp = new XMLProperty(ns, v); + XMLProperty* new_property = new XMLProperty(name, value); - if (!tmp) { + if (!new_property) { return 0; } - _propmap[tmp->name()] = tmp; - _proplist.insert(_proplist.end(), tmp); + _proplist.insert(_proplist.end(), new_property); - return tmp; + return new_property; } -XMLProperty* -XMLNode::add_property(const char* n, const char* v) +bool +XMLNode::get_property(const char* name, std::string& value) const { - string vs(v); - return add_property(n, vs); -} + XMLProperty const* const prop = property (name); + if (!prop) + return false; -XMLProperty* -XMLNode::add_property(const char* name, const long value) -{ - char str[64]; - snprintf(str, sizeof(str), "%ld", value); - return add_property(name, str); + value = prop->value (); + + return true; } void -XMLNode::remove_property(const string& n) +XMLNode::remove_property(const string& name) { - if (_propmap.find(n) != _propmap.end()) { - XMLProperty* p = _propmap[n]; - XMLPropertyIterator i = std::find(_proplist.begin(), _proplist.end(), p); - if (i != _proplist.end ()) { - _proplist.erase (i); + XMLPropertyIterator iter = _proplist.begin(); + + while (iter != _proplist.end()) { + if ((*iter)->name() == name) { + XMLProperty* property = *iter; + _proplist.erase (iter); + delete property; + break; } - delete p; - _propmap.erase(n); + ++iter; } } @@ -639,16 +658,26 @@ XMLNode::remove_nodes_and_delete(const string& propname, const string& val) } } +void +XMLNode::remove_node_and_delete(const string& n, const string& propname, + const string& val) +{ + for (XMLNodeIterator i = _children.begin(); i != _children.end(); ++i) { + if ((*i)->name() == n) { + XMLProperty const * prop = (*i)->property (propname); + if (prop && prop->value() == val) { + delete *i; + _children.erase (i); + break; + } + } + } +} + XMLProperty::XMLProperty(const string& n, const string& v) : _name(n) , _value(v) { - // Normalize property name (replace '_' with '-' as old session are inconsistent) - for (size_t i = 0; i < _name.length(); ++i) { - if (_name[i] == '_') { - _name[i] = '-'; - } - } } XMLProperty::~XMLProperty() @@ -674,7 +703,7 @@ readnode(xmlNodePtr node) if (attr->children) { content = (char*)attr->children->content; } - tmp->add_property((const char*)attr->name, content); + tmp->set_property((const char*)attr->name, content); } if (node->content) { @@ -693,10 +722,6 @@ readnode(xmlNodePtr node) static void writenode(xmlDocPtr doc, XMLNode* n, xmlNodePtr p, int root = 0) { - XMLPropertyList props; - XMLPropertyIterator curprop; - XMLNodeList children; - XMLNodeIterator curchild; xmlNodePtr node; if (root) { @@ -710,14 +735,18 @@ writenode(xmlDocPtr doc, XMLNode* n, xmlNodePtr p, int root = 0) xmlNodeSetContentLen(node, (const xmlChar*)n->content().c_str(), n->content().length()); } - props = n->properties(); - for (curprop = props.begin(); curprop != props.end(); ++curprop) { - xmlSetProp(node, (const xmlChar*) (*curprop)->name().c_str(), (const xmlChar*) (*curprop)->value().c_str()); + const XMLPropertyList& props = n->properties(); + + for (XMLPropertyConstIterator prop_iter = props.begin (); prop_iter != props.end (); + ++prop_iter) { + xmlSetProp (node, (const xmlChar*)(*prop_iter)->name ().c_str (), + (const xmlChar*)(*prop_iter)->value ().c_str ()); } - children = n->children(); - for (curchild = children.begin(); curchild != children.end(); ++curchild) { - writenode(doc, *curchild, node); + const XMLNodeList& children = n->children (); + for (XMLNodeConstIterator child_iter = children.begin (); child_iter != children.end (); + ++child_iter) { + writenode (doc, *child_iter, node); } }