This patch is a starting point for cleaning up eet_data.c.
authorcedric <cedric>
Thu, 26 Jun 2008 15:47:25 +0000 (15:47 +0000)
committercedric <cedric@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Thu, 26 Jun 2008 15:47:25 +0000 (15:47 +0000)
It also add EET_G_VAR_ARRAY and EET_G_ARRAY thanks to
turran's (jorgeluis.zapata@gmail.com) last year patch.
Of course we have test code for it and eet_data.c code
is covered around 90.1%. We need to test with garbage
data for increasing it more.

WARNING: API of eet_data_descriptor_element_add is not
clean and we will need to break it, if we want a clean
API. So this is the plan for version 2.0.0.

git-svn-id: http://svn.enlightenment.org/svn/e/trunk/e17/libs/eet@34919 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33

ChangeLog
configure.in
src/lib/Eet.h
src/lib/Eet_private.h
src/lib/eet_data.c
src/tests/eet_suite.c

index 9c7dd59..9b12dc9 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
        * Introduce tile support and the possibility to decompress eet
        image inside an existing surface.
 
+2008-06-26  Cedric BAIL
+
+       * Massiv code cleanup.
+       * Add EET_G_ARRAY and EET_G_VAR_ARRAY support.
+       * Plan for version 2.0 API break of eet_data_descriptor_element_add.
+
 
index 2e0a505..ebf301e 100644 (file)
@@ -200,6 +200,20 @@ else
   AC_DEFINE(EET_OLD_EET_FILE_FORMAT, 0, [support old eet file format])
 fi
 
