diff options
author | John Ericson <John.Ericson@Obsidian.Systems> | 2021-09-30 22:36:50 +0000 |
---|---|---|
committer | John Ericson <John.Ericson@Obsidian.Systems> | 2021-09-30 22:41:53 +0000 |
commit | f4f3203aa7c2fc9225a8ae220db25593066fb397 (patch) | |
tree | 9063673af148e34069dd894a2fd6a2981b13ff26 /src/libutil/serialise.cc | |
parent | 1b6cf0d5f56e166a1cbbf38142375b7a92fc88f2 (diff) | |
parent | 6a8d6246f603a372d557ab026670ae42bad558b0 (diff) |
Merge remote-tracking branch 'upstream/master' into path-info
Diffstat (limited to 'src/libutil/serialise.cc')
-rw-r--r-- | src/libutil/serialise.cc | 57 |
1 files changed, 56 insertions, 1 deletions
diff --git a/src/libutil/serialise.cc b/src/libutil/serialise.cc index d1a16b6ba..16f3476c2 100644 --- a/src/libutil/serialise.cc +++ b/src/libutil/serialise.cc @@ -201,6 +201,62 @@ static DefaultStackAllocator defaultAllocatorSingleton; StackAllocator *StackAllocator::defaultAllocator = &defaultAllocatorSingleton; +std::unique_ptr<FinishSink> sourceToSink(std::function<void(Source &)> fun) +{ + struct SourceToSink : FinishSink + { + typedef boost::coroutines2::coroutine<bool> coro_t; + + std::function<void(Source &)> fun; + std::optional<coro_t::push_type> coro; + + SourceToSink(std::function<void(Source &)> fun) : fun(fun) + { + } + + std::string_view cur; + + void operator () (std::string_view in) override + { + if (in.empty()) return; + cur = in; + + if (!coro) + coro = coro_t::push_type(VirtualStackAllocator{}, [&](coro_t::pull_type & yield) { + LambdaSource source([&](char *out, size_t out_len) { + if (cur.empty()) { + yield(); + if (yield.get()) { + return (size_t)0; + } + } + + size_t n = std::min(cur.size(), out_len); + memcpy(out, cur.data(), n); + cur.remove_prefix(n); + return n; + }); + fun(source); + }); + + if (!*coro) { abort(); } + + if (!cur.empty()) (*coro)(false); + } + + void finish() override + { + if (!coro) return; + if (!*coro) abort(); + (*coro)(true); + if (*coro) abort(); + } + }; + + return std::make_unique<SourceToSink>(fun); +} + + std::unique_ptr<Source> sinkToSource( std::function<void(Sink &)> fun, std::function<void()> eof) @@ -212,7 +268,6 @@ std::unique_ptr<Source> sinkToSource( std::function<void(Sink &)> fun; std::function<void()> eof; std::optional<coro_t::pull_type> coro; - bool started = false; SinkToSource(std::function<void(Sink &)> fun, std::function<void()> eof) : fun(fun), eof(eof) |