diff --git a/src/libutil/serialise.cc b/src/libutil/serialise.cc index 381e7ae3825..d612c11b2d7 100644 --- a/src/libutil/serialise.cc +++ b/src/libutil/serialise.cc @@ -227,8 +227,7 @@ std::unique_ptr sourceToSink(std::function fun) throw EndOfFile("coroutine has finished"); } - size_t n = std::min(cur.size(), out_len); - memcpy(out, cur.data(), n); + size_t n = cur.copy(out, out_len); cur.remove_prefix(n); return n; }); @@ -260,7 +259,7 @@ std::unique_ptr sinkToSource( { struct SinkToSource : Source { - typedef boost::coroutines2::coroutine coro_t; + typedef boost::coroutines2::coroutine coro_t; std::function fun; std::function eof; @@ -271,33 +270,37 @@ std::unique_ptr sinkToSource( { } - std::string cur; - size_t pos = 0; + std::string_view cur; size_t read(char * data, size_t len) override { - if (!coro) { + bool hasCoro = coro.has_value(); + if (!hasCoro) { coro = coro_t::pull_type([&](coro_t::push_type & yield) { LambdaSink sink([&](std::string_view data) { - if (!data.empty()) yield(std::string(data)); + if (!data.empty()) { + yield(data); + } }); fun(sink); }); } - if (!*coro) { eof(); unreachable(); } - - if (pos == cur.size()) { - if (!cur.empty()) { + if (cur.empty()) { + if (hasCoro) { (*coro)(); } - cur = coro->get(); - pos = 0; + if (*coro) { + cur = coro->get(); + } else { + coro.reset(); + eof(); + unreachable(); + } } - auto n = std::min(cur.size() - pos, len); - memcpy(data, cur.data() + pos, n); - pos += n; + size_t n = cur.copy(data, len); + cur.remove_prefix(n); return n; }