summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCedric BAIL <cedric.bail@samsung.com>2013-03-14 20:49:45 +0900
committerCedric BAIL <cedric.bail@samsung.com>2013-03-15 11:05:25 +0900
commite70502f1a15e26e634bfb356d565fe27943a671a (patch)
tree05ddf3cf20e857204950caf78cd446182b4f5310
parentf90726cf35bb89f14af7b57d8360848a8228dce9 (diff)
downloadefl-e70502f1a15e26e634bfb356d565fe27943a671a.tar.gz
eina: improve portability of Eina_File.
-rw-r--r--src/Makefile_Eina.am2
-rw-r--r--src/lib/eina/eina_file.c367
-rw-r--r--src/lib/eina/eina_file_common.c305
-rw-r--r--src/lib/eina/eina_file_common.h100
-rw-r--r--src/lib/eina/eina_file_win32.c366
5 files changed, 495 insertions, 645 deletions
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 <Escape.h>
@@ -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,39 +556,51 @@ eina_file_mmap_faulty(void *addr, long page_size)
eina_lock_release(&_eina_file_lock_cache);
}
-/*============================================================================*
- * API *
- *============================================================================*/
+/* ================================================================ *
+ * Simplified logic for portability layer with eina_file_common *
+ * ================================================================ */
-EAPI char *
-eina_file_path_sanitize(const char *path)
+Eina_Bool
+eina_file_path_relative(const char *path)
{
- char *result = NULL;
- int len;
+ if (*path != '/') return EINA_TRUE;
+ return EINA_FALSE;
+}
- if (!path) return NULL;
+Eina_Tmpstr *
+eina_file_current_directory_get(const char *path, size_t len)
+{
+ char cwd[PATH_MAX];
+ char *tmp = NULL;
- len = strlen(path);
+ tmp = getcwd(cwd, PATH_MAX);
+ if (!tmp) return NULL;
- if (*path != '/')
- {
- char cwd[PATH_MAX];
- char *tmp = NULL;
+ len += strlen(cwd) + 2;
+ tmp = alloca(sizeof (char) * len);
- tmp = getcwd(cwd, PATH_MAX);
- if (!tmp) return NULL;
+ slprintf(tmp, len, "%s/%s", cwd, path);
- len += strlen(cwd) + 2;
- tmp = alloca(sizeof (char) * len);
+ return eina_tmpstr_add_length(tmp, len);
+}
- slprintf(tmp, len, "%s/%s", cwd, path);
+char *
+eina_file_cleanup(Eina_Tmpstr *path)
+{
+ char *result;
- result = tmp;
- }
+ result = strdup(path ? path : "");
+ eina_tmpstr_del(path);
- return _eina_file_escape(result ? result : path, &len);
+ return result;
}
+/*============================================================================*
+ * API *
+ *============================================================================*/
+
+
+
EAPI Eina_Bool
eina_file_dir_list(const char *dir,
Eina_Bool recursive,
@@ -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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <string.h>
+#include <stdint.h>
+
+#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 <Escape.h>
+#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 <http://www.gnu.org/licenses/>.
+ */
+
+#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;
}
-/*============================================================================*
- * 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)