+dnl Assert or fail.
+prefer_assert="no"
+AC_ARG_ENABLE(assert,
+  AC_HELP_STRING(
+    [--enable-assert],
+    [enable assert, [[default=disabled]]]
+  ),
+  [ prefer_assert=$enableval ]
+)
+AM_CONDITIONAL(EET_ASSERT, test "x$prefer_assert" = "xyes")
+if test "x$prefer_assert" = "xno"; then
+  cflags="$cflags -DNDEBUG"
+fi
+
 #AM_CHECK_DOXYGEN()
 
 AC_OUTPUT([
index 6ef1182..dc7a383 100644 (file)
@@ -889,7 +889,7 @@ extern "C" {
     *
     * @since 1.0.0
     */
-   EAPI void eet_data_descriptor_element_add(Eet_Data_Descriptor *edd, const char *name, int type, int group_type, int offset, int count, const char *counter_name, Eet_Data_Descriptor *subtype);
+   EAPI void eet_data_descriptor_element_add(Eet_Data_Descriptor *edd, const char *name, int type, int group_type, int offset, /* int count_offset,  */int count, const char *counter_name, Eet_Data_Descriptor *subtype);
 
    /**
     * Read a data structure from an eet file and decodes it.
@@ -1114,7 +1114,7 @@ eet_dictionary_string_check    * example: values), and @p type is the basic data
        \
        eet_data_descriptor_element_add(edd, name, type, EET_G_UNKNOWN, \
                                        (char *)(&(___ett.member)) - (char *)(&(___ett)), \
-                                       0, NULL, NULL); \
+                                       0, /* 0,  */NULL, NULL); \
      }
 
    /**
@@ -1139,7 +1139,7 @@ eet_dictionary_string_check    * example: values), and @p type is the basic data
        \
        eet_data_descriptor_element_add(edd, name, EET_T_UNKNOW, EET_G_UNKNOWN, \
                                        (char *)(&(___ett.member)) - (char *)(&(___ett)), \
-                                       0, NULL, subtype); \
+                                       0, /* 0,  */NULL, subtype); \
      }
 
    /**
@@ -1163,7 +1163,7 @@ eet_dictionary_string_check    * example: values), and @p type is the basic data
        \
        eet_data_descriptor_element_add(edd, name, EET_T_UNKNOW, EET_G_LIST, \
                                        (char *)(&(___ett.member)) - (char *)(&(___ett)), \
-                                       0, NULL, subtype); \
+                                       0, /* 0,  */NULL, subtype); \
      }
 
    /**
@@ -1187,7 +1187,55 @@ eet_dictionary_string_check    * example: values), and @p type is the basic data
        \
        eet_data_descriptor_element_add(edd, name, EET_T_UNKNOW, EET_G_HASH, \
                                        (char *)(&(___ett.member)) - (char *)(&(___ett)), \
-                                       0, NULL, subtype); \
+                                       0, /* 0,  */NULL, subtype); \
+     }
+
+   /**
+    * Add a fixed size array type to a data descriptor
+    * @param edd The data descriptor to add the type to.
+    * @param struct_type The type of the struct.
+    * @param name The string name to use to encode/decode this member (must be a constant global and never change).
+    * @param member The struct member itself to be encoded.
+    * @param subtype The type of hash member to add.
+    *
+    * This macro lets you easily add a fixed size array of other data types. All the
+    * parameters are the same as for EET_DATA_DESCRIPTOR_ADD_BASIC(), with the
+    * @p subtype being the exception. This must be the data descriptor of the
+    * element that is in each member of the hash to be stored.
+    *
+    * @since 1.0.2
+    */
+#define EET_DATA_DESCRIPTOR_ADD_ARRAY(edd, struct_type, name, member, subtype) \
+     { \
+       struct_type ___ett; \
+       \
+       eet_data_descriptor_element_add(edd, name, EET_T_UNKNOW, EET_G_ARRAY, \
+                                       (char *)(&(___ett.member)) - (char *)(&(___ett)), \
+                                       /* 0,  */sizeof(___ett.member)/sizeof(___ett.member[0]), NULL, subtype); \
+     }
+
+   /**
+    * Add a variable size array type to a data descriptor
+    * @param edd The data descriptor to add the type to.
+    * @param struct_type The type of the struct.
+    * @param name The string name to use to encode/decode this member (must be a constant global and never change).
+    * @param member The struct member itself to be encoded.
+    * @param subtype The type of hash member to add.
+    *
+    * This macro lets you easily add a fixed size array of other data types. All the
+    * parameters are the same as for EET_DATA_DESCRIPTOR_ADD_BASIC(), with the
+    * @p subtype being the exception. This must be the data descriptor of the
+    * element that is in each member of the hash to be stored.
+    *
+    * @since 1.0.2
+    */
+#define EET_DATA_DESCRIPTOR_ADD_VAR_ARRAY(edd, struct_type, name, member, subtype) \
+     { \
+       struct_type ___ett; \
+       \
+       eet_data_descriptor_element_add(edd, name, EET_T_UNKNOW, EET_G_VAR_ARRAY, \
+                                       (char *)(&(___ett.member)) - (char *)(&(___ett)), \
+                                       (char *)(&(___ett.member ## _count)) - (char *)(&(___ett)), /* 0,  */NULL, subtype); \
      }
 
 /***************************************************************************/
index a2c2e13..09a37d2 100644 (file)
@@ -74,4 +74,10 @@ void  _eet_double_to_string_convert(char des[128], double d);
 #define PATH_MAX 4096
 #endif
 
+#ifdef DNDEBUG
+#define EET_ASSERT(Test, Do) if (Test == 0) Do;
+#else
+#define EET_ASSERT(Test, Do) if (Test == 0) abort();
+#endif
+
 #endif
index f35b42f..425231e 100644 (file)
@@ -12,7 +12,6 @@
 #define __UNUSED__
 #endif
 
-#include <assert.h>
 #include <stdio.h>
 #include <string.h>
 #include <math.h>
@@ -70,7 +69,8 @@
 /*---*/
 
 typedef struct _Eet_Data_Element            Eet_Data_Element;
-typedef struct _Eet_Data_Basic_Type_Decoder Eet_Data_Basic_Type_Decoder;
+typedef struct _Eet_Data_Basic_Type_Codec   Eet_Data_Basic_Type_Codec;
+typedef struct _Eet_Data_Group_Type_Codec   Eet_Data_Group_Type_Codec;
 typedef struct _Eet_Data_Chunk              Eet_Data_Chunk;
 typedef struct _Eet_Data_Stream             Eet_Data_Stream;
 typedef struct _Eet_Data_Descriptor_Hash    Eet_Data_Descriptor_Hash;
@@ -78,7 +78,11 @@ typedef struct _Eet_Data_Encode_Hash_Info   Eet_Data_Encode_Hash_Info;
 
 /*---*/
 
-struct _Eet_Data_Basic_Type_Decoder
+/* TODO:
+ * Eet_Data_Basic_Type_Codec (Coder, Decoder)
+ * Eet_Data_Group_Type_Codec (Coder, Decoder)
+ */
+struct _Eet_Data_Basic_Type_Codec
 {
    int         size;
    const char *name;
@@ -86,6 +90,12 @@ struct _Eet_Data_Basic_Type_Decoder
    void     *(*put) (Eet_Dictionary *ed, const void *src, int *size_ret);
 };
 
+struct _Eet_Data_Group_Type_Codec
+{
+   int  (*get) (const Eet_Dictionary *ed, Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Chunk *echnk, int type, int group_type, void *data_in, int level, void (*dumpfunc) (void *data, const char *str), void *dumpdata, char **p, int *size);
+   void (*put) (Eet_Dictionary *ed, Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Stream *ds, void *data_in);
+};
+
 struct _Eet_Data_Chunk
 {
    char          *name;
@@ -145,10 +155,11 @@ struct _Eet_Data_Element
    const char          *name;
    const char          *counter_name;
    Eet_Data_Descriptor *subtype;
-   int                  offset;
-   int                  count;
-   unsigned char        type;
-   unsigned char        group_type;
+   int                  offset;         /* offset in bytes from the base element */
+   int                  count;          /* number of elements for a fixed array */
+   int                  counter_offset; /* for a variable array we need the offset of the count variable */
+   unsigned char        type;           /* EET_T_XXX */
+   unsigned char        group_type;     /* EET_G_XXX */
 };
 
 struct _Eet_Data_Encode_Hash_Info
@@ -180,6 +191,15 @@ static void *eet_data_put_istring(Eet_Dictionary *ed, const void *src, int *size
 static int   eet_data_get_type(const Eet_Dictionary *ed, int type, const void *src, const void *src_end, void *dest);
 static void *eet_data_put_type(Eet_Dictionary *ed, int type, const void *src, int *size_ret);
 
+static int  eet_data_get_unknown(const Eet_Dictionary *ed, Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Chunk *echnk, int type, int group_type, void *data_in, int level, void (*dumpfunc) (void *data, const char *str), void *dumpdata, char **p, int *size);
+static void eet_data_put_unknown(Eet_Dictionary *ed, Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Stream *ds, void *data_in);
+static void eet_data_put_array(Eet_Dictionary *ed, Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Stream *ds, void *data_in);
+static int  eet_data_get_array(const Eet_Dictionary *ed, Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Chunk *echnk, int type, int group_type, void *data, int level, void (*dumpfunc) (void *data, const char *str), void *dumpdata, char **p, int *size);
+static int  eet_data_get_list(const Eet_Dictionary *ed, Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Chunk *echnk, int type, int group_type, void *data_in, int level, void (*dumpfunc) (void *data, const char *str), void *dumpdata, char **p, int *size);
+static void eet_data_put_list(Eet_Dictionary *ed, Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Stream *ds, void *data_in);
+static void eet_data_put_hash(Eet_Dictionary *ed, Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Stream *ds, void *data_in);
+static int  eet_data_get_hash(const Eet_Dictionary *ed, Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Chunk *echnk, int type, int group_type, void *data, int level, void (*dumpfunc) (void *data, const char *str), void *dumpdata, char **p, int *size);
+
 static void            eet_data_chunk_get(const Eet_Dictionary *ed, Eet_Data_Chunk *chnk, const void *src, int size);
 static Eet_Data_Chunk *eet_data_chunk_new(void *data, int size, const char *name, int type, int group_type);
 static void            eet_data_chunk_free(Eet_Data_Chunk *chnk);
@@ -202,7 +222,7 @@ static void     *_eet_data_descriptor_decode(const Eet_Dictionary *ed,
 
 /*---*/
 
-const Eet_Data_Basic_Type_Decoder eet_coder[] =
+static const Eet_Data_Basic_Type_Codec eet_basic_codec[] =
 {
      {sizeof(char),      "char",       eet_data_get_char,      eet_data_put_char     },
      {sizeof(short),     "short",      eet_data_get_short,     eet_data_put_short    },
@@ -218,6 +238,15 @@ const Eet_Data_Basic_Type_Decoder eet_coder[] =
      {sizeof(char *),    "inlined",    eet_data_get_istring,   eet_data_put_istring  }
 };
 
+static const Eet_Data_Group_Type_Codec eet_group_codec[] =
+{
+     { eet_data_get_unknown,  eet_data_put_unknown },
+     { eet_data_get_array,    eet_data_put_array },
+     { eet_data_get_array,    eet_data_put_array },
+     { eet_data_get_list,     eet_data_put_list },
+     { eet_data_get_hash,     eet_data_put_hash }
+};
+
 static int words_bigendian = -1;
 
 /*---*/
@@ -606,7 +635,7 @@ eet_data_get_type(const Eet_Dictionary *ed, int type, const void *src, const voi
 {
    int ret;
 
-   ret = eet_coder[type - 1].get(ed, src, src_end, dest);
+   ret = eet_basic_codec[type - 1].get(ed, src, src_end, dest);
    return ret;
 }
 
@@ -615,7 +644,7 @@ eet_data_put_type(Eet_Dictionary *ed, int type, const void *src, int *size_ret)
 {
    void *ret;
 
-   ret = eet_coder[type - 1].put(ed, src, size_ret);
+   ret = eet_basic_codec[type - 1].put(ed, src, size_ret);
    return ret;
 }
 
@@ -625,7 +654,7 @@ eet_data_put_type(Eet_Dictionary *ed, int type, const void *src, int *size_ret)
  * char[4] = "CHKx"; // typed data - x == type
  *
  * int     = chunk size (including magic string);
- * char[]  = chuck magic/name string (0 byte terminated);
+ * char[]  = chunk magic/name string (0 byte terminated);
  * ... sub-chunks (a chunk can contain chuncks recusrively) ...
  * or
  * ... payload data ...
@@ -633,7 +662,8 @@ eet_data_put_type(Eet_Dictionary *ed, int type, const void *src, int *size_ret)
  */
 
 static void
-eet_data_chunk_get(const Eet_Dictionary *ed, Eet_Data_Chunk *chnk, const void *src, int size)
+eet_data_chunk_get(const Eet_Dictionary *ed, Eet_Data_Chunk *chnk,
+                  const void *src, int size)
 {
    const char *s;
    int ret1, ret2;
@@ -1023,10 +1053,13 @@ eet_data_descriptor_free(Eet_Data_Descriptor *edd)
 
 EAPI void
 eet_data_descriptor_element_add(Eet_Data_Descriptor *edd,
-                               const char *name, int type,
+                               const char *name,
+                               int type,
                                int group_type,
                                int offset,
-                               int count, const char *counter_name,
+                               int count,
+/*                             int counter_offset, */
+                               const char *counter_name /* Useless should go on a major release */,
                                Eet_Data_Descriptor *subtype)
 {
    Eet_Data_Element *ede;
@@ -1053,11 +1086,11 @@ eet_data_descriptor_element_add(Eet_Data_Descriptor *edd,
        subtype = calloc(1, sizeof (Eet_Data_Descriptor));
        if (!subtype) return ;
        subtype->name = "implicit";
-       subtype->size = eet_coder[type - 1].size;
+       subtype->size = eet_basic_codec[type - 1].size;
        memcpy(&subtype->func, &edd->func, sizeof(subtype->func));
 
-       eet_data_descriptor_element_add(subtype, eet_coder[type - 1].name, type,
-                                       EET_G_UNKNOWN, 0, 0, NULL, NULL);
+       eet_data_descriptor_element_add(subtype, eet_basic_codec[type - 1].name, type,
+                                       EET_G_UNKNOWN, 0, 0, /* 0,  */NULL, NULL);
        type = EET_T_UNKNOW;
      }
 
@@ -1065,6 +1098,9 @@ eet_data_descriptor_element_add(Eet_Data_Descriptor *edd,
    ede->group_type = group_type;
    ede->offset = offset;
    ede->count = count;
+   /* FIXME: For the time being, EET_G_VAR_ARRAY will put the counter_offset in count. */
+   ede->counter_offset = count;
+/*    ede->counter_offset = counter_offset; */
    ede->counter_name = counter_name;
 
    ede->subtype = subtype;
@@ -1283,7 +1319,7 @@ eet_data_descriptor_encode_hash_cb(void *hash __UNUSED__, const char *key, void
        data = NULL;
      }
 
-   assert(!IS_SIMPLE_TYPE(ede->type));
+   EET_ASSERT(!IS_SIMPLE_TYPE(ede->type), return 1);
 
    /* Store data */
    if (ede->subtype)
@@ -1429,6 +1465,7 @@ typedef struct _Node Node;
 struct _Node
 {
    int    type;
+   int    count;
    char  *name;
    char  *key;
    Node  *values;
@@ -1500,7 +1537,7 @@ _eet_data_dump_encode(Eet_Dictionary *ed,
    Eet_Data_Stream *ds;
    void *cdata, *data;
    int csize, size;
-   Node *n;
+   Node *n, *n2;
 
    if (words_bigendian == -1)
      {
@@ -1528,27 +1565,39 @@ _eet_data_dump_encode(Eet_Dictionary *ed,
          }
        break;
       case EET_G_ARRAY:
-       for (n = node->values; n; n = n->next)
+      case EET_G_VAR_ARRAY:
+       data = eet_data_put_type(ed,
+                                EET_T_INT,
+                                &node->count,
+                                &size);
+       if (data)
          {
-            data = _eet_data_dump_encode(ed, n, &size);
-            if (data)
-              {
-                 eet_data_stream_write(ds, data, size);
-                 free(data);
-              }
+            echnk = eet_data_chunk_new(data, size, node->name, node->type, node->type);
+            eet_data_chunk_put(ed, echnk, ds);
+            eet_data_chunk_free(echnk);
+            free(data);
          }
-       break;
-      case EET_G_VAR_ARRAY:
        for (n = node->values; n; n = n->next)
          {
             data = _eet_data_dump_encode(ed, n, &size);
             if (data)
               {
-                 eet_data_stream_write(ds, data, size);
+                 echnk = eet_data_chunk_new(data, size, node->name, node->type, node->type);
+                 eet_data_chunk_put(ed, echnk, ds);
+                 eet_data_chunk_free(echnk);
                  free(data);
               }
          }
-       break;
+
+       /* Array is somekind of special case, so we should embed it inside another chunk. */
+       *size_ret = ds->pos;
+       cdata = ds->data;
+
+       ds->data = NULL;
+       ds->size = 0;
+       eet_data_stream_free(ds);
+
+       return cdata;
       case EET_G_LIST:
        for (n = node->values; n; n = n->next)
          {
@@ -1931,6 +1980,19 @@ _eet_data_dump_parse(Eet_Dictionary *ed,
                       free(tok2);
                    }
               }
+            else if (!strcmp(tok1, "count"))
+              {
+                 TOK_GET(tok2);
+                 if (tok2)
+                   {
+                      /* we have a 'count COUNT' */
+                      if (node)
+                        {
+                           sscanf(tok2, "%i", &(node->count));
+                        }
+                      free(tok2);
+                   }
+              }
             else if (!strcmp(tok1, "}"))
               {
                  /* we have an end of the group */
@@ -2055,6 +2117,7 @@ _eet_data_descriptor_decode(const Eet_Dictionary *ed,
             if (ede)
               {
                  int group_type = EET_G_UNKNOWN, type = EET_T_UNKNOW;
+                 int ret = 0;
 
                  group_type = ede->group_type;
                  type = ede->type;
@@ -2065,8 +2128,7 @@ _eet_data_descriptor_decode(const Eet_Dictionary *ed,
                    }
                  else
                    {
-                      if ((echnk.type > EET_T_UNKNOW) &&
-                          (echnk.type < EET_T_LAST) &&
+                      if (IS_SIMPLE_TYPE(echnk.type) &&
                           (echnk.type == ede->type))
                         type = echnk.type;
                       else if ((echnk.group_type > EET_G_UNKNOWN) &&
@@ -2074,162 +2136,9 @@ _eet_data_descriptor_decode(const Eet_Dictionary *ed,
                                (echnk.group_type == ede->group_type))
                         group_type = echnk.group_type;
                    }
-                 if (group_type == EET_G_UNKNOWN)
-                   {
-                      int ret;
-                      void *data_ret;
-
-                      if (IS_SIMPLE_TYPE(type))
-                        {
-                           ret = eet_data_get_type(ed,
-                                                    type,
-                                                   echnk.data,
-                                                   ((char *)echnk.data) + echnk.size,
-                                                   ((char *)data) + ede->offset);
-                           if (type == EET_T_STRING)
-                             {
-                                char **str;
-
-                                str = (char **)(((char *)data) + ede->offset);
-                                if (*str)
-                                  {
-                                      if (ed == NULL
-                                          || edd->func.str_direct_alloc == NULL)
-                                        {
-                                           *str = edd->func.str_alloc(*str);
-                                           _eet_freelist_str_add(*str);
-                                        }
-                                      else
-                                        {
-                                           *str = edd->func.str_direct_alloc(*str);
-                                           _eet_freelist_direct_str_add(*str);
-                                        }
-                                  }
-                             }
-                           else
-                             if (type == EET_T_INLINED_STRING)
-                               {
-                                  char **str;
-
-                                  str = (char **)(((char *)data) + ede->offset);
-                                  if (*str)
-                                    {
-                                       *str = edd->func.str_alloc(*str);
-                                       _eet_freelist_str_add(*str);
-                                    }
-                               }
-                        }
-                      else if (ede->subtype)
-                        {
-                           void **ptr;
-
-                           data_ret = _eet_data_descriptor_decode(ed,
-                                                                   ede->subtype,
-                                                                  echnk.data,
-                                                                  echnk.size,
-                                                                  level + 1,
-                                                                  dumpfunc,
-                                                                  dumpdata);
-                           if (!data_ret) goto error;
-                           ptr = (void **)(((char *)data) + ede->offset);
-                           *ptr = (void *)data_ret;
-                        }
-                   }
-                 else
-                   {
-                      switch (group_type)
-                        {
-                         case EET_G_ARRAY:
-                         case EET_G_VAR_ARRAY:
-                             {
-                                printf("ERROR: EET - ARRAY TYPE NOT IMPLIMENTED YET!!!\n");
-                             }
-                           break;
-                         case EET_G_LIST:
-                             {
-                                void *list = NULL;
-                                void **ptr;
-                                void *data_ret;
-
-                                ptr = (void **)(((char *)data) + ede->offset);
-                                list = *ptr;
-                                data_ret = NULL;
-
-                                assert(!IS_SIMPLE_TYPE(type));
-
-                                if (ede->subtype)
-                                  data_ret = _eet_data_descriptor_decode(ed,
-                                                                          ede->subtype,
-                                                                         echnk.data,
-                                                                         echnk.size,
-                                                                         level + 2,
-                                                                         dumpfunc,
-                                                                         dumpdata);
-                                if (data_ret)
-                                  {
-                                     list = edd->func.list_append(list, data_ret);
-                                     *ptr = list;
-                                     _eet_freelist_list_add(ptr);
-                                  }
-                                else
-                                  goto error;
-                             }
-                           break;
-                         case EET_G_HASH:
-                             {
-                                int ret;
-                                void *hash = NULL;
-                                void **ptr;
-                                char *key = NULL;
-                                void *data_ret = NULL;
-
-                                ptr = (void **)(((char *)data) + ede->offset);
-                                hash = *ptr;
-
-                                /* Read key */
-                                ret = eet_data_get_type(ed,
-                                                         EET_T_STRING,
-                                                        echnk.data,
-                                                        ((char *)echnk.data) + echnk.size,
-                                                        &key);
-                                if (ret <= 0) goto error;
-
-                                /* Advance to next chunk */
-                                 NEXT_CHUNK(p, size, echnk, ed);
-                                memset(&echnk, 0, sizeof(Eet_Data_Chunk));
-
-                                /* Read value */
-                                eet_data_chunk_get(ed, &echnk, p, size);
-                                if (!echnk.name) goto error;
-
-                                assert(!IS_SIMPLE_TYPE(type));
-
-                                if (ede->subtype)
-                                  {
-                                     data_ret = _eet_data_descriptor_decode(ed,
-                                                                             ede->subtype,
-                                                                            echnk.data,
-                                                                            echnk.size,
-                                                                            level + 2,
-                                                                            dumpfunc,
-                                                                            dumpdata);
-                                  }
-                                if (data_ret)
-                                  {
-                                     hash = edd->func.hash_add(hash, key, data_ret);
-                                     *ptr = hash;
-                                     _eet_freelist_list_add(ptr);
-                                  }
-                                else
-                                  {
-                                     goto error;
-                                  }
-                             }
-                           break;
-                         default:
-                           break;
-                        }
-                   }
+                 /* hashes doesnt fit well with the table */
+                 ret = eet_group_codec[group_type - 100].get(ed, edd, ede, &echnk, type, group_type, ((char *)data) + ede->offset, level, dumpfunc, dumpdata, &p, &size);
+                 if (ret <= 0) goto error;
               }
          }
        /*...... dump func */
@@ -2374,16 +2283,55 @@ _eet_data_descriptor_decode(const Eet_Dictionary *ed,
                     case EET_G_ARRAY:
                     case EET_G_VAR_ARRAY:
                         {
-                           printf("ARRAY TYPE NOT IMPLIMENTED YET!!!\n");
+                           void *data_ret = NULL;
+                           int count;
+                           int ret;
+                           int i;
+
+                           EET_ASSERT(!IS_SIMPLE_TYPE(type), goto error);
+
+                           ret = eet_data_get_type(ed,
+                                                   EET_T_INT,
+                                                   echnk.data,
+                                                   ((char *)echnk.data) + echnk.size,
+                                                   &count);
+                           if (ret <= 0) goto error;
+
+                           for (i = 0; i < level; i++) dumpfunc(dumpdata, "  ");
+                           dumpfunc(dumpdata, "    count ");
+                           snprintf(tbuf, sizeof(tbuf), "%i", count);
+                           dumpfunc(dumpdata, tbuf);
+                           dumpfunc(dumpdata, ";\n");
+
+                           /* get all array elements */
+                           for (i = 0; i < count; i++)
+                             {
+                                void *dst;
+                                void *data_ret = NULL;
+
+                                /* Advance to next chunk */
+                                NEXT_CHUNK(p, size, echnk, ed);
+                                memset(&echnk, 0, sizeof(Eet_Data_Chunk));
+
+                                eet_data_chunk_get(ed, &echnk, p, size);
+                                if (!echnk.name) return 0;
+                                /* get the data */
+                                data_ret = _eet_data_descriptor_decode(ed,
+                                                                       NULL,
+                                                                       echnk.data,
+                                                                       echnk.size,
+                                                                       level + 2,
+                                                                       dumpfunc,
+                                                                       dumpdata);
+                                if (!data_ret) goto error;
+                             }
                         }
                       break;
                     case EET_G_LIST:
                         {
-                           void *data_ret;
-
-                           data_ret = NULL;
+                           void *data_ret = NULL;
 
-                           assert(!IS_SIMPLE_TYPE(type));
+                           EET_ASSERT(!IS_SIMPLE_TYPE(type), goto error);
 
                            data_ret = _eet_data_descriptor_decode(ed,
                                                                   NULL,
@@ -2392,8 +2340,7 @@ _eet_data_descriptor_decode(const Eet_Dictionary *ed,
                                                                   level + 2,
                                                                   dumpfunc,
                                                                   dumpdata);
-                           if (!data_ret)
-                             goto error;
+                           if (!data_ret) goto error;
                         }
                       break;
                     case EET_G_HASH:
@@ -2418,7 +2365,7 @@ _eet_data_descriptor_decode(const Eet_Dictionary *ed,
                            eet_data_chunk_get(ed, &echnk, p, size);
                            if (!echnk.name) goto error;
 
-                           assert(!IS_SIMPLE_TYPE(type));
+                           EET_ASSERT(!IS_SIMPLE_TYPE(type), goto error);
 
                            {
                               char *s;
@@ -2511,6 +2458,309 @@ error:
    return NULL;
 }
 
+static int
+eet_data_get_list(const Eet_Dictionary *ed, Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Chunk *echnk,
+                 int type, int group_type, void *data,
+                 int level, void (*dumpfunc) (void *data, const char *str), void *dumpdata,
+                 char **p, int *size)
+{
+   void *list = NULL;
+   void **ptr;
+   void *data_ret;
+   int ret;
+
+   EET_ASSERT(!IS_SIMPLE_TYPE(type), return 0);
+
+   ptr = (void **)data;
+   list = *ptr;
+   data_ret = NULL;
+
+   data_ret = _eet_data_descriptor_decode(ed, ede->subtype, echnk->data, echnk->size, level + 2, dumpfunc, dumpdata);
+   if (!data_ret) return 0;
+
+   list = edd->func.list_append(list, data_ret);
+   *ptr = list;
+   _eet_freelist_list_add(ptr);
+
+   return 1;
+}
+
+static int
+eet_data_get_hash(const Eet_Dictionary *ed, Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Chunk *echnk,
+                 int type, int group_type, void *data,
+                 int level, void (*dumpfunc) (void *data, const char *str), void *dumpdata,
+                 char **p, int *size)
+{
+   void **ptr;
+   void *hash = NULL;
+   char *key = NULL;
+   void *data_ret = NULL;
+   int ret = 0;
+
+   EET_ASSERT(!IS_SIMPLE_TYPE(type), return 0);
+
+   ptr = (void **)data;
+   hash = *ptr;
+
+   /* Read key */
+   ret = eet_data_get_type(ed,
+                          EET_T_STRING,
+                          echnk->data,
+                          ((char *)echnk->data) + echnk->size,
+                          &key);
+   if (ret <= 0) goto on_error;
+
+   /* Advance to next chunk */
+   NEXT_CHUNK((*p), (*size), (*echnk), ed);
+   memset(echnk, 0, sizeof(Eet_Data_Chunk));
+
+   /* Read value */
+   eet_data_chunk_get(ed, echnk, *p, *size);
+   if (!echnk->name) goto on_error;
+
+   data_ret = _eet_data_descriptor_decode(ed,
+                                         ede->subtype,
+                                         echnk->data,
+                                         echnk->size,
+                                         level + 2,
+                                         dumpfunc,
+                                         dumpdata);
+   if (!data_ret) goto on_error;
+
+   hash = edd->func.hash_add(hash, key, data_ret);
+   *ptr = hash;
+   _eet_freelist_list_add(ptr);
+   return 1;
+
+ on_error:
+   return ret;
+}
+
+/* var arrays and fixed arrays have to
+ * get all chunks at once. for fixed arrays
+ * we can get each chunk and increment a
+ * counter stored on the element itself but
+ * it wont be thread safe. for var arrays
+ * we still need a way to get the number of
+ * elements from the data, so storing the
+ * number of elements and the element data on
+ * each chunk is pointless.
+ */
+static int
+eet_data_get_array(const Eet_Dictionary *ed, Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Chunk *echnk,
+                  int type, int group_type, void *data,
+                  int level, void (*dumpfunc) (void *data, const char *str), void *dumpdata,
+                  char **p, int *size)
+{
+   void *ptr;
+   int count;
+   int ret;
+   int i;
+
+   EET_ASSERT(!IS_SIMPLE_TYPE(type), return 0);
+
+   ptr = data;
+   /* read the number of elements */
+   ret = eet_data_get_type(ed,
+                          EET_T_INT,
+                          echnk->data,
+                          ((char *)echnk->data) + echnk->size,
+                          &count);
+   if (ret <= 0) return ret;
+   if (group_type == EET_G_VAR_ARRAY)
+     {
+       /* store the number of elements
+        * on the counter offset */
+       *(int *)(((char *)data) + ede->count - ede->offset) = count;
+       /* allocate space for the array of elements */
+       *(void **)ptr = calloc(count, ede->subtype->size);
+
+       if (!*(void **)ptr) return 0;
+
+       _eet_freelist_add(*(void **)ptr);
+     }
+
+   /* get all array elements */
+   for (i = 0; i < count; i++)
+     {
+       void *dst;
+       void *data_ret = NULL;
+
+       /* Advance to next chunk */
+       NEXT_CHUNK((*p), (*size), (*echnk), ed);
+       memset(echnk, 0, sizeof(Eet_Data_Chunk));
+
+       eet_data_chunk_get(ed, echnk, *p, *size);
+       if (!echnk->name) return 0;
+       /* get the data */
+
+       /* get the destination pointer */
+       if (group_type == EET_G_ARRAY)
+         dst = (char *)ptr + (ede->subtype->size * i);
+       else
+         dst = *(char **)ptr + (ede->subtype->size * i);
+       data_ret = _eet_data_descriptor_decode(ed,
+                                              ede->subtype,
+                                              echnk->data,
+                                              echnk->size,
+                                              level + 2,
+                                              dumpfunc,
+                                              dumpdata);
+       if (!data_ret) return 0;
+       memcpy(dst, data_ret, ede->subtype->size);
+       free(data_ret);
+     }
+   return 1;
+}
+
+static int
+eet_data_get_unknown(const Eet_Dictionary *ed, Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Chunk *echnk,
+                    int type, int group_type, void *data,
+                    int level, void (*dumpfunc) (void *data, const char *str), void *dumpdata,
+                    char **p, int *size)
+{
+   int ret;
+   void *data_ret;
+
+   if (IS_SIMPLE_TYPE(type))
+     {
+       ret = eet_data_get_type(ed, type, echnk->data, ((char *)echnk->data) + echnk->size, ((char *)data));
+       if (ret <= 0) return ret;
+
+       if (type == EET_T_STRING)
+         {
+            char **str, *str2;
+
+            str = (char **)(((char *)data));
+            if (*str)
+              {
+                 if (ed == NULL
+                     || edd->func.str_direct_alloc == NULL)
+                   {
+                      *str = edd->func.str_alloc(*str);
+                      _eet_freelist_str_add(*str);
+                   }
+                 else
+                   {
+                      *str = edd->func.str_direct_alloc(*str);
+                      _eet_freelist_direct_str_add(*str);
+                   }
+              }
+         }
+     }
+   else if (ede->subtype)
+     {
+       void **ptr;
+
+       data_ret = _eet_data_descriptor_decode(ed, ede->subtype, echnk->data, echnk->size, level + 1, dumpfunc, dumpdata);
+       if (!data_ret) return 0;
+
+       ptr = (void **)(((char *)data));
+       *ptr = (void *)data_ret;
+     }
+
+   return 1;
+}
+
+static void
+eet_data_encode(Eet_Dictionary *ed, Eet_Data_Stream *ds, void *data, const char *name, int size, int type, int group_type)
+{
+   Eet_Data_Chunk *echnk;
+
+   echnk = eet_data_chunk_new(data, size, name, type, group_type);
+   eet_data_chunk_put(ed, echnk, ds);
+   eet_data_chunk_free(echnk);
+   free(data);
+}
+
+static void
+eet_data_put_array(Eet_Dictionary *ed, Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Stream *ds, void *data_in)
+{
+   void *data;
+   int size;
+   int j;
+   int offset = 0;
+   int count;
+
+   EET_ASSERT(!IS_SIMPLE_TYPE(ede->type), return );
+
+   if (ede->group_type == EET_G_ARRAY)
+     count = ede->counter_offset;
+   else
+     count = *(int *)(((char *)data_in) + ede->count - ede->offset);
+
+   if (count <= 0) return;
+   /* Store number of elements */
+   data = eet_data_put_type(ed, EET_T_INT, &count, &size);
+   if (data) eet_data_encode(ed, ds, data, ede->name, size, ede->type, ede->group_type);
+
+   for (j = 0; j < count; j++)
+     {
+       void *d;
+
+       if (ede->group_type == EET_G_ARRAY)
+         d = (void *)(((char *)data_in) + offset);
+       else
+         d = *(((char **)data_in)) + offset;
+
+       data = _eet_data_descriptor_encode(ed, ede->subtype, d, &size);
+       offset += ede->subtype->size;
+       if (data) eet_data_encode(ed, ds, data, ede->name, size, ede->type, ede->group_type);
+     }
+}
+
+static void
+eet_data_put_unknown(Eet_Dictionary *ed, Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Stream *ds, void *data_in)
+{
+   int size;
+   void *data;
+
+   if (IS_SIMPLE_TYPE(ede->type))
+     data = eet_data_put_type(ed, ede->type, data_in, &size);
+   else if (ede->subtype)
+     {
+       if (*((char **)(((char *)data_in))))
+         data = _eet_data_descriptor_encode(ed,
+                                            ede->subtype,
+                                            *((char **)((char *)(data_in))),
+                                            &size);
+     }
+   if (data) eet_data_encode(ed, ds, data, ede->name, size, ede->type, ede->group_type);
+}
+
+static void
+eet_data_put_list(Eet_Dictionary *ed, Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Stream *ds, void *data_in)
+{
+   void *data;
+   void *l;
+   int size;
+
+   EET_ASSERT(!IS_SIMPLE_TYPE(ede->type), return );
+
+   l = *((void **)(((char *)data_in)));
+   for (; l; l = edd->func.list_next(l))
+     {
+       data = _eet_data_descriptor_encode(ed,
+                                          ede->subtype,
+                                          edd->func.list_data(l),
+                                          &size);
+       if (data) eet_data_encode(ed, ds, data, ede->name, size, ede->type, ede->group_type);
+     }
+}
+
+static void
+eet_data_put_hash(Eet_Dictionary *ed, Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Stream *ds, void *data_in)
+{
+   Eet_Data_Encode_Hash_Info fdata;
+   void *l;
+
+   l = *((void **)(((char *)data_in)));
+   fdata.ds = ds;
+   fdata.ede = ede;
+   fdata.ed = ed;
+   edd->func.hash_foreach(l, eet_data_descriptor_encode_hash_cb, &fdata);
+}
+
 EAPI int
 eet_data_dump(Eet_File *ef,
              const char *name,
@@ -2624,82 +2874,7 @@ _eet_data_descriptor_encode(Eet_Dictionary *ed,
        int size;
 
        ede = &(edd->elements.set[i]);
-       data = NULL;
-       if (ede->group_type == EET_G_UNKNOWN)
-         {
-            if (IS_SIMPLE_TYPE(ede->type))
-              data = eet_data_put_type(ed,
-                                        ede->type,
-                                       ((char *)data_in) + ede->offset,
-                                       &size);
-            else if (ede->subtype)
-              {
-                 if (*((char **)(((char *)data_in) + ede->offset)))
-                   data = _eet_data_descriptor_encode(ed,
-                                                       ede->subtype,
-                                                       *((char **)(((char *)data_in) + ede->offset)),
-                                                       &size);
-              }
-            if (data)
-              {
-                 echnk = eet_data_chunk_new(data, size, ede->name, ede->type, ede->group_type);
-                 eet_data_chunk_put(ed, echnk, ds);
-                 eet_data_chunk_free(echnk);
-                 free(data);
-                 data = NULL;
-              }
-         }
-       else
-         {
-            switch (ede->group_type)
-              {
-               case EET_G_ARRAY:
-               case EET_G_VAR_ARRAY:
-                   {
-                      printf("ARRAY TYPE NOT IMPLIMENTED YET!!!\n");
-                   }
-                 break;
-               case EET_G_LIST:
-                   {
-                      void *l;
-
-                      l = *((void **)(((char *)data_in) + ede->offset));
-                      for (; l; l = edd->func.list_next(l))
-                        {
-                           assert(!IS_SIMPLE_TYPE(ede->type));
-
-                           if (ede->subtype)
-                             data = _eet_data_descriptor_encode(ed,
-                                                                 ede->subtype,
-                                                                 edd->func.list_data(l),
-                                                                 &size);
-                           if (data)
-                             {
-                                echnk = eet_data_chunk_new(data, size, ede->name, ede->type, ede->group_type);
-                                eet_data_chunk_put(ed, echnk, ds);
-                                eet_data_chunk_free(echnk);
-                                free(data);
-                                data = NULL;
-                             }
-                        }
-                   }
-                 break;
-               case EET_G_HASH:
-                   {
-                      Eet_Data_Encode_Hash_Info fdata;
-                      void *l;
-
-                      l = *((void **)(((char *)data_in) + ede->offset));
-                      fdata.ds = ds;
-                      fdata.ede = ede;
-                       fdata.ed = ed;
-                      edd->func.hash_foreach(l, eet_data_descriptor_encode_hash_cb, &fdata);
-                   }
-                 break;
-               default:
-                 break;
-              }
-         }
+       eet_group_codec[ede->group_type - 100].put(ed, edd, ede, ds, ((char *)data_in) + ede->offset);
      }
    chnk = eet_data_chunk_new(ds->data, ds->pos, edd->name, EET_T_UNKNOW, EET_G_UNKNOWN);
    ds->data = NULL;
index 9026b65..090a82c 100644 (file)
@@ -1,5 +1,6 @@
 #include <stdlib.h>
 #include <string.h>
+#include <strings.h>
 #include <stdio.h>
 
 #include <check.h>
@@ -91,38 +92,56 @@ static const Eet_Test_Image test_alpha = {
   }
 };
 
+static void
+_eet_test_basic_set(Eet_Test_Basic_Type *res, int i)
+{
+   res->c = EET_TEST_CHAR;
+   res->s = EET_TEST_SHORT;
+   res->i = EET_TEST_INT + i;
+   res->l = EET_TEST_LONG_LONG;
+   res->str = EET_TEST_STRING;
+   res->istr = EET_TEST_STRING;
+   res->f1 = - EET_TEST_FLOAT;
+   res->d = - EET_TEST_DOUBLE;
+   res->f2 = EET_TEST_FLOAT4;
+   res->uc = EET_TEST_CHAR;
+   res->us = EET_TEST_SHORT;
+   res->ui = EET_TEST_INT;
+   res->ul = EET_TEST_LONG_LONG;
+}
 
-START_TEST(eet_test_basic_data_type_encoding_decoding)
+static void
+_eet_test_basic_check(Eet_Test_Basic_Type *result, int i)
 {
-   Eet_Data_Descriptor *edd;
-   Eet_Test_Basic_Type *result;
-   Eet_Data_Descriptor_Class eddc;
-   Eet_Test_Basic_Type etbt;
-   void *transfert;
-   int size;
    float tmp;
 
-   etbt.c = EET_TEST_CHAR;
-   etbt.s = EET_TEST_SHORT;
-   etbt.i = EET_TEST_INT;
-   etbt.l = EET_TEST_LONG_LONG;
-   etbt.str = EET_TEST_STRING;
-   etbt.istr = EET_TEST_STRING;
-   etbt.f1 = - EET_TEST_FLOAT;
-   etbt.d = - EET_TEST_DOUBLE;
-   etbt.f2 = EET_TEST_FLOAT4;
-   etbt.uc = EET_TEST_CHAR;
-   etbt.us = EET_TEST_SHORT;
-   etbt.ui = EET_TEST_INT;
-   etbt.ul = EET_TEST_LONG_LONG;
+   fail_if(result->c != EET_TEST_CHAR);
+   fail_if(result->s != EET_TEST_SHORT);
+   fail_if(result->i != EET_TEST_INT + i);
+   fail_if(result->l != EET_TEST_LONG_LONG);
+   fail_if(strcmp(result->str, EET_TEST_STRING) != 0);
+   fail_if(strcmp(result->istr, EET_TEST_STRING) != 0);
+   fail_if(result->uc != EET_TEST_CHAR);
+   fail_if(result->us != EET_TEST_SHORT);
+   fail_if(result->ui != EET_TEST_INT);
+   fail_if(result->ul != EET_TEST_LONG_LONG);
 
-   eet_test_setup_eddc(&eddc);
-   eddc.name = "Eet_Test_Basic_Type";
-   eddc.size = sizeof(Eet_Test_Basic_Type);
+   tmp = (result->f1 + EET_TEST_FLOAT);
+   if (tmp < 0) tmp = -tmp;
+   fail_if(tmp > 0.005);
 
-   edd = eet_data_descriptor2_new(&eddc);
-   fail_if(!edd);
+   tmp = (result->f2 - EET_TEST_FLOAT4);
+   if (tmp < 0) tmp = -tmp;
+   fail_if(tmp > 0.005);
+
+   tmp = (result->d + EET_TEST_DOUBLE);
+   if (tmp < 0) tmp = -tmp;
+   fail_if(tmp > 0.00005);
+}
 
+static void
+_eet_build_basic_descriptor(Eet_Data_Descriptor *edd)
+{
    EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Basic_Type, "c", c, EET_T_CHAR);
    EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Basic_Type, "s", s, EET_T_SHORT);
    EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Basic_Type, "i", i, EET_T_INT);
@@ -136,6 +155,27 @@ START_TEST(eet_test_basic_data_type_encoding_decoding)
    EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Basic_Type, "us", us, EET_T_USHORT);
    EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Basic_Type, "ui", ui, EET_T_UINT);
    EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Basic_Type, "ul", ul, EET_T_ULONG_LONG);
+}
+
+START_TEST(eet_test_basic_data_type_encoding_decoding)
+{
+   Eet_Data_Descriptor *edd;
+   Eet_Test_Basic_Type *result;
+   Eet_Data_Descriptor_Class eddc;
+   Eet_Test_Basic_Type etbt;
+   void *transfert;
+   int size;
+
+   _eet_test_basic_set(&etbt, 0);
+
+   eet_test_setup_eddc(&eddc);
+   eddc.name = "Eet_Test_Basic_Type";
+   eddc.size = sizeof(Eet_Test_Basic_Type);
+
+   edd = eet_data_descriptor2_new(&eddc);
+   fail_if(!edd);
+
+   _eet_build_basic_descriptor(edd);
 
    transfert = eet_data_descriptor_encode(edd, &etbt, &size);
    fail_if(!transfert || size <= 0);
@@ -143,28 +183,7 @@ START_TEST(eet_test_basic_data_type_encoding_decoding)
    result = eet_data_descriptor_decode(edd, transfert, size);
    fail_if(!result);
 
-   fail_if(result->c != EET_TEST_CHAR);
-   fail_if(result->s != EET_TEST_SHORT);
-   fail_if(result->i != EET_TEST_INT);
-   fail_if(result->l != EET_TEST_LONG_LONG);
-   fail_if(strcmp(result->str, EET_TEST_STRING) != 0);
-   fail_if(strcmp(result->istr, EET_TEST_STRING) != 0);
-   fail_if(result->uc != EET_TEST_CHAR);
-   fail_if(result->us != EET_TEST_SHORT);
-   fail_if(result->ui != EET_TEST_INT);
-   fail_if(result->ul != EET_TEST_LONG_LONG);
-
-   tmp = (result->f1 + EET_TEST_FLOAT);
-   if (tmp < 0) tmp = -tmp;
-   fail_if(tmp > 0.005);
-
-   tmp = (result->f2 - EET_TEST_FLOAT4);
-   if (tmp < 0) tmp = -tmp;
-   fail_if(tmp > 0.005);
-
-   tmp = (result->d + EET_TEST_DOUBLE);
-   if (tmp < 0) tmp = -tmp;
-   fail_if(tmp > 0.00005);
+   _eet_test_basic_check(result, 0);
 
    free(result->str);
    free(result);
@@ -194,6 +213,12 @@ struct _Eet_Test_Ex_Type
    Eet_Hash *hash;
    Eet_List *ilist;
    Eet_Hash *ihash;
+   Eet_Test_Basic_Type sarray1[10];
+   unsigned int sarray2[5];
+   unsigned int varray1_count;
+   unsigned int *varray1;
+   unsigned int varray2_count;
+   Eet_Test_Basic_Type *varray2;
    unsigned char uc;
    unsigned short us;
    unsigned int ui;
@@ -203,9 +228,63 @@ struct _Eet_Test_Ex_Type
 static int i42 = 42;
 static int i7 = 7;
 
+
+static void
+_eet_build_ex_descriptor(Eet_Data_Descriptor *edd)
+{
+   Eet_Data_Descriptor_Class eddc;
+   Eet_Test_Ex_Type etbt;
+   Eet_Data_Descriptor *eddb;
+
+   eet_test_setup_eddc(&eddc);
+   eddc.name = "Eet_Test_Basic_Type";
+   eddc.size = sizeof(Eet_Test_Basic_Type);
+   eddb = eet_data_descriptor3_new(&eddc);
+   fail_if(!eddb);
+
+   _eet_build_basic_descriptor(eddb);
+
+   EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Ex_Type, "c", c, EET_T_CHAR);
+   EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Ex_Type, "s", s, EET_T_SHORT);
+   EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Ex_Type, "i", i, EET_T_INT);
+   EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Ex_Type, "l", l, EET_T_LONG_LONG);
+   EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Ex_Type, "str", str, EET_T_STRING);
+   EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Ex_Type, "istr", istr, EET_T_INLINED_STRING);
+   EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Ex_Type, "f1", f1, EET_T_FLOAT);
+   EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Ex_Type, "f2", f2, EET_T_FLOAT);
+   EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Ex_Type, "f3", f3, EET_T_FLOAT);
+   EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Ex_Type, "f4", f4, EET_T_FLOAT);
+   EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Ex_Type, "d1", d1, EET_T_DOUBLE);
+   EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Ex_Type, "d2", d2, EET_T_DOUBLE);
+   EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Ex_Type, "d3", d3, EET_T_DOUBLE);
+   EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Ex_Type, "d4", d4, EET_T_DOUBLE);
+   EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Ex_Type, "uc", uc, EET_T_UCHAR);
+   EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Ex_Type, "us", us, EET_T_USHORT);
+   EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Ex_Type, "ui", ui, EET_T_UINT);
+   EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Ex_Type, "ul", ul, EET_T_ULONG_LONG);
+   EET_DATA_DESCRIPTOR_ADD_ARRAY(edd, Eet_Test_Ex_Type, "sarray1", sarray1, eddb);
+   EET_DATA_DESCRIPTOR_ADD_VAR_ARRAY(edd, Eet_Test_Ex_Type, "varray2", varray2, eddb);
+   eet_data_descriptor_element_add(edd, "varray1", EET_T_INT, EET_G_VAR_ARRAY,
+                                  (char *)(&(etbt.varray1)) - (char *)(&(etbt)),
+                                  (char *)(&(etbt.varray1_count)) - (char *)(&(etbt)), /* 0,  */NULL, NULL);
+   eet_data_descriptor_element_add(edd, "sarray2", EET_T_INT, EET_G_ARRAY,
+                                  (char *)(&(etbt.sarray2)) - (char *)(&(etbt)),
+                                  /* 0,  */sizeof(etbt.sarray2)/sizeof(etbt.sarray2[0]), NULL, NULL);
+   EET_DATA_DESCRIPTOR_ADD_LIST(edd, Eet_Test_Ex_Type, "list", list, edd);
+   EET_DATA_DESCRIPTOR_ADD_HASH(edd, Eet_Test_Ex_Type, "hash", hash, edd);
+   eet_data_descriptor_element_add(edd, "ilist", EET_T_INT, EET_G_LIST,
+                                  (char *)(&(etbt.ilist)) - (char *)(&(etbt)),
+                                  0, /* 0,  */NULL, NULL);
+   eet_data_descriptor_element_add(edd, "ihash", EET_T_INT, EET_G_HASH,
+                                  (char *)(&(etbt.ihash)) - (char *)(&(etbt)),
+                                  0, /* 0,  */NULL, NULL);
+}
+
 static Eet_Test_Ex_Type*
 _eet_test_ex_set(Eet_Test_Ex_Type *res, int offset)
 {
+   int i;
+
    if (!res) res = malloc( sizeof(Eet_Test_Ex_Type));
    if (!res) return NULL;
 
@@ -227,6 +306,23 @@ _eet_test_ex_set(Eet_Test_Ex_Type *res, int offset)
    res->hash = NULL;
    res->ilist = NULL;
    res->ihash = NULL;
+
+   res->varray2 = malloc(sizeof (Eet_Test_Basic_Type) * 10);
+   res->varray1 = malloc(sizeof (int) * 5);
+   fail_if(!res->varray1 || !res->varray2);
+   for (i = 0; i < 10; ++i)
+     {
+       _eet_test_basic_set(res->sarray1 + i, i);
+       _eet_test_basic_set(res->varray2 + i, i);
+     }
+   res->varray2_count = 10;
+   for (i = 0; i < 5; ++i)
+     {
+       res->sarray2[i] = i * 42 + 1;
+       res->varray1[i] = i * 42 + 1;
+     }
+   res->varray1_count = 5;
+
    res->uc = EET_TEST_CHAR + offset;
    res->us = EET_TEST_SHORT + offset;
    res->ui = EET_TEST_INT + offset;
@@ -239,6 +335,7 @@ static int
 _eet_test_ex_check(Eet_Test_Ex_Type *stuff, int offset)
 {
    double tmp;
+   int i;
 
    if (!stuff) return 1;
 
@@ -271,6 +368,13 @@ _eet_test_ex_check(Eet_Test_Ex_Type *stuff, int offset)
    if (stuff->ui != EET_TEST_INT + offset) return 1;
    if (stuff->ul != EET_TEST_LONG_LONG + offset) return 1;
 
+   for (i = 0; i < 5; ++i)
+     if (stuff->sarray2[i] != i * 42 + 1)
+       return 1;
+
+   for (i = 0; i < 10; ++i)
+     _eet_test_basic_check(stuff->sarray1 + i, i);
+
    return 0;
 }
 
@@ -323,32 +427,7 @@ START_TEST(eet_test_data_type_encoding_decoding)
    edd = eet_data_descriptor3_new(&eddc);
    fail_if(!edd);
 
-   EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Ex_Type, "c", c, EET_T_CHAR);
-   EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Ex_Type, "s", s, EET_T_SHORT);
-   EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Ex_Type, "i", i, EET_T_INT);
-   EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Ex_Type, "l", l, EET_T_LONG_LONG);
-   EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Ex_Type, "str", str, EET_T_STRING);
-   EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Ex_Type, "istr", istr, EET_T_INLINED_STRING);
-   EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Ex_Type, "f1", f1, EET_T_FLOAT);
-   EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Ex_Type, "f2", f2, EET_T_FLOAT);
-   EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Ex_Type, "f3", f3, EET_T_FLOAT);
-   EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Ex_Type, "f4", f4, EET_T_FLOAT);
-   EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Ex_Type, "d1", d1, EET_T_DOUBLE);
-   EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Ex_Type, "d2", d2, EET_T_DOUBLE);
-   EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Ex_Type, "d3", d3, EET_T_DOUBLE);
-   EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Ex_Type, "d4", d4, EET_T_DOUBLE);
-   EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Ex_Type, "uc", uc, EET_T_UCHAR);
-   EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Ex_Type, "us", us, EET_T_USHORT);
-   EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Ex_Type, "ui", ui, EET_T_UINT);
-   EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Ex_Type, "ul", ul, EET_T_ULONG_LONG);
-   EET_DATA_DESCRIPTOR_ADD_LIST(edd, Eet_Test_Ex_Type, "list", list, edd);
-   EET_DATA_DESCRIPTOR_ADD_HASH(edd, Eet_Test_Ex_Type, "hash", hash, edd);
-   eet_data_descriptor_element_add(edd, "ilist", EET_T_INT, EET_G_LIST,
-                                  (char *)(&(etbt.ilist)) - (char *)(&(etbt)),
-                                  0, NULL, NULL);
-   eet_data_descriptor_element_add(edd, "ihash", EET_T_INT, EET_G_HASH,
-                                  (char *)(&(etbt.ihash)) - (char *)(&(etbt)),
-                                  0, NULL, NULL);
+   _eet_build_ex_descriptor(edd);
 
    transfert = eet_data_descriptor_encode(edd, &etbt, &size);
    fail_if(!transfert || size <= 0);
