Serialize.cpp 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. #include "Serialize.h"
  2. #include "tinyxml2.h"
  3. #include "XmlException.h"
  4. #include <sstream>
  5. using alm::ImageView;
  6. using alm::XmlException;
  7. using tinyxml2::XMLElement;
  8. using tinyxml2::XMLDocument;
  9. using tinyxml2::XMLError;
  10. using tinyxml2::XMLNode;
  11. using tinyxml2::XML_SUCCESS;
  12. template<>
  13. alm::Gradient alm::deserialize<alm::Gradient>(XMLElement* elem)
  14. {
  15. if (elem == nullptr)
  16. throw alm::XmlException{ "invalid root node" };
  17. bool repeat = false;
  18. bool hasMax = false;
  19. float maxVal = 0.0f;
  20. repeat = elem->BoolAttribute("repeat", false);
  21. XMLError e = elem->QueryFloatAttribute("max", &maxVal);
  22. if (e == XML_SUCCESS)
  23. hasMax = true;
  24. std::vector<std::pair<RGBColor, float>> points;
  25. XMLElement* colorNode = elem->FirstChildElement("color");
  26. while(colorNode != nullptr) {
  27. int r = colorNode->IntAttribute("r");
  28. int g = colorNode->IntAttribute("g");
  29. int b = colorNode->IntAttribute("b");
  30. float p = colorNode->FloatAttribute("p");
  31. uint8_t cr = uint8_t(std::clamp(r, 0, 255));
  32. uint8_t cg = uint8_t(std::clamp(g, 0, 255));
  33. uint8_t cb = uint8_t(std::clamp(b, 0, 255));
  34. points.push_back(std::make_pair(RGBColor{ cr, cg, cb }, p));
  35. colorNode = colorNode->NextSiblingElement("color");
  36. }
  37. if (hasMax)
  38. return Gradient{ std::move(points), maxVal, repeat };
  39. else
  40. return Gradient{ std::move(points), repeat };
  41. }
  42. template<>
  43. tinyxml2::XMLElement* alm::serialize<alm::Gradient>(tinyxml2::XMLDocument& doc, const alm::Gradient&)
  44. {
  45. return nullptr;
  46. }
  47. template<>
  48. alm::Gradient alm::fromXml<alm::Gradient>(const std::string& xml)
  49. {
  50. XMLDocument xmlDoc;
  51. XMLError err = xmlDoc.Parse(xml.c_str());
  52. if (err != XML_SUCCESS)
  53. throw alm::XmlException{ "error parsing gradient xml" };
  54. return deserialize<Gradient>(xmlDoc.RootElement());
  55. }
  56. template<>
  57. std::string alm::toXml<alm::Gradient>(const alm::Gradient& g)
  58. {
  59. std::stringstream buf;
  60. std::string version = "1.0.0";
  61. buf << "<gradient max=\"" << g.getMax() << "\" repeat=\"" << (g.isRepeat() ? "true" : "false")
  62. << "\" version=\"" << version << "\" >" << std::endl;
  63. for (const auto&[color, val] : g.getPoints()) {
  64. buf << " <color " <<
  65. "r=\"" << int(color.r) <<
  66. "\" g=\"" << int(color.g) <<
  67. "\" b=\"" << int(color.b) <<
  68. "\" p=\"" << val << "\" />" << std::endl;
  69. }
  70. buf << "</gradient>" << std::endl;
  71. return buf.str();
  72. }