summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCedric BAIL <cedric.bail@samsung.com>2015-01-26 15:48:49 +0100
committerCedric BAIL <cedric@osg.samsung.com>2015-02-16 14:47:47 +0100
commitc393d6ff9875e3d7c901885085d9fe3c073ad1f1 (patch)
treed40457e53f268edc4084a4e564c633244d0cdf51
parent31770f439353f609f1160a17ff6f97486c42df21 (diff)
downloadefl-c393d6ff9875e3d7c901885085d9fe3c073ad1f1.tar.gz
emile: add compress/uncompress logic.
-rw-r--r--src/Makefile_Emile.am27
-rw-r--r--src/lib/emile/Emile.h24
-rw-r--r--src/lib/emile/emile_compress.c136
3 files changed, 184 insertions, 3 deletions
diff --git a/src/Makefile_Emile.am b/src/Makefile_Emile.am
index e93b594905..067eb988ca 100644
--- a/src/Makefile_Emile.am
+++ b/src/Makefile_Emile.am
@@ -9,19 +9,40 @@ dist_installed_emilemainheaders_DATA = lib/emile/Emile.h
lib_emile_libemile_la_SOURCES = \
lib/emile/emile_private.h \
lib/emile/emile_main.c \
-lib/emile/emile_cipher.c
+lib/emile/emile_compress.c
+
+if ! ENABLE_LIBLZ4
+lib_emile_libemile_la_SOURCES += \
+static_libs/lz4/lz4.c \
+static_libs/lz4/lz4.h \
+static_libs/lz4/lz4hc.c \
+static_libs/lz4/lz4hc.h
+endif
lib_emile_libemile_la_CPPFLAGS = -I$(top_builddir)/src/lib/efl \
--I$(top_srcdir)/src/static_libs/lz4 \
-DPACKAGE_BIN_DIR=\"$(bindir)\" \
-DPACKAGE_LIB_DIR=\"$(libdir)\" \
-DPACKAGE_DATA_DIR=\"$(datadir)/emile\" \
@EMILE_CFLAGS@
+
+if ! ENABLE_LIBLZ4
+lib_emile_libemile_la_CPPFLAGS += \
+-I$(top_srcdir)/src/static_libs/lz4
+endif
+
lib_emile_libemile_la_LIBADD = @EMILE_LIBS@
lib_emile_libemile_la_DEPENDENCIES = @EMILE_INTERNAL_LIBS@
lib_emile_libemile_la_LDFLAGS = @EFL_LTLIBRARY_FLAGS@
-EXTRA_DIST += static_libs/lz4/README
+if ! ENABLE_LIBLZ4
+lib_emile_libemile_la_LIBADD += @LIBLZ4_LIBS@
+endif
+
+EXTRA_DIST += static_libs/lz4/README \
+static_libs/lz4/lz4.c \
+static_libs/lz4/lz4.h \
+static_libs/lz4/lz4hc.c \
+static_libs/lz4/lz4hc.h
### Binary
diff --git a/src/lib/emile/Emile.h b/src/lib/emile/Emile.h
index 28f84aa53c..c82af0af91 100644
--- a/src/lib/emile/Emile.h
+++ b/src/lib/emile/Emile.h
@@ -112,6 +112,30 @@ EAPI Eina_Binbuf *emile_binbuf_cipher(const Eina_Binbuf *in,
EAPI Eina_Binbuf *emile_binbuf_decipher(const Eina_Binbuf *in,
const char *key, unsigned int length);
+typedef enum
+{
+ EMILE_ZLIB,
+ EMILE_LZ4,
+ EMILE_LZ4HC
+} Emile_Compressor_Type;
+
+typedef enum
+{
+ EMILE_DEFAULT = -1,
+ EMILE_NO_COMPRESSION = 0,
+ EMILE_FAST_COMPRESSION = 1,
+ EMILE_BEST_COMPRESSION = 9
+} Emile_Compressor_Level;
+
+EAPI Eina_Binbuf *emile_binbuf_compress(const Eina_Binbuf *in,
+ Emile_Compressor_Type t, int level);
+EAPI Eina_Binbuf *emile_binbuf_uncompress(const Eina_Binbuf *in,
+ Emile_Compressor_Type t,
+ unsigned int dest_length);
+EAPI Eina_Bool emile_binbuf_expand(const Eina_Binbuf *in,
+ Eina_Binbuf *out,
+ Emile_Compressor_Type t);
+
#ifdef __cplusplus
}
#endif /* ifdef __cplusplus */
diff --git a/src/lib/emile/emile_compress.c b/src/lib/emile/emile_compress.c
new file mode 100644
index 0000000000..4db0ed7bc1
--- /dev/null
+++ b/src/lib/emile/emile_compress.c
@@ -0,0 +1,136 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif /* ifdef HAVE_CONFIG_H */
+
+#include <zlib.h>
+
+#include <Eina.h>
+#include "Emile.h"
+
+#ifdef ENABLE_LIBLZ4
+# include <lz4.h>
+# include <lz4hc.h>
+#else
+# include "lz4.h"
+# include "lz4hc.h"
+#endif
+
+static int
+emile_compress_buffer_size(const Eina_Binbuf *data, Emile_Compressor_Type t)
+{
+ switch (t)
+ {
+ case EMILE_ZLIB:
+ return 12 + ((eina_binbuf_length_get(data) * 101) / 100);
+ case EMILE_LZ4:
+ case EMILE_LZ4HC:
+ return LZ4_compressBound(eina_binbuf_length_get(data));
+ default:
+ return -1;
+ }
+}
+
+EAPI Eina_Binbuf *
+emile_binbuf_compress(const Eina_Binbuf *data, Emile_Compressor_Type t, int level)
+{
+ void *compact;
+ int length;
+ Eina_Bool ok = EINA_FALSE;
+
+ length = emile_compress_buffer_size(data, t);
+
+ compact = malloc(length);
+ if (!compact) return NULL;
+
+ switch (t)
+ {
+ case EMILE_LZ4:
+ length = LZ4_compress((const char *) eina_binbuf_string_get(data), compact, eina_binbuf_length_get(data));
+ if (length > 0) ok = EINA_TRUE;
+ compact = realloc(compact, length); // It is going to be smaller and should never fail, if it does you are in deep poo.
+ break;
+ case EMILE_LZ4HC:
+ length = LZ4_compressHC((const char *) eina_binbuf_string_get(data), compact, eina_binbuf_length_get(data));
+ if (length > 0) ok = EINA_TRUE;
+ compact = realloc(compact, length);
+ break;
+ case EMILE_ZLIB:
+ {
+ uLongf buflen = (uLongf) length;
+
+ if (compress2((Bytef *)compact, &buflen, (Bytef *) eina_binbuf_string_get(data),
+ (uLong) eina_binbuf_length_get(data), level) == Z_OK)
+ ok = EINA_TRUE;
+ length = (int) buflen;
+ }
+ }
+
+ if (!ok)
+ {
+ free(compact);
+ return NULL;
+ }
+
+ return eina_binbuf_manage_new_length(compact, length);
+}
+
+EAPI Eina_Bool
+emile_binbuf_expand(const Eina_Binbuf *in,
+ Eina_Binbuf *out,
+ Emile_Compressor_Type t)
+{
+ if (!in || !out) return EINA_FALSE;
+
+ switch (t)
+ {
+ case EMILE_LZ4:
+ case EMILE_LZ4HC:
+ {
+ int ret;
+
+ ret = LZ4_uncompress((const char*) eina_binbuf_string_get(in),
+ (char*) eina_binbuf_string_get(out),
+ eina_binbuf_length_get(out));
+ if ((unsigned int) ret != eina_binbuf_length_get(in))
+ return EINA_FALSE;
+ break;
+ }
+ case EMILE_ZLIB:
+ {
+ uLongf dlen = eina_binbuf_length_get(out);
+
+ if (uncompress((Bytef *) eina_binbuf_string_get(out), &dlen,
+ eina_binbuf_string_get(in),
+ (uLongf) eina_binbuf_length_get(in)) != Z_OK)
+ return EINA_FALSE;
+ break;
+ }
+ default:
+ return EINA_FALSE;
+ }
+
+ return EINA_TRUE;
+}
+
+EAPI Eina_Binbuf *
+emile_binbuf_uncompress(const Eina_Binbuf *data, Emile_Compressor_Type t, unsigned int dest_length)
+{
+ Eina_Binbuf *out;
+ void *expanded;
+
+ expanded = malloc(dest_length);
+ if (!expanded) return NULL;
+
+ out = eina_binbuf_manage_new_length(expanded, dest_length);
+ if (!out) goto on_error;
+
+ if (!emile_binbuf_expand(data, out, t))
+ goto on_error;
+
+ return out;
+
+ on_error:
+ if (!out) free(expanded);
+ if (out) eina_binbuf_free(out);
+ return NULL;
+}