diff --git a/libs/xmlutil/Document.cpp b/libs/xmlutil/Document.cpp index a6906fb95d..1f2c5314c7 100644 --- a/libs/xmlutil/Document.cpp +++ b/libs/xmlutil/Document.cpp @@ -127,6 +127,8 @@ Node Document::addTopLevelNode(const std::string& name) Node Document::getTopLevelNode() const { + std::lock_guard lock(_lock); + if (!isValid()) { // Invalid Document, return a NULL node diff --git a/libs/xmlutil/Node.cpp b/libs/xmlutil/Node.cpp index 2784de7777..eda4cf38f6 100644 --- a/libs/xmlutil/Node.cpp +++ b/libs/xmlutil/Node.cpp @@ -1,7 +1,10 @@ #include "Node.h" +#include #include +#include "Document.h" + namespace xml { @@ -15,38 +18,41 @@ bool Node::isValid() const return _xmlNode != nullptr; } -// Return the name of a node std::string Node::getName() const { - if (_xmlNode) { - return std::string( reinterpret_cast(_xmlNode->name) ); - } - else { - return ""; + std::lock_guard lock(_owner->getLock()); + + if (_xmlNode) + { + return std::string(reinterpret_cast(_xmlNode->name)); } + + return {}; } -// Return a NodeList of all children of this node NodeList Node::getChildren() const { + // Lock the document to collect the children + std::lock_guard lock(_owner->getLock()); + NodeList retval; - // Iterate throught the list of children, adding each child node - // to the return list if it matches the requested name - for (xmlNodePtr child = _xmlNode->children; child != NULL; child = child->next) { + for (auto child = _xmlNode->children; child != nullptr; child = child->next) + { retval.emplace_back(_owner, child); } return retval; } -// Creates a new child with no content (i.e. ) Node Node::createChild(const std::string& name) { + std::lock_guard lock(_owner->getLock()); + xmlChar* nodeName = xmlCharStrdup(name.c_str()); // Create a new child under the contained node - xmlNodePtr newChild = xmlNewChild(_xmlNode, NULL, nodeName, NULL); + xmlNodePtr newChild = xmlNewChild(_xmlNode, nullptr, nodeName, nullptr); xmlFree(nodeName); @@ -56,12 +62,16 @@ Node Node::createChild(const std::string& name) NodeList Node::getNamedChildren(const std::string& name) const { + std::lock_guard lock(_owner->getLock()); + NodeList retval; // Iterate throught the list of children, adding each child node // to the return list if it matches the requested name - for (xmlNodePtr child = _xmlNode->children; child != NULL; child = child->next) { - if (xmlStrcmp(child->name, reinterpret_cast(name.c_str())) == 0) { + for (auto child = _xmlNode->children; child != nullptr; child = child->next) + { + if (xmlStrcmp(child->name, reinterpret_cast(name.c_str())) == 0) + { retval.emplace_back(_owner, child); } } @@ -71,6 +81,8 @@ NodeList Node::getNamedChildren(const std::string& name) const void Node::setAttributeValue(const std::string& key, const std::string& value) { + std::lock_guard lock(_owner->getLock()); + xmlChar* k = xmlCharStrdup(key.c_str()); xmlChar* v = xmlCharStrdup(value.c_str()); @@ -85,32 +97,37 @@ void Node::setAttributeValue(const std::string& key, const std::string& value) std::string Node::getAttributeValue(const std::string& key) const { + std::lock_guard lock(_owner->getLock()); + // Iterate through the chain of attributes to find the requested one. - for (xmlAttrPtr attr = _xmlNode->properties; attr != NULL; attr = attr->next) { - if (xmlStrcmp(attr->name, reinterpret_cast(key.c_str())) == 0) { + for (auto attr = _xmlNode->properties; attr != nullptr; attr = attr->next) + { + if (xmlStrcmp(attr->name, reinterpret_cast(key.c_str())) == 0) + { return reinterpret_cast(attr->children->content); } } // Not found, return an empty string - return ""; + return {}; } -// Return the textual content of a given node. This may be an empty string if there is no -// content available. - std::string Node::getContent() const { - if (_xmlNode->children && _xmlNode->children->content) { + std::lock_guard lock(_owner->getLock()); + + if (_xmlNode->children && _xmlNode->children->content) + { return std::string(reinterpret_cast(_xmlNode->children->content)); } - else { - return ""; - } + + return {}; } void Node::setContent(const std::string& content) { + std::lock_guard lock(_owner->getLock()); + // Remove all text children first for (xmlNodePtr child = _xmlNode->children; child != nullptr; ) { @@ -131,10 +148,10 @@ void Node::setContent(const std::string& content) void Node::addText(const std::string& text) { + std::lock_guard lock(_owner->getLock()); + // Allocate a new text node - xmlNodePtr whitespace = xmlNewText( - reinterpret_cast(text.c_str()) - ); + auto whitespace = xmlNewText(reinterpret_cast(text.c_str())); // Add the newly allocated text as sibling of this node xmlAddNextSibling(_xmlNode, whitespace); @@ -142,6 +159,8 @@ void Node::addText(const std::string& text) void Node::erase() { + std::lock_guard lock(_owner->getLock()); + // unlink the node from the list first, otherwise: crashes ahead! xmlUnlinkNode(_xmlNode);