diff options
author | Thorbjørn Lindeijer <bjorn@lindeijer.nl> | 2024-10-28 09:53:05 +0100 |
---|---|---|
committer | Thorbjørn Lindeijer <bjorn@lindeijer.nl> | 2025-01-18 21:04:16 +0100 |
commit | bbbc318634f3be2c4d755e71d99cdfba5c2b82f3 (patch) | |
tree | 0cf8e417eb33caae0e13192fa128ac69114fd4af | |
parent | 8ce74a1d4ea65a7a524070ae3589b6d04874a077 (diff) | |
download | mana-bbbc318634f3be2c4d755e71d99cdfba5c2b82f3.tar.gz mana-bbbc318634f3be2c4d755e71d99cdfba5c2b82f3.tar.bz2 mana-bbbc318634f3be2c4d755e71d99cdfba5c2b82f3.tar.xz mana-bbbc318634f3be2c4d755e71d99cdfba5c2b82f3.zip |
Introduced small convenience wrapper to write XML
Might not seem worth it right now, but it will be if we write out more
XML structures.
-rw-r--r-- | src/configuration.cpp | 36 | ||||
-rw-r--r-- | src/configuration.h | 10 | ||||
-rw-r--r-- | src/utils/stringutils.cpp | 9 | ||||
-rw-r--r-- | src/utils/stringutils.h | 4 | ||||
-rw-r--r-- | src/utils/xml.cpp | 36 | ||||
-rw-r--r-- | src/utils/xml.h | 87 |
6 files changed, 140 insertions, 42 deletions
diff --git a/src/configuration.cpp b/src/configuration.cpp index f0499b2d..084c8563 100644 --- a/src/configuration.cpp +++ b/src/configuration.cpp @@ -269,32 +269,30 @@ void Configuration::init(const std::string &filename, bool useResManager) initFromXML(rootNode); } -void ConfigurationObject::writeToXML(xmlTextWriterPtr writer) +void ConfigurationObject::writeToXML(XML::Writer &writer) const { - for (const auto &option : mOptions) + for (auto &[name, value] : mOptions) { - xmlTextWriterStartElement(writer, BAD_CAST "option"); - xmlTextWriterWriteAttribute(writer, - BAD_CAST "name", BAD_CAST option.first.c_str()); - xmlTextWriterWriteAttribute(writer, - BAD_CAST "value", BAD_CAST option.second.c_str()); - xmlTextWriterEndElement(writer); + writer.startElement("option"); + writer.addAttribute("name", name); + writer.addAttribute("value", value); + writer.endElement(); } for (auto &[name, list] : mContainerOptions) { - xmlTextWriterStartElement(writer, BAD_CAST "list"); - xmlTextWriterWriteAttribute(writer, BAD_CAST "name", BAD_CAST name.c_str()); + writer.startElement("list"); + writer.addAttribute("name", name); // Recurse on all elements for (auto element : list) { - xmlTextWriterStartElement(writer, BAD_CAST name.c_str()); + writer.startElement(name.c_str()); element->writeToXML(writer); - xmlTextWriterEndElement(writer); + writer.endElement(); } - xmlTextWriterEndElement(writer); + writer.endElement(); } } @@ -312,9 +310,9 @@ void Configuration::write() fclose(testFile); - xmlTextWriterPtr writer = xmlNewTextWriterFilename(mConfigPath.c_str(), 0); + XML::Writer writer(mConfigPath); - if (!writer) + if (!writer.isValid()) { logger->log("Configuration::write() error while creating writer"); return; @@ -322,12 +320,6 @@ void Configuration::write() logger->log("Configuration::write() writing configuration..."); - xmlTextWriterSetIndent(writer, 1); - xmlTextWriterStartDocument(writer, nullptr, nullptr, nullptr); - xmlTextWriterStartElement(writer, BAD_CAST "configuration"); - + writer.startElement("configuration"); writeToXML(writer); - - xmlTextWriterEndDocument(writer); - xmlFreeTextWriter(writer); } diff --git a/src/configuration.h b/src/configuration.h index a26c6e20..41071304 100644 --- a/src/configuration.h +++ b/src/configuration.h @@ -22,10 +22,10 @@ #ifndef CONFIGURATION_H #define CONFIGURATION_H -#include "utils/stringutils.h" #include "defaults.h" -#include <libxml/xmlwriter.h> +#include "utils/stringutils.h" +#include "utils/xml.h" #include <cassert> #include <list> @@ -108,7 +108,7 @@ class ConfigurationObject /** * Re-sets all data in the configuration */ - virtual void clear(); + void clear(); /** * Serialises a container into a list of configuration options @@ -171,8 +171,8 @@ class ConfigurationObject } protected: - virtual void initFromXML(xmlNodePtr node); - virtual void writeToXML(xmlTextWriterPtr writer); + void initFromXML(xmlNodePtr node); + void writeToXML(XML::Writer &writer) const; void deleteList(std::list<ConfigurationObject *> &list); diff --git a/src/utils/stringutils.cpp b/src/utils/stringutils.cpp index 17f5c453..747243fd 100644 --- a/src/utils/stringutils.cpp +++ b/src/utils/stringutils.cpp @@ -168,13 +168,12 @@ std::string findSameSubstring(const std::string &str1, return str1.substr(0, minLength); } -bool getBoolFromString(const std::string &text, bool def) +bool getBoolFromString(std::string text, bool def) { - std::string a = text; - toLower(trim(a)); - if (a == "true" || a == "1" || a == "on" || a == "yes" || a == "y") + toLower(trim(text)); + if (text == "true" || text == "1" || text == "on" || text == "yes" || text == "y") return true; - if (a == "false" || a == "0" || a == "off" || a == "no" || a == "n") + if (text == "false" || text == "0" || text == "off" || text == "no" || text == "n") return false; return def; diff --git a/src/utils/stringutils.h b/src/utils/stringutils.h index b394e29f..d6c45474 100644 --- a/src/utils/stringutils.h +++ b/src/utils/stringutils.h @@ -67,7 +67,7 @@ unsigned int atox(const std::string &str); */ template<typename T> std::string toString(const T &arg) { - std::stringstream ss; + std::ostringstream ss; ss << arg; return ss.str(); } @@ -142,7 +142,7 @@ std::string findSameSubstring(const std::string &str1, * @param text the string used to get the bool value * @return a boolean value.. */ -bool getBoolFromString(const std::string &text, bool def = false); +bool getBoolFromString(std::string text, bool def = false); /** * Returns the most approaching string of base from candidates. diff --git a/src/utils/xml.cpp b/src/utils/xml.cpp index 72de10c7..a1b1fa75 100644 --- a/src/utils/xml.cpp +++ b/src/utils/xml.cpp @@ -116,8 +116,7 @@ namespace XML { int &ret = def; - xmlChar *prop = xmlGetProp(node, BAD_CAST name); - if (prop) + if (xmlChar *prop = xmlGetProp(node, BAD_CAST name)) { ret = atol((char*)prop); xmlFree(prop); @@ -130,8 +129,7 @@ namespace XML { double &ret = def; - xmlChar *prop = xmlGetProp(node, BAD_CAST name); - if (prop) + if (xmlChar *prop = xmlGetProp(node, BAD_CAST name)) { ret = atof((char*)prop); xmlFree(prop); @@ -143,8 +141,7 @@ namespace XML std::string getProperty(xmlNodePtr node, const char *name, const std::string &def) { - xmlChar *prop = xmlGetProp(node, BAD_CAST name); - if (prop) + if (xmlChar *prop = xmlGetProp(node, BAD_CAST name)) { std::string val = (char*)prop; xmlFree(prop); @@ -157,8 +154,8 @@ namespace XML bool getBoolProperty(xmlNodePtr node, const char* name, bool def) { bool ret = def; - xmlChar *prop = xmlGetProp(node, BAD_CAST name); - if (prop) + + if (xmlChar *prop = xmlGetProp(node, BAD_CAST name)) { ret = getBoolFromString((char*) prop, def); xmlFree(prop); @@ -186,4 +183,27 @@ namespace XML xmlSetStructuredErrorFunc(nullptr, xmlLogger); } + + Writer::Writer(const std::string &fileName) + { + mWriter = xmlNewTextWriterFilename(fileName.c_str(), 0); + if (!mWriter) + { + logger->log("Error creating XML writer for file %s", fileName.c_str()); + return; + } + + xmlTextWriterSetIndent(mWriter, 1); + xmlTextWriterStartDocument(mWriter, nullptr, nullptr, nullptr); + } + + Writer::~Writer() + { + if (!mWriter) + return; + + xmlTextWriterEndDocument(mWriter); + xmlFreeTextWriter(mWriter); + } + } // namespace XML diff --git a/src/utils/xml.h b/src/utils/xml.h index fe15273b..6878397a 100644 --- a/src/utils/xml.h +++ b/src/utils/xml.h @@ -22,8 +22,11 @@ #ifndef XML_H #define XML_H +#include "utils/stringutils.h" + #include <libxml/parser.h> #include <libxml/tree.h> +#include <libxml/xmlwriter.h> #include <string> @@ -124,6 +127,90 @@ namespace XML private: xmlNodePtr mNode; }; + + /** + * Helper class for writing out XML data. + * + * Based on libxml2's text writing API for XML. + */ + class Writer + { + public: + Writer(const std::string &fileName); + ~Writer(); + + bool isValid() const { return mWriter != nullptr; } + + void startElement(const char *name); + void endElement(); + + void addAttribute(const char *name, const std::string &value); + void addAttribute(const char *name, const char *value); + void addAttribute(const char *name, int value); + void addAttribute(const char *name, unsigned value); + void addAttribute(const char *name, float value); + void addAttribute(const char *name, bool value); + + template<typename Enum, std::enable_if_t<std::is_enum_v<Enum>, bool> = true> + void addAttribute(const char *name, Enum &value); + + void writeText(const std::string &text); + + private: + xmlTextWriterPtr mWriter; + }; + + template<typename Enum, std::enable_if_t<std::is_enum_v<Enum>, bool>> + inline void Writer::addAttribute(const char *name, Enum &value) + { + return addAttribute(name, static_cast<int>(value)); + } + + inline void Writer::startElement(const char *name) + { + xmlTextWriterStartElement(mWriter, BAD_CAST name); + } + + inline void Writer::endElement() + { + xmlTextWriterEndElement(mWriter); + } + + inline void Writer::addAttribute(const char *name, const std::string &value) + { + addAttribute(name, value.c_str()); + } + + inline void Writer::addAttribute(const char *name, const char *value) + { + xmlTextWriterWriteAttribute(mWriter, BAD_CAST name, BAD_CAST value); + } + + inline void Writer::addAttribute(const char *name, int value) + { + xmlTextWriterWriteAttribute(mWriter, BAD_CAST name, BAD_CAST toString(value).c_str()); + } + + inline void Writer::addAttribute(const char *name, unsigned value) + { + xmlTextWriterWriteAttribute(mWriter, BAD_CAST name, BAD_CAST toString(value).c_str()); + } + + inline void Writer::addAttribute(const char *name, float value) + { + xmlTextWriterWriteAttribute(mWriter, BAD_CAST name, BAD_CAST toString(value).c_str()); + } + + inline void Writer::addAttribute(const char *name, bool value) + { + xmlTextWriterWriteAttribute(mWriter, BAD_CAST name, BAD_CAST (value ? "1" : "0")); + } + + inline void Writer::writeText(const std::string &text) + { + xmlTextWriterWriteString(mWriter, BAD_CAST text.c_str()); + } + } #endif // XML_H |