aboutsummaryrefslogtreecommitdiff
path: root/src/libutil/serialise.hh
diff options
context:
space:
mode:
authorCarlo Nucera <carlo.nucera@protonmail.com>2020-07-15 17:19:56 -0400
committerCarlo Nucera <carlo.nucera@protonmail.com>2020-07-15 17:21:01 -0400
commitd0905623488ca97feeb28ebd9817af6270a53c48 (patch)
treebe3504d2c37bc65df0f80dc358bbec49c217e7bf /src/libutil/serialise.hh
parent44157653850ce18536f837d7ed53521d61a238a1 (diff)
parent36a124260361ba8dfa43bf43a067dcc48064c93f (diff)
Merge branch 'master' of github.com:NixOS/nix into hash-always-has-type
Diffstat (limited to 'src/libutil/serialise.hh')
-rw-r--r--src/libutil/serialise.hh46
1 files changed, 41 insertions, 5 deletions
diff --git a/src/libutil/serialise.hh b/src/libutil/serialise.hh
index a04118512..8386a4991 100644
--- a/src/libutil/serialise.hh
+++ b/src/libutil/serialise.hh
@@ -166,17 +166,30 @@ struct StringSource : Source
};
-/* Adapter class of a Source that saves all data read to `s'. */
+/* A sink that writes all incoming data to two other sinks. */
+struct TeeSink : Sink
+{
+ Sink & sink1, & sink2;
+ TeeSink(Sink & sink1, Sink & sink2) : sink1(sink1), sink2(sink2) { }
+ virtual void operator () (const unsigned char * data, size_t len)
+ {
+ sink1(data, len);
+ sink2(data, len);
+ }
+};
+
+
+/* Adapter class of a Source that saves all data read to a sink. */
struct TeeSource : Source
{
Source & orig;
- ref<std::string> data;
- TeeSource(Source & orig)
- : orig(orig), data(make_ref<std::string>()) { }
+ Sink & sink;
+ TeeSource(Source & orig, Sink & sink)
+ : orig(orig), sink(sink) { }
size_t read(unsigned char * data, size_t len)
{
size_t n = orig.read(data, len);
- this->data->append((const char *) data, n);
+ sink(data, len);
return n;
}
};
@@ -336,4 +349,27 @@ Source & operator >> (Source & in, bool & b)
}
+/* An adapter that converts a std::basic_istream into a source. */
+struct StreamToSourceAdapter : Source
+{
+ std::shared_ptr<std::basic_istream<char>> istream;
+
+ StreamToSourceAdapter(std::shared_ptr<std::basic_istream<char>> istream)
+ : istream(istream)
+ { }
+
+ size_t read(unsigned char * data, size_t len) override
+ {
+ if (!istream->read((char *) data, len)) {
+ if (istream->eof()) {
+ if (istream->gcount() == 0)
+ throw EndOfFile("end of file");
+ } else
+ throw Error("I/O error in StreamToSourceAdapter");
+ }
+ return istream->gcount();
+ }
+};
+
+
}