201 lines
4.2 KiB
C++
201 lines
4.2 KiB
C++
|
#include "XMLNode.h"
|
||
|
|
||
|
static int CompareStuff(const wchar_t *const &str1, const wchar_t *const &str2)
|
||
|
{
|
||
|
return CompareStringW(MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT), 0, str1, -1, str2, -1)-2;
|
||
|
}
|
||
|
|
||
|
XMLNode::XMLNode() : content(0), content_len(0), parent(0)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
XMLNode::~XMLNode()
|
||
|
{
|
||
|
for (PropMap::iterator mapItr=properties.begin();mapItr != properties.end();mapItr++)
|
||
|
{
|
||
|
free((wchar_t *)mapItr->first);
|
||
|
free(mapItr->second);
|
||
|
}
|
||
|
|
||
|
for (NodeMap::iterator mapItr=nodes.begin();mapItr != nodes.end();mapItr++)
|
||
|
{
|
||
|
NodeList * const nodeList = mapItr->second;
|
||
|
if (nodeList)
|
||
|
{
|
||
|
for (NodeList::iterator itr=nodeList->begin(); itr!= nodeList->end(); itr++)
|
||
|
{
|
||
|
delete static_cast<XMLNode *>(*itr);
|
||
|
}
|
||
|
}
|
||
|
free((wchar_t *)mapItr->first);
|
||
|
}
|
||
|
|
||
|
if (content)
|
||
|
{
|
||
|
free(content);
|
||
|
content = 0;
|
||
|
content_len = 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
const XMLNode *XMLNode::Get(const wchar_t *tagName) const
|
||
|
{
|
||
|
NodeMap::const_iterator itr = nodes.find(tagName);
|
||
|
if (itr == nodes.end())
|
||
|
return 0;
|
||
|
else
|
||
|
{
|
||
|
NodeList *list = itr->second;
|
||
|
return list->at(0);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
const XMLNode::NodeList *XMLNode::GetList(const wchar_t *tagName) const
|
||
|
{
|
||
|
NodeMap::const_iterator itr = nodes.find(tagName);
|
||
|
if (itr == nodes.end())
|
||
|
{
|
||
|
return 0;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
NodeList *list = itr->second;
|
||
|
return list;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
const bool XMLNode::Present(const wchar_t *tagName) const
|
||
|
{
|
||
|
return nodes.find(tagName) != nodes.end();
|
||
|
}
|
||
|
|
||
|
// LEGACY implementaions!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||
|
//void XMLNode::SetProperty(const wchar_t *prop, const wchar_t *value)
|
||
|
//{
|
||
|
// PropMap::MapPair &pair = properties.getItem(prop);
|
||
|
// if (pair.first == prop) // replace with a copy if we made a new entry
|
||
|
// pair.first = _wcsdup(prop);
|
||
|
// free(pair.second);
|
||
|
// pair.second = _wcsdup(value);
|
||
|
//}
|
||
|
void XMLNode::SetProperty(const wchar_t* prop, const wchar_t* value)
|
||
|
{
|
||
|
auto it = properties.find(prop);
|
||
|
if (properties.end() == it)
|
||
|
{
|
||
|
properties.insert({ _wcsdup(prop), _wcsdup(value) });
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (nullptr != it->second)
|
||
|
{
|
||
|
free(it->second);
|
||
|
}
|
||
|
properties[prop] = _wcsdup(value);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void XMLNode::SetContent_Own(wchar_t *new_content)
|
||
|
{
|
||
|
if (content)
|
||
|
{
|
||
|
free(content);
|
||
|
content = 0;
|
||
|
content_len = 0;
|
||
|
}
|
||
|
|
||
|
if (new_content && *new_content)
|
||
|
{
|
||
|
content = new_content;
|
||
|
content_len = wcslen(content);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void XMLNode::AppendContent(wchar_t *append)
|
||
|
{
|
||
|
if (append && *append)
|
||
|
{
|
||
|
if (content)
|
||
|
{
|
||
|
size_t len = wcslen(append), new_len = len + content_len;
|
||
|
wchar_t *new_content = (wchar_t *)realloc(content, (new_len+1)*sizeof(wchar_t));
|
||
|
if (new_content)
|
||
|
{
|
||
|
content = new_content;
|
||
|
wcsncpy(content+content_len, append, len);
|
||
|
*(content+content_len+len) = 0;
|
||
|
content_len = new_len;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
new_content = (wchar_t *)malloc((new_len+1)*sizeof(wchar_t));
|
||
|
if (new_content)
|
||
|
{
|
||
|
memcpy(new_content, content, content_len*sizeof(wchar_t));
|
||
|
free(content);
|
||
|
content = new_content;
|
||
|
|
||
|
wcsncpy(content+content_len, append, len);
|
||
|
*(content+content_len+len) = 0;
|
||
|
content_len = new_len;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
content_len = wcslen(append);
|
||
|
content = (wchar_t *)malloc((content_len+1)*sizeof(wchar_t));
|
||
|
if (content)
|
||
|
memcpy(content, append, (content_len+1)*sizeof(wchar_t));
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// LEGACY implementaions!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||
|
//void XMLNode::AddNode(const wchar_t *name, XMLNode *new_node)
|
||
|
//{
|
||
|
// // first, add entry in nodes map
|
||
|
// NodeMap::MapPair &pair = nodes.getItem(name);
|
||
|
// if (pair.first == name) // replace with a copy if we made a new entry
|
||
|
// pair.first = _wcsdup(name);
|
||
|
//
|
||
|
// // make the node list if we need it
|
||
|
// if (!pair.second)
|
||
|
// pair.second = new NodeList;
|
||
|
//
|
||
|
// pair.second->push_back(new_node);
|
||
|
//}
|
||
|
void XMLNode::AddNode(const wchar_t* name, XMLNode* new_node)
|
||
|
{
|
||
|
auto it = nodes.find(name);
|
||
|
if (nodes.end() == it)
|
||
|
{
|
||
|
nodes.insert({ _wcsdup(name), new NodeList() });
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (nullptr == it->second)
|
||
|
{
|
||
|
nodes[name] = new NodeList();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
nodes[name]->push_back(new_node);
|
||
|
}
|
||
|
|
||
|
const wchar_t *XMLNode::GetContent() const
|
||
|
{
|
||
|
return content;
|
||
|
}
|
||
|
|
||
|
const wchar_t *XMLNode::GetProperty(const wchar_t *prop) const
|
||
|
{
|
||
|
for (PropMap::const_iterator mapItr = properties.begin(); mapItr != properties.end(); mapItr++)
|
||
|
{
|
||
|
if (CompareStuff(mapItr->first, prop) == 0)
|
||
|
{
|
||
|
return mapItr->second;
|
||
|
}
|
||
|
}
|
||
|
return 0;
|
||
|
}
|