? .tm_project2.cache
? TODO.tasks
Index: src/lib/Eet.h
===================================================================
RCS file: /cvs/e/e17/libs/eet/src/lib/Eet.h,v
retrieving revision 1.38
diff -u -r1.38 Eet.h
--- src/lib/Eet.h	20 Jan 2007 15:20:23 -0000	1.38
+++ src/lib/Eet.h	8 Mar 2007 19:52:26 -0000
@@ -733,7 +733,7 @@
     * thus is not documented.
     *
     */
-   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.
@@ -853,7 +853,7 @@
 	\
 	eet_data_descriptor_element_add(edd, name, type, EET_G_UNKNOWN, \
 					(char *)(&(___ett.member)) - (char *)(&(___ett)), \
-					0, NULL, NULL); \
+					0, 0, NULL, NULL); \
      }
 
    /**
@@ -877,7 +877,7 @@
 	\
 	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); \
      }
 
    /**
@@ -900,7 +900,7 @@
 	\
 	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); \
      }
 
    /**
@@ -923,7 +923,33 @@
 	\
 	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); \
+     }
+
+/**
+ *
+ *
+ */
+#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); \
+     }
+
+/**
+ *
+ *
+ */
+#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: src/lib/eet_data.c
===================================================================
RCS file: /cvs/e/e17/libs/eet/src/lib/eet_data.c,v
retrieving revision 1.46
diff -u -r1.46 eet_data.c
--- src/lib/eet_data.c	28 Dec 2006 15:23:47 -0000	1.46
+++ src/lib/eet_data.c	8 Mar 2007 19:52:26 -0000
@@ -1,3 +1,6 @@
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
 #include "Eet.h"
 #include "Eet_private.h"
 
@@ -42,21 +45,31 @@
 /*---*/
 
 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;
 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;
    int   (*get) (void *src, void *src_end, void *dest);
    void *(*put) (const void *src, int *size_ret);
 };
 
+struct _Eet_Data_Group_Type_Codec
+{
+   int  (*get) (Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Chunk *echnk, void *data_in);
+   void (*put) (Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Stream *ds, void *data_in);
+};
+
 struct _Eet_Data_Chunk
 {
    char *name;
@@ -109,11 +122,12 @@
 struct _Eet_Data_Element
 {
    const char          *name;
-   int                  type;
-   int                  group_type;
-   int                  offset;
-   int                  count;
-   const char          *counter_name;
+   int                  type; 		/* EET_T_XXX */
+   int                  group_type; 	/* EET_G_XXX */
+   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 */
+   const char          *counter_name; 	/* what is it needed for ? */
    Eet_Data_Descriptor *subtype;
 };
 
@@ -143,6 +157,14 @@
 static int   eet_data_get_type(int type, void *src, void *src_end, void *dest);
 static void *eet_data_put_type(int type, const void *src, int *size_ret);
 
+static int  eet_data_get_unknown(Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Chunk *echnk, void *data_in);
+static void eet_data_put_unknown(Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Stream *ds, void *data_in);
+static void eet_data_put_array(Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Stream *ds, void *data_in);
+static int  eet_data_get_list(Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Chunk *echnk, void *data_in);
+static void eet_data_put_list(Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Stream *ds, void *data_in);
+static void eet_data_put_hash(Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Stream *ds, void *data_in);
+
+
 static void            eet_data_chunk_get(Eet_Data_Chunk *chnk, const void *src, int size);
 static Eet_Data_Chunk *eet_data_chunk_new(void *data, int size, const char *name);
 static void            eet_data_chunk_free(Eet_Data_Chunk *chnk);
@@ -157,7 +179,7 @@
 
 /*---*/
 
-const Eet_Data_Basic_Type_Decoder eet_coder[] =
+const Eet_Data_Basic_Type_Codec eet_basic_codec[] =
 {
      {sizeof(char),      eet_data_get_char,      eet_data_put_char     },
      {sizeof(short),     eet_data_get_short,     eet_data_put_short    },
@@ -172,6 +194,16 @@
      {sizeof(char *),    eet_data_get_string,    eet_data_put_string   }
 };
 
+
+const Eet_Data_Group_Type_Codec eet_group_codec[] = 
+{
+	{eet_data_get_unknown,  eet_data_put_unknown },
+	{NULL,                  eet_data_put_array   },
+	{NULL,                  eet_data_put_array   },
+	{eet_data_get_list,     eet_data_put_list    },
+	{NULL,                  eet_data_put_hash    }
+};
+
 static int words_bigendian = -1;
 
 /*---*/
@@ -451,7 +483,7 @@
 {
    int ret;
 
-   ret = eet_coder[type - 1].get(src, src_end, dest);
+   ret = eet_basic_codec[type - 1].get(src, src_end, dest);
    return ret;
 }
 
@@ -460,7 +492,7 @@
 {
    void *ret;
 
-   ret = eet_coder[type - 1].put(src, size_ret);
+   ret = eet_basic_codec[type - 1].put(src, size_ret);
    return ret;
 }
 
@@ -468,7 +500,7 @@
  *
  * char[4] = "CHnK";
  * 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 ...
@@ -768,12 +800,27 @@
    free(edd);
 }
 
