summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThorbjørn Lindeijer <bjorn@lindeijer.nl>2024-10-28 09:53:05 +0100
committerThorbjørn Lindeijer <bjorn@lindeijer.nl>2025-01-18 21:04:16 +0100
commitbbbc318634f3be2c4d755e71d99cdfba5c2b82f3 (patch)
tree0cf8e417eb33caae0e13192fa128ac69114fd4af
parent8ce74a1d4ea65a7a524070ae3589b6d04874a077 (diff)
downloadmana-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.cpp36
-rw-r--r--src/configuration.h10
-rw-r--r--src/utils/stringutils.cpp9
-rw-r--r--src/utils/stringutils.h4
-rw-r--r--src/utils/xml.cpp36
-rw-r--r--src/utils/xml.h87
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