1
0
Fork 0
mirror of https://github.com/NixOS/nix synced 2025-06-29 02:11:15 +02:00

sinkToSource: avoid heap allocation

This commit is contained in:
Philipp Otterbein 2025-01-23 00:18:55 +01:00 committed by Jörg Thalheim
parent 06123f6284
commit 4f8f12f79a

View file

@ -227,8 +227,7 @@ std::unique_ptr<FinishSink> sourceToSink(std::function<void(Source &)> fun)
throw EndOfFile("coroutine has finished"); throw EndOfFile("coroutine has finished");
} }
size_t n = std::min(cur.size(), out_len); size_t n = cur.copy(out, out_len);
memcpy(out, cur.data(), n);
cur.remove_prefix(n); cur.remove_prefix(n);
return n; return n;
}); });
@ -260,7 +259,7 @@ std::unique_ptr<Source> sinkToSource(
{ {
struct SinkToSource : Source struct SinkToSource : Source
{ {
typedef boost::coroutines2::coroutine<std::string> coro_t; typedef boost::coroutines2::coroutine<std::string_view> coro_t;
std::function<void(Sink &)> fun; std::function<void(Sink &)> fun;
std::function<void()> eof; std::function<void()> eof;
@ -271,33 +270,37 @@ std::unique_ptr<Source> sinkToSource(
{ {
} }
std::string cur; std::string_view cur;
size_t pos = 0;
size_t read(char * data, size_t len) override 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) { coro = coro_t::pull_type([&](coro_t::push_type & yield) {
LambdaSink sink([&](std::string_view data) { LambdaSink sink([&](std::string_view data) {
if (!data.empty()) yield(std::string(data)); if (!data.empty()) {
yield(data);
}
}); });
fun(sink); fun(sink);
}); });
} }
if (!*coro) { eof(); unreachable(); } if (cur.empty()) {
if (hasCoro) {
if (pos == cur.size()) {
if (!cur.empty()) {
(*coro)(); (*coro)();
} }
cur = coro->get(); if (*coro) {
pos = 0; cur = coro->get();
} else {
coro.reset();
eof();
unreachable();
}
} }
auto n = std::min(cur.size() - pos, len); size_t n = cur.copy(data, len);
memcpy(data, cur.data() + pos, n); cur.remove_prefix(n);
pos += n;
return n; return n;
} }