emile: initial introduction of Emile.
authorCedric BAIL <cedric.bail@samsung.com>
Tue, 17 Mar 2015 07:49:57 +0000 (08:49 +0100)
committerCedric BAIL <cedric@osg.samsung.com>
Tue, 17 Mar 2015 08:58:17 +0000 (09:58 +0100)
The intent of Emile is to be the common layer for serialisation, compression
and ciphering. It will expose the library we currently use internally to an
easier use from the outside (like gcrypt and lz4). It should improve portability.
Instead of pushing JSON, XML and what's not to Eina, I do think that they will
fit better in Emile.

As for the naming of Emile, you will need to be French and say :
"Un quoi ?" "Un serializer !"

Regarding why it is put there in the stack. Right now there is two users of
compression (eet and terminology), two users of cipher library (eet and ecore_con)
and a few handful of user for serialization (eina, eet, efreet, ecore_con, ...).
So the choice was quite simple, it needed to be below Eet. Now it could have been
on top of Eo or integrated into Eina.

One of the use case I am thinking of, is to compress Eo object when a canvas get
hidden/minized. For that it require Eo to use that library and it can't be a higher
level object. And with current implementation of Eo it is perfectly possible to
implement such idea. So not at Eo level.

As for Eina, I am starting to think it is getting to much things in its namespace.
I do believe that infact Eina_Simple_XML and Eina_File should after all have landed
in their own library. That's why I am putting the current logic in a new library.
It is going to expand, I want it to provide an few SAX like parser for JSON,
Eet_Data and protobuf with also an API like Eet_Data to directly feed those value
into a C structure without using a DOM at all. It would also be the right place
to experiment and benchmark for a new Eet_Data format that could be more efficient
to use.

So at the end, and due to how I see things going and being used, I do think it
is better of in its own library.

COPYING
Makefile.am
configure.ac
pc/.gitignore
pc/emile.pc.in [new file with mode: 0644]
src/Makefile.am
src/Makefile_Emile.am [new file with mode: 0644]
src/lib/emile/Emile.h [new file with mode: 0644]
src/lib/emile/emile_main.c [new file with mode: 0644]
src/tests/emile/emile_suite.c [new file with mode: 0644]

diff --git a/COPYING b/COPYING
index 80f87c3..d429450 100644 (file)
--- a/COPYING
+++ b/COPYING
@@ -14,6 +14,7 @@ use them and is not more restrictive).
 evil:            licenses/COPYING.BSD
 escape:          licenses/COPYING.GPL (used in PlayStation native)
 eina:            licenses/COPYING.LGPL
+emile:           licenses/COPYING.LGPL
 eet:             licenses/COPYING.BSD
 eo:              licenses/COPYING.BSD
 evas:            licenses/COPYING.BSD
index b1b7ea1..af334fe 100644 (file)
@@ -128,6 +128,7 @@ pc/eo.pc \
 pc/eolian.pc \
 pc/efl.pc \
 pc/efl-cxx.pc \
+pc/emile.pc \
 pc/eet.pc \
 pc/evas.pc \
 pc/ecore.pc \
index c12968b..e4e2ab3 100644 (file)
@@ -1034,6 +1034,54 @@ EFL_EVAL_PKGS([EET_CXX])
 EFL_LIB_END([Eet_Cxx])
 #### End of Eet CXX
 
+#### Emile
+
+EFL_LIB_START([Emile])
+
+### Default values
+
+### Additional options to configure
+
+### Checks for programs
+
+### Checks for libraries
+
+## Compatibility layers
+EFL_PLATFORM_DEPEND([EMILE], [evil])
+
+EFL_ADD_LIBS([EMILE], [-lm])
+
+# Cryptography support
+if test "$build_crypto" != "none" ; then
+   AC_DEFINE([HAVE_CIPHER], [1], [Have cipher support built in emile])
+   AC_DEFINE([HAVE_SIGNATURE], [1], [Have signature support in emile])
+   EFL_CRYPTO_DEPEND([EMILE])
+fi
+
+EFL_CHECK_LIBS([EMILE], [zlib])
+
+EFL_INTERNAL_DEPEND_PKG([EMILE], [eina])
+
+EFL_EVAL_PKGS([EMILE])
+
+### Checks for header files
+
+### Checks for types
+
+### Checks for structures
+
+### Checks for compiler characteristics
+
+### Checks for linker characteristics
+
+### Checks for library functions
+
+### Check availability
+
+EFL_LIB_END([Emile])
+#### End of Emile
+
+
 #### Eet
 
 EFL_LIB_START([Eet])
