From 3dc9f9d66ee412d2b3476a9b9d50fa04acb0499d Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Mon, 3 Oct 2016 14:23:21 +0100 Subject: Adds support for reading/writing in ICE native format --- slicer/Jamfile.jam | 3 +- slicer/ice/Jamfile.jam | 47 ++++++++++++++ slicer/ice/serializer.cpp | 72 +++++++++++++++++++++ slicer/ice/serializer.h | 65 +++++++++++++++++++ slicer/ice/testSpecifics.cpp | 118 +++++++++++++++++++++++++++++++++++ slicer/slicer/modelParts.h | 3 + slicer/slicer/modelPartsTypes.h | 2 + slicer/slicer/modelPartsTypes.impl.h | 60 ++++++++++++++++++ 8 files changed, 369 insertions(+), 1 deletion(-) create mode 100644 slicer/ice/Jamfile.jam create mode 100644 slicer/ice/serializer.cpp create mode 100644 slicer/ice/serializer.h create mode 100644 slicer/ice/testSpecifics.cpp diff --git a/slicer/Jamfile.jam b/slicer/Jamfile.jam index 3d5a62b..3108454 100644 --- a/slicer/Jamfile.jam +++ b/slicer/Jamfile.jam @@ -5,13 +5,14 @@ build-project slicer ; build-project xml ; build-project json ; build-project db ; +build-project ice ; build-project test ; explicit install ; explicit install-xml ; explicit install-json ; explicit install-db ; -alias install : slicer//install tool//install ; +alias install : slicer//install tool//install ice//install ; alias install-xml : xml//install ; alias install-json : json//install ; alias install-db : db//install ; diff --git a/slicer/ice/Jamfile.jam b/slicer/ice/Jamfile.jam new file mode 100644 index 0000000..d4c6685 --- /dev/null +++ b/slicer/ice/Jamfile.jam @@ -0,0 +1,47 @@ +import testing ; +import package ; + +lib pthread ; +lib Ice ; +lib boost_system ; +lib boost_filesystem ; +lib boost_utf : : boost_unit_test_framework ; +lib IceUtil ; +lib adhocutil : : : : /usr/include/adhocutil ; + +lib slicer-ice : + [ glob *.cpp : test*.cpp ] + : + .. + boost_system + boost_filesystem + pthread + Ice + IceUtil + adhocutil + ../slicer//slicer + ../slicer//slicer + : : + ; + +run testSpecifics.cpp + : : : + BOOST_TEST_DYN_LINK + slicer-ice + boost_utf + ../test//types + ../test//common + ../slicer//slicer + .. + ../test//compilation + : + testSpecifics + ; + +alias install : install-lib install-slice ; +explicit install ; +explicit install-lib ; +explicit install-slice ; +package.install install-lib : slicer/ice : : slicer-ice : [ glob-tree *.h ] ; +package.install-data install-slice : slicer/ice : [ glob *.ice ] ; + diff --git a/slicer/ice/serializer.cpp b/slicer/ice/serializer.cpp new file mode 100644 index 0000000..981223f --- /dev/null +++ b/slicer/ice/serializer.cpp @@ -0,0 +1,72 @@ +#include "serializer.h" +#include "Ice/Initialize.h" +#include "Ice/Stream.h" +#include "Ice/Communicator.h" + +NAMEDFACTORY("application/ice", Slicer::IceStreamSerializer, Slicer::StreamSerializerFactory); +NAMEDFACTORY("application/ice", Slicer::IceStreamDeserializer, Slicer::StreamDeserializerFactory); + +namespace Slicer { + Ice::StringSeq empty; + + IceBase::IceBase() : + ic(Ice::initialize(empty)) + { + } + + IceBase::~IceBase() + { + ic->destroy(); + } + IceBlobSerializer::IceBlobSerializer(Ice::ByteSeq & b) : + blob(b) + { + } + + void + IceBlobSerializer::Serialize(ModelPartForRootPtr mp) + { + auto s = Ice::createOutputStream(ic); + mp->Write(s); + s->finished(blob); + } + + IceStreamSerializer::IceStreamSerializer(std::ostream & os) : + IceBlobSerializer(blob), + strm(os) + { + } + + void + IceStreamSerializer::Serialize(ModelPartForRootPtr mp) + { + IceBlobSerializer::Serialize(mp); + strm.write((const char *)&blob.front(), blob.size()); + } + + IceBlobDeserializer::IceBlobDeserializer(const Ice::ByteSeq & b) : + blob(b) + { + } + + void + IceBlobDeserializer::Deserialize(ModelPartForRootPtr mp) + { + auto s = Ice::createInputStream(ic, blob); + mp->Read(s); + } + + IceStreamDeserializer::IceStreamDeserializer(std::istream & is) : + IceBlobDeserializer(blob), + strm(is) + { + } + + void + IceStreamDeserializer::Deserialize(ModelPartForRootPtr mp) + { + blob.assign(std::istreambuf_iterator(strm), std::istreambuf_iterator()); + IceBlobDeserializer::Deserialize(mp); + } +} + diff --git a/slicer/ice/serializer.h b/slicer/ice/serializer.h new file mode 100644 index 0000000..d534b3e --- /dev/null +++ b/slicer/ice/serializer.h @@ -0,0 +1,65 @@ +#ifndef SLICER_ICE_H +#define SLICER_ICE_H + +#include +#include +#include +#include + +namespace Slicer { + class IceBase { + public: + virtual ~IceBase(); + + protected: + IceBase(); + + Ice::CommunicatorPtr ic; + }; + + class DLL_PUBLIC IceBlobSerializer : public Serializer, protected IceBase { + public: + IceBlobSerializer(Ice::ByteSeq &); + + virtual void Serialize(ModelPartForRootPtr) override; + + private: + Ice::ByteSeq & blob; + }; + + class DLL_PUBLIC IceStreamSerializer : public IceBlobSerializer { + public: + IceStreamSerializer(std::ostream &); + + virtual void Serialize(ModelPartForRootPtr) override; + + protected: + std::ostream & strm; + Ice::ByteSeq blob; + }; + + class DLL_PUBLIC IceBlobDeserializer : public Deserializer, protected IceBase { + public: + IceBlobDeserializer(const Ice::ByteSeq &); + + virtual void Deserialize(ModelPartForRootPtr) override; + + protected: + const Ice::ByteSeq & blob; + }; + + class DLL_PUBLIC IceStreamDeserializer : public IceBlobDeserializer { + public: + IceStreamDeserializer(std::istream &); + + virtual void Deserialize(ModelPartForRootPtr) override; + + protected: + std::istream & strm; + Ice::ByteSeq blob; + }; +} + +#endif + + diff --git a/slicer/ice/testSpecifics.cpp b/slicer/ice/testSpecifics.cpp new file mode 100644 index 0000000..8a625cd --- /dev/null +++ b/slicer/ice/testSpecifics.cpp @@ -0,0 +1,118 @@ +#define BOOST_TEST_MODULE ice_specifics +#include +#include +#include "serializer.h" +#include + +// LCOV_EXCL_START +BOOST_TEST_DONT_PRINT_LOG_VALUE(TestModule::IsoDate); +// LCOV_EXCL_END + +template +void +testCompare(const X & x) +{ + BOOST_TEST_CHECKPOINT(typeid(X).name()); + std::stringstream strm; + Slicer::SerializeAny(x, strm); + auto x2 = Slicer::DeserializeAny(strm); + BOOST_REQUIRE_EQUAL(x, x2); +} + +template +void +testCompare(const X & x, const boost::function & cmp) +{ + BOOST_TEST_CHECKPOINT(typeid(X).name()); + std::stringstream strm; + Slicer::SerializeAny(x, strm); + auto x2 = Slicer::DeserializeAny(strm); + BOOST_REQUIRE(cmp(x, x2)); +} + +BOOST_AUTO_TEST_CASE( builtins ) +{ + testCompare("some string value"); + testCompare(true); + testCompare(false); + testCompare(10); + testCompare(0); + testCompare(-5); + testCompare(534); + testCompare(-433); + testCompare(3434090); + testCompare(-4000033); + testCompare(343409898900); + testCompare(-3.14); + testCompare(3.14); + testCompare(-3.14159); + testCompare(3.14159); +} + +template +void +testCompareOptional(const X & d) +{ + BOOST_TEST_CHECKPOINT(typeid(X).name()); + std::stringstream strm; + IceUtil::Optional x; + Slicer::SerializeAny(x, strm); + auto x2 = Slicer::DeserializeAny>(strm); + BOOST_REQUIRE(!x2); + x = d; + Slicer::SerializeAny(x, strm); + auto x3 = Slicer::DeserializeAny>(strm); + BOOST_REQUIRE_EQUAL(d, *x3); +} + +BOOST_AUTO_TEST_CASE( optionalBuiltins ) +{ + testCompareOptional("some string value"); + testCompareOptional(true); + testCompareOptional(false); + testCompareOptional(10); + testCompareOptional(0); + testCompareOptional(-5); + testCompareOptional(534); + testCompareOptional(-433); + testCompareOptional(3434090); + testCompareOptional(-4000033); + testCompareOptional(343409898900); + testCompareOptional(-3.14); + testCompareOptional(3.14); + testCompareOptional(-3.14159); + testCompareOptional(3.14159); +} + + + +BOOST_AUTO_TEST_CASE( classes ) +{ + TestModule::BuiltInsPtr x = new TestModule::BuiltIns(); + x->mbool = true; + x->mbyte = 14; + x->mshort = 31434; + x->mint = 324324234; + x->mlong = 343242342343243; + x->mfloat = 3434.32432; + x->mdouble = 3423423423.42342342343; + x->mstring = "sdfsf432423"; + testCompare(x, [](const auto & a, const auto & b) { + return a->mbool == b->mbool + && a->mbyte == b->mbyte + && a->mshort == b->mshort + && a->mint == b->mint + && a->mlong == b->mlong + && a->mfloat == b->mfloat + && a->mdouble == b->mdouble + && a->mstring == b->mstring; + }); +} + +BOOST_AUTO_TEST_CASE( structes ) +{ + TestModule::IsoDate date({ 2016, 10, 3 }); + testCompare(date); + testCompareOptional(date); +} + diff --git a/slicer/slicer/modelParts.h b/slicer/slicer/modelParts.h index 8cf3bc5..59f12c7 100644 --- a/slicer/slicer/modelParts.h +++ b/slicer/slicer/modelParts.h @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -189,6 +190,8 @@ namespace Slicer { virtual void OnEachChild(const ChildHandler & ch) override; virtual ModelPartType GetType() const override; virtual bool IsOptional() const override; + virtual void Write(::Ice::OutputStreamPtr &) const = 0; + virtual void Read(::Ice::InputStreamPtr &) = 0; ModelPartPtr mp; }; diff --git a/slicer/slicer/modelPartsTypes.h b/slicer/slicer/modelPartsTypes.h index 88ee0bd..5dae7bf 100644 --- a/slicer/slicer/modelPartsTypes.h +++ b/slicer/slicer/modelPartsTypes.h @@ -11,6 +11,8 @@ namespace Slicer { const std::string & GetRootName() const override; virtual bool HasValue() const override; + void Write(::Ice::OutputStreamPtr &) const override; + void Read(::Ice::InputStreamPtr &) override; static const std::string rootName; diff --git a/slicer/slicer/modelPartsTypes.impl.h b/slicer/slicer/modelPartsTypes.impl.h index 46c028b..5788c3f 100644 --- a/slicer/slicer/modelPartsTypes.impl.h +++ b/slicer/slicer/modelPartsTypes.impl.h @@ -3,6 +3,10 @@ #include "modelPartsTypes.h" #include "common.h" +#include +#include +#include +#include #define CUSTOMMODELPARTFOR(Type, BaseModelPart, ModelPartType) \ template class BaseModelPart; \ @@ -35,6 +39,62 @@ namespace Slicer { return ModelObject && mp->HasValue(); } + template + void + typeWrite(::Ice::OutputStreamPtr & s, const ::IceUtil::Optional & m) + { + typedef Ice::StreamableTraits traits; + s->startEncapsulation(); + if (m && s->writeOptional(0, + Ice::StreamOptionalHelper::optionalFormat)) { + Ice::StreamOptionalHelper::write(s.get(), *m); + } + s->endEncapsulation(); + } + + template + void + typeWrite(::Ice::OutputStreamPtr & s, const T & m) + { + s->write(m); + } + + template + void + typeRead(::Ice::InputStreamPtr & s, ::IceUtil::Optional & m) + { + typedef Ice::StreamableTraits traits; + s->startEncapsulation(); + if (s->readOptional(0, + Ice::StreamOptionalHelper::optionalFormat)) { + m.__setIsSet(); + Ice::StreamOptionalHelper::read(s.get(), *m); + } + else { + m = IceUtil::None; + } + s->endEncapsulation(); + } + + template + void + typeRead(::Ice::InputStreamPtr & s, T & m) + { + s->read(m); + } + + template + void ModelPartForRoot::Write(::Ice::OutputStreamPtr & s) const + { + typeWrite(s, *ModelObject); + } + + template + void ModelPartForRoot::Read(::Ice::InputStreamPtr & s) + { + typeRead(s, *ModelObject); + } + // ModelPartForSimple template ModelPartForSimple::ModelPartForSimple(T & h) : -- cgit v1.2.3