summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Goodliffe <dan@randomdan.homeip.net>2017-07-23 18:56:25 +0100
committerDan Goodliffe <dan@randomdan.homeip.net>2017-07-23 18:56:25 +0100
commit6a7a44458431acee1fb2857c1130b47b4e704a28 (patch)
tree0a6458f8f72c831e67a1248af771e23fd5bede39
parentDon't copy (take by const reference) when serializing (although we do cast of... (diff)
downloadslicer-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.ice4
-rw-r--r--slicer/slicer/modelPartsTypes.cpp12
-rw-r--r--slicer/slicer/modelPartsTypes.h50
-rw-r--r--slicer/slicer/modelPartsTypes.impl.h43
-rw-r--r--slicer/slicer/slicer.cpp7
-rw-r--r--slicer/test/Jamfile.jam19
-rw-r--r--slicer/test/expected/streamOut.json1
-rw-r--r--slicer/test/expected/streamOut.xml13
-rw-r--r--slicer/test/streams-mp.cpp5
-rw-r--r--slicer/test/streams.cpp46
-rw-r--r--slicer/test/streams.h12
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
+