+/**
+ * @edd:
+ * @name:
+ * @type:
+ * @group_type:
+ * @offset: the offset of this element from the start of the descriptor
+ * @counter_offset: in case of a variable array we need the offset of 
+ * the parameter which will store the number of elements
+ * @count: in case of a fixed array we need its size
+ * @counter_name
+ */
+
 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 counter_offset, /* API breakage */
+				int count, 
+				const char *counter_name,
 				Eet_Data_Descriptor *subtype)
 {
    Eet_Data_Element *ede;
@@ -818,6 +865,7 @@
    ede->group_type = group_type;
    ede->offset = offset;
    ede->count = count;
+   ede->counter_offset = counter_offset;
 /*	
    if (counter_name)
      {
@@ -1115,160 +1163,154 @@
 	ede = _eet_descriptor_hash_find(edd, echnk.name);
 	if (ede)
 	  {
-	     if (ede->group_type == EET_G_UNKNOWN)
-	       {
-		  int ret;
-		  void *data_ret;
-		  
-		  if ((ede->type >= EET_T_CHAR) &&
-		      (ede->type <= EET_T_STRING))
-		    {
-		       ret = eet_data_get_type(ede->type,
-					       echnk.data,
-					       ((char *)echnk.data) + echnk.size,
-					       ((char *)data) + ede->offset);
-		       if (ede->type == EET_T_STRING)
-			 {
-			    char **str, *str2;
-			    
-			    str = (char **)(((char *)data) + ede->offset);
-			    if (*str)
-			      {
-				 str2 = edd->func.str_alloc(*str);
-				 free(*str);
-				 *str = str2;
-				 _eet_freelist_str_add(str2);
-			      }
-			 }
-		    }
-		  else if (ede->subtype)
-		    {
-		       void **ptr;
-		       
-		       data_ret = eet_data_descriptor_decode(ede->subtype,
-							     echnk.data,
-							     echnk.size);
-		       if (!data_ret) goto error;
-		       ptr = (void **)(((char *)data) + ede->offset);
-		       *ptr = (void *)data_ret;
-		    }
-	       }
-	     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:
-			 {
-			    int ret;
-			    void *list = NULL;
-			    void **ptr;
-			    void *data_ret;
-			    
-			    ptr = (void **)(((char *)data) + ede->offset);
-			    list = *ptr;
-			    data_ret = NULL;
-			    if ((ede->type >= EET_T_CHAR) &&
+		int ret = 0;
+		/* 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.
+		 */
+		if (ede->group_type == EET_G_VAR_ARRAY || 
+			ede->group_type == EET_G_ARRAY)
+		{
+			void *ptr;
+			int count, i;
+			
+			ptr = (((char *)data) + ede->offset);
+			/* read the number of elements */
+			ret = eet_data_get_type(EET_T_INT,
+				echnk.data, 
+				((char *)echnk.data) + echnk.size,
+				&count);
+
+			if (ret <= 0) goto error;
+			if (ede->group_type == EET_G_VAR_ARRAY)
+			{
+				/* store the number of elements
+				 * on the counter offset */
+				*(int *)(((char *)data) + ede->counter_offset) = count;
+				/* allocate space for the array of elements */
+				if ((ede->type >= EET_T_CHAR) && 
 				(ede->type <= EET_T_STRING))
-			      {
-				 data_ret = calloc(1, eet_coder[ede->type].size);
-				 if (data_ret)
-				   {
-				      _eet_freelist_add(data_ret);
-				      ret = eet_data_get_type(ede->type,
-							      echnk.data,
-							      ((char *)echnk.data) + echnk.size,
-							      data_ret);
-				      if (ret <= 0) goto error;
-				   }
-				 else
-				   goto error;
-			      }
-			    else if (ede->subtype)
-			      {
-				 data_ret = eet_data_descriptor_decode(ede->subtype,
-								       echnk.data,
-								       echnk.size);
-			      }
-			    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;
+			 		*(void **)ptr = calloc(count, eet_basic_codec[ede->type].size);
+				else if (ede->subtype)
+			 		*(void **)ptr = calloc(count, ede->subtype->size);
+
+				if (*(void **)ptr)
+					_eet_freelist_add(*(void **)ptr);
+				else
+					goto error;
+
+			}
+			/* get all array elements */
+			for (i = 0; i < count; i++)
+			{
+				void *dst;
+				void *data_ret = NULL;
+
+		    		/* Advance to next chunk */
+				p += (4 + 4 + strlen(echnk.name) + 1 + echnk.size);
+				size -= (4 + 4 + strlen(echnk.name) + 1 + echnk.size);
+				free(echnk.name);
+				memset(&echnk, 0, sizeof(Eet_Data_Chunk));
+		    		eet_data_chunk_get(&echnk, p, size);
+				if (!echnk.name) goto error;
+
 
-			    /* Read key */
-			    ret = eet_data_get_type(EET_T_STRING,
-						    echnk.data,
-						    ((char *)echnk.data) + echnk.size,
-						    &key);
-			    if (ret <= 0) goto error;
-
-			    /* Advance to next chunk */
-			    p += (4 + 4 + strlen(echnk.name) + 1 + echnk.size);
-			    size -= (4 + 4 + strlen(echnk.name) + 1 + echnk.size);
-			    free(echnk.name);
-			    memset(&echnk, 0, sizeof(Eet_Data_Chunk));
-
-			    /* Read value */
-			    eet_data_chunk_get(&echnk, p, size);
-			    if (!echnk.name) goto error;
-			    if ((ede->type >= EET_T_CHAR) &&
+				/* get the data */
+				if ((ede->type >= EET_T_CHAR) && 
 				(ede->type <= EET_T_STRING))
-			      {
-				 data_ret = calloc(1, eet_coder[ede->type].size);
-				 if (data_ret)
-				   {
-				      _eet_freelist_add(data_ret);
-				      ret = eet_data_get_type(ede->type,
-							      echnk.data,
-							      ((char *)echnk.data) + echnk.size,
-							      data_ret);
-				      if (ret <= 0) goto error;
-				   }
-				 else
-				   goto error;
-			      }
-			    else if (ede->subtype)
-			      {
-				 data_ret = eet_data_descriptor_decode(ede->subtype,
-								       echnk.data,
-								       echnk.size);
-			      }
-			    if (data_ret)
-			      {
-				 hash = edd->func.hash_add(hash, key, data_ret);
-				 *ptr = hash;
-				 free(key);
-				 _eet_freelist_list_add(ptr);
-			      }
-			    else
-			      goto error;
-			 }
-		       break;
-		     default:
-		       break;
-		    }
-	       }
+				{
+					/* get the destination pointer */
+					if (ede->group_type == EET_G_ARRAY)
+						dst = (char *)ptr + (eet_basic_codec[ede->type - 1].size * i);
+					else
+						dst = *(void **)ptr + (eet_basic_codec[ede->type - 1].size * i);
+					ret = eet_data_get_type(ede->type, 
+					echnk.data, 
+					((char *)echnk.data) + echnk.size, dst);
+					if (ret <= 0) goto error;
+				}
+				else if (ede->subtype)
+				{
+					/* get the destination pointer */
+					if (ede->group_type == EET_G_ARRAY)
+						dst = (char *)ptr + (ede->subtype->size * i);
+					else
+						dst = *(void **)ptr + (ede->subtype->size * i);
+					data_ret = eet_data_descriptor_decode(ede->subtype, echnk.data, echnk.size);
+					if (!data_ret) goto error;
+					memcpy(dst, data_ret, ede->subtype->size);
+					free(data_ret);
+				}
+			}
+		}
+		/* hashes doesnt fit well with the table */
+		else if (ede->group_type == EET_G_HASH)
+		{
+		    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(EET_T_STRING,
+					    echnk.data,
+					    ((char *)echnk.data) + echnk.size,
+					    &key);
+		    if (ret <= 0) goto error;
+
+		    /* Advance to next chunk */
+		    p += (4 + 4 + strlen(echnk.name) + 1 + echnk.size);
+		    size -= (4 + 4 + strlen(echnk.name) + 1 + echnk.size);
+		    free(echnk.name);
+		    memset(&echnk, 0, sizeof(Eet_Data_Chunk));
+
+		    /* Read value */
+		    eet_data_chunk_get(&echnk, p, size);
+		    if (!echnk.name) goto error;
+		    if ((ede->type >= EET_T_CHAR) &&
+			(ede->type <= EET_T_STRING))
+		      {
+			 data_ret = calloc(1, eet_basic_codec[ede->type].size);
+			 if (data_ret)
+			   {
+			      _eet_freelist_add(data_ret);
+			      ret = eet_data_get_type(ede->type,
+						      echnk.data,
+						      ((char *)echnk.data) + echnk.size,
+						      data_ret);
+			      if (ret <= 0) goto error;
+			   }
+			 else
+			   goto error;
+		      }
+		    else if (ede->subtype)
+		      {
+			 data_ret = eet_data_descriptor_decode(ede->subtype,
+							       echnk.data,
+							       echnk.size);
+		      }
+		    if (data_ret)
+		      {
+			 hash = edd->func.hash_add(hash, key, data_ret);
+			 *ptr = hash;
+			 free(key);
+			 _eet_freelist_list_add(ptr);
+		      }
+		    else
+		      goto error;
+		}
+		else
+		ret = eet_group_codec[ede->group_type - 100].get(edd, ede, &echnk, ((char *)data) + ede->offset);
+		if (ret <= 0) goto error;
 	  }
 	/* advance to next chunk */
 	p += (4 + 4 + strlen(echnk.name) + 1 + echnk.size);
