diff options
author | Dan Goodliffe <dan@randomdan.homeip.net> | 2017-07-23 18:56:25 +0100 |
---|---|---|
committer | Dan Goodliffe <dan@randomdan.homeip.net> | 2017-07-23 18:56:25 +0100 |
commit | 6a7a44458431acee1fb2857c1130b47b4e704a28 (patch) | |
tree | 0a6458f8f72c831e67a1248af771e23fd5bede39 | |
parent | Don't copy (take by const reference) when serializing (although we do cast of... (diff) | |
download | slicer-1.5.0.tar.bz2 slicer-1.5.0.tar.xz slicer-1.5.0.zip |
Adds the [input] streaming interfacesslicer-1.5.0
-rw-r--r-- | slicer/slicer/common.ice | 4 | ||||
-rw-r--r-- | slicer/slicer/modelPartsTypes.cpp | 12 | ||||
-rw-r--r-- | slicer/slicer/modelPartsTypes.h | 50 | ||||
-rw-r--r-- | slicer/slicer/modelPartsTypes.impl.h | 43 | ||||
-rw-r--r-- | slicer/slicer/slicer.cpp | 7 | ||||
-rw-r--r-- | slicer/test/Jamfile.jam | 19 | ||||
-rw-r--r-- | slicer/test/expected/streamOut.json | 1 | ||||
-rw-r--r-- | slicer/test/expected/streamOut.xml | 13 | ||||
-rw-r--r-- | slicer/test/streams-mp.cpp | 5 | ||||
-rw-r--r-- | slicer/test/streams.cpp | 46 | ||||
-rw-r--r-- | slicer/test/streams.h | 12 |
11 files changed, 212 insertions, 0 deletions
diff --git a/slicer/slicer/common.ice b/slicer/slicer/common.ice index 6960f42..9198aaa 100644 --- a/slicer/slicer/common.ice +++ b/slicer/slicer/common.ice @@ -38,6 +38,10 @@ module Slicer { string symbol; string type; }; + ["cpp:ice_print"] + exception InvalidStreamOperation extends SerializerError { + string method; + }; }; #endif diff --git a/slicer/slicer/modelPartsTypes.cpp b/slicer/slicer/modelPartsTypes.cpp index 801759d..c1661de 100644 --- a/slicer/slicer/modelPartsTypes.cpp +++ b/slicer/slicer/modelPartsTypes.cpp @@ -182,5 +182,17 @@ namespace Slicer { bool ModelPartForDictionaryBase::HasValue() const { return true; } ModelPartType ModelPartForDictionaryBase::GetType() const { return type; } const ModelPartType ModelPartForDictionaryBase::type = mpt_Dictionary; + + // Streams + ChildRefPtr ModelPartForStreamBase::GetAnonChildRef(const Slicer::HookFilter &) { throw InvalidStreamOperation(__FUNCTION__); } + ChildRefPtr ModelPartForStreamBase::GetChildRef(const std::string &, const Slicer::HookFilter &) { throw InvalidStreamOperation(__FUNCTION__); } + ModelPartType ModelPartForStreamBase::GetType() const { return mpt_Sequence; } + bool ModelPartForStreamBase::HasValue() const { return true; } + // Stream Roots + ModelPartForStreamRootBase::ModelPartForStreamRootBase(ModelPartPtr mp) : ModelPartForRootBase(mp) { } + void ModelPartForStreamRootBase::Write(Ice::OutputStreamPtr&) const { throw InvalidStreamOperation(__FUNCTION__); } + void ModelPartForStreamRootBase::Read(Ice::InputStreamPtr&) { throw InvalidStreamOperation(__FUNCTION__); } + bool ModelPartForStreamRootBase::HasValue() const { return mp->HasValue(); } + void ModelPartForStreamRootBase::OnEachChild(const ChildHandler & ch) { ch(GetRootName(), mp, NULL); } } diff --git a/slicer/slicer/modelPartsTypes.h b/slicer/slicer/modelPartsTypes.h index 2038350..69c29b3 100644 --- a/slicer/slicer/modelPartsTypes.h +++ b/slicer/slicer/modelPartsTypes.h @@ -310,6 +310,56 @@ namespace Slicer { static const std::string pairName; }; + template<typename T> + class DLL_PUBLIC Stream { + public: + typedef boost::function<void(const T &)> Consumer; + typedef T element_type; + + virtual void Produce(const Consumer & c) = 0; + }; + + class DLL_PUBLIC ModelPartForStreamBase : public ModelPart { + public: + virtual ModelPartType GetType() const override; + virtual bool HasValue() const override; + virtual ChildRefPtr GetAnonChildRef(const HookFilter &) override; + virtual ChildRefPtr GetChildRef(const std::string &, const HookFilter &) override; + + virtual ModelPartPtr GetContainedModelPart() override = 0; + virtual void OnEachChild(const ChildHandler & ch) override = 0; + }; + + template<typename T> + class DLL_PUBLIC ModelPartForStream : public ModelPartForStreamBase, ModelPartModel<Stream<T>> { + public: + ModelPartForStream(Stream<T> * s); + + virtual ModelPartPtr GetContainedModelPart() override; + virtual void OnEachChild(const ChildHandler & ch) override; + }; + + class DLL_PUBLIC ModelPartForStreamRootBase : public ModelPartForRootBase { + public: + ModelPartForStreamRootBase(ModelPartPtr mp); + + virtual void Write(Ice::OutputStreamPtr&) const override; + virtual void Read(Ice::InputStreamPtr&) override; + virtual bool HasValue() const override; + virtual void OnEachChild(const ChildHandler & ch) override; + virtual const std::string & GetRootName() const override = 0; + }; + + template<typename T> + class DLL_PUBLIC ModelPartForStreamRoot : public ModelPartForStreamRootBase { + public: + ModelPartForStreamRoot(Stream<T> * s); + + virtual const std::string & GetRootName() const override; + + private: + Stream<T> * stream; + }; } #endif diff --git a/slicer/slicer/modelPartsTypes.impl.h b/slicer/slicer/modelPartsTypes.impl.h index 988d91e..3f701c2 100644 --- a/slicer/slicer/modelPartsTypes.impl.h +++ b/slicer/slicer/modelPartsTypes.impl.h @@ -24,6 +24,12 @@ #define MODELPARTFOR(Type, ModelPartType) \ CUSTOMMODELPARTFOR(Type, ModelPartType<Type>, ModelPartType<Type>) +#define MODELPARTFORSTREAM(StreamImpl) \ + namespace Slicer { \ + template<> ModelPartForRootPtr ModelPart::CreateRootFor(const StreamImpl & stream) { \ + return new ModelPartForStreamRoot<typename StreamImpl::element_type>(const_cast<StreamImpl *>(&stream)); \ + } \ + } namespace Slicer { // ModelPartForRoot @@ -576,6 +582,43 @@ namespace Slicer { { return new ModelPartForStruct<typename T::value_type>(nullptr); } + + // ModelPartForStream + template<typename T> + ModelPartForStream<T>::ModelPartForStream(Stream<T> * s) : + ModelPartModel<Stream<T>>(s) + { + } + + template<typename T> + ModelPartPtr + ModelPartForStream<T>::GetContainedModelPart() + { + return ModelPart::CreateFor<T>(); + } + + template<typename T> + void + ModelPartForStream<T>::OnEachChild(const ChildHandler & ch) + { + BOOST_ASSERT(this->Model); + this->Model->Produce([&ch](const T & element) { + ch(ModelPartForSequence<std::vector<T>>::elementName, ModelPart::CreateFor(element), NULL); + }); + } + + template<typename T> + ModelPartForStreamRoot<T>::ModelPartForStreamRoot(Stream<T> * s) : + ModelPartForStreamRootBase(new ModelPartForStream<T>(s)) + { + } + + template<typename T> + const std::string & + ModelPartForStreamRoot<T>::GetRootName() const + { + return ModelPartForRoot<std::vector<T>>::rootName; + } } #endif diff --git a/slicer/slicer/slicer.cpp b/slicer/slicer/slicer.cpp index dbda326..ba4db3f 100644 --- a/slicer/slicer/slicer.cpp +++ b/slicer/slicer/slicer.cpp @@ -109,5 +109,12 @@ namespace Slicer { { CompilerErrorMsg::write(s, what); } + + AdHocFormatter(InvalidStreamOperationMsg, "%? is not valid on streams"); + void + InvalidStreamOperation::ice_print(std::ostream & s) const + { + InvalidStreamOperationMsg::write(s, method); + } } diff --git a/slicer/test/Jamfile.jam b/slicer/test/Jamfile.jam index 53a9489..9a801c4 100644 --- a/slicer/test/Jamfile.jam +++ b/slicer/test/Jamfile.jam @@ -92,3 +92,22 @@ run serializers.cpp serializers ; +lib streams-mp : + streams-mp.cpp + : + <library>common + <library>types + ; + +run streams.cpp + helpers.cpp + : : : + <library>streams-mp + <library>types + <library>common + <library>../slicer//slicer + <implicit-dependency>../slicer//slicer + <library>../xml//slicer-xml + <library>../json//slicer-json + ; + diff --git a/slicer/test/expected/streamOut.json b/slicer/test/expected/streamOut.json new file mode 100644 index 0000000..385fa12 --- /dev/null +++ b/slicer/test/expected/streamOut.json @@ -0,0 +1 @@ +["0","1","2","3","4","5","6","7","8","9"] diff --git a/slicer/test/expected/streamOut.xml b/slicer/test/expected/streamOut.xml new file mode 100644 index 0000000..a595ade --- /dev/null +++ b/slicer/test/expected/streamOut.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="UTF-8"?> +<SimpleSeq> + <element>0</element> + <element>1</element> + <element>2</element> + <element>3</element> + <element>4</element> + <element>5</element> + <element>6</element> + <element>7</element> + <element>8</element> + <element>9</element> +</SimpleSeq> diff --git a/slicer/test/streams-mp.cpp b/slicer/test/streams-mp.cpp new file mode 100644 index 0000000..119ee1f --- /dev/null +++ b/slicer/test/streams-mp.cpp @@ -0,0 +1,5 @@ +#include <slicer/modelPartsTypes.impl.h> +#include "streams.h" + +MODELPARTFORSTREAM(TestStream); + diff --git a/slicer/test/streams.cpp b/slicer/test/streams.cpp new file mode 100644 index 0000000..2f8a513 --- /dev/null +++ b/slicer/test/streams.cpp @@ -0,0 +1,46 @@ +#define BOOST_TEST_MODULE streams +#include <boost/test/unit_test.hpp> + +#include <boost/lexical_cast.hpp> +#include <xml/serializer.h> +#include <json/serializer.h> +#include <slicer.h> +#include <collections.h> +#include <definedDirs.h> +#include "helpers.h" +#include "streams.h" + +void TestStream::Produce(const Consumer & c) +{ + for (int x = 0; x < 10; x += 1) { + auto str = boost::lexical_cast<std::string>(x); + c(str); + } +} + +BOOST_FIXTURE_TEST_SUITE( stream, TestStream ); + +BOOST_AUTO_TEST_CASE( streamToXml ) +{ + const auto outputXml = binDir / "streamOut.xml"; + Slicer::SerializeAny<Slicer::XmlFileSerializer, const TestStream>(*this, outputXml); + diff(rootDir / "expected" / "streamOut.xml", outputXml); + auto seq = Slicer::DeserializeAny<Slicer::XmlFileDeserializer, TestModule::SimpleSeq>(outputXml); + BOOST_REQUIRE_EQUAL(10, seq.size()); + BOOST_REQUIRE_EQUAL("0", seq.front()); + BOOST_REQUIRE_EQUAL("9", seq.back()); +} + +BOOST_AUTO_TEST_CASE( streamToJson ) +{ + const auto outputJson = binDir / "streamOut.json"; + Slicer::SerializeAny<Slicer::JsonFileSerializer, const TestStream>(*this, outputJson); + diff(rootDir / "expected" / "streamOut.json", outputJson); + auto seq = Slicer::DeserializeAny<Slicer::JsonFileDeserializer, TestModule::SimpleSeq>(outputJson); + BOOST_REQUIRE_EQUAL(10, seq.size()); + BOOST_REQUIRE_EQUAL("0", seq.front()); + BOOST_REQUIRE_EQUAL("9", seq.back()); +} + +BOOST_AUTO_TEST_SUITE_END(); + diff --git a/slicer/test/streams.h b/slicer/test/streams.h new file mode 100644 index 0000000..28c0c9d --- /dev/null +++ b/slicer/test/streams.h @@ -0,0 +1,12 @@ +#ifndef SLICER_TEST_STREAMS_H +#define SLICER_TEST_STREAMS_H + +#include <slicer/modelPartsTypes.h> + +class TestStream : public Slicer::Stream<std::string> { + public: + void Produce(const Consumer & c) override; +}; + +#endif + |