From 20d28e80a5c861a9d5f449ea911ab75b4f37ad0d Mon Sep 17 00:00:00 2001 From: Jef Date: Tue, 24 Sep 2024 14:54:57 +0200 Subject: Initial community commit --- Src/xml/XMLNode.cpp | 201 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 201 insertions(+) create mode 100644 Src/xml/XMLNode.cpp (limited to 'Src/xml/XMLNode.cpp') diff --git a/Src/xml/XMLNode.cpp b/Src/xml/XMLNode.cpp new file mode 100644 index 00000000..65fe1a36 --- /dev/null +++ b/Src/xml/XMLNode.cpp @@ -0,0 +1,201 @@ +#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(*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; +} \ No newline at end of file -- cgit