From 630e9cd5105e089896b0034403dec8c0d71137a0 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Sun, 18 Jun 2006 07:24:29 +0000 Subject: Add some incremental encryption wrappers to torgzip code svn:r6636 --- src/common/torgzip.c | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) (limited to 'src/common/torgzip.c') diff --git a/src/common/torgzip.c b/src/common/torgzip.c index 3542a4882..c08ed514d 100644 --- a/src/common/torgzip.c +++ b/src/common/torgzip.c @@ -282,3 +282,95 @@ detect_compression_method(const char *in, size_t in_len) } } +struct tor_zlib_state_t { + struct z_stream_s stream; + int compress; +}; + +/** DOCDOC */ +tor_zlib_state_t * +tor_zlib_new(int compress, compress_method_t method) +{ + tor_zlib_state_t *out; + + if (method == GZIP_METHOD && !is_gzip_supported()) { + /* Old zlib version don't support gzip in inflateInit2 */ + log_warn(LD_GENERAL, "Gzip not supported with zlib %s", ZLIB_VERSION); + return NULL; + } + + out = tor_malloc_zero(sizeof(tor_zlib_state_t)); + out->stream.zalloc = Z_NULL; + out->stream.zfree = Z_NULL; + out->stream.opaque = NULL; + out->compress = compress; + if (compress) { + if (deflateInit2(&out->stream, Z_BEST_COMPRESSION, Z_DEFLATED, + method_bits(method), 8, Z_DEFAULT_STRATEGY) != Z_OK) + goto err; + } else { + if (inflateInit2(&out->stream, method_bits(method)) != Z_OK) + goto err; + } + return out; + + err: + tor_free(out); + return NULL; +} + +/** DOCDOC */ +tor_zlib_output_t +tor_zlib_process(tor_zlib_state_t *state, + char **out, size_t *out_len, + const char **in, size_t *in_len, + int finish) +{ + int err; + state->stream.next_in = (unsigned char*) *in; + state->stream.avail_in = *in_len; + state->stream.next_out = (unsigned char*) *out; + state->stream.avail_out = *out_len; + + if (state->compress) { + err = deflate(&state->stream, finish ? Z_FINISH : Z_SYNC_FLUSH); + } else { + err = inflate(&state->stream, finish ? Z_FINISH : Z_SYNC_FLUSH); + } + + *out = (char*) state->stream.next_out; + *out_len = state->stream.avail_out; + *in = (const char *) state->stream.next_in; + *in_len = state->stream.avail_in; + + switch (err) + { + case Z_STREAM_END: + return TOR_ZLIB_DONE; + case Z_BUF_ERROR: + return TOR_ZLIB_BUF_FULL; + case Z_OK: + if (state->stream.avail_out == 0) + return TOR_ZLIB_BUF_FULL; + return TOR_ZLIB_OK; + default: + log_warn(LD_GENERAL, "Gzip returned an error: %s", + state->stream.msg ? state->stream.msg : ""); + return TOR_ZLIB_ERR; + } +} + +/** DOCDOC */ +void +tor_zlib_free(tor_zlib_state_t *state) +{ + tor_assert(state); + + if (state->compress) + deflateEnd(&state->stream); + else + inflateEnd(&state->stream); + + tor_free(state); +} + -- cgit v1.2.3