Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/WolfireGames/overgrowth.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'Source/XML/xml_helper.cpp')
-rw-r--r--Source/XML/xml_helper.cpp292
1 files changed, 292 insertions, 0 deletions
diff --git a/Source/XML/xml_helper.cpp b/Source/XML/xml_helper.cpp
new file mode 100644
index 00000000..cbe21253
--- /dev/null
+++ b/Source/XML/xml_helper.cpp
@@ -0,0 +1,292 @@
+//-----------------------------------------------------------------------------
+// Name: xml_helper.cpp
+// Developer: Wolfire Games LLC
+// Description:
+// License: Read below
+//-----------------------------------------------------------------------------
+//
+// Copyright 2022 Wolfire Games LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-----------------------------------------------------------------------------
+
+#include <Internal/error.h>
+#include <Internal/common.h>
+#include <Internal/filesystem.h>
+
+#include <Memory/allocation.h>
+#include <XML/xml_helper.h>
+#include <Compat/fileio.h>
+
+TiXmlElement *XmlHelper::findNode(TiXmlDocument &doc, std::string &item, TiXmlElement* element)
+{
+ //TiXmlElement* element = NULL;
+ while(item.size())
+ {
+ if (element == NULL)
+ {
+ element = doc.FirstChildElement(item.substr(0, item.find("/")));
+ }
+ else
+ {
+ element = element->FirstChildElement(item.substr(0, item.find("/")));
+ }
+
+ if (element == NULL)
+ return NULL;
+
+ if (std::string::npos != item.find("/"))
+ item = item.substr(item.find("/") + 1);
+ else
+ item = "";
+ }
+
+ return element;
+}
+
+TiXmlElement *XmlHelper::findNode(TiXmlDocument &doc, const char *item, TiXmlElement* element)
+{
+ std::string i = item;
+ return findNode(doc, i, element);
+}
+
+bool XmlHelper::getNodeValue(TiXmlDocument &doc, const char *item, std::string &text)
+{
+ std::string istr(item);
+ TiXmlElement* element = findNode(doc, istr);
+
+ if (element != NULL)
+ {
+ text = element->GetText();
+ return true;
+ }
+
+ return false;
+}
+
+bool XmlHelper::getNodeValue(TiXmlDocument &doc, const char *item, double &d)
+{
+ std::string text;
+ bool retval = getNodeValue(doc, item, text);
+
+ if (retval)
+ {
+ d = ::atof(text.c_str());
+ }
+
+ return retval;
+}
+
+bool XmlHelper::getNodeValue(TiXmlDocument &doc, const char *item, float &f)
+{
+ std::string text;
+ bool retval = getNodeValue(doc, item, text);
+
+ if (retval)
+ {
+ f = (float)(::atof(text.c_str()));
+ }
+
+ return retval;
+}
+
+bool XmlHelper::getNodeValue(TiXmlDocument &doc, TiXmlElement *element, const char *item, std::string &text)
+{
+ std::string istr(item);
+ element = findNode(doc, istr, element);
+
+ if (element != NULL)
+ {
+ text = element->GetText();
+ return true;
+ }
+
+ return false;
+}
+
+bool XmlHelper::getNodeValue(TiXmlDocument &doc, TiXmlElement *element, const char *item, double &d)
+{
+ std::string text;
+ bool retval = getNodeValue(doc, element, item, text);
+
+ if (retval)
+ {
+ d = ::atof(text.c_str());
+ }
+
+ return retval;
+}
+
+bool XmlHelper::getNodeValue(TiXmlDocument &doc, TiXmlElement *element, const char *item, float &f)
+{
+ std::string text;
+ bool retval = getNodeValue(doc, element, item, text);
+
+ if (retval)
+ {
+ f = (float)(::atof(text.c_str()));
+ }
+
+ return retval;
+}
+
+void GetRange(const TiXmlElement *el,
+ const std::string &val_str,
+ const std::string &min_str,
+ const std::string &max_str,
+ float &min_val,
+ float &max_val)
+{
+ int result = el->QueryFloatAttribute(val_str.c_str(), &min_val);
+ if(result != TIXML_SUCCESS){
+ result = el->QueryFloatAttribute(min_str.c_str(), &min_val);
+ result = el->QueryFloatAttribute(max_str.c_str(), &max_val);
+ } else {
+ max_val = min_val;
+ }
+}
+
+bool LoadXML( TiXmlDocument& doc,
+ const std::string &path,
+ const std::string type )
+{
+ char abs_path[kPathSize];
+ bool retry = true;
+ if (FindFilePath(path.c_str(), abs_path, kPathSize, kDataPaths | kModPaths | kAbsPath) == -1){
+ return false;
+ }
+ doc.LoadFile(abs_path);
+ return true;
+}
+
+bool LoadXMLRetryable( TiXmlDocument& doc,
+ const std::string &path,
+ const std::string type )
+{
+ char abs_path[kPathSize];
+ bool retry = true;
+ if (FindFilePath(path.c_str(), abs_path, kPathSize, kDataPaths | kModPaths | kAbsPath) == -1){
+ ErrorResponse err;
+ while(retry){
+ err = DisplayError("Error",
+ (type+" file \""+path+"\" did not load correctly.").c_str(),
+ _ok_cancel_retry);
+ if(err != _retry){
+ return false;
+ }
+ if (FindFilePath(path.c_str(), abs_path, kPathSize, kDataPaths | kModPaths | kAbsPath) != -1){
+ retry = false;
+ }
+ }
+ }
+ doc.LoadFile(abs_path);
+ return true;
+}
+
+uint8_t* StackLoadText(const char* path, size_t* size_out) {
+ uint8_t* mem = NULL;
+ long file_size = 0;
+ char abs_path[kPathSize];
+ bool retry = true;
+ if (FindFilePath(path, abs_path, kPathSize, kDataPaths | kModPaths | kAbsPath) != -1) {
+ FILE* file = my_fopen(abs_path, "rb");
+ if(file) {
+ fseek (file, 0, SEEK_END);
+ file_size = ftell(file);
+ if( file_size > 0 ) {
+ rewind (file);
+
+ LOG_ASSERT(file_size < (1024 * 1024));
+
+ mem = (uint8_t*)alloc.stack.Alloc(file_size+1);
+ if(mem) {
+ size_t count = fread(mem, 1, file_size, file);
+ if( (long)count == file_size ) {
+ mem[file_size] = '\0';
+ } else {
+ LOGE << "Did not read expected amount of data from file: " << abs_path << std::endl;
+ alloc.stack.Free(mem);
+ mem = NULL;
+ }
+ } else {
+ LOGF << "Could not allocate " << file_size + 1 << " bytes on stack for file " << abs_path << std::endl;
+ }
+ }
+ fclose(file);
+ }
+ }
+
+ if( size_out ) {
+ *size_out = file_size;
+ }
+ return mem;
+}
+
+bool LoadText(void* &mem, const char* path){
+ FILE* file = my_fopen(path, "rb");
+ if(!file){
+ return false;
+ }
+
+ fseek (file, 0, SEEK_END);
+ long file_size = ftell(file);
+ rewind (file);
+
+ mem = OG_MALLOC(file_size+1);
+ if(!mem){
+ FatalError("Error", "Could not allocate memory for file: %s", path);
+ }
+ size_t read = fread(mem, 1, file_size, file);
+
+ if( read != file_size ) {
+ LOGW << "Read less than ftell told us we would!" << std::endl;
+ }
+
+ ((char*)mem)[read] = '\0';
+
+ fclose(file);
+
+ return true;
+}
+
+bool LoadTextRetryable(void* &mem,
+ const std::string &path,
+ const std::string type )
+{
+ char abs_path[kPathSize];
+ bool retry = true;
+ if (FindFilePath(path.c_str(), abs_path, kPathSize, kDataPaths | kModPaths | kAbsPath) == -1) {
+ ErrorResponse err;
+ while(retry){
+ err = DisplayError("Error",
+ (type+" file \""+path+"\" did not load correctly.").c_str(),
+ _ok_cancel_retry);
+ if(err != _retry){
+ return false;
+ }
+ if (FindFilePath(path.c_str(), abs_path, kPathSize, kDataPaths | kModPaths | kAbsPath) != -1){
+ retry = false;
+ }
+ }
+ }
+ LoadText(mem, abs_path);
+ return true;
+}
+
+void LoadAttribIntoString(TiXmlElement* el, const char* attrib, std::string &str){
+ const char* label = el->Attribute(attrib);
+ if(label){
+ str = label;
+ }
+}