diff options
author | Gilles Vollant <info@winimage.com> | 2020-05-25 17:49:46 +0200 |
---|---|---|
committer | Daniel Stenberg <daniel@haxx.se> | 2020-07-12 18:11:37 +0200 |
commit | e13357b14b7de013043d704dc9c80697e62616c6 (patch) | |
tree | 47146c8bc1645313653e15fdeb8e1f9f8f0e3bff /lib/content_encoding.c | |
parent | c4026a98979f6ed0f6cf9e544d6544ea3b23464c (diff) | |
download | curl-e13357b14b7de013043d704dc9c80697e62616c6.tar.gz |
content_encoding: add zstd decoding support
include zstd curl patch for Makefile.m32 from vszakats
and include Add CMake support for zstd from Peter Wu
Helped-by: Viktor Szakats
Helped-by: Peter Wu
Closes #5453
Diffstat (limited to 'lib/content_encoding.c')
-rw-r--r-- | lib/content_encoding.c | 96 |
1 files changed, 96 insertions, 0 deletions
diff --git a/lib/content_encoding.c b/lib/content_encoding.c index e2e68a116..2fc3d43c4 100644 --- a/lib/content_encoding.c +++ b/lib/content_encoding.c @@ -38,6 +38,10 @@ #include <brotli/decode.h> #endif +#ifdef HAVE_ZSTD +#include <zstd.h> +#endif + #include "sendf.h" #include "http.h" #include "content_encoding.h" @@ -710,6 +714,95 @@ static const struct content_encoding brotli_encoding = { #endif +#ifdef HAVE_ZSTD +/* Writer parameters. */ +struct zstd_params { + ZSTD_DStream *zds; /* State structure for zstd. */ + void *decomp; +}; + +static CURLcode zstd_init_writer(struct connectdata *conn, + struct contenc_writer *writer) +{ + struct zstd_params *zp = (struct zstd_params *)&writer->params; + (void)conn; + + if(!writer->downstream) + return CURLE_WRITE_ERROR; + + zp->zds = ZSTD_createDStream(); + zp->decomp = NULL; + return zp->zds ? CURLE_OK : CURLE_OUT_OF_MEMORY; +} + +static CURLcode zstd_unencode_write(struct connectdata *conn, + struct contenc_writer *writer, + const char *buf, size_t nbytes) +{ + CURLcode result = CURLE_OK; + struct zstd_params *zp = (struct zstd_params *)&writer->params; + ZSTD_inBuffer in; + ZSTD_outBuffer out; + size_t errorCode; + + if(!zp->decomp) { + zp->decomp = malloc(DSIZ); + if(!zp->decomp) + return CURLE_OUT_OF_MEMORY; + } + in.pos = 0; + in.src = buf; + in.size = nbytes; + + for(;;) { + out.pos = 0; + out.dst = zp->decomp; + out.size = DSIZ; + + errorCode = ZSTD_decompressStream(zp->zds, &out, &in); + if(ZSTD_isError(errorCode)) { + return CURLE_BAD_CONTENT_ENCODING; + } + if(out.pos > 0) { + result = Curl_unencode_write(conn, writer->downstream, + zp->decomp, out.pos); + if(result) + break; + } + if((in.pos == nbytes) && (out.pos < out.size)) + break; + } + + return result; +} + +static void zstd_close_writer(struct connectdata *conn, + struct contenc_writer *writer) +{ + struct zstd_params *zp = (struct zstd_params *)&writer->params; + (void)conn; + + if(zp->decomp) { + free(zp->decomp); + zp->decomp = NULL; + } + if(zp->zds) { + ZSTD_freeDStream(zp->zds); + zp->zds = NULL; + } +} + +static const struct content_encoding zstd_encoding = { + "zstd", + NULL, + zstd_init_writer, + zstd_unencode_write, + zstd_close_writer, + sizeof(struct zstd_params) +}; +#endif + + /* Identity handler. */ static CURLcode identity_init_writer(struct connectdata *conn, struct contenc_writer *writer) @@ -752,6 +845,9 @@ static const struct content_encoding * const encodings[] = { #ifdef HAVE_BROTLI &brotli_encoding, #endif +#ifdef HAVE_ZSTD + &zstd_encoding, +#endif NULL }; |