From 18562d4dcfefc16c50a6eb9a339b29aebf9ee3f5 Mon Sep 17 00:00:00 2001 From: num0005 Date: Mon, 26 Jul 2021 17:16:04 +0100 Subject: [PATCH] [XMLWriter] Add a new class for writing XML. Should have a much lower memory footprint than the ptree based writer. --- H2Codez/util/XMLWriter.h | 81 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 H2Codez/util/XMLWriter.h diff --git a/H2Codez/util/XMLWriter.h b/H2Codez/util/XMLWriter.h new file mode 100644 index 0000000..05ea848 --- /dev/null +++ b/H2Codez/util/XMLWriter.h @@ -0,0 +1,81 @@ +#pragma once +#include +#include +#include +#include +#include +#include "FastString.h" + +class XMLWriter { +public: + XMLWriter() = delete; + XMLWriter(std::ostream& stream) : _stream(stream) + {}; + ~XMLWriter() { + _stream.get().flush(); + } + + inline void write_self_closing(FastString name, FastString contents, std::optional> attributes = std::nullopt) { + start_element(name, attributes, true); + _stream.get() << contents.get() << " >\n"; + } + + inline void write(FastString name, std::function&)> setup, std::function element) { + std::map attributes; + setup(attributes); + + start_element(name, attributes, false); + + indent_level++; + while (element(*this)) {}; + indent_level--; + + write_end_element(name); + } + + inline void write(FastString name, std::function element, std::optional> attributes = std::nullopt) { + start_element(name, attributes, false); + + indent_level++; + while (element(*this)) {}; + indent_level--; + + write_end_element(name); + } + + +private: + + inline void write_indent(int additional = 0) { + std::fill_n(std::ostream_iterator(_stream), indent_level + additional, '\t'); + } + + inline void start_element(const FastString &element, std::optional > attributes, bool self_closing) { + + write_indent(); + + _stream.get() << "<" << element.get(); + + if (attributes) + write_attributes(attributes.value()); + + if (!self_closing) + _stream.get() << ">\n"; + else + _stream.get() << " "; + } + + inline void write_end_element(const FastString& element) { + write_indent(); + _stream.get() << "<\\" << element.get() << ">\n"; + } + + template + inline void write_attributes(T attributes) { + for (std::pair atpair : attributes) + _stream.get() << " " << atpair.first.get() << " = \"" << atpair.second.get() << "\""; + } + + int indent_level = 0; + std::reference_wrapper _stream; +}; \ No newline at end of file