Changeset View
Changeset View
Standalone View
Standalone View
source/ps/DataTreeXML.cpp
- This file was added.
/* Copyright (C) 2020 Wildfire Games. | |||||
* This file is part of 0 A.D. | |||||
* | |||||
* 0 A.D. is free software: you can redistribute it and/or modify | |||||
* it under the terms of the GNU General Public License as published by | |||||
* the Free Software Foundation, either version 2 of the License, or | |||||
* (at your option) any later version. | |||||
* | |||||
* 0 A.D. is distributed in the hope that it will be useful, | |||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
* GNU General Public License for more details. | |||||
* | |||||
* You should have received a copy of the GNU General Public License | |||||
* along with 0 A.D. If not, see <http://www.gnu.org/licenses/>. | |||||
*/ | |||||
#include "precompiled.h" | |||||
#include "DataTreeXML.h" | |||||
bool DataTreeXMLImpl::IsIncludeNode(const nodetype& node) const | |||||
{ | |||||
return node->type == XML_ELEMENT_NODE && | |||||
(xmlStrEqual(node->name, (xmlChar*)"include") || | |||||
xmlHasProp(node, (xmlChar*)"_parent") != nullptr); | |||||
; | |||||
} | |||||
VfsPath DataTreeXMLImpl::GetIncludePath(const VfsPath& filename, const nodetype& node) const | |||||
{ | |||||
if (xmlStrEqual(node->name, (xmlChar*)"include")) | |||||
return (filename.Parent() / reinterpret_cast<const char*>(xmlNodeGetContent(node))).ChangeExtension(".xml"); | |||||
xmlChar* merge_path = xmlGetProp(node, (xmlChar*)"_parent"); | |||||
VfsPath ret = (filename.Parent() / reinterpret_cast<const char*>(merge_path)).ChangeExtension(".xml"); | |||||
xmlFree(merge_path); | |||||
return ret; | |||||
} | |||||
bool DataTreeXMLImpl::CheckForInclude() const | |||||
{ | |||||
for (xmlNodePtr child = doc->children; child; child = child->next) | |||||
if (child->type == XML_PI_NODE && xmlStrEqual(child->name, (xmlChar*)"use_include")) | |||||
return true; | |||||
return false; | |||||
} | |||||
void DataTreeXMLImpl::ParseFile(const CVFSFile& input, const VfsPath& filename) | |||||
{ | |||||
doc = xmlReadMemory((const char*)input.GetBuffer(), input.GetBufferSize(), CStrW(filename.string()).ToUTF8().c_str(), NULL, | |||||
XML_PARSE_NONET|XML_PARSE_NOCDATA); | |||||
} | |||||
DataTreeXMLImpl::nodetype DataTreeXMLImpl::GetRootNode(const doctype& doc) const | |||||
{ | |||||
return xmlDocGetRootElement(doc); | |||||
} | |||||
DataTreeXMLImpl::nodetype DataTreeXMLImpl::GetSameChild(const nodetype& node, const nodetype& similar_to) const | |||||
{ | |||||
for (xmlNodePtr child = node->children; child; child = child->next) | |||||
if (xmlStrEqual(child->name, similar_to->name)) | |||||
return child; | |||||
return nullptr; | |||||
} | |||||
void DataTreeXMLImpl::AddChild(nodetype& node, nodetype& child) | |||||
{ | |||||
xmlNodePtr add = xmlDocCopyNode(child, doc, 1); | |||||
xmlAddChild(node, add); | |||||
} | |||||
void DataTreeXMLImpl::DeleteNode(nodetype& node) | |||||
{ | |||||
xmlUnlinkNode(node); | |||||
xmlFreeNode(node); | |||||
} | |||||
void DataTreeXMLImpl::UpdateNode(nodetype& node_to_update, const nodetype& reference) | |||||
{ | |||||
if (xmlStrEqual(node_to_update->name, (xmlChar*)"include") || xmlHasProp(node_to_update, (xmlChar*)"_parent") != nullptr) | |||||
{ | |||||
// Copy the node and its prop, but not children. | |||||
xmlNodePtr ref = xmlDocCopyNode(reference, doc, 2); | |||||
// Swap exitsting children so they're preserved. | |||||
for (xmlNodePtr child = node_to_update->children; child;) | |||||
{ | |||||
xmlNodePtr next = child->next; | |||||
if (child->type == XML_ELEMENT_NODE) | |||||
{ | |||||
xmlUnlinkNode(child); | |||||
xmlAddChild(ref, child); | |||||
} | |||||
child = next; | |||||
} | |||||
// Replace the node. | |||||
xmlAddNextSibling(node_to_update, ref); | |||||
xmlUnlinkNode(node_to_update); | |||||
xmlFreeNode(node_to_update); | |||||
if (xmlHasProp(node_to_update, (xmlChar*)"_parent") != nullptr) | |||||
xmlUnsetProp(node_to_update, (xmlChar*)"_parent"); | |||||
node_to_update = ref; | |||||
} | |||||
} | |||||
void DataTreeXMLImpl::PostMergeProcessing(nodetype& node) | |||||
{ | |||||
if (xmlHasProp(node, (xmlChar*)"temporary") != nullptr) | |||||
{ | |||||
// The node was a temporary node that needs to be dropped. | |||||
xmlNodePtr newnode = nullptr; | |||||
for (xmlNodePtr child = node->children; child;) | |||||
{ | |||||
xmlNodePtr temp = child->next; | |||||
newnode = xmlAddPrevSibling(node, child); | |||||
child = temp; | |||||
} | |||||
xmlUnlinkNode(node); | |||||
xmlFreeNode(node); | |||||
node = newnode; | |||||
} | |||||
} |
Wildfire Games · Phabricator