@@ -417,32 +496,7 @@ START_TEST(eet_test_data_type_dump_undump)
    edd = eet_data_descriptor3_new(&eddc);
    fail_if(!edd);
 
-   EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Ex_Type, "c", c, EET_T_CHAR);
-   EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Ex_Type, "s", s, EET_T_SHORT);
-   EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Ex_Type, "i", i, EET_T_INT);
-   EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Ex_Type, "l", l, EET_T_LONG_LONG);
-   EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Ex_Type, "str", str, EET_T_STRING);
-   EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Ex_Type, "istr", istr, EET_T_INLINED_STRING);
-   EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Ex_Type, "f1", f1, EET_T_FLOAT);
-   EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Ex_Type, "f2", f2, EET_T_FLOAT);
-   EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Ex_Type, "f3", f3, EET_T_FLOAT);
-   EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Ex_Type, "f4", f4, EET_T_FLOAT);
-   EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Ex_Type, "d1", d1, EET_T_DOUBLE);
-   EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Ex_Type, "d2", d2, EET_T_DOUBLE);
-   EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Ex_Type, "d3", d3, EET_T_DOUBLE);
-   EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Ex_Type, "d4", d4, EET_T_DOUBLE);
-   EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Ex_Type, "uc", uc, EET_T_UCHAR);
-   EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Ex_Type, "us", us, EET_T_USHORT);
-   EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Ex_Type, "ui", ui, EET_T_UINT);
-   EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Ex_Type, "ul", ul, EET_T_ULONG_LONG);
-   EET_DATA_DESCRIPTOR_ADD_LIST(edd, Eet_Test_Ex_Type, "list", list, edd);
-   EET_DATA_DESCRIPTOR_ADD_HASH(edd, Eet_Test_Ex_Type, "hash", hash, edd);
-   eet_data_descriptor_element_add(edd, "ilist", EET_T_INT, EET_G_LIST,
-                                  (char *)(&(etbt.ilist)) - (char *)(&(etbt)),
-                                  0, NULL, NULL);
-   eet_data_descriptor_element_add(edd, "ihash", EET_T_INT, EET_G_HASH,
-                                  (char *)(&(etbt.ihash)) - (char *)(&(etbt)),
-                                  0, NULL, NULL);
+   _eet_build_ex_descriptor(edd);
 
    transfert1 = eet_data_descriptor_encode(edd, &etbt, &size1);
    fail_if(!transfert1 || size1 <= 0);