@@ -1295,6 +1337,192 @@
    return NULL;
 }
 
+static int 
+eet_data_get_list(Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Chunk *echnk, void *data)
+{
+	int ret;
+	void *list = NULL;
+	void **ptr;
+	void *data_ret;
+			    
+	
+	ptr = (void **)(((char *)data));
+	list = *ptr;
+	data_ret = NULL;
+	
+	if ((ede->type >= EET_T_CHAR) && (ede->type <= EET_T_STRING))
+	{
+		
+		data_ret = calloc(1, eet_basic_codec[ede->type].size);
+		
+		if (data_ret)
+		{
+			_eet_freelist_add(data_ret);
+			ret = eet_data_get_type(ede->type, echnk->data, ((char *)echnk->data) + echnk->size, data_ret);
+			if (ret <= 0) return ret;
+		}
+		else
+			return 0;
+	}
+	else if (ede->subtype)
+	{
+		data_ret = eet_data_descriptor_decode(ede->subtype, echnk->data, echnk->size);
+	}
+	if (data_ret)
+	{
+		list = edd->func.list_append(list, data_ret);
+		*ptr = list;
+		_eet_freelist_list_add(ptr);
+	}
+	else
+		return 0;
+	return 1;
+}
+
+static int 
+eet_data_get_unknown(Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Chunk *echnk, void *data)
+{
+	int ret;
+	void *data_ret;
+		  
+	
+	if ((ede->type >= EET_T_CHAR) && (ede->type <= EET_T_STRING))
+	{
+		ret = eet_data_get_type(ede->type, echnk->data, ((char *)echnk->data) + echnk->size, ((char *)data));
+		
+		if (ret <= 0) return ret;
+
+		if (ede->type == EET_T_STRING)
+		{
+			char **str, *str2;
+			
+			str = (char **)(((char *)data));
+			if (*str)
+			{
+				str2 = edd->func.str_alloc(*str);
+				free(*str);
+				*str = str2;
+				_eet_freelist_str_add(str2);
+			}
+		}
+	}
+	else if (ede->subtype)
+	{
+		void **ptr;
+	
+		data_ret = eet_data_descriptor_decode(ede->subtype, echnk->data, echnk->size);
+		if (!data_ret) return 0;
+	
+		ptr = (void **)(((char *)data));
+		*ptr = (void *)data_ret;
+	}
+	return 1;
+}
+
+
+static void eet_data_encode(Eet_Data_Stream *ds, void *data, const char *name, int size)
+{
+	Eet_Data_Chunk *echnk;
+	
+	echnk = eet_data_chunk_new(data, size, name);
+	eet_data_chunk_put(echnk, ds);
+	eet_data_chunk_free(echnk);
+	free(data);
+}
+
+
+static void eet_data_put_array(Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Stream *ds, void *data_in)
+{
+	int size;
+	void *data;
+	
+	int j;
+	int offset = 0;
+
+	int count;
+
+	if (ede->group_type == EET_G_ARRAY)
+		count = ede->count;
+	else
+		count = *(int *)(((char *)data_in) + ede->counter_offset - ede->offset);
+	
+	if (count <= 0) return;
+	/* Store number of elements */
+	data = eet_data_put_type(EET_T_INT, &count, &size);
+	if (data) eet_data_encode(ds, data, ede->name, size);
+
+	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;
+		}
+		if ((ede->type >= EET_T_CHAR) && (ede->type <= EET_T_STRING))
+		{
+			data = eet_data_put_type(ede->type, d, &size);
+			offset += eet_basic_codec[ede->type - 1].size;
+		}
+		else if (ede->subtype)
+		{
+			data = eet_data_descriptor_encode(ede->subtype, d, &size);
+			offset += ede->subtype->size;
+		}
+		if (data) eet_data_encode(ds, data, ede->name, size);
+	}
+}
+
+static void eet_data_put_unknown(Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Stream *ds, void *data_in)
+{
+	int size;
+	void *data;
+
+	if ((ede->type >= EET_T_CHAR) && (ede->type <= EET_T_STRING))
+		data = eet_data_put_type(ede->type, data_in, &size);
+	else if (ede->subtype)
+	{
+		if (*((char **)(((char *)data_in))))
+			data = eet_data_descriptor_encode(ede->subtype,
+				*((char **)((char *)(data_in))), &size);
+	}
+	if (data) eet_data_encode(ds, data, ede->name, size);
+}
+
+static void eet_data_put_list(Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Stream *ds, void *data_in)
+{
+	int size;
+	void *data;
+	
+	void *l;
+
+	l = *((void **)(((char *)data_in)));
+	for (; l; l = edd->func.list_next(l))
+	{
+		if ((ede->type >= EET_T_CHAR) && (ede->type <= EET_T_STRING))
+			data = eet_data_put_type(ede->type,
+						       edd->func.list_data(l),
+						       &size);
+		else if (ede->subtype)
+			data = eet_data_descriptor_encode(ede->subtype,
+								edd->func.list_data(l),
+								&size);
+		if (data) eet_data_encode(ds, data, ede->name, size);
+	}
+}
+
+static void eet_data_put_hash(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;
+	edd->func.hash_foreach(l, eet_data_descriptor_encode_hash_cb, &fdata);
+}
+
 EAPI void *
 eet_data_descriptor_encode(Eet_Data_Descriptor *edd,
 			   const void *data_in,
@@ -1319,87 +1547,9 @@
    for (i = 0; i < edd->elements.num; i++)
      {
 	Eet_Data_Element *ede;
-	Eet_Data_Chunk *echnk;
-	void *data;
-	int size;
 
 	ede = &(edd->elements.set[i]);
-	data = NULL;
-	if (ede->group_type == EET_G_UNKNOWN)
-	  {
-	     if ((ede->type >= EET_T_CHAR) &&
-		 (ede->type <= EET_T_STRING))
-	       data = eet_data_put_type(ede->type,
-					((char *)data_in) + ede->offset,
-					&size);
-	     else if (ede->subtype)
-	       {
-		  if (*((char **)(((char *)data_in) + ede->offset)))
-		    data = eet_data_descriptor_encode(ede->subtype,
-						      *((char **)(((char *)data_in) + ede->offset)),
-						      &size);
-	       }
-	     if (data)
-	       {
-		  echnk = eet_data_chunk_new(data, size, ede->name);
-		  eet_data_chunk_put(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))
-			 {
-			    if ((ede->type >= EET_T_CHAR) &&
-				(ede->type <= EET_T_STRING))
-			      data = eet_data_put_type(ede->type,
-						       edd->func.list_data(l),
-						       &size);
-			    else if (ede->subtype)
-			      data = eet_data_descriptor_encode(ede->subtype,
-								edd->func.list_data(l),
-								&size);
-			    if (data)
-			      {
-				 echnk = eet_data_chunk_new(data, size, ede->name);
-				 eet_data_chunk_put(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;
-		       edd->func.hash_foreach(l, eet_data_descriptor_encode_hash_cb, &fdata);
-		    }
-		  break;
-		default:
-		  break;
-	       }
-	  }
+	eet_group_codec[ede->group_type - 100].put(edd,ede,ds, ((char *)data_in) + ede->offset);
      }
    chnk = eet_data_chunk_new(ds->data, ds->pos, edd->name);
    ds->data = NULL;