@@ -1061,6 +1109,7 @@ fi
 EFL_CHECK_LIBS([EET], [libjpeg zlib])
 
 EFL_INTERNAL_DEPEND_PKG([EET], [eina])
+EFL_INTERNAL_DEPEND_PKG([EET], [emile])
 
 EFL_EVAL_PKGS([EET])
 
@@ -4413,6 +4462,7 @@ pc/evil.pc
 pc/escape.pc
 pc/eina.pc
 pc/eina-cxx.pc
+pc/emile.pc
 pc/eet.pc
 pc/eet-cxx.pc
 pc/eo.pc
@@ -4591,15 +4641,17 @@ echo "  Cryptography..: ${build_crypto}"
 echo "  X11...........: ${with_x11}"
 echo "  OpenGL........: ${with_opengl}"
 echo "  C++11.........: ${have_cxx11}"
+echo "Eina............: yes (${features_eina})"
+echo "Eo..............: yes (${features_eo})"
+echo "Eolian..........: yes (${features_eolian})"
+echo "Emile...........: yes"
+echo "Eet.............: yes"
 echo "Evas............: yes (${features_evas})"
 echo "  Engines.......: ${features_evas_engine}"
 echo "  Image Loaders.: ${features_evas_loader}"
 if test "x${have_pixman}" = "xyes" ; then
 echo "  Pixman........: ${features_evas_pixman}"
 fi
-echo "Eo..............: yes (${features_eo})"
-echo "Eolian..........: yes (${features_eolian})"
-echo "Eina............: yes (${features_eina})"
 echo "Ecore...........: yes (${features_ecore})"
 echo "Ecore_Con.......: yes (${features_ecore_con})"
 echo "Ecore_File......: yes"
index db9bc3f..4aaaa13 100644 (file)
@@ -61,3 +61,4 @@
 /efl.pc
 /efl-cxx.pc
 /elua.pc
+/emile.pc
diff --git a/pc/emile.pc.in b/pc/emile.pc.in
new file mode 100644 (file)
index 0000000..a933808
--- /dev/null
@@ -0,0 +1,12 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: emile
+Description: Library for simplified serialization, compression and ciphering.
+Version: @VERSION@
+Requires.private: @requirements_pc_emile@
+Libs: -L${libdir} -lemile
+Libs.private: @requirements_libs_emile@
+Cflags: -I${includedir}/efl-@VMAJ@ -I${includedir}/emile-@VMAJ@
index 4c9c95e..580911a 100644 (file)
@@ -31,6 +31,7 @@ include Makefile_Escape.am
 include Makefile_Eina.am
 include Makefile_Eo.am
 include Makefile_Efl.am
+include Makefile_Emile.am
 include Makefile_Eet.am
 include Makefile_Eolian.am
 include Makefile_Evas.am
