Enlightenment CVS committal Author : cedric Project : e17 Module : libs/eet
Dir : e17/libs/eet/src/lib Modified Files: Eet.h Eet_private.h eet_data.c Log Message: This patch is a starting point for cleaning up eet_data.c. It also add EET_G_VAR_ARRAY and EET_G_ARRAY thanks to turran's ([EMAIL PROTECTED]) 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. =================================================================== RCS file: /cvs/e/e17/libs/eet/src/lib/Eet.h,v retrieving revision 1.55 retrieving revision 1.56 diff -u -3 -r1.55 -r1.56 --- Eet.h 2 Jun 2008 16:01:18 -0000 1.55 +++ Eet.h 26 Jun 2008 15:47:25 -0000 1.56 @@ -889,7 +889,7 @@ * * @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_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_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_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_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); \ } /***************************************************************************/ =================================================================== RCS file: /cvs/e/e17/libs/eet/src/lib/Eet_private.h,v retrieving revision 1.25 retrieving revision 1.26 diff -u -3 -r1.25 -r1.26 --- Eet_private.h 19 May 2008 15:27:04 -0000 1.25 +++ Eet_private.h 26 Jun 2008 15:47:25 -0000 1.26 @@ -74,4 +74,10 @@ #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 =================================================================== RCS file: /cvs/e/e17/libs/eet/src/lib/eet_data.c,v retrieving revision 1.83 retrieving revision 1.84 diff -u -3 -r1.83 -r1.84 --- eet_data.c 19 May 2008 16:01:50 -0000 1.83 +++ eet_data.c 26 Jun 2008 15:47:25 -0000 1.84 @@ -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 @@ /*---*/ -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 @@ 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 @@ 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 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 @@ /*---*/ -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 @@ {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 @@ { 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 @@ { 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 @@ * 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 @@ */ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ struct _Node { int type; + int count; char *name; char *key; Node *values; @@ -1500,7 +1537,7 @@ Eet_Data_Stream *ds; void *cdata, *data; int csize, size; - Node *n; + Node *n, *n2; if (words_bigendian == -1) { @@ -1528,27 +1565,39 @@ } 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 @@ 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 @@ 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 @@ } 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 @@ (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 @@ 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 @@ 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_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 @@ 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 @@ 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; ------------------------------------------------------------------------- Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://sourceforge.net/services/buy/index.php _______________________________________________ enlightenment-cvs mailing list enlightenment-cvs@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/enlightenment-cvs