From 43af41b5e1cd9990ce2556964feca4cdca2c0c78 Mon Sep 17 00:00:00 2001 From: Sebastian Dransfeld Date: Sun, 17 Dec 2006 11:00:45 +0000 Subject: [PATCH] Store hashes. Please review. SVN revision: 27489 --- legacy/eet/src/lib/Eet.h | 23 ++++++ legacy/eet/src/lib/eet_data.c | 136 ++++++++++++++++++++++++++++++++-- 2 files changed, 154 insertions(+), 5 deletions(-) diff --git a/legacy/eet/src/lib/Eet.h b/legacy/eet/src/lib/Eet.h index 5a163c68b8..89e404be22 100644 --- a/legacy/eet/src/lib/Eet.h +++ b/legacy/eet/src/lib/Eet.h @@ -903,6 +903,29 @@ extern "C" { 0, NULL, subtype); \ } + /** + * Add a hash 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 hash 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. + * + */ +#define EET_DATA_DESCRIPTOR_ADD_HASH(edd, struct_type, name, member, subtype) \ + { \ + struct_type ___ett; \ + \ + eet_data_descriptor_element_add(edd, name, EET_T_UNKNOW, EET_G_HASH, \ + (char *)(&(___ett.member)) - (char *)(&(___ett)), \ + 0, NULL, subtype); \ + } + /***************************************************************************/ #ifdef __cplusplus } diff --git a/legacy/eet/src/lib/eet_data.c b/legacy/eet/src/lib/eet_data.c index 7ad6b2b265..3fbdf4e3f7 100644 --- a/legacy/eet/src/lib/eet_data.c +++ b/legacy/eet/src/lib/eet_data.c @@ -46,6 +46,7 @@ typedef struct _Eet_Data_Basic_Type_Decoder Eet_Data_Basic_Type_Decoder; 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; /*---*/ @@ -116,6 +117,12 @@ struct _Eet_Data_Element Eet_Data_Descriptor *subtype; }; +struct _Eet_Data_Encode_Hash_Info +{ + Eet_Data_Stream *ds; + Eet_Data_Element *ede; +}; + /*---*/ static int eet_data_get_char(void *src, void *src_end, void *dest); @@ -134,7 +141,7 @@ static int eet_data_get_string(void *src, void *src_end, void *dest); static void *eet_data_put_string(const void *src, int *size_ret); static int eet_data_get_type(int type, void *src, void *src_end, void *dest); -static void *eet_data_put_type(int type, void *src, int *size_ret); +static void *eet_data_put_type(int type, const void *src, int *size_ret); 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); @@ -146,6 +153,8 @@ static void eet_data_stream_free(Eet_Data_Stream *ds); static void eet_data_chunk_put(Eet_Data_Chunk *chnk, Eet_Data_Stream *ds); +static int eet_data_descriptor_encode_hash_cb(void *hash, const char *key, void *hdata, void *fdata); + /*---*/ const Eet_Data_Basic_Type_Decoder eet_coder[] = @@ -447,7 +456,7 @@ eet_data_get_type(int type, void *src, void *src_end, void *dest) } static void * -eet_data_put_type(int type, void *src, int *size_ret) +eet_data_put_type(int type, const void *src, int *size_ret) { void *ret; @@ -830,7 +839,7 @@ eet_data_read(Eet_File *ef, Eet_Data_Descriptor *edd, const char *name) int size; int required_free = 0; - data = eet_read_direct (ef, name, &size); + data = eet_read_direct(ef, name, &size); if (!data) { required_free = 1; @@ -1014,6 +1023,54 @@ _eet_freelist_str_unref(void) freelist_str_ref--; } +static int +eet_data_descriptor_encode_hash_cb(void *hash, const char *key, void *hdata, void *fdata) +{ + Eet_Data_Encode_Hash_Info *edehi; + Eet_Data_Stream *ds; + Eet_Data_Element *ede; + Eet_Data_Chunk *echnk; + void *data = NULL; + int size; + + edehi = fdata; + ede = edehi->ede; + ds = edehi->ds; + + /* Store key */ + data = eet_data_put_type(EET_T_STRING, + &key, + &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; + } + + /* Store data */ + if ((ede->type >= EET_T_CHAR) && + (ede->type <= EET_T_STRING)) + data = eet_data_put_type(ede->type, + hdata, + &size); + else if (ede->subtype) + data = eet_data_descriptor_encode(ede->subtype, + hdata, + &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; + } + return 1; +} + EAPI void * eet_data_descriptor_decode(Eet_Data_Descriptor *edd, const void *data_in, @@ -1149,7 +1206,70 @@ eet_data_descriptor_decode(Eet_Data_Descriptor *edd, } break; case EET_G_HASH: - printf("HASH TYPE NOT IMPLIMENTED YET!!!\n"); + { + int ret; + void *hash = NULL; + void **ptr; + char *key = NULL; + void *data_ret = NULL; + + ptr = (void **)(((char *)data) + ede->offset); + hash = *ptr; + + /* Read key */ + key = calloc(1, eet_coder[EET_T_STRING].size); + if (key) + { + _eet_freelist_add(key); + ret = eet_data_get_type(EET_T_STRING, + echnk.data, + ((char *)echnk.data) + echnk.size, + &key); + if (ret <= 0) goto error; + } + else + 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_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; + _eet_freelist_list_add(ptr); + } + else + goto error; + } break; default: break; @@ -1273,7 +1393,13 @@ eet_data_descriptor_encode(Eet_Data_Descriptor *edd, break; case EET_G_HASH: { - printf("HASH TYPE NOT IMPLIMENTED YET!!!\n"); + 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: