summaryrefslogtreecommitdiff
path: root/lib/zstd/zstd.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/zstd/zstd.c')
-rw-r--r--lib/zstd/zstd.c53
1 files changed, 25 insertions, 28 deletions
diff --git a/lib/zstd/zstd.c b/lib/zstd/zstd.c
index bf9cd19cfa..3a2abc8367 100644
--- a/lib/zstd/zstd.c
+++ b/lib/zstd/zstd.c
@@ -13,14 +13,12 @@
int zstd_decompress(struct abuf *in, struct abuf *out)
{
- ZSTD_DStream *dstream;
- ZSTD_inBuffer in_buf;
- ZSTD_outBuffer out_buf;
+ zstd_dctx *ctx;
+ size_t wsize, len;
void *workspace;
- size_t wsize;
int ret;
- wsize = ZSTD_DStreamWorkspaceBound(abuf_size(in));
+ wsize = zstd_dctx_workspace_bound();
workspace = malloc(wsize);
if (!workspace) {
debug("%s: cannot allocate workspace of size %zu\n", __func__,
@@ -28,36 +26,35 @@ int zstd_decompress(struct abuf *in, struct abuf *out)
return -ENOMEM;
}
- dstream = ZSTD_initDStream(abuf_size(in), workspace, wsize);
- if (!dstream) {
- log_err("%s: ZSTD_initDStream failed\n", __func__);
+ ctx = zstd_init_dctx(workspace, wsize);
+ if (!ctx) {
+ log_err("%s: zstd_init_dctx() failed\n", __func__);
ret = -EPERM;
goto do_free;
}
- in_buf.src = abuf_data(in);
- in_buf.pos = 0;
- in_buf.size = abuf_size(in);
-
- out_buf.dst = abuf_data(out);
- out_buf.pos = 0;
- out_buf.size = abuf_size(out);
-
- while (1) {
- size_t res;
-
- res = ZSTD_decompressStream(dstream, &out_buf, &in_buf);
- if (ZSTD_isError(res)) {
- ret = ZSTD_getErrorCode(res);
- log_err("ZSTD_decompressStream error %d\n", ret);
- goto do_free;
- }
+ /*
+ * Find out how large the frame actually is, there may be junk at
+ * the end of the frame that zstd_decompress_dctx() can't handle.
+ */
+ len = zstd_find_frame_compressed_size(abuf_data(in), abuf_size(in));
+ if (zstd_is_error(len)) {
+ log_err("%s: failed to detect compressed size: %d\n", __func__,
+ zstd_get_error_code(len));
+ ret = -EINVAL;
+ goto do_free;
+ }
- if (in_buf.pos >= abuf_size(in) || !res)
- break;
+ len = zstd_decompress_dctx(ctx, abuf_data(out), abuf_size(out),
+ abuf_data(in), len);
+ if (zstd_is_error(len)) {
+ log_err("%s: failed to decompress: %d\n", __func__,
+ zstd_get_error_code(len));
+ ret = -EINVAL;
+ goto do_free;
}
- ret = out_buf.pos;
+ ret = len;
do_free:
free(workspace);
return ret;