about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorEelco Dolstra <eelco.dolstra@logicblox.com>2016-02-15T20·45+0100
committerEelco Dolstra <eelco.dolstra@logicblox.com>2016-02-15T20·45+0100
commiteff5021eaa6dc69f65ea1a8abe8f3ab11ef5eb0a (patch)
tree014068ef94f3aae867e035c0c30ba5e721555c09 /src
parentbfdacb712c9a95b5c61857b2b3a7dd3cfd0faf3b (diff)
Add xz compression function
This is used by the Hydra queue runner, but since it may also be
useful for the C++ rewrite of nix-push, I'm putting it here.
Diffstat (limited to 'src')
-rw-r--r--src/libutil/compression.cc40
-rw-r--r--src/libutil/compression.hh2
2 files changed, 42 insertions, 0 deletions
diff --git a/src/libutil/compression.cc b/src/libutil/compression.cc
index eaaaf246b18d..a3fa0dab737b 100644
--- a/src/libutil/compression.cc
+++ b/src/libutil/compression.cc
@@ -15,6 +15,46 @@ struct LzmaStream
     lzma_stream & operator()() { return strm; }
 };
 
+std::string compressXZ(const std::string & in)
+{
+    LzmaStream strm;
+
+    // FIXME: apply the x86 BCJ filter?
+
+    lzma_ret ret = lzma_easy_encoder(
+        &strm(), 6, LZMA_CHECK_CRC64);
+    if (ret != LZMA_OK)
+        throw Error("unable to initialise lzma encoder");
+
+    lzma_action action = LZMA_RUN;
+    uint8_t outbuf[BUFSIZ];
+    string res;
+    strm().next_in = (uint8_t *) in.c_str();
+    strm().avail_in = in.size();
+    strm().next_out = outbuf;
+    strm().avail_out = sizeof(outbuf);
+
+    while (true) {
+
+        if (strm().avail_in == 0)
+            action = LZMA_FINISH;
+
+        lzma_ret ret = lzma_code(&strm(), action);
+
+        if (strm().avail_out == 0 || ret == LZMA_STREAM_END) {
+            res.append((char *) outbuf, sizeof(outbuf) - strm().avail_out);
+            strm().next_out = outbuf;
+            strm().avail_out = sizeof(outbuf);
+        }
+
+        if (ret == LZMA_STREAM_END)
+            return res;
+
+        if (ret != LZMA_OK)
+            throw Error("error while decompressing xz file");
+    }
+}
+
 std::string decompressXZ(const std::string & in)
 {
     LzmaStream strm;
diff --git a/src/libutil/compression.hh b/src/libutil/compression.hh
index 962ce5ac7767..eb1697fc4aa4 100644
--- a/src/libutil/compression.hh
+++ b/src/libutil/compression.hh
@@ -4,6 +4,8 @@
 
 namespace nix {
 
+std::string compressXZ(const std::string & in);
+
 std::string decompressXZ(const std::string & in);
 
 }