@@ -572,32 +626,7 @@ START_TEST(eet_file_data_test)
    edd = eet_data_descriptor3_new(&eddc);
    fail_if(!edd);
 
-   EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Ex_Type, "c", c, EET_T_CHAR);
-   EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Ex_Type, "s", s, EET_T_SHORT);
-   EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Ex_Type, "i", i, EET_T_INT);
-   EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Ex_Type, "l", l, EET_T_LONG_LONG);
-   EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Ex_Type, "str", str, EET_T_STRING);
-   EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Ex_Type, "istr", istr, EET_T_INLINED_STRING);
-   EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Ex_Type, "f1", f1, EET_T_FLOAT);
-   EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Ex_Type, "f2", f2, EET_T_FLOAT);
-   EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Ex_Type, "f3", f3, EET_T_FLOAT);
-   EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Ex_Type, "f4", f4, EET_T_FLOAT);
-   EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Ex_Type, "d1", d1, EET_T_DOUBLE);
-   EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Ex_Type, "d2", d2, EET_T_DOUBLE);
-   EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Ex_Type, "d3", d3, EET_T_DOUBLE);
-   EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Ex_Type, "d4", d4, EET_T_DOUBLE);
-   EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Ex_Type, "uc", uc, EET_T_UCHAR);
-   EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Ex_Type, "us", us, EET_T_USHORT);
-   EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Ex_Type, "ui", ui, EET_T_UINT);
-   EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Ex_Type, "ul", ul, EET_T_ULONG_LONG);
-   EET_DATA_DESCRIPTOR_ADD_LIST(edd, Eet_Test_Ex_Type, "list", list, edd);
-   EET_DATA_DESCRIPTOR_ADD_HASH(edd, Eet_Test_Ex_Type, "hash", hash, edd);
-   eet_data_descriptor_element_add(edd, "ilist", EET_T_INT, EET_G_LIST,
-                                  (char *)(&(etbt.ilist)) - (char *)(&(etbt)),
-                                  0, NULL, NULL);
-   eet_data_descriptor_element_add(edd, "ihash", EET_T_INT, EET_G_HASH,
-                                  (char *)(&(etbt.ihash)) - (char *)(&(etbt)),
-                                  0, NULL, NULL);
+   _eet_build_ex_descriptor(edd);
 
    mktemp(file);
 
