diff --git a/legacy/eet/ChangeLog b/legacy/eet/ChangeLog index 6594360d4c..c65c30a006 100644 --- a/legacy/eet/ChangeLog +++ b/legacy/eet/ChangeLog @@ -486,3 +486,8 @@ * Use eina_stringshare_add() instead of strdup() on mmaped file names on Windows. This fix eet shut down on Windows. + +2011-02-14 Cedric BAIL + + * Improve Eet_Data to make decoding of EET_G_UNION and EET_G_*ARRAY + faster and less memory heavy. diff --git a/legacy/eet/src/lib/eet_data.c b/legacy/eet/src/lib/eet_data.c index e7c7fdc5fa..0666826c93 100644 --- a/legacy/eet/src/lib/eet_data.c +++ b/legacy/eet/src/lib/eet_data.c @@ -430,7 +430,9 @@ static void * _eet_data_descriptor_decode(Eet_Free_Context *co const Eet_Dictionary *ed, Eet_Data_Descriptor *edd, const void *data_in, - int size_in); + int size_in, + void *data_out, + int size_out); /*---*/ @@ -529,13 +531,15 @@ static int _eet_data_words_bigendian = -1; if (!___r) { goto Label; }\ } while (0) -#define STRUCT_TYPE_DECODE(Data_Ret, Context, Ed, Ede, Data, Size, Label)\ +#define STRUCT_TYPE_DECODE(Data_Ret, Context, Ed, Ede, Data, Size, SubSize, Label) \ do {\ Data_Ret = _eet_data_descriptor_decode(Context,\ Ed,\ Ede,\ Data,\ - Size);\ + Size,\ + SubSize > 0 ? Data_Ret : NULL,\ + SubSize); \ if (!Data_Ret) { goto Label; }\ } while (0) @@ -1980,7 +1984,7 @@ eet_data_read_cipher(Eet_File *ef, } eet_free_context_init(&context); - data_dec = _eet_data_descriptor_decode(&context, ed, edd, data, size); + data_dec = _eet_data_descriptor_decode(&context, ed, edd, data, size, NULL, 0); eet_free_context_shutdown(&context); if (required_free) @@ -2015,7 +2019,7 @@ eet_data_node_read_cipher(Eet_File *ef, } eet_free_context_init(&context); - result = _eet_data_descriptor_decode(&context, ed, NULL, data, size); + result = _eet_data_descriptor_decode(&context, ed, NULL, data, size, NULL, 0); eet_free_context_shutdown(&context); if (required_free) @@ -3161,7 +3165,9 @@ _eet_data_descriptor_decode(Eet_Free_Context *context, const Eet_Dictionary *ed, Eet_Data_Descriptor *edd, const void *data_in, - int size_in) + int size_in, + void *data_out, + int size_out) { Eet_Node *result = NULL; void *data = NULL; @@ -3182,7 +3188,16 @@ _eet_data_descriptor_decode(Eet_Free_Context *context, if (edd) { - data = edd->func.mem_alloc(edd->size); + if (data_out) + { + if (size_out <= edd->size) + data = data_out; + } + else + { + data = edd->func.mem_alloc(edd->size); + } + if (!data) return NULL; @@ -3195,7 +3210,7 @@ _eet_data_descriptor_decode(Eet_Free_Context *context, } _eet_freelist_all_ref(context); - if (data) + if (data && !data_out) _eet_freelist_add(context, data); memset(&chnk, 0, sizeof(Eet_Data_Chunk)); @@ -3425,6 +3440,7 @@ eet_data_get_list(Eet_Free_Context *context, subtype, echnk->data, echnk->size, + -1, on_error); if (edd) @@ -3509,6 +3525,7 @@ eet_data_get_hash(Eet_Free_Context *context, ede ? ede->subtype : NULL, echnk->data, echnk->size, + -1, on_error); if (edd) @@ -3602,7 +3619,6 @@ eet_data_get_array(Eet_Free_Context *context, for (i = 0; i < count; i++) { void *dst = NULL; - void *data_ret = NULL; /* Advance to next chunk */ NEXT_CHUNK((*p), (*size), (*echnk), ed); @@ -3632,6 +3648,8 @@ eet_data_get_array(Eet_Free_Context *context, if (IS_POINTER_TYPE(echnk->type)) { + void *data_ret = NULL; + POINTER_TYPE_DECODE(context, ed, edd, @@ -3650,26 +3668,17 @@ eet_data_get_array(Eet_Free_Context *context, } else { - STRUCT_TYPE_DECODE(data_ret, + STRUCT_TYPE_DECODE(dst, context, ed, ede ? ede->subtype : NULL, echnk->data, echnk->size, + subsize, on_error); - if (dst) - { - memcpy(dst, data_ret, subsize); - if ((ede) && (ede->subtype)) - ede->subtype->func.mem_free(data_ret); - else if (edd) - edd->func.mem_free(data_ret); - else free(data_ret); - _eet_freelist_del(context, data_ret); - } if (!edd) - childs = eina_list_append(childs, data_ret); + childs = eina_list_append(childs, dst); } } @@ -3810,16 +3819,12 @@ eet_data_get_union(Eet_Free_Context *context, ed, sede->subtype, echnk->data, - echnk->size); + echnk->size, + data, + sede->subtype->size); if (!data_ret) goto on_error; - /* Memcopy the structure content to remove pointer indirection. */ - memcpy(data, data_ret, sede->subtype->size); - - /* data_ret is now useless. */ - sede->subtype->func.mem_free(data_ret); - /* Set union type. */ if ((!ed) || (!ede->subtype->func.str_direct_alloc)) { @@ -3847,7 +3852,8 @@ eet_data_get_union(Eet_Free_Context *context, /* FIXME: generate node structure. */ data_ret = _eet_data_descriptor_decode(context, ed, NULL, - echnk->data, echnk->size); + echnk->data, echnk->size, + NULL, 0); goto on_error; } @@ -4074,7 +4080,8 @@ eet_data_get_variant(Eet_Free_Context *context, ed, sede->subtype, echnk->data, - echnk->size); + echnk->size, + NULL, 0); if (!data_ret) break; @@ -4112,7 +4119,8 @@ eet_data_get_variant(Eet_Free_Context *context, /* FIXME: dump node structure. */ data_ret = _eet_data_descriptor_decode(context, ed, NULL, - echnk->data, echnk->size); + echnk->data, echnk->size, + NULL, 0); goto on_error; } @@ -4245,7 +4253,8 @@ eet_data_get_unknown(Eet_Free_Context *context, ed, subtype, echnk->data, - echnk->size); + echnk->size, + NULL, 0); if (!data_ret) return 0; @@ -4463,7 +4472,7 @@ eet_data_dump_cipher(Eet_File *ef, } eet_free_context_init(&context); - result = _eet_data_descriptor_decode(&context, ed, NULL, data, size); + result = _eet_data_descriptor_decode(&context, ed, NULL, data, size, NULL, 0); eet_free_context_shutdown(&context); eet_node_dump(result, 0, dumpfunc, dumpdata); @@ -4518,7 +4527,7 @@ eet_data_text_dump_cipher(const void *data_in, } eet_free_context_init(&context); - result = _eet_data_descriptor_decode(&context, NULL, NULL, ret, ret_len); + result = _eet_data_descriptor_decode(&context, NULL, NULL, ret, ret_len, NULL, 0); eet_free_context_shutdown(&context); eet_node_dump(result, 0, dumpfunc, dumpdata); @@ -4640,7 +4649,8 @@ eet_data_descriptor_decode_cipher(Eet_Data_Descriptor *edd, NULL, edd, deciphered, - deciphered_len); + deciphered_len, + NULL, 0); eet_free_context_shutdown(&context); if (data_in != deciphered) @@ -4682,7 +4692,8 @@ eet_data_node_decode_cipher(const void *data_in, NULL, NULL, deciphered, - deciphered_len); + deciphered_len, + NULL, 0); eet_free_context_shutdown(&context); if (data_in != deciphered)