aboutsummaryrefslogtreecommitdiff
path: root/src/common/torgzip.c
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2006-06-18 07:24:29 +0000
committerNick Mathewson <nickm@torproject.org>2006-06-18 07:24:29 +0000
commit630e9cd5105e089896b0034403dec8c0d71137a0 (patch)
treed0c9ee27349341cf78ab36611ec69911df8a6ab8 /src/common/torgzip.c
parentaf8096815e126dcab718b2eef6e500ed2aa83912 (diff)
downloadtor-630e9cd5105e089896b0034403dec8c0d71137a0.tar
tor-630e9cd5105e089896b0034403dec8c0d71137a0.tar.gz
Add some incremental encryption wrappers to torgzip code
svn:r6636
Diffstat (limited to 'src/common/torgzip.c')
-rw-r--r--src/common/torgzip.c92
1 files changed, 92 insertions, 0 deletions
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 : "<no message>");
+ 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);
+}
+