aboutsummaryrefslogtreecommitdiff
path: root/src/libutil
diff options
context:
space:
mode:
Diffstat (limited to 'src/libutil')
-rw-r--r--src/libutil/compression.cc21
-rw-r--r--src/libutil/compression.hh1
2 files changed, 17 insertions, 5 deletions
diff --git a/src/libutil/compression.cc b/src/libutil/compression.cc
index e78d76500..d93a1b1d6 100644
--- a/src/libutil/compression.cc
+++ b/src/libutil/compression.cc
@@ -192,11 +192,9 @@ struct BrotliDecompressionSource : Source
std::string decompress(const std::string & method, std::string_view in)
{
- StringSink ssink;
- auto sink = makeDecompressionSink(method, ssink);
- (*sink)(in);
- sink->finish();
- return std::move(ssink.s);
+ StringSource src{in};
+ auto filter = makeDecompressionSource(method, src);
+ return filter->drain();
}
std::unique_ptr<FinishSink> makeDecompressionSink(const std::string & method, Sink & nextSink)
@@ -224,6 +222,19 @@ std::unique_ptr<FinishSink> makeDecompressionSink(const std::string & method, Si
});
}
+std::unique_ptr<Source> makeDecompressionSource(const std::string & method, Source & inner)
+{
+ if (method == "none" || method == "") {
+ return std::make_unique<LambdaSource>([&](char * data, size_t len) {
+ return inner.read(data, len);
+ });
+ } else if (method == "br") {
+ return std::make_unique<BrotliDecompressionSource>(inner);
+ } else {
+ return std::make_unique<ArchiveDecompressionSource>(inner);
+ }
+}
+
struct BrotliCompressionSink : ChunkedCompressionSink
{
Sink & nextSink;
diff --git a/src/libutil/compression.hh b/src/libutil/compression.hh
index 4e53a7b3c..8affdddd6 100644
--- a/src/libutil/compression.hh
+++ b/src/libutil/compression.hh
@@ -19,6 +19,7 @@ struct CompressionSink : BufferedSink, FinishSink
std::string decompress(const std::string & method, std::string_view in);
std::unique_ptr<FinishSink> makeDecompressionSink(const std::string & method, Sink & nextSink);
+std::unique_ptr<Source> makeDecompressionSource(const std::string & method, Source & inner);
std::string compress(const std::string & method, std::string_view in, const bool parallel = false, int level = -1);