From 663d56e49868189685576be88597b62faf32167d Mon Sep 17 00:00:00 2001 From: Cedric BAIL Date: Wed, 2 Jan 2013 02:46:05 +0000 Subject: [PATCH] efl: add eet_map and use it. SVN revision: 81970 --- ChangeLog | 3 +- NEWS | 3 +- src/lib/eet/Eet.h | 25 +++++++ src/lib/eet/Eet_private.h | 1 + src/lib/eet/eet_lib.c | 65 ++++++++++++++++++- .../evas/loaders/eet/evas_image_load_eet.c | 36 +++++++--- 6 files changed, 120 insertions(+), 13 deletions(-) diff --git a/ChangeLog b/ChangeLog index 663e818158..0637ca4190 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,7 @@ 2013-01-02 Cedric Bail - * Use Eina_File for evas webp loader. + * Use Eina_File for evas webp and eet loader. + * Add eet_map to open an Eet file from an Eina_File. 2012-12-31 Gustavo Sverzut Barbieri (k-s) diff --git a/NEWS b/NEWS index ee70475e14..445b284f20 100644 --- a/NEWS +++ b/NEWS @@ -47,6 +47,7 @@ Additions: eina_xattr_del(), eina_xattr_fd_del(), eina_xattr_copy() and eina_xattr_fd_copy() * Added eina_file_copy() + * Add eet_map. Deprecations: * ecore_x: @@ -68,7 +69,7 @@ Improvements: * Display more information with eet -l -v. * eina_magic_fail() now throws error messages on NULL pointers instead of critical * all efl object-freeing functions now take NULL without crashing or erroring - * use Eina_File in webp loader + * use Eina_File in webp and eet loader Fixes: * Fix PPC (big endian) image codec bug. diff --git a/src/lib/eet/Eet.h b/src/lib/eet/Eet.h index 693b839056..ef07f246e1 100644 --- a/src/lib/eet/Eet.h +++ b/src/lib/eet/Eet.h @@ -557,6 +557,31 @@ EAPI Eet_File * eet_open(const char *file, Eet_File_Mode mode); +/** + * Open an eet file on disk from an Eina_File handle, and returns a handle to it. + * @param file The Eina_File handle to map to an eet file. + * @return An opened eet file handle. + * @ingroup Eet_File_Group + * + * This function will open an exiting eet file for reading, and build + * the directory table in memory and return a handle to the file, if it + * exists and can be read, and no memory errors occur on the way, otherwise + * NULL will be returned. + * + * This function can't open file for writing only read only mode is supported for now. + * + * If the same file is opened multiple times, then the same file handle will + * be returned as eet maintains an internal list of all currently open + * files. That means opening a file for read only looks in the read only set, + * and returns a handle to that file handle and increments its reference count. + * You need to close an eet file handle as many times as it has been opened to + * maintain correct reference counts. + * + * @since 1.8.0 + */ +EAPI Eet_File * +eet_map(Eina_File *file); + /** * Open an eet file directly from a memory location. The data is not copied, * so you must keep it around as long as the eet file is open. There is diff --git a/src/lib/eet/Eet_private.h b/src/lib/eet/Eet_private.h index 20c12d75be..e4cb713f99 100644 --- a/src/lib/eet/Eet_private.h +++ b/src/lib/eet/Eet_private.h @@ -97,6 +97,7 @@ struct _Eet_File unsigned char writes_pending : 1; unsigned char delete_me_now : 1; + unsigned char readfp_owned : 1; }; struct _Eet_File_Header diff --git a/src/lib/eet/eet_lib.c b/src/lib/eet/eet_lib.c index 431b87a3db..654c09a0eb 100644 --- a/src/lib/eet/eet_lib.c +++ b/src/lib/eet/eet_lib.c @@ -1346,7 +1346,7 @@ eet_internal_close(Eet_File *ef, if (ef->sha1) free(ef->sha1); - if (ef->readfp) + if (ef->readfp && ef->readfp_owned) { if (ef->data) eina_file_map_free(ef->readfp, (void *)ef->data); @@ -1396,6 +1396,7 @@ eet_memopen_read(const void *data, ef->data_size = size; ef->sha1 = NULL; ef->sha1_length = 0; + ef->readfp_owned = EINA_FALSE; /* eet_internal_read expects the cache lock to be held when it is called */ LOCK_CACHE; @@ -1411,6 +1412,67 @@ eet_file_get(Eet_File *ef) return ef->path; } +EAPI Eet_File * +eet_map(Eina_File *file) +{ + Eet_File *ef = NULL; + const char *path; + + path = eina_file_filename_get(file); + + LOCK_CACHE; + ef = eet_cache_find(path, eet_writers, eet_writers_num); + if (ef) + { + eet_sync(ef); + ef->references++; + ef->delete_me_now = 1; + eet_internal_close(ef, EINA_TRUE); + } + + ef = eet_cache_find(path, eet_readers, eet_readers_num); + if (ef->readfp == file) goto done; + + /* Allocate struct for eet file and have it zero'd out */ + ef = eet_file_malloc(1); + if (!ef) return NULL; + + /* fill some of the members */ + INIT_FILE(ef); + ef->key = NULL; + ef->readfp = file; + ef->path = eina_stringshare_add(path); + ef->magic = EET_MAGIC_FILE; + ef->references = 1; + ef->mode = EET_FILE_MODE_READ; + ef->header = NULL; + ef->writes_pending = 0; + ef->delete_me_now = 0; + ef->data = NULL; + ef->data_size = 0; + ef->sha1 = NULL; + ef->sha1_length = 0; + ef->readfp_owned = EINA_FALSE; + + ef->data_size = eina_file_size_get(file); + ef->data = eina_file_map_all(file, EINA_FILE_SEQUENTIAL); + if (eet_test_close((ef->data == NULL), ef)) + goto on_error; + + ef = eet_internal_read(ef); + if (!ef) + goto on_error; + + done: + ef->references++; + UNLOCK_CACHE; + return ef; + + on_error: + UNLOCK_CACHE; + return NULL; +} + EAPI Eet_File * eet_open(const char *file, Eet_File_Mode mode) @@ -1535,6 +1597,7 @@ open_error: ef->data_size = 0; ef->sha1 = NULL; ef->sha1_length = 0; + ef->readfp_owned = EINA_TRUE; ef->ed = (mode == EET_FILE_MODE_WRITE) || (!ef->readfp && mode == EET_FILE_MODE_READ_WRITE) ? diff --git a/src/modules/evas/loaders/eet/evas_image_load_eet.c b/src/modules/evas/loaders/eet/evas_image_load_eet.c index 7526420bc6..6b349d43db 100644 --- a/src/modules/evas/loaders/eet/evas_image_load_eet.c +++ b/src/modules/evas/loaders/eet/evas_image_load_eet.c @@ -20,13 +20,13 @@ Evas_Image_Load_Func evas_image_load_eet_func = EINA_FALSE }; - static Eina_Bool evas_image_load_file_head_eet(Image_Entry *ie, const char *file, const char *key, int *error) { int alpha, compression, quality, lossy; unsigned int w, h; - Eet_File *ef; + Eina_File *f = NULL; + Eet_File *ef = NULL; int ok; Eina_Bool res = EINA_FALSE; @@ -36,11 +36,18 @@ evas_image_load_file_head_eet(Image_Entry *ie, const char *file, const char *key return EINA_FALSE; } - ef = eet_open((char *)file, EET_FILE_MODE_READ); + f = eina_file_open(file, EINA_FALSE); + if (!f) + { + *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST; + return EINA_FALSE; + } + + ef = eet_map(f); if (!ef) { - *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST; - return EINA_FALSE; + *error = EVAS_LOAD_ERROR_CORRUPT_FILE; + goto on_error; } ok = eet_data_image_header_read(ef, key, &w, &h, &alpha, &compression, &quality, &lossy); @@ -61,7 +68,8 @@ evas_image_load_file_head_eet(Image_Entry *ie, const char *file, const char *key *error = EVAS_LOAD_ERROR_NONE; on_error: - eet_close(ef); + if (ef) eet_close(ef); + eina_file_close(f); return res; } @@ -70,6 +78,7 @@ evas_image_load_file_data_eet(Image_Entry *ie, const char *file, const char *key { unsigned int w, h; int alpha, compression, quality, lossy, ok; + Eina_File *f; Eet_File *ef; DATA32 *body, *p, *end, *data; DATA32 nas = 0; @@ -85,11 +94,17 @@ evas_image_load_file_data_eet(Image_Entry *ie, const char *file, const char *key *error = EVAS_LOAD_ERROR_NONE; return EINA_TRUE; } - ef = eet_open(file, EET_FILE_MODE_READ); + f = eina_file_open(file, EINA_FALSE); + if (!f) + { + *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST; + return EINA_FALSE; + } + ef = eet_map(f); if (!ef) { - *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST; - return EINA_FALSE; + *error = EVAS_LOAD_ERROR_CORRUPT_FILE; + goto on_error; } ok = eet_data_image_header_read(ef, key, &w, &h, &alpha, &compression, &quality, &lossy); @@ -148,7 +163,8 @@ evas_image_load_file_data_eet(Image_Entry *ie, const char *file, const char *key res = EINA_TRUE; on_error: - eet_close(ef); + if (ef) eet_close(ef); + eina_file_close(f); return res; }