summaryrefslogtreecommitdiff
path: root/legacy
diff options
context:
space:
mode:
authorVincent Torri <vincent.torri@gmail.com>2012-01-22 08:57:50 +0000
committerVincent Torri <vincent.torri@gmail.com>2012-01-22 08:57:50 +0000
commitf4baf62a914833138c1c58faae57d75b5c534463 (patch)
treeda2190d6d9189fab0bf66412627c7a9136907579 /legacy
parent54b589cfe9fe7dfcc18bc8e6b24d2ac2bff1cad0 (diff)
Eina: DOS2UNIX eina_file_win32.c
SVN revision: 67445
Diffstat (limited to 'legacy')
-rw-r--r--legacy/eina/src/lib/eina_file_win32.c2306
1 files changed, 1153 insertions, 1153 deletions
diff --git a/legacy/eina/src/lib/eina_file_win32.c b/legacy/eina/src/lib/eina_file_win32.c
index 47de11aa1c..54d3a10306 100644
--- a/legacy/eina/src/lib/eina_file_win32.c
+++ b/legacy/eina/src/lib/eina_file_win32.c
@@ -1,1153 +1,1153 @@
1/* EINA - EFL data type library 1/* EINA - EFL data type library
2 * Copyright (C) 2010 Vincent Torri 2 * Copyright (C) 2010 Vincent Torri
3 * 3 *
4 * This library is free software; you can redistribute it and/or 4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public 5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either 6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version. 7 * version 2.1 of the License, or (at your option) any later version.
8 * 8 *
9 * This library is distributed in the hope that it will be useful, 9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details. 12 * Lesser General Public License for more details.
13 * 13 *
14 * You should have received a copy of the GNU Lesser General Public 14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; 15 * License along with this library;
16 * if not, see <http://www.gnu.org/licenses/>. 16 * if not, see <http://www.gnu.org/licenses/>.
17 */ 17 */
18 18
19#ifdef HAVE_CONFIG_H 19#ifdef HAVE_CONFIG_H
20# include "config.h" 20# include "config.h"
21#endif 21#endif
22 22
23#ifdef HAVE_ALLOCA_H 23#ifdef HAVE_ALLOCA_H
24# include <alloca.h> 24# include <alloca.h>
25#elif defined __GNUC__ 25#elif defined __GNUC__
26# define alloca __builtin_alloca 26# define alloca __builtin_alloca
27#elif defined _AIX 27#elif defined _AIX
28# define alloca __alloca 28# define alloca __alloca
29#elif defined _MSC_VER 29#elif defined _MSC_VER
30# include <malloc.h> 30# include <malloc.h>
31# define alloca _alloca 31# define alloca _alloca
32#else 32#else
33# include <stddef.h> 33# include <stddef.h>
34# ifdef __cplusplus 34# ifdef __cplusplus
35extern "C" 35extern "C"
36# endif 36# endif
37void *alloca (size_t); 37void *alloca (size_t);
38#endif 38#endif
39 39
40#define WIN32_LEAN_AND_MEAN 40#define WIN32_LEAN_AND_MEAN
41#include <windows.h> 41#include <windows.h>
42#undef WIN32_LEAN_AND_MEAN 42#undef WIN32_LEAN_AND_MEAN
43 43
44#include <Evil.h> 44#include <Evil.h>
45 45
46#include "eina_config.h" 46#include "eina_config.h"
47#include "eina_private.h" 47#include "eina_private.h"
48 48
49/* undefs EINA_ARG_NONULL() so NULL checks are not compiled out! */ 49/* undefs EINA_ARG_NONULL() so NULL checks are not compiled out! */
50#include "eina_safety_checks.h" 50#include "eina_safety_checks.h"
51#include "eina_file.h" 51#include "eina_file.h"
52#include "eina_stringshare.h" 52#include "eina_stringshare.h"
53#include "eina_hash.h" 53#include "eina_hash.h"
54#include "eina_list.h" 54#include "eina_list.h"
55#include "eina_lock.h" 55#include "eina_lock.h"
56#include "eina_log.h" 56#include "eina_log.h"
57 57
58/*============================================================================* 58/*============================================================================*
59 * Local * 59 * Local *
60 *============================================================================*/ 60 *============================================================================*/
61 61
62/** 62/**
63 * @cond LOCAL 63 * @cond LOCAL
64 */ 64 */
65 65
66#ifndef EINA_LOG_COLOR_DEFAULT 66#ifndef EINA_LOG_COLOR_DEFAULT
67#define EINA_LOG_COLOR_DEFAULT EINA_COLOR_CYAN 67#define EINA_LOG_COLOR_DEFAULT EINA_COLOR_CYAN
68#endif 68#endif
69 69
70#ifdef ERR 70#ifdef ERR
71#undef ERR 71#undef ERR
72#endif 72#endif
73#define ERR(...) EINA_LOG_DOM_ERR(_eina_file_log_dom, __VA_ARGS__) 73#define ERR(...) EINA_LOG_DOM_ERR(_eina_file_log_dom, __VA_ARGS__)
74 74
75#ifdef WRN 75#ifdef WRN
76#undef WRN 76#undef WRN
77#endif 77#endif
78#define WRN(...) EINA_LOG_DOM_WARN(_eina_file_log_dom, __VA_ARGS__) 78#define WRN(...) EINA_LOG_DOM_WARN(_eina_file_log_dom, __VA_ARGS__)
79 79
80#ifdef DBG 80#ifdef DBG
81#undef DBG 81#undef DBG
82#endif 82#endif
83#define DBG(...) EINA_LOG_DOM_DBG(_eina_file_log_dom, __VA_ARGS__) 83#define DBG(...) EINA_LOG_DOM_DBG(_eina_file_log_dom, __VA_ARGS__)
84 84
85#ifdef MAP_FAILED 85#ifdef MAP_FAILED
86# undef MAP_FAILED 86# undef MAP_FAILED
87#endif 87#endif
88#define MAP_FAILED ((void *)-1) 88#define MAP_FAILED ((void *)-1)
89 89
90typedef struct _Eina_File_Iterator Eina_File_Iterator; 90typedef struct _Eina_File_Iterator Eina_File_Iterator;
91typedef struct _Eina_File_Direct_Iterator Eina_File_Direct_Iterator; 91typedef struct _Eina_File_Direct_Iterator Eina_File_Direct_Iterator;
92typedef struct _Eina_File_Map Eina_File_Map; 92typedef struct _Eina_File_Map Eina_File_Map;
93 93
94struct _Eina_File_Iterator 94struct _Eina_File_Iterator
95{ 95{
96 Eina_Iterator iterator; 96 Eina_Iterator iterator;
97 97
98 WIN32_FIND_DATA data; 98 WIN32_FIND_DATA data;
99 HANDLE handle; 99 HANDLE handle;
100 size_t length; 100 size_t length;
101 Eina_Bool is_last : 1; 101 Eina_Bool is_last : 1;
102 102
103 char dir[1]; 103 char dir[1];
104}; 104};
105 105
106struct _Eina_File_Direct_Iterator 106struct _Eina_File_Direct_Iterator
107{ 107{
108 Eina_Iterator iterator; 108 Eina_Iterator iterator;
109 109
110 WIN32_FIND_DATA data; 110 WIN32_FIND_DATA data;
111 HANDLE handle; 111 HANDLE handle;
112 size_t length; 112 size_t length;
113 Eina_Bool is_last : 1; 113 Eina_Bool is_last : 1;
114 114
115 Eina_File_Direct_Info info; 115 Eina_File_Direct_Info info;
116 116
117 char dir[1]; 117 char dir[1];
118}; 118};
119 119
120struct _Eina_File 120struct _Eina_File
121{ 121{
122 const char *filename; 122 const char *filename;
123 123
124 Eina_Hash *map; 124 Eina_Hash *map;
125 Eina_Hash *rmap; 125 Eina_Hash *rmap;
126 void *global_map; 126 void *global_map;
127 127
128 Eina_Lock lock; 128 Eina_Lock lock;
129 129
130 ULONGLONG length; 130 ULONGLONG length;
131 ULONGLONG mtime; 131 ULONGLONG mtime;
132 132
133 int refcount; 133 int refcount;
134 int global_refcount; 134 int global_refcount;
135 135
136 HANDLE handle; 136 HANDLE handle;
137 HANDLE fm; 137 HANDLE fm;
138 138
139 Eina_Bool shared : 1; 139 Eina_Bool shared : 1;
140 Eina_Bool delete_me : 1; 140 Eina_Bool delete_me : 1;
141}; 141};
142 142
143struct _Eina_File_Map 143struct _Eina_File_Map
144{ 144{
145 void *map; 145 void *map;
146 146
147 unsigned long int offset; 147 unsigned long int offset;
148 unsigned long int length; 148 unsigned long int length;
149 149
150 int refcount; 150 int refcount;
151}; 151};
152 152
153static Eina_Hash *_eina_file_cache = NULL; 153static Eina_Hash *_eina_file_cache = NULL;
154static Eina_Lock _eina_file_lock_cache; 154static Eina_Lock _eina_file_lock_cache;
155 155
156static int _eina_file_log_dom = -1; 156static int _eina_file_log_dom = -1;
157 157
158static void 158static void
159_eina_file_win32_backslash_change(char *dir) 159_eina_file_win32_backslash_change(char *dir)
160{ 160{
161 char *tmp; 161 char *tmp;
162 162
163 tmp = dir; 163 tmp = dir;
164 while (*tmp) 164 while (*tmp)
165 { 165 {
166 if (*tmp == '/') *tmp = '\\'; 166 if (*tmp == '/') *tmp = '\\';
167 tmp++; 167 tmp++;
168 } 168 }
169} 169}
170 170
171static Eina_Bool 171static Eina_Bool
172_eina_file_win32_is_dir(const char *dir) 172_eina_file_win32_is_dir(const char *dir)
173{ 173{
174#ifdef UNICODE 174#ifdef UNICODE
175 wchar_t *wdir = NULL; 175 wchar_t *wdir = NULL;
176#endif 176#endif
177 DWORD attr; 177 DWORD attr;
178 178
179 /* check if it's a directory */ 179 /* check if it's a directory */
180#ifdef UNICODE 180#ifdef UNICODE
181 wdir = evil_char_to_wchar(dir); 181 wdir = evil_char_to_wchar(dir);
182 if (!wdir) 182 if (!wdir)
183 return EINA_FALSE; 183 return EINA_FALSE;
184 184
185 attr = GetFileAttributes(wdir); 185 attr = GetFileAttributes(wdir);
186 free(wdir); 186 free(wdir);
187#else 187#else
188 attr = GetFileAttributes(dir); 188 attr = GetFileAttributes(dir);
189#endif 189#endif
190 190
191 if (attr == 0xFFFFFFFF) 191 if (attr == 0xFFFFFFFF)
192 return EINA_FALSE; 192 return EINA_FALSE;
193 193
194 if (!(attr & FILE_ATTRIBUTE_DIRECTORY)) 194 if (!(attr & FILE_ATTRIBUTE_DIRECTORY))
195 return EINA_FALSE; 195 return EINA_FALSE;
196 196
197 return EINA_TRUE; 197 return EINA_TRUE;
198} 198}
199 199
200static char * 200static char *
201_eina_file_win32_dir_new(const char *dir) 201_eina_file_win32_dir_new(const char *dir)
202{ 202{
203 char *new_dir; 203 char *new_dir;
204 size_t length; 204 size_t length;
205 205
206 length = strlen(dir); 206 length = strlen(dir);
207 207
208 new_dir = (char *)malloc(sizeof(char) * length + 5); 208 new_dir = (char *)malloc(sizeof(char) * length + 5);
209 if (!new_dir) 209 if (!new_dir)
210 return NULL; 210 return NULL;
211 211
212 memcpy(new_dir, dir, length); 212 memcpy(new_dir, dir, length);
213 memcpy(new_dir + length, "\\*.*", 5); 213 memcpy(new_dir + length, "\\*.*", 5);
214 _eina_file_win32_backslash_change(new_dir); 214 _eina_file_win32_backslash_change(new_dir);
215 215
216 return new_dir; 216 return new_dir;
217} 217}
218 218
219static HANDLE 219static HANDLE
220_eina_file_win32_first_file(const char *dir, WIN32_FIND_DATA *fd) 220_eina_file_win32_first_file(const char *dir, WIN32_FIND_DATA *fd)
221{ 221{
222 HANDLE h; 222 HANDLE h;
223#ifdef UNICODE 223#ifdef UNICODE
224 wchar_t *wdir = NULL; 224 wchar_t *wdir = NULL;
225 225
226 wdir = evil_char_to_wchar(dir); 226 wdir = evil_char_to_wchar(dir);
227 if (!wdir) 227 if (!wdir)
228 return NULL; 228 return NULL;
229 229
230 h = FindFirstFile(wdir, fd); 230 h = FindFirstFile(wdir, fd);
231 free(wdir); 231 free(wdir);
232#else 232#else
233 h = FindFirstFile(dir, fd); 233 h = FindFirstFile(dir, fd);
234#endif 234#endif
235 235
236 if (!h) 236 if (!h)
237 return NULL; 237 return NULL;
238 238
239 while ((fd->cFileName[0] == '.') && 239 while ((fd->cFileName[0] == '.') &&
240 ((fd->cFileName[1] == '\0') || 240 ((fd->cFileName[1] == '\0') ||
241 ((fd->cFileName[1] == '.') && (fd->cFileName[2] == '\0')))) 241 ((fd->cFileName[1] == '.') && (fd->cFileName[2] == '\0'))))
242 { 242 {
243 if (!FindNextFile(h, fd)) 243 if (!FindNextFile(h, fd))
244 return NULL; 244 return NULL;
245 } 245 }
246 246
247 return h; 247 return h;
248} 248}
249 249
250static Eina_Bool 250static Eina_Bool
251_eina_file_win32_ls_iterator_next(Eina_File_Iterator *it, void **data) 251_eina_file_win32_ls_iterator_next(Eina_File_Iterator *it, void **data)
252{ 252{
253#ifdef UNICODE 253#ifdef UNICODE
254 wchar_t *old_name; 254 wchar_t *old_name;
255#else 255#else
256 char *old_name; 256 char *old_name;
257#endif 257#endif
258 char *name; 258 char *name;
259 char *cname; 259 char *cname;
260 size_t length; 260 size_t length;
261 Eina_Bool is_last; 261 Eina_Bool is_last;
262 Eina_Bool res = EINA_TRUE; 262 Eina_Bool res = EINA_TRUE;
263 263
264 if (it->handle == INVALID_HANDLE_VALUE) 264 if (it->handle == INVALID_HANDLE_VALUE)
265 return EINA_FALSE; 265 return EINA_FALSE;
266 266
267 is_last = it->is_last; 267 is_last = it->is_last;
268#ifdef UNICODE 268#ifdef UNICODE
269 old_name = _wcsdup(it->data.cFileName); 269 old_name = _wcsdup(it->data.cFileName);
270#else 270#else
271 old_name = _strdup(it->data.cFileName); 271 old_name = _strdup(it->data.cFileName);
272#endif 272#endif
273 if (!old_name) 273 if (!old_name)
274 return EINA_FALSE; 274 return EINA_FALSE;
275 275
276 do { 276 do {
277 if (!FindNextFile(it->handle, &it->data)) 277 if (!FindNextFile(it->handle, &it->data))
278 { 278 {
279 if (GetLastError() == ERROR_NO_MORE_FILES) 279 if (GetLastError() == ERROR_NO_MORE_FILES)
280 it->is_last = EINA_TRUE; 280 it->is_last = EINA_TRUE;
281 else 281 else
282 res = EINA_FALSE; 282 res = EINA_FALSE;
283 } 283 }
284 } while ((it->data.cFileName[0] == '.') && 284 } while ((it->data.cFileName[0] == '.') &&
285 ((it->data.cFileName[1] == '\0') || 285 ((it->data.cFileName[1] == '\0') ||
286 ((it->data.cFileName[1] == '.') && (it->data.cFileName[2] == '\0')))); /* FIXME: what about UNICODE ? */ 286 ((it->data.cFileName[1] == '.') && (it->data.cFileName[2] == '\0')))); /* FIXME: what about UNICODE ? */
287 287
288#ifdef UNICODE 288#ifdef UNICODE
289 cname = evil_wchar_to_char(old_name); 289 cname = evil_wchar_to_char(old_name);
290 if (!cname) 290 if (!cname)
291 return EINA_FALSE; 291 return EINA_FALSE;
292#else 292#else
293 cname = old_name; 293 cname = old_name;
294#endif 294#endif
295 295
296 length = strlen(cname); 296 length = strlen(cname);
297 name = alloca(length + 2 + it->length); 297 name = alloca(length + 2 + it->length);
298 298
299 memcpy(name, it->dir, it->length); 299 memcpy(name, it->dir, it->length);
300 memcpy(name + it->length, "\\", 1); 300 memcpy(name + it->length, "\\", 1);
301 memcpy(name + it->length + 1, cname, length + 1); 301 memcpy(name + it->length + 1, cname, length + 1);
302 302
303 *data = (char *)eina_stringshare_add(name); 303 *data = (char *)eina_stringshare_add(name);
304 304
305#ifdef UNICODE 305#ifdef UNICODE
306 free(cname); 306 free(cname);
307#endif 307#endif
308 free(old_name); 308 free(old_name);
309 309
310 if (is_last) 310 if (is_last)
311 res = EINA_FALSE; 311 res = EINA_FALSE;
312 312
313 return res; 313 return res;
314} 314}
315 315
316static HANDLE 316static HANDLE
317_eina_file_win32_ls_iterator_container(Eina_File_Iterator *it) 317_eina_file_win32_ls_iterator_container(Eina_File_Iterator *it)
318{ 318{
319 return it->handle; 319 return it->handle;
320} 320}
321 321
322static void 322static void
323_eina_file_win32_ls_iterator_free(Eina_File_Iterator *it) 323_eina_file_win32_ls_iterator_free(Eina_File_Iterator *it)
324{ 324{
325 if (it->handle != INVALID_HANDLE_VALUE) 325 if (it->handle != INVALID_HANDLE_VALUE)
326 FindClose(it->handle); 326 FindClose(it->handle);
327 327
328 EINA_MAGIC_SET(&it->iterator, 0); 328 EINA_MAGIC_SET(&it->iterator, 0);
329 free(it); 329 free(it);
330} 330}
331 331
332static Eina_Bool 332static Eina_Bool
333_eina_file_win32_direct_ls_iterator_next(Eina_File_Direct_Iterator *it, void **data) 333_eina_file_win32_direct_ls_iterator_next(Eina_File_Direct_Iterator *it, void **data)
334{ 334{
335#ifdef UNICODE 335#ifdef UNICODE
336 wchar_t *old_name; 336 wchar_t *old_name;
337#else 337#else
338 char *old_name; 338 char *old_name;
339#endif 339#endif
340 char *cname; 340 char *cname;
341 size_t length; 341 size_t length;
342 DWORD attr; 342 DWORD attr;
343 Eina_Bool is_last; 343 Eina_Bool is_last;
344 Eina_Bool res = EINA_TRUE; 344 Eina_Bool res = EINA_TRUE;
345 345
346 if (it->handle == INVALID_HANDLE_VALUE) 346 if (it->handle == INVALID_HANDLE_VALUE)
347 return EINA_FALSE; 347 return EINA_FALSE;
348 348
349 attr = it->data.dwFileAttributes; 349 attr = it->data.dwFileAttributes;
350 is_last = it->is_last; 350 is_last = it->is_last;
351#ifdef UNICODE 351#ifdef UNICODE
352 old_name = _wcsdup(it->data.cFileName); 352 old_name = _wcsdup(it->data.cFileName);
353#else 353#else
354 old_name = _strdup(it->data.cFileName); 354 old_name = _strdup(it->data.cFileName);
355#endif 355#endif
356 if (!old_name) 356 if (!old_name)
357 return EINA_FALSE; 357 return EINA_FALSE;
358 358
359 do { 359 do {
360 if (!FindNextFile(it->handle, &it->data)) 360 if (!FindNextFile(it->handle, &it->data))
361 { 361 {
362 if (GetLastError() == ERROR_NO_MORE_FILES) 362 if (GetLastError() == ERROR_NO_MORE_FILES)
363 it->is_last = EINA_TRUE; 363 it->is_last = EINA_TRUE;
364 else 364 else
365 res = EINA_FALSE; 365 res = EINA_FALSE;
366 } 366 }
367 367
368#ifdef UNICODE 368#ifdef UNICODE
369 length = wcslen(old_name); 369 length = wcslen(old_name);
370#else 370#else
371 length = strlen(old_name); 371 length = strlen(old_name);
372#endif 372#endif
373 if (it->info.name_start + length + 1 >= PATH_MAX) 373 if (it->info.name_start + length + 1 >= PATH_MAX)
374 { 374 {
375 free(old_name); 375 free(old_name);
376#ifdef UNICODE 376#ifdef UNICODE
377 old_name = _wcsdup(it->data.cFileName); 377 old_name = _wcsdup(it->data.cFileName);
378#else 378#else
379 old_name = _strdup(it->data.cFileName); 379 old_name = _strdup(it->data.cFileName);
380#endif 380#endif
381 continue; 381 continue;
382 } 382 }
383 383
384 } while ((it->data.cFileName[0] == '.') && 384 } while ((it->data.cFileName[0] == '.') &&
385 ((it->data.cFileName[1] == '\0') || 385 ((it->data.cFileName[1] == '\0') ||
386 ((it->data.cFileName[1] == '.') && (it->data.cFileName[2] == '\0')))); /* FIXME: what about UNICODE ? */ 386 ((it->data.cFileName[1] == '.') && (it->data.cFileName[2] == '\0')))); /* FIXME: what about UNICODE ? */
387 387
388#ifdef UNICODE 388#ifdef UNICODE
389 cname = evil_wchar_to_char(old_name); 389 cname = evil_wchar_to_char(old_name);
390 if (!cname) 390 if (!cname)
391 return EINA_FALSE; 391 return EINA_FALSE;
392#else 392#else
393 cname = old_name; 393 cname = old_name;
394#endif 394#endif
395 395
396 memcpy(it->info.path + it->info.name_start, cname, length); 396 memcpy(it->info.path + it->info.name_start, cname, length);
397 it->info.name_length = length; 397 it->info.name_length = length;
398 it->info.path_length = it->info.name_start + length; 398 it->info.path_length = it->info.name_start + length;
399 it->info.path[it->info.path_length] = '\0'; 399 it->info.path[it->info.path_length] = '\0';
400 400
401 if (attr & FILE_ATTRIBUTE_DIRECTORY) 401 if (attr & FILE_ATTRIBUTE_DIRECTORY)
402 it->info.type = EINA_FILE_DIR; 402 it->info.type = EINA_FILE_DIR;
403 else if (attr & FILE_ATTRIBUTE_REPARSE_POINT) 403 else if (attr & FILE_ATTRIBUTE_REPARSE_POINT)
404 it->info.type = EINA_FILE_LNK; 404 it->info.type = EINA_FILE_LNK;
405 else if (attr & (FILE_ATTRIBUTE_ARCHIVE | 405 else if (attr & (FILE_ATTRIBUTE_ARCHIVE |
406 FILE_ATTRIBUTE_COMPRESSED | 406 FILE_ATTRIBUTE_COMPRESSED |
407 FILE_ATTRIBUTE_COMPRESSED | 407 FILE_ATTRIBUTE_COMPRESSED |
408 FILE_ATTRIBUTE_HIDDEN | 408 FILE_ATTRIBUTE_HIDDEN |
409 FILE_ATTRIBUTE_NORMAL | 409 FILE_ATTRIBUTE_NORMAL |
410 FILE_ATTRIBUTE_SPARSE_FILE | 410 FILE_ATTRIBUTE_SPARSE_FILE |
411 FILE_ATTRIBUTE_TEMPORARY)) 411 FILE_ATTRIBUTE_TEMPORARY))
412 it->info.type = EINA_FILE_REG; 412 it->info.type = EINA_FILE_REG;
413 else 413 else
414 it->info.type = EINA_FILE_UNKNOWN; 414 it->info.type = EINA_FILE_UNKNOWN;
415 415
416 *data = &it->info; 416 *data = &it->info;
417 417
418#ifdef UNICODE 418#ifdef UNICODE
419 free(cname); 419 free(cname);
420#endif 420#endif
421 421
422 free(old_name); 422 free(old_name);
423 423
424 if (is_last) 424 if (is_last)
425 res = EINA_FALSE; 425 res = EINA_FALSE;
426 426
427 return res; 427 return res;
428} 428}
429 429
430static HANDLE 430static HANDLE
431_eina_file_win32_direct_ls_iterator_container(Eina_File_Direct_Iterator *it) 431_eina_file_win32_direct_ls_iterator_container(Eina_File_Direct_Iterator *it)
432{ 432{
433 return it->handle; 433 return it->handle;
434} 434}
435 435
436static void 436static void
437_eina_file_win32_direct_ls_iterator_free(Eina_File_Direct_Iterator *it) 437_eina_file_win32_direct_ls_iterator_free(Eina_File_Direct_Iterator *it)
438{ 438{
439 if (it->handle != INVALID_HANDLE_VALUE) 439 if (it->handle != INVALID_HANDLE_VALUE)
440 FindClose(it->handle); 440 FindClose(it->handle);
441 441
442 EINA_MAGIC_SET(&it->iterator, 0); 442 EINA_MAGIC_SET(&it->iterator, 0);
443 free(it); 443 free(it);
444} 444}
445 445
446static void 446static void
447_eina_file_real_close(Eina_File *file) 447_eina_file_real_close(Eina_File *file)
448{ 448{
449 eina_hash_free(file->rmap); 449 eina_hash_free(file->rmap);
450 eina_hash_free(file->map); 450 eina_hash_free(file->map);
451 451
452 if (file->global_map != MAP_FAILED) 452 if (file->global_map != MAP_FAILED)
453 UnmapViewOfFile(file->global_map); 453 UnmapViewOfFile(file->global_map);
454 454
455 CloseHandle(file->fm); 455 CloseHandle(file->fm);
456 CloseHandle(file->handle); 456 CloseHandle(file->handle);
457 457
458 eina_stringshare_del(file->filename); 458 eina_stringshare_del(file->filename);
459 459
460 free(file); 460 free(file);
461} 461}
462 462
463static void 463static void
464_eina_file_map_close(Eina_File_Map *map) 464_eina_file_map_close(Eina_File_Map *map)
465{ 465{
466 if (map->map != MAP_FAILED) 466 if (map->map != MAP_FAILED)
467 UnmapViewOfFile(map->map); 467 UnmapViewOfFile(map->map);
468 free(map); 468 free(map);
469} 469}
470 470
471static unsigned int 471static unsigned int
472_eina_file_map_key_length(const void *key __UNUSED__) 472_eina_file_map_key_length(const void *key __UNUSED__)
473{ 473{
474 return sizeof (unsigned long int) * 2; 474 return sizeof (unsigned long int) * 2;
475} 475}
476 476
477static int 477static int
478_eina_file_map_key_cmp(const unsigned long int *key1, int key1_length __UNUSED__, 478_eina_file_map_key_cmp(const unsigned long int *key1, int key1_length __UNUSED__,
479 const unsigned long int *key2, int key2_length __UNUSED__) 479 const unsigned long int *key2, int key2_length __UNUSED__)
480{ 480{
481 if (key1[0] - key2[0] == 0) return key1[1] - key2[1]; 481 if (key1[0] - key2[0] == 0) return key1[1] - key2[1];
482 return key1[0] - key2[0]; 482 return key1[0] - key2[0];
483} 483}
484 484
485static int 485static int
486_eina_file_map_key_hash(const unsigned long int *key, int key_length __UNUSED__) 486_eina_file_map_key_hash(const unsigned long int *key, int key_length __UNUSED__)
487{ 487{
488 return eina_hash_int64(&key[0], sizeof (unsigned long int)) 488 return eina_hash_int64(&key[0], sizeof (unsigned long int))
489 ^ eina_hash_int64(&key[1], sizeof (unsigned long int)); 489 ^ eina_hash_int64(&key[1], sizeof (unsigned long int));
490} 490}
491 491
492static char * 492static char *
493_eina_file_win32_escape(const char *path, size_t *length) 493_eina_file_win32_escape(const char *path, size_t *length)
494{ 494{
495 char *result = strdup(path ? path : ""); 495 char *result = strdup(path ? path : "");
496 char *p = result; 496 char *p = result;
497 char *q = result; 497 char *q = result;
498 size_t len; 498 size_t len;
499 499
500 if (!result) 500 if (!result)
501 return NULL; 501 return NULL;
502 502
503 if (length) len = *length; 503 if (length) len = *length;
504 else len = strlen(result); 504 else len = strlen(result);
505 505
506 while ((p = strchr(p, '/'))) 506 while ((p = strchr(p, '/')))
507 { 507 {
508 // remove double `/' 508 // remove double `/'
509 if (p[1] == '/') 509 if (p[1] == '/')
510 { 510 {
511 memmove(p, p + 1, --len - (p - result)); 511 memmove(p, p + 1, --len - (p - result));
512 result[len] = '\0'; 512 result[len] = '\0';
513 } 513 }
514 else 514 else
515 if (p[1] == '.' 515 if (p[1] == '.'
516 && p[2] == '.') 516 && p[2] == '.')
517 { 517 {
518 // remove `/../' 518 // remove `/../'
519 if (p[3] == '/') 519 if (p[3] == '/')
520 { 520 {
521 char tmp; 521 char tmp;
522 522
523 len -= p + 3 - q; 523 len -= p + 3 - q;
524 memmove(q, p + 3, len - (q - result)); 524 memmove(q, p + 3, len - (q - result));
525 result[len] = '\0'; 525 result[len] = '\0';
526 p = q; 526 p = q;
527 527
528 /* Update q correctly. */ 528 /* Update q correctly. */
529 tmp = *p; 529 tmp = *p;
530 *p = '\0'; 530 *p = '\0';
531 q = strrchr(result, '/'); 531 q = strrchr(result, '/');
532 if (!q) q = result; 532 if (!q) q = result;
533 *p = tmp; 533 *p = tmp;
534 } 534 }
535 else 535 else
536 // remove '/..$' 536 // remove '/..$'
537 if (p[3] == '\0') 537 if (p[3] == '\0')
538 { 538 {
539 len -= p + 2 - q; 539 len -= p + 2 - q;
540 result[len] = '\0'; 540 result[len] = '\0';
541 q = p; 541 q = p;
542 ++p; 542 ++p;
543 } 543 }
544 else 544 else
545 { 545 {
546 q = p; 546 q = p;
547 ++p; 547 ++p;
548 } 548 }
549 } 549 }
550 else 550 else
551 { 551 {
552 q = p; 552 q = p;
553 ++p; 553 ++p;
554 } 554 }
555 } 555 }
556 556
557 if (length) 557 if (length)
558 *length = len; 558 *length = len;
559 559
560 return result; 560 return result;
561} 561}
562 562
563 563
564/** 564/**
565 * @endcond 565 * @endcond
566 */ 566 */
567 567
568/*============================================================================* 568/*============================================================================*
569 * Global * 569 * Global *
570 *============================================================================*/ 570 *============================================================================*/
571 571
572Eina_Bool 572Eina_Bool
573eina_file_init(void) 573eina_file_init(void)
574{ 574{
575 _eina_file_log_dom = eina_log_domain_register("eina_file", 575 _eina_file_log_dom = eina_log_domain_register("eina_file",
576 EINA_LOG_COLOR_DEFAULT); 576 EINA_LOG_COLOR_DEFAULT);
577 if (_eina_file_log_dom < 0) 577 if (_eina_file_log_dom < 0)
578 { 578 {
579 EINA_LOG_ERR("Could not register log domain: eina_file"); 579 EINA_LOG_ERR("Could not register log domain: eina_file");
580 return EINA_FALSE; 580 return EINA_FALSE;
581 } 581 }
582 582
583 _eina_file_cache = eina_hash_string_djb2_new(NULL); 583 _eina_file_cache = eina_hash_string_djb2_new(NULL);
584 if (!_eina_file_cache) 584 if (!_eina_file_cache)
585 { 585 {
586 ERR("Could not create cache."); 586 ERR("Could not create cache.");
587 eina_log_domain_unregister(_eina_file_log_dom); 587 eina_log_domain_unregister(_eina_file_log_dom);
588 _eina_file_log_dom = -1; 588 _eina_file_log_dom = -1;
589 return EINA_FALSE; 589 return EINA_FALSE;
590 } 590 }
591 591
592 eina_lock_new(&_eina_file_lock_cache); 592 eina_lock_new(&_eina_file_lock_cache);
593 593
594 return EINA_TRUE; 594 return EINA_TRUE;
595} 595}
596 596
597Eina_Bool 597Eina_Bool
598eina_file_shutdown(void) 598eina_file_shutdown(void)
599{ 599{
600 if (eina_hash_population(_eina_file_cache) > 0) 600 if (eina_hash_population(_eina_file_cache) > 0)
601 { 601 {
602 Eina_Iterator *it; 602 Eina_Iterator *it;
603 const char *key; 603 const char *key;
604 604
605 it = eina_hash_iterator_key_new(_eina_file_cache); 605 it = eina_hash_iterator_key_new(_eina_file_cache);
606 EINA_ITERATOR_FOREACH(it, key) 606 EINA_ITERATOR_FOREACH(it, key)
607 ERR("File [%s] still open !", key); 607 ERR("File [%s] still open !", key);
608 eina_iterator_free(it); 608 eina_iterator_free(it);
609 } 609 }
610 610
611 eina_hash_free(_eina_file_cache); 611 eina_hash_free(_eina_file_cache);
612 612
613 eina_lock_free(&_eina_file_lock_cache); 613 eina_lock_free(&_eina_file_lock_cache);
614 614
615 eina_log_domain_unregister(_eina_file_log_dom); 615 eina_log_domain_unregister(_eina_file_log_dom);
616 _eina_file_log_dom = -1; 616 _eina_file_log_dom = -1;
617 return EINA_TRUE; 617 return EINA_TRUE;
618} 618}
619 619
620/*============================================================================* 620/*============================================================================*
621 * API * 621 * API *
622 *============================================================================*/ 622 *============================================================================*/
623 623
624 624
625EAPI char * 625EAPI char *
626eina_file_path_sanitize(const char *path) 626eina_file_path_sanitize(const char *path)
627{ 627{
628 char *result = NULL; 628 char *result = NULL;
629 size_t len; 629 size_t len;
630 630
631 if (!path) return NULL; 631 if (!path) return NULL;
632 632
633 len = strlen(path); 633 len = strlen(path);
634 if (len < 3) return NULL; 634 if (len < 3) return NULL;
635 635
636 if (!evil_path_is_absolute(path)) 636 if (!evil_path_is_absolute(path))
637 { 637 {
638 DWORD l; 638 DWORD l;
639 639
640 l = GetCurrentDirectory(0, NULL); 640 l = GetCurrentDirectory(0, NULL);
641 if (l > 0) 641 if (l > 0)
642 { 642 {
643 char *cwd; 643 char *cwd;
644 DWORD l2; 644 DWORD l2;
645 645
646 cwd = alloca(sizeof(char) * (l + 1)); 646 cwd = alloca(sizeof(char) * (l + 1));
647 l2 = GetCurrentDirectory(l + 1, cwd); 647 l2 = GetCurrentDirectory(l + 1, cwd);
648 if (l2 == l) 648 if (l2 == l)
649 { 649 {
650 char *tmp; 650 char *tmp;
651 651
652 len += l + 2; 652 len += l + 2;
653 tmp = alloca(sizeof (char) * len); 653 tmp = alloca(sizeof (char) * len);
654 snprintf(tmp, len, "%s/%s", cwd, path); 654 snprintf(tmp, len, "%s/%s", cwd, path);
655 tmp[len - 1] = '\0'; 655 tmp[len - 1] = '\0';
656 result = tmp; 656 result = tmp;
657 } 657 }
658 } 658 }
659 } 659 }
660 660
661 return _eina_file_win32_escape(result ? result : path, &len); 661 return _eina_file_win32_escape(result ? result : path, &len);
662} 662}
663 663
664EAPI Eina_Bool 664EAPI Eina_Bool
665eina_file_dir_list(const char *dir, 665eina_file_dir_list(const char *dir,
666 Eina_Bool recursive, 666 Eina_Bool recursive,
667 Eina_File_Dir_List_Cb cb, 667 Eina_File_Dir_List_Cb cb,
668 void *data) 668 void *data)
669{ 669{
670 WIN32_FIND_DATA file; 670 WIN32_FIND_DATA file;
671 HANDLE h; 671 HANDLE h;
672 char *new_dir; 672 char *new_dir;
673 673
674 EINA_SAFETY_ON_NULL_RETURN_VAL(cb, EINA_FALSE); 674 EINA_SAFETY_ON_NULL_RETURN_VAL(cb, EINA_FALSE);
675 EINA_SAFETY_ON_NULL_RETURN_VAL(dir, EINA_FALSE); 675 EINA_SAFETY_ON_NULL_RETURN_VAL(dir, EINA_FALSE);
676 EINA_SAFETY_ON_TRUE_RETURN_VAL(dir[0] == '\0', EINA_FALSE); 676 EINA_SAFETY_ON_TRUE_RETURN_VAL(dir[0] == '\0', EINA_FALSE);
677 677
678 if (!_eina_file_win32_is_dir(dir)) 678 if (!_eina_file_win32_is_dir(dir))
679 return EINA_FALSE; 679 return EINA_FALSE;
680 680
681 new_dir = _eina_file_win32_dir_new(dir); 681 new_dir = _eina_file_win32_dir_new(dir);
682 if (!new_dir) 682 if (!new_dir)
683 return EINA_FALSE; 683 return EINA_FALSE;
684 684
685 h = _eina_file_win32_first_file(new_dir, &file); 685 h = _eina_file_win32_first_file(new_dir, &file);
686 686
687 if (h == INVALID_HANDLE_VALUE) 687 if (h == INVALID_HANDLE_VALUE)
688 return EINA_FALSE; 688 return EINA_FALSE;
689 689
690 do 690 do
691 { 691 {
692 char *filename; 692 char *filename;
693 693
694# ifdef UNICODE 694# ifdef UNICODE
695 filename = evil_wchar_to_char(file.cFileName); 695 filename = evil_wchar_to_char(file.cFileName);
696# else 696# else
697 filename = file.cFileName; 697 filename = file.cFileName;
698# endif /* ! UNICODE */ 698# endif /* ! UNICODE */
699 if (!strcmp(filename, ".") || !strcmp(filename, "..")) 699 if (!strcmp(filename, ".") || !strcmp(filename, ".."))
700 continue; 700 continue;
701 701
702 cb(filename, dir, data); 702 cb(filename, dir, data);
703 703
704 if (recursive == EINA_TRUE) 704 if (recursive == EINA_TRUE)
705 { 705 {
706 char *path; 706 char *path;
707 707
708 path = alloca(strlen(dir) + strlen(filename) + 2); 708 path = alloca(strlen(dir) + strlen(filename) + 2);
709 strcpy(path, dir); 709 strcpy(path, dir);
710 strcat(path, "/"); 710 strcat(path, "/");
711 strcat(path, filename); 711 strcat(path, filename);
712 712
713 if (!(file.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) 713 if (!(file.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
714 continue; 714 continue;
715 715
716 eina_file_dir_list(path, recursive, cb, data); 716 eina_file_dir_list(path, recursive, cb, data);
717 } 717 }
718 718
719# ifdef UNICODE 719# ifdef UNICODE
720 free(filename); 720 free(filename);
721# endif /* UNICODE */ 721# endif /* UNICODE */
722 722
723 } while (FindNextFile(h, &file)); 723 } while (FindNextFile(h, &file));
724 FindClose(h); 724 FindClose(h);
725 725
726 return EINA_TRUE; 726 return EINA_TRUE;
727} 727}
728 728
729EAPI Eina_Array * 729EAPI Eina_Array *
730eina_file_split(char *path) 730eina_file_split(char *path)
731{ 731{
732 Eina_Array *ea; 732 Eina_Array *ea;
733 char *current; 733 char *current;
734 size_t length; 734 size_t length;
735 735
736 EINA_SAFETY_ON_NULL_RETURN_VAL(path, NULL); 736 EINA_SAFETY_ON_NULL_RETURN_VAL(path, NULL);
737 737
738 ea = eina_array_new(16); 738 ea = eina_array_new(16);
739 739
740 if (!ea) 740 if (!ea)
741 return NULL; 741 return NULL;
742 742
743 for (current = strchr(path, '\\'); 743 for (current = strchr(path, '\\');
744 current; 744 current;
745 path = current + 1, current = strchr(path, '\\')) 745 path = current + 1, current = strchr(path, '\\'))
746 { 746 {
747 length = current - path; 747 length = current - path;
748 748
749 if (length <= 0) 749 if (length <= 0)
750 continue; 750 continue;
751 751
752 eina_array_push(ea, path); 752 eina_array_push(ea, path);
753 *current = '\0'; 753 *current = '\0';
754 } 754 }
755 755
756 if (*path != '\0') 756 if (*path != '\0')
757 eina_array_push(ea, path); 757 eina_array_push(ea, path);
758 758
759 return ea; 759 return ea;
760} 760}
761 761
762EAPI Eina_Iterator * 762EAPI Eina_Iterator *
763eina_file_ls(const char *dir) 763eina_file_ls(const char *dir)
764{ 764{
765 Eina_File_Iterator *it; 765 Eina_File_Iterator *it;
766 char *new_dir; 766 char *new_dir;
767 size_t length; 767 size_t length;
768 768
769 EINA_SAFETY_ON_NULL_RETURN_VAL(dir, NULL); 769 EINA_SAFETY_ON_NULL_RETURN_VAL(dir, NULL);
770 770
771 if (!dir || !*dir) 771 if (!dir || !*dir)
772 return NULL; 772 return NULL;
773 773
774 if (!_eina_file_win32_is_dir(dir)) 774 if (!_eina_file_win32_is_dir(dir))
775 return NULL; 775 return NULL;
776 776
777 length = strlen(dir); 777 length = strlen(dir);
778 778
779 it = calloc(1, sizeof (Eina_File_Iterator) + length); 779 it = calloc(1, sizeof (Eina_File_Iterator) + length);
780 if (!it) 780 if (!it)
781 return NULL; 781 return NULL;
782 782
783 EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR); 783 EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR);
784 784
785 new_dir = _eina_file_win32_dir_new(dir); 785 new_dir = _eina_file_win32_dir_new(dir);
786 if (!new_dir) 786 if (!new_dir)
787 goto free_it; 787 goto free_it;
788 788
789 it->handle = _eina_file_win32_first_file(new_dir, &it->data); 789 it->handle = _eina_file_win32_first_file(new_dir, &it->data);
790 free(new_dir); 790 free(new_dir);
791 if (it->handle == INVALID_HANDLE_VALUE) 791 if (it->handle == INVALID_HANDLE_VALUE)
792 goto free_it; 792 goto free_it;
793 793
794 memcpy(it->dir, dir, length + 1); 794 memcpy(it->dir, dir, length + 1);
795 if (dir[length - 1] != '\\') 795 if (dir[length - 1] != '\\')
796 it->length = length; 796 it->length = length;
797 else 797 else
798 it->length = length - 1; 798 it->length = length - 1;
799 _eina_file_win32_backslash_change(it->dir); 799 _eina_file_win32_backslash_change(it->dir);
800 800
801 it->iterator.version = EINA_ITERATOR_VERSION; 801 it->iterator.version = EINA_ITERATOR_VERSION;
802 it->iterator.next = FUNC_ITERATOR_NEXT(_eina_file_win32_ls_iterator_next); 802 it->iterator.next = FUNC_ITERATOR_NEXT(_eina_file_win32_ls_iterator_next);
803 it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(_eina_file_win32_ls_iterator_container); 803 it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(_eina_file_win32_ls_iterator_container);
804 it->iterator.free = FUNC_ITERATOR_FREE(_eina_file_win32_ls_iterator_free); 804 it->iterator.free = FUNC_ITERATOR_FREE(_eina_file_win32_ls_iterator_free);
805 805
806 return &it->iterator; 806 return &it->iterator;
807 807
808 free_it: 808 free_it:
809 free(it); 809 free(it);
810 810
811 return NULL; 811 return NULL;
812} 812}
813 813
814EAPI Eina_Iterator * 814EAPI Eina_Iterator *
815eina_file_direct_ls(const char *dir) 815eina_file_direct_ls(const char *dir)
816{ 816{
817 Eina_File_Direct_Iterator *it; 817 Eina_File_Direct_Iterator *it;
818 char *new_dir; 818 char *new_dir;
819 size_t length; 819 size_t length;
820 820
821 EINA_SAFETY_ON_NULL_RETURN_VAL(dir, NULL); 821 EINA_SAFETY_ON_NULL_RETURN_VAL(dir, NULL);
822 822
823 if (!dir || !*dir) 823 if (!dir || !*dir)
824 return NULL; 824 return NULL;
825 825
826 length = strlen(dir); 826 length = strlen(dir);
827 827
828 if (length + 12 + 2 >= MAX_PATH) 828 if (length + 12 + 2 >= MAX_PATH)
829 return NULL; 829 return NULL;
830 830
831 it = calloc(1, sizeof(Eina_File_Direct_Iterator) + length); 831 it = calloc(1, sizeof(Eina_File_Direct_Iterator) + length);
832 if (!it) 832 if (!it)
833 return NULL; 833 return NULL;
834 834
835 EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR); 835 EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR);
836 836
837 new_dir = _eina_file_win32_dir_new(dir); 837 new_dir = _eina_file_win32_dir_new(dir);
838 if (!new_dir) 838 if (!new_dir)
839 goto free_it; 839 goto free_it;
840 840
841 it->handle = _eina_file_win32_first_file(new_dir, &it->data); 841 it->handle = _eina_file_win32_first_file(new_dir, &it->data);
842 free(new_dir); 842 free(new_dir);
843 if (it->handle == INVALID_HANDLE_VALUE) 843 if (it->handle == INVALID_HANDLE_VALUE)
844 goto free_it; 844 goto free_it;
845 845
846 memcpy(it->dir, dir, length + 1); 846 memcpy(it->dir, dir, length + 1);
847 it->length = length; 847 it->length = length;
848 _eina_file_win32_backslash_change(it->dir); 848 _eina_file_win32_backslash_change(it->dir);
849 849
850 memcpy(it->info.path, dir, length); 850 memcpy(it->info.path, dir, length);
851 if (dir[length - 1] == '\\') 851 if (dir[length - 1] == '\\')
852 it->info.name_start = length; 852 it->info.name_start = length;
853 else 853 else
854 { 854 {
855 it->info.path[length] = '\\'; 855 it->info.path[length] = '\\';
856 it->info.name_start = length + 1; 856 it->info.name_start = length + 1;
857 } 857 }
858 _eina_file_win32_backslash_change(it->info.path); 858 _eina_file_win32_backslash_change(it->info.path);
859 859
860 it->iterator.version = EINA_ITERATOR_VERSION; 860 it->iterator.version = EINA_ITERATOR_VERSION;
861 it->iterator.next = FUNC_ITERATOR_NEXT(_eina_file_win32_direct_ls_iterator_next); 861 it->iterator.next = FUNC_ITERATOR_NEXT(_eina_file_win32_direct_ls_iterator_next);
862 it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(_eina_file_win32_direct_ls_iterator_container); 862 it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(_eina_file_win32_direct_ls_iterator_container);
863 it->iterator.free = FUNC_ITERATOR_FREE(_eina_file_win32_direct_ls_iterator_free); 863 it->iterator.free = FUNC_ITERATOR_FREE(_eina_file_win32_direct_ls_iterator_free);
864 864
865 return &it->iterator; 865 return &it->iterator;
866 866
867 free_it: 867 free_it:
868 free(it); 868 free(it);
869 869
870 return NULL; 870 return NULL;
871} 871}
872 872
873EAPI Eina_Iterator * 873EAPI Eina_Iterator *
874eina_file_stat_ls(const char *dir) 874eina_file_stat_ls(const char *dir)
875{ 875{
876 return eina_file_direct_ls(dir); 876 return eina_file_direct_ls(dir);
877} 877}
878 878
879EAPI Eina_File * 879EAPI Eina_File *
880eina_file_open(const char *path, Eina_Bool shared) 880eina_file_open(const char *path, Eina_Bool shared)
881{ 881{
882 Eina_File *file; 882 Eina_File *file;
883 Eina_File *n; 883 Eina_File *n;
884 char *filename; 884 char *filename;
885 HANDLE handle; 885 HANDLE handle;
886 HANDLE fm; 886 HANDLE fm;
887 WIN32_FILE_ATTRIBUTE_DATA fad; 887 WIN32_FILE_ATTRIBUTE_DATA fad;
888 ULARGE_INTEGER length; 888 ULARGE_INTEGER length;
889 ULARGE_INTEGER mtime; 889 ULARGE_INTEGER mtime;
890 890
891 EINA_SAFETY_ON_NULL_RETURN_VAL(path, NULL); 891 EINA_SAFETY_ON_NULL_RETURN_VAL(path, NULL);
892 892
893 filename = eina_file_path_sanitize(path); 893 filename = eina_file_path_sanitize(path);
894 if (!filename) return NULL; 894 if (!filename) return NULL;
895 895
896 /* FIXME: how to emulate shm_open ? Just OpenFileMapping ? */ 896 /* FIXME: how to emulate shm_open ? Just OpenFileMapping ? */
897#if 0 897#if 0
898 if (shared) 898 if (shared)
899 handle = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, 899 handle = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ,
900 NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, 900 NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY,
901 NULL); 901 NULL);
902 else 902 else
903#endif 903#endif
904 handle = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, 904 handle = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ,
905 NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, 905 NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY,
906 NULL); 906 NULL);
907 907
908 if (handle == INVALID_HANDLE_VALUE) 908 if (handle == INVALID_HANDLE_VALUE)
909 return NULL; 909 return NULL;
910 910
911 fm = CreateFileMapping(handle, NULL, PAGE_READONLY, 0, 0, NULL); 911 fm = CreateFileMapping(handle, NULL, PAGE_READONLY, 0, 0, NULL);
912 if (!fm) 912 if (!fm)
913 goto close_handle; 913 goto close_handle;
914 914
915 if (!GetFileAttributesEx(filename, GetFileExInfoStandard, &fad)) 915 if (!GetFileAttributesEx(filename, GetFileExInfoStandard, &fad))
916 goto close_fm; 916 goto close_fm;
917 917
918 length.u.LowPart = fad.nFileSizeLow; 918 length.u.LowPart = fad.nFileSizeLow;
919 length.u.HighPart = fad.nFileSizeHigh; 919 length.u.HighPart = fad.nFileSizeHigh;
920 mtime.u.LowPart = fad.ftLastWriteTime.dwLowDateTime; 920 mtime.u.LowPart = fad.ftLastWriteTime.dwLowDateTime;
921 mtime.u.HighPart = fad.ftLastWriteTime.dwHighDateTime; 921 mtime.u.HighPart = fad.ftLastWriteTime.dwHighDateTime;
922 922
923 eina_lock_take(&_eina_file_lock_cache); 923 eina_lock_take(&_eina_file_lock_cache);
924 924
925 file = eina_hash_find(_eina_file_cache, filename); 925 file = eina_hash_find(_eina_file_cache, filename);
926 if (file && 926 if (file &&
927 (file->mtime == mtime.QuadPart && file->length == length.QuadPart)) 927 (file->mtime == mtime.QuadPart && file->length == length.QuadPart))
928 { 928 {
929 file->delete_me = EINA_TRUE; 929 file->delete_me = EINA_TRUE;
930 eina_hash_del(_eina_file_cache, file->filename, file); 930 eina_hash_del(_eina_file_cache, file->filename, file);
931 _eina_file_real_close(file); 931 _eina_file_real_close(file);
932 file = NULL; 932 file = NULL;
933 } 933 }
934 934
935 if (!file) 935 if (!file)
936 { 936 {
937 n = malloc(sizeof (Eina_File) + strlen(filename) + 1); 937 n = malloc(sizeof (Eina_File) + strlen(filename) + 1);
938 if (!n) 938 if (!n)
939 { 939 {
940 eina_lock_release(&_eina_file_lock_cache); 940 eina_lock_release(&_eina_file_lock_cache);
941 goto close_fm; 941 goto close_fm;
942 } 942 }
943 943
944 n->filename = (char*) (n + 1); 944 n->filename = (char*) (n + 1);
945 strcpy((char*) n->filename, filename); 945 strcpy((char*) n->filename, filename);
946 n->map = eina_hash_new(EINA_KEY_LENGTH(_eina_file_map_key_length), 946 n->map = eina_hash_new(EINA_KEY_LENGTH(_eina_file_map_key_length),
947 EINA_KEY_CMP(_eina_file_map_key_cmp), 947 EINA_KEY_CMP(_eina_file_map_key_cmp),
948 EINA_KEY_HASH(_eina_file_map_key_hash), 948 EINA_KEY_HASH(_eina_file_map_key_hash),
949 EINA_FREE_CB(_eina_file_map_close), 949 EINA_FREE_CB(_eina_file_map_close),
950 3); 950 3);
951 n->rmap = eina_hash_pointer_new(NULL); 951 n->rmap = eina_hash_pointer_new(NULL);
952 n->global_map = MAP_FAILED; 952 n->global_map = MAP_FAILED;
953 n->global_refcount = 0; 953 n->global_refcount = 0;
954 n->length = length.QuadPart; 954 n->length = length.QuadPart;
955 n->mtime = mtime.QuadPart; 955 n->mtime = mtime.QuadPart;
956 n->refcount = 0; 956 n->refcount = 0;
957 n->handle = handle; 957 n->handle = handle;
958 n->fm = fm; 958 n->fm = fm;
959 n->shared = shared; 959 n->shared = shared;
960 n->delete_me = EINA_FALSE; 960 n->delete_me = EINA_FALSE;
961 eina_lock_new(&n->lock); 961 eina_lock_new(&n->lock);
962 eina_hash_direct_add(_eina_file_cache, n->filename, n); 962 eina_hash_direct_add(_eina_file_cache, n->filename, n);
963 } 963 }
964 else 964 else
965 { 965 {
966 CloseHandle(fm); 966 CloseHandle(fm);
967 CloseHandle(handle); 967 CloseHandle(handle);
968 968
969 n = file; 969 n = file;
970 } 970 }
971 eina_lock_take(&n->lock); 971 eina_lock_take(&n->lock);
972 n->refcount++; 972 n->refcount++;
973 eina_lock_release(&n->lock); 973 eina_lock_release(&n->lock);
974 974
975 eina_lock_release(&_eina_file_lock_cache); 975 eina_lock_release(&_eina_file_lock_cache);
976 976
977 free(filename); 977 free(filename);
978 978
979 return n; 979 return n;
980 980
981 close_fm: 981 close_fm:
982 CloseHandle(fm); 982 CloseHandle(fm);
983 close_handle: 983 close_handle:
984 CloseHandle(handle); 984 CloseHandle(handle);
985 985
986 return NULL; 986 return NULL;
987} 987}
988 988
989EAPI void 989EAPI void
990eina_file_close(Eina_File *file) 990eina_file_close(Eina_File *file)
991{ 991{
992 EINA_SAFETY_ON_NULL_RETURN(file); 992 EINA_SAFETY_ON_NULL_RETURN(file);
993 993
994 eina_lock_take(&file->lock); 994 eina_lock_take(&file->lock);
995 file->refcount--; 995 file->refcount--;
996 eina_lock_release(&file->lock); 996 eina_lock_release(&file->lock);
997 997
998 if (file->refcount != 0) return ; 998 if (file->refcount != 0) return ;
999 eina_lock_take(&_eina_file_lock_cache); 999 eina_lock_take(&_eina_file_lock_cache);
1000 1000
1001 eina_hash_del(_eina_file_cache, file->filename, file); 1001 eina_hash_del(_eina_file_cache, file->filename, file);
1002 _eina_file_real_close(file); 1002 _eina_file_real_close(file);
1003 1003
1004 eina_lock_release(&_eina_file_lock_cache); 1004 eina_lock_release(&_eina_file_lock_cache);
1005} 1005}
1006 1006
1007EAPI size_t 1007EAPI size_t
1008eina_file_size_get(Eina_File *file) 1008eina_file_size_get(Eina_File *file)
1009{ 1009{
1010 EINA_SAFETY_ON_NULL_RETURN_VAL(file, 0); 1010 EINA_SAFETY_ON_NULL_RETURN_VAL(file, 0);
1011 return file->length; 1011 return file->length;
1012} 1012}
1013 1013
1014EAPI time_t 1014EAPI time_t
1015eina_file_mtime_get(Eina_File *file) 1015eina_file_mtime_get(Eina_File *file)
1016{ 1016{
1017 EINA_SAFETY_ON_NULL_RETURN_VAL(file, 0); 1017 EINA_SAFETY_ON_NULL_RETURN_VAL(file, 0);
1018 return file->mtime; 1018 return file->mtime;
1019} 1019}
1020 1020
1021EAPI const char * 1021EAPI const char *
1022eina_file_filename_get(Eina_File *file) 1022eina_file_filename_get(Eina_File *file)
1023{ 1023{
1024 EINA_SAFETY_ON_NULL_RETURN_VAL(file, NULL); 1024 EINA_SAFETY_ON_NULL_RETURN_VAL(file, NULL);
1025 return file->filename; 1025 return file->filename;
1026} 1026}
1027 1027
1028EAPI void * 1028EAPI void *
1029eina_file_map_all(Eina_File *file, Eina_File_Populate rule __UNUSED__) 1029eina_file_map_all(Eina_File *file, Eina_File_Populate rule __UNUSED__)
1030{ 1030{
1031 EINA_SAFETY_ON_NULL_RETURN_VAL(file, NULL); 1031 EINA_SAFETY_ON_NULL_RETURN_VAL(file, NULL);
1032 1032
1033 eina_lock_take(&file->lock); 1033 eina_lock_take(&file->lock);
1034 if (file->global_map == MAP_FAILED) 1034 if (file->global_map == MAP_FAILED)
1035 { 1035 {
1036 void *data; 1036 void *data;
1037 1037
1038 data = MapViewOfFile(file->fm, FILE_MAP_READ, 1038 data = MapViewOfFile(file->fm, FILE_MAP_READ,
1039 0, 0, file->length); 1039 0, 0, file->length);
1040 if (!data) 1040 if (!data)
1041 file->global_map = MAP_FAILED; 1041 file->global_map = MAP_FAILED;
1042 else 1042 else
1043 file->global_map = data; 1043 file->global_map = data;
1044 } 1044 }
1045 1045
1046 if (file->global_map != MAP_FAILED) 1046 if (file->global_map != MAP_FAILED)
1047 { 1047 {
1048 file->global_refcount++; 1048 file->global_refcount++;
1049 return file->global_map; 1049 return file->global_map;
1050 } 1050 }
1051 1051
1052 eina_lock_release(&file->lock); 1052 eina_lock_release(&file->lock);
1053 return NULL; 1053 return NULL;
1054} 1054}
1055 1055
1056EAPI void * 1056EAPI void *
1057eina_file_map_new(Eina_File *file, Eina_File_Populate rule, 1057eina_file_map_new(Eina_File *file, Eina_File_Populate rule,
1058 unsigned long int offset, unsigned long int length) 1058 unsigned long int offset, unsigned long int length)
1059{ 1059{
1060 Eina_File_Map *map; 1060 Eina_File_Map *map;
1061 unsigned long int key[2]; 1061 unsigned long int key[2];
1062 1062
1063 EINA_SAFETY_ON_NULL_RETURN_VAL(file, NULL); 1063 EINA_SAFETY_ON_NULL_RETURN_VAL(file, NULL);
1064 1064
1065 if (offset > file->length) 1065 if (offset > file->length)
1066 return NULL; 1066 return NULL;
1067 if (offset + length > file->length) 1067 if (offset + length > file->length)
1068 return NULL; 1068 return NULL;
1069 1069
1070 if (offset == 0 && length == file->length) 1070 if (offset == 0 && length == file->length)
1071 return eina_file_map_all(file, rule); 1071 return eina_file_map_all(file, rule);
1072 1072
1073 key[0] = offset; 1073 key[0] = offset;
1074 key[1] = length; 1074 key[1] = length;
1075 1075
1076 eina_lock_take(&file->lock); 1076 eina_lock_take(&file->lock);
1077 1077
1078 map = eina_hash_find(file->map, &key); 1078 map = eina_hash_find(file->map, &key);
1079 if (!map) 1079 if (!map)
1080 { 1080 {
1081 void *data; 1081 void *data;
1082 1082
1083 map = malloc(sizeof (Eina_File_Map)); 1083 map = malloc(sizeof (Eina_File_Map));
1084 if (!map) return NULL; 1084 if (!map) return NULL;
1085 1085
1086 data = MapViewOfFile(file->fm, FILE_MAP_READ, 1086 data = MapViewOfFile(file->fm, FILE_MAP_READ,
1087 offset & 0xffff0000, 1087 offset & 0xffff0000,
1088 offset & 0x0000ffff, 1088 offset & 0x0000ffff,
1089 length); 1089 length);
1090 if (!data) 1090 if (!data)
1091 map->map = MAP_FAILED; 1091 map->map = MAP_FAILED;
1092 else 1092 else
1093 map->map = data; 1093 map->map = data;
1094 1094
1095 map->offset = offset; 1095 map->offset = offset;
1096 map->length = length; 1096 map->length = length;
1097 map->refcount = 0; 1097 map->refcount = 0;
1098 1098
1099 if (map->map == MAP_FAILED) 1099 if (map->map == MAP_FAILED)
1100 { 1100 {
1101 free(map); 1101 free(map);
1102 return NULL; 1102 return NULL;
1103 } 1103 }
1104 1104
1105 eina_hash_add(file->map, &key, map); 1105 eina_hash_add(file->map, &key, map);
1106 eina_hash_direct_add(file->rmap, map->map, map); 1106 eina_hash_direct_add(file->rmap, map->map, map);
1107 } 1107 }
1108 1108
1109 map->refcount++; 1109 map->refcount++;
1110 1110
1111 eina_lock_release(&file->lock); 1111 eina_lock_release(&file->lock);
1112 1112
1113 return map->map; 1113 return map->map;
1114} 1114}
1115 1115
1116EAPI void 1116EAPI void
1117eina_file_map_free(Eina_File *file, void *map) 1117eina_file_map_free(Eina_File *file, void *map)
1118{ 1118{
1119 EINA_SAFETY_ON_NULL_RETURN(file); 1119 EINA_SAFETY_ON_NULL_RETURN(file);
1120 1120
1121 eina_lock_take(&file->lock); 1121 eina_lock_take(&file->lock);
1122 1122
1123 if (file->global_map == map) 1123 if (file->global_map == map)
1124 { 1124 {
1125 file->global_refcount--; 1125 file->global_refcount--;
1126 1126
1127 if (file->global_refcount > 0) goto on_exit; 1127 if (file->global_refcount > 0) goto on_exit;
1128 1128
1129 UnmapViewOfFile(file->global_map); 1129 UnmapViewOfFile(file->global_map);
1130 file->global_map = MAP_FAILED; 1130 file->global_map = MAP_FAILED;
1131 } 1131 }
1132 else 1132 else
1133 { 1133 {
1134 Eina_File_Map *em; 1134 Eina_File_Map *em;
1135 unsigned long int key[2]; 1135 unsigned long int key[2];
1136 1136
1137 em = eina_hash_find(file->rmap, &map); 1137 em = eina_hash_find(file->rmap, &map);
1138 if (!em) return ; 1138 if (!em) return ;
1139 1139
1140 em->refcount--; 1140 em->refcount--;
1141 1141
1142 if (em->refcount > 0) goto on_exit; 1142 if (em->refcount > 0) goto on_exit;
1143 1143
1144 key[0] = em->offset; 1144 key[0] = em->offset;
1145 key[1] = em->length; 1145 key[1] = em->length;
1146 1146
1147 eina_hash_del(file->rmap, &map, em); 1147 eina_hash_del(file->rmap, &map, em);
1148 eina_hash_del(file->map, &key, em); 1148 eina_hash_del(file->map, &key, em);
1149 } 1149 }
1150 1150
1151 on_exit: 1151 on_exit:
1152 eina_lock_release(&file->lock); 1152 eina_lock_release(&file->lock);
1153} 1153}