serialize to xml

This commit is contained in:
Filip Sykala 2021-09-21 19:25:54 +02:00
parent b975fe84ed
commit 28528c8344
2 changed files with 105 additions and 56 deletions

View File

@ -1,68 +1,101 @@
#include "TextConfigurationSerialization.hpp" #include "TextConfigurationSerialization.hpp"
#include "utils.hpp"
#include <cereal/archives/xml.hpp>
#include <strstream>
using namespace Slic3r; using namespace Slic3r;
// Convert map
const std::map<FontItem::Type, std::string> TextConfigurationSerialization::to_string = {
{FontItem::Type::file_path, "file_path"},
{FontItem::Type::wx_font_descr, "wx_font_descriptor"}
};
const std::string TextConfigurationSerialization::font_item = "FontItem"; const char TextConfigurationSerialization::separator = '|';
const std::string TextConfigurationSerialization::font_prop = "FontProp";
const std::string TextConfigurationSerialization::text = "Text";
namespace cereal { const std::map<std::string, FontItem::Type> TextConfigurationSerialization::to_type =
template<class Archive> TextConfigurationSerialization::create_oposit_map(TextConfigurationSerialization::to_string);
void serialize(Archive &archive, FontItem &font_item)
std::string TextConfigurationSerialization::serialize(const TextConfiguration &text_configuration)
{ {
archive( auto twice_separator = [](const std::string& data) {
CEREAL_NVP(font_item.name), if (data.empty()) return std::string(" ");
CEREAL_NVP(font_item.path) std::string::size_type pos = data.find(separator);
//,CEREAL_NVP(font_item.type) if (pos == data.npos) return data;
); // twice all separator inside data
std::string copy = data;
do {
copy.insert(pos, 1, separator);
pos += 2;
} while (copy.npos != (pos = copy.find(separator, pos)));
return copy;
};
const FontItem &font_item = text_configuration.font_item;
const FontProp &font_prop = text_configuration.font_prop;
return twice_separator(text_configuration.text) + separator +
twice_separator(font_item.name) + separator +
twice_separator(font_item.path) + separator +
to_string.at(font_item.type) + separator +
std::to_string(font_prop.emboss) + separator +
std::to_string(font_prop.flatness) + separator +
std::to_string(font_prop.size_in_mm) + separator +
std::to_string(font_prop.char_gap) + separator +
std::to_string(font_prop.line_gap);
} }
template<class Archive> void TextConfigurationSerialization::to_xml(
void serialize(Archive &archive, FontProp &font_prop) const TextConfiguration &text_configuration,
unsigned count_indent,
std::stringstream & stream)
{ {
archive( // Because of back compatibility must be main tag metadata (source: 3mf.cpp)
CEREAL_NVP(font_prop.char_gap), const std::string_view main_tag = "metadata";
CEREAL_NVP(font_prop.line_gap), const std::string_view main_name_attr = "name";
CEREAL_NVP(font_prop.flatness), const std::string_view main_name_value= "TextConfiguration";
CEREAL_NVP(font_prop.size_in_mm),
CEREAL_NVP(font_prop.emboss)
);
}
template<class Archive> const std::string_view font_item_tag = "fontItem";
void serialize(Archive &archive, TextConfiguration &text_configuration) const std::string_view name_attr = "name";
{ const std::string_view path_attr = "path";
archive(CEREAL_NVP(text_configuration.font_item), const std::string_view type_attr = "type";
CEREAL_NVP(text_configuration.font_prop),
CEREAL_NVP(text_configuration.text));
}
} // namespace cereal
std::string TextConfigurationSerialization::to_string( const std::string_view font_prop_tag = "fontProp";
const TextConfiguration &text_configuration) const std::string_view char_gap_attr = "charGap";
{ const std::string_view line_gap_attr = "lineGap";
std::strstream ss; const std::string_view flatness_attr = "flatness";
{ const std::string_view height_attr = "height";
cereal::XMLOutputArchive archive(ss); const std::string_view depth_attr = "depth";
// CEREAL_NVP - Names the output the same as the variable name
archive(CEREAL_NVP(text_configuration)); const std::string_view text_tag = "text";
}
std::string result = ss.str(); auto get_path = [&text_configuration]() {
static size_t start = std::string("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<cereal>\n\t").size(); const std::string &path = text_configuration.font_item.path;
size_t end = result.find("\n</cereal>", start); return xml_escape(
result = result.substr(start, end - start); (text_configuration.font_item.type == FontItem::Type::file_path) ?
return result; path.substr(path.find_last_of("/\\") + 1) : path);
};
std::string indent = std::string(count_indent, ' ');
std::string indent2 = std::string(count_indent+1, ' ');
stream << indent << "<" << main_tag << " " << main_name_attr << "=\"" << main_name_value << "\">\n";
stream << indent2 << "<" << font_item_tag
<< ' ' << name_attr << "=\"" << xml_escape(text_configuration.font_item.name) << '"'
<< ' ' << path_attr << "=\"" << get_path() << '"'
<< ' ' << type_attr << "=\"" << to_string.at(text_configuration.font_item.type) << '"'
<< "/>\n";
stream << indent2 << "<" << font_prop_tag
<< ' ' << char_gap_attr << "=\"" << text_configuration.font_prop.char_gap << '"'
<< ' ' << line_gap_attr << "=\"" << text_configuration.font_prop.line_gap << '"'
<< ' ' << flatness_attr << "=\"" << text_configuration.font_prop.flatness << '"'
<< ' ' << height_attr << "=\"" << text_configuration.font_prop.size_in_mm << '"'
<< ' ' << depth_attr << "=\"" << text_configuration.font_prop.emboss << '"'
<< "/>\n";
stream << indent2 << "<" << text_tag << ">";
stream << xml_escape(text_configuration.text);
stream << indent2 << "</" << text_tag << ">\n";
stream << indent << "</" << main_tag << ">\n";
} }
std::optional<TextConfiguration> TextConfigurationSerialization::from_string(const std::string &data) std::optional<TextConfiguration> TextConfigurationSerialization::from_string(const std::string &data)
{ {
std::strstream ss;
ss << data;
cereal::XMLInputArchive archive(ss);
TextConfiguration tc; TextConfiguration tc;
archive(tc);
return tc; return tc;
} }

View File

@ -3,6 +3,9 @@
#include "TextConfiguration.hpp" #include "TextConfiguration.hpp"
#include <optional> #include <optional>
#include <string_view>
#include <sstream>
#include <map>
namespace Slic3r { namespace Slic3r {
@ -11,13 +14,26 @@ class TextConfigurationSerialization
{ {
public: public:
TextConfigurationSerialization() = delete; // only static functions TextConfigurationSerialization() = delete; // only static functions
static std::string to_string(const TextConfiguration &text_configuration); static std::string serialize(const TextConfiguration &text_configuration);
static void to_xml(const TextConfiguration &text_configuration, unsigned count_indent, std::stringstream& stream);
static std::optional<TextConfiguration> from_string(const std::string &data); static std::optional<TextConfiguration> from_string(const std::string &data);
private: // convert type to string and vice versa
static const std::string font_item; static const std::map<std::string, FontItem::Type> to_type;
static const std::string font_prop; static const std::map<FontItem::Type, std::string> to_string;
static const std::string text;
static const char separator;
// Move to map utility
template<typename Key, typename Value>
static std::map<Value, Key> create_oposit_map(
const std::map<Key, Value> &map)
{
std::map<Value, Key> result;
for (const auto &it : map) result[it.second] = it.first;
return result;
}
}; };
} // namespace Slic3r } // namespace Slic3r