@@ -608,7 +637,7 @@ START_TEST(eet_file_data_test)
    ef = eet_open(file, EET_FILE_MODE_READ_WRITE);
    fail_if(!ef);
 
-   fail_if(!eet_data_write(ef, edd, EET_TEST_FILE_KEY1, &etbt, 1));
+   fail_if(!eet_data_write(ef, edd, EET_TEST_FILE_KEY1, &etbt, 0));
 
    result = eet_data_read(ef, edd, EET_TEST_FILE_KEY1);
    fail_if(!result);
@@ -729,32 +758,7 @@ START_TEST(eet_file_data_dump_test)
    edd = eet_data_descriptor3_new(&eddc);
    fail_if(!edd);
 
-   EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Ex_Type, "c", c, EET_T_CHAR);
-   EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Ex_Type, "s", s, EET_T_SHORT);
-   EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Ex_Type, "i", i, EET_T_INT);
-   EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Ex_Type, "l", l, EET_T_LONG_LONG);
-   EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Ex_Type, "str", str, EET_T_STRING);
-   EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Ex_Type, "istr", istr, EET_T_INLINED_STRING);
-   EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Ex_Type, "f1", f1, EET_T_FLOAT);
-   EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Ex_Type, "f2", f2, EET_T_FLOAT);
-   EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Ex_Type, "f3", f3, EET_T_FLOAT);
-   EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Ex_Type, "f4", f4, EET_T_FLOAT);
-   EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Ex_Type, "d1", d1, EET_T_DOUBLE);
-   EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Ex_Type, "d2", d2, EET_T_DOUBLE);
-   EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Ex_Type, "d3", d3, EET_T_DOUBLE);
-   EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Ex_Type, "d4", d4, EET_T_DOUBLE);
-   EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Ex_Type, "uc", uc, EET_T_UCHAR);
-   EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Ex_Type, "us", us, EET_T_USHORT);
-   EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Ex_Type, "ui", ui, EET_T_UINT);
-   EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Eet_Test_Ex_Type, "ul", ul, EET_T_ULONG_LONG);
-   EET_DATA_DESCRIPTOR_ADD_LIST(edd, Eet_Test_Ex_Type, "list", list, edd);
-   EET_DATA_DESCRIPTOR_ADD_HASH(edd, Eet_Test_Ex_Type, "hash", hash, edd);
-   eet_data_descriptor_element_add(edd, "ilist", EET_T_INT, EET_G_LIST,
-                                  (char *)(&(etbt.ilist)) - (char *)(&(etbt)),
-                                  0, NULL, NULL);
-   eet_data_descriptor_element_add(edd, "ihash", EET_T_INT, EET_G_HASH,
-                                  (char *)(&(etbt.ihash)) - (char *)(&(etbt)),
-                                  0, NULL, NULL);
+   _eet_build_ex_descriptor(edd);
 
    mktemp(file);