From 4af1317f4536034e74c22c63d62c5121110aff86 Mon Sep 17 00:00:00 2001 From: randomdan Date: Thu, 11 Sep 2014 16:39:26 +0000 Subject: Slicer core to operate on any types passed to constructor, not just boost paths Extend implementations to work on their native document types + covering tests --- slicer/json/Jamfile.jam | 2 + slicer/json/serializer.cpp | 31 ++++++++++--- slicer/json/serializer.h | 30 ++++++++----- slicer/slicer/slicer.h | 13 +++--- slicer/test/run-slicer.cpp | 110 ++++++++++++++++++++++++++++++++++++++++----- slicer/xml/Jamfile.jam | 2 + slicer/xml/serializer.cpp | 32 ++++++++++--- slicer/xml/serializer.h | 34 ++++++++------ 8 files changed, 199 insertions(+), 55 deletions(-) diff --git a/slicer/json/Jamfile.jam b/slicer/json/Jamfile.jam index 27022ee..0a0b02a 100644 --- a/slicer/json/Jamfile.jam +++ b/slicer/json/Jamfile.jam @@ -20,4 +20,6 @@ lib slicer-json : IceUtil jsonpp glibmm + : : + jsonpp ; diff --git a/slicer/json/serializer.cpp b/slicer/json/serializer.cpp index d680a69..0aae914 100644 --- a/slicer/json/serializer.cpp +++ b/slicer/json/serializer.cpp @@ -156,11 +156,6 @@ namespace Slicer { ModelPartPtr modelPart; }; - Json::Json(const boost::filesystem::path & p) : - path(p) - { - } - void Json::ModelTreeIterateSeq(json::Value * n, ModelPartPtr mp) { @@ -232,8 +227,13 @@ namespace Slicer { } } + JsonFile::JsonFile(const boost::filesystem::path & p) : + path(p) + { + } + void - Json::Deserialize(ModelPartPtr modelRoot) + JsonFile::Deserialize(ModelPartPtr modelRoot) { std::ifstream inFile(path.string()); std::stringstream buffer; @@ -245,13 +245,30 @@ namespace Slicer { } void - Json::Serialize(ModelPartPtr modelRoot) + JsonFile::Serialize(ModelPartPtr modelRoot) { json::Value doc; modelRoot->OnEachChild(boost::bind(&Json::ModelTreeIterateRoot, &doc, _2)); std::ofstream outFile(path.string()); json::serializeValue(doc, outFile, "utf-8"); } + + JsonValue::JsonValue(json::Value & v) : + value(v) + { + } + + void + JsonValue::Deserialize(ModelPartPtr modelRoot) + { + boost::apply_visitor(DocumentTreeIterate(modelRoot->GetChild(std::string())), value); + } + + void + JsonValue::Serialize(ModelPartPtr modelRoot) + { + modelRoot->OnEachChild(boost::bind(&Json::ModelTreeIterateRoot, &value, _2)); + } } diff --git a/slicer/json/serializer.h b/slicer/json/serializer.h index c6bfb52..a01b836 100644 --- a/slicer/json/serializer.h +++ b/slicer/json/serializer.h @@ -2,27 +2,37 @@ #define SLICER_JSON_H #include - -namespace json { - class Value; -} +#include namespace Slicer { class Json : public Serializer { - public: - Json(const boost::filesystem::path &); - - virtual void Deserialize(ModelPartPtr) override; - virtual void Serialize(ModelPartPtr) override; - protected: static void ModelTreeIterate(json::Value *, const std::string &, ModelPartPtr mp); static void ModelTreeIterateSeq(json::Value *, ModelPartPtr mp); static void ModelTreeIterateRoot(json::Value *, ModelPartPtr mp); + }; + + class JsonFile : public Json { + public: + JsonFile(const boost::filesystem::path &); + + virtual void Deserialize(ModelPartPtr) override; + virtual void Serialize(ModelPartPtr) override; private: const boost::filesystem::path path; }; + + class JsonValue : public Json { + public: + JsonValue(json::Value &); + + virtual void Deserialize(ModelPartPtr) override; + virtual void Serialize(ModelPartPtr) override; + + private: + json::Value & value; + }; } #endif diff --git a/slicer/slicer/slicer.h b/slicer/slicer/slicer.h index 01b040d..d8d9f8e 100644 --- a/slicer/slicer/slicer.h +++ b/slicer/slicer/slicer.h @@ -2,27 +2,26 @@ #define SLICER_H #include -#include #include #include namespace Slicer { - template + template IceInternal::Handle - Deserialize(const boost::filesystem::path & path) + Deserialize(SerializerParams & ... sp) { IceUtil::Handle>> root = new ModelPartForClassRoot>(); - SerializerPtr serializer = new Serializer(path); + SerializerPtr serializer = new Serializer(sp ...); serializer->Deserialize(root); return root->GetModel(); } - template + template void - Serialize(IceInternal::Handle object, const boost::filesystem::path & path) + Serialize(IceInternal::Handle object, SerializerParams & ... sp) { IceUtil::Handle>> root = new ModelPartForClassRoot>(object); - SerializerPtr serializer = new Serializer(path); + SerializerPtr serializer = new Serializer(sp ...); serializer->Serialize(root); } } diff --git a/slicer/test/run-slicer.cpp b/slicer/test/run-slicer.cpp index 955b735..0044c64 100644 --- a/slicer/test/run-slicer.cpp +++ b/slicer/test/run-slicer.cpp @@ -1,6 +1,8 @@ #include #include +#include #include +#include #include #include #include @@ -9,13 +11,14 @@ #include #include #include +#include #include "helpers.h" namespace fs = boost::filesystem; template void -verify(const fs::path & root, const fs::path & tmp, const fs::path & infile, const boost::function & check = NULL) +verifyByFile(const fs::path & root, const fs::path & tmp, const fs::path & infile, const boost::function & check = NULL) { const fs::path input = root / "initial" / infile; const fs::path output = tmp / infile; @@ -29,9 +32,9 @@ verify(const fs::path & root, const fs::path & tmp, const fs::path & infile, con check(*p); } fprintf(stderr, "%s : Serialize -> %s\n", input.string().c_str(), outputJson.string().c_str()); - Slicer::Serialize(p, outputJson); + Slicer::Serialize(p, outputJson); fprintf(stderr, "%s : Serialize -> %s\n", input.string().c_str(), outputXml.string().c_str()); - Slicer::Serialize(p, outputXml); + Slicer::Serialize(p, outputXml); if (check) { fprintf(stderr, "%s : Check2\n", input.string().c_str()); check(*p); @@ -41,6 +44,45 @@ verify(const fs::path & root, const fs::path & tmp, const fs::path & infile, con system(stringbf("diff -w %s %s", input, output)); } +template +void +verifyByHelper(const fs::path & root, const fs::path & tmp, const fs::path & infile, + const boost::function & in, + const boost::function & out, + const boost::function & ifree, + const boost::function & check = NULL) +{ + const fs::path input = root / "initial" / infile; + const fs::path output = tmp / infile; + + fprintf(stderr, "%s : Read\n", input.string().c_str()); + Internal docRead = in(input); + + fprintf(stderr, "%s : Deserialize\n", input.string().c_str()); + IceInternal::Handle p = Slicer::Deserialize(docRead); + ifree(docRead); + if (check) { + fprintf(stderr, "%s : Check1\n", input.string().c_str()); + check(*p); + } + + fprintf(stderr, "%s : Serialize\n", input.string().c_str()); + Internal docWrite; + Slicer::Serialize(p, docWrite); + if (check) { + fprintf(stderr, "%s : Check2\n", input.string().c_str()); + check(*p); + } + + fprintf(stderr, "%s : Write\n", input.string().c_str()); + out(docWrite, output); + ifree(docWrite); + + fprintf(stderr, "%s : OK\n", input.string().c_str()); + + system(stringbf("diff -w %s %s", input, output)); +} + void checkBuiltIns_valuesCorrect(const TestModule::BuiltIns & bt) { @@ -91,6 +133,47 @@ checkOptionals_areset(const TestModule::Optionals & opts) BOOST_ASSERT(opts.optDict->find(13)->second->b == 15); } +xmlpp::Document * +readXml(const fs::path & path) +{ + return new xmlpp::Document(xmlParseFile(path.string().c_str())); +} + +void +writeXml(xmlpp::Document * const & doc, const fs::path & path) +{ + doc->write_to_file_formatted(path.string()); +} + +void +freeXml(xmlpp::Document * & doc) +{ + delete doc; +} + +json::Value +readJson(const fs::path & path) +{ + std::ifstream inFile(path.string()); + std::stringstream buffer; + buffer << inFile.rdbuf(); + Glib::ustring doc(buffer.str()); + Glib::ustring::const_iterator itr = doc.begin(); + return json::parseValue(itr); +} + +void +writeJson(const json::Value & value, const fs::path & path) +{ + std::ofstream outFile(path.string()); + json::serializeValue(value, outFile, "utf-8"); +} + +void +freeJson(json::Value &) +{ +} + int main(int, char ** argv) { @@ -106,15 +189,22 @@ main(int, char ** argv) const fs::path tmp = root / "bin" / "slicer"; fprintf(stderr, "tmp --- %s\n", tmp.string().c_str()); fs::create_directory(tmp); + const fs::path tmpf = tmp / "byFile"; + fs::create_directory(tmpf); + const fs::path tmph = tmp / "byHelper"; + fs::create_directory(tmph); // Execute - verify(root, tmp, "builtins.xml", checkBuiltIns_valuesCorrect); - verify(root, tmp, "optionals-notset.xml", checkOptionals_notset); - verify(root, tmp, "optionals-areset.xml", checkOptionals_areset); - verify(root, tmp, "inherit-a.xml"); - verify(root, tmp, "inherit-b.xml"); - verify(root, tmp, "builtins2.json", checkBuiltIns_valuesCorrect); - verify(root, tmp, "optionals-areset2.json", checkOptionals_areset); + verifyByFile(root, tmpf, "builtins.xml", checkBuiltIns_valuesCorrect); + verifyByFile(root, tmpf, "optionals-notset.xml", checkOptionals_notset); + verifyByFile(root, tmpf, "optionals-areset.xml", checkOptionals_areset); + verifyByFile(root, tmpf, "inherit-a.xml"); + verifyByFile(root, tmpf, "inherit-b.xml"); + verifyByFile(root, tmpf, "builtins2.json", checkBuiltIns_valuesCorrect); + verifyByFile(root, tmpf, "optionals-areset2.json", checkOptionals_areset); + + verifyByHelper(root, tmph, "optionals-areset2.json", readJson, writeJson, freeJson, checkOptionals_areset); + verifyByHelper(root, tmph, "optionals-areset.xml", readXml, writeXml, freeXml, checkOptionals_areset); return 0; } diff --git a/slicer/xml/Jamfile.jam b/slicer/xml/Jamfile.jam index 97f013c..6c5322b 100644 --- a/slicer/xml/Jamfile.jam +++ b/slicer/xml/Jamfile.jam @@ -13,4 +13,6 @@ lib slicer-xml : boost_filesystem IceUtil libxmlpp + : : + libxmlpp ; diff --git a/slicer/xml/serializer.cpp b/slicer/xml/serializer.cpp index 0cf6b03..103f8f5 100644 --- a/slicer/xml/serializer.cpp +++ b/slicer/xml/serializer.cpp @@ -160,11 +160,6 @@ namespace Slicer { } }; - Xml::Xml(const boost::filesystem::path & p) : - path(p) - { - } - void Xml::DocumentTreeIterate(const xmlpp::Node * node, ModelPartPtr mp) { @@ -234,8 +229,13 @@ namespace Slicer { mp->OnEachChild(boost::bind(&Xml::ModelTreeIterate, root, _1, _2)); } + XmlFile::XmlFile(const boost::filesystem::path & p) : + path(p) + { + } + void - Xml::Deserialize(ModelPartPtr modelRoot) + XmlFile::Deserialize(ModelPartPtr modelRoot) { xmlpp::DomParser dom(path.string()); auto doc = dom.get_document(); @@ -243,11 +243,29 @@ namespace Slicer { } void - Xml::Serialize(ModelPartPtr modelRoot) + XmlFile::Serialize(ModelPartPtr modelRoot) { xmlpp::Document doc; modelRoot->OnEachChild(boost::bind(&Xml::ModelTreeIterateRoot, &doc, _1, _2)); doc.write_to_file_formatted(path.string()); } + + XmlDocument::XmlDocument(xmlpp::Document * & d) : + doc(d) + { + } + + void + XmlDocument::Deserialize(ModelPartPtr modelRoot) + { + DocumentTreeIterate(doc, modelRoot); + } + + void + XmlDocument::Serialize(ModelPartPtr modelRoot) + { + doc = new xmlpp::Document(); + modelRoot->OnEachChild(boost::bind(&Xml::ModelTreeIterateRoot, doc, _1, _2)); + } } diff --git a/slicer/xml/serializer.h b/slicer/xml/serializer.h index 487070b..842b565 100644 --- a/slicer/xml/serializer.h +++ b/slicer/xml/serializer.h @@ -2,32 +2,38 @@ #define SLICER_XML_H #include - -namespace xmlpp { - class Document; - class Node; - class Element; - class Attribute; - class ContentNode; -} +#include namespace Slicer { class Xml : public Serializer { - public: - Xml(const boost::filesystem::path &); - - virtual void Deserialize(ModelPartPtr) override; - virtual void Serialize(ModelPartPtr) override; - protected: static void DocumentTreeIterate(const xmlpp::Node * node, ModelPartPtr mp); static void DocumentTreeIterate(const xmlpp::Document * doc, ModelPartPtr mp); static void ModelTreeIterate(xmlpp::Element *, const std::string &, ModelPartPtr mp); static void ModelTreeIterateRoot(xmlpp::Document *, const std::string &, ModelPartPtr mp); + }; + + class XmlFile : public Xml { + public: + XmlFile(const boost::filesystem::path &); + + virtual void Deserialize(ModelPartPtr) override; + virtual void Serialize(ModelPartPtr) override; private: const boost::filesystem::path path; }; + + class XmlDocument : public Xml { + public: + XmlDocument(xmlpp::Document * &); + + virtual void Deserialize(ModelPartPtr) override; + virtual void Serialize(ModelPartPtr) override; + + private: + xmlpp::Document * & doc; + }; } #endif -- cgit v1.2.3