diff --git a/src/Makefile_Eina.am b/src/Makefile_Eina.am index 91ebe577df..91c4ec9079 100644 --- a/src/Makefile_Eina.am +++ b/src/Makefile_Eina.am @@ -107,6 +107,8 @@ lib/eina/eina_counter.c \ lib/eina/eina_cow.c \ lib/eina/eina_cpu.c \ lib/eina/eina_error.c \ +lib/eina/eina_file_common.h \ +lib/eina/eina_file_common.c \ lib/eina/eina_fp.c \ lib/eina/eina_hamster.c \ lib/eina/eina_hash.c \ diff --git a/src/lib/eina/eina_file.c b/src/lib/eina/eina_file.c index e498794e1b..d54b703fa4 100644 --- a/src/lib/eina/eina_file.c +++ b/src/lib/eina/eina_file.c @@ -53,6 +53,7 @@ #include "eina_mmap.h" #include "eina_log.h" #include "eina_xattr.h" +#include "eina_file_common.h" #ifdef HAVE_ESCAPE # include @@ -106,50 +107,6 @@ struct _Eina_File_Iterator }; #endif -struct _Eina_File -{ - const char *filename; - - Eina_Hash *map; - Eina_Hash *rmap; - void *global_map; - - Eina_Lock lock; - - unsigned long long length; - time_t mtime; - ino_t inode; -#ifdef _STAT_VER_LINUX - unsigned long int mtime_nsec; -#endif - - int refcount; - int global_refcount; - - int fd; - - Eina_Bool shared : 1; - Eina_Bool delete_me : 1; - Eina_Bool global_faulty : 1; -}; - -typedef struct _Eina_File_Map Eina_File_Map; -struct _Eina_File_Map -{ - void *map; - - unsigned long int offset; - unsigned long int length; - - int refcount; - - Eina_Bool hugetlb : 1; - Eina_Bool faulty : 1; -}; - -static Eina_Hash *_eina_file_cache = NULL; -static Eina_Lock _eina_file_lock_cache; - static int _eina_file_log_dom = -1; /* @@ -368,8 +325,8 @@ _eina_file_stat_ls_iterator_next(Eina_File_Direct_Iterator *it, void **data) } #endif -static void -_eina_file_real_close(Eina_File *file) +void +eina_file_real_close(Eina_File *file) { if (file->refcount != 0) return; @@ -488,90 +445,6 @@ slprintf(char *str, size_t size, const char *format, ...) va_end(ap); } -static char * -_eina_file_escape(const char *path, int *length) -{ - char *result; - char *p; - char *q; - size_t len; - - result = strdup(path ? path : ""); - 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'; - break; - } - else - { - q = p; - ++p; - } - } - else - if (p[1] == '.' - && p[2] == '/') - { - // remove '/./' - len -= 2; - memmove(p, p + 2, len - (p - result)); - result[len] = '\0'; - q = p; - ++p; - } - else - { - q = p; - ++p; - } - } - - if (length) - *length = len; - return result; -} - /** * @endcond */ @@ -683,38 +556,50 @@ eina_file_mmap_faulty(void *addr, long page_size) eina_lock_release(&_eina_file_lock_cache); } +/* ================================================================ * + * Simplified logic for portability layer with eina_file_common * + * ================================================================ */ + +Eina_Bool +eina_file_path_relative(const char *path) +{ + if (*path != '/') return EINA_TRUE; + return EINA_FALSE; +} + +Eina_Tmpstr * +eina_file_current_directory_get(const char *path, size_t len) +{ + char cwd[PATH_MAX]; + char *tmp = NULL; + + tmp = getcwd(cwd, PATH_MAX); + if (!tmp) return NULL; + + len += strlen(cwd) + 2; + tmp = alloca(sizeof (char) * len); + + slprintf(tmp, len, "%s/%s", cwd, path); + + return eina_tmpstr_add_length(tmp, len); +} + +char * +eina_file_cleanup(Eina_Tmpstr *path) +{ + char *result; + + result = strdup(path ? path : ""); + eina_tmpstr_del(path); + + return result; +} + /*============================================================================* * API * *============================================================================*/ -EAPI char * -eina_file_path_sanitize(const char *path) -{ - char *result = NULL; - int len; - if (!path) return NULL; - - len = strlen(path); - - if (*path != '/') - { - char cwd[PATH_MAX]; - char *tmp = NULL; - - tmp = getcwd(cwd, PATH_MAX); - if (!tmp) return NULL; - - len += strlen(cwd) + 2; - tmp = alloca(sizeof (char) * len); - - slprintf(tmp, len, "%s/%s", cwd, path); - - result = tmp; - } - - return _eina_file_escape(result ? result : path, &len); -} EAPI Eina_Bool eina_file_dir_list(const char *dir, @@ -997,7 +882,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; } @@ -1056,45 +941,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 void * eina_file_map_all(Eina_File *file, Eina_File_Populate rule) { @@ -1139,145 +985,6 @@ eina_file_map_all(Eina_File *file, Eina_File_Populate rule) return ret; } -typedef struct _Eina_Lines_Iterator Eina_Lines_Iterator; -struct _Eina_Lines_Iterator -{ - Eina_Iterator iterator; - - Eina_File *fp; - const char *map; - const char *end; - - int boundary; - - Eina_File_Line current; -}; - -/* 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); -} - -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) diff --git a/src/lib/eina/eina_file_common.c b/src/lib/eina/eina_file_common.c new file mode 100644 index 0000000000..d8d96bf4d1 --- /dev/null +++ b/src/lib/eina/eina_file_common.c @@ -0,0 +1,305 @@ +/* EINA - EFL data type library + * Copyright (C) 2013 Cedric Bail + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; + * if not, see . + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include + +#define COPY_BLOCKSIZE (4 * 1024 * 1024) + +#include "eina_config.h" +#include "eina_private.h" + +#include "eina_hash.h" +#include "eina_safety_checks.h" +#include "eina_file_common.h" + +#ifdef HAVE_ESCAPE +# include +#endif + +Eina_Hash *_eina_file_cache = NULL; +Eina_Lock _eina_file_lock_cache; + +static char * +_eina_file_escape(char *path, size_t len) +{ + char *result; + char *p; + char *q; + + result = path; + p = result; + q = result; + + if (!result) + return NULL; + + 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'; + break; + } + else + { + q = p; + ++p; + } + } + else + if (p[1] == '.' + && p[2] == '/') + { + // remove '/./' + len -= 2; + memmove(p, p + 2, len - (p - result)); + result[len] = '\0'; + q = p; + ++p; + } + else + { + q = p; + ++p; + } + } + + return result; +} + +// Global API + +EAPI char * +eina_file_path_sanitize(const char *path) +{ + Eina_Tmpstr *result = NULL; + size_t len; + + if (!path) return NULL; + + len = strlen(path); + + if (eina_file_path_relative(path)) + { + result = eina_file_current_directory_get(path, len); + len = eina_tmpstr_strlen(result); + } + else + result = path; + + return _eina_file_escape(eina_file_cleanup(result), len); +} + +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; +} + +/* 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); +} + +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; +} diff --git a/src/lib/eina/eina_file_common.h b/src/lib/eina/eina_file_common.h new file mode 100644 index 0000000000..3081d23293 --- /dev/null +++ b/src/lib/eina/eina_file_common.h @@ -0,0 +1,100 @@ +/* EINA - EFL data type library + * Copyright (C) 2013 Cedric Bail + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; + * if not, see . + */ + +#ifndef EINA_FILE_COMMON_H_ +# define EINA_FILE_COMMON_H_ + +#include "eina_file.h" +#include "eina_tmpstr.h" +#include "eina_lock.h" + +typedef struct _Eina_File_Map Eina_File_Map; +typedef struct _Eina_Lines_Iterator Eina_Lines_Iterator; + +struct _Eina_File +{ + const char *filename; + + Eina_Hash *map; + Eina_Hash *rmap; + void *global_map; + + Eina_Lock lock; + +#ifndef _WIN32 + unsigned long long length; + time_t mtime; + ino_t inode; +#ifdef _STAT_VER_LINUX + unsigned long int mtime_nsec; +#endif +#else + ULONGLONG length; + ULONGLONG mtime; +#endif + + int refcount; + int global_refcount; + +#ifndef _WIN32 + int fd; +#else + HANDLE handle; + HANDLE fm; +#endif + + Eina_Bool shared : 1; + Eina_Bool delete_me : 1; + Eina_Bool global_faulty : 1; +}; + +struct _Eina_File_Map +{ + void *map; + + unsigned long int offset; + unsigned long int length; + + int refcount; + + Eina_Bool hugetlb : 1; + Eina_Bool faulty : 1; +}; + +struct _Eina_Lines_Iterator +{ + Eina_Iterator iterator; + + Eina_File *fp; + const char *map; + const char *end; + + int boundary; + + Eina_File_Line current; +}; + +Eina_Bool eina_file_path_relative(const char *path); +Eina_Tmpstr *eina_file_current_directory_get(const char *path, size_t len); +char *eina_file_cleanup(Eina_Tmpstr *path); +void eina_file_real_close(Eina_File *file); + +extern Eina_Hash *_eina_file_cache; +extern Eina_Lock _eina_file_lock_cache; + +#endif /* EINA_FILE_COMMON_H_ */ 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; } + +/* ================================================================ * + * 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; +} + +Eina_Tmpstr * +eina_file_current_directory_get(const char *path, size_t len) +{ + char *cwd; + char *tmp; + DWORD l; + + l = GetCurrentDirectory(0, NULL); + if (l <= 0) return NULL; + + 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'; + + return eina_tmpstr_add_length(tmp, len); +} + +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 result; +} + /*============================================================================* * API * *============================================================================*/ - -EAPI char * -eina_file_path_sanitize(const char *path) -{ - char *result = NULL; - size_t len; - - if (!path) return NULL; - - len = strlen(path); - - if (!evil_path_is_absolute(path)) - { - DWORD l; - - 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; - } - } - - return _eina_file_win32_escape(result ? result : path, &len); -} - 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)