diff --git a/src/Makefile_Emile.am b/src/Makefile_Emile.am
new file mode 100644 (file)
index 0000000..227be05
--- /dev/null
@@ -0,0 +1,48 @@
+
+### Library
+
+lib_LTLIBRARIES += lib/emile/libemile.la
+
+installed_emilemainheadersdir = $(includedir)/emile-@VMAJ@
+dist_installed_emilemainheaders_DATA = lib/emile/Emile.h
+
+lib_emile_libemile_la_SOURCES = \
+lib/emile/emile_main.c
+
+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@
+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
+
+### Binary
+
+# None yet, maybe a tool to manually use cypher/compression ?
+
+### Unit tests
+
+if EFL_ENABLE_TESTS
+
+check_PROGRAMS += tests/emile/emile_suite
+TESTS += tests/emile/emile_suite
+
+tests_emile_emile_suite_SOURCES = \
+tests/emile/emile_suite.c
+
+tests_emile_emile_suite_CPPFLAGS = -I$(top_builddir)/src/lib/efl \
+-DTESTS_WD=\"`pwd`\" \
+-DTESTS_SRC_DIR=\"$(top_srcdir)/src/tests/emile\" \
+-DTESTS_BUILD_DIR=\"$(top_builddir)/src/tests/emile\" \
+@CHECK_CFLAGS@ \
+@EMILE_CFLAGS@
+
+tests_emile_emile_suite_LDADD = @CHECK_LIBS@ @USE_EMILE_LIBS@
+tests_emile_emile_suite_DEPENDENCIES = @USE_EMILE_INTERNAL_LIBS@
+
+endif
diff --git a/src/lib/emile/Emile.h b/src/lib/emile/Emile.h
new file mode 100644 (file)
index 0000000..b0ab0ef
--- /dev/null
@@ -0,0 +1,111 @@
+/* EMILE - EFL serialization, compression and crypto library.
+ * Copyright (C) 2013 Enlightenment Developers:
+ *           Cedric Bail <cedric.bail@samsung.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library;
+ * if not, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ * @brief Emile serialization, compression and ciphering public API calls.
+ *
+ * These routines are used for Emile Library interaction
+ *
+ * @date 2013 (created)
+ */
+#ifndef EMILE_H_
+#define EMILE_H_
+
+#ifdef EAPI
+# undef EAPI
+#endif /* ifdef EAPI */
+
+#ifdef _WIN32
+# ifdef EFL_EMILE_BUILD
+#  ifdef DLL_EXPORT
+#   define EAPI __declspec(dllexport)
+#  else /* ifdef DLL_EXPORT */
+#   define EAPI
+#  endif /* ! DLL_EXPORT */
+# else /* ifdef EFL_EET_BUILD */
+#  define EAPI __declspec(dllimport)
+# endif /* ! EFL_EET_BUILD */
+#else /* ifdef _WIN32 */
+# ifdef __GNUC__
+#  if __GNUC__ >= 4
+#   define EAPI __attribute__ ((visibility("default")))
+#  else /* if __GNUC__ >= 4 */
+#   define EAPI
+#  endif /* if __GNUC__ >= 4 */
+# else /* ifdef __GNUC__ */
+#  define EAPI
+# endif /* ifdef __GNUC__ */
+#endif /* ! _WIN32 */
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* ifdef __cplusplus */
+
+/**
+ * @file Emile.h
+ * @brief The file that provide the Emile function
+ *
+ * This header provides the Emile management functions.
+ */
+
+/**
+ * @defgroup Emile_Group Top level functions
+ * @ingroup Emile
+ * Function that affect Emile as a whole.
+ *
+ * @{
+ */
+
+/**
+ * Initialize the Emile library
+ *
+ * The first time this function is called, it will perform all the internal
+ * initialization required for the library to function properly and
+ * increment the initialization counter. Any subsequent call only
+ * increment this counter and return its new value, so it's safe to call
+ * this function more than once.
+ *
+ * @return The new init count. Will be 0 if initialization failed.
+ *
+ * @since 1.9.0
+ */
+EAPI int emile_init(void);
+
+/**
+ * Shut down the Emile library
+ *
+ * If emile_init() was called more than once for the running application,
+ * emile_shutdown() will decrement the initialization counter and return its
+ * new value, without doing anything else. When the counter reaches 0, all
+ * of the internal elements will be shutdown and any memory used freed.
+ *
+ * @return The new init count.
+ * @since 1.9.0
+ */
+EAPI int emile_shutdown(void);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif /* ifdef __cplusplus */
+
+#endif /* ifndef _EET_H */
diff --git a/src/lib/emile/emile_main.c b/src/lib/emile/emile_main.c
new file mode 100644 (file)
index 0000000..389f660
--- /dev/null
@@ -0,0 +1,56 @@
+#include <Eina.h>
+
+#include "Emile.h"
+
+static unsigned int _emile_init_count = 0;
+int _emile_log_dom_global = -1;
+
+EAPI int
+emile_init(void)
+{
+   if (++_emile_init_count != 1)
+     return _emile_init_count;
+
+   if (!eina_init())
+     return --_emile_init_count;
+
+   _emile_log_dom_global = eina_log_domain_register("emile", EINA_COLOR_CYAN);
+   if (_emile_log_dom_global < 0)
+     {
+        EINA_LOG_ERR("Emile can not create a general log domain.");
+        goto shutdown_eina;
+     }
+
+   // FIXME: Init the rest here.
+
+   eina_log_timing(_emile_log_dom_global,
+                   EINA_LOG_STATE_STOP,
+                   EINA_LOG_STATE_INIT);
+
+   return _emile_init_count;
+
+ shutdown_eina:
+   eina_shutdown();
+
+   return --_emile_init_count;
+}
+
+EAPI int
+emile_shutdown(void)
+{
+   if (--_emile_init_count != 0)
+     return _emile_init_count;
+
+   eina_log_timing(_emile_log_dom_global,
+                   EINA_LOG_STATE_START,
+                   EINA_LOG_STATE_SHUTDOWN);
+
+   // FIXME: Shutdown the rest here.
+
+   eina_log_domain_unregister(_emile_log_dom_global);
+   _emile_log_dom_global = -1;
+
+   eina_shutdown();
+
+   return _emile_init_count;
+}
diff --git a/src/tests/emile/emile_suite.c b/src/tests/emile/emile_suite.c
new file mode 100644 (file)
index 0000000..2663bce
--- /dev/null
@@ -0,0 +1,102 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif /* ifdef HAVE_CONFIG_H */
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <check.h>
+
+#include <Eina.h>
+#include <Emile.h>
+
+START_TEST(emile_test_init)
+{
+   fail_if(emile_init() <= 0);
+   fail_if(emile_shutdown() != 0);
+}
+END_TEST
+
+static void
+emile_base_test(TCase *tc)
+{
+   tcase_add_test(tc, emile_test_init);
+}
+
+static const struct {
+   const char *name;
+   void (*build)(TCase *tc);
+} tests[] = {
+   { "Emile_Base", emile_base_test }
+};
+
+static void
+_list_tests(void)
+{
+   unsigned int i;
+
+   fputs("Available tests cases :\n", stderr);
+   for (i = 0; i < sizeof (tests) / sizeof (tests[0]); i++)
+     fprintf(stderr, "\t%s\n", tests[i].name);
+}
+
+static Eina_Bool
+_use_test(const char *name, int argc, char *argv[])
+{
+   argc--; argv--;
+
+   if (argc < 1) return EINA_TRUE;
+
+   for (; argc > 1; argc--, argv++)
+     if (strcmp(name, *argv) == 0)
+       return EINA_TRUE;
+   return EINA_FALSE;
+}
+
+int
+main(int argc, char *argv[])
+{
+   SRunner *sr;
+   Suite *s;
+   unsigned int i;
+   int failed_count;
+   int j;
+
+   for (j = 1; j < argc; j++)
+     if ((strcmp(argv[j], "-h") == 0) ||
+         (strcmp(argv[j], "--help") == 0))
+       {
+          fprintf(stderr, "Usage:\n\t%s [test_case1 .. [test_caseN]]\n",
+                  argv[0]);
+          _list_tests();
+          return 0;
+       }
+     else if ((strcmp(argv[j], "-l") == 0) ||
+              (strcmp(argv[j], "--list") == 0))
+       {
+          _list_tests();
+          return 0;
+       }
+
+   s = suite_create("Emile");
+
+   for (i = 0; i < sizeof (tests) / sizeof (tests[0]); ++i)
+     {
+        TCase *tc;
+
+        if (!_use_test(tests[i].name, argc, argv)) continue ;
+
+        tc = tcase_create(tests[i].name);
+        tests[i].build(tc);
+        suite_add_tcase(s, tc);
+        tcase_set_timeout(tc, 0);
+     }
+
+   sr = srunner_create(s);
+   srunner_set_xml(sr, TESTS_BUILD_DIR "/check-results.xml");
+   srunner_run_all(sr, CK_ENV);
+   failed_count = srunner_ntests_failed(sr);
+   srunner_free(sr);
+
+   return (failed_count == 0) ? 0 : 255;
+}