diff options
author | Cedric BAIL <cedric.bail@samsung.com> | 2013-03-14 20:49:45 +0900 |
---|---|---|
committer | Cedric BAIL <cedric.bail@samsung.com> | 2013-03-15 11:05:25 +0900 |
commit | e70502f1a15e26e634bfb356d565fe27943a671a (patch) | |
tree | 05ddf3cf20e857204950caf78cd446182b4f5310 /src/lib/eina/eina_file_win32.c | |
parent | f90726cf35bb89f14af7b57d8360848a8228dce9 (diff) | |
download | efl-e70502f1a15e26e634bfb356d565fe27943a671a.tar.gz |
eina: improve portability of Eina_File.
Diffstat (limited to 'src/lib/eina/eina_file_win32.c')
-rw-r--r-- | src/lib/eina/eina_file_win32.c | 366 |
1 files changed, 51 insertions, 315 deletions
diff --git a/src/lib/eina/eina_file_win32.c b/src/lib/eina/eina_file_win32.c index 8fc6bb4c0d..cb73c0a75b 100644 --- a/src/lib/eina/eina_file_win32.c +++ b/src/lib/eina/eina_file_win32.c @@ -41,6 +41,7 @@ #include "eina_list.h" #include "eina_lock.h" #include "eina_log.h" +#include "eina_file_common.h" /*============================================================================* * Local * @@ -104,42 +105,6 @@ struct _Eina_File_Direct_Iterator char dir[1]; }; -struct _Eina_File -{ - const char *filename; - - Eina_Hash *map; - Eina_Hash *rmap; - void *global_map; - - Eina_Lock lock; - - ULONGLONG length; - ULONGLONG mtime; - - int refcount; - int global_refcount; - - HANDLE handle; - HANDLE fm; - - Eina_Bool shared : 1; - Eina_Bool delete_me : 1; -}; - -struct _Eina_File_Map -{ - void *map; - - unsigned long int offset; - unsigned long int length; - - int refcount; -}; - -static Eina_Hash *_eina_file_cache = NULL; -static Eina_Lock _eina_file_lock_cache; - static int _eina_file_log_dom = -1; static Eina_Bool @@ -415,8 +380,8 @@ _eina_file_win32_direct_ls_iterator_free(Eina_File_Direct_Iterator *it) free(it); } -static void -_eina_file_real_close(Eina_File *file) +void +eina_file_real_close(Eina_File *file) { eina_hash_free(file->rmap); eina_hash_free(file->map); @@ -459,175 +424,6 @@ _eina_file_map_key_hash(const unsigned long int *key, int key_length EINA_UNUSED ^ eina_hash_int64(&key[1], sizeof (unsigned long int)); } -static char * -_eina_file_win32_escape(const char *path, size_t *length) -{ - char *result; - char *p; - char *q; - size_t len; - - result = strdup(path ? path : ""); - if (!result) - return NULL; - - p = result; - while (*p) - { - if (*p == '\\') *p = '/'; - p++; - } - p = result; - q = result; - - if (!result) - return NULL; - - if (length) len = *length; - else len = strlen(result); - - while ((p = strchr(p, '/'))) - { - // remove double `/' - if (p[1] == '/') - { - memmove(p, p + 1, --len - (p - result)); - result[len] = '\0'; - } - else - if (p[1] == '.' - && p[2] == '.') - { - // remove `/../' - if (p[3] == '/') - { - char tmp; - - len -= p + 3 - q; - memmove(q, p + 3, len - (q - result)); - result[len] = '\0'; - p = q; - - /* Update q correctly. */ - tmp = *p; - *p = '\0'; - q = strrchr(result, '/'); - if (!q) q = result; - *p = tmp; - } - else - // remove '/..$' - if (p[3] == '\0') - { - len -= p + 2 - q; - result[len] = '\0'; - q = p; - ++p; - } - else - { - q = p; - ++p; - } - } - else - { - q = p; - ++p; - } - } - - if (length) - *length = len; - - return result; -} - -/* search '\r' and '\n' by preserving cache locality and page locality - in doing a search inside 4K boundary. - */ -static inline const char * -_eina_fine_eol(const char *start, int boundary, const char *end) -{ - const char *cr; - const char *lf; - unsigned long long chunk; - - while (start < end) - { - chunk = start + boundary < end ? boundary : end - start; - cr = memchr(start, '\r', chunk); - lf = memchr(start, '\n', chunk); - if (cr) - { - if (lf && lf < cr) - return lf + 1; - return cr + 1; - } - else if (lf) - return lf + 1; - - start += chunk; - boundary = 4096; - } - - return end; -} - -static Eina_Bool -_eina_file_map_lines_iterator_next(Eina_Lines_Iterator *it, void **data) -{ - const char *eol; - unsigned char match; - - if (it->current.end >= it->end) - return EINA_FALSE; - - match = *it->current.end; - while ((*it->current.end == '\n' || *it->current.end == '\r') - && it->current.end < it->end) - { - if (match == *it->current.end) - it->current.index++; - it->current.end++; - } - it->current.index++; - - if (it->current.end == it->end) - return EINA_FALSE; - - eol = _eina_fine_eol(it->current.end, - it->boundary, - it->end); - it->boundary = (uintptr_t) eol & 0x3FF; - if (it->boundary == 0) it->boundary = 4096; - - it->current.start = it->current.end; - - it->current.end = eol; - it->current.length = eol - it->current.start - 1; - - *data = &it->current; - return EINA_TRUE; -} - -static Eina_File * -_eina_file_map_lines_iterator_container(Eina_Lines_Iterator *it) -{ - return it->fp; -} - -static void -_eina_file_map_lines_iterator_free(Eina_Lines_Iterator *it) -{ - eina_file_map_free(it->fp, (void*) it->map); - eina_file_close(it->fp); - - EINA_MAGIC_SET(&it->iterator, 0); - free(it); -} - - /** * @endcond */ @@ -684,44 +480,64 @@ eina_file_shutdown(void) return EINA_TRUE; } -/*============================================================================* - * API * - *============================================================================*/ +/* ================================================================ * + * Simplified logic for portability layer with eina_file_common * + * ================================================================ */ + +Eina_Bool +eina_file_path_relative(const char *path) +{ + if (!evil_path_is_absolute(path)) return EINA_TRUE; + return EINA_FALSE; +} -EAPI char * -eina_file_path_sanitize(const char *path) +Eina_Tmpstr * +eina_file_current_directory_get(const char *path, size_t len) { - char *result = NULL; - size_t len; + char *cwd; + char *tmp; + DWORD l; - if (!path) return NULL; + l = GetCurrentDirectory(0, NULL); + if (l <= 0) return NULL; - len = strlen(path); + cwd = alloca(sizeof(char) * (l + 1)); + GetCurrentDirectory(l + 1, cwd); + len += l + 2; + tmp = alloca(sizeof (char) * len); + snprintf(tmp, len, "%s\\%s", cwd, path); + tmp[len - 1] = '\0'; - if (!evil_path_is_absolute(path)) - { - DWORD l; + return eina_tmpstr_add_length(tmp, len); +} - l = GetCurrentDirectory(0, NULL); - if (l > 0) - { - char *cwd; - char *tmp; - - cwd = alloca(sizeof(char) * (l + 1)); - GetCurrentDirectory(l + 1, cwd); - len += l + 2; - tmp = alloca(sizeof (char) * len); - snprintf(tmp, len, "%s\\%s", cwd, path); - tmp[len - 1] = '\0'; - result = tmp; - } +char * +eina_file_cleanup(Eina_Tmpstr *path) +{ + char *result; + char *p; + + result = strdup(path ? path : ""); + eina_tmpstr_del(path); + + if (!result) + return NULL; + + p = result; + while (*p) + { + if (*p == '\\') *p = '/'; + p++; } - return _eina_file_win32_escape(result ? result : path, &len); + return result; } +/*============================================================================* + * API * + *============================================================================*/ + EAPI Eina_Bool eina_file_dir_list(const char *dir, Eina_Bool recursive, @@ -997,7 +813,7 @@ eina_file_open(const char *path, Eina_Bool shared) { file->delete_me = EINA_TRUE; eina_hash_del(_eina_file_cache, file->filename, file); - _eina_file_real_close(file); + eina_file_real_close(file); file = NULL; } @@ -1053,45 +869,6 @@ eina_file_open(const char *path, Eina_Bool shared) return NULL; } -EAPI void -eina_file_close(Eina_File *file) -{ - EINA_SAFETY_ON_NULL_RETURN(file); - - eina_lock_take(&file->lock); - file->refcount--; - eina_lock_release(&file->lock); - - if (file->refcount != 0) return ; - eina_lock_take(&_eina_file_lock_cache); - - eina_hash_del(_eina_file_cache, file->filename, file); - _eina_file_real_close(file); - - eina_lock_release(&_eina_file_lock_cache); -} - -EAPI size_t -eina_file_size_get(Eina_File *file) -{ - EINA_SAFETY_ON_NULL_RETURN_VAL(file, 0); - return file->length; -} - -EAPI time_t -eina_file_mtime_get(Eina_File *file) -{ - EINA_SAFETY_ON_NULL_RETURN_VAL(file, 0); - return file->mtime; -} - -EAPI const char * -eina_file_filename_get(Eina_File *file) -{ - EINA_SAFETY_ON_NULL_RETURN_VAL(file, NULL); - return file->filename; -} - EAPI Eina_Iterator *eina_file_xattr_get(Eina_File *file EINA_UNUSED) { return NULL; @@ -1130,47 +907,6 @@ eina_file_map_all(Eina_File *file, Eina_File_Populate rule EINA_UNUSED) return NULL; } -EAPI Eina_Iterator * -eina_file_map_lines(Eina_File *file) -{ - Eina_Lines_Iterator *it; - - EINA_SAFETY_ON_NULL_RETURN_VAL(file, NULL); - - if (file->length == 0) return NULL; - - it = calloc(1, sizeof (Eina_Lines_Iterator)); - if (!it) return NULL; - - EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR); - - it->map = eina_file_map_all(file, EINA_FILE_SEQUENTIAL); - if (!it->map) - { - free(it); - return NULL; - } - - eina_lock_take(&file->lock); - file->refcount++; - eina_lock_release(&file->lock); - - it->fp = file; - it->boundary = 4096; - it->current.start = it->map; - it->current.end = it->current.start; - it->current.index = 0; - it->current.length = 0; - it->end = it->map + it->fp->length; - - it->iterator.version = EINA_ITERATOR_VERSION; - it->iterator.next = FUNC_ITERATOR_NEXT(_eina_file_map_lines_iterator_next); - it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(_eina_file_map_lines_iterator_container); - it->iterator.free = FUNC_ITERATOR_FREE(_eina_file_map_lines_iterator_free); - - return &it->iterator; -} - EAPI void * eina_file_map_new(Eina_File *file, Eina_File_Populate rule, unsigned long int offset, unsigned long int length) |