summaryrefslogtreecommitdiff
path: root/src/modules/ecordova/linux
diff options
context:
space:
mode:
authorFelipe Magno de Almeida <felipe@expertisesolutions.com.br>2015-10-28 19:39:36 -0200
committerFelipe Magno de Almeida <felipe@expertisesolutions.com.br>2015-10-28 19:39:36 -0200
commit74f70e020995860f8427633b5872c70ed27e0c0d (patch)
tree433b3668b5c58d79aa97b14d2e2af98173e58d5a /src/modules/ecordova/linux
parentb030e01b2f03b5ef3218dcbf9ecea3d958ac56ea (diff)
partial move ecordova to modules
Diffstat (limited to 'src/modules/ecordova/linux')
-rw-r--r--src/modules/ecordova/linux/ecordova_console.c216
-rw-r--r--src/modules/ecordova/linux/ecordova_console_private.h20
-rw-r--r--src/modules/ecordova/linux/ecordova_directoryentry.c361
-rw-r--r--src/modules/ecordova/linux/ecordova_directoryentry_private.h18
-rw-r--r--src/modules/ecordova/linux/ecordova_directoryreader.c210
-rw-r--r--src/modules/ecordova/linux/ecordova_directoryreader_private.h18
-rw-r--r--src/modules/ecordova/linux/ecordova_entry.c544
-rw-r--r--src/modules/ecordova/linux/ecordova_entry_private.h53
-rw-r--r--src/modules/ecordova/linux/ecordova_file.c166
-rw-r--r--src/modules/ecordova/linux/ecordova_file_private.h23
-rw-r--r--src/modules/ecordova/linux/ecordova_fileentry.c147
-rw-r--r--src/modules/ecordova/linux/ecordova_fileentry_private.h16
-rw-r--r--src/modules/ecordova/linux/ecordova_filereader.c306
-rw-r--r--src/modules/ecordova/linux/ecordova_filereader_private.h26
-rw-r--r--src/modules/ecordova/linux/ecordova_filewriter.c395
-rw-r--r--src/modules/ecordova/linux/ecordova_filewriter_private.h26
-rw-r--r--src/modules/ecordova/linux/ecordova_linux.c52
-rw-r--r--src/modules/ecordova/linux/undefs.h10
18 files changed, 2607 insertions, 0 deletions
diff --git a/src/modules/ecordova/linux/ecordova_console.c b/src/modules/ecordova/linux/ecordova_console.c
new file mode 100644
index 0000000000..53ffed0d75
--- /dev/null
+++ b/src/modules/ecordova/linux/ecordova_console.c
@@ -0,0 +1,216 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#include <Eina.h>
6#include <Eo.h>
7
8#include "ecordova_console_private.h"
9
10#include <stdbool.h>
11#include <stdint.h>
12#include <stdlib.h>
13
14#define MY_CLASS ECORDOVA_CONSOLE_CLASS
15#define MY_CLASS_NAME "Ecordova_Console"
16
17#ifdef EAPI
18# undef EAPI
19#endif
20
21#ifdef _WIN32
22# ifdef DLL_EXPORT
23# define EAPI __declspec(dllexport)
24# else
25# define EAPI
26# endif /* ! DLL_EXPORT */
27#else
28# ifdef __GNUC__
29# if __GNUC__ >= 4
30# define EAPI __attribute__ ((visibility("default")))
31# else
32# define EAPI
33# endif
34# else
35# define EAPI
36# endif
37#endif /* ! _WIN32 */
38
39/* logging support */
40extern int _ecordova_log_dom;
41
42#define CRI(...) EINA_LOG_DOM_CRIT(_ecordova_log_dom, __VA_ARGS__)
43#define ERR(...) EINA_LOG_DOM_ERR(_ecordova_log_dom, __VA_ARGS__)
44#define WRN(...) EINA_LOG_DOM_WARN(_ecordova_log_dom, __VA_ARGS__)
45#define INF(...) EINA_LOG_DOM_INFO(_ecordova_log_dom, __VA_ARGS__)
46#define DBG(...) EINA_LOG_DOM_DBG(_ecordova_log_dom, __VA_ARGS__)
47
48static void _ecordova_console_level_log(Ecordova_Console_Data *, Ecordova_Console_LoggerLevel, const char *);
49
50static Eo_Base *
51_ecordova_console_eo_base_constructor(Eo *obj, Ecordova_Console_Data *pd)
52{
53 DBG("(%p)", obj);
54
55 pd->obj = obj;
56 pd->logger_use = EINA_TRUE;
57
58 return eo_do_super_ret(obj, MY_CLASS, obj, eo_constructor());
59}
60
61static void
62_ecordova_console_constructor(Eo *obj EINA_UNUSED,
63 Ecordova_Console_Data *pd EINA_UNUSED)
64{
65 DBG("(%p)", obj);
66}
67
68static void
69_ecordova_console_eo_base_destructor(Eo *obj,
70 Ecordova_Console_Data *pd EINA_UNUSED)
71{
72 DBG("(%p)", obj);
73
74 eo_do_super(obj, MY_CLASS, eo_destructor());
75}
76
77static Ecordova_Console_LoggerLevel
78_ecordova_console_level_get(Eo *obj EINA_UNUSED, Ecordova_Console_Data *pd)
79{
80 return pd->level;
81}
82
83static void
84_ecordova_console_level_set(Eo *obj EINA_UNUSED,
85 Ecordova_Console_Data *pd,
86 Ecordova_Console_LoggerLevel value)
87{
88 pd->level = value;
89}
90
91static Eina_Bool
92_ecordova_console_console_use_get(Eo *obj EINA_UNUSED, Ecordova_Console_Data *pd)
93{
94 return pd->console_use;
95}
96
97static void
98_ecordova_console_console_use_set(Eo *obj EINA_UNUSED,
99 Ecordova_Console_Data *pd,
100 Eina_Bool value)
101{
102 pd->console_use = value;
103}
104
105static Eina_Bool
106_ecordova_console_logger_use_get(Eo *obj EINA_UNUSED, Ecordova_Console_Data *pd)
107{
108 return pd->logger_use;
109}
110
111static void
112_ecordova_console_logger_use_set(Eo *obj EINA_UNUSED,
113 Ecordova_Console_Data *pd,
114 Eina_Bool value)
115{
116 pd->logger_use = value;
117}
118
119static void
120_ecordova_console_log(Eo *obj EINA_UNUSED,
121 Ecordova_Console_Data *pd,
122 const char *message)
123{
124 _ecordova_console_level_log(pd, ECORDOVA_CONSOLE_LOGGERLEVEL_LOG, message);
125}
126
127static void
128_ecordova_console_error(Eo *obj EINA_UNUSED,
129 Ecordova_Console_Data *pd,
130 const char *message)
131{
132 _ecordova_console_level_log(pd, ECORDOVA_CONSOLE_LOGGERLEVEL_ERROR, message);
133}
134
135static void
136_ecordova_console_warn(Eo *obj EINA_UNUSED,
137 Ecordova_Console_Data *pd,
138 const char *message)
139{
140 _ecordova_console_level_log(pd, ECORDOVA_CONSOLE_LOGGERLEVEL_WARN, message);
141}
142
143static void
144_ecordova_console_info(Eo *obj EINA_UNUSED,
145 Ecordova_Console_Data *pd,
146 const char *message)
147{
148 _ecordova_console_level_log(pd, ECORDOVA_CONSOLE_LOGGERLEVEL_INFO, message);
149}
150
151static void
152_ecordova_console_debug(Eo *obj EINA_UNUSED,
153 Ecordova_Console_Data *pd,
154 const char *message)
155{
156 _ecordova_console_level_log(pd, ECORDOVA_CONSOLE_LOGGERLEVEL_DEBUG, message);
157}
158
159static void
160_ecordova_console_level_log(Ecordova_Console_Data *pd,
161 Ecordova_Console_LoggerLevel level,
162 const char *message)
163{
164 EINA_SAFETY_ON_NULL_RETURN(message);
165
166 if (level < 0 || pd->level >= ECORDOVA_CONSOLE_LOGGERLEVEL_LAST)
167 {
168 ERR("Invalid logging level: %d", level);
169 return;
170 }
171
172 if (level > pd->level) return;
173
174 if (pd->logger_use)
175 {
176 switch (level)
177 {
178 case ECORDOVA_CONSOLE_LOGGERLEVEL_LOG:
179 CRI("%s", message);
180 break;
181 case ECORDOVA_CONSOLE_LOGGERLEVEL_ERROR:
182 ERR("%s", message);
183 break;
184 case ECORDOVA_CONSOLE_LOGGERLEVEL_WARN:
185 WRN("%s", message);
186 break;
187 case ECORDOVA_CONSOLE_LOGGERLEVEL_INFO:
188 INF("%s", message);
189 break;
190 case ECORDOVA_CONSOLE_LOGGERLEVEL_DEBUG:
191 DBG("%s", message);
192 break;
193 default: break; // removes warning
194 }
195 }
196
197 const char *level_str[ECORDOVA_CONSOLE_LOGGERLEVEL_LAST] = {
198 [ECORDOVA_CONSOLE_LOGGERLEVEL_LOG] = "",
199 [ECORDOVA_CONSOLE_LOGGERLEVEL_ERROR] = "ERROR: ",
200 [ECORDOVA_CONSOLE_LOGGERLEVEL_WARN] = "WARN: ",
201 [ECORDOVA_CONSOLE_LOGGERLEVEL_INFO] = "INFO: ",
202 [ECORDOVA_CONSOLE_LOGGERLEVEL_DEBUG] = "DEBUG: ",
203 };
204
205 if (pd->console_use)
206 printf("%s%s\n", level_str[level], message);
207}
208
209#undef EOAPI
210#define EOAPI EAPI
211
212#include "undefs.h"
213
214#define ecordova_console_class_get ecordova_console_impl_class_get
215
216#include "ecordova_console.eo.c"
diff --git a/src/modules/ecordova/linux/ecordova_console_private.h b/src/modules/ecordova/linux/ecordova_console_private.h
new file mode 100644
index 0000000000..b82870bfab
--- /dev/null
+++ b/src/modules/ecordova/linux/ecordova_console_private.h
@@ -0,0 +1,20 @@
1#ifndef _ECORDOVA_CONSOLE_PRIVATE_H
2#define _ECORDOVA_CONSOLE_PRIVATE_H
3
4//#include "ecordova_private.h"
5#include "ecordova_console.eo.h"
6
7typedef struct _Ecordova_Console_Data Ecordova_Console_Data;
8
9/**
10 * Ecordova.Console private data
11 */
12struct _Ecordova_Console_Data
13{
14 Eo *obj;
15 Ecordova_Console_LoggerLevel level;
16 Eina_Bool console_use;
17 Eina_Bool logger_use;
18};
19
20#endif
diff --git a/src/modules/ecordova/linux/ecordova_directoryentry.c b/src/modules/ecordova/linux/ecordova_directoryentry.c
new file mode 100644
index 0000000000..e1bd724e59
--- /dev/null
+++ b/src/modules/ecordova/linux/ecordova_directoryentry.c
@@ -0,0 +1,361 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#include <Eo.h>
6#include <Ecore_File.h>
7#include <Ecordova_Eo.h>
8
9#include "ecordova_directoryentry_private.h"
10#include "ecordova_entry_private.h"
11
12#include <stdio.h>
13
14#ifdef EAPI
15# undef EAPI
16#endif
17
18#ifdef _WIN32
19# ifdef DLL_EXPORT
20# define EAPI __declspec(dllexport)
21# else
22# define EAPI
23# endif /* ! DLL_EXPORT */
24#else
25# ifdef __GNUC__
26# if __GNUC__ >= 4
27# define EAPI __attribute__ ((visibility("default")))
28# else
29# define EAPI
30# endif
31# else
32# define EAPI
33# endif
34#endif /* ! _WIN32 */
35
36/* logging support */
37extern int _ecordova_log_dom;
38
39#define CRI(...) EINA_LOG_DOM_CRIT(_ecordova_log_dom, __VA_ARGS__)
40#define ERR(...) EINA_LOG_DOM_ERR(_ecordova_log_dom, __VA_ARGS__)
41#define WRN(...) EINA_LOG_DOM_WARN(_ecordova_log_dom, __VA_ARGS__)
42#define INF(...) EINA_LOG_DOM_INFO(_ecordova_log_dom, __VA_ARGS__)
43#define DBG(...) EINA_LOG_DOM_DBG(_ecordova_log_dom, __VA_ARGS__)
44
45#define MY_CLASS ECORDOVA_DIRECTORYENTRY_CLASS
46#define MY_CLASS_NAME "Ecordova_DirectoryEntry"
47
48static void _remove_notify(Eo *, void *);
49static bool _is_absolute(const char *);
50static void _directory_get(Eo *, void *);
51static void _file_get(Eo *, void *);
52static void _eio_directory_get_cb(void *, Eio_File *, const Eina_Stat *);
53static void _eio_file_get_cb(void *, Eio_File *, const Eina_Stat *);
54static void _eio_create_directory_cb(void *, Eio_File *, int);
55static void _eio_fail_if_path_exists_cb(void *, Eio_File *, const Eina_Stat *);
56static void _eio_mkdir_cb(void *, Eio_File *);
57static void _set_data_path_name_native(Eio_Operation_Data *, const char *);
58static void _eio_create_file_cb(void *, Eio_File *, int);
59
60static Eo_Base *
61_ecordova_directoryentry_eo_base_constructor(Eo *obj,
62 Ecordova_DirectoryEntry_Data *pd)
63{
64 DBG("(%p)", obj);
65
66 pd->obj = obj;
67
68 return eo_do_super_ret(obj, MY_CLASS, obj, eo_constructor());
69}
70
71static void
72_ecordova_directoryentry_constructor(Eo *obj,
73 Ecordova_DirectoryEntry_Data *pd EINA_UNUSED,
74 const char *name,
75 const char *path,
76 Ecordova_FileSystem *file_system,
77 const char *url)
78{
79 DBG("(%p)", obj);
80 eo_do_super(obj, MY_CLASS, ecordova_entry_constructor(EINA_FALSE,
81 EINA_TRUE,
82 name,
83 path,
84 file_system,
85 url));
86}
87
88static void
89_ecordova_directoryentry_eo_base_destructor(Eo *obj EINA_UNUSED,
90 Ecordova_DirectoryEntry_Data *pd EINA_UNUSED)
91{
92 DBG("(%p)", obj);
93
94 eo_do_super(obj, MY_CLASS, eo_destructor());
95}
96
97static Ecordova_DirectoryReader *
98_ecordova_directoryentry_reader_create(Eo *obj,
99 Ecordova_DirectoryEntry_Data *pd EINA_UNUSED)
100{
101 Ecordova_Entry_Data *super = eo_data_scope_get(obj, ECORDOVA_ENTRY_CLASS);
102 EINA_SAFETY_ON_NULL_RETURN_VAL(super, NULL);
103
104 return eo_add(ECORDOVA_DIRECTORYREADER_CLASS, NULL,
105 ecordova_directoryreader_constructor(super->native));
106}
107
108static void
109_ecordova_directoryentry_directory_get(Eo *obj,
110 Ecordova_DirectoryEntry_Data *pd EINA_UNUSED,
111 const char *path,
112 Ecordova_FileFlags flags)
113{
114 DBG("(%p)", obj);
115 EINA_SAFETY_ON_NULL_RETURN(path);
116
117 Ecordova_Entry_Data *super = eo_data_scope_get(obj, ECORDOVA_ENTRY_CLASS);
118 EINA_SAFETY_ON_NULL_RETURN(super);
119
120 Eio_Operation_Data *data = _data_new(super, _directory_get, _error_notify);
121 _set_data_path_name_native(data, path);
122
123 Eio_Stat_Cb eio_stat_cb = _eio_directory_get_cb;
124 Eio_Error_Cb eio_error_cb = _eio_error_cb;
125
126 if (ECORDOVA_FILEFLAGS_CREATE & flags)
127 {
128 eio_error_cb = _eio_create_directory_cb;
129 if (ECORDOVA_FILEFLAGS_EXCLUSIVE & flags)
130 eio_stat_cb = _eio_fail_if_path_exists_cb;
131 }
132
133 super->pending = eina_list_append(super->pending, data);
134
135 data->file = eio_file_direct_stat(data->native,
136 eio_stat_cb,
137 eio_error_cb,
138 data);
139 EINA_SAFETY_ON_NULL_RETURN(data->file);
140}
141
142static void
143_eio_directory_get_cb(void *user_data,
144 Eio_File *handler EINA_UNUSED,
145 const Eina_Stat *stat EINA_UNUSED)
146{
147 Eio_Operation_Data *data = user_data;
148 DBG("(%p)", data->pd->obj);
149 Ecordova_DirectoryEntry *directory = eo_add(ECORDOVA_DIRECTORYENTRY_CLASS, NULL,
150 ecordova_directoryentry_constructor(data->name, data->path, NULL, data->native)); // TODO: filesystem?
151
152 data->success_cb(data->pd->obj, directory);
153 _data_free(data);
154}
155
156static void
157_eio_file_get_cb(void *user_data,
158 Eio_File *handler EINA_UNUSED,
159 const Eina_Stat *stat EINA_UNUSED)
160{
161 Eio_Operation_Data *data = user_data;
162 Ecordova_FileEntry *file = eo_add(ECORDOVA_FILEENTRY_CLASS, NULL,
163 ecordova_fileentry_constructor(data->name, data->path, NULL, data->native)); // TODO: filesystem?
164
165 data->success_cb(data->pd->obj, file);
166 _data_free(data);
167}
168
169static void
170_eio_fail_if_path_exists_cb(void *user_data,
171 Eio_File *handler EINA_UNUSED,
172 const Eina_Stat *stat EINA_UNUSED)
173{
174 Eio_Operation_Data *data = user_data;
175 DBG("(%p)", data->pd->obj);
176 Ecordova_FileError file_error = ECORDOVA_FILEERROR_PATH_EXISTS_ERR;
177 eo_do(data->pd->obj,
178 eo_event_callback_call(ECORDOVA_ENTRY_EVENT_ERROR, &file_error));
179 _data_free(data);
180}
181
182static void
183_eio_create_directory_cb(void *user_data,
184 Eio_File *handler EINA_UNUSED,
185 int error)
186{
187 Eio_Operation_Data *data = user_data;
188 DBG("(%p)", data->pd->obj);
189 if (ENOENT != error)
190 {
191 _error_notify(data->pd->obj, error);
192 _data_free(data);
193 return;
194 }
195
196 data->file = eio_file_mkdir(data->native,
197 0777,
198 _eio_mkdir_cb,
199 _eio_error_cb,
200 data);
201}
202
203static void
204_eio_create_file_cb(void *user_data,
205 Eio_File *handler EINA_UNUSED,
206 int error)
207{
208 Eio_Operation_Data *data = user_data;
209 DBG("(%p)", data->pd->obj);
210 if (ENOENT != error)
211 {
212 _error_notify(data->pd->obj, error);
213 _data_free(data);
214 return;
215 }
216
217 // TODO: Create the file in a background thread
218 FILE *fd = fopen(data->native, "ab+");
219 if (!fd)
220 {
221 _error_notify(data->pd->obj, errno);
222 _data_free(data);
223 return;
224 }
225 fclose(fd);
226
227 Ecordova_FileEntry *file = eo_add(ECORDOVA_FILEENTRY_CLASS, NULL,
228 ecordova_fileentry_constructor(data->name, data->path, NULL, data->native)); // TODO: filesystem?
229 data->success_cb(data->pd->obj, file);
230 _data_free(data);
231}
232
233static void
234_eio_mkdir_cb(void *user_data, Eio_File *handler EINA_UNUSED)
235{
236 Eio_Operation_Data *data = user_data;
237 DBG("(%p)", data->pd->obj);
238 Ecordova_DirectoryEntry *directory = eo_add(ECORDOVA_DIRECTORYENTRY_CLASS, NULL,
239 ecordova_directoryentry_constructor(data->name, data->path, NULL, data->native)); // TODO: filesystem?
240 data->success_cb(data->pd->obj, directory);
241 _data_free(data);
242}
243
244static void
245_directory_get(Eo *obj, void *data)
246{
247 Ecordova_DirectoryEntry *directory = data;
248 eo_do(obj,
249 eo_event_callback_call(ECORDOVA_DIRECTORYENTRY_EVENT_DIRECTORY_GET, directory));
250 eo_unref(directory);
251}
252
253static void
254_file_get(Eo *obj, void *data)
255{
256 Ecordova_FileEntry *file = data;
257 eo_do(obj, eo_event_callback_call(ECORDOVA_DIRECTORYENTRY_EVENT_FILE_GET, file));
258 eo_unref(file);
259}
260
261static void
262_ecordova_directoryentry_recursively_remove(Eo *obj,
263 Ecordova_DirectoryEntry_Data *pd EINA_UNUSED)
264{
265 DBG("(%p)", obj);
266
267 Ecordova_Entry_Data *super = eo_data_scope_get(obj, ECORDOVA_ENTRY_CLASS);
268 EINA_SAFETY_ON_NULL_RETURN(super);
269
270 _entry_remove(super, _remove_notify, _error_notify, true);
271}
272
273static void
274_ecordova_directoryentry_file_get(Eo *obj,
275 Ecordova_DirectoryEntry_Data *pd EINA_UNUSED,
276 const char *path,
277 Ecordova_FileFlags flags)
278{
279 EINA_SAFETY_ON_NULL_RETURN(path);
280 DBG("(%p) path=%s", obj, path);
281
282 Ecordova_Entry_Data *super = eo_data_scope_get(obj, ECORDOVA_ENTRY_CLASS);
283 EINA_SAFETY_ON_NULL_RETURN(super);
284
285 Eio_Operation_Data *data = _data_new(super, _file_get, _error_notify);
286 _set_data_path_name_native(data, path);
287
288 Eio_Stat_Cb eio_stat_cb = _eio_file_get_cb;
289 Eio_Error_Cb eio_error_cb = _eio_error_cb;
290
291 if (ECORDOVA_FILEFLAGS_CREATE & flags)
292 {
293 eio_error_cb = _eio_create_file_cb;
294 if (ECORDOVA_FILEFLAGS_EXCLUSIVE & flags)
295 eio_stat_cb = _eio_fail_if_path_exists_cb;
296 }
297
298 super->pending = eina_list_append(super->pending, data);
299
300 data->file = eio_file_direct_stat(data->native,
301 eio_stat_cb,
302 eio_error_cb,
303 data);
304}
305
306static void
307_remove_notify(Eo *obj, void *data EINA_UNUSED)
308{
309 eo_do(obj,
310 eo_event_callback_call(ECORDOVA_DIRECTORYENTRY_EVENT_REMOVE_SUCCESS, NULL));
311}
312
313static bool
314_is_absolute(const char *path)
315{
316 // TODO: not multiplatform
317 return path[0] == '/';
318}
319
320static void
321_set_data_path_name_native(Eio_Operation_Data *data, const char *path)
322{
323 EINA_SAFETY_ON_NULL_RETURN(data);
324 EINA_SAFETY_ON_NULL_RETURN(path);
325 split_path(data->pd->native, path, &data->path, &data->name, &data->native);
326}
327
328void
329split_path(const char *working_dir,
330 const char *path,
331 char **dir,
332 char **name,
333 char **url)
334{
335 EINA_SAFETY_ON_NULL_RETURN(path);
336 EINA_SAFETY_ON_NULL_RETURN(dir);
337 EINA_SAFETY_ON_NULL_RETURN(name);
338 EINA_SAFETY_ON_NULL_RETURN(url);
339
340 if (!working_dir || _is_absolute(path))
341 *url = eina_file_path_sanitize(path);
342 else
343 {
344 size_t len = strlen(working_dir) + 1 + strlen(path) + 1;
345 char buffer[len];
346 snprintf(buffer, len, "%s/%s", working_dir, path); // TODO: path separator ?
347 *url = eina_file_path_sanitize(buffer);
348 }
349
350 const char *nameonly = ecore_file_file_get(*url);
351 EINA_SAFETY_ON_NULL_RETURN(nameonly);
352 *name = strdup(nameonly);
353
354 *dir = ecore_file_dir_get(*url);
355}
356
357#include "undefs.h"
358
359#define ecordova_directoryentry_class_get ecordova_directoryentry_impl_class_get
360
361#include "ecordova_directoryentry.eo.c"
diff --git a/src/modules/ecordova/linux/ecordova_directoryentry_private.h b/src/modules/ecordova/linux/ecordova_directoryentry_private.h
new file mode 100644
index 0000000000..b1c27acf02
--- /dev/null
+++ b/src/modules/ecordova/linux/ecordova_directoryentry_private.h
@@ -0,0 +1,18 @@
1#ifndef _ECORDOVA_DIRECTORYENTRY_PRIVATE_H
2#define _ECORDOVA_DIRECTORYENTRY_PRIVATE_H
3
4//#include "ecordova_private.h"
5
6typedef struct _Ecordova_DirectoryEntry_Data Ecordova_DirectoryEntry_Data;
7
8/**
9 * Ecordova.DirectoryEntry private data
10 */
11struct _Ecordova_DirectoryEntry_Data
12{
13 Eo *obj;
14};
15
16void split_path(const char *, const char *, char **, char **, char **);
17
18#endif
diff --git a/src/modules/ecordova/linux/ecordova_directoryreader.c b/src/modules/ecordova/linux/ecordova_directoryreader.c
new file mode 100644
index 0000000000..7164887751
--- /dev/null
+++ b/src/modules/ecordova/linux/ecordova_directoryreader.c
@@ -0,0 +1,210 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#include <Eo.h>
6#include <Ecordova_Eo.h>
7
8#include "ecordova_directoryreader_private.h"
9#include "ecordova_entry_private.h"
10
11#ifdef EAPI
12# undef EAPI
13#endif
14
15#ifdef _WIN32
16# ifdef DLL_EXPORT
17# define EAPI __declspec(dllexport)
18# else
19# define EAPI
20# endif /* ! DLL_EXPORT */
21#else
22# ifdef __GNUC__
23# if __GNUC__ >= 4
24# define EAPI __attribute__ ((visibility("default")))
25# else
26# define EAPI
27# endif
28# else
29# define EAPI
30# endif
31#endif /* ! _WIN32 */
32
33/* logging support */
34extern int _ecordova_log_dom;
35
36#define CRI(...) EINA_LOG_DOM_CRIT(_ecordova_log_dom, __VA_ARGS__)
37#define ERR(...) EINA_LOG_DOM_ERR(_ecordova_log_dom, __VA_ARGS__)
38#define WRN(...) EINA_LOG_DOM_WARN(_ecordova_log_dom, __VA_ARGS__)
39#define INF(...) EINA_LOG_DOM_INFO(_ecordova_log_dom, __VA_ARGS__)
40#define DBG(...) EINA_LOG_DOM_DBG(_ecordova_log_dom, __VA_ARGS__)
41
42#define MY_CLASS ECORDOVA_DIRECTORYREADER_CLASS
43#define MY_CLASS_NAME "Ecordova_DirectoryReader"
44
45typedef struct
46{
47 Ecordova_DirectoryReader_Data *pd;
48 Eio_File *file;
49 Eina_List *entries;
50} DirectoryReader_Data;
51
52static Eina_Bool _filter_cb(void *, Eio_File *, const Eina_File_Direct_Info *);
53static void _main_cb(void *, Eio_File *, const Eina_File_Direct_Info *);
54static void _done_cb(void *, Eio_File *);
55static void _error_cb(void *, Eio_File *, int);
56static void _directory_data_free(DirectoryReader_Data *);
57
58static Eo_Base *
59_ecordova_directoryreader_eo_base_constructor(Eo *obj,
60 Ecordova_DirectoryReader_Data *pd)
61{
62 DBG("(%p)", obj);
63 fprintf(stderr, "%s:%s:%d\n", __func__, __FILE__, __LINE__); fflush(stderr);
64
65 pd->obj = obj;
66 pd->native = NULL;
67 pd->pending = NULL;
68
69 return eo_do_super_ret(obj, MY_CLASS, obj, eo_constructor());
70}
71
72static void
73_ecordova_directoryreader_constructor(Eo *obj,
74 Ecordova_DirectoryReader_Data *pd,
75 const char *native)
76{
77 DBG("(%p) url=%s", obj, native);
78 fprintf(stderr, "%s:%s:%d\n", __func__, __FILE__, __LINE__); fflush(stderr);
79 pd->native = strdup(native);
80}
81
82static void
83_ecordova_directoryreader_eo_base_destructor(Eo *obj,
84 Ecordova_DirectoryReader_Data *pd)
85{
86 DBG("(%p)", obj);
87 fprintf(stderr, "%s:%s:%d\n", __func__, __FILE__, __LINE__); fflush(stderr);
88
89 free(pd->native);
90
91 DirectoryReader_Data *data;
92 EINA_LIST_FREE(pd->pending, data)
93 {
94 eio_file_cancel(data->file);
95 _directory_data_free(data);
96 }
97
98 eo_do_super(obj, MY_CLASS, eo_destructor());
99}
100
101static void
102_ecordova_directoryreader_entries_read(Eo *obj,
103 Ecordova_DirectoryReader_Data *pd)
104{
105 DBG("(%p)", obj);
106 fprintf(stderr, "%s:%s:%d\n", __func__, __FILE__, __LINE__); fflush(stderr);
107
108 DirectoryReader_Data *data = calloc(1, sizeof(DirectoryReader_Data));
109 data->pd = pd;
110 data->file = eio_file_stat_ls(pd->native,
111 _filter_cb,
112 _main_cb,
113 _done_cb,
114 _error_cb,
115 data);
116 fprintf(stderr, "%s:%s:%d\n", __func__, __FILE__, __LINE__); fflush(stderr);
117
118 pd->pending = eina_list_append(pd->pending, data);
119 fprintf(stderr, "%s:%s:%d\n", __func__, __FILE__, __LINE__); fflush(stderr);
120}
121
122static Eina_Bool
123_filter_cb(void *data EINA_UNUSED,
124 Eio_File *handler EINA_UNUSED,
125 const Eina_File_Direct_Info *info EINA_UNUSED)
126{
127 fprintf(stderr, "%s:%s:%d\n", __func__, __FILE__, __LINE__); fflush(stderr);
128 return EINA_TRUE;
129}
130
131static void
132_main_cb(void *user_data,
133 Eio_File *handler EINA_UNUSED,
134 const Eina_File_Direct_Info *info)
135{
136 fprintf(stderr, "%s:%s:%d\n", __func__, __FILE__, __LINE__); fflush(stderr);
137 DirectoryReader_Data *data = user_data;
138 Ecordova_Entry *entry = NULL;
139
140 size_t len = info->path_length - info->name_length - 1;
141 char path[len + 1];
142 strncpy(path, info->path, len);
143 path[len] = '\0';
144
145 const char *name = &info->path[info->name_start];
146
147 switch (info->type)
148 {
149 case EINA_FILE_DIR:
150 {
151 entry = eo_add(ECORDOVA_DIRECTORYENTRY_CLASS, NULL,
152 ecordova_directoryentry_constructor(name, path, NULL, info->path)); // TODO: filesystem?
153 break;
154 }
155 case EINA_FILE_REG:
156 {
157 entry = eo_add(ECORDOVA_FILEENTRY_CLASS, NULL,
158 ecordova_fileentry_constructor(name, path, NULL, info->path)); // TODO: filesystem?
159 break;
160 }
161 // TODO: case EINA_FILE_LNK ?
162 default: break;
163 }
164
165 if (entry)
166 data->entries = eina_list_append(data->entries, entry);
167}
168
169static void
170_done_cb(void *user_data, Eio_File *handler EINA_UNUSED)
171{
172 fprintf(stderr, "%s:%s:%d\n", __func__, __FILE__, __LINE__); fflush(stderr);
173 DirectoryReader_Data *data = user_data;
174 data->pd->pending = eina_list_remove(data->pd->pending, data);
175
176 eo_do(data->pd->obj,
177 eo_event_callback_call(ECORDOVA_DIRECTORYREADER_EVENT_SUCCESS,
178 data->entries));
179 _directory_data_free(data);
180}
181
182static void
183_error_cb(void *user_data, Eio_File *handler EINA_UNUSED, int error)
184{
185 fprintf(stderr, "%s:%s:%d\n", __func__, __FILE__, __LINE__); fflush(stderr);
186 DirectoryReader_Data *data = user_data;
187 data->pd->pending = eina_list_remove(data->pd->pending, data);
188
189 Ecordova_FileError file_error = _translate_errno(error);
190 eo_do(data->pd->obj,
191 eo_event_callback_call(ECORDOVA_DIRECTORYREADER_EVENT_ERROR,
192 &file_error));
193 _directory_data_free(data);
194}
195
196static void
197_directory_data_free(DirectoryReader_Data *data)
198{
199 fprintf(stderr, "%s:%s:%d\n", __func__, __FILE__, __LINE__); fflush(stderr);
200 Ecordova_Entry *entry;
201 EINA_LIST_FREE(data->entries, entry)
202 eo_unref(entry);
203 free(data);
204}
205
206#include "undefs.h"
207
208#define ecordova_directoryreader_class_get ecordova_directoryreader_impl_class_get
209
210#include "ecordova_directoryreader.eo.c"
diff --git a/src/modules/ecordova/linux/ecordova_directoryreader_private.h b/src/modules/ecordova/linux/ecordova_directoryreader_private.h
new file mode 100644
index 0000000000..9a30a25d6f
--- /dev/null
+++ b/src/modules/ecordova/linux/ecordova_directoryreader_private.h
@@ -0,0 +1,18 @@
1#ifndef _ECORDOVA_DIRECTORYREADER_PRIVATE_H
2#define _ECORDOVA_DIRECTORYREADER_PRIVATE_H
3
4//#include "ecordova_private.h"
5
6typedef struct _Ecordova_DirectoryReader_Data Ecordova_DirectoryReader_Data;
7
8/**
9 * Ecordova.DirectoryReader private data
10 */
11struct _Ecordova_DirectoryReader_Data
12{
13 Eo *obj;
14 char *native;
15 Eina_List *pending;
16};
17
18#endif
diff --git a/src/modules/ecordova/linux/ecordova_entry.c b/src/modules/ecordova/linux/ecordova_entry.c
new file mode 100644
index 0000000000..0d2e31c7ee
--- /dev/null
+++ b/src/modules/ecordova/linux/ecordova_entry.c
@@ -0,0 +1,544 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#include <Eo.h>
6#include <Ecordova.h>
7
8#include "ecordova_entry_private.h"
9#include "ecordova_directoryentry_private.h"
10
11#ifdef EAPI
12# undef EAPI
13#endif
14
15#ifdef _WIN32
16# ifdef DLL_EXPORT
17# define EAPI __declspec(dllexport)
18# else
19# define EAPI
20# endif /* ! DLL_EXPORT */
21#else
22# ifdef __GNUC__
23# if __GNUC__ >= 4
24# define EAPI __attribute__ ((visibility("default")))
25# else
26# define EAPI
27# endif
28# else
29# define EAPI
30# endif
31#endif /* ! _WIN32 */
32
33/* logging support */
34extern int _ecordova_log_dom;
35
36#define CRI(...) EINA_LOG_DOM_CRIT(_ecordova_log_dom, __VA_ARGS__)
37#define ERR(...) EINA_LOG_DOM_ERR(_ecordova_log_dom, __VA_ARGS__)
38#define WRN(...) EINA_LOG_DOM_WARN(_ecordova_log_dom, __VA_ARGS__)
39#define INF(...) EINA_LOG_DOM_INFO(_ecordova_log_dom, __VA_ARGS__)
40#define DBG(...) EINA_LOG_DOM_DBG(_ecordova_log_dom, __VA_ARGS__)
41
42#define MY_CLASS ECORDOVA_ENTRY_CLASS
43#define MY_CLASS_NAME "Ecordova_Entry"
44
45static void _eio_stat_cb(void *, Eio_File *, const Eina_Stat *);
46static void _eio_moved_cb(void *, Eio_File *);
47static void _eio_copied_cb(void *, Eio_File *);
48static void _metadata_notify(Eo *, void *);
49static void _move_notify(Eo *, void *);
50static void _copy_notify(Eo *, void *);
51static void _remove_notify(Eo *, void *);
52static Eina_Bool _eio_remove_non_recursively_filter_cb(void *, Eio_File *, const Eina_File_Direct_Info *);
53static void _parent_get_cb(void *, Eio_File *, const Eina_Stat *);
54static void _parent_get_notify(Eo *, void *);
55
56static Eo_Base *
57_ecordova_entry_eo_base_constructor(Eo *obj, Ecordova_Entry_Data *pd)
58{
59 DBG("(%p)", obj);
60
61 pd->obj = obj;
62 pd->name = NULL;
63 pd->path = NULL;
64 pd->file_system = NULL;
65 pd->native = NULL;
66 pd->pending = NULL;
67
68 return eo_do_super_ret(obj, MY_CLASS, obj, eo_constructor());
69}
70
71static void
72_ecordova_entry_constructor(Eo *obj,
73 Ecordova_Entry_Data *pd,
74 Eina_Bool file_is,
75 Eina_Bool directory_is,
76 const char *name,
77 const char *path,
78 Ecordova_FileSystem *file_system,
79 const char *url)
80{
81 EINA_SAFETY_ON_NULL_RETURN(name);
82 EINA_SAFETY_ON_NULL_RETURN(path);
83 //EINA_SAFETY_ON_NULL_RETURN(file_system);
84 EINA_SAFETY_ON_NULL_RETURN(url);
85 DBG("(%p) name=%s, path=%s, url=%s", obj, name, path, url);
86
87 pd->is_file = file_is;
88 pd->is_directory = directory_is;
89 pd->name = strdup(name);
90 pd->path = strdup(path);
91 pd->file_system = eo_ref(file_system);
92 pd->native = strdup(url);
93}
94
95static void
96_ecordova_entry_eo_base_destructor(Eo *obj, Ecordova_Entry_Data *pd)
97{
98 DBG("(%p)", obj);
99
100 free(pd->name);
101 free(pd->path);
102 eo_unref(pd->file_system);
103 free(pd->native);
104
105 Eio_Operation_Data *data;
106 EINA_LIST_FREE(pd->pending, data)
107 {
108 eio_file_cancel(data->file);
109 _data_free(data);
110 }
111
112 eo_do_super(obj, MY_CLASS, eo_destructor());
113}
114
115static void
116_ecordova_entry_metadata_get(Eo *obj EINA_UNUSED, Ecordova_Entry_Data *pd)
117{
118 DBG("(%p)", obj);
119 _metadata_get(pd, _metadata_notify, _error_notify);
120}
121
122static void
123_ecordova_entry_metadata_set(Eo *obj EINA_UNUSED,
124 Ecordova_Entry_Data *pd EINA_UNUSED,
125 Ecordova_Metadata *metadata EINA_UNUSED)
126{
127 ERR("Not implemented.");
128}
129
130static void
131_ecordova_entry_move(Eo *obj EINA_UNUSED,
132 Ecordova_Entry_Data *pd,
133 Ecordova_DirectoryEntry *parent,
134 const char *new_name)
135{
136 DBG("(%p)", obj);
137 EINA_SAFETY_ON_NULL_RETURN(parent);
138 if (!new_name) new_name = pd->name;
139
140 Eio_Operation_Data *data = _data_new(pd, _move_notify, _error_notify);
141
142 Ecordova_Entry_Data *dest_dir = eo_data_scope_get(parent, ECORDOVA_ENTRY_CLASS);
143
144 data->name = strdup(new_name);
145 data->path = strdup(dest_dir->native);
146
147 // TODO: file_system?
148
149 size_t len = strlen(data->path) + 1 + strlen(data->name) + 1;
150 data->native = malloc(len);
151 EINA_SAFETY_ON_NULL_GOTO(data->native, on_error);
152 snprintf(data->native, len, "%s/%s", data->path, new_name);
153
154 if (pd->is_file)
155 {
156 DBG("Moving file from %s to %s", pd->native, data->native);
157 data->file = eio_file_move(pd->native,
158 data->native,
159 _eio_progress_cb,
160 _eio_moved_cb,
161 _eio_error_cb,
162 data);
163 }
164 else
165 {
166 DBG("Moving directory from %s to %s", pd->native, data->native);
167 data->file = eio_dir_move(pd->native,
168 data->native,
169 _eio_filter_cb,
170 _eio_progress_cb,
171 _eio_moved_cb,
172 _eio_error_cb,
173 data);
174 }
175
176 pd->pending = eina_list_append(pd->pending, data);
177 return;
178
179on_error:
180 _data_free(data);
181}
182
183static void
184_ecordova_entry_copy(Eo *obj EINA_UNUSED,
185 Ecordova_Entry_Data *pd,
186 Ecordova_DirectoryEntry *parent,
187 const char *new_name)
188{
189 DBG("(%p)", obj);
190 EINA_SAFETY_ON_NULL_RETURN(parent);
191 if (!new_name) new_name = pd->name;
192
193 Eio_Operation_Data *data = _data_new(pd, _copy_notify, _error_notify);
194
195 Ecordova_Entry_Data *dest_dir = eo_data_scope_get(parent, ECORDOVA_ENTRY_CLASS);
196
197 data->name = strdup(new_name);
198 data->path = strdup(dest_dir->native);
199
200 // TODO: file_system?
201
202 size_t len = strlen(data->path) + 1 + strlen(data->name) + 1;
203 data->native = malloc(len);
204 EINA_SAFETY_ON_NULL_GOTO(data->native, on_error);
205 snprintf(data->native, len, "%s/%s", data->path, new_name);
206
207 if (pd->is_file)
208 data->file = eio_file_copy(pd->native,
209 data->native,
210 _eio_progress_cb,
211 _eio_copied_cb,
212 _eio_error_cb,
213 data);
214 else
215 data->file = eio_dir_copy(pd->native,
216 data->native,
217 _eio_filter_cb,
218 _eio_progress_cb,
219 _eio_copied_cb,
220 _eio_error_cb,
221 data);
222
223 pd->pending = eina_list_append(pd->pending, data);
224 return;
225
226on_error:
227 _data_free(data);
228}
229
230static void
231_ecordova_entry_remove(Eo *obj EINA_UNUSED, Ecordova_Entry_Data *pd)
232{
233 DBG("(%p)", obj);
234 _entry_remove(pd, _remove_notify, _error_notify, false);
235}
236
237void
238_entry_remove(Ecordova_Entry_Data *pd,
239 Ecordova_Entry_Success_Callback success_cb,
240 Ecordova_Entry_Error_Callback error_cb,
241 bool recursively)
242{
243 DBG("(%p)", pd->obj);
244
245 Eio_Operation_Data *data = _data_new(pd, success_cb, error_cb);
246
247 // TODO: file_system?
248
249 if (pd->is_file)
250 data->file = eio_file_unlink(pd->native,
251 _eio_removed_cb,
252 _eio_error_cb,
253 data);
254 else
255 {
256 Eio_Filter_Direct_Cb filter_cb =
257 recursively ? _eio_filter_cb
258 : _eio_remove_non_recursively_filter_cb;
259
260 data->file = eio_dir_unlink(pd->native,
261 filter_cb,
262 _eio_progress_cb,
263 _eio_removed_cb,
264 _eio_error_cb,
265 data);
266 }
267
268 pd->pending = eina_list_append(pd->pending, data);
269}
270
271static void
272_ecordova_entry_parent_get(Eo *obj, Ecordova_Entry_Data *pd)
273{
274 DBG("(%p)", obj);
275
276 Eio_Operation_Data *data = _data_new(pd, _parent_get_notify, _error_notify);
277
278 data->file = eio_file_direct_stat(pd->native,
279 _parent_get_cb,
280 _eio_error_cb,
281 data);
282
283 pd->pending = eina_list_append(pd->pending, data);
284 }
285
286static void
287_parent_get_cb(void *user_data,
288 Eio_File *handler EINA_UNUSED,
289 const Eina_Stat *stat EINA_UNUSED)
290{
291 Eio_Operation_Data *data = user_data;
292 data->success_cb(data->pd->obj, data->pd);
293 _data_free(data);
294}
295
296static void
297_parent_get_notify(Eo *obj, void *data)
298{
299 Ecordova_Entry_Data *pd = data;
300
301 char *name, *path, *url;
302 split_path(NULL, pd->path, &path, &name, &url);
303
304 Ecordova_DirectoryEntry *parent =
305 eo_add(ECORDOVA_DIRECTORYENTRY_CLASS,
306 NULL,
307 ecordova_directoryentry_constructor(name,
308 path,
309 NULL, // TODO: filesystem ?
310 url));
311 free(name);
312 free(path);
313 free(url);
314
315 eo_do(obj, eo_event_callback_call(ECORDOVA_ENTRY_EVENT_PARENT_GET, parent));
316 eo_unref(parent);
317}
318
319static Eina_Bool
320_ecordova_entry_file_is_get(Eo *obj EINA_UNUSED, Ecordova_Entry_Data *pd)
321{
322 return pd->is_file;
323}
324
325static Eina_Bool
326_ecordova_entry_directory_is_get(Eo *obj EINA_UNUSED, Ecordova_Entry_Data *pd)
327{
328 return pd->is_directory;
329}
330
331static const char *
332_ecordova_entry_name_get(Eo *obj EINA_UNUSED, Ecordova_Entry_Data *pd)
333{
334 return pd->name;
335}
336
337static const char *
338_ecordova_entry_path_get(Eo *obj EINA_UNUSED, Ecordova_Entry_Data *pd)
339{
340 return pd->path;
341}
342
343void
344_metadata_get(Ecordova_Entry_Data *pd,
345 Ecordova_Entry_Success_Callback success_cb,
346 Ecordova_Entry_Error_Callback error_cb)
347{
348 DBG("(%p)", pd->obj);
349
350 Eio_Operation_Data *data = _data_new(pd, success_cb, error_cb);
351
352 data->file = eio_file_direct_stat(pd->native,
353 _eio_stat_cb,
354 _eio_error_cb,
355 data);
356
357 pd->pending = eina_list_append(pd->pending, data);
358}
359
360static void
361_eio_stat_cb(void *user_data,
362 Eio_File *handler EINA_UNUSED,
363 const Eina_Stat *stat)
364{
365 Eio_Operation_Data *data = user_data;
366 Ecordova_Metadata metadata = {
367 .modification_date = (time_t)stat->mtime,
368 .size = stat->size
369 };
370
371 data->success_cb(data->pd->obj, &metadata);
372 _data_free(data);
373}
374
375static void
376_metadata_notify(Eo *obj, void *data)
377{
378 eo_do(obj, eo_event_callback_call(ECORDOVA_ENTRY_EVENT_METADATA_GET, data));
379}
380
381void
382_eio_error_cb(void *user_data,
383 Eio_File *handler EINA_UNUSED,
384 int error)
385{
386 Eio_Operation_Data *data = user_data;
387 DBG("(%p)", data->pd->obj);
388 data->error_cb(data->pd->obj, error);
389 _data_free(data);
390}
391
392void
393_eio_progress_cb(void *data EINA_UNUSED,
394 Eio_File *handler EINA_UNUSED,
395 const Eio_Progress *info EINA_UNUSED)
396{
397}
398
399static void
400_eio_moved_cb(void *user_data, Eio_File *handler EINA_UNUSED)
401{
402 Eio_Operation_Data *data = user_data;
403 free(data->pd->path);
404 free(data->pd->name);
405 free(data->pd->native);
406 data->pd->path = data->path;
407 data->pd->name = data->name;
408 data->pd->native = data->native;
409 data->path = NULL;
410 data->name = NULL;
411 data->native = NULL;
412
413 data->success_cb(data->pd->obj, data->pd->obj);
414 _data_free(data);
415}
416
417static void
418_move_notify(Eo *obj, void *data)
419{
420 eo_do(obj, eo_event_callback_call(ECORDOVA_ENTRY_EVENT_MOVE_SUCCESS, data));
421}
422
423static void
424_eio_copied_cb(void *user_data, Eio_File *handler EINA_UNUSED)
425{
426 Eio_Operation_Data *data = user_data;
427 Ecordova_Entry *entry = NULL;
428 if (data->pd->is_file)
429 entry = eo_add(ECORDOVA_FILEENTRY_CLASS,
430 NULL,
431 ecordova_fileentry_constructor(data->name,
432 data->path,
433 data->pd->file_system,
434 data->native));
435 else
436 entry = eo_add(ECORDOVA_DIRECTORYENTRY_CLASS,
437 NULL,
438 ecordova_directoryentry_constructor(data->name,
439 data->path,
440 data->pd->file_system,
441 data->native));
442
443 data->success_cb(data->pd->obj, entry);
444
445 eo_unref(entry);
446 _data_free(data);
447}
448
449static void
450_copy_notify(Eo *obj, void *data)
451{
452 eo_do(obj, eo_event_callback_call(ECORDOVA_ENTRY_EVENT_COPY_SUCCESS, data));
453}
454
455void
456_eio_removed_cb(void *user_data, Eio_File *handler EINA_UNUSED)
457{
458 Eio_Operation_Data *data = user_data;
459 data->success_cb(data->pd->obj, NULL);
460 _data_free(data);
461}
462
463static void
464_remove_notify(Eo *obj, void *data)
465{
466 eo_do(obj, eo_event_callback_call(ECORDOVA_ENTRY_EVENT_REMOVE_SUCCESS, data));
467}
468
469Eina_Bool
470_eio_filter_cb(void *data EINA_UNUSED,
471 Eio_File *handler EINA_UNUSED,
472 const Eina_File_Direct_Info *info EINA_UNUSED)
473{
474 return EINA_TRUE;
475}
476
477static Eina_Bool
478_eio_remove_non_recursively_filter_cb(void *user_data,
479 Eio_File *handler EINA_UNUSED,
480 const Eina_File_Direct_Info *info EINA_UNUSED)
481{
482 Eio_Operation_Data *data = user_data;
483 DBG("filter_cb: %s", info->path);
484 if (++data->count != 1)
485 {
486 eio_file_cancel(handler);
487 return EINA_FALSE;
488 }
489
490 return EINA_TRUE;
491}
492
493Eio_Operation_Data *
494_data_new(Ecordova_Entry_Data *pd,
495 Ecordova_Entry_Success_Callback success_cb,
496 Ecordova_Entry_Error_Callback error_cb)
497{
498 Eio_Operation_Data *data = calloc(1, sizeof(Eio_Operation_Data));
499 data->pd = pd;
500 data->success_cb = success_cb;
501 data->error_cb = error_cb;
502 return data;
503}
504
505void
506_data_free(Eio_Operation_Data *data)
507{
508 EINA_SAFETY_ON_NULL_RETURN(data);
509
510 data->pd->pending = eina_list_remove(data->pd->pending, data);
511 free(data->path);
512 free(data->name);
513 free(data->native);
514 free(data);
515}
516
517void
518_error_notify(Eo *obj, int error)
519{
520 Ecordova_FileError file_error = _translate_errno(error);
521 eo_do(obj, eo_event_callback_call(ECORDOVA_ENTRY_EVENT_ERROR, &file_error));
522}
523
524Ecordova_FileError
525_translate_errno(int error)
526{
527 // TODO: translate other errors
528 switch (error)
529 {
530 case EPERM:
531 case EACCES:
532 return ECORDOVA_FILEERROR_SECURITY_ERR;
533 case ENOENT:
534 return ECORDOVA_FILEERROR_NOT_FOUND_ERR;
535 }
536
537 return -1;
538}
539
540#include "undefs.h"
541
542#define ecordova_entry_class_get ecordova_entry_impl_class_get
543
544#include "ecordova_entry.eo.c"
diff --git a/src/modules/ecordova/linux/ecordova_entry_private.h b/src/modules/ecordova/linux/ecordova_entry_private.h
new file mode 100644
index 0000000000..a50f250f81
--- /dev/null
+++ b/src/modules/ecordova/linux/ecordova_entry_private.h
@@ -0,0 +1,53 @@
1#ifndef _ECORDOVA_ENTRY_PRIVATE_H
2#define _ECORDOVA_ENTRY_PRIVATE_H
3
4//#include "ecordova_private.h"
5
6#include <Eio.h>
7
8#include <stdbool.h>
9
10typedef struct _Ecordova_Entry_Data Ecordova_Entry_Data;
11
12/**
13 * Ecordova.Entry private data
14 */
15struct _Ecordova_Entry_Data
16{
17 Eo *obj;
18 Eina_Bool is_file;
19 Eina_Bool is_directory;
20 char *name;
21 char *path;
22 Ecordova_FileSystem *file_system;
23 char *native;
24 Eina_List *pending;
25};
26
27typedef void(*Ecordova_Entry_Success_Callback)(Eo *, void *);
28typedef void(*Ecordova_Entry_Error_Callback)(Eo *, int);
29
30typedef struct
31{
32 Ecordova_Entry_Data *pd;
33 Eio_File *file;
34 char *path;
35 char *name;
36 char *native;
37 Ecordova_Entry_Success_Callback success_cb;
38 Ecordova_Entry_Error_Callback error_cb;
39 unsigned long count;
40} Eio_Operation_Data;
41
42Eio_Operation_Data *_data_new(Ecordova_Entry_Data *, Ecordova_Entry_Success_Callback, Ecordova_Entry_Error_Callback);
43void _data_free(Eio_Operation_Data *);
44void _metadata_get(Ecordova_Entry_Data *, Ecordova_Entry_Success_Callback, Ecordova_Entry_Error_Callback);
45void _entry_remove(Ecordova_Entry_Data *, Ecordova_Entry_Success_Callback, Ecordova_Entry_Error_Callback, bool);
46void _error_notify(Eo *, int);
47void _eio_error_cb(void *, Eio_File *, int);
48void _eio_removed_cb(void *, Eio_File *);
49Eina_Bool _eio_filter_cb(void *, Eio_File *, const Eina_File_Direct_Info *);
50void _eio_progress_cb(void *, Eio_File *, const Eio_Progress *);
51Ecordova_FileError _translate_errno(int);
52
53#endif
diff --git a/src/modules/ecordova/linux/ecordova_file.c b/src/modules/ecordova/linux/ecordova_file.c
new file mode 100644
index 0000000000..a7c2dec2ac
--- /dev/null
+++ b/src/modules/ecordova/linux/ecordova_file.c
@@ -0,0 +1,166 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#include "ecordova_file_private.h"
6
7#ifdef EAPI
8# undef EAPI
9#endif
10
11#ifdef _WIN32
12# ifdef DLL_EXPORT
13# define EAPI __declspec(dllexport)
14# else
15# define EAPI
16# endif /* ! DLL_EXPORT */
17#else
18# ifdef __GNUC__
19# if __GNUC__ >= 4
20# define EAPI __attribute__ ((visibility("default")))
21# else
22# define EAPI
23# endif
24# else
25# define EAPI
26# endif
27#endif /* ! _WIN32 */
28
29/* logging support */
30extern int _ecordova_log_dom;
31
32#define CRI(...) EINA_LOG_DOM_CRIT(_ecordova_log_dom, __VA_ARGS__)
33#define ERR(...) EINA_LOG_DOM_ERR(_ecordova_log_dom, __VA_ARGS__)
34#define WRN(...) EINA_LOG_DOM_WARN(_ecordova_log_dom, __VA_ARGS__)
35#define INF(...) EINA_LOG_DOM_INFO(_ecordova_log_dom, __VA_ARGS__)
36#define DBG(...) EINA_LOG_DOM_DBG(_ecordova_log_dom, __VA_ARGS__)
37
38#define MY_CLASS ECORDOVA_FILE_CLASS
39#define MY_CLASS_NAME "Ecordova_File"
40
41static Eo_Base *
42_ecordova_file_eo_base_constructor(Eo *obj, Ecordova_File_Data *pd)
43{
44 DBG("(%p)", obj);
45
46 pd->obj = obj;
47
48 return eo_do_super_ret(obj, MY_CLASS, obj, eo_constructor());
49}
50
51static void
52_ecordova_file_constructor(Eo *obj,
53 Ecordova_File_Data *pd,
54 const char *name,
55 const char *url,
56 const char *type,
57 time_t last_modified_date,
58 long size)
59{
60 DBG("(%p)", obj);
61 pd->name = name ? strdup(name) : strdup("");
62 pd->url = url ? strdup(url) : NULL;
63 pd->type = type ? strdup(type) : NULL;
64 pd->modified_date = last_modified_date;
65 pd->size = size;
66
67 pd->start = 0;
68 pd->end = pd->size;
69}
70
71static void
72_ecordova_file_eo_base_destructor(Eo *obj, Ecordova_File_Data *pd)
73{
74 DBG("(%p)", obj);
75
76 free(pd->name);
77 free(pd->url);
78 free(pd->type);
79
80 eo_do_super(obj, MY_CLASS, eo_destructor());
81}
82
83static Ecordova_File *
84_ecordova_file_slice(Eo *obj EINA_UNUSED,
85 Ecordova_File_Data *pd,
86 long start,
87 long end)
88{
89 DBG("(%p) start=%ld end=%ld", obj, start, end);
90 long size = pd->end - pd->start;
91 long new_start = 0;
92 long new_end = size;
93
94 if (start < 0)
95 new_start = MAX(size + start, 0);
96 else
97 new_start = MIN(size, start);
98
99 if (end < 0)
100 new_end = MAX(size + end, 0);
101 else
102 new_end = MIN(end, size);
103
104 if (new_start > new_end)
105 {
106 long aux = new_start;
107 new_start = new_end;
108 new_end = aux;
109 }
110
111 Ecordova_File *new_file = eo_add(MY_CLASS, NULL,
112 ecordova_file_constructor(pd->name,
113 pd->url,
114 pd->type,
115 pd->modified_date,
116 pd->size));
117 EINA_SAFETY_ON_NULL_RETURN_VAL(new_file, NULL);
118
119 Ecordova_File_Data *new_file_pd = eo_data_scope_get(new_file, MY_CLASS);
120 EINA_SAFETY_ON_NULL_GOTO(new_file_pd, on_error);
121
122 new_file_pd->start = pd->start + new_start;
123 new_file_pd->end = pd->start + new_end;
124 return new_file;
125
126on_error:
127 eo_unref(new_file);
128 return NULL;
129}
130
131static const char *
132_ecordova_file_name_get(Eo *obj EINA_UNUSED, Ecordova_File_Data *pd)
133{
134 DBG("(%p)", obj);
135 return pd->name;
136}
137
138static const char *
139_ecordova_file_url_get(Eo *obj EINA_UNUSED, Ecordova_File_Data *pd)
140{
141 DBG("(%p)", obj);
142 return pd->url;
143}
144
145static long
146_ecordova_file_start_get(Eo *obj EINA_UNUSED, Ecordova_File_Data *pd)
147{
148 DBG("(%p)", obj);
149 return pd->start;
150}
151
152static long
153_ecordova_file_end_get(Eo *obj EINA_UNUSED, Ecordova_File_Data *pd)
154{
155 DBG("(%p)", obj);
156 return pd->end;
157}
158
159#undef EOAPI
160#define EOAPI EAPI
161
162#include "undefs.h"
163
164#define ecordova_file_class_get ecordova_file_impl_class_get
165
166#include "ecordova_file.eo.c"
diff --git a/src/modules/ecordova/linux/ecordova_file_private.h b/src/modules/ecordova/linux/ecordova_file_private.h
new file mode 100644
index 0000000000..9e17c1805b
--- /dev/null
+++ b/src/modules/ecordova/linux/ecordova_file_private.h
@@ -0,0 +1,23 @@
1#ifndef _ECORDOVA_FILE_PRIVATE_H
2#define _ECORDOVA_FILE_PRIVATE_H
3
4#include "ecordova_private.h"
5
6typedef struct _Ecordova_File_Data Ecordova_File_Data;
7
8/**
9 * Ecordova.File private data
10 */
11struct _Ecordova_File_Data
12{
13 Eo *obj;
14 char *name;
15 char *url;
16 char *type;
17 time_t modified_date;
18 long size;
19 long start;
20 long end;
21};
22
23#endif
diff --git a/src/modules/ecordova/linux/ecordova_fileentry.c b/src/modules/ecordova/linux/ecordova_fileentry.c
new file mode 100644
index 0000000000..273c28dac3
--- /dev/null
+++ b/src/modules/ecordova/linux/ecordova_fileentry.c
@@ -0,0 +1,147 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#include "ecordova_fileentry_private.h"
6#include "ecordova_entry_private.h"
7
8#ifdef EAPI
9# undef EAPI
10#endif
11
12#ifdef _WIN32
13# ifdef DLL_EXPORT
14# define EAPI __declspec(dllexport)
15# else
16# define EAPI
17# endif /* ! DLL_EXPORT */
18#else
19# ifdef __GNUC__
20# if __GNUC__ >= 4
21# define EAPI __attribute__ ((visibility("default")))
22# else
23# define EAPI
24# endif
25# else
26# define EAPI
27# endif
28#endif /* ! _WIN32 */
29
30/* logging support */
31extern int _ecordova_log_dom;
32
33#define CRI(...) EINA_LOG_DOM_CRIT(_ecordova_log_dom, __VA_ARGS__)
34#define ERR(...) EINA_LOG_DOM_ERR(_ecordova_log_dom, __VA_ARGS__)
35#define WRN(...) EINA_LOG_DOM_WARN(_ecordova_log_dom, __VA_ARGS__)
36#define INF(...) EINA_LOG_DOM_INFO(_ecordova_log_dom, __VA_ARGS__)
37#define DBG(...) EINA_LOG_DOM_DBG(_ecordova_log_dom, __VA_ARGS__)
38
39#define MY_CLASS ECORDOVA_FILEENTRY_CLASS
40#define MY_CLASS_NAME "Ecordova_FileEntry"
41
42static void _file_notify(Eo *, void *);
43static void _writer_create(Eo *, void *);
44
45static Eo_Base *
46_ecordova_fileentry_eo_base_constructor(Eo *obj, Ecordova_FileEntry_Data *pd)
47{
48 DBG("(%p)", obj);
49
50 pd->obj = obj;
51
52 return eo_do_super_ret(obj, MY_CLASS, obj, eo_constructor());
53}
54
55static void
56_ecordova_fileentry_constructor(Eo *obj,
57 Ecordova_FileEntry_Data *pd EINA_UNUSED,
58 const char *name,
59 const char *path,
60 Ecordova_FileSystem *file_system,
61 const char *url)
62{
63 DBG("(%p)", obj);
64 eo_do_super(obj, MY_CLASS, ecordova_entry_constructor(EINA_TRUE,
65 EINA_FALSE,
66 name,
67 path,
68 file_system,
69 url));
70}
71
72static void
73_ecordova_fileentry_eo_base_destructor(Eo *obj,
74 Ecordova_FileEntry_Data *pd EINA_UNUSED)
75{
76 DBG("(%p)", obj);
77
78 eo_do_super(obj, MY_CLASS, eo_destructor());
79}
80
81static void
82_ecordova_fileentry_writer_create(Eo *obj,
83 Ecordova_FileEntry_Data *pd EINA_UNUSED)
84{
85 Ecordova_Entry_Data *super = eo_data_scope_get(obj, ECORDOVA_ENTRY_CLASS);
86 EINA_SAFETY_ON_NULL_RETURN(super);
87
88 _metadata_get(super, _writer_create, _error_notify);
89}
90
91static void
92_ecordova_fileentry_file(Eo *obj, Ecordova_FileEntry_Data *pd EINA_UNUSED)
93{
94 Ecordova_Entry_Data *super = eo_data_scope_get(obj, ECORDOVA_ENTRY_CLASS);
95 EINA_SAFETY_ON_NULL_RETURN(super);
96
97 _metadata_get(super, _file_notify, _error_notify);
98}
99
100static Ecordova_File *
101_create_file(Eo *obj, const Ecordova_Metadata *metadata)
102{
103 Ecordova_Entry_Data *super = eo_data_scope_get(obj, ECORDOVA_ENTRY_CLASS);
104 EINA_SAFETY_ON_NULL_RETURN_VAL(super, NULL);
105
106 return eo_add(ECORDOVA_FILE_CLASS, NULL,
107 ecordova_file_constructor(super->name,
108 super->native,
109 NULL, //< TODO: mime-type?
110 metadata->modification_date,
111 metadata->size));
112}
113
114static void
115_file_notify(Eo *obj, void *data)
116{
117 const Ecordova_Metadata *metadata = data;
118
119 Ecordova_File *file = _create_file(obj, metadata);
120
121 eo_do(obj, eo_event_callback_call(ECORDOVA_FILEENTRY_EVENT_FILE, file));
122 eo_unref(file);
123}
124
125static void
126_writer_create(Eo *obj, void *data)
127{
128 const Ecordova_Metadata *metadata = data;
129 Ecordova_File *file = _create_file(obj, metadata);
130 Ecordova_FileWriter *writer = eo_add(ECORDOVA_FILEWRITER_CLASS, NULL,
131 ecordova_filewriter_constructor(file));
132
133 eo_do(obj,
134 eo_event_callback_call(ECORDOVA_FILEENTRY_EVENT_CREATE_WRITER, writer));
135
136 eo_unref(writer);
137 eo_unref(file);
138}
139
140#undef EOAPI
141#define EOAPI EAPI
142
143#include "undefs.h"
144
145#define ecordova_fileentry_class_get ecordova_fileentry_impl_class_get
146
147#include "ecordova_fileentry.eo.c"
diff --git a/src/modules/ecordova/linux/ecordova_fileentry_private.h b/src/modules/ecordova/linux/ecordova_fileentry_private.h
new file mode 100644
index 0000000000..832aeb881c
--- /dev/null
+++ b/src/modules/ecordova/linux/ecordova_fileentry_private.h
@@ -0,0 +1,16 @@
1#ifndef _ECORDOVA_FILEENTRY_PRIVATE_H
2#define _ECORDOVA_FILEENTRY_PRIVATE_H
3
4#include "ecordova_private.h"
5
6typedef struct _Ecordova_FileEntry_Data Ecordova_FileEntry_Data;
7
8/**
9 * Ecordova.FileEntry private data
10 */
11struct _Ecordova_FileEntry_Data
12{
13 Eo *obj;
14};
15
16#endif
diff --git a/src/modules/ecordova/linux/ecordova_filereader.c b/src/modules/ecordova/linux/ecordova_filereader.c
new file mode 100644
index 0000000000..70f26af4ff
--- /dev/null
+++ b/src/modules/ecordova/linux/ecordova_filereader.c
@@ -0,0 +1,306 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#include "ecordova_filereader_private.h"
6#include "ecordova_entry_private.h"
7
8#include <Eio.h>
9
10#ifdef _WIN32
11# ifdef DLL_EXPORT
12# define EAPI __declspec(dllexport)
13# else
14# define EAPI
15# endif /* ! DLL_EXPORT */
16#else
17# ifdef __GNUC__
18# if __GNUC__ >= 4
19# define EAPI __attribute__ ((visibility("default")))
20# else
21# define EAPI
22# endif
23# else
24# define EAPI
25# endif
26#endif /* ! _WIN32 */
27
28/* logging support */
29extern int _ecordova_log_dom;
30
31#define CRI(...) EINA_LOG_DOM_CRIT(_ecordova_log_dom, __VA_ARGS__)
32#define ERR(...) EINA_LOG_DOM_ERR(_ecordova_log_dom, __VA_ARGS__)
33#define WRN(...) EINA_LOG_DOM_WARN(_ecordova_log_dom, __VA_ARGS__)
34#define INF(...) EINA_LOG_DOM_INFO(_ecordova_log_dom, __VA_ARGS__)
35#define DBG(...) EINA_LOG_DOM_DBG(_ecordova_log_dom, __VA_ARGS__)
36
37#define MY_CLASS ECORDOVA_FILEREADER_CLASS
38#define MY_CLASS_NAME "Ecordova_FileReader"
39
40static void _read_cb(void *, Ecore_Thread *);
41static void _progress_notify(size_t, size_t, Eo *, Ecore_Thread *);
42static void _read_progress_cb(void *, Ecore_Thread *, void *);
43static void _read_end_cb(void *, Ecore_Thread *);
44static void _read_abort_cb(void *, Ecore_Thread *);
45
46static Eo_Base *
47_ecordova_filereader_eo_base_constructor(Eo *obj, Ecordova_FileReader_Data *pd)
48{
49 DBG("(%p)", obj);
50
51 pd->obj = obj;
52 pd->error = 0;
53 pd->state = ECORDOVA_FILEREADER_STATE_EMPTY;
54 pd->result = NULL;
55 pd->result_length = 0;
56 pd->thread = NULL;
57 pd->url = NULL;
58 pd->offset = 0;
59 pd->length = 0;
60
61 return eo_do_super_ret(obj, MY_CLASS, obj, eo_constructor());
62}
63
64static void
65_ecordova_filereader_constructor(Eo *obj EINA_UNUSED,
66 Ecordova_FileReader_Data *pd EINA_UNUSED)
67{
68 DBG("(%p)", obj);
69}
70
71static void
72_ecordova_filereader_eo_base_destructor(Eo *obj, Ecordova_FileReader_Data *pd)
73{
74 DBG("(%p)", obj);
75
76 if (pd->thread) ERR("%s", "Destructing without aborting first");
77
78 free(pd->result);
79 free(pd->url);
80
81 eo_do_super(obj, MY_CLASS, eo_destructor());
82}
83
84static void
85_ecordova_filereader_abort(Eo *obj, Ecordova_FileReader_Data *pd)
86{
87 DBG("(%p)", obj);
88
89 if (ECORDOVA_FILEREADER_STATE_DONE == pd->state ||
90 ECORDOVA_FILEREADER_STATE_EMPTY == pd->state)
91 return;
92 pd->error = ECORDOVA_FILEERROR_ABORT_ERR;
93 pd->state = ECORDOVA_FILEREADER_STATE_DONE;
94
95 if (pd->thread)
96 ecore_thread_cancel(pd->thread);
97}
98
99static Ecordova_FileError
100_ecordova_filereader_read(Eo *obj,
101 Ecordova_FileReader_Data *pd,
102 Ecordova_File *file)
103{
104 DBG("(%p)", obj);
105 EINA_SAFETY_ON_NULL_RETURN_VAL(file, ECORDOVA_FILEERROR_SYNTAX_ERR);
106
107 if (ECORDOVA_FILEREADER_STATE_LOADING == pd->state)
108 return ECORDOVA_FILEERROR_INVALID_STATE_ERR;
109 pd->state = ECORDOVA_FILEREADER_STATE_LOADING;
110 pd->error = 0;
111
112 const char *url;
113 eo_do(file,
114 url = ecordova_file_url_get(),
115 pd->offset = ecordova_file_start_get(),
116 pd->length = ecordova_file_end_get() - pd->offset);
117 EINA_SAFETY_ON_NULL_RETURN_VAL(url, ECORDOVA_FILEERROR_SYNTAX_ERR);
118 pd->url = strdup(url);
119
120 Ecordova_ProgressEvent loadstart = {.type = "loadstart", .target = obj};
121 eo_do(obj, eo_event_callback_call(ECORDOVA_FILEREADER_EVENT_ON_LOAD_START, &loadstart));
122
123 pd->thread = ecore_thread_feedback_run(_read_cb,
124 _read_progress_cb,
125 _read_end_cb,
126 _read_abort_cb,
127 pd,
128 EINA_FALSE);
129 return 0;
130}
131
132static Ecordova_FileError
133_ecordova_filereader_error_get(Eo *obj, Ecordova_FileReader_Data *pd)
134{
135 DBG("(%p)", obj);
136 return pd->error;
137}
138
139static const char *
140_ecordova_filereader_result_get(Eo *obj, Ecordova_FileReader_Data *pd)
141{
142 DBG("(%p)", obj);
143 return pd->result;
144}
145
146static size_t
147_ecordova_filereader_length_get(Eo *obj, Ecordova_FileReader_Data *pd)
148{
149 DBG("(%p)", obj);
150 return pd->result_length;
151}
152
153static Ecordova_FileReader_State
154_ecordova_filereader_state_get(Eo *obj, Ecordova_FileReader_Data *pd)
155{
156 DBG("(%p)", obj);
157 return pd->state;
158}
159
160static void
161_read_cb(void *data, Ecore_Thread *thread)
162{
163 Ecordova_FileReader_Data *pd = data;
164 DBG("(%p)", pd->obj);
165
166 if (ecore_thread_check(thread))
167 return;
168
169 FILE *stream = fopen(pd->url, "rb");
170 if (!stream)
171 {
172 pd->error = _translate_errno(errno);
173 return;
174 }
175
176 if (pd->offset > 0)
177 {
178 int error = fseek(stream, pd->offset, SEEK_SET);
179 if (error)
180 {
181 pd->error = _translate_errno(errno);
182 goto on_error;
183 }
184 }
185
186 _progress_notify(0, pd->length, pd->obj, thread);
187 if (ecore_thread_check(thread))
188 goto on_error;
189
190 pd->result = pd->result ? realloc(pd->result, pd->length * sizeof(char))
191 : malloc(pd->length * sizeof(char));
192 if (NULL == pd->result)
193 {
194 pd->error = _translate_errno(errno);
195 goto on_error;
196 }
197
198 pd->result_length = 0;
199 size_t total = pd->length;
200 char *buffer = pd->result;
201 do
202 {
203 size_t read = fread(buffer, sizeof(char), total, stream);
204 if (!read)
205 {
206 pd->error = _translate_errno(errno);
207 goto on_error;
208 }
209
210 buffer += read;
211 total -= read;
212 pd->result_length += read;
213
214 _progress_notify(pd->length - total, pd->length, pd->obj, thread);
215 if (ecore_thread_check(thread))
216 goto on_error;
217 }
218 while (total > 0);
219
220on_error:
221 fclose(stream);
222}
223
224static void
225_progress_notify(size_t read, size_t total, Eo *obj, Ecore_Thread *thread)
226{
227 DBG("(%p)", obj);
228 Ecordova_ProgressEvent *progress = malloc(sizeof(Ecordova_ProgressEvent));
229 *progress = (Ecordova_ProgressEvent)
230 {
231 .type = "progress",
232 .length_computable = EINA_TRUE,
233 .loaded = read,
234 .total = total,
235 .target = obj
236 };
237 if (!ecore_thread_feedback(thread, progress))
238 free(progress);
239}
240
241static void
242_read_progress_cb(void *data,
243 Ecore_Thread *thread EINA_UNUSED,
244 void *msg_data)
245{
246 Ecordova_FileReader_Data *pd = data;
247 DBG("(%p)", pd->obj);
248 Ecordova_ProgressEvent *event = msg_data;
249 eo_do(pd->obj,
250 eo_event_callback_call(ECORDOVA_FILEREADER_EVENT_ON_PROGRESS, &event));
251 free(event);
252}
253
254static void
255_read_end_cb(void *data, Ecore_Thread *thread EINA_UNUSED)
256{
257 Ecordova_FileReader_Data *pd = data;
258 DBG("(%p)", pd->obj);
259
260 // If DONE (cancelled), then don't do anything
261 if (ECORDOVA_FILEREADER_STATE_DONE == pd->state)
262 return;
263 pd->thread = NULL;
264 pd->state = ECORDOVA_FILEREADER_STATE_DONE;
265
266 if (pd->error)
267 {
268 Ecordova_ProgressEvent error = {.type = "error", .target = pd->obj};
269 eo_do(pd->obj,
270 eo_event_callback_call(ECORDOVA_FILEREADER_EVENT_ON_ERROR, &error));
271 }
272 else
273 {
274 Ecordova_ProgressEvent load = {.type = "load", .target = pd->obj};
275 eo_do(pd->obj,
276 eo_event_callback_call(ECORDOVA_FILEREADER_EVENT_ON_LOAD, &load));
277 }
278
279 Ecordova_ProgressEvent loadend = {.type = "loadend", .target = pd->obj};
280 eo_do(pd->obj,
281 eo_event_callback_call(ECORDOVA_FILEREADER_EVENT_ON_LOAD_END, &loadend));
282}
283
284static void
285_read_abort_cb(void *data, Ecore_Thread *thread EINA_UNUSED)
286{
287 Ecordova_FileReader_Data *pd = data;
288 DBG("(%p)", pd->obj);
289
290 pd->thread = NULL;
291
292 Ecordova_ProgressEvent on_abort = {.type = "abort", .target = pd->obj};
293 eo_do(pd->obj, eo_event_callback_call(ECORDOVA_FILEREADER_EVENT_ON_ABORT, &on_abort));
294
295 Ecordova_ProgressEvent loadend = {.type = "loadend", .target = pd->obj};
296 eo_do(pd->obj, eo_event_callback_call(ECORDOVA_FILEREADER_EVENT_ON_LOAD_END, &loadend));
297}
298
299#undef EOAPI
300#define EOAPI EAPI
301
302#include "undefs.h"
303
304#define ecordova_filereader_class_get ecordova_filereader_impl_class_get
305
306#include "ecordova_filereader.eo.c"
diff --git a/src/modules/ecordova/linux/ecordova_filereader_private.h b/src/modules/ecordova/linux/ecordova_filereader_private.h
new file mode 100644
index 0000000000..bff6857eca
--- /dev/null
+++ b/src/modules/ecordova/linux/ecordova_filereader_private.h
@@ -0,0 +1,26 @@
1#ifndef _ECORDOVA_FILEREADER_PRIVATE_H
2#define _ECORDOVA_FILEREADER_PRIVATE_H
3
4#include "ecordova_private.h"
5
6#include <Eio.h>
7
8typedef struct _Ecordova_FileReader_Data Ecordova_FileReader_Data;
9
10/**
11 * Ecordova.FileReader private data
12 */
13struct _Ecordova_FileReader_Data
14{
15 Eo *obj;
16 Ecordova_FileError error;
17 Ecordova_FileReader_State state;
18 char *result;
19 size_t result_length;
20 Ecore_Thread *thread;
21 char *url;
22 long offset;
23 long length;
24};
25
26#endif
diff --git a/src/modules/ecordova/linux/ecordova_filewriter.c b/src/modules/ecordova/linux/ecordova_filewriter.c
new file mode 100644
index 0000000000..fd048d1f06
--- /dev/null
+++ b/src/modules/ecordova/linux/ecordova_filewriter.c
@@ -0,0 +1,395 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#include "ecordova_filewriter_private.h"
6#include "ecordova_entry_private.h"
7
8#include <stdbool.h>
9#include <unistd.h>
10
11#ifdef EAPI
12# undef EAPI
13#endif
14
15#ifdef _WIN32
16# ifdef DLL_EXPORT
17# define EAPI __declspec(dllexport)
18# else
19# define EAPI
20# endif /* ! DLL_EXPORT */
21#else
22# ifdef __GNUC__
23# if __GNUC__ >= 4
24# define EAPI __attribute__ ((visibility("default")))
25# else
26# define EAPI
27# endif
28# else
29# define EAPI
30# endif
31#endif /* ! _WIN32 */
32
33/* logging support */
34extern int _ecordova_log_dom;
35
36#define CRI(...) EINA_LOG_DOM_CRIT(_ecordova_log_dom, __VA_ARGS__)
37#define ERR(...) EINA_LOG_DOM_ERR(_ecordova_log_dom, __VA_ARGS__)
38#define WRN(...) EINA_LOG_DOM_WARN(_ecordova_log_dom, __VA_ARGS__)
39#define INF(...) EINA_LOG_DOM_INFO(_ecordova_log_dom, __VA_ARGS__)
40#define DBG(...) EINA_LOG_DOM_DBG(_ecordova_log_dom, __VA_ARGS__)
41
42#define MY_CLASS ECORDOVA_FILEWRITER_CLASS
43#define MY_CLASS_NAME "Ecordova_FileWriter"
44
45static void _write_cb(void *, Ecore_Thread *);
46static void _truncate_cb(void *, Ecore_Thread *);
47static bool _stream_init(Ecordova_FileWriter_Data *);
48static bool _offset_set(Ecordova_FileWriter_Data *);
49static void _write_end_cb(void *, Ecore_Thread *);
50static void _write_abort_cb(void *, Ecore_Thread *);
51static void _write_progress_cb(void *, Ecore_Thread *, void *);
52static void _progress_notify(size_t, size_t, Eo *, Ecore_Thread *);
53
54static Eo_Base *
55_ecordova_filewriter_eo_base_constructor(Eo *obj,
56 Ecordova_FileWriter_Data *pd)
57{
58 DBG("(%p)", obj);
59
60 pd->obj = obj;
61 pd->error = 0;
62 pd->error = ECORDOVA_FILEWRITER_STATE_INIT;
63 pd->url = NULL;
64 pd->offset = 0;
65 pd->length = 0;
66 pd->stream = NULL;
67 pd->data = NULL;
68 pd->data_size = 0;
69 pd->truncate_size = 0;
70
71 return eo_do_super_ret(obj, MY_CLASS, obj, eo_constructor());
72}
73
74static void
75_ecordova_filewriter_constructor(Eo *obj,
76 Ecordova_FileWriter_Data *pd,
77 Ecordova_File *file)
78{
79 DBG("(%p)", obj);
80 EINA_SAFETY_ON_NULL_RETURN(file);
81
82 eo_do(file,
83 pd->url = strdup(ecordova_file_url_get()),
84 pd->offset = ecordova_file_start_get(),
85 pd->length = ecordova_file_end_get() - pd->offset);
86}
87
88static void
89_ecordova_filewriter_eo_base_destructor(Eo *obj,
90 Ecordova_FileWriter_Data *pd)
91{
92 DBG("(%p)", obj);
93
94 if (pd->thread) ERR("%s", "Destructing without aborting first");
95
96 free(pd->url);
97 if (pd->stream)
98 fclose(pd->stream);
99 if (pd->data)
100 free(pd->data);
101
102 eo_do_super(obj, MY_CLASS, eo_destructor());
103}
104
105static Ecordova_FileError
106_ecordova_filewriter_abort(Eo *obj, Ecordova_FileWriter_Data *pd)
107{
108 DBG("(%p)", obj);
109
110 if (ECORDOVA_FILEWRITER_STATE_DONE == pd->state ||
111 ECORDOVA_FILEWRITER_STATE_INIT == pd->state)
112 return ECORDOVA_FILEERROR_INVALID_STATE_ERR;
113 pd->state = ECORDOVA_FILEWRITER_STATE_DONE;
114 pd->error = ECORDOVA_FILEERROR_ABORT_ERR;
115
116 if (pd->thread)
117 ecore_thread_cancel(pd->thread);
118
119 return 0;
120}
121
122static Ecordova_FileError
123_ecordova_filewriter_write(Eo *obj,
124 Ecordova_FileWriter_Data *pd,
125 const char *data,
126 long size)
127{
128 DBG("(%p)", obj);
129
130 if (ECORDOVA_FILEWRITER_STATE_WRITING == pd->state)
131 return ECORDOVA_FILEERROR_INVALID_STATE_ERR;
132 pd->state = ECORDOVA_FILEWRITER_STATE_WRITING;
133 pd->error = 0;
134
135 Ecordova_ProgressEvent writestart = {.type = "writestart", .target = obj};
136 eo_do(obj,
137 eo_event_callback_call(ECORDOVA_FILEWRITER_EVENT_ON_WRITE_START,
138 &writestart));
139
140 pd->data_size = size ? size : (long)strlen(data);
141 EINA_SAFETY_ON_FALSE_RETURN_VAL(pd->data_size > 0, ECORDOVA_FILEERROR_SYNTAX_ERR);
142
143 pd->data = pd->data ? realloc(pd->data, pd->data_size) : malloc(pd->data_size);
144 EINA_SAFETY_ON_NULL_RETURN_VAL(pd->data, ECORDOVA_FILEERROR_SYNTAX_ERR);
145
146 memcpy(pd->data, data, pd->data_size);
147
148 pd->thread = ecore_thread_feedback_run(_write_cb,
149 _write_progress_cb,
150 _write_end_cb,
151 _write_abort_cb,
152 pd,
153 EINA_FALSE);
154 return 0;
155}
156
157static Ecordova_FileError
158_ecordova_filewriter_seek(Eo *obj, Ecordova_FileWriter_Data *pd, long offset)
159{
160 DBG("(%p)", obj);
161 if (ECORDOVA_FILEWRITER_STATE_WRITING == pd->state)
162 return ECORDOVA_FILEERROR_INVALID_STATE_ERR;
163
164 if (offset < 0)
165 pd->offset = MAX(offset + pd->length, 0);
166 else if (offset > pd->length)
167 pd->offset = pd->length;
168 else
169 pd->offset = offset;
170
171 return 0;
172}
173
174static Ecordova_FileError
175_ecordova_filewriter_truncate(Eo *obj, Ecordova_FileWriter_Data *pd, long size)
176{
177 DBG("(%p)", obj);
178
179 if (ECORDOVA_FILEWRITER_STATE_WRITING == pd->state)
180 return ECORDOVA_FILEERROR_INVALID_STATE_ERR;
181 pd->state = ECORDOVA_FILEWRITER_STATE_WRITING;
182 pd->error = 0;
183 pd->truncate_size = size;
184
185 pd->thread = ecore_thread_run(_truncate_cb,
186 _write_end_cb,
187 _write_abort_cb,
188 pd);
189 return 0;
190}
191
192static Ecordova_FileError
193_ecordova_filewriter_error_get(Eo *obj, Ecordova_FileWriter_Data *pd)
194{
195 DBG("(%p)", obj);
196 return pd->error;
197}
198
199static long
200_ecordova_filewriter_position_get(Eo *obj, Ecordova_FileWriter_Data *pd)
201{
202 DBG("(%p)", obj);
203 return pd->offset;
204}
205
206static Ecordova_FileWriter_State
207_ecordova_filewriter_state_get(Eo *obj, Ecordova_FileWriter_Data *pd)
208{
209 DBG("(%p)", obj);
210 return pd->state;
211}
212
213static void
214_write_cb(void *data, Ecore_Thread *thread)
215{
216 Ecordova_FileWriter_Data *pd = data;
217 DBG("(%p)", pd->obj);
218
219 if (ecore_thread_check(thread))
220 return;
221
222 if (!pd->stream && !_stream_init(pd))
223 return;
224
225 if (!_offset_set(pd))
226 return;
227
228 _progress_notify(0, pd->data_size, pd->obj, thread);
229 if (ecore_thread_check(thread))
230 return;
231
232 size_t total = pd->data_size;
233 char *buffer = pd->data;
234 do
235 {
236 size_t written = fwrite(buffer, sizeof(char), total, pd->stream);
237 if (!written)
238 {
239 pd->error = _translate_errno(errno);
240 return;
241 }
242
243 buffer += written;
244 total -= written;
245 pd->offset += written;
246
247 _progress_notify(pd->data_size - total, pd->data_size, pd->obj, thread);
248 if (ecore_thread_check(thread))
249 return;
250 }
251 while (total > 0);
252
253 pd->length = MAX(pd->offset, pd->length);
254}
255
256static void
257_truncate_cb(void *data, Ecore_Thread *thread EINA_UNUSED)
258{
259 Ecordova_FileWriter_Data *pd = data;
260 DBG("(%p)", pd->obj);
261
262 if (ecore_thread_check(thread))
263 return;
264
265 if (!pd->stream && !_stream_init(pd))
266 return;
267
268 if (!_offset_set(pd))
269 return;
270
271 if (ftruncate(fileno(pd->stream), pd->truncate_size) != 0)
272 {
273 pd->error = _translate_errno(errno);
274 return;
275 }
276
277 pd->length = pd->truncate_size;
278 pd->offset = MIN(pd->offset, pd->truncate_size);
279}
280
281static bool
282_stream_init(Ecordova_FileWriter_Data *pd)
283{
284 pd->stream = fopen(pd->url, "rb+");
285 if (!pd->stream)
286 {
287 pd->error = _translate_errno(errno);
288 return false;
289 }
290
291 return true;
292}
293
294static bool
295_offset_set(Ecordova_FileWriter_Data *pd)
296{
297 int error = fseek(pd->stream, pd->offset, SEEK_SET);
298 if (error)
299 {
300 pd->error = _translate_errno(errno);
301 return false;
302 }
303
304 return true;
305}
306
307static void
308_progress_notify(size_t written, size_t total, Eo *obj, Ecore_Thread *thread)
309{
310 Ecordova_ProgressEvent *progress = malloc(sizeof(Ecordova_ProgressEvent));
311 *progress = (Ecordova_ProgressEvent)
312 {
313 .type = "progress",
314 .length_computable = EINA_TRUE,
315 .loaded = written,
316 .total = total,
317 .target = obj
318 };
319 if (!ecore_thread_feedback(thread, progress))
320 free(progress);
321}
322
323static void
324_write_progress_cb(void *data,
325 Ecore_Thread *thread EINA_UNUSED,
326 void *msg_data)
327{
328 Ecordova_FileWriter_Data *pd = data;
329 DBG("(%p)", pd->obj);
330 Ecordova_ProgressEvent *event = msg_data;
331 eo_do(pd->obj,
332 eo_event_callback_call(ECORDOVA_FILEWRITER_EVENT_ON_PROGRESS, &event));
333 free(event);
334}
335
336static void
337_write_end_cb(void *data, Ecore_Thread *thread EINA_UNUSED)
338{
339 Ecordova_FileWriter_Data *pd = data;
340 DBG("(%p)", pd->obj);
341
342 // If DONE (cancelled), then don't do anything
343 if (ECORDOVA_FILEWRITER_STATE_DONE == pd->state)
344 return;
345 pd->thread = NULL;
346 pd->state = ECORDOVA_FILEWRITER_STATE_DONE;
347
348 if (pd->error)
349 {
350 Ecordova_ProgressEvent error = {.type = "error", .target = pd->obj};
351 eo_do(pd->obj,
352 eo_event_callback_call(ECORDOVA_FILEWRITER_EVENT_ON_ERROR,
353 &error));
354 }
355 else
356 {
357 Ecordova_ProgressEvent write = {.type = "write", .target = pd->obj};
358 eo_do(pd->obj,
359 eo_event_callback_call(ECORDOVA_FILEWRITER_EVENT_ON_WRITE,
360 &write));
361 }
362
363 Ecordova_ProgressEvent writeend = {.type = "writeend", .target = pd->obj};
364 eo_do(pd->obj,
365 eo_event_callback_call(ECORDOVA_FILEWRITER_EVENT_ON_WRITE_END,
366 &writeend));
367}
368
369static void
370_write_abort_cb(void *data, Ecore_Thread *thread EINA_UNUSED)
371{
372 Ecordova_FileWriter_Data *pd = data;
373 DBG("(%p)", pd->obj);
374
375 pd->thread = NULL;
376
377 Ecordova_ProgressEvent on_abort = {.type = "abort", .target = pd->obj};
378 eo_do(pd->obj,
379 eo_event_callback_call(ECORDOVA_FILEWRITER_EVENT_ON_ABORT,
380 &on_abort));
381
382 Ecordova_ProgressEvent writeend = {.type = "writeend", .target = pd->obj};
383 eo_do(pd->obj,
384 eo_event_callback_call(ECORDOVA_FILEWRITER_EVENT_ON_WRITE_END,
385 &writeend));
386}
387
388#undef EOAPI
389#define EOAPI EAPI
390
391#include "undefs.h"
392
393#define ecordova_filewriter_class_get ecordova_filewriter_impl_class_get
394
395#include "ecordova_filewriter.eo.c"
diff --git a/src/modules/ecordova/linux/ecordova_filewriter_private.h b/src/modules/ecordova/linux/ecordova_filewriter_private.h
new file mode 100644
index 0000000000..459d1c671f
--- /dev/null
+++ b/src/modules/ecordova/linux/ecordova_filewriter_private.h
@@ -0,0 +1,26 @@
1#ifndef _ECORDOVA_FILEWRITER_PRIVATE_H
2#define _ECORDOVA_FILEWRITER_PRIVATE_H
3
4#include "ecordova_private.h"
5
6typedef struct _Ecordova_FileWriter_Data Ecordova_FileWriter_Data;
7
8/**
9 * Ecordova.FileWriter private data
10 */
11struct _Ecordova_FileWriter_Data
12{
13 Eo *obj;
14 Ecordova_FileError error;
15 Ecordova_FileWriter_State state;
16 char *url;
17 long offset;
18 long length;
19 FILE *stream;
20 char *data;
21 long data_size;
22 long truncate_size;
23 Ecore_Thread *thread;
24};
25
26#endif
diff --git a/src/modules/ecordova/linux/ecordova_linux.c b/src/modules/ecordova/linux/ecordova_linux.c
new file mode 100644
index 0000000000..ae37dee862
--- /dev/null
+++ b/src/modules/ecordova/linux/ecordova_linux.c
@@ -0,0 +1,52 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#include <Ecore.h>
6
7int _ecordova_log_dom;
8
9#define CRI(...) EINA_LOG_DOM_CRIT(_ecordova_log_dom, __VA_ARGS__)
10#define ERR(...) EINA_LOG_DOM_ERR(_ecordova_log_dom, __VA_ARGS__)
11#define WRN(...) EINA_LOG_DOM_WARN(_ecordova_log_dom, __VA_ARGS__)
12#define INF(...) EINA_LOG_DOM_INFO(_ecordova_log_dom, __VA_ARGS__)
13#define DBG(...) EINA_LOG_DOM_DBG(_ecordova_log_dom, __VA_ARGS__)
14
15static Eina_Bool
16_ecordova_linux_init(void)
17{
18 fprintf(stderr, "%s:%s:%d\n", __func__, __FILE__, __LINE__); fflush(stderr);
19
20 _ecordova_log_dom = eina_log_domain_register("ecordova_linux", EINA_COLOR_CYAN);
21 if (_ecordova_log_dom < 0)
22 {
23 EINA_LOG_ERR("Unable to create an 'ecordova' log domain");
24 //goto on_error_1;
25 }
26
27 if (!ecore_file_init())
28 {
29 ERR("Unable to initialize ecore_file");
30 //goto on_error_3;
31 }
32
33 if (!eio_init())
34 {
35 ERR("Unable to initialize eio");
36 //goto on_error_4;
37 }
38
39
40 return EINA_TRUE;
41}
42
43static void
44_ecordova_linux_shutdown(void)
45{
46 fprintf(stderr, "%s:%s:%d\n", __func__, __FILE__, __LINE__); fflush(stderr);
47 eio_shutdown();
48 ecore_file_shutdown();
49}
50
51EINA_MODULE_INIT(_ecordova_linux_init);
52EINA_MODULE_SHUTDOWN(_ecordova_linux_shutdown);
diff --git a/src/modules/ecordova/linux/undefs.h b/src/modules/ecordova/linux/undefs.h
new file mode 100644
index 0000000000..83955a3bf8
--- /dev/null
+++ b/src/modules/ecordova/linux/undefs.h
@@ -0,0 +1,10 @@
1
2#undef EO_FUNC_BODY
3#define EO_FUNC_BODY(...)
4#undef EO_VOID_FUNC_BODY
5#define EO_VOID_FUNC_BODY(...)
6#undef EO_FUNC_BODYV
7#define EO_FUNC_BODYV(...)
8#undef EO_VOID_FUNC_BODYV
9#define EO_VOID_FUNC_BODYV(...)
10