Valgrind was reporting lots of leaks of the form: ==5048== at 0x4C2BBAF: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==5048== by 0x5D50D18: xmlBufCreateSize (in /usr/lib/x86_64-linux-gnu/libxml2.so.2.9.4) ==5048== by 0x5CDDD91: xmlNodeGetContent (in /usr/lib/x86_64-linux-gnu/libxml2.so.2.9.4) ==5048== by 0x38EB01: XMLNode::getContent[abi:cxx11]() const (in /usr/sbin/vermont) ==5048== by 0x285B62: CollectorCfg::CollectorCfg(XMLElement*, unsigned int) (in /usr/sbin/vermont) The API guide for xmlNodeGetContent() states: Returns: a new #xmlChar * or NULL if no content is available. It's up to the caller to free the memory with xmlFree(). So call xmlFree() after using the std:string copy constructor Fixes #117
94 lines
2.1 KiB
C++
94 lines
2.1 KiB
C++
#include "XMLNode.h"
|
|
|
|
#include <cassert>
|
|
|
|
XMLNode::XMLNode(xmlNodePtr doc)
|
|
: xmlNode(doc)
|
|
{
|
|
xmlNode->_private = this;
|
|
}
|
|
|
|
XMLNode::~XMLNode()
|
|
{
|
|
}
|
|
|
|
std::string XMLNode::getName() const
|
|
{
|
|
if (!xmlNode->name)
|
|
return "";
|
|
|
|
return std::string((const char*)xmlNode->name);
|
|
}
|
|
|
|
const std::string XMLNode::getContent() const
|
|
{
|
|
xmlChar *xmlString = xmlNodeGetContent(xmlNode);
|
|
std::string string ((const char*)xmlString);
|
|
xmlFree(xmlString);
|
|
return string;
|
|
}
|
|
|
|
XMLNode::XMLNodeSet XMLNode::findChildren(const std::string& name)
|
|
{
|
|
XMLNode::XMLNodeSet children;
|
|
|
|
for (xmlNodePtr child = xmlNode->children; child; child = child->next) {
|
|
if(child->_private &&
|
|
(name.empty() || name == (const char*)child->name)) {
|
|
children.push_back(reinterpret_cast<XMLNode*>(child->_private));
|
|
}
|
|
}
|
|
|
|
return children;
|
|
}
|
|
|
|
XMLNode* XMLNode::getFirstChild(const std::string& name)
|
|
{
|
|
for (xmlNodePtr child = xmlNode->children; child; child = child->next) {
|
|
if(child->_private &&
|
|
(name.empty() || name == (const char*)child->name)) {
|
|
return reinterpret_cast<XMLNode*>(child->_private);
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
XMLNode::XMLSet<XMLTextNode*> XMLNode::getTextChildren()
|
|
{
|
|
XMLNode::XMLSet<XMLTextNode*> children;
|
|
assert(xmlNode != NULL);
|
|
|
|
for (xmlNodePtr child = xmlNode->children; child; child = child->next) {
|
|
// check if name and/or type matches
|
|
if (child->_private && child->type == XML_TEXT_NODE) {
|
|
XMLTextNode* tn = reinterpret_cast<XMLTextNode*>(child->_private);
|
|
if (!tn->isBlank())
|
|
children.push_back(tn);
|
|
}
|
|
}
|
|
return children;
|
|
}
|
|
|
|
std::string XMLNode::getFirstText()
|
|
{
|
|
XMLNode::XMLSet<XMLTextNode*> set = getTextChildren();
|
|
if (set.size() <= 0)
|
|
return "";
|
|
|
|
return set.front()->getContent();
|
|
}
|
|
|
|
XMLNode::XMLSet<XMLElement*> XMLNode::getElementChildren()
|
|
{
|
|
XMLNode::XMLSet<XMLElement*> children;
|
|
|
|
for (xmlNodePtr child = xmlNode->children; child; child = child->next) {
|
|
// check if name and/or type matches
|
|
if (child->_private && child->type == XML_ELEMENT_NODE) {
|
|
XMLElement* e = reinterpret_cast<XMLElement*>(child->_private);
|
|
children.push_back(e);
|
|
}
|
|
}
|
|
return children;
|
|
}
|