diff options
author | Curl Upstream <curl-library@cool.haxx.se> | 2020-08-19 09:37:28 +0200 |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2020-08-19 12:44:30 -0400 |
commit | 7ceb56989f8ab3a4e1b1f2c48c9a0f382b85ec04 (patch) | |
tree | 936c40c921e79b8eabd623181d78167188bbc810 /lib/content_encoding.c | |
parent | 4446fda8e019a0138bec1aa2d83a720d63019ff9 (diff) | |
download | cmake-7ceb56989f8ab3a4e1b1f2c48c9a0f382b85ec04.tar.gz |
curl 2020-08-19 (9d954e49)
Code extracted from:
https://github.com/curl/curl.git
at commit 9d954e49bce3706a9a2efb119ecd05767f0f2a9e (curl-7_72_0).
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 e2e68a1166..2fc3d43c44 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 }; |