about summary refs log tree commit diff
path: root/src/libutil/serialise.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/libutil/serialise.cc')
-rw-r--r--src/libutil/serialise.cc31
1 files changed, 18 insertions, 13 deletions
diff --git a/src/libutil/serialise.cc b/src/libutil/serialise.cc
index 17448f70efb6..0e75eeec2bfe 100644
--- a/src/libutil/serialise.cc
+++ b/src/libutil/serialise.cc
@@ -169,17 +169,13 @@ std::unique_ptr<Source> sinkToSource(
     {
         typedef boost::coroutines2::coroutine<std::string> coro_t;
 
+        std::function<void(Sink &)> fun;
         std::function<void()> eof;
-        coro_t::pull_type coro;
+        std::experimental::optional<coro_t::pull_type> coro;
+        bool started = false;
 
         SinkToSource(std::function<void(Sink &)> fun, std::function<void()> eof)
-            : eof(eof)
-            , coro([&](coro_t::push_type & yield) {
-                LambdaSink sink([&](const unsigned char * data, size_t len) {
-                    if (len) yield(std::string((const char *) data, len));
-                });
-                fun(sink);
-            })
+            : fun(fun), eof(eof)
         {
         }
 
@@ -188,11 +184,19 @@ std::unique_ptr<Source> sinkToSource(
 
         size_t read(unsigned char * data, size_t len) override
         {
-            if (!coro) { eof(); abort(); }
+            if (!coro)
+                coro = coro_t::pull_type([&](coro_t::push_type & yield) {
+                    LambdaSink sink([&](const unsigned char * data, size_t len) {
+                            if (len) yield(std::string((const char *) data, len));
+                        });
+                    fun(sink);
+                });
+
+            if (!*coro) { eof(); abort(); }
 
             if (pos == cur.size()) {
-                if (!cur.empty()) coro();
-                cur = coro.get();
+                if (!cur.empty()) (*coro)();
+                cur = coro->get();
                 pos = 0;
             }
 
@@ -268,16 +272,17 @@ void readPadding(size_t len, Source & source)
 size_t readString(unsigned char * buf, size_t max, Source & source)
 {
     auto len = readNum<size_t>(source);
-    if (len > max) throw Error("string is too long");
+    if (len > max) throw SerialisationError("string is too long");
     source(buf, len);
     readPadding(len, source);
     return len;
 }
 
 
-string readString(Source & source)
+string readString(Source & source, size_t max)
 {
     auto len = readNum<size_t>(source);
+    if (len > max) throw SerialisationError("string is too long");
     std::string res(len, 0);
     source((unsigned char*) res.data(), len);
     readPadding(len, source);