Add some incremental encryption wrappers to torgzip code

svn:r6636
This commit is contained in:
Nick Mathewson 2006-06-18 07:24:29 +00:00
parent af8096815e
commit 630e9cd510
2 changed files with 104 additions and 0 deletions

View File

@ -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);
}

View File

@ -31,5 +31,17 @@ int is_gzip_supported(void);
int detect_compression_method(const char *in, size_t in_len);
typedef enum {
TOR_ZLIB_OK, TOR_ZLIB_DONE, TOR_ZLIB_BUF_FULL, TOR_ZLIB_ERR
} tor_zlib_output_t;
typedef struct tor_zlib_state_t tor_zlib_state_t;
tor_zlib_state_t *tor_zlib_new(int compress, compress_method_t method);
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);
void tor_zlib_free(tor_zlib_state_t *state);
#endif