aboutsummaryrefslogtreecommitdiffstats
path: root/src/libutil
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2017-08-12 22:38:25 +0100
committerVsevolod Stakhov <vsevolod@highsecure.ru>2017-08-12 22:38:25 +0100
commit8189d621e70b4f38abdc6411c3c4ba890ef023f6 (patch)
treea07e989007fb5ba78b1d8f64a82ee00e61032b05 /src/libutil
parenteaddd226401393ff96b1f9505e1b530c59bc5504 (diff)
downloadrspamd-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.c65
-rw-r--r--src/libutil/util.h7
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