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

View File

@ -3,6 +3,9 @@
#include "TextConfiguration.hpp"
#include <optional>
#include <string_view>
#include <sstream>
#include <map>
namespace Slic3r {
@ -11,13 +14,26 @@ class TextConfigurationSerialization
{
public:
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);
private:
static const std::string font_item;
static const std::string font_prop;
static const std::string text;
// convert type to string and vice versa
static const std::map<std::string, FontItem::Type> to_type;
static const std::map<FontItem::Type, std::string> to_string;
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