diff options
author | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2017-08-12 22:38:25 +0100 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2017-08-12 22:38:25 +0100 |
commit | 8189d621e70b4f38abdc6411c3c4ba890ef023f6 (patch) | |
tree | a07e989007fb5ba78b1d8f64a82ee00e61032b05 /src/libutil | |
parent | eaddd226401393ff96b1f9505e1b530c59bc5504 (diff) | |
download | rspamd-8189d621e70b4f38abdc6411c3c4ba890ef023f6.tar.gz rspamd-8189d621e70b4f38abdc6411c3c4ba890ef023f6.zip |
[Minor] Make a more universal gzip compress utility
Diffstat (limited to 'src/libutil')
-rw-r--r-- | src/libutil/util.c | 65 | ||||
-rw-r--r-- | src/libutil/util.h | 7 |
2 files changed, 71 insertions, 1 deletions
diff --git a/src/libutil/util.c b/src/libutil/util.c index 54cacef44..fbd1ba823 100644 --- a/src/libutil/util.c +++ b/src/libutil/util.c @@ -1,5 +1,5 @@ /*- - * Copyright 2016 Vsevolod Stakhov + * Copyright 2017 Vsevolod Stakhov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -73,6 +73,7 @@ #include <math.h> /* for pow */ #include "cryptobox.h" +#include "zlib.h" /* Check log messages intensity once per minute */ #define CHECK_TIME 60 @@ -2688,3 +2689,65 @@ rspamd_tm_to_time (const struct tm *tm, glong tz) return result; } + +gboolean +rspamd_fstring_gzip (rspamd_fstring_t **in) +{ + z_stream strm; + gint rc; + rspamd_fstring_t *comp, *buf = *in; + gchar *p; + gsize remain; + + memset (&strm, 0, sizeof (strm)); + rc = deflateInit2 (&strm, Z_DEFAULT_COMPRESSION, Z_DEFLATED, + MAX_WBITS + 16, MAX_MEM_LEVEL - 1, Z_DEFAULT_STRATEGY); + + if (rc != Z_OK) { + return FALSE; + } + + comp = rspamd_fstring_sized_new (MIN (buf->len, 32768)); + + strm.avail_in = buf->len; + strm.next_in = (guchar *)buf->str; + p = comp->str; + remain = comp->allocated; + + while (strm.avail_in != 0) { + strm.avail_out = remain; + strm.next_out = p; + + rc = deflate (&strm, Z_FINISH); + + if (rc != Z_OK) { + if (rc == Z_STREAM_END) { + break; + } + else { + rspamd_fstring_free (comp); + deflateEnd (&strm); + + return FALSE; + } + } + + comp->len = strm.total_out; + + if (strm.avail_out == 0 && strm.avail_in != 0) { + /* Need to allocate more */ + remain = comp->len; + comp = rspamd_fstring_grow (comp, comp->allocated + + strm.avail_in + 10); + p = comp->str + remain; + remain = comp->allocated - remain; + } + } + + deflateEnd (&strm); + comp->len = strm.total_out; + rspamd_fstring_free (buf); /* We replace buf with its compressed version */ + *in = comp; + + return TRUE; +}
\ No newline at end of file diff --git a/src/libutil/util.h b/src/libutil/util.h index 9f42d6c92..d1d83716e 100644 --- a/src/libutil/util.h +++ b/src/libutil/util.h @@ -510,5 +510,12 @@ guint64 rspamd_tm_to_time (const struct tm *tm, glong tz); #define PTR_ARRAY_FOREACH(ar, i, cur) for ((i) = 0; (ar) != NULL && (i) < (ar)->len && (((cur) = g_ptr_array_index((ar), (i))) || 1); ++(i)) +/** + * Compresses the input string using gzip+zlib. Old string is replaced and freed + * if compressed. If not compressed it is untouched. + * @param in + * @return TRUE if a string has been compressed + */ +gboolean rspamd_fstring_gzip (rspamd_fstring_t **in); #endif |