From e076a78519b2eed449579116dac83b1eae55f2d8 Mon Sep 17 00:00:00 2001 From: Carsten Haitzler Date: Sat, 1 Mar 2008 06:38:09 +0000 Subject: [PATCH] cedric's eet and edje patches to use eet dictionaries for strings. SVN revision: 33873 --- legacy/edje/src/bin/edje_cc_sources.c | 8 +- legacy/edje/src/lib/edje_cache.c | 37 +- legacy/edje/src/lib/edje_data.c | 57 +- legacy/edje/src/lib/edje_load.c | 93 +- legacy/edje/src/lib/edje_private.h | 4 + legacy/edje/src/lib/edje_textblock_styles.c | 19 +- legacy/eet/src/lib/Eet.h | 44 +- legacy/eet/src/lib/Eet_private.h | 45 + legacy/eet/src/lib/Makefile.am | 1 + legacy/eet/src/lib/eet_data.c | 1004 ++++++++++------- legacy/eet/src/lib/eet_image.c | 9 +- legacy/eet/src/lib/eet_lib.c | 502 ++++++++- legacy/eet/src/lib/eet_memfile.c | 4 +- .../engines/software_x11/evas_outbuf.c | 7 +- 14 files changed, 1253 insertions(+), 581 deletions(-) diff --git a/legacy/edje/src/bin/edje_cc_sources.c b/legacy/edje/src/bin/edje_cc_sources.c index df40874694..6f55f8cd37 100644 --- a/legacy/edje/src/bin/edje_cc_sources.c +++ b/legacy/edje/src/bin/edje_cc_sources.c @@ -23,8 +23,8 @@ source_edd(void) (void (*) (void *, int (*) (void *, const char *, void *, void *), void *))evas_hash_foreach, (void *(*) (void *, const char *, void *))evas_hash_add, (void (*) (void *))evas_hash_free); - EET_DATA_DESCRIPTOR_ADD_BASIC(_srcfile_edd, SrcFile, "name", name, EET_T_STRING); - EET_DATA_DESCRIPTOR_ADD_BASIC(_srcfile_edd, SrcFile, "file", file, EET_T_STRING); + EET_DATA_DESCRIPTOR_ADD_BASIC(_srcfile_edd, SrcFile, "name", name, EET_T_INLINED_STRING); + EET_DATA_DESCRIPTOR_ADD_BASIC(_srcfile_edd, SrcFile, "file", file, EET_T_INLINED_STRING); _srcfile_list_edd = eet_data_descriptor_new("srcfile_list", sizeof(SrcFile_List), (void *(*) (void *))evas_list_next, (void *(*) (void *, void *))evas_list_append, @@ -43,8 +43,8 @@ source_edd(void) (void (*) (void *, int (*) (void *, const char *, void *, void *), void *))evas_hash_foreach, (void *(*) (void *, const char *, void *))evas_hash_add, (void (*) (void *))evas_hash_free); - EET_DATA_DESCRIPTOR_ADD_BASIC(_font_edd, Font, "file", file, EET_T_STRING); - EET_DATA_DESCRIPTOR_ADD_BASIC(_font_edd, Font, "name", name, EET_T_STRING); + EET_DATA_DESCRIPTOR_ADD_BASIC(_font_edd, Font, "file", file, EET_T_INLINED_STRING); + EET_DATA_DESCRIPTOR_ADD_BASIC(_font_edd, Font, "name", name, EET_T_INLINED_STRING); _font_list_edd = eet_data_descriptor_new("font_list", sizeof(Font_List), (void *(*) (void *))evas_list_next, (void *(*) (void *, void *))evas_list_append, diff --git a/legacy/edje/src/lib/edje_cache.c b/legacy/edje/src/lib/edje_cache.c index ea1684a28a..b23f4b7c27 100644 --- a/legacy/edje/src/lib/edje_cache.c +++ b/legacy/edje/src/lib/edje_cache.c @@ -12,11 +12,11 @@ static Evas_List *_edje_file_cache = NULL; static int _edje_collection_cache_size = 16; static Edje_Part_Collection * -_edje_file_coll_open(Edje_File *edf, Eet_File *ef, const char *coll) +_edje_file_coll_open(Edje_File *edf, const char *coll) { Edje_Part_Collection *edc = NULL; Evas_List *l = NULL; - int id = -1, close_eet = 0, size = 0; + int id = -1, size = 0; char buf[256]; void *data; @@ -33,23 +33,12 @@ _edje_file_coll_open(Edje_File *edf, Eet_File *ef, const char *coll) } if (id < 0) return NULL; - if (!ef) - { - ef = eet_open(edf->path, EET_FILE_MODE_READ); - if (!ef) return NULL; - close_eet = 1; - } snprintf(buf, sizeof(buf), "collections/%i", id); - edc = eet_data_read(ef, _edje_edd_edje_part_collection, buf); - if (!edc) - { - if (close_eet) eet_close(ef); - return NULL; - } + edc = eet_data_read(edf->ef, _edje_edd_edje_part_collection, buf); + if (!edc) return NULL; snprintf(buf, sizeof(buf), "scripts/%i", id); - data = eet_read(ef, buf, &size); - if (close_eet) eet_close(ef); + data = eet_read(edf->ef, buf, &size); if (data) { @@ -83,7 +72,8 @@ _edje_font_hash(Edje_File *edf) snprintf(tmp, length, "fonts/%s", fnt->entry); fnt->path = evas_stringshare_add(tmp); - evas_stringshare_del(fnt->entry); + if (edf->free_strings) + evas_stringshare_del(fnt->entry); fnt->entry = fnt->path + 6; edf->font_hash = evas_hash_direct_add(edf->font_hash, fnt->entry, fnt); @@ -121,18 +111,21 @@ _edje_file_open(const char *file, const char *coll, int *error_ret, Edje_Part_Co eet_close(ef); return NULL; } + + edf->free_strings = eet_dictionary_get(ef) ? 0 : 1; + + edf->ef = ef; + if (edf->version != EDJE_FILE_VERSION) { *error_ret = EDJE_LOAD_ERROR_INCOMPATIBLE_FILE; _edje_file_free(edf); - eet_close(ef); return NULL; } if (!edf->collection_dir) { *error_ret = EDJE_LOAD_ERROR_CORRUPT_FILE; _edje_file_free(edf); - eet_close(ef); return NULL; } @@ -151,7 +144,7 @@ _edje_file_open(const char *file, const char *coll, int *error_ret, Edje_Part_Co if (coll) { - edc = _edje_file_coll_open(edf, ef, coll); + edc = _edje_file_coll_open(edf, coll); if (!edc) { *error_ret = EDJE_LOAD_ERROR_UNKNOWN_COLLECTION; @@ -163,8 +156,6 @@ _edje_file_open(const char *file, const char *coll, int *error_ret, Edje_Part_Co _edje_font_hash(edf); - eet_close(ef); - return edf; } @@ -227,7 +218,7 @@ _edje_cache_file_coll_open(const char *file, const char *coll, int *error_ret, E } if (!edc) { - edc = _edje_file_coll_open(edf, NULL, coll); + edc = _edje_file_coll_open(edf, coll); if (!edc) { *error_ret = EDJE_LOAD_ERROR_UNKNOWN_COLLECTION; diff --git a/legacy/edje/src/lib/edje_data.c b/legacy/edje/src/lib/edje_data.c index 4480053ca2..aed89df77b 100644 --- a/legacy/edje/src/lib/edje_data.c +++ b/legacy/edje/src/lib/edje_data.c @@ -59,6 +59,19 @@ _edje_edd_free(void) FREED(_edje_edd_edje_part_image_id); } +static char * +_edge_str_direct_alloc(const char *str) +{ + + return (char *) str; +} + +static void +_edje_str_direct_free(const char *str) +{ + (void) str; +} + void _edje_edd_setup(void) { @@ -76,25 +89,27 @@ _edje_edd_setup(void) eddc.func.hash_foreach = evas_hash_foreach; eddc.func.hash_add = evas_hash_add; eddc.func.hash_free = evas_hash_free; + eddc.func.str_direct_alloc = _edge_str_direct_alloc; + eddc.func.str_direct_free = _edje_str_direct_free; /* font directory */ NEWD("Edje_Font_Directory_Entry", Edje_Font_Directory_Entry); _edje_edd_edje_font_directory_entry = - eet_data_descriptor2_new(&eddc); + eet_data_descriptor3_new(&eddc); EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_font_directory_entry, Edje_Font_Directory_Entry, "entry", entry, EET_T_STRING); NEWD("Edje_Font_Directory", Edje_Font_Directory); _edje_edd_edje_font_directory = - eet_data_descriptor2_new(&eddc); + eet_data_descriptor3_new(&eddc); EET_DATA_DESCRIPTOR_ADD_LIST(_edje_edd_edje_font_directory, Edje_Font_Directory, "entries", entries, _edje_edd_edje_font_directory_entry); /* image directory */ NEWD("Edje_Image_Directory_Entry", Edje_Image_Directory_Entry); _edje_edd_edje_image_directory_entry = - eet_data_descriptor2_new(&eddc); + eet_data_descriptor3_new(&eddc); EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_image_directory_entry, Edje_Image_Directory_Entry, "entry", entry, EET_T_STRING); EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_image_directory_entry, Edje_Image_Directory_Entry, "source_type", source_type, EET_T_INT); EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_image_directory_entry, Edje_Image_Directory_Entry, "source_param", source_param, EET_T_INT); @@ -103,14 +118,14 @@ _edje_edd_setup(void) NEWD("Edje_Image_Directory", Edje_Image_Directory); _edje_edd_edje_image_directory = - eet_data_descriptor2_new(&eddc); + eet_data_descriptor3_new(&eddc); EET_DATA_DESCRIPTOR_ADD_LIST(_edje_edd_edje_image_directory, Edje_Image_Directory, "entries", entries, _edje_edd_edje_image_directory_entry); /* spectrum directory */ NEWD("Edje_Spectrum_Color", Edje_Spectrum_Color); _edje_edd_edje_spectrum_color = - eet_data_descriptor2_new(&eddc); + eet_data_descriptor3_new(&eddc); EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_spectrum_color, Edje_Spectrum_Color, "r", r, EET_T_INT); EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_spectrum_color, Edje_Spectrum_Color, "g", g, EET_T_INT); EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_spectrum_color, Edje_Spectrum_Color, "b", b, EET_T_INT); @@ -120,7 +135,7 @@ _edje_edd_setup(void) NEWD("Edje_Spectrum_Directory_Entry", Edje_Spectrum_Directory_Entry); _edje_edd_edje_spectrum_directory_entry = - eet_data_descriptor2_new(&eddc); + eet_data_descriptor3_new(&eddc); EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_spectrum_directory_entry, Edje_Spectrum_Directory_Entry, "entry", entry, EET_T_STRING); EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_spectrum_directory_entry, Edje_Spectrum_Directory_Entry, "filename", filename, EET_T_STRING); EET_DATA_DESCRIPTOR_ADD_LIST(_edje_edd_edje_spectrum_directory_entry, Edje_Spectrum_Directory_Entry, "color_list", color_list, _edje_edd_edje_spectrum_color); @@ -129,49 +144,49 @@ _edje_edd_setup(void) NEWD("Edje_Spectrum_Directory", Edje_Spectrum_Directory); _edje_edd_edje_spectrum_directory = - eet_data_descriptor2_new(&eddc); + eet_data_descriptor3_new(&eddc); EET_DATA_DESCRIPTOR_ADD_LIST(_edje_edd_edje_spectrum_directory, Edje_Spectrum_Directory, "entries", entries, _edje_edd_edje_spectrum_directory_entry); /* collection directory */ NEWD("Edje_Part_Collection_Directory_Entry", Edje_Part_Collection_Directory_Entry); _edje_edd_edje_part_collection_directory_entry = - eet_data_descriptor2_new(&eddc); + eet_data_descriptor3_new(&eddc); EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_collection_directory_entry, Edje_Part_Collection_Directory_Entry, "entry", entry, EET_T_STRING); EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_collection_directory_entry, Edje_Part_Collection_Directory_Entry, "id", id, EET_T_INT); NEWD("Edje_Part_Collection_Directory", Edje_Part_Collection_Directory); _edje_edd_edje_part_collection_directory = - eet_data_descriptor2_new(&eddc); + eet_data_descriptor3_new(&eddc); EET_DATA_DESCRIPTOR_ADD_LIST(_edje_edd_edje_part_collection_directory, Edje_Part_Collection_Directory, "entries", entries, _edje_edd_edje_part_collection_directory_entry); /* generic data attachment */ NEWD("Edje_Data", Edje_Data); _edje_edd_edje_data = - eet_data_descriptor2_new(&eddc); + eet_data_descriptor3_new(&eddc); EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_data, Edje_Data, "key", key, EET_T_STRING); EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_data, Edje_Data, "value", value, EET_T_STRING); NEWD("Edje_Style_Tag", Edje_Style_Tag); _edje_edd_edje_style_tag = - eet_data_descriptor2_new(&eddc); + eet_data_descriptor3_new(&eddc); EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_style_tag, Edje_Style_Tag, "key", key, EET_T_STRING); EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_style_tag, Edje_Style_Tag, "value", value, EET_T_STRING); NEWD("Edje_Style", Edje_Style); _edje_edd_edje_style = - eet_data_descriptor2_new(&eddc); + eet_data_descriptor3_new(&eddc); EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_style, Edje_Style, "name", name, EET_T_STRING); EET_DATA_DESCRIPTOR_ADD_LIST(_edje_edd_edje_style, Edje_Style, "tags", tags, _edje_edd_edje_style_tag); NEWD("Edje_Color_Class", Edje_Color_Class); _edje_edd_edje_color_class = - eet_data_descriptor2_new(&eddc); + eet_data_descriptor3_new(&eddc); EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_color_class, Edje_Color_Class, "name", name, EET_T_STRING); EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_color_class, Edje_Color_Class, "r", r, EET_T_UCHAR); EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_color_class, Edje_Color_Class, "g", g, EET_T_UCHAR); @@ -190,7 +205,7 @@ _edje_edd_setup(void) NEWD("Edje_File", Edje_File); _edje_edd_edje_file = - eet_data_descriptor2_new(&eddc); + eet_data_descriptor3_new(&eddc); EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_file, Edje_File, "compiler", compiler, EET_T_STRING); EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_file, Edje_File, "version", version, EET_T_INT); EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_file, Edje_File, "feature_ver", feature_ver, EET_T_INT); @@ -206,20 +221,20 @@ _edje_edd_setup(void) NEWD("Edje_Program_Target", Edje_Program_Target); _edje_edd_edje_program_target = - eet_data_descriptor2_new(&eddc); + eet_data_descriptor3_new(&eddc); EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_program_target, Edje_Program_Target, "id", id, EET_T_INT); NEWD("Edje_Program_After", Edje_Program_After); _edje_edd_edje_program_after = - eet_data_descriptor2_new(&eddc); + eet_data_descriptor3_new(&eddc); EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_program_after, Edje_Program_After, "id", id, EET_T_INT); NEWD("Edje_Program", Edje_Program); _edje_edd_edje_program = - eet_data_descriptor2_new(&eddc); + eet_data_descriptor3_new(&eddc); EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_program, Edje_Program, "id", id, EET_T_INT); EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_program, Edje_Program, "name", name, EET_T_STRING); EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_program, Edje_Program, "signal", signal, EET_T_STRING); @@ -239,13 +254,13 @@ _edje_edd_setup(void) NEWD("Edje_Part_Image_Id", Edje_Part_Image_Id); _edje_edd_edje_part_image_id = - eet_data_descriptor2_new(&eddc); + eet_data_descriptor3_new(&eddc); EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_image_id, Edje_Part_Image_Id, "id", id, EET_T_INT); NEWD("Edje_Part_Description", Edje_Part_Description); _edje_edd_edje_part_description = - eet_data_descriptor2_new(&eddc); + eet_data_descriptor3_new(&eddc); EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_description, Edje_Part_Description, "state.name", state.name, EET_T_STRING); EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_description, Edje_Part_Description, "state.value", state.value, EET_T_DOUBLE); EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_description, Edje_Part_Description, "visible", visible, EET_T_CHAR); @@ -338,7 +353,7 @@ _edje_edd_setup(void) NEWD("Edje_Part", Edje_Part); _edje_edd_edje_part = - eet_data_descriptor2_new(&eddc); + eet_data_descriptor3_new(&eddc); EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part, Edje_Part, "name", name, EET_T_STRING); EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part, Edje_Part, "id", id, EET_T_INT); EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part, Edje_Part, "type", type, EET_T_CHAR); @@ -364,7 +379,7 @@ _edje_edd_setup(void) NEWD("Edje_Part_Collection", Edje_Part_Collection); _edje_edd_edje_part_collection = - eet_data_descriptor2_new(&eddc); + eet_data_descriptor3_new(&eddc); EET_DATA_DESCRIPTOR_ADD_LIST(_edje_edd_edje_part_collection, Edje_Part_Collection, "programs", programs, _edje_edd_edje_program); EET_DATA_DESCRIPTOR_ADD_LIST(_edje_edd_edje_part_collection, Edje_Part_Collection, "parts", parts, _edje_edd_edje_part); EET_DATA_DESCRIPTOR_ADD_LIST(_edje_edd_edje_part_collection, Edje_Part_Collection, "data", data, _edje_edd_edje_data); diff --git a/legacy/edje/src/lib/edje_load.c b/legacy/edje/src/lib/edje_load.c index 02bde62d10..736f7d8a35 100644 --- a/legacy/edje/src/lib/edje_load.c +++ b/legacy/edje/src/lib/edje_load.c @@ -5,7 +5,7 @@ #include "Edje.h" #include "edje_private.h" -static void _edje_collection_free_part_description_free(Edje_Part_Description *desc); +static void _edje_collection_free_part_description_free(Edje_Part_Description *desc, unsigned int free_strings); static Evas_Bool _edje_file_collection_hash_foreach(const Evas_Hash *hash, const char *key, void *data, void *fdata); #ifdef EDJE_PROGRAM_CACHE static int _edje_collection_free_prog_cache_matches_free_cb(Evas_Hash *hash, const char *key, void *data, void *fdata); @@ -430,6 +430,8 @@ _edje_object_file_set_internal(Evas_Object *obj, const char *file, const char *p _edje_programs_patterns_init(ed); n = evas_list_count(ed->collection->programs); + ed->patterns.programs.signals_patterns = edje_match_programs_signal_init(ed->collection->programs); + ed->patterns.programs.sources_patterns = edje_match_programs_source_init(ed->collection->programs); if (n > 0) { /* FIXME: keeping a table AND a list is just bad - nuke list */ @@ -683,7 +685,7 @@ _edje_file_del(Edje *ed) if (rp->text.cache.out_str) evas_stringshare_del(rp->text.cache.out_str); if (rp->custom.description) - _edje_collection_free_part_description_free(rp->custom.description); + _edje_collection_free_part_description_free(rp->custom.description, ed->file->free_strings); _edje_unref(rp->edje); free(rp); @@ -725,10 +727,12 @@ _edje_file_del(Edje *ed) * Used to free the cached data values that are stored in the data_cache * hash table. */ -static Evas_Bool -data_cache_free(const Evas_Hash *hash, const char *key, void *data, void *fdata) +static Evas_Bool data_cache_free(const Evas_Hash *hash, const char *key, void *data, void *fdata) { - evas_stringshare_del(data); + Edje_File *edf; + + edf = fdata; + if (edf->free_strings) evas_stringshare_del(data); return 1; } @@ -744,8 +748,8 @@ _edje_file_free(Edje_File *edf) fe = edf->font_dir->entries->data; edf->font_dir->entries = evas_list_remove_list(edf->font_dir->entries, edf->font_dir->entries); - edf->font_hash = evas_hash_del(edf->font_hash, fe->entry, NULL); - if (fe->path) evas_stringshare_del(fe->path); + edf->font_hash = evas_hash_del(edf->font_hash, fe->entry, edf); + if (edf->free_strings && fe->path) evas_stringshare_del(fe->path); free(fe); } free(edf->font_dir); @@ -759,7 +763,7 @@ _edje_file_free(Edje_File *edf) ie = edf->image_dir->entries->data; edf->image_dir->entries = evas_list_remove_list(edf->image_dir->entries, edf->image_dir->entries); - if (ie->entry) evas_stringshare_del(ie->entry); + if (edf->free_strings && ie->entry) evas_stringshare_del(ie->entry); free(ie); } free(edf->image_dir); @@ -773,7 +777,7 @@ _edje_file_free(Edje_File *edf) ce = edf->collection_dir->entries->data; edf->collection_dir->entries = evas_list_remove_list(edf->collection_dir->entries, edf->collection_dir->entries); - if (ce->entry) evas_stringshare_del(ce->entry); + if (edf->free_strings && ce->entry) evas_stringshare_del(ce->entry); free(ce); } free(edf->collection_dir); @@ -793,8 +797,11 @@ _edje_file_free(Edje_File *edf) se->color_list = evas_list_remove_list(se->color_list, se->color_list); } - if (se->entry) evas_stringshare_del(se->entry); - if (se->filename) evas_stringshare_del(se->filename); + if (edf->free_strings) + { + if (se->entry) evas_stringshare_del(se->entry); + if (se->filename) evas_stringshare_del(se->filename); + } free(se); } free(edf->spectrum_dir); @@ -805,13 +812,16 @@ _edje_file_free(Edje_File *edf) edt = edf->data->data; edf->data = evas_list_remove(edf->data, edt); - if (edt->key) evas_stringshare_del(edt->key); - if (edt->value) evas_stringshare_del(edt->value); + if (edf->free_strings) + { + if (edt->key) evas_stringshare_del(edt->key); + if (edt->value) evas_stringshare_del(edt->value); + } free(edt); } if (edf->data_cache) { - evas_hash_foreach(edf->data_cache, data_cache_free, NULL); + evas_hash_foreach(edf->data_cache, data_cache_free, edf); evas_hash_free(edf->data_cache); edf->data_cache = NULL; } @@ -823,7 +833,7 @@ _edje_file_free(Edje_File *edf) ecc = edf->color_classes->data; edf->color_classes = evas_list_remove_list(edf->color_classes, edf->color_classes); - if (ecc->name) evas_stringshare_del(ecc->name); + if (edf->free_strings && ecc->name) evas_stringshare_del(ecc->name); free(ecc); } @@ -845,9 +855,10 @@ _edje_file_free(Edje_File *edf) evas_hash_free(edf->collection_hash); } if (edf->path) evas_stringshare_del(edf->path); - if (edf->compiler) evas_stringshare_del(edf->compiler); + if (edf->free_strings && edf->compiler) evas_stringshare_del(edf->compiler); if (edf->collection_cache) _edje_cache_coll_flush(edf); _edje_textblock_style_cleanup(edf); + if (edf->ef) eet_close(edf->ef); free(edf); } @@ -860,11 +871,14 @@ _edje_collection_free(Edje_File *edf, Edje_Part_Collection *ec) pr = ec->programs->data; ec->programs = evas_list_remove_list(ec->programs, ec->programs); - if (pr->name) evas_stringshare_del(pr->name); - if (pr->signal) evas_stringshare_del(pr->signal); - if (pr->source) evas_stringshare_del(pr->source); - if (pr->state) evas_stringshare_del(pr->state); - if (pr->state2) evas_stringshare_del(pr->state2); + if (edf->free_strings) + { + if (pr->name) evas_stringshare_del(pr->name); + if (pr->signal) evas_stringshare_del(pr->signal); + if (pr->source) evas_stringshare_del(pr->source); + if (pr->state) evas_stringshare_del(pr->state); + if (pr->state2) evas_stringshare_del(pr->state2); + } while (pr->targets) { Edje_Program_Target *prt; @@ -889,10 +903,10 @@ _edje_collection_free(Edje_File *edf, Edje_Part_Collection *ec) ep = ec->parts->data; ec->parts = evas_list_remove(ec->parts, ep); - if (ep->name) evas_stringshare_del(ep->name); + if (edf->free_strings && ep->name) evas_stringshare_del(ep->name); if (ep->default_desc) { - _edje_collection_free_part_description_free(ep->default_desc); + _edje_collection_free_part_description_free(ep->default_desc, edf->free_strings); ep->default_desc = NULL; } while (ep->other_desc) @@ -901,7 +915,7 @@ _edje_collection_free(Edje_File *edf, Edje_Part_Collection *ec) desc = ep->other_desc->data; ep->other_desc = evas_list_remove(ep->other_desc, desc); - _edje_collection_free_part_description_free(desc); + _edje_collection_free_part_description_free(desc, edf->free_strings); } free(ep); } @@ -913,12 +927,15 @@ _edje_collection_free(Edje_File *edf, Edje_Part_Collection *ec) edt = ec->data->data; ec->data = evas_list_remove(ec->data, edt); - if (edt->key) evas_stringshare_del(edt->key); - if (edt->value) evas_stringshare_del(edt->value); + if (edf->free_strings) + { + if (edt->key) evas_stringshare_del(edt->key); + if (edt->value) evas_stringshare_del(edt->value); + } free(edt); } } - if (ec->part) evas_stringshare_del(ec->part); + if (edf->free_strings && ec->part) evas_stringshare_del(ec->part); #ifdef EDJE_PROGRAM_CACHE if (ec->prog_cache.no_matches) evas_hash_free(ec->prog_cache.no_matches); if (ec->prog_cache.matches) @@ -934,9 +951,8 @@ _edje_collection_free(Edje_File *edf, Edje_Part_Collection *ec) } static void -_edje_collection_free_part_description_free(Edje_Part_Description *desc) +_edje_collection_free_part_description_free(Edje_Part_Description *desc, unsigned int free_strings) { - if (desc->state.name) evas_stringshare_del(desc->state.name); while (desc->image.tween_list) { Edje_Part_Image_Id *pi; @@ -945,13 +961,16 @@ _edje_collection_free_part_description_free(Edje_Part_Description *desc) desc->image.tween_list = evas_list_remove(desc->image.tween_list, pi); free(pi); } - if (desc->color_class) evas_stringshare_del(desc->color_class); - if (desc->text.text) evas_stringshare_del(desc->text.text); - if (desc->text.text_class) evas_stringshare_del(desc->text.text_class); - if (desc->text.style) evas_stringshare_del(desc->text.style); - if (desc->text.font) evas_stringshare_del(desc->text.font); - if (desc->gradient.type) evas_stringshare_del(desc->gradient.type); - if (desc->gradient.params) evas_stringshare_del(desc->gradient.params); + if (free_strings) + { + if (desc->color_class) evas_stringshare_del(desc->color_class); + if (desc->text.text) evas_stringshare_del(desc->text.text); + if (desc->text.text_class) evas_stringshare_del(desc->text.text_class); + if (desc->text.style) evas_stringshare_del(desc->text.style); + if (desc->text.font) evas_stringshare_del(desc->text.font); + if (desc->gradient.type) evas_stringshare_del(desc->gradient.type); + if (desc->gradient.params) evas_stringshare_del(desc->gradient.params); + } free(desc); } @@ -973,7 +992,7 @@ _edje_file_collection_hash_foreach(const Evas_Hash *hash, const char *key, void #ifdef EDJE_PROGRAM_CACHE static int -_edje_collection_free_prog_cache_matches_free_cb(Evas_Hash *hash, const char *key, void *data, void *fdata) +_edje_collection_free_prog_cache_matches_free_cb(const Evas_Hash *hash, const char *key, void *data, void *fdata) { evas_list_free((Evas_List *)data); return 1; diff --git a/legacy/edje/src/lib/edje_private.h b/legacy/edje/src/lib/edje_private.h index 022c7f35b2..3ff3efedf2 100644 --- a/legacy/edje/src/lib/edje_private.h +++ b/legacy/edje/src/lib/edje_private.h @@ -294,6 +294,10 @@ struct _Edje_File Evas_Hash *font_hash; Evas_List *collection_cache; Evas_Hash *data_cache; + + Eet_File *ef; + + unsigned int free_strings : 1; }; struct _Edje_Style diff --git a/legacy/edje/src/lib/edje_textblock_styles.c b/legacy/edje/src/lib/edje_textblock_styles.c index e2dd81a38e..839573ef4c 100644 --- a/legacy/edje/src/lib/edje_textblock_styles.c +++ b/legacy/edje/src/lib/edje_textblock_styles.c @@ -410,7 +410,8 @@ _edje_textblock_style_parse_and_fix(Edje_File *edf) /* Add and Handle tag parsed data */ if (ts) { - evas_stringshare_del(tag->value); + /* FIXME: How to know if the previous value was a stringshare */ +/* evas_stringshare_del(tag->value); */ tag->value = evas_stringshare_add(ts); buf = _edje_strbuf_append(buf, tag->value, &buflen, &bufalloc); free(ts); @@ -476,13 +477,17 @@ _edje_textblock_style_cleanup(Edje_File *edf) tag = stl->tags->data; stl->tags = evas_list_remove_list(stl->tags, stl->tags); - if (tag->key) evas_stringshare_del(tag->key); - if (tag->value) evas_stringshare_del(tag->value); - if (tag->text_class) evas_stringshare_del(tag->text_class); - if (tag->font) evas_stringshare_del(tag->font); - free(tag); + if (edf->free_strings) + { + if (tag->key) evas_stringshare_del(tag->key); +/* FIXME: Find a proper way to handle it. */ + if (tag->value) evas_stringshare_del(tag->value); + if (tag->text_class) evas_stringshare_del(tag->text_class); + if (tag->font) evas_stringshare_del(tag->font); + } + free(tag); } - if (stl->name) evas_stringshare_del(stl->name); + if (edf->free_strings && stl->name) evas_stringshare_del(stl->name); if (stl->style) evas_textblock_style_free(stl->style); free(stl); } diff --git a/legacy/eet/src/lib/Eet.h b/legacy/eet/src/lib/Eet.h index fd28b81420..bdc842a6c4 100644 --- a/legacy/eet/src/lib/Eet.h +++ b/legacy/eet/src/lib/Eet.h @@ -38,19 +38,20 @@ extern "C" { /***************************************************************************/ -#define EET_T_UNKNOW 0 /**< Unknown data encoding type */ -#define EET_T_CHAR 1 /**< Data type: char */ -#define EET_T_SHORT 2 /**< Data type: short */ -#define EET_T_INT 3 /**< Data type: int */ -#define EET_T_LONG_LONG 4 /**< Data type: long long */ -#define EET_T_FLOAT 5 /**< Data type: float */ -#define EET_T_DOUBLE 6 /**< Data type: double */ -#define EET_T_UCHAR 7 /**< Data type: unsigned char */ -#define EET_T_USHORT 8 /**< Data type: unsigned short */ -#define EET_T_UINT 9 /**< Data type: unsigned int */ -#define EET_T_ULONG_LONG 10 /**< Data type: unsigned long long */ -#define EET_T_STRING 11 /**< Data type: char * */ -#define EET_T_LAST 12 /**< Last data type */ +#define EET_T_UNKNOW 0 /**< Unknown data encoding type */ +#define EET_T_CHAR 1 /**< Data type: char */ +#define EET_T_SHORT 2 /**< Data type: short */ +#define EET_T_INT 3 /**< Data type: int */ +#define EET_T_LONG_LONG 4 /**< Data type: long long */ +#define EET_T_FLOAT 5 /**< Data type: float */ +#define EET_T_DOUBLE 6 /**< Data type: double */ +#define EET_T_UCHAR 7 /**< Data type: unsigned char */ +#define EET_T_USHORT 8 /**< Data type: unsigned short */ +#define EET_T_UINT 9 /**< Data type: unsigned int */ +#define EET_T_ULONG_LONG 10 /**< Data type: unsigned long long */ +#define EET_T_STRING 11 /**< Data type: char * */ +#define EET_T_INLINED_STRING 12 /**< Data type: char * (but compressed inside the resulting eet) */ +#define EET_T_LAST 13 /**< Last data type */ #define EET_G_UNKNOWN 100 /**< Unknown group data encoding type */ #define EET_G_ARRAY 101 /**< Fixed size array group type */ @@ -84,11 +85,12 @@ extern "C" { } Eet_Error; typedef struct _Eet_File Eet_File; + typedef struct _Eet_Dictionary Eet_Dictionary; typedef struct _Eet_Data_Descriptor Eet_Data_Descriptor; typedef struct _Eet_Data_Descriptor_Class Eet_Data_Descriptor_Class; -#define EET_DATA_DESCRIPTOR_CLASS_VERSION 1 +#define EET_DATA_DESCRIPTOR_CLASS_VERSION 2 struct _Eet_Data_Descriptor_Class { int version; @@ -97,7 +99,7 @@ extern "C" { struct { void *(*mem_alloc) (size_t size); void (*mem_free) (void *mem); - char *(*str_alloc) (const char *str); + char *(*str_alloc) (const char *str); void (*str_free) (const char *str); void *(*list_next) (void *l); void *(*list_append) (void *l, void *d); @@ -106,6 +108,8 @@ extern "C" { void (*hash_foreach) (void *h, int (*func) (void *h, const char *k, void *dt, void *fdt), void *fdt); void *(*hash_add) (void *h, const char *k, void *d); void (*hash_free) (void *h); + char *(*str_direct_alloc) (const char *str); + void (*str_direct_free) (const char *str); } func; }; @@ -216,6 +220,9 @@ extern "C" { */ EAPI Eet_Error eet_close(Eet_File *ef); + /* FIXME: Add some documentation */ + EAPI Eet_Dictionary* eet_dictionary_get(Eet_File *ef); + /** * Read a specified entry from an eet file and return data * @param ef A valid eet file handle opened for reading. @@ -667,12 +674,6 @@ extern "C" { * blah.blah3 = evas_list_append(blah.blah3, &blah3); * * data = eet_data_descriptor_encode(edd, &blah, &size); - * f = fopen("out", "w"); - * if (f) - * { - * fwrite(data, size, 1, f); - * fclose(f); - * } * printf("-----DECODING\n"); * blah_in = eet_data_descriptor_decode(edd, data, size); * @@ -716,6 +717,7 @@ extern "C" { * move happens - but be warned */ EAPI Eet_Data_Descriptor *eet_data_descriptor2_new(Eet_Data_Descriptor_Class *eddc); + EAPI Eet_Data_Descriptor *eet_data_descriptor3_new(Eet_Data_Descriptor_Class *eddc); /** * This function frees a data descriptor when it is not needed anymore. diff --git a/legacy/eet/src/lib/Eet_private.h b/legacy/eet/src/lib/Eet_private.h index 044ba83405..37b4dc1d10 100644 --- a/legacy/eet/src/lib/Eet_private.h +++ b/legacy/eet/src/lib/Eet_private.h @@ -51,6 +51,51 @@ void *alloca (size_t); # endif #endif +typedef struct _Eet_String Eet_String; + +struct _Eet_String +{ + const char *mmap; + char *str; + + struct + { + unsigned int converted : 1; + unsigned int is_float : 1; + } flags; + union + { + float f; + double d; + } convert; + + int hash; + int len; + + int next; + int prev; +}; +struct _Eet_Dictionary +{ + Eet_String *all; + + int size; + int offset; + + int hash[256]; + + int count; + int total; +}; + +Eet_Dictionary *eet_dictionary_add(void); +void eet_dictionary_free(Eet_Dictionary *ed); +int eet_dictionary_string_add(Eet_Dictionary *ed, const char *string); +int eet_dictionary_string_get_size(const Eet_Dictionary *ed, int index); +const char *eet_dictionary_string_get_char(const Eet_Dictionary *ed, int index); +int eet_dictionary_string_get_float(const Eet_Dictionary *ed, int index, float *result); +int eet_dictionary_string_get_double(const Eet_Dictionary *ed, int index, double *result); + FILE *_eet_memfile_read_open(const void *data, size_t size); void _eet_memfile_read_close(FILE *f); FILE *_eet_memfile_write_open(void **data, size_t *size); diff --git a/legacy/eet/src/lib/Makefile.am b/legacy/eet/src/lib/Makefile.am index 0a98bced53..fc72819062 100644 --- a/legacy/eet/src/lib/Makefile.am +++ b/legacy/eet/src/lib/Makefile.am @@ -15,6 +15,7 @@ eet_lib.c \ eet_data.c \ eet_image.c \ eet_memfile.c \ +eet_dictionary.c \ eet_utils.c \ Eet_private.h diff --git a/legacy/eet/src/lib/eet_data.c b/legacy/eet/src/lib/eet_data.c index 8f2fbe652d..8a12e2b011 100644 --- a/legacy/eet/src/lib/eet_data.c +++ b/legacy/eet/src/lib/eet_data.c @@ -1,7 +1,7 @@ #include -#include "Eet_private.h" #include "Eet.h" +#include "Eet_private.h" /* * routines for doing data -> struct and struct -> data conversion @@ -55,13 +55,14 @@ typedef struct _Eet_Data_Encode_Hash_Info Eet_Data_Encode_Hash_Info; struct _Eet_Data_Basic_Type_Decoder { int size; - int (*get) (const void *src, const void *src_end, void *dest); - void *(*put) (const void *src, int *size_ret); + int (*get) (const Eet_Dictionary *ed, const void *src, const void *src_end, void *dest); + void *(*put) (Eet_Dictionary *ed, const void *src, int *size_ret); }; struct _Eet_Data_Chunk { char *name; + int len; int size; void *data; unsigned char type; @@ -83,13 +84,15 @@ struct _Eet_Data_Descriptor_Hash struct _Eet_Data_Descriptor { - const char *name; - int size; + const char *name; + int size; struct { void *(*mem_alloc) (size_t size); void (*mem_free) (void *mem); char *(*str_alloc) (const char *str); + char *(*str_direct_alloc) (const char *str); void (*str_free) (const char *str); + void (*str_direct_free) (const char *str); void *(*list_next) (void *l); void *(*list_append) (void *l, void *d); void *(*list_data) (void *l); @@ -99,11 +102,11 @@ struct _Eet_Data_Descriptor void (*hash_free) (void *h); } func; struct { - int num; - Eet_Data_Element *set; + int num; + Eet_Data_Element *set; struct { - int size; - Eet_Data_Descriptor_Hash *buckets; + int size; + Eet_Data_Descriptor_Hash *buckets; } hash; } elements; // char *strings; @@ -123,31 +126,34 @@ struct _Eet_Data_Element struct _Eet_Data_Encode_Hash_Info { - Eet_Data_Stream *ds; - Eet_Data_Element *ede; + Eet_Data_Stream *ds; + Eet_Data_Element *ede; + Eet_Dictionary *ed; }; /*---*/ -static int eet_data_get_char(const void *src, const void *src_end, void *dest); -static void *eet_data_put_char(const void *src, int *size_ret); -static int eet_data_get_short(const void *src, const void *src_end, void *dest); -static void *eet_data_put_short(const void *src, int *size_ret); -static int eet_data_get_int(const void *src, const void *src_end, void *dest); -static void *eet_data_put_int(const void *src, int *size_ret); -static int eet_data_get_long_long(const void *src, const void *src_end, void *dest); -static void *eet_data_put_long_long(const void *src, int *size_ret); -static int eet_data_get_float(const void *src, const void *src_end, void *dest); -static void *eet_data_put_float(const void *src, int *size_ret); -static int eet_data_get_double(const void *src, const void *src_end, void *dest); -static void *eet_data_put_double(const void *src, int *size_ret); -static int eet_data_get_string(const void *src, const void *src_end, void *dest); -static void *eet_data_put_string(const void *src, int *size_ret); +static int eet_data_get_char(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dest); +static void *eet_data_put_char(Eet_Dictionary *ed, const void *src, int *size_ret); +static int eet_data_get_short(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dest); +static void *eet_data_put_short(Eet_Dictionary *ed, const void *src, int *size_ret); +static int eet_data_get_int(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dest); +static void *eet_data_put_int(Eet_Dictionary *ed, const void *src, int *size_ret); +static int eet_data_get_long_long(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dest); +static void *eet_data_put_long_long(Eet_Dictionary *ed, const void *src, int *size_ret); +static int eet_data_get_float(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dest); +static void *eet_data_put_float(Eet_Dictionary *ed, const void *src, int *size_ret); +static int eet_data_get_double(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dest); +static void *eet_data_put_double(Eet_Dictionary *ed, const void *src, int *size_ret); +static int eet_data_get_string(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dest); +static void *eet_data_put_string(Eet_Dictionary *ed, const void *src, int *size_ret); +static int eet_data_get_istring(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dest); +static void *eet_data_put_istring(Eet_Dictionary *ed, const void *src, int *size_ret); -static int eet_data_get_type(int type, const void *src, const void *src_end, void *dest); -static void *eet_data_put_type(int type, const void *src, int *size_ret); +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 void eet_data_chunk_get(Eet_Data_Chunk *chnk, const void *src, 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); @@ -155,9 +161,17 @@ static Eet_Data_Stream *eet_data_stream_new(void); static void eet_data_stream_write(Eet_Data_Stream *ds, const void *data, int size); 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 void eet_data_chunk_put(Eet_Dictionary *ed, 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); +static int eet_data_descriptor_encode_hash_cb(void *hash, const char *key, void *hdata, void *fdata); +static void *_eet_data_descriptor_encode(Eet_Dictionary *ed, Eet_Data_Descriptor *edd, const void *data_in, int *size_ret); +static void *_eet_data_descriptor_decode(const Eet_Dictionary *ed, + Eet_Data_Descriptor *edd, + const void *data_in, + int size_in, + int level, + void (*dumpfunc) (void *data, const char *str), + void *dumpdata); /*---*/ @@ -173,7 +187,8 @@ const Eet_Data_Basic_Type_Decoder eet_coder[] = {sizeof(short), eet_data_get_short, eet_data_put_short }, {sizeof(int), eet_data_get_int, eet_data_put_int }, {sizeof(long long), eet_data_get_long_long, eet_data_put_long_long}, - {sizeof(char *), eet_data_get_string, eet_data_put_string } + {sizeof(char *), eet_data_get_string, eet_data_put_string }, + {sizeof(char *), eet_data_get_istring, eet_data_put_istring } }; static int words_bigendian = -1; @@ -203,11 +218,13 @@ static int words_bigendian = -1; #define CONV32(x) {if (words_bigendian) SWAP32(x);} #define CONV64(x) {if (words_bigendian) SWAP64(x);} +#define IS_SIMPLE_TYPE(Type) (Type > EET_T_UNKNOW && Type < EET_T_LAST) + /*---*/ /* CHAR TYPE */ static int -eet_data_get_char(const void *src, const void *src_end, void *dst) +eet_data_get_char(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dst) { char *s, *d; @@ -220,7 +237,7 @@ eet_data_get_char(const void *src, const void *src_end, void *dst) } static void * -eet_data_put_char(const void *src, int *size_ret) +eet_data_put_char(Eet_Dictionary *ed, const void *src, int *size_ret) { char *s, *d; @@ -235,7 +252,7 @@ eet_data_put_char(const void *src, int *size_ret) /* SHORT TYPE */ static int -eet_data_get_short(const void *src, const void *src_end, void *dst) +eet_data_get_short(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dst) { short *d; @@ -247,7 +264,7 @@ eet_data_get_short(const void *src, const void *src_end, void *dst) } static void * -eet_data_put_short(const void *src, int *size_ret) +eet_data_put_short(Eet_Dictionary *ed, const void *src, int *size_ret) { short *s, *d; @@ -262,7 +279,7 @@ eet_data_put_short(const void *src, int *size_ret) /* INT TYPE */ static int -eet_data_get_int(const void *src, const void *src_end, void *dst) +eet_data_get_int(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dst) { int *d; @@ -274,7 +291,7 @@ eet_data_get_int(const void *src, const void *src_end, void *dst) } static void * -eet_data_put_int(const void *src, int *size_ret) +eet_data_put_int(Eet_Dictionary *ed, const void *src, int *size_ret) { int *s, *d; @@ -289,7 +306,7 @@ eet_data_put_int(const void *src, int *size_ret) /* LONG LONG TYPE */ static int -eet_data_get_long_long(const void *src, const void *src_end, void *dst) +eet_data_get_long_long(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dst) { unsigned long long *d; @@ -301,7 +318,7 @@ eet_data_get_long_long(const void *src, const void *src_end, void *dst) } static void * -eet_data_put_long_long(const void *src, int *size_ret) +eet_data_put_long_long(Eet_Dictionary *ed, const void *src, int *size_ret) { unsigned long long *s, *d; @@ -316,34 +333,57 @@ eet_data_put_long_long(const void *src, int *size_ret) /* STRING TYPE */ static int -eet_data_get_string(const void *src, const void *src_end, void *dst) +eet_data_get_string(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dst) { - char *s, **d, *p; - int len; + char *s, **d; + + d = (char **)dst; + + if (ed) + { + const char *str; + int index; + + if (eet_data_get_int(ed, src, src_end, &index) < 0) return -1; + + str = eet_dictionary_string_get_char(ed, index); + if (str == NULL) + return -1; + + *d = (char *) str; + return eet_dictionary_string_get_size(ed, index); + } s = (char *)src; - d = (char **)dst; - p = s; - len = 0; - while ((p < (char *)src_end) && (*p != 0)) {len++; p++;} - if (len == 0) + if (s == NULL) { - *d = NULL; - return 0; + *d = NULL; + return 0; } - *d = malloc(len + 1); - if (!(*d)) return -1; - memcpy(*d, s, len); - (*d)[len] = 0; - return len + 1; + + *d = s; + return strlen(s) + 1; } static void * -eet_data_put_string(const void *src, int *size_ret) +eet_data_put_string(Eet_Dictionary *ed, const void *src, int *size_ret) { char *s, *d; int len; - /* const char *empty_s = ""; */ + + if (ed) + { + const char *str; + int index; + + str = *((const char **) src); + if (!str) return NULL; + + index = eet_dictionary_string_add(ed, str); + if (index == -1) return NULL; + + return eet_data_put_int(ed, &index, size_ret); + } s = (char *)(*((char **)src)); if (!s) return NULL; @@ -355,6 +395,19 @@ eet_data_put_string(const void *src, int *size_ret) return d; } +/* ALWAYS INLINED STRING TYPE */ +static int +eet_data_get_istring(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dst) +{ + return eet_data_get_string(NULL, src, src_end, dst); +} + +static void * +eet_data_put_istring(Eet_Dictionary *ed, const void *src, int *size_ret) +{ + return eet_data_put_string(NULL, src, size_ret); +} + /** * Fast lookups of simple doubles/floats. * @@ -362,7 +415,7 @@ eet_data_put_string(const void *src, int *size_ret) * values, but have a so simple math that is almost as fast. */ static inline int -_eet_data_float_cache_get(char *s, int len, float *d) +_eet_data_float_cache_get(const char *s, int len, float *d) { /* fast handle of simple case 0xMp+E*/ if ((len == 6) && (s[0] == '0') && (s[1] == 'x') && (s[3] == 'p')) @@ -379,7 +432,7 @@ _eet_data_float_cache_get(char *s, int len, float *d) } static inline int -_eet_data_double_cache_get(char *s, int len, double *d) +_eet_data_double_cache_get(const char *s, int len, double *d) { /* fast handle of simple case 0xMp+E*/ if ((len == 6) && (s[0] == '0') && (s[1] == 'x') && (s[3] == 'p')) @@ -397,109 +450,145 @@ _eet_data_double_cache_get(char *s, int len, double *d) /* FLOAT TYPE */ static int -eet_data_get_float(const void *src, const void *src_end, void *dst) +eet_data_get_float(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dst) { - float *d; - long long mantisse; - long exponent; - char *s, *str, *p; - int len; + float *d; + int index; - s = (char *)src; - d = (float *)dst; - p = s; - len = 0; - while ((p < (char *)src_end) && (*p != 0)) {len++; p++;} + d = (float *) dst; + if (!ed) + { + const char *s, *p; + long long mantisse; + long exponent; + int len; - if (_eet_data_float_cache_get(s, len, d) != 0) return len + 1; + s = (const char *)src; + p = s; + len = 0; + while ((p < (const char *)src_end) && (*p != 0)) {len++; p++;} - str = alloca(len + 1); - memcpy(str, s, len); - str[len] = '\0'; + if (_eet_data_float_cache_get(s, len, d) != 0) return len + 1; - _eet_string_to_double_convert(str, &mantisse, &exponent); - *d = (float)ldexp((double)mantisse, exponent); - - return len + 1; + _eet_string_to_double_convert(s, &mantisse, &exponent); + *d = (float)ldexp((double)mantisse, exponent); + + return len + 1; + } + + if (eet_data_get_int(ed, src, src_end, &index) < 0) return -1; + + if (!eet_dictionary_string_get_float(ed, index, d)) + return -1; + return 1; } static void * -eet_data_put_float(const void *src, int *size_ret) +eet_data_put_float(Eet_Dictionary *ed, const void *src, int *size_ret) { - char buf[64]; - char *d; - int len; + char buf[64]; + int index; _eet_double_to_string_convert(buf, (double)(*(float *)src)); - len = strlen(buf); - d = malloc(len + 1); - if (!d) return NULL; - strcpy(d, buf); - *size_ret = len + 1; - return d; + if (!ed) + { + char *d; + int len; + + len = strlen(buf); + d = malloc(len + 1); + if (!d) return NULL; + strcpy(d, buf); + *size_ret = len + 1; + return d; + } + + index = eet_dictionary_string_add(ed, buf); + if (index == -1) return NULL; + + return eet_data_put_int(ed, &index, size_ret); } /* DOUBLE TYPE */ static int -eet_data_get_double(const void *src, const void *src_end, void *dst) +eet_data_get_double(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dst) { - double *d; - long long mantisse = 0; - long exponent = 0; - char *s, *str, *p; - int len; + double *d; + int index; - s = (char *)src; - d = (double *)dst; - p = s; - len = 0; - while ((p < (char *)src_end) && (*p != 0)) {len++; p++;} + d = (double *) dst; - if (_eet_data_double_cache_get(s, len, d) != 0) return len + 1; + if (!ed) + { + const char *s, *p; + long long mantisse = 0; + long exponent = 0; + int len; - str = alloca(len + 1); - memcpy(str, s, len); - str[len] = '\0'; + s = (const char *) src; + p = s; + len = 0; + while ((p < (const char *)src_end) && (*p != 0)) {len++; p++;} - _eet_string_to_double_convert(str, &mantisse, &exponent); - *d = ldexp((double)mantisse, exponent); + if (_eet_data_double_cache_get(s, len, d) != 0) return len + 1; - return len + 1; + _eet_string_to_double_convert(s, &mantisse, &exponent); + *d = ldexp((double) mantisse, exponent); + + return len + 1; + } + + if (eet_data_get_int(ed, src, src_end, &index) < 0) return -1; + + if (!eet_dictionary_string_get_double(ed, index, d)) + return -1; + return 1; } static void * -eet_data_put_double(const void *src, int *size_ret) +eet_data_put_double(Eet_Dictionary *ed, const void *src, int *size_ret) { - char buf[128]; - char *d; - int len; + char buf[128]; + int index; _eet_double_to_string_convert(buf, (double)(*(double *)src)); - len = strlen(buf); - d = malloc(len + 1); - if (!d) return NULL; - strcpy(d, buf); - *size_ret = len + 1; - return d; + if (!ed) + { + char *d; + int len; + + len = strlen(buf); + d = malloc(len + 1); + if (!d) return NULL; + strcpy(d, buf); + *size_ret = len + 1; + + return d; + } + + index = eet_dictionary_string_add(ed, buf); + if (index == -1) return NULL; + + return eet_data_put_int(ed, &index, size_ret); } static int -eet_data_get_type(int type, const void *src, const void *src_end, void *dest) +eet_data_get_type(const Eet_Dictionary *ed, int type, const void *src, const void *src_end, void *dest) { int ret; - ret = eet_coder[type - 1].get(src, src_end, dest); + ret = eet_coder[type - 1].get(ed, src, src_end, dest); return ret; } static void * -eet_data_put_type(int type, const void *src, int *size_ret) +eet_data_put_type(Eet_Dictionary *ed, int type, const void *src, int *size_ret) { void *ret; - ret = eet_coder[type - 1].put(src, size_ret); + ret = eet_coder[type - 1].put(ed, src, size_ret); return ret; } @@ -517,7 +606,7 @@ 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) +eet_data_chunk_get(const Eet_Dictionary *ed, Eet_Data_Chunk *chnk, const void *src, int size) { const char *s; int ret1, ret2; @@ -556,7 +645,7 @@ eet_data_chunk_get(Eet_Data_Chunk *chnk, const void *src, int size) return; } } - ret1 = eet_data_get_type(EET_T_INT, (s + 4), (s + size), &(chnk->size)); + ret1 = eet_data_get_type(ed, EET_T_INT, (s + 4), (s + size), &(chnk->size)); if (ret1 <= 0) { return; @@ -565,13 +654,24 @@ eet_data_chunk_get(Eet_Data_Chunk *chnk, const void *src, int size) { return; } - ret2 = eet_data_get_type(EET_T_STRING, (s + 8), (s + size), &(chnk->name)); + ret2 = eet_data_get_type(ed, EET_T_STRING, (s + 8), (s + size), &(chnk->name)); if (ret2 <= 0) { return; } - chnk->data = (char *)src + 4 + ret1 + ret2; - chnk->size -= ret2; + + chnk->len = ret2; + if (ed) + { + chnk->data = (char *)src + 4 + ret1 + sizeof(int); + chnk->size -= sizeof(int); + } + else + { + chnk->data = (char *)src + 4 + ret1 + chnk->len; + chnk->size -= chnk->len; + } + return; } @@ -585,6 +685,7 @@ eet_data_chunk_new(void *data, int size, const char *name, int type, int group_t if (!chnk) return NULL; chnk->name = strdup(name); + chnk->len = strlen(name) + 1; chnk->size = size; chnk->data = data; chnk->type = type; @@ -638,32 +739,48 @@ eet_data_stream_write(Eet_Data_Stream *ds, const void *data, int size) } static void -eet_data_chunk_put(Eet_Data_Chunk *chnk, Eet_Data_Stream *ds) +eet_data_chunk_put(Eet_Dictionary *ed, Eet_Data_Chunk *chnk, Eet_Data_Stream *ds) { - int *size; - int s; - int size_ret = 0; + int *size; + void *string; + int s; + int size_ret = 0; + int string_ret = 0; unsigned char buf[4] = "CHK"; - + if (!chnk->data) return; /* chunk head */ - + /* eet_data_stream_write(ds, "CHnK", 4);*/ if (chnk->type != EET_T_UNKNOW) buf[3] = chnk->type; else buf[3] = chnk->group_type; - eet_data_stream_write(ds, buf, 4); + + string = eet_data_put_string(ed, &chnk->name, &string_ret); + if (!string) + return ; + /* size of chunk payload data + name */ - s = strlen(chnk->name) + 1 + chnk->size; - size = eet_data_put_int(&s, &size_ret); - if (size) - { - eet_data_stream_write(ds, size, size_ret); - free(size); - } + s = chnk->size + string_ret; + size = eet_data_put_int(ed, &s, &size_ret); + + /* FIXME: If something goes wrong the resulting file will be corrupted. */ + if (!size) + goto on_error; + + eet_data_stream_write(ds, buf, 4); + + /* write chunk length */ + eet_data_stream_write(ds, size, size_ret); + /* write chunk name */ - eet_data_stream_write(ds, chnk->name, strlen(chnk->name) + 1); + eet_data_stream_write(ds, string, string_ret); + /* write payload */ eet_data_stream_write(ds, chnk->data, chnk->size); + + free(string); + on_error: + free(size); } /*---*/ @@ -775,17 +892,16 @@ eet_data_descriptor_new(const char *name, Eet_Data_Descriptor *edd; if (!name) return NULL; -/* - edd = calloc(1, sizeof(Eet_Data_Descriptor) + strlen(name) + 1); - edd->name = ((char *)edd) + sizeof(Eet_Data_Descriptor); - strcpy(edd->name, name); - */ edd = calloc(1, sizeof(Eet_Data_Descriptor)); + if (!edd) return NULL; + edd->name = name; edd->size = size; edd->func.mem_alloc = _eet_mem_alloc; edd->func.mem_free = _eet_mem_free; edd->func.str_alloc = _eet_str_alloc; + edd->func.str_direct_alloc = NULL; + edd->func.str_direct_free = NULL; edd->func.str_free = _eet_str_free; edd->func.list_next = func_list_next; edd->func.list_append = func_list_append; @@ -804,8 +920,10 @@ eet_data_descriptor2_new(Eet_Data_Descriptor_Class *eddc) Eet_Data_Descriptor *edd; if (!eddc) return NULL; + if (eddc->version < 1) return NULL; edd = calloc(1, sizeof(Eet_Data_Descriptor)); - if (eddc->version < 1) return edd; + if (!edd) return NULL; + edd->name = eddc->name; edd->size = eddc->size; edd->func.mem_alloc = _eet_mem_alloc; @@ -827,6 +945,46 @@ eet_data_descriptor2_new(Eet_Data_Descriptor_Class *eddc) edd->func.hash_foreach = eddc->func.hash_foreach; edd->func.hash_add = eddc->func.hash_add; edd->func.hash_free = eddc->func.hash_free; + + return edd; +} + +EAPI Eet_Data_Descriptor * +eet_data_descriptor3_new(Eet_Data_Descriptor_Class *eddc) +{ + Eet_Data_Descriptor *edd; + + if (!eddc) return NULL; + if (eddc->version < 2) return NULL; + edd = calloc(1, sizeof(Eet_Data_Descriptor)); + if (!edd) return NULL; + + edd->name = eddc->name; + edd->size = eddc->size; + edd->func.mem_alloc = _eet_mem_alloc; + edd->func.mem_free = _eet_mem_free; + edd->func.str_alloc = _eet_str_alloc; + edd->func.str_free = _eet_str_free; + if (eddc->func.mem_alloc) + edd->func.mem_alloc = eddc->func.mem_alloc; + if (eddc->func.mem_free) + edd->func.mem_free = eddc->func.mem_free; + if (eddc->func.str_alloc) + edd->func.str_alloc = eddc->func.str_alloc; + if (eddc->func.str_free) + edd->func.str_free = eddc->func.str_free; + if (eddc->func.str_direct_alloc) + edd->func.str_direct_alloc = eddc->func.str_direct_alloc; + if (eddc->func.str_direct_free) + edd->func.str_direct_free = eddc->func.str_direct_free; + edd->func.list_next = eddc->func.list_next; + edd->func.list_append = eddc->func.list_append; + edd->func.list_data = eddc->func.list_data; + edd->func.list_free = eddc->func.list_free; + edd->func.hash_foreach = eddc->func.hash_foreach; + edd->func.hash_add = eddc->func.hash_add; + edd->func.hash_free = eddc->func.hash_free; + return edd; } @@ -834,7 +992,6 @@ EAPI void eet_data_descriptor_free(Eet_Data_Descriptor *edd) { _eet_descriptor_hash_free(edd); -// if (edd->strings) free(edd->strings); if (edd->elements.set) free(edd->elements.set); free(edd); } @@ -855,71 +1012,39 @@ eet_data_descriptor_element_add(Eet_Data_Descriptor *edd, edd->elements.set = realloc(edd->elements.set, edd->elements.num * sizeof(Eet_Data_Element)); if (!edd->elements.set) return; ede = &(edd->elements.set[edd->elements.num - 1]); -/* - l1 = strlen(name); - p1 = edd->strings_len; - if (counter_name) - { - l2 = strlen(counter_name); - p2 = p1 + l1 + 1; - } - else l2 = -1; - ps = edd->strings; - edd->strings_len += l1 + 1 + l2 + 1; - edd->strings = realloc(edd->strings, edd->strings_len); - if (!edd->strings) - { - edd->strings = ps; - return; - } - for (i = 0; i < edd->elements.num; i++) - { - edd->elements.set[i].name = - edd->strings + (edd->elements.set[i].name - ps); - if (edd->elements.set[i].counter_name) - edd->elements.set[i].counter_name = - edd->strings + (edd->elements.set[i].counter_name - ps); - } - ede->name = edd->strings + p1; - strcpy(ede->name, name); - */ ede->name = name; - + ede->type = type; ede->group_type = group_type; ede->offset = offset; ede->count = count; -/* - if (counter_name) - { - ede->counter_name = edd->strings + p2; - strcpy(ede->counter_name, counter_name); - } - else ede->counter_name = NULL; - */ ede->counter_name = counter_name; - + ede->subtype = subtype; } EAPI void * eet_data_read(Eet_File *ef, Eet_Data_Descriptor *edd, const char *name) { - void *data_dec; - void *data; - int size; - int required_free = 0; + const Eet_Dictionary *ed = NULL; + const void *data; + void *data_dec; + int size; + int required_free = 0; - data = (void *)eet_read_direct(ef, name, &size); + ed = eet_dictionary_get(ef); + + data = eet_read_direct(ef, name, &size); if (!data) { required_free = 1; data = eet_read(ef, name, &size); if (!data) return NULL; } - data_dec = eet_data_descriptor_decode(edd, data, size); + + data_dec = _eet_data_descriptor_decode(ed, edd, data, size, 0, NULL, NULL); if (required_free) - free(data); + free((void*)data); return data_dec; } @@ -927,227 +1052,205 @@ eet_data_read(Eet_File *ef, Eet_Data_Descriptor *edd, const char *name) EAPI int eet_data_write(Eet_File *ef, Eet_Data_Descriptor *edd, const char *name, const void *data, int compress) { - void *data_enc; - int size; - int val; + Eet_Dictionary *ed; + void *data_enc; + int size; + int val; - data_enc = eet_data_descriptor_encode(edd, data, &size); + ed = eet_dictionary_get(ef); + + data_enc = _eet_data_descriptor_encode(ed, edd, data, &size); if (!data_enc) return 0; val = eet_write(ef, name, data_enc, size, compress); free(data_enc); return val; } -static int freelist_ref = 0; -static int freelist_len = 0; -static int freelist_num = 0; -static void **freelist = NULL; +typedef struct _Eet_Free Eet_Free; +struct _Eet_Free +{ + int ref; + int len; + int num; + void **list; +}; static void -_eet_freelist_add(void *data) +_eet_free_add(Eet_Free *ef, void *data) { - freelist_num++; - if (freelist_num > freelist_len) + int i; + + for (i = 0; i < ef->num; ++i) + if (ef->list[i] == data) return; + + ef->num++; + if (ef->num > ef->len) { - freelist_len += 16; - freelist = realloc(freelist, freelist_len * sizeof(void *)); + void **tmp; + + tmp = realloc(ef->list, (ef->len + 16) * sizeof(void*)); + if (!tmp) return ; + + ef->len += 16; + ef->list = tmp; } - freelist[freelist_num - 1] = data; + ef->list[ef->num - 1] = data; +} +static void +_eet_free_reset(Eet_Free *ef) +{ + if (ef->ref > 0) return ; + ef->len = 0; + ef->num = 0; + if (ef->list) free(ef->list); + ef->list = NULL; +} +static void +_eet_free_ref(Eet_Free *ef) +{ + ef->ref++; +} +static void +_eet_free_unref(Eet_Free *ef) +{ + ef->ref--; } -static void -_eet_freelist_reset(void) -{ - if (freelist_ref > 0) return; - freelist_len = 0; - freelist_num = 0; - if (freelist) free(freelist); - freelist = NULL; -} +static Eet_Free freelist = { 0, 0, 0, NULL }; + +#define _eet_freelist_add(Data) _eet_free_add(&freelist, Data); +#define _eet_freelist_reset() _eet_free_reset(&freelist); +#define _eet_freelist_ref() _eet_free_ref(&freelist); +#define _eet_freelist_unref() _eet_free_unref(&freelist); static void _eet_freelist_free(Eet_Data_Descriptor *edd) { int i; - if (freelist_ref > 0) return; - for (i = 0; i < freelist_num; i++) + if (freelist.ref > 0) return; + for (i = 0; i < freelist.num; i++) { if (edd) - edd->func.mem_free(freelist[i]); + edd->func.mem_free(freelist.list[i]); else - free(freelist[i]); + free(freelist.list[i]); } - _eet_freelist_reset(); + _eet_free_reset(&freelist); } -static void -_eet_freelist_ref(void) -{ - freelist_ref++; -} +static Eet_Free freelist_list = { 0, 0, 0, NULL }; -static void -_eet_freelist_unref(void) -{ - freelist_ref--; -} - -static int freelist_list_ref = 0; -static int freelist_list_len = 0; -static int freelist_list_num = 0; -static void ***freelist_list = NULL; - -static void -_eet_freelist_list_add(void **data) -{ - int i; - - for (i = 0; i < freelist_list_num; i++) - { - if (freelist_list[i] == data) return; - } - freelist_list_num++; - if (freelist_list_num > freelist_list_len) - { - freelist_list_len += 16; - freelist_list = realloc(freelist_list, freelist_list_len * sizeof(void *)); - } - freelist_list[freelist_list_num - 1] = data; -} - -static void -_eet_freelist_list_reset(void) -{ - if (freelist_list_ref > 0) return; - freelist_list_len = 0; - freelist_list_num = 0; - if (freelist_list) free(freelist_list); - freelist_list = NULL; -} +#define _eet_freelist_list_add(Data) _eet_free_add(&freelist_list, Data); +#define _eet_freelist_list_reset() _eet_free_reset(&freelist_list); +#define _eet_freelist_list_ref() _eet_free_ref(&freelist_list); +#define _eet_freelist_list_unref() _eet_free_unref(&freelist_list); static void _eet_freelist_list_free(Eet_Data_Descriptor *edd) { int i; - if (freelist_list_ref > 0) return; - for (i = 0; i < freelist_list_num; i++) + if (freelist_list.ref > 0) return; + for (i = 0; i < freelist_list.num; i++) { if (edd) - edd->func.list_free(*(freelist_list[i])); + edd->func.list_free(*((void**)(freelist_list.list[i]))); } - _eet_freelist_list_reset(); + _eet_free_reset(&freelist_list); } -static void -_eet_freelist_list_ref(void) -{ - freelist_list_ref++; -} +static Eet_Free freelist_str = { 0, 0, 0, NULL }; -static void -_eet_freelist_list_unref(void) -{ - freelist_list_ref--; -} - -static int freelist_str_ref = 0; -static int freelist_str_len = 0; -static int freelist_str_num = 0; -static void **freelist_str = NULL; - -static void -_eet_freelist_str_add(void *data) -{ - freelist_str_num++; - if (freelist_str_num > freelist_str_len) - { - freelist_str_len += 16; - freelist_str = realloc(freelist_str, freelist_str_len * sizeof(void *)); - } - freelist_str[freelist_str_num - 1] = data; -} - -static void -_eet_freelist_str_reset(void) -{ - if (freelist_str_ref > 0) return; - freelist_str_len = 0; - freelist_str_num = 0; - if (freelist_str) free(freelist_str); - freelist_str = NULL; -} +#define _eet_freelist_str_add(Data) _eet_free_add(&freelist_str, Data); +#define _eet_freelist_str_reset() _eet_free_reset(&freelist_str); +#define _eet_freelist_str_ref() _eet_free_ref(&freelist_str); +#define _eet_freelist_str_unref() _eet_free_unref(&freelist_str); static void _eet_freelist_str_free(Eet_Data_Descriptor *edd) { int i; - if (freelist_str_ref > 0) return; - for (i = 0; i < freelist_str_num; i++) + if (freelist_str.ref > 0) return; + for (i = 0; i < freelist_str.num; i++) { if (edd) - edd->func.str_free(freelist_str[i]); + edd->func.str_free(freelist_str.list[i]); else - free(freelist_str[i]); + free(freelist_str.list[i]); } - _eet_freelist_str_reset(); + _eet_free_reset(&freelist_str); } -static void -_eet_freelist_str_ref(void) -{ - freelist_str_ref++; -} +static Eet_Free freelist_direct_str = { 0, 0, 0, NULL }; + +#define _eet_freelist_direct_str_add(Data) _eet_free_add(&freelist_direct_str, Data); +#define _eet_freelist_direct_str_reset() _eet_free_reset(&freelist_direct_str); +#define _eet_freelist_direct_str_ref() _eet_free_ref(&freelist_direct_str); +#define _eet_freelist_direct_str_unref() _eet_free_unref(&freelist_direct_str); static void -_eet_freelist_str_unref(void) +_eet_freelist_direct_str_free(Eet_Data_Descriptor *edd) { - freelist_str_ref--; + int i; + + if (freelist_str.ref > 0) return; + for (i = 0; i < freelist_str.num; i++) + { + if (edd) + edd->func.str_direct_free(freelist_str.list[i]); + else + free(freelist_str.list[i]); + } + _eet_free_reset(&freelist_str); } 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; + Eet_Dictionary *ed; + 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; + ed = edehi->ed; /* Store key */ - data = eet_data_put_type(EET_T_STRING, + data = eet_data_put_type(ed, + EET_T_STRING, &key, &size); if (data) { echnk = eet_data_chunk_new(data, size, ede->name, ede->type, ede->group_type); - eet_data_chunk_put(echnk, ds); + eet_data_chunk_put(ed, 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, + if (IS_SIMPLE_TYPE(ede->type)) + data = eet_data_put_type(ed, + ede->type, hdata, &size); else if (ede->subtype) - data = eet_data_descriptor_encode(ede->subtype, - hdata, - &size); + data = _eet_data_descriptor_encode(ed, + ede->subtype, + hdata, + &size); if (data) { echnk = eet_data_chunk_new(data, size, ede->name, ede->type, ede->group_type); - eet_data_chunk_put(echnk, ds); + eet_data_chunk_put(ed, echnk, ds); eet_data_chunk_free(echnk); free(data); data = NULL; @@ -1344,7 +1447,8 @@ _eet_data_dump_free(Node *node) } static void * -_eet_data_dump_encode(Node *node, +_eet_data_dump_encode(Eet_Dictionary *ed, + Node *node, int *size_ret) { Eet_Data_Chunk *chnk = NULL, *echnk = NULL; @@ -1361,7 +1465,7 @@ _eet_data_dump_encode(Node *node, if (v == 0x12345678) words_bigendian = 1; else words_bigendian = 0; } - + ds = eet_data_stream_new(); if (!ds) return NULL; @@ -1370,7 +1474,7 @@ _eet_data_dump_encode(Node *node, case EET_G_UNKNOWN: for (n = node->values; n; n = n->next) { - data = _eet_data_dump_encode(n, &size); + data = _eet_data_dump_encode(ed, n, &size); if (data) { eet_data_stream_write(ds, data, size); @@ -1381,7 +1485,7 @@ _eet_data_dump_encode(Node *node, case EET_G_ARRAY: for (n = node->values; n; n = n->next) { - data = _eet_data_dump_encode(n, &size); + data = _eet_data_dump_encode(ed, n, &size); if (data) { eet_data_stream_write(ds, data, size); @@ -1392,7 +1496,7 @@ _eet_data_dump_encode(Node *node, case EET_G_VAR_ARRAY: for (n = node->values; n; n = n->next) { - data = _eet_data_dump_encode(n, &size); + data = _eet_data_dump_encode(ed, n, &size); if (data) { eet_data_stream_write(ds, data, size); @@ -1403,7 +1507,7 @@ _eet_data_dump_encode(Node *node, case EET_G_LIST: for (n = node->values; n; n = n->next) { - data = _eet_data_dump_encode(n, &size); + data = _eet_data_dump_encode(ed, n, &size); if (data) { eet_data_stream_write(ds, data, size); @@ -1414,20 +1518,21 @@ _eet_data_dump_encode(Node *node, case EET_G_HASH: if (node->key) { - data = eet_data_put_type(EET_T_STRING, + data = eet_data_put_type(ed, + EET_T_STRING, &node->key, &size); if (data) { echnk = eet_data_chunk_new(data, size, node->name, node->type, node->type); - eet_data_chunk_put(echnk, ds); + eet_data_chunk_put(ed, echnk, ds); eet_data_chunk_free(echnk); free(data); } } for (n = node->values; n; n = n->next) { - data = _eet_data_dump_encode(n, &size); + data = _eet_data_dump_encode(ed, n, &size); if (data) { eet_data_stream_write(ds, data, size); @@ -1436,7 +1541,7 @@ _eet_data_dump_encode(Node *node, } break; case EET_T_CHAR: - data = eet_data_put_type(node->type, &(node->data.c), &size); + data = eet_data_put_type(ed, node->type, &(node->data.c), &size); if (data) { eet_data_stream_write(ds, data, size); @@ -1444,7 +1549,7 @@ _eet_data_dump_encode(Node *node, } break; case EET_T_SHORT: - data = eet_data_put_type(node->type, &(node->data.s), &size); + data = eet_data_put_type(ed, node->type, &(node->data.s), &size); if (data) { eet_data_stream_write(ds, data, size); @@ -1452,7 +1557,7 @@ _eet_data_dump_encode(Node *node, } break; case EET_T_INT: - data = eet_data_put_type(node->type, &(node->data.i), &size); + data = eet_data_put_type(ed, node->type, &(node->data.i), &size); if (data) { eet_data_stream_write(ds, data, size); @@ -1460,7 +1565,7 @@ _eet_data_dump_encode(Node *node, } break; case EET_T_LONG_LONG: - data = eet_data_put_type(node->type, &(node->data.l), &size); + data = eet_data_put_type(ed, node->type, &(node->data.l), &size); if (data) { eet_data_stream_write(ds, data, size); @@ -1468,7 +1573,7 @@ _eet_data_dump_encode(Node *node, } break; case EET_T_FLOAT: - data = eet_data_put_type(node->type, &(node->data.f), &size); + data = eet_data_put_type(ed, node->type, &(node->data.f), &size); if (data) { eet_data_stream_write(ds, data, size); @@ -1476,7 +1581,7 @@ _eet_data_dump_encode(Node *node, } break; case EET_T_DOUBLE: - data = eet_data_put_type(node->type, &(node->data.d), &size); + data = eet_data_put_type(ed, node->type, &(node->data.d), &size); if (data) { eet_data_stream_write(ds, data, size); @@ -1484,7 +1589,7 @@ _eet_data_dump_encode(Node *node, } break; case EET_T_UCHAR: - data = eet_data_put_type(node->type, &(node->data.uc), &size); + data = eet_data_put_type(ed, node->type, &(node->data.uc), &size); if (data) { eet_data_stream_write(ds, data, size); @@ -1492,7 +1597,7 @@ _eet_data_dump_encode(Node *node, } break; case EET_T_USHORT: - data = eet_data_put_type(node->type, &(node->data.us), &size); + data = eet_data_put_type(ed, node->type, &(node->data.us), &size); if (data) { eet_data_stream_write(ds, data, size); @@ -1500,7 +1605,7 @@ _eet_data_dump_encode(Node *node, } break; case EET_T_UINT: - data = eet_data_put_type(node->type, &(node->data.ui), &size); + data = eet_data_put_type(ed, node->type, &(node->data.ui), &size); if (data) { eet_data_stream_write(ds, data, size); @@ -1508,7 +1613,7 @@ _eet_data_dump_encode(Node *node, } break; case EET_T_ULONG_LONG: - data = eet_data_put_type(node->type, &(node->data.ul), &size); + data = eet_data_put_type(ed, node->type, &(node->data.ul), &size); if (data) { eet_data_stream_write(ds, data, size); @@ -1516,7 +1621,7 @@ _eet_data_dump_encode(Node *node, } break; case EET_T_STRING: - data = eet_data_put_type(node->type, &(node->data.str), &size); + data = eet_data_put_type(ed, node->type, &(node->data.str), &size); if (data) { eet_data_stream_write(ds, data, size); @@ -1536,7 +1641,7 @@ _eet_data_dump_encode(Node *node, eet_data_stream_free(ds); ds = eet_data_stream_new(); - eet_data_chunk_put(chnk, ds); + eet_data_chunk_put(ed, chnk, ds); cdata = ds->data; csize = ds->pos; @@ -1552,7 +1657,8 @@ _eet_data_dump_encode(Node *node, } static void * -_eet_data_dump_parse(int *size_ret, +_eet_data_dump_parse(Eet_Dictionary *ed, + int *size_ret, const char *src, int size) { @@ -1767,14 +1873,23 @@ _eet_data_dump_parse(int *size_ret, if (node_base) { - cdata = _eet_data_dump_encode(node_base, size_ret); + cdata = _eet_data_dump_encode(ed, node_base, size_ret); _eet_data_dump_free(node_base); } return cdata; } +#define NEXT_CHUNK(P, Size, Echnk, Ed) \ + { \ + int tmp; \ + tmp = Ed ? sizeof (int) * 2 : Echnk.len + 4; \ + P += (4 + Echnk.size + tmp); \ + Size -= (4 + Echnk.size + tmp); \ + } + static void * -_eet_data_descriptor_decode(Eet_Data_Descriptor *edd, +_eet_data_descriptor_decode(const Eet_Dictionary *ed, + Eet_Data_Descriptor *edd, const void *data_in, int size_in, int level, @@ -1806,14 +1921,17 @@ _eet_data_descriptor_decode(Eet_Data_Descriptor *edd, if (data) _eet_freelist_add(data); dump = 0; memset(&chnk, 0, sizeof(Eet_Data_Chunk)); - eet_data_chunk_get(&chnk, data_in, size_in); + eet_data_chunk_get(ed, &chnk, data_in, size_in); if (!chnk.name) goto error; if (edd) { if (strcmp(chnk.name, edd->name)) goto error; } p = chnk.data; - size = size_in - (4 + 4 + strlen(chnk.name) + 1); + if (ed) + size = size_in - (4 + sizeof(int) * 2); + else + size = size_in - (4 + 4 + chnk.len); if (edd) { if (!edd->elements.hash.buckets) _eet_descriptor_hash_new(edd); @@ -1855,7 +1973,7 @@ _eet_data_descriptor_decode(Eet_Data_Descriptor *edd, /* get next data chunk */ memset(&echnk, 0, sizeof(Eet_Data_Chunk)); - eet_data_chunk_get(&echnk, p, size); + eet_data_chunk_get(ed, &echnk, p, size); if (!echnk.name) goto error; /* FIXME: don't REPLY on edd - work without */ if ((edd) && (!dumpfunc)) @@ -1888,24 +2006,31 @@ _eet_data_descriptor_decode(Eet_Data_Descriptor *edd, int ret; void *data_ret; - if ((type >= EET_T_CHAR) && - (type <= EET_T_STRING)) + if (IS_SIMPLE_TYPE(type)) { - ret = eet_data_get_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, *str2; + char **str; str = (char **)(((char *)data) + ede->offset); if (*str) { - str2 = edd->func.str_alloc(*str); - free(*str); - *str = str2; - _eet_freelist_str_add(str2); + 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); + } } } } @@ -1913,7 +2038,8 @@ _eet_data_descriptor_decode(Eet_Data_Descriptor *edd, { void **ptr; - data_ret = _eet_data_descriptor_decode(ede->subtype, + data_ret = _eet_data_descriptor_decode(ed, + ede->subtype, echnk.data, echnk.size, level + 1, @@ -1944,14 +2070,14 @@ _eet_data_descriptor_decode(Eet_Data_Descriptor *edd, ptr = (void **)(((char *)data) + ede->offset); list = *ptr; data_ret = NULL; - if ((type >= EET_T_CHAR) && - (type <= EET_T_STRING)) + if (IS_SIMPLE_TYPE(type)) { data_ret = calloc(1, eet_coder[type].size); if (data_ret) { _eet_freelist_add(data_ret); - ret = eet_data_get_type(type, + ret = eet_data_get_type(ed, + type, echnk.data, ((char *)echnk.data) + echnk.size, data_ret); @@ -1961,7 +2087,8 @@ _eet_data_descriptor_decode(Eet_Data_Descriptor *edd, goto error; } else if (ede->subtype) - data_ret = _eet_data_descriptor_decode(ede->subtype, + data_ret = _eet_data_descriptor_decode(ed, + ede->subtype, echnk.data, echnk.size, level + 2, @@ -1989,29 +2116,28 @@ _eet_data_descriptor_decode(Eet_Data_Descriptor *edd, hash = *ptr; /* Read key */ - ret = eet_data_get_type(EET_T_STRING, + 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 */ - p += (4 + 4 + strlen(echnk.name) + 1 + echnk.size); - size -= (4 + 4 + strlen(echnk.name) + 1 + echnk.size); - free(echnk.name); + NEXT_CHUNK(p, size, echnk, ed); memset(&echnk, 0, sizeof(Eet_Data_Chunk)); /* Read value */ - eet_data_chunk_get(&echnk, p, size); + eet_data_chunk_get(ed, &echnk, p, size); if (!echnk.name) goto error; - if ((type >= EET_T_CHAR) && - (type <= EET_T_STRING)) + if (IS_SIMPLE_TYPE(type)) { data_ret = calloc(1, eet_coder[type].size); if (data_ret) { _eet_freelist_add(data_ret); - ret = eet_data_get_type(type, + ret = eet_data_get_type(ed, + type, echnk.data, ((char *)echnk.data) + echnk.size, data_ret); @@ -2022,7 +2148,8 @@ _eet_data_descriptor_decode(Eet_Data_Descriptor *edd, } else if (ede->subtype) { - data_ret = _eet_data_descriptor_decode(ede->subtype, + data_ret = _eet_data_descriptor_decode(ed, + ede->subtype, echnk.data, echnk.size, level + 2, @@ -2033,12 +2160,10 @@ _eet_data_descriptor_decode(Eet_Data_Descriptor *edd, { hash = edd->func.hash_add(hash, key, data_ret); *ptr = hash; - free(key); _eet_freelist_list_add(ptr); } else { - free(key); goto error; } } @@ -2066,10 +2191,10 @@ _eet_data_descriptor_decode(Eet_Data_Descriptor *edd, int ret; void *data_ret; - if ((type >= EET_T_CHAR) && - (type <= EET_T_STRING)) + if (IS_SIMPLE_TYPE(type)) { - ret = eet_data_get_type(type, + ret = eet_data_get_type(ed, + type, echnk.data, ((char *)echnk.data) + echnk.size, dd); @@ -2129,7 +2254,6 @@ _eet_data_descriptor_decode(Eet_Data_Descriptor *edd, dumpfunc(dumpdata, "string: \""); _eet_data_dump_string_escape(dumpdata, dumpfunc, s); dumpfunc(dumpdata, "\""); - free(s); } } break; @@ -2141,7 +2265,8 @@ _eet_data_descriptor_decode(Eet_Data_Descriptor *edd, } else { - data_ret = _eet_data_descriptor_decode(NULL, + data_ret = _eet_data_descriptor_decode(ed, + NULL, echnk.data, echnk.size, level + 1, @@ -2187,18 +2312,19 @@ _eet_data_descriptor_decode(Eet_Data_Descriptor *edd, void *data_ret; data_ret = NULL; - if ((type >= EET_T_CHAR) && - (type <= EET_T_STRING)) + if (IS_SIMPLE_TYPE(type)) { data_ret = (void *)1; - ret = eet_data_get_type(type, + ret = eet_data_get_type(ed, + type, echnk.data, ((char *)echnk.data) + echnk.size, dd); if (ret <= 0) goto error; } else - data_ret = _eet_data_descriptor_decode(NULL, + data_ret = _eet_data_descriptor_decode(ed, + NULL, echnk.data, echnk.size, level + 2, @@ -2215,26 +2341,25 @@ _eet_data_descriptor_decode(Eet_Data_Descriptor *edd, void *data_ret = NULL; /* Read key */ - ret = eet_data_get_type(EET_T_STRING, + 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 */ - p += (4 + 4 + strlen(echnk.name) + 1 + echnk.size); - size -= (4 + 4 + strlen(echnk.name) + 1 + echnk.size); - free(echnk.name); + NEXT_CHUNK(p, size, echnk, ed); memset(&echnk, 0, sizeof(Eet_Data_Chunk)); /* Read value */ - eet_data_chunk_get(&echnk, p, size); + eet_data_chunk_get(ed, &echnk, p, size); if (!echnk.name) goto error; - if ((type >= EET_T_CHAR) && - (type <= EET_T_STRING)) + if (IS_SIMPLE_TYPE(type)) { data_ret = (void *)1; - ret = eet_data_get_type(type, + ret = eet_data_get_type(ed, + type, echnk.data, ((char *)echnk.data) + echnk.size, dd); @@ -2252,18 +2377,16 @@ _eet_data_descriptor_decode(Eet_Data_Descriptor *edd, _eet_data_dump_string_escape(dumpdata, dumpfunc, s); dumpfunc(dumpdata, "\";\n"); } - data_ret = _eet_data_descriptor_decode(NULL, + data_ret = _eet_data_descriptor_decode(ed, + NULL, echnk.data, echnk.size, level + 2, dumpfunc, dumpdata); } - if (data_ret) - free(key); - else + if (!data_ret) { - free(key); goto error; } } @@ -2279,18 +2402,16 @@ _eet_data_descriptor_decode(Eet_Data_Descriptor *edd, } } /* 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); + NEXT_CHUNK(p, size, echnk, ed); } - free(chnk.name); _eet_freelist_unref(); _eet_freelist_str_unref(); _eet_freelist_list_unref(); if (dumpfunc) { _eet_freelist_str_free(edd); + _eet_freelist_direct_str_free(edd); _eet_freelist_list_free(edd); _eet_freelist_free(edd); } @@ -2315,11 +2436,11 @@ _eet_data_descriptor_decode(Eet_Data_Descriptor *edd, return data; error: - if (chnk.name) free(chnk.name); _eet_freelist_unref(); _eet_freelist_str_unref(); _eet_freelist_list_unref(); _eet_freelist_str_free(edd); + _eet_freelist_direct_str_free(edd); _eet_freelist_list_free(edd); _eet_freelist_free(edd); if (dumpfunc) @@ -2342,7 +2463,7 @@ eet_data_text_dump(const void *data_in, void (*dumpfunc) (void *data, const char *str), void *dumpdata) { - if (_eet_data_descriptor_decode(NULL, data_in, size_in, 0, + if (_eet_data_descriptor_decode(NULL, NULL, data_in, size_in, 0, dumpfunc, dumpdata)) return 1; return 0; @@ -2353,7 +2474,7 @@ eet_data_text_undump(const char *text, int textlen, int *size_ret) { - return _eet_data_dump_parse(size_ret, text, textlen); + return _eet_data_dump_parse(NULL, size_ret, text, textlen); } EAPI void * @@ -2361,19 +2482,21 @@ eet_data_descriptor_decode(Eet_Data_Descriptor *edd, const void *data_in, int size_in) { - return _eet_data_descriptor_decode(edd, data_in, size_in, 0, NULL, NULL); + return _eet_data_descriptor_decode(NULL, edd, data_in, size_in, 0, + NULL, NULL); } -EAPI void * -eet_data_descriptor_encode(Eet_Data_Descriptor *edd, - const void *data_in, - int *size_ret) +static void * +_eet_data_descriptor_encode(Eet_Dictionary *ed, + Eet_Data_Descriptor *edd, + const void *data_in, + int *size_ret) { - Eet_Data_Chunk *chnk; - Eet_Data_Stream *ds; - int i; - void *cdata; - int csize; + Eet_Data_Stream *ds; + Eet_Data_Chunk *chnk; + void *cdata; + int csize; + int i; if (words_bigendian == -1) { @@ -2396,22 +2519,23 @@ eet_data_descriptor_encode(Eet_Data_Descriptor *edd, 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, + 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(ede->subtype, - *((char **)(((char *)data_in) + ede->offset)), - &size); + 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(echnk, ds); + eet_data_chunk_put(ed, echnk, ds); eet_data_chunk_free(echnk); free(data); data = NULL; @@ -2434,19 +2558,20 @@ eet_data_descriptor_encode(Eet_Data_Descriptor *edd, 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, + if (IS_SIMPLE_TYPE(ede->type)) + data = eet_data_put_type(ed, + 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); + 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(echnk, ds); + eet_data_chunk_put(ed, echnk, ds); eet_data_chunk_free(echnk); free(data); data = NULL; @@ -2462,6 +2587,7 @@ eet_data_descriptor_encode(Eet_Data_Descriptor *edd, 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; @@ -2476,7 +2602,7 @@ eet_data_descriptor_encode(Eet_Data_Descriptor *edd, eet_data_stream_free(ds); ds = eet_data_stream_new(); - eet_data_chunk_put(chnk, ds); + eet_data_chunk_put(ed, chnk, ds); cdata = ds->data; csize = ds->pos; @@ -2490,3 +2616,11 @@ eet_data_descriptor_encode(Eet_Data_Descriptor *edd, return cdata; } + +EAPI void * +eet_data_descriptor_encode(Eet_Data_Descriptor *edd, + const void *data_in, + int *size_ret) +{ + return _eet_data_descriptor_encode(NULL, edd, data_in, size_ret); +} diff --git a/legacy/eet/src/lib/eet_image.c b/legacy/eet/src/lib/eet_image.c index 09d6fdd5dc..6b1eac5665 100644 --- a/legacy/eet/src/lib/eet_image.c +++ b/legacy/eet/src/lib/eet_image.c @@ -1,5 +1,5 @@ -#include "Eet_private.h" #include "Eet.h" +#include "Eet_private.h" /*---*/ @@ -728,10 +728,11 @@ eet_data_image_read(Eet_File *ef, const char *name, unsigned int *w, unsigned int *h, int *alpha, int *compress, int *quality, int *lossy) { - void *data; - int size; unsigned int *d = NULL; - int free_data = 0; + void *data; + int size; + int free_data = 0; + data = (void *)eet_read_direct(ef, name, &size); if (!data) diff --git a/legacy/eet/src/lib/eet_lib.c b/legacy/eet/src/lib/eet_lib.c index 324705fc89..3357267ea9 100644 --- a/legacy/eet/src/lib/eet_lib.c +++ b/legacy/eet/src/lib/eet_lib.c @@ -2,8 +2,8 @@ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2 */ -#include "Eet_private.h" #include "Eet.h" +#include "Eet_private.h" #include #ifdef HAVE_SYS_MMAN_H @@ -17,6 +17,8 @@ #define EET_MAGIC_FILE 0x1ee7ff00 #define EET_MAGIC_FILE_HEADER 0x1ee7ff01 +#define EET_MAGIC_FILE2 0x1ee70f42 + typedef struct _Eet_File_Header Eet_File_Header; typedef struct _Eet_File_Node Eet_File_Node; typedef struct _Eet_File_Directory Eet_File_Directory; @@ -27,6 +29,7 @@ struct _Eet_File FILE *fp; Eet_File_Header *header; const unsigned char *data; + Eet_Dictionary *ed; int magic; int references; @@ -53,19 +56,24 @@ struct _Eet_File_Directory struct _Eet_File_Node { - char *name; - void *data; - Eet_File_Node *next; /* FIXME: make buckets linked lists */ + char *name; + void *data; + Eet_File_Node *next; /* FIXME: make buckets linked lists */ - int offset; - int size; - int data_size; + int offset; + int dictionary_offset; + int name_offset; - unsigned char free_name : 1; - unsigned char compression : 1; + int name_size; + int size; + int data_size; + + unsigned char free_name : 1; + unsigned char compression : 1; }; #if 0 +/* Version 2 */ /* NB: all int's are stored in network byte order on disk */ /* file format: */ int magic; /* magic number ie 0x1ee7ff00 */ @@ -78,17 +86,54 @@ struct int size; /* size of the data chunk */ int data_size; /* size of the (uncompressed) data chunk */ int name_size; /* length in bytes of the name field */ - char name[name_size]; /* name string (variable length) */ + char name[name_size]; /* name string (variable length) and \0 terminated */ } directory[num_directory_entries]; /* and now startes the data stream... */ #endif +#if 0 +/* Version 3 */ +/* NB: all int's are stored in network byte order on disk */ +/* file format: */ +int magic; /* magic number ie 0x1ee70f42 */ +int num_directory_entries; /* number of directory entries to follow */ +int num_dictionary_entries; /* number of dictionary entries to follow */ +struct +{ + int data_offset; /* bytes offset into file for data chunk */ + int size; /* size of the data chunk */ + int data_size; /* size of the (uncompressed) data chunk */ + int name_offset; /* bytes offset into file for name string */ + int name_size; /* length in bytes of the name field */ + int flags; /* flags - for now 0 = uncompressed, 1 = compressed */ +} directory[num_directory_entries]; +struct +{ + int hash; + int offset; + int size; + int prev; + int next; +} dictionary[num_dictionary_entries]; +/* now start the string stream. */ +/* and right after them the data stream. */ +#endif + +#define EET_FILE2_HEADER_COUNT 3 +#define EET_FILE2_DIRECTORY_ENTRY_COUNT 6 +#define EET_FILE2_DICTIONARY_ENTRY_COUNT 5 + +#define EET_FILE2_HEADER_SIZE (sizeof(int) * EET_FILE2_HEADER_COUNT) +#define EET_FILE2_DIRECTORY_ENTRY_SIZE (sizeof(int) * EET_FILE2_DIRECTORY_ENTRY_COUNT) +#define EET_FILE2_DICTIONARY_ENTRY_SIZE (sizeof(int) * EET_FILE2_DICTIONARY_ENTRY_COUNT) + /* prototypes of internal calls */ static Eet_File *eet_cache_find(const char *path, Eet_File **cache, int cache_num); static void eet_cache_add(Eet_File *ef, Eet_File ***cache, int *cache_num, int *cache_alloc); static void eet_cache_del(Eet_File *ef, Eet_File ***cache, int *cache_num, int *cache_alloc); static int eet_string_match(const char *s1, const char *s2); static Eet_Error eet_flush(Eet_File *ef); +static Eet_Error eet_flush2(Eet_File *ef); static Eet_File_Node *find_node_by_name(Eet_File *ef, const char *name); static int read_data_from_disk(Eet_File *ef, Eet_File_Node *efn, void *buf, int len); @@ -263,6 +308,179 @@ eet_string_match(const char *s1, const char *s2) return (!strcmp(s1, s2)); } +/* flush out writes to a v2 eet file */ +static Eet_Error +eet_flush2(Eet_File *ef) +{ + Eet_File_Node *efn; + Eet_Error error = EET_ERROR_NONE; + int head[EET_FILE2_HEADER_COUNT]; + int num_directory_entries = 0; + int num_dictionary_entries = 0; + int bytes_directory_entries = 0; + int bytes_dictionary_entries = 0; + int bytes_strings = 0; + int data_offset = 0; + int strings_offset = 0; + int num; + int i; + int j; + + if (eet_check_pointer(ef)) + return EET_ERROR_BAD_OBJECT; + if (eet_check_header(ef)) + return EET_ERROR_EMPTY; + if ((ef->mode != EET_FILE_MODE_WRITE) && (ef->mode != EET_FILE_MODE_READ_WRITE)) + return EET_ERROR_NOT_WRITABLE; + if (!ef->writes_pending) + return EET_ERROR_NONE; + + /* calculate string base offset and data base offset */ + num = (1 << ef->header->directory->size); + for (i = 0; i < num; ++i) + { + for (efn = ef->header->directory->nodes[i]; efn; efn = efn->next) + { + num_directory_entries++; + bytes_strings += strlen(efn->name) + 1; + } + } + if (ef->ed) + { + num_dictionary_entries = ef->ed->count; + + for (i = 0; i < num_dictionary_entries; ++i) + bytes_strings += ef->ed->all[i].len; + } + + /* calculate section bytes size */ + bytes_directory_entries = EET_FILE2_DIRECTORY_ENTRY_SIZE * num_directory_entries + EET_FILE2_HEADER_SIZE; + bytes_dictionary_entries = EET_FILE2_DICTIONARY_ENTRY_SIZE * num_dictionary_entries; + + /* calculate per entry offset */ + strings_offset = bytes_directory_entries + bytes_dictionary_entries; + data_offset = bytes_directory_entries + bytes_dictionary_entries + bytes_strings; + + for (i = 0; i < num; ++i) + { + for (efn = ef->header->directory->nodes[i]; efn; efn = efn->next) + { + efn->offset = data_offset; + data_offset += efn->size; + + efn->name_offset = strings_offset; + strings_offset += efn->name_size; + } + } + + /* calculate dictionary strings offset */ + if (ef->ed) + ef->ed->offset = strings_offset; + + /* go thru and write the header */ + head[0] = (int) htonl ((unsigned int) EET_MAGIC_FILE2); + head[1] = (int) htonl ((unsigned int) num_directory_entries); + head[2] = (int) htonl ((unsigned int) num_dictionary_entries); + + fseek(ef->fp, 0, SEEK_SET); + if (fwrite(head, sizeof (head), 1, ef->fp) != 1) + goto write_error; + + /* write directories entry */ + j = 0; + for (i = 0; i < num; i++) + { + for (efn = ef->header->directory->nodes[i]; efn; efn = efn->next) + { + int ibuf[EET_FILE2_DIRECTORY_ENTRY_COUNT]; + + ibuf[0] = (int) htonl ((unsigned int) efn->offset); + ibuf[1] = (int) htonl ((unsigned int) efn->size); + ibuf[2] = (int) htonl ((unsigned int) efn->data_size); + ibuf[3] = (int) htonl ((unsigned int) efn->name_offset); + ibuf[4] = (int) htonl ((unsigned int) efn->name_size); + ibuf[5] = (int) htonl ((unsigned int) efn->compression); + + if (fwrite(ibuf, sizeof(ibuf), 1, ef->fp) != 1) + goto write_error; + } + } + + /* write dictionnary */ + if (ef->ed) + { + int offset = strings_offset; + + for (j = 0; j < ef->ed->count; ++j) + { + int sbuf[EET_FILE2_DICTIONARY_ENTRY_COUNT]; + + sbuf[0] = (int) htonl ((unsigned int) ef->ed->all[j].hash); + sbuf[1] = (int) htonl ((unsigned int) offset); + sbuf[2] = (int) htonl ((unsigned int) ef->ed->all[j].len); + sbuf[3] = (int) htonl ((unsigned int) ef->ed->all[j].prev); + sbuf[4] = (int) htonl ((unsigned int) ef->ed->all[j].next); + + offset += ef->ed->all[j].len; + + if (fwrite(sbuf, sizeof (sbuf), 1, ef->fp) != 1) + goto write_error; + } + } + + /* write directories name */ + for (i = 0; i < num; i++) + { + for (efn = ef->header->directory->nodes[i]; efn; efn = efn->next) + { + if (fwrite(efn->name, efn->name_size, 1, ef->fp) != 1) + goto write_error; + } + } + + /* write strings */ + if (ef->ed) + for (j = 0; j < ef->ed->count; ++j) + if (ef->ed->all[j].str) + { + if (fwrite(ef->ed->all[j].str, ef->ed->all[j].len, 1, ef->fp) != 1) + goto write_error; + } + else + { + if (fwrite(ef->ed->all[j].mmap, ef->ed->all[j].len, 1, ef->fp) != 1) + goto write_error; + } + + /* write data */ + for (i = 0; i < num; i++) + { + for (efn = ef->header->directory->nodes[i]; efn; efn = efn->next) + { + if (fwrite(efn->data, efn->size, 1, ef->fp) != 1) + goto write_error; + } + } + + /* no more writes pending */ + ef->writes_pending = 0; + + return EET_ERROR_NONE; + + write_error: + switch (ferror(ef->fp)) + { + case EFBIG: error = EET_ERROR_WRITE_ERROR_FILE_TOO_BIG; break; + case EIO: error = EET_ERROR_WRITE_ERROR_IO_ERROR; break; + case ENOSPC: error = EET_ERROR_WRITE_ERROR_OUT_OF_SPACE; break; + case EPIPE: error = EET_ERROR_WRITE_ERROR_FILE_CLOSED; break; + default: error = EET_ERROR_WRITE_ERROR; break; + } + fclose(ef->fp); + ef->fp = NULL; + return error; +} + /* flush out writes to an eet file */ static Eet_Error eet_flush(Eet_File *ef) @@ -454,21 +672,193 @@ eet_clearcache(void) } } +/* FIXME: MMAP race condition in READ_WRITE_MODE */ static Eet_File* -eet_internal_read(Eet_File *ef) +eet_internal_read2(Eet_File *ef) +{ + const int *data = (const int*) ef->data; + const char *start = (const char*) ef->data; + int index = 0; + int num_directory_entries; + int bytes_directory_entries; + int num_dictionary_entries; + int bytes_dictionary_entries; + int i; + + index += sizeof(int); + if (eet_test_close((int) ntohl(*data) != EET_MAGIC_FILE2, ef)) + return NULL; + data++; + +#define GET_INT(Value, Pointer, Index) \ + { \ + Value = ntohl(*Pointer); \ + Pointer++; \ + Index += sizeof(int); \ + } + + /* get entries count and byte count */ + GET_INT(num_directory_entries, data, index); + /* get dictionary count and byte count */ + GET_INT(num_dictionary_entries, data, index); + + bytes_directory_entries = EET_FILE2_DIRECTORY_ENTRY_SIZE * num_directory_entries + EET_FILE2_HEADER_SIZE; + bytes_dictionary_entries = EET_FILE2_DICTIONARY_ENTRY_SIZE * num_dictionary_entries; + + /* we cant have <= 0 values here - invalid */ + if (eet_test_close((num_directory_entries <= 0), ef)) + return NULL; + + /* we cant have more bytes directory and bytes in dictionaries than the size of the file */ + if (eet_test_close((bytes_directory_entries + bytes_dictionary_entries) > ef->data_size, ef)) + return NULL; + + /* allocate header */ + ef->header = calloc(1, sizeof(Eet_File_Header)); + if (eet_test_close(!ef->header, ef)) + return NULL; + + ef->header->magic = EET_MAGIC_FILE_HEADER; + + /* allocate directory block in ram */ + ef->header->directory = calloc(1, sizeof(Eet_File_Directory)); + if (eet_test_close(!ef->header->directory, ef)) + return NULL; + + /* 8 bit hash table (256 buckets) */ + ef->header->directory->size = 8; + /* allocate base hash table */ + ef->header->directory->nodes = calloc(1, sizeof(Eet_File_Node *) * (1 << ef->header->directory->size)); + if (eet_test_close(!ef->header->directory->nodes, ef)) + return NULL; + + /* actually read the directory block - all of it, into ram */ + for (i = 0; i < num_directory_entries; ++i) + { + const char *name; + Eet_File_Node *efn; + int name_offset; + int name_size; + int hash; + + /* out directory block is inconsistent - we have oveerun our */ + /* dynamic block buffer before we finished scanning dir entries */ + efn = malloc (sizeof(Eet_File_Node)); + if (eet_test_close(!efn, ef)) + return NULL; + + /* get entrie header */ + GET_INT(efn->offset, data, index); + GET_INT(efn->size, data, index); + GET_INT(efn->data_size, data, index); + GET_INT(name_offset, data, index); + GET_INT(name_size, data, index); + GET_INT(efn->compression, data, index); + +#define EFN_TEST(Test, Ef, Efn) \ + if (eet_test_close(Test, Ef)) \ + { \ + free(Efn); \ + return NULL; \ + } + + /* check data pointer position */ + EFN_TEST(!((efn->size > 0) + && (efn->offset + efn->size <= ef->data_size) + && (efn->offset > bytes_dictionary_entries + bytes_directory_entries)), ef, efn); + + /* check name position */ + EFN_TEST(!((name_size > 0) + && (name_offset + name_size < ef->data_size) + && (name_offset >= bytes_dictionary_entries + bytes_directory_entries)), ef, efn); + + name = start + name_offset; + + /* check '\0' at the end of name string */ + EFN_TEST(name[name_size - 1] != '\0', ef, efn); + + efn->free_name = 0; + efn->name = (char*) name; + efn->name_size = name_size; + + hash = _eet_hash_gen(efn->name, ef->header->directory->size); + efn->next = ef->header->directory->nodes[hash]; + ef->header->directory->nodes[hash] = efn; + + /* read-only mode, so currently we have no data loaded */ + if (ef->mode == EET_FILE_MODE_READ) + efn->data = NULL; + /* read-write mode - read everything into ram */ + else + { + efn->data = malloc(efn->size); + if (efn->data) + memcpy(efn->data, ef->data + efn->offset, efn->size); + } + } + + ef->ed = NULL; + + if (num_dictionary_entries) + { + const int *dico = (const int*) ef->data + EET_FILE2_DIRECTORY_ENTRY_COUNT * num_directory_entries + EET_FILE2_HEADER_COUNT; + int j; + + if (eet_test_close((num_directory_entries * EET_FILE2_DICTIONARY_ENTRY_SIZE + index) > (bytes_dictionary_entries + bytes_directory_entries), ef)) + return NULL; + + ef->ed = calloc(1, sizeof (Eet_Dictionary)); + if (eet_test_close(!ef->ed, ef)) return NULL; + + ef->ed->all = calloc(num_dictionary_entries, sizeof (Eet_String)); + if (eet_test_close(!ef->ed->all, ef)) return NULL; + + ef->ed->count = num_dictionary_entries; + + for (j = 0; j < ef->ed->count; ++j) + { + int hash; + int offset; + + GET_INT(hash, dico, index); + GET_INT(offset, dico, index); + GET_INT(ef->ed->all[j].len, dico, index); + GET_INT(ef->ed->all[j].prev, dico, index); + GET_INT(ef->ed->all[j].next, dico, index); + + /* Hash value could be stored on 8bits data, but this will break alignment of all the others data. + So stick to int and check the value. */ + if (eet_test_close(hash & 0xFFFFFF00, ef)) return NULL; + + /* Check string position */ + if (eet_test_close(!((ef->ed->all[j].len > 0) + && (offset > (bytes_dictionary_entries + bytes_directory_entries)) + && (offset + ef->ed->all[j].len < ef->data_size)), ef)) + return NULL; + + ef->ed->all[j].mmap = start + offset; + ef->ed->all[j].str = NULL; + + /* Check '\0' at the end of the string */ + if (eet_test_close(ef->ed->all[j].mmap[ef->ed->all[j].len - 1] != '\0', ef)) return NULL; + + if (ef->ed->all[j].prev == -1) + ef->ed->hash[hash] = j; + } + } + + return ef; +} + +static Eet_File* +eet_internal_read1(Eet_File *ef) { const unsigned char *dyn_buf = NULL; const unsigned char *p = NULL; - int index = 0; - int num_entries; - int byte_entries; - int i; - - if (eet_test_close((ef->data == (void *)-1) || (ef->data == NULL), ef)) - return NULL; - - if (eet_test_close(ef->data_size < sizeof(int) * 3, ef)) - return NULL; + int index = 0; + int num_entries; + int byte_entries; + int i; /* build header table if read mode */ /* geat header */ @@ -496,6 +886,10 @@ eet_internal_read(Eet_File *ef) if (eet_test_close((num_entries * 20) > byte_entries, ef)) return NULL; + /* check we will not outrun the file limit */ + if (eet_test_close(((byte_entries + sizeof(int) * 3) > ef->data_size), ef)) + return NULL; + /* allocate header */ ef->header = calloc(1, sizeof(Eet_File_Header)); if (eet_test_close(!ef->header, ef)) @@ -542,13 +936,15 @@ eet_internal_read(Eet_File *ef) if (eet_test_close(!efn, ef)) return NULL; - /* get entrie header */ + /* get entrie header */ EXTRACT_INT(efn->offset, p, indexn); EXTRACT_INT(efn->compression, p, indexn); EXTRACT_INT(efn->size, p, indexn); EXTRACT_INT(efn->data_size, p, indexn); EXTRACT_INT(name_size, p, indexn); + efn->name_size = name_size; + /* invalid size */ if (eet_test_close(efn->size <= 0, ef)) { @@ -616,6 +1012,32 @@ eet_internal_read(Eet_File *ef) return ef; } +static Eet_File* +eet_internal_read(Eet_File *ef) +{ + const int *data = (const int*) ef->data; + + if (eet_test_close((ef->data == (void *)-1) || (ef->data == NULL), ef)) + return NULL; + + if (eet_test_close(ef->data_size < sizeof(int) * 3, ef)) + return NULL; + + switch (ntohl(*data)) + { + case EET_MAGIC_FILE: + return eet_internal_read1(ef); + case EET_MAGIC_FILE2: + return eet_internal_read2(ef); + default: + ef->delete_me_now = 1; + eet_close(ef); + break; + } + + return NULL; +} + EAPI Eet_File * eet_memopen_read(const void *data, size_t size) { @@ -628,6 +1050,7 @@ eet_memopen_read(const void *data, size_t size) if (!ef) return NULL; + ef->ed = NULL; ef->path = NULL; ef->magic = EET_MAGIC_FILE; ef->references = 1; @@ -663,7 +1086,7 @@ eet_open(const char *file, Eet_File_Mode mode) ef = eet_cache_find((char *)file, eet_writers, eet_writers_num); if (ef) { - eet_flush(ef); + eet_flush2(ef); ef->delete_me_now = 1; eet_close(ef); } @@ -741,6 +1164,9 @@ eet_open(const char *file, Eet_File_Mode mode) ef->data = NULL; ef->data_size = 0; + /* FIXME: Add new ed on EET_FILE_MODE_WRITE */ + ef->ed = mode == EET_FILE_MODE_WRITE ? eet_dictionary_add() : NULL; + /* if we can't open - bail out */ if (eet_test_close(!ef->fp, ef)) return NULL; @@ -805,6 +1231,17 @@ eet_open(const char *file, Eet_File_Mode mode) } } } + + if (ef->ed) + { + for (i = 0; i < ef->ed->count; ++i) + if (ef->ed->all[i].mmap) + { + ef->ed->all[i].str = strdup(ef->ed->all[i].mmap); + ef->ed->all[i].mmap = NULL; + } + } + fclose(ef->fp); unlink(ef->path); ef->fp = fopen(ef->path, "wb"); @@ -846,7 +1283,7 @@ eet_close(Eet_File *ef) /* if its still referenced - dont go any further */ if (ef->references > 0) return EET_ERROR_NONE; /* flush any writes */ - err = eet_flush(ef); + err = eet_flush2(ef); /* if not urgent to delete it - dont free it - leave it in cache */ if ((!ef->delete_me_now) && (ef->mode == EET_FILE_MODE_READ)) @@ -892,6 +1329,8 @@ eet_close(Eet_File *ef) free(ef->header); } + eet_dictionary_free(ef->ed); + #ifndef _WIN32 if (ef->data) munmap((void*)ef->data, ef->data_size); #else @@ -1156,7 +1595,9 @@ eet_write(Eet_File *ef, const char *name, const void *data, int size, int compre return 0; } efn->name = strdup(name); - efn->free_name = 1; + efn->name_size = strlen(efn->name) + 1; + efn->free_name = 1; + efn->next = ef->header->directory->nodes[hash]; ef->header->directory->nodes[hash] = efn; efn->offset = 0; @@ -1210,6 +1651,8 @@ eet_delete(Eet_File *ef, const char *name) ef->header->directory->nodes[hash] = efn->next; else pefn->next = efn->next; + + if (efn->free_name) free(efn->name); free(efn); exists_already = 1; break; @@ -1223,6 +1666,15 @@ eet_delete(Eet_File *ef, const char *name) return exists_already; } +EAPI Eet_Dictionary* +eet_dictionary_get(Eet_File *ef) +{ + if (eet_check_pointer(ef)) return NULL; + + return ef->ed; +} + + EAPI char ** eet_list(Eet_File *ef, const char *glob, int *count_ret) { diff --git a/legacy/eet/src/lib/eet_memfile.c b/legacy/eet/src/lib/eet_memfile.c index 78c28fac6a..64fe3e9daa 100644 --- a/legacy/eet/src/lib/eet_memfile.c +++ b/legacy/eet/src/lib/eet_memfile.c @@ -1,5 +1,7 @@ -#include "Eet_private.h" +#define _GNU_SOURCE + #include "Eet.h" +#include "Eet_private.h" FILE * _eet_memfile_read_open(const void *data, size_t size) diff --git a/legacy/evas/src/modules/engines/software_x11/evas_outbuf.c b/legacy/evas/src/modules/engines/software_x11/evas_outbuf.c index d62f46f6d7..102f55f424 100644 --- a/legacy/evas/src/modules/engines/software_x11/evas_outbuf.c +++ b/legacy/evas/src/modules/engines/software_x11/evas_outbuf.c @@ -6,7 +6,8 @@ static Evas_List *shmpool = NULL; static int shmsize = 0; - +static int shmmemlimit = 10 * 1024 * 1024; +static int shmcountlimit = 32; static X_Output_Buffer * _find_xob(Display *d, Visual *v, int depth, int w, int h, int shm, void *data) { @@ -74,8 +75,8 @@ _unfind_xob(X_Output_Buffer *xob, int sync) { shmpool = evas_list_prepend(shmpool, xob); shmsize += xob->psize * xob->xim->depth / 8; - while ((shmsize > (1024 * 4096)) || - (evas_list_count(shmpool) > 32)) + while ((shmsize > (shmmemlimit)) || + (evas_list_count(shmpool) > shmcountlimit)) { Evas_List *xl;