summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/bin/Makefile.am2
-rw-r--r--src/bin/eet/Makefile.am17
-rw-r--r--src/bin/eet/eet_main.c507
-rw-r--r--src/examples/Makefile.am6
-rw-r--r--src/examples/eet/Makefile.am50
-rw-r--r--src/examples/eet/eet-basic.c40
-rw-r--r--src/examples/eet/eet-data-cipher_decipher.c119
-rw-r--r--src/examples/eet/eet-data-file_descriptor_01.c529
-rw-r--r--src/examples/eet/eet-data-file_descriptor_02.c944
-rw-r--r--src/examples/eet/eet-data-nested.c272
-rw-r--r--src/examples/eet/eet-data-simple.c224
-rw-r--r--src/examples/eet/eet-file.c127
-rw-r--r--src/examples/eina/Makefile.am2
-rw-r--r--src/lib/Makefile.am2
-rw-r--r--src/lib/eet/Eet.h4271
-rw-r--r--src/lib/eet/Eet_private.h329
-rw-r--r--src/lib/eet/Makefile.am43
-rw-r--r--src/lib/eet/eet_alloc.c93
-rw-r--r--src/lib/eet/eet_cipher.c1391
-rw-r--r--src/lib/eet/eet_connection.c228
-rw-r--r--src/lib/eet/eet_data.c5014
-rw-r--r--src/lib/eet/eet_dictionary.c514
-rw-r--r--src/lib/eet/eet_image.c1881
-rw-r--r--src/lib/eet/eet_lib.c2707
-rw-r--r--src/lib/eet/eet_node.c797
-rw-r--r--src/lib/eet/eet_utils.c36
-rw-r--r--src/lib/eet/lz4/README7
-rw-r--r--src/lib/eet/lz4/lz4.c819
-rw-r--r--src/lib/eet/lz4/lz4.h120
-rw-r--r--src/lib/eet/lz4/lz4hc.c663
-rw-r--r--src/lib/eet/lz4/lz4hc.h60
-rw-r--r--src/tests/Makefile.am2
-rw-r--r--src/tests/eet/Makefile.am19
-rw-r--r--src/tests/eet/TODO3
-rw-r--r--src/tests/eet/cert.pem22
-rw-r--r--src/tests/eet/eet_data_suite.c73
-rw-r--r--src/tests/eet/eet_suite.c2779
-rw-r--r--src/tests/eet/eet_suite.h9
-rw-r--r--src/tests/eet/key.pem15
-rw-r--r--src/tests/eet/key_enc.pem17
-rw-r--r--src/tests/eet/key_enc_none.pem16
41 files changed, 24764 insertions, 5 deletions
diff --git a/src/bin/Makefile.am b/src/bin/Makefile.am
index d89d02e560..70889282e3 100644
--- a/src/bin/Makefile.am
+++ b/src/bin/Makefile.am
@@ -7,3 +7,5 @@ if HAVE_WINDOWS
7SUBDIRS += evil 7SUBDIRS += evil
8 8
9endif 9endif
10
11SUBDIRS += eet
diff --git a/src/bin/eet/Makefile.am b/src/bin/eet/Makefile.am
new file mode 100644
index 0000000000..af5fa844c8
--- /dev/null
+++ b/src/bin/eet/Makefile.am
@@ -0,0 +1,17 @@
1
2MAINTAINERCLEANFILES = Makefile.in
3
4AM_CPPFLAGS = \
5-I$(top_srcdir)/src/lib/eet \
6-I$(top_builddir)/src/lib/eet \
7-DPACKAGE_BIN_DIR=\"$(bindir)\" \
8-DPACKAGE_LIB_DIR=\"$(libdir)\" \
9-DPACKAGE_DATA_DIR=\"$(datadir)/$(PACKAGE)\" \
10@EET_CFLAGS@
11
12bin_PROGRAMS = @EET_PRG@
13EXTRA_PROGRAMS = eet
14
15eet_SOURCES = eet_main.c
16eet_LDADD = $(top_builddir)/src/lib/eet/libeet.la @EET_LIBS@
17eet_LDFLAGS = @lt_enable_auto_import@
diff --git a/src/bin/eet/eet_main.c b/src/bin/eet/eet_main.c
new file mode 100644
index 0000000000..8a93d11b4f
--- /dev/null
+++ b/src/bin/eet/eet_main.c
@@ -0,0 +1,507 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif /* ifdef HAVE_CONFIG_H */
4
5#include <stdio.h>
6#include <stdlib.h>
7#include <string.h>
8
9#ifdef HAVE_UNISTD_H
10# include <unistd.h>
11#endif /* ifdef HAVE_UNISTD_H */
12
13#ifdef HAVE_EVIL
14# include <Evil.h>
15#endif /* ifdef HAVE_EVIL */
16
17#include <Eet.h>
18
19static int _eet_main_log_dom = -1;
20
21#ifdef EET_DEFAULT_LOG_COLOR
22#undef EET_DEFAULT_LOG_COLOR
23#endif /* ifdef EET_DEFAULT_LOG_COLOR */
24#define EET_DEFAULT_LOG_COLOR EINA_COLOR_CYAN
25#ifdef ERR
26#undef ERR
27#endif /* ifdef ERR */
28#define ERR(...) EINA_LOG_DOM_ERR(_eet_main_log_dom, __VA_ARGS__)
29#ifdef DBG
30#undef DBG
31#endif /* ifdef DBG */
32#define DBG(...) EINA_LOG_DOM_DBG(_eet_main_log_dom, __VA_ARGS__)
33#ifdef INF
34#undef INF
35#endif /* ifdef INF */
36#define INF(...) EINA_LOG_DOM_INFO(_eet_main_log_dom, __VA_ARGS__)
37#ifdef WRN
38#undef WRN
39#endif /* ifdef WRN */
40#define WRN(...) EINA_LOG_DOM_WARN(_eet_main_log_dom, __VA_ARGS__)
41#ifdef CRIT
42#undef CRIT
43#endif /* ifdef CRIT */
44#define CRIT(...) EINA_LOG_DOM_CRIT(_eet_main_log_dom, __VA_ARGS__)
45
46static void
47do_eet_list(const char *file)
48{
49 int i, num;
50 char **list;
51 Eet_File *ef;
52
53 ef = eet_open(file, EET_FILE_MODE_READ);
54 if (!ef)
55 {
56 ERR("cannot open for reading: %s", file);
57 exit(-1);
58 }
59
60 list = eet_list(ef, "*", &num);
61 if (list)
62 {
63 for (i = 0; i < num; i++)
64 printf("%s\n", list[i]);
65 free(list);
66 }
67
68 eet_close(ef);
69} /* do_eet_list */
70
71static void
72do_eet_stats(const char *file)
73{
74 int i, num;
75 int count[2] = { 0, 0 };
76 int size[2] = { 0, 0 };
77 char **list;
78 Eet_File *ef;
79 Eet_Dictionary *ed;
80
81 ef = eet_open(file, EET_FILE_MODE_READ);
82 if (!ef)
83 {
84 ERR("cannot open for reading: %s", file);
85 exit(-1);
86 }
87
88 printf("*** sections stats ***\n");
89 list = eet_list(ef, "*", &num);
90 if (list)
91 {
92 for (i = 0; i < num; i++)
93 {
94 const void *ro = NULL;
95 void *rw = NULL;
96 int tsize;
97
98 ro = eet_read_direct(ef, list[i], &tsize);
99 if (!ro) rw = eet_read(ef, list[i], &tsize);
100 printf(rw ? "%s of size %i is compressed.\n" : "%s of size %i is not compressed.\n", list[i], tsize);
101 count[rw ? 0 : 1]++;
102 size[rw ? 0 : 1] += tsize;
103 free(rw);
104 }
105 free(list);
106 }
107
108 printf("*** dictionary ***\n");
109 ed = eet_dictionary_get(ef);
110 if (ed)
111 {
112 printf("%i strings inside the dictionary.\n", eet_dictionary_count(ed));
113 }
114 else
115 {
116 printf("no dictionary in this file.\n");
117 }
118 printf("*** global ***\n");
119 printf("%i sections\n", num);
120 printf("- %i of them are compressed (%02.2f%%) expanding in %i bytes.\n",
121 count[0], (float) count[0] * 100 / (float) num, size[0]);
122 printf("- %i of them are directly mappable in memory (%02.2f%%) representing %i bytes.\n",
123 count[1], (float) count[1] * 100 / (float) num, size[1]);
124
125 eet_close(ef);
126}
127
128static void
129do_eet_extract(const char *file,
130 const char *key,
131 const char *out,
132 const char *crypto_key)
133{
134 Eet_File *ef;
135 void *data;
136 int size = 0;
137 FILE *f = stdout;
138
139 ef = eet_open(file, EET_FILE_MODE_READ);
140 if (!ef)
141 {
142 ERR("cannot open for reading: %s", file);
143 exit(-1);
144 }
145
146 data = eet_read_cipher(ef, key, &size, crypto_key);
147 if (!data)
148 {
149 ERR("cannot read key %s", key);
150 exit(-1);
151 }
152
153 if (out)
154 {
155 f = fopen(out, "wb");
156 if (!f)
157 {
158 ERR("cannot open %s", out);
159 exit(-1);
160 }
161 }
162
163 if (fwrite(data, size, 1, f) != 1)
164 {
165 ERR("cannot write to %s", out ? out : "standard output");
166 exit(-1);
167 }
168
169 if (out) fclose(f);
170 free(data);
171 eet_close(ef);
172} /* do_eet_extract */
173
174static void
175do_eet_decode_dump(void *data,
176 const char *str)
177{
178 fputs(str, (FILE *)data);
179} /* do_eet_decode_dump */
180
181static void
182do_eet_decode(const char *file,
183 const char *key,
184 const char *out,
185 const char *crypto_key)
186{
187 Eet_File *ef;
188 FILE *f = stdout;
189
190 ef = eet_open(file, EET_FILE_MODE_READ);
191 if (!ef)
192 {
193 ERR("cannot open for reading: %s", file);
194 exit(-1);
195 }
196
197 if (out)
198 {
199 f = fopen(out, "wb");
200 if (!f)
201 {
202 ERR("cannot open %s", out);
203 exit(-1);
204 }
205 }
206
207 if (!eet_data_dump_cipher(ef, key, crypto_key, do_eet_decode_dump, f))
208 {
209 ERR("cannot write to %s", out ? out : "standard output");
210 exit(-1);
211 }
212
213 if (out) fclose(f);
214 eet_close(ef);
215} /* do_eet_decode */
216
217static void
218do_eet_insert(const char *file,
219 const char *key,
220 const char *out,
221 int compress,
222 const char *crypto_key)
223{
224 Eet_File *ef;
225 void *data;
226 int size = 0;
227 FILE *f;
228
229 ef = eet_open(file, EET_FILE_MODE_READ_WRITE);
230 if (!ef)
231 ef = eet_open(file, EET_FILE_MODE_WRITE);
232
233 if (!ef)
234 {
235 ERR("cannot open for read+write: %s", file);
236 exit(-1);
237 }
238
239 f = fopen(out, "rb");
240 if (!f)
241 {
242 ERR("cannot open %s", out);
243 exit(-1);
244 }
245
246 fseek(f, 0, SEEK_END);
247 size = ftell(f);
248 rewind(f);
249 data = malloc(size);
250 if (!data)
251 {
252 ERR("cannot allocate %i bytes", size);
253 exit(-1);
254 }
255
256 if (fread(data, size, 1, f) != 1)
257 {
258 ERR("cannot read file %s", out);
259 exit(-1);
260 }
261
262 fclose(f);
263 eet_write_cipher(ef, key, data, size, compress, crypto_key);
264 free(data);
265 eet_close(ef);
266} /* do_eet_insert */
267
268static void
269do_eet_encode(const char *file,
270 const char *key,
271 const char *out,
272 int compress,
273 const char *crypto_key)
274{
275 Eet_File *ef;
276 char *text;
277 int textlen = 0;
278 int size = 0;
279 FILE *f;
280
281 ef = eet_open(file, EET_FILE_MODE_READ_WRITE);
282 if (!ef)
283 ef = eet_open(file, EET_FILE_MODE_WRITE);
284
285 if (!ef)
286 {
287 ERR("cannot open for read+write: %s", file);
288 exit(-1);
289 }
290
291 f = fopen(out, "rb");
292 if (!f)
293 {
294 ERR("cannot open %s", out);
295 exit(-1);
296 }
297
298 fseek(f, 0, SEEK_END);
299 textlen = ftell(f);
300 rewind(f);
301 text = malloc(textlen);
302 if (!text)
303 {
304 ERR("cannot allocate %i bytes", size);
305 exit(-1);
306 }
307
308 if (fread(text, textlen, 1, f) != 1)
309 {
310 ERR("cannot read file %s", out);
311 exit(-1);
312 }
313
314 fclose(f);
315 if (!eet_data_undump_cipher(ef, key, crypto_key, text, textlen, compress))
316 {
317 ERR("cannot parse %s", out);
318 exit(-1);
319 }
320
321 free(text);
322 eet_close(ef);
323} /* do_eet_encode */
324
325static void
326do_eet_remove(const char *file,
327 const char *key)
328{
329 Eet_File *ef;
330
331 ef = eet_open(file, EET_FILE_MODE_READ_WRITE);
332 if (!ef)
333 {
334 ERR("cannot open for read+write: %s", file);
335 exit(-1);
336 }
337
338 eet_delete(ef, key);
339 eet_close(ef);
340} /* do_eet_remove */
341
342static void
343do_eet_check(const char *file)
344{
345 Eet_File *ef;
346 const void *der;
347 int der_length;
348 int sign_length;
349
350 ef = eet_open(file, EET_FILE_MODE_READ);
351 if (!ef)
352 {
353 ERR("checking signature of `%s` failed", file);
354 exit(-1);
355 }
356
357 der = eet_identity_x509(ef, &der_length);
358
359 fprintf(stdout, "Certificate length %i.\n", der_length);
360 eet_identity_certificate_print(der, der_length, stdout);
361
362 eet_identity_signature(ef, &sign_length);
363 fprintf(stdout, "Signature length %i.\n", sign_length);
364
365 eet_close(ef);
366} /* do_eet_check */
367
368static void
369do_eet_sign(const char *file,
370 const char *private_key,
371 const char *public_key)
372{
373 Eet_File *ef;
374 Eet_Key *key;
375
376 ef = eet_open(file, EET_FILE_MODE_READ_WRITE);
377 if (!ef)
378 {
379 ERR("cannot open for read+write: %s.", file);
380 exit(-1);
381 }
382
383 key = eet_identity_open(public_key, private_key, NULL);
384 if (!key)
385 {
386 ERR("cannot open key '%s:%s'.", public_key, private_key);
387 exit(-1);
388 }
389
390 fprintf(stdout, "Using the following key to sign `%s`.\n", file);
391 eet_identity_print(key, stdout);
392
393 eet_identity_set(ef, key);
394
395 eet_close(ef);
396} /* do_eet_sign */
397
398int
399main(int argc,
400 char **argv)
401{
402 if (!eet_init())
403 return -1;
404
405 _eet_main_log_dom = eina_log_domain_register("eet_main", EINA_COLOR_CYAN);
406 if(_eet_main_log_dom < -1)
407 {
408 EINA_LOG_ERR("Impossible to create a log domain for eet_main.");
409 eet_shutdown();
410 return -1;
411 }
412
413 if (argc < 2)
414 {
415help:
416 printf(
417 "Usage:\n"
418 " eet -l FILE.EET list all keys in FILE.EET\n"
419 " eet -x FILE.EET KEY [OUT-FILE] [CRYPTO_KEY] extract data stored in KEY in FILE.EET and write to OUT-FILE or standard output\n"
420 " eet -d FILE.EET KEY [OUT-FILE] [CRYPTO_KEY] extract and decode data stored in KEY in FILE.EET and write to OUT-FILE or standard output\n"
421 " eet -i FILE.EET KEY IN-FILE COMPRESS [CRYPTO_KEY] insert data to KEY in FILE.EET from IN-FILE and if COMPRESS is 1, compress it\n"
422 " eet -e FILE.EET KEY IN-FILE COMPRESS [CRYPTO_KEY] insert and encode to KEY in FILE.EET from IN-FILE and if COMPRESS is 1, compress it\n"
423 " eet -r FILE.EET KEY remove KEY in FILE.EET\n"
424 " eet -c FILE.EET report and check the signature information of an eet file\n"
425 " eet -s FILE.EET PRIVATE_KEY PUBLIC_KEY sign FILE.EET with PRIVATE_KEY and attach PUBLIC_KEY as it's certificate\n"
426 " eet -t FILE.EET give some statistic about a file\n"
427 );
428 eet_shutdown();
429 return -1;
430 }
431
432 if ((!strncmp(argv[1], "-h", 2)))
433 goto help;
434 else if ((!strcmp(argv[1], "-l")) && (argc > 2))
435 do_eet_list(argv[2]);
436 else if ((!strcmp(argv[1], "-x")) && (argc > 3))
437 {
438 switch (argc)
439 {
440 case 4:
441 {
442 do_eet_extract(argv[2], argv[3], NULL, NULL);
443 break;
444 }
445 case 5:
446 {
447 do_eet_extract(argv[2], argv[3], argv[4], NULL);
448 break;
449 }
450 default:
451 {
452 do_eet_extract(argv[2], argv[3], argv[4], argv[5]);
453 break;
454 }
455 }
456 }
457 else if ((!strcmp(argv[1], "-d")) && (argc > 3))
458 {
459 switch (argc)
460 {
461 case 4:
462 {
463 do_eet_decode(argv[2], argv[3], NULL, NULL);
464 break;
465 }
466 case 5:
467 {
468 do_eet_decode(argv[2], argv[3], argv[4], NULL);
469 break;
470 }
471 default:
472 {
473 do_eet_decode(argv[2], argv[3], argv[4], argv[5]);
474 break;
475 }
476 }
477 }
478 else if ((!strcmp(argv[1], "-i")) && (argc > 5))
479 {
480 if (argc > 6)
481 do_eet_insert(argv[2], argv[3], argv[4], atoi(argv[5]), argv[6]);
482 else
483 do_eet_insert(argv[2], argv[3], argv[4], atoi(argv[5]), NULL);
484 }
485 else if ((!strcmp(argv[1], "-e")) && (argc > 5))
486 {
487 if (argc > 6)
488 do_eet_encode(argv[2], argv[3], argv[4], atoi(argv[5]), argv[6]);
489 else
490 do_eet_encode(argv[2], argv[3], argv[4], atoi(argv[5]), NULL);
491 }
492 else if ((!strcmp(argv[1], "-r")) && (argc > 3))
493 do_eet_remove(argv[2], argv[3]);
494 else if ((!strcmp(argv[1], "-c")) && (argc > 2))
495 do_eet_check(argv[2]);
496 else if ((!strcmp(argv[1], "-s")) && (argc > 4))
497 do_eet_sign(argv[2], argv[3], argv[4]);
498 else if ((!strcmp(argv[1], "-t")) && (argc > 2))
499 do_eet_stats(argv[2]);
500 else
501 goto help;
502
503 eina_log_domain_unregister(_eet_main_log_dom);
504 eet_shutdown();
505 return 0;
506} /* main */
507
diff --git a/src/examples/Makefile.am b/src/examples/Makefile.am
index d6fbe3e3fe..85c8ca3a4e 100644
--- a/src/examples/Makefile.am
+++ b/src/examples/Makefile.am
@@ -1,9 +1,11 @@
1MAINTAINERCLEANFILES = Makefile.in 1MAINTAINERCLEANFILES = Makefile.in
2 2
3SUBDIRS = eina 3SUBDIRS = eina eet
4 4
5examples: 5examples:
6 @$(MAKE) -C eina examples 6 @$(MAKE) -C eina examples
7 @$(MAKE) -C eet examples
7 8
8install-examples: 9install-examples:
9 @$(MAKE) -C eina install-examples \ No newline at end of file 10 @$(MAKE) -C eina install-examples
11 @$(MAKE) -C eet install-examples \ No newline at end of file
diff --git a/src/examples/eet/Makefile.am b/src/examples/eet/Makefile.am
new file mode 100644
index 0000000000..16815c14bd
--- /dev/null
+++ b/src/examples/eet/Makefile.am
@@ -0,0 +1,50 @@
1MAINTAINERCLEANFILES = Makefile.in
2AM_CPPFLAGS = \
3-I$(top_srcdir)/src/lib/eet \
4-I$(top_builddir)/src/lib/eet \
5@EET_CFLAGS@
6
7EXTRA_PROGRAMS = eet_basic eet_file eet_data_simple eet_data_nested eet_data_file_descriptor_01 eet_data_file_descriptor_02 eet_data_cipher_decipher
8
9eet_basic_SOURCES = eet-basic.c
10eet_basic_LDADD = $(top_builddir)/src/lib/eet/libeet.la @EET_LIBS@
11
12eet_file_SOURCES = eet-file.c
13eet_file_LDADD = $(top_builddir)/src/lib/eet/libeet.la @EET_LIBS@
14
15eet_data_simple_SOURCES = eet-data-simple.c
16eet_data_simple_LDADD = $(top_builddir)/src/lib/eet/libeet.la @EET_LIBS@
17
18eet_data_nested_SOURCES = eet-data-nested.c
19eet_data_nested_LDADD = $(top_builddir)/src/lib/eet/libeet.la @EET_LIBS@
20
21eet_data_file_descriptor_01_SOURCES = eet-data-file_descriptor_01.c
22eet_data_file_descriptor_01_LDADD = $(top_builddir)/src/lib/eet/libeet.la @EET_LIBS@
23
24eet_data_file_descriptor_02_SOURCES = eet-data-file_descriptor_02.c
25eet_data_file_descriptor_02_LDADD = $(top_builddir)/src/lib/eet/libeet.la @EET_LIBS@
26
27eet_data_cipher_decipher_SOURCES = eet-data-cipher_decipher.c
28eet_data_cipher_decipher_LDADD = $(top_builddir)/src/lib/eet/libeet.la @EET_LIBS@
29
30SRCS = \
31eet-basic.c \
32eet-file.c \
33eet-data-simple.c \
34eet-data-nested.c \
35eet-data-file_descriptor_01.c \
36eet-data-file_descriptor_02.c \
37eet-data-cipher_decipher.c
38
39examples: $(EXTRA_PROGRAMS)
40
41install-examples:
42 mkdir -p $(pkgdatadir)/examples
43 $(install_sh_DATA) -c $(SRCS) $(pkgdatadir)/examples
44
45uninstall-local:
46 for f in $(SRCS) ; do \
47 rm -f $(pkgdatadir)/examples/$$f ; \
48 done
49
50EXTRA_DIST = addr_book.txt chat.xml
diff --git a/src/examples/eet/eet-basic.c b/src/examples/eet/eet-basic.c
new file mode 100644
index 0000000000..05ff397789
--- /dev/null
+++ b/src/examples/eet/eet-basic.c
@@ -0,0 +1,40 @@
1#include <Eet.h>
2
3int
4main(void)
5{
6 Eet_File *ef;
7 char *ret;
8 int size;
9 char *entries[] =
10 {
11 "Entry 1",
12 "Big text string here compared to others",
13 "Eet is cool"
14 };
15
16 eet_init();
17
18 // blindly open an file for output and write strings with their NUL char
19 ef = eet_open("test.eet", EET_FILE_MODE_WRITE);
20 eet_write(ef, "Entry 1", entries[0], strlen(entries[0]) + 1, 0);
21 eet_write(ef, "Entry 2", entries[1], strlen(entries[1]) + 1, 1);
22 eet_write(ef, "Entry 3", entries[2], strlen(entries[2]) + 1, 0);
23 eet_close(ef);
24
25 // open the file again and blindly get the entries we wrote
26 ef = eet_open("test.eet", EET_FILE_MODE_READ);
27 ret = eet_read(ef, "Entry 1", &size);
28 printf("%s\n", ret);
29 free(ret);
30 ret = eet_read(ef, "Entry 2", &size);
31 printf("%s\n", ret);
32 free(ret);
33 ret = eet_read(ef, "Entry 3", &size);
34 printf("%s\n", ret);
35 free(ret);
36 eet_close(ef);
37
38 eet_shutdown();
39}
40
diff --git a/src/examples/eet/eet-data-cipher_decipher.c b/src/examples/eet/eet-data-cipher_decipher.c
new file mode 100644
index 0000000000..2ef965c745
--- /dev/null
+++ b/src/examples/eet/eet-data-cipher_decipher.c
@@ -0,0 +1,119 @@
1/*
2 * build: gcc -o eet_data_file_cipher_decipher eet-data-file_cipher_decipher.c `pkg-config --cflags --libs eet eina`
3 */
4
5#include <Eina.h>
6#include <Eet.h>
7#include <stdio.h>
8#include <limits.h>
9#include <sys/types.h>
10#include <sys/stat.h>
11#include <unistd.h>
12
13int
14main(void)
15{
16 const char *buffer = "Here is a string of data to save !";
17 const char *key = "This is a crypto key";
18 const char *key_bad = "This is another crypto key";
19
20 char *file = strdup("/tmp/eet_cipher_example_XXXXX");
21 Eet_File *ef;
22 char *test;
23 int size;
24
25 eet_init();
26
27 if (!(file = tmpnam(file)))
28 {
29 fprintf(
30 stderr, "ERROR: could not create temporary file (%s).\n", file);
31 goto panic;
32 }
33
34 /* Crypt an eet file. */
35 ef = eet_open(file, EET_FILE_MODE_WRITE);
36 if (!ef)
37 {
38 fprintf(
39 stderr, "ERROR: could not access file (%s).\n", file);
40 goto error;
41 }
42
43 if (!eet_write_cipher(ef, "keys/tests", buffer, strlen(buffer) + 1, 0, key))
44 {
45 fprintf(
46 stderr, "ERROR: could not access file (%s).\n", file);
47 goto error;
48 }
49
50 eet_close(ef);
51
52 /* Decrypt an eet file. */
53 ef = eet_open(file, EET_FILE_MODE_READ);
54 if (!ef)
55 {
56 fprintf(
57 stderr, "ERROR: could not access file (%s).\n", file);
58 goto error;
59 }
60
61 test = eet_read_cipher(ef, "keys/tests", &size, key);
62 if (!test)
63 {
64 fprintf(
65 stderr, "ERROR: could decript contents on file %s, with key %s.\n",
66 file, key);
67 goto error;
68 }
69
70 if (size != (int)strlen(buffer) + 1)
71 {
72 fprintf(
73 stderr, "ERROR: something is wrong with the decripted data\n");
74 goto error;
75 }
76
77 if (memcmp(test, buffer, strlen(buffer) + 1) != 0)
78 {
79 fprintf(
80 stderr, "ERROR: something is wrong with the decripted data\n");
81 goto error;
82 }
83
84 eet_close(ef);
85
86 /* Decrypt an eet file, now using our BAD key!! */
87 ef = eet_open(file, EET_FILE_MODE_READ);
88 if (!ef)
89 {
90 fprintf(
91 stderr, "ERROR: could not access file (%s).\n", file);
92 goto error;
93 }
94
95 test = eet_read_cipher(ef, "keys/tests", &size, key_bad);
96
97 if (size == (int)strlen(buffer) + 1)
98 if (memcmp(test, buffer, strlen(buffer) + 1) == 0)
99 {
100 fprintf(
101 stderr, "ERROR: something is wrong with the contents of %s, as"
102 " we accessed it with a different key and it decripted our"
103 " information right.\n", file);
104 goto error;
105 }
106
107 eet_close(ef);
108
109error:
110 if (unlink(file) != 0)
111 {
112 fprintf(
113 stderr, "ERROR: could not unlink file (%s).\n", file);
114 }
115
116panic:
117 eet_shutdown();
118}
119
diff --git a/src/examples/eet/eet-data-file_descriptor_01.c b/src/examples/eet/eet-data-file_descriptor_01.c
new file mode 100644
index 0000000000..4b5b75f865
--- /dev/null
+++ b/src/examples/eet/eet-data-file_descriptor_01.c
@@ -0,0 +1,529 @@
1/*
2 * build: gcc -o eet_data_file_descriptor eet-data-file_descriptor.c `pkg-config --cflags --libs eet eina`
3 */
4#include <Eina.h>
5#include <Eet.h>
6#include <stdio.h>
7#include <limits.h>
8#include <sys/types.h>
9#include <sys/stat.h>
10#include <unistd.h>
11
12// complex real-world structures based on elmdentica database
13typedef struct
14{
15 const char *screen_name;
16 const char *name;
17 const char *message;
18 unsigned int id;
19 unsigned int status_id;
20 unsigned int date;
21 unsigned int timeline;
22} My_Message;
23
24typedef struct
25{
26 const char *dm_to;
27 const char *message;
28} My_Post;
29
30typedef struct
31{
32 unsigned int id;
33 const char *name;
34 Eina_List *messages;
35 My_Post *posts;
36 int posts_count;
37} My_Account;
38
39typedef struct
40{
41 unsigned int version; // it is recommended to use versioned configuration!
42 Eina_Hash *accounts;
43} My_Cache;
44
45// string that represents the entry in eet file, you might like to have
46// different profiles or so in the same file, this is possible with
47// different strings
48static const char MY_CACHE_FILE_ENTRY[] = "cache";
49
50// keep the descriptor static global, so it can be
51// shared by different functions (load/save) of this and only this
52// file.
53static Eet_Data_Descriptor *_my_cache_descriptor;
54static Eet_Data_Descriptor *_my_account_descriptor;
55static Eet_Data_Descriptor *_my_message_descriptor;
56static Eet_Data_Descriptor *_my_post_descriptor;
57
58// keep file handle alive, so mmap()ed strings are all alive as well
59static Eet_File *_my_cache_file = NULL;
60static Eet_Dictionary *_my_cache_dict = NULL;
61
62static void
63_my_cache_descriptor_init(void)
64{
65 Eet_Data_Descriptor_Class eddc;
66
67 // The FILE variant is good for caches and things that are just
68 // appended, but needs to take care when changing strings and files must
69 // be kept open so mmap()ed strings will be kept alive.
70 EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, My_Cache);
71 _my_cache_descriptor = eet_data_descriptor_file_new(&eddc);
72
73 EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, My_Account);
74 _my_account_descriptor = eet_data_descriptor_file_new(&eddc);
75
76 EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, My_Message);
77 _my_message_descriptor = eet_data_descriptor_file_new(&eddc);
78
79 EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, My_Post);
80 _my_post_descriptor = eet_data_descriptor_file_new(&eddc);
81
82 // Describe the members to be saved:
83 // Use a temporary macro so we don't type a lot, also avoid errors:
84
85#define ADD_BASIC(member, eet_type) \
86 EET_DATA_DESCRIPTOR_ADD_BASIC \
87 (_my_message_descriptor, My_Message, # member, member, eet_type)
88 ADD_BASIC(screen_name, EET_T_STRING);
89 ADD_BASIC(name, EET_T_STRING);
90 ADD_BASIC(message, EET_T_STRING);
91 ADD_BASIC(id, EET_T_UINT);
92 ADD_BASIC(status_id, EET_T_UINT);
93 ADD_BASIC(date, EET_T_UINT);
94 ADD_BASIC(timeline, EET_T_UINT);
95#undef ADD_BASIC
96
97#define ADD_BASIC(member, eet_type) \
98 EET_DATA_DESCRIPTOR_ADD_BASIC \
99 (_my_post_descriptor, My_Post, # member, member, eet_type)
100 ADD_BASIC(dm_to, EET_T_STRING);
101 ADD_BASIC(message, EET_T_STRING);
102#undef ADD_BASIC
103
104#define ADD_BASIC(member, eet_type) \
105 EET_DATA_DESCRIPTOR_ADD_BASIC \
106 (_my_account_descriptor, My_Account, # member, member, eet_type)
107 ADD_BASIC(name, EET_T_STRING);
108 ADD_BASIC(id, EET_T_UINT);
109#undef ADD_BASIC
110
111 EET_DATA_DESCRIPTOR_ADD_LIST
112 (_my_account_descriptor, My_Account, "messages", messages,
113 _my_message_descriptor);
114 EET_DATA_DESCRIPTOR_ADD_VAR_ARRAY
115 (_my_account_descriptor, My_Account, "posts", posts,
116 _my_post_descriptor);
117
118#define ADD_BASIC(member, eet_type) \
119 EET_DATA_DESCRIPTOR_ADD_BASIC \
120 (_my_cache_descriptor, My_Cache, # member, member, eet_type)
121 ADD_BASIC(version, EET_T_UINT);
122#undef ADD_BASIC
123
124 EET_DATA_DESCRIPTOR_ADD_HASH
125 (_my_cache_descriptor, My_Cache, "accounts", accounts,
126 _my_account_descriptor);
127} /* _my_cache_descriptor_init */
128
129static void
130_my_cache_descriptor_shutdown(void)
131{
132 eet_data_descriptor_free(_my_cache_descriptor);
133 eet_data_descriptor_free(_my_account_descriptor);
134 eet_data_descriptor_free(_my_message_descriptor);
135 eet_data_descriptor_free(_my_post_descriptor);
136} /* _my_cache_descriptor_shutdown */
137
138// need to check if the pointer came from mmaped area in eet_dictionary
139// or it was allocated with eina_stringshare_add()
140static void
141_eet_string_free(const char *str)
142{
143 if (!str)
144 return;
145
146 if ((_my_cache_dict) && (eet_dictionary_string_check(_my_cache_dict, str)))
147 return;
148
149 eina_stringshare_del(str);
150} /* _eet_string_free */
151
152static My_Message *
153_my_message_new(const char *message)
154{
155 My_Message *msg = calloc(1, sizeof(My_Message));
156 if (!msg)
157 {
158 fprintf(stderr, "ERROR: could not calloc My_Message\n");
159 return NULL;
160 }
161
162 msg->message = eina_stringshare_add(message);
163 return msg;
164} /* _my_message_new */
165
166static void
167_my_message_free(My_Message *msg)
168{
169 _eet_string_free(msg->screen_name);
170 _eet_string_free(msg->name);
171 _eet_string_free(msg->message);
172 free(msg);
173} /* _my_message_free */
174
175static Eina_Bool
176_my_post_add(My_Account *acc,
177 const char *message)
178{
179 int new_count = acc->posts_count + 1;
180 My_Post *post = realloc(acc->posts, new_count * sizeof(My_Post));
181 if (!post)
182 {
183 fprintf(stderr, "ERROR: could add My_Post\n");
184 return EINA_FALSE;
185 }
186
187 post[acc->posts_count].message = eina_stringshare_add(message);
188 post[acc->posts_count].dm_to = NULL;
189 acc->posts_count = new_count;
190 acc->posts = post;
191 return EINA_TRUE;
192} /* _my_post_new */
193
194static void
195_my_post_free(My_Post *post)
196{
197 _eet_string_free(post->dm_to);
198 _eet_string_free(post->message);
199} /* _my_post_free */
200
201static My_Account *
202_my_account_new(const char *name)
203{
204 My_Account *acc = calloc(1, sizeof(My_Account));
205 if (!acc)
206 {
207 fprintf(stderr, "ERROR: could not calloc My_Account\n");
208 return NULL;
209 }
210
211 acc->name = eina_stringshare_add(name);
212 return acc;
213} /* _my_account_new */
214
215static void
216_my_account_free(My_Account *acc)
217{
218 My_Message *m;
219 int i;
220
221 _eet_string_free(acc->name);
222
223 EINA_LIST_FREE(acc->messages, m)
224 _my_message_free(m);
225
226 for (i = 0; i < acc->posts_count; i++)
227 _my_post_free(&acc->posts[i]);
228 free(acc->posts);
229
230 free(acc);
231} /* _my_account_free */
232
233static My_Cache *
234_my_cache_new(void)
235{
236 My_Cache *my_cache = calloc(1, sizeof(My_Cache));
237 if (!my_cache)
238 {
239 fprintf(stderr, "ERROR: could not calloc My_Cache\n");
240 return NULL;
241 }
242
243 my_cache->accounts = eina_hash_string_small_new(NULL);
244
245 my_cache->version = 1;
246 return my_cache;
247} /* _my_cache_new */
248
249static Eina_Bool
250_my_cache_account_free_cb(const Eina_Hash *hash,
251 const void *key,
252 void *data,
253 void *fdata)
254{
255 _my_account_free(data);
256 return EINA_TRUE;
257}
258
259static void
260_my_cache_free(My_Cache *my_cache)
261{
262 My_Account *acc;
263 eina_hash_foreach(my_cache->accounts, _my_cache_account_free_cb, NULL);
264 eina_hash_free(my_cache->accounts);
265 free(my_cache);
266} /* _my_cache_free */
267
268static My_Account *
269_my_cache_account_find(My_Cache *my_cache,
270 const char *name)
271{
272 return eina_hash_find(my_cache->accounts, name);
273} /* _my_cache_account_find */
274
275static My_Cache *
276_my_cache_load(const char *filename)
277{
278 My_Cache *my_cache;
279 Eet_File *ef = eet_open(filename, EET_FILE_MODE_READ);
280 if (!ef)
281 {
282 fprintf(stderr, "ERROR: could not open '%s' for read\n", filename);
283 return NULL;
284 }
285
286 my_cache = eet_data_read(ef, _my_cache_descriptor, MY_CACHE_FILE_ENTRY);
287 if (!my_cache)
288 {
289 eet_close(ef);
290 return NULL;
291 }
292
293 if (my_cache->version < 1)
294 {
295 fprintf(stderr,
296 "WARNING: version %#x was too old, upgrading it to %#x\n",
297 my_cache->version, 1);
298
299 my_cache->version = 1;
300 }
301
302 if (_my_cache_file)
303 eet_close(_my_cache_file);
304
305 _my_cache_file = ef;
306 _my_cache_dict = eet_dictionary_get(ef);
307
308 return my_cache;
309} /* _my_cache_load */
310
311static Eina_Bool
312_my_cache_save(const My_Cache *my_cache,
313 const char *filename)
314{
315 char tmp[PATH_MAX];
316 Eet_File *ef;
317 Eina_Bool ret;
318 unsigned int i, len;
319 struct stat st;
320
321 len = eina_strlcpy(tmp, filename, sizeof(tmp));
322 if (len + 12 >= (int)sizeof(tmp))
323 {
324 fprintf(stderr, "ERROR: file name is too big: %s\n", filename);
325 return EINA_FALSE;
326 }
327
328 i = 0;
329 do
330 {
331 snprintf(tmp + len, 12, ".%u", i);
332 i++;
333 }
334 while (stat(tmp, &st) == 0);
335
336 ef = eet_open(tmp, EET_FILE_MODE_WRITE);
337 if (!ef)
338 {
339 fprintf(stderr, "ERROR: could not open '%s' for write\n", tmp);
340 return EINA_FALSE;
341 }
342
343 ret = eet_data_write
344 (ef, _my_cache_descriptor, MY_CACHE_FILE_ENTRY, my_cache, EINA_TRUE);
345
346 // VERY IMPORTANT NOTE:
347 // after eet_close(), all strings mmaped from file will be GONE, invalid!
348 // you'll need to free the old cache and open the new one.
349 // For cache this is okay, as you should be saving not so often or just
350 // at end.
351 //
352 // This is a trade off, you save memory by using mmap()ed strings, but
353 // you have to care about this.
354 eet_close(ef);
355
356 if (ret)
357 {
358 unlink(filename);
359 rename(tmp, filename);
360 }
361
362 return ret;
363} /* _my_cache_save */
364
365int
366main(int argc,
367 char *argv[])
368{
369 My_Cache *my_cache;
370 const Eina_List *l_acc;
371 Eina_Iterator *it;
372 My_Account *acc;
373 int ret = 0;
374
375 if (argc < 3)
376 {
377 fprintf(stderr,
378 "Usage:\n\t%s <input> <output> [action] [action-params]\n\n"
379 "Where actions and their parameters:\n"
380 "\tacc <name>\n"
381 "\tpost <account-name> <message>\n"
382 "\tmessage <account-name> <message>\n"
383 "\n",
384 argv[0]);
385 return -1;
386 }
387
388 eina_init();
389 eet_init();
390 _my_cache_descriptor_init();
391
392 my_cache = _my_cache_load(argv[1]);
393 if (!my_cache)
394 {
395 printf("creating new cache.\n");
396 my_cache = _my_cache_new();
397 if (!my_cache)
398 {
399 ret = -2;
400 goto end;
401 }
402 }
403
404 if (argc > 3)
405 {
406 if (strcmp(argv[3], "acc") == 0)
407 {
408 if (argc == 5)
409 {
410 My_Account *acc = _my_cache_account_find(my_cache, argv[4]);
411 if (!acc)
412 {
413 acc = _my_account_new(argv[4]);
414 eina_hash_direct_add(my_cache->accounts, acc->name, acc);
415 }
416 else
417 fprintf(stderr, "ERROR: account '%s' already exists.\n",
418 argv[4]);
419 }
420 else
421 fprintf(stderr,
422 "ERROR: wrong number of parameters (%d).\n",
423 argc);
424 }
425 else if (strcmp(argv[3], "post") == 0)
426 {
427 if (argc == 6)
428 {
429 My_Account *acc = _my_cache_account_find(my_cache, argv[4]);
430 if (acc)
431 {
432 _my_post_add(acc, argv[5]);
433 }
434 else
435 fprintf(stderr, "ERROR: unknown account: '%s'\n", argv[4]);
436 }
437 else
438 fprintf(stderr,
439 "ERROR: wrong number of parameters (%d).\n",
440 argc);
441 }
442 else if (strcmp(argv[3], "message") == 0)
443 {
444 if (argc == 6)
445 {
446 My_Account *acc = _my_cache_account_find(my_cache, argv[4]);
447 if (acc)
448 {
449 My_Message *msg = _my_message_new(argv[5]);
450 acc->messages = eina_list_append(acc->messages, msg);
451 }
452 else
453 fprintf(stderr, "ERROR: unknown account: '%s'\n", argv[4]);
454 }
455 else
456 fprintf(stderr,
457 "ERROR: wrong number of parameters (%d).\n",
458 argc);
459 }
460 else
461 fprintf(stderr, "ERROR: unknown action '%s'\n", argv[2]);
462 }
463
464 printf("My_Cache:\n"
465 "\tversion.: %#x\n"
466 "\taccounts: %u\n",
467 my_cache->version,
468 eina_hash_population(my_cache->accounts));
469 it = eina_hash_iterator_data_new(my_cache->accounts);
470 EINA_ITERATOR_FOREACH(it, acc)
471 {
472 const My_Post *post;
473
474 printf("\t > %-#8x '%.20s' stats: m=%u, p=%u\n",
475 acc->id, acc->name ? acc->name : "",
476 eina_list_count(acc->messages),
477 acc->posts_count);
478
479 if (eina_list_count(acc->messages))
480 {
481 const Eina_List *l;
482 const My_Message *msg;
483 printf("\t |messages:\n");
484
485 EINA_LIST_FOREACH(acc->messages, l, msg)
486 {
487 printf("\t | %-8x '%s' [%s]: '%.20s'\n",
488 msg->id,
489 msg->name ? msg->name : "",
490 msg->screen_name ? msg->screen_name : "",
491 msg->message ? msg->message : "");
492 }
493 }
494
495 if (acc->posts_count)
496 {
497 const My_Post *post;
498 int i;
499 printf("\t |posts:\n");
500
501 for (i = 0; i < acc->posts_count; i++)
502 {
503 post = &acc->posts[i];
504 if (post->dm_to)
505 printf("\t | @%s: '%.20s'\n", post->dm_to, post->message);
506 else
507 printf("\t | '%.20s'\n", post->message);
508 }
509 }
510
511 printf("\n");
512 }
513 eina_iterator_free(it);
514
515 if (!_my_cache_save(my_cache, argv[2]))
516 ret = -3;
517
518 _my_cache_free(my_cache);
519
520end:
521 if (_my_cache_file)
522 eet_close(_my_cache_file);
523 _my_cache_descriptor_shutdown();
524 eet_shutdown();
525 eina_shutdown();
526
527 return ret;
528} /* main */
529
diff --git a/src/examples/eet/eet-data-file_descriptor_02.c b/src/examples/eet/eet-data-file_descriptor_02.c
new file mode 100644
index 0000000000..65ba79ec40
--- /dev/null
+++ b/src/examples/eet/eet-data-file_descriptor_02.c
@@ -0,0 +1,944 @@
1/*
2 * build: gcc -o eet_data_file_descriptor_02 eet-data-file_descriptor_02.c `pkg-config --cflags --libs eet eina`
3 */
4
5#include <Eina.h>
6#include <Eet.h>
7#include <stdio.h>
8#include <limits.h>
9#include <sys/types.h>
10#include <sys/stat.h>
11#include <unistd.h>
12
13typedef enum _Example_Data_Type Example_Data_Type;
14typedef struct _Example_Variant_Type Example_Variant_Type;
15typedef struct _Example_Variant Example_Variant;
16typedef struct _Example_Union Example_Union;
17typedef struct _Example_Struct1 Example_Struct1;
18typedef struct _Example_Struct2 Example_Struct2;
19typedef struct _Example_Struct3 Example_Struct3;
20typedef struct _Example_Lists Example_Lists;
21
22enum _Example_Data_Type
23{
24 EET_UNKNOWN = 0,
25 EET_STRUCT1,
26 EET_STRUCT2,
27 EET_STRUCT3
28};
29
30struct
31{
32 Example_Data_Type u;
33 const char *name;
34} eet_mapping[] = {
35 { EET_STRUCT1, "ST1" },
36 { EET_STRUCT2, "ST2" },
37 { EET_STRUCT3, "ST3" },
38 { EET_UNKNOWN, NULL }
39};
40
41struct _Example_Struct1
42{
43 double val1;
44 int stuff;
45 const char *s1;
46};
47
48struct _Example_Struct2
49{
50 Eina_Bool b1;
51 unsigned long long v1;
52};
53
54struct _Example_Struct3
55{
56 int body;
57};
58
59struct _Example_Union
60{
61 Example_Data_Type type;
62
63 union {
64 Example_Struct1 st1;
65 Example_Struct2 st2;
66 Example_Struct3 st3;
67 } u;
68};
69
70struct _Example_Variant_Type
71{
72 const char *type;
73 Eina_Bool unknow : 1;
74};
75
76struct _Example_Variant
77{
78 Example_Variant_Type t;
79
80 void *data; /* differently than the union type, we
81 * don't need to pre-allocate the memory
82 * for the field*/
83};
84
85struct _Example_Lists
86{
87 Eina_List *union_list;
88 Eina_List *variant_list;
89};
90
91static void
92_st1_set(Example_Struct1 *st1,
93 double v1,
94 int v2,
95 const char *v3)
96{
97 st1->val1 = v1;
98 st1->stuff = v2;
99 st1->s1 = v3;
100} /* _st1_set */
101
102static void
103_st2_set(Example_Struct2 *st2,
104 Eina_Bool v1,
105 unsigned long long v2)
106{
107 st2->b1 = v1;
108 st2->v1 = v2;
109} /* _st2_set */
110
111static void
112_st3_set(Example_Struct3 *st3,
113 int v1)
114{
115 st3->body = v1;
116} /* _st3_set */
117
118static const char *
119/* union
120 type_get() */
121_union_type_get(const void *data,
122 Eina_Bool *unknow)
123{
124 const Example_Data_Type *u = data;
125 int i;
126
127 if (unknow)
128 *unknow = EINA_FALSE;
129
130 for (i = 0; eet_mapping[i].name != NULL; ++i)
131 if (*u == eet_mapping[i].u)
132 return eet_mapping[i].name;
133
134 if (unknow)
135 *unknow = EINA_TRUE;
136
137 return NULL;
138} /* _union_type_get */
139
140static Eina_Bool
141_union_type_set(const char *type,
142 void *data,
143 Eina_Bool unknow)
144{
145 Example_Data_Type *u = data;
146 int i;
147
148 if (unknow)
149 return EINA_FALSE;
150
151 for (i = 0; eet_mapping[i].name != NULL; ++i)
152 if (strcmp(eet_mapping[i].name, type) == 0)
153 {
154 *u = eet_mapping[i].u;
155 return EINA_TRUE;
156 }
157
158 return EINA_FALSE;
159} /* _union_type_set */
160
161static const char *
162_variant_type_get(const void *data,
163 Eina_Bool *unknow)
164{
165 const Example_Variant_Type *type = data;
166 int i;
167
168 if (unknow)
169 *unknow = type->unknow;
170
171 for (i = 0; eet_mapping[i].name != NULL; ++i)
172 if (strcmp(type->type, eet_mapping[i].name) == 0)
173 return eet_mapping[i].name;
174
175 if (unknow)
176 *unknow = EINA_FALSE;
177
178 return type->type;
179} /* _variant_type_get */
180
181static Eina_Bool
182_variant_type_set(const char *type,
183 void *data,
184 Eina_Bool unknow)
185{
186 Example_Variant_Type *vt = data;
187
188 vt->type = type;
189 vt->unknow = unknow;
190 return EINA_TRUE;
191} /* _variant_type_set */
192
193static Eet_Data_Descriptor *
194_st1_dd(void)
195{
196 Eet_Data_Descriptor_Class eddc;
197 Eet_Data_Descriptor *res;
198
199 EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Example_Struct1);
200 res = eet_data_descriptor_file_new(&eddc);
201 EET_DATA_DESCRIPTOR_ADD_BASIC(
202 res, Example_Struct1, "val1", val1, EET_T_DOUBLE);
203 EET_DATA_DESCRIPTOR_ADD_BASIC(
204 res, Example_Struct1, "stuff", stuff, EET_T_INT);
205 EET_DATA_DESCRIPTOR_ADD_BASIC(
206 res, Example_Struct1, "s1", s1, EET_T_STRING);
207
208 return res;
209} /* _st1_dd */
210
211static Eet_Data_Descriptor *
212_st2_dd(void)
213{
214 Eet_Data_Descriptor_Class eddc;
215 Eet_Data_Descriptor *res;
216
217 EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Example_Struct2);
218 res = eet_data_descriptor_file_new(&eddc);
219 EET_DATA_DESCRIPTOR_ADD_BASIC(
220 res, Example_Struct2, "b1", b1, EET_T_UCHAR);
221 EET_DATA_DESCRIPTOR_ADD_BASIC(
222 res, Example_Struct2, "v1", v1, EET_T_ULONG_LONG);
223
224 return res;
225} /* _st2_dd */
226
227static Eet_Data_Descriptor *
228_st3_dd(void)
229{
230 Eet_Data_Descriptor_Class eddc;
231 Eet_Data_Descriptor *res;
232
233 EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Example_Struct3);
234 res = eet_data_descriptor_file_new(&eddc);
235 EET_DATA_DESCRIPTOR_ADD_BASIC(
236 res, Example_Struct3, "body", body, EET_T_INT);
237
238 return res;
239} /* _st3_dd */
240
241/* string that represents the entry in the eet file. you might like to
242 * have different profiles or so in the same file, this is possible
243 * with different strings
244 */
245static const char CACHE_FILE_ENTRY[] = "cache";
246
247/* keep the descriptor static global, so it can be shared by different
248 * functions (load/save) of this and only this file.
249 */
250static Eet_Data_Descriptor *_lists_descriptor;
251static Eet_Data_Descriptor *_struct_1_descriptor;
252static Eet_Data_Descriptor *_struct_2_descriptor;
253static Eet_Data_Descriptor *_struct_3_descriptor;
254static Eet_Data_Descriptor *_union_descriptor;
255static Eet_Data_Descriptor *_variant_descriptor;
256static Eet_Data_Descriptor *_union_unified_descriptor;
257static Eet_Data_Descriptor *_variant_unified_descriptor;
258
259/* keep file handle alive, so mmap()ed strings are all alive as
260 * well */
261static Eet_File *_cache_file = NULL;
262static Eet_Dictionary *_cache_dict = NULL;
263
264static void
265/* declaring types */
266_data_descriptors_init(void)
267{
268 Eet_Data_Descriptor_Class eddc;
269
270 EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Example_Lists);
271 _lists_descriptor = eet_data_descriptor_file_new(&eddc);
272
273 _struct_1_descriptor = _st1_dd();
274 _struct_2_descriptor = _st2_dd();
275 _struct_3_descriptor = _st3_dd();
276
277 /* for union */
278 EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Example_Union);
279 _union_descriptor = eet_data_descriptor_file_new(&eddc);
280
281 eddc.version = EET_DATA_DESCRIPTOR_CLASS_VERSION;
282 eddc.func.type_get = _union_type_get;
283 eddc.func.type_set = _union_type_set;
284 _union_unified_descriptor = eet_data_descriptor_file_new(&eddc);
285
286 EET_DATA_DESCRIPTOR_ADD_MAPPING(
287 _union_unified_descriptor, "ST1", _struct_1_descriptor);
288 EET_DATA_DESCRIPTOR_ADD_MAPPING(
289 _union_unified_descriptor, "ST2", _struct_2_descriptor);
290 EET_DATA_DESCRIPTOR_ADD_MAPPING(
291 _union_unified_descriptor, "ST3", _struct_3_descriptor);
292
293 EET_DATA_DESCRIPTOR_ADD_UNION(
294 _union_descriptor, Example_Union, "u", u, type,
295 _union_unified_descriptor);
296
297 EET_DATA_DESCRIPTOR_ADD_LIST(
298 _lists_descriptor, Example_Lists, "union_list", union_list,
299 _union_descriptor);
300
301 /* for variant */
302 EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Example_Variant);
303 _variant_descriptor = eet_data_descriptor_file_new(&eddc);
304
305 eddc.version = EET_DATA_DESCRIPTOR_CLASS_VERSION;
306 eddc.func.type_get = _variant_type_get;
307 eddc.func.type_set = _variant_type_set;
308 _variant_unified_descriptor = eet_data_descriptor_stream_new(&eddc);
309
310 EET_DATA_DESCRIPTOR_ADD_MAPPING(
311 _variant_unified_descriptor, "ST1", _struct_1_descriptor);
312 EET_DATA_DESCRIPTOR_ADD_MAPPING(
313 _variant_unified_descriptor, "ST2", _struct_2_descriptor);
314 EET_DATA_DESCRIPTOR_ADD_MAPPING(
315 _variant_unified_descriptor, "ST3", _struct_3_descriptor);
316
317 EET_DATA_DESCRIPTOR_ADD_VARIANT(
318 _variant_descriptor, Example_Variant, "data", data, t,
319 _variant_unified_descriptor);
320
321 EET_DATA_DESCRIPTOR_ADD_LIST(
322 _lists_descriptor, Example_Lists, "variant_list", variant_list,
323 _variant_descriptor);
324} /* _data_descriptors_init */
325
326static void
327_data_descriptors_shutdown(void)
328{
329 eet_data_descriptor_free(_lists_descriptor);
330 eet_data_descriptor_free(_struct_1_descriptor);
331 eet_data_descriptor_free(_struct_2_descriptor);
332 eet_data_descriptor_free(_struct_3_descriptor);
333 eet_data_descriptor_free(_union_descriptor);
334 eet_data_descriptor_free(_variant_descriptor);
335 eet_data_descriptor_free(_union_unified_descriptor);
336 eet_data_descriptor_free(_variant_unified_descriptor);
337} /* _data_descriptors_shutdown */
338
339/* need to check if the pointer came from mmap()ed area in
340 * eet_dictionary or it was allocated with eina_stringshare_add()
341 */
342static void
343_string_free(const char *str)
344{
345 if (!str)
346 return;
347
348 if ((_cache_dict) && (eet_dictionary_string_check(_cache_dict, str)))
349 return;
350
351 eina_stringshare_del(str);
352} /* _string_free */
353
354static Example_Union *
355_union_1_new(const char *v1,
356 const char *v2,
357 const char *v3)
358{
359 Example_Union *un = calloc(1, sizeof(Example_Union));
360 if (!un)
361 {
362 fprintf(
363 stderr, "ERROR: could not allocate an Example_Union struct.\n");
364 return NULL;
365 }
366
367 un->type = EET_STRUCT1;
368 _st1_set(&(un->u.st1), atof(v1), atoi(v2), eina_stringshare_add(v3));
369
370 return un;
371}
372
373static Example_Union *
374_union_2_new(const char *v1,
375 const char *v2)
376{
377 Example_Union *un = calloc(1, sizeof(Example_Union));
378 if (!un)
379 {
380 fprintf(
381 stderr, "ERROR: could not allocate an Example_Union struct.\n");
382 return NULL;
383 }
384
385 un->type = EET_STRUCT2;
386 _st2_set(&(un->u.st2), atoi(v1), atoi(v2));
387
388 return un;
389}
390
391static Example_Union *
392_union_3_new(const char *v1)
393{
394 Example_Union *un = calloc(1, sizeof(Example_Union));
395 if (!un)
396 {
397 fprintf(
398 stderr, "ERROR: could not allocate an Example_Union struct.\n");
399 return NULL;
400 }
401
402 un->type = EET_STRUCT3;
403 _st3_set(&(un->u.st3), atoi(v1));
404
405 return un;
406}
407
408static Example_Variant *
409_variant_1_new(const char *v1,
410 const char *v2,
411 const char *v3)
412{
413 Example_Struct1 *st1;
414 Example_Variant *va = calloc(1, sizeof(Example_Variant));
415 if (!va)
416 {
417 fprintf(
418 stderr, "ERROR: could not allocate an Example_Variant struct.\n");
419 return NULL;
420 }
421
422 va = calloc(1, sizeof (Example_Variant));
423 va->t.type = eet_mapping[0].name;
424 st1 = calloc(1, sizeof (Example_Struct1));
425 _st1_set(st1, atof(v1), atoi(v2), eina_stringshare_add(v3));
426 va->data = st1;
427
428 return va;
429}
430
431static Example_Variant *
432_variant_2_new(const char *v1,
433 const char *v2)
434{
435 printf("varinant 2 new\n");
436
437 Example_Struct2 *st2;
438 Example_Variant *va = calloc(1, sizeof(Example_Variant));
439 if (!va)
440 {
441 fprintf(
442 stderr, "ERROR: could not allocate an Example_Variant struct.\n");
443 return NULL;
444 }
445
446 va = calloc(1, sizeof (Example_Variant));
447
448 va->t.type = eet_mapping[1].name;
449
450 printf("type gets %s\n", va->t.type);
451
452 st2 = calloc(1, sizeof (Example_Struct2));
453 _st2_set(st2, atoi(v1), atoi(v2));
454 va->data = st2;
455
456 return va;
457}
458
459static Example_Variant *
460_variant_3_new(const char *v1)
461{
462 Example_Struct3 *st3;
463 Example_Variant *va = calloc(1, sizeof(Example_Variant));
464 if (!va)
465 {
466 fprintf(
467 stderr, "ERROR: could not allocate an Example_Variant struct.\n");
468 return NULL;
469 }
470
471 va = calloc(1, sizeof (Example_Variant));
472 va->t.type = eet_mapping[2].name;
473 st3 = calloc(1, sizeof (Example_Struct3));
474 _st3_set(st3, atoi(v1));
475 va->data = st3;
476
477 return va;
478}
479
480static Example_Lists *
481_data_new(void)
482{
483 Example_Lists *example_lists = calloc(1, sizeof(Example_Lists));
484 if (!example_lists)
485 {
486 fprintf(stderr, "ERROR: could not allocate a Example_Lists struct.\n");
487 return NULL;
488 }
489
490 return example_lists;
491} /* _data_new */
492
493static void
494_union_free(Example_Union *un)
495{
496 if (un->type == EET_STRUCT1)
497 {
498 Example_Struct1 *st1 = &(un->u.st1);
499 _string_free(st1->s1);
500 }
501
502 free(un);
503}
504
505static void
506_variant_free(Example_Variant *va)
507{
508 if (!strcmp(va->t.type, eet_mapping[0].name))
509 {
510 Example_Struct1 *st1 = va->data;
511 _string_free(st1->s1);
512 }
513
514 free(va->data);
515 free(va);
516}
517
518static void
519_data_free(Example_Lists *cache)
520{
521 Example_Union *un;
522 Example_Variant *va;
523
524 EINA_LIST_FREE(cache->union_list, un)
525 _union_free(un);
526
527 EINA_LIST_FREE(cache->variant_list, va)
528 _variant_free(va);
529
530 free(cache);
531} /* _data_free */
532
533static Example_Lists *
534_data_load(const char *filename)
535{
536 Example_Lists *data;
537 Eet_File *ef = eet_open(filename, EET_FILE_MODE_READ);
538 if (!ef)
539 {
540 fprintf(stderr, "ERROR: could not open '%s' for read\n", filename);
541 return NULL;
542 }
543
544 data = eet_data_read(ef, _lists_descriptor, CACHE_FILE_ENTRY);
545 if (!data)
546 {
547 eet_close(ef);
548 return NULL;
549 }
550
551 if (_cache_file)
552 eet_close(_cache_file);
553
554 _cache_file = ef;
555 _cache_dict = eet_dictionary_get(ef);
556
557 return data;
558} /* _data_load */
559
560static Eina_Bool
561_data_save(const Example_Lists *cache,
562 const char *filename)
563{
564 char tmp[PATH_MAX];
565 Eet_File *ef;
566 Eina_Bool ret;
567 unsigned int i, len;
568 struct stat st;
569
570 len = eina_strlcpy(tmp, filename, sizeof(tmp));
571 if (len + 12 >= (int)sizeof(tmp))
572 {
573 fprintf(stderr, "ERROR: file name is too big: %s\n", filename);
574 return EINA_FALSE;
575 }
576
577 i = 0;
578 do
579 {
580 snprintf(tmp + len, 12, ".%u", i);
581 i++;
582 }
583 while (stat(tmp, &st) == 0);
584
585 ef = eet_open(tmp, EET_FILE_MODE_WRITE);
586 if (!ef)
587 {
588 fprintf(stderr, "ERROR: could not open '%s' for write\n", tmp);
589 return EINA_FALSE;
590 }
591
592 ret = eet_data_write
593 (ef, _lists_descriptor, CACHE_FILE_ENTRY, cache, EINA_TRUE);
594
595 eet_close(ef);
596
597 if (ret)
598 {
599 unlink(filename);
600 rename(tmp, filename);
601 }
602
603 return ret;
604} /* _data_save */
605
606static void
607_print_union(const Example_Union *un)
608{
609 printf("\t | type: %s'\n", eet_mapping[un->type - 1].name);
610
611 switch (un->type)
612 {
613 case EET_STRUCT1:
614 printf("\t\t val1: %f\n", un->u.st1.val1);
615 printf("\t\t stuff: %d\n", un->u.st1.stuff);
616 printf("\t\t s1: %s\n", un->u.st1.s1);
617 break;
618
619 case EET_STRUCT2:
620 printf("\t\t val1: %i\n", un->u.st2.b1);
621 printf("\t\t stuff: %lli\n", un->u.st2.v1);
622 break;
623
624 case EET_STRUCT3:
625 printf("\t\t val1: %i\n", un->u.st3.body);
626 break;
627
628 default:
629 return;
630 }
631}
632
633static void
634_print_variant(const Example_Variant *va)
635{
636 printf("\t | type: %s'\n", va->t.type);
637
638 switch (va->t.type[2])
639 {
640 case '1':
641 {
642 Example_Struct1 *st1 = va->data;
643
644 printf("\t\t val1: %f\n", st1->val1);
645 printf("\t\t stuff: %d\n", st1->stuff);
646 printf("\t\t s1: %s\n", st1->s1);
647 }
648 break;
649
650 case '2':
651 {
652 Example_Struct2 *st2 = va->data;
653
654 printf("\t\t val1: %i\n", st2->b1);
655 printf("\t\t stuff: %lli\n", st2->v1);
656 }
657 break;
658
659 case '3':
660 {
661 Example_Struct3 *st3 = va->data;
662
663 printf("\t\t val1: %i\n", st3->body);
664 }
665 break;
666
667 default:
668 return;
669 }
670}
671
672int
673main(int argc,
674 char *argv[])
675{
676 Example_Lists *data_lists;
677 int ret = 0;
678
679 if (argc < 3)
680 {
681 fprintf(stderr,
682 "Usage:\n\t%s <input> <output> [action action-params]\n\n"
683 "where actions and their parameters are:\n"
684 "\tunion <type> [fields]\n"
685 "\tvariant <type> [fields]\n"
686 "\n",
687 argv[0]);
688 return -1;
689 }
690
691 eina_init();
692 eet_init();
693 _data_descriptors_init();
694
695 data_lists = _data_load(argv[1]);
696 if (!data_lists)
697 {
698 printf("Creating new data lists.\n");
699 data_lists = _data_new();
700 if (!data_lists)
701 {
702 ret = -2;
703 goto end;
704 }
705 }
706
707 if (argc > 3)
708 {
709 if (strcmp(argv[3], "union") == 0)
710 {
711 if (argc > 4)
712 {
713 int type = atoi(argv[4]);
714 Example_Union *un;
715
716 if (type < EET_STRUCT1 || type > EET_STRUCT3)
717 {
718 fprintf(stderr,
719 "ERROR: invalid type parameter (%s).\n",
720 argv[4]);
721 goto cont;
722 }
723
724 switch (type)
725 {
726 case 1:
727 if (argc != 8)
728 {
729 fprintf(
730 stderr, "ERROR: wrong number of parameters"
731 " (%d).\n", argc);
732 goto cont;
733 }
734
735 un = _union_1_new(
736 argv[5], argv[6], argv[7]);
737 if (!un)
738 {
739 fprintf(
740 stderr, "ERROR: could not create the "
741 "requested union.\n");
742 goto cont;
743 }
744 data_lists->union_list =
745 eina_list_append(data_lists->union_list, un);
746 break;
747
748 case 2:
749 if (argc != 7)
750 {
751 fprintf(
752 stderr, "ERROR: wrong number of parameters"
753 " (%d).\n", argc);
754 goto cont;
755 }
756
757 un = _union_2_new(argv[5], argv[6]);
758 if (!un)
759 {
760 fprintf(
761 stderr, "ERROR: could not create the "
762 "requested union.\n");
763 goto cont;
764 }
765 data_lists->union_list =
766 eina_list_append(data_lists->union_list, un);
767 break;
768
769 case 3:
770 if (argc != 6)
771 {
772 fprintf(
773 stderr, "ERROR: wrong number of parameters"
774 " (%d).\n", argc);
775 goto cont;
776 }
777
778 un = _union_3_new(argv[5]);
779 if (!un)
780 {
781 fprintf(
782 stderr, "ERROR: could not create the "
783 "requested union.\n");
784 goto cont;
785 }
786 data_lists->union_list =
787 eina_list_append(data_lists->union_list, un);
788 break;
789
790 default:
791 fprintf(
792 stderr, "ERROR: bad type of of struct passed\n");
793 goto cont;
794 }
795 }
796 else
797 fprintf(stderr,
798 "ERROR: wrong number of parameters (%d).\n",
799 argc);
800 }
801 else if (strcmp(argv[3], "variant") == 0)
802 {
803 if (argc > 4)
804 {
805 int type = atoi(argv[4]);
806 Example_Variant *va;
807
808 if (type < EET_STRUCT1 || type > EET_STRUCT3)
809 {
810 fprintf(stderr,
811 "ERROR: invalid type parameter (%s).\n",
812 argv[4]);
813 goto cont;
814 }
815
816 switch (type)
817 {
818 case 1:
819 if (argc != 8)
820 {
821 fprintf(
822 stderr, "ERROR: wrong number of parameters"
823 " (%d).\n", argc);
824 goto cont;
825 }
826
827 va = _variant_1_new(
828 argv[5], argv[6], argv[7]);
829 if (!va)
830 {
831 fprintf(
832 stderr, "ERROR: could not create the "
833 "requested variant.\n");
834 goto cont;
835 }
836 data_lists->variant_list =
837 eina_list_append(data_lists->variant_list, va);
838 break;
839
840 case 2:
841 if (argc != 7)
842 {
843 fprintf(
844 stderr, "ERROR: wrong number of parameters"
845 " (%d).\n", argc);
846 goto cont;
847 }
848
849 va = _variant_2_new(argv[5], argv[6]);
850 if (!va)
851 {
852 fprintf(
853 stderr, "ERROR: could not create the "
854 "requested variant.\n");
855 goto cont;
856 }
857 data_lists->variant_list =
858 eina_list_append(data_lists->variant_list, va);
859 break;
860
861 case 3:
862 if (argc != 6)
863 {
864 fprintf(
865 stderr, "ERROR: wrong number of parameters"
866 " (%d).\n", argc);
867 goto cont;
868 }
869
870 va = _variant_3_new(argv[5]);
871 if (!va)
872 {
873 fprintf(
874 stderr, "ERROR: could not create the "
875 "requested variant.\n");
876 goto cont;
877 }
878 data_lists->variant_list =
879 eina_list_append(data_lists->variant_list, va);
880 break;
881
882 default:
883 fprintf(
884 stderr, "ERROR: bad type of of struct passed\n");
885 goto cont;
886 }
887 }
888 else
889 fprintf(stderr,
890 "ERROR: wrong number of parameters (%d).\n",
891 argc);
892 }
893 else
894 fprintf(stderr, "ERROR: unknown action '%s'\n", argv[3]);
895 }
896
897cont:
898 printf("Cached data:\n");
899
900 printf("\tstats: unions=%u, variants=%u\n",
901 eina_list_count(data_lists->union_list),
902 eina_list_count(data_lists->variant_list));
903
904 if (eina_list_count(data_lists->union_list))
905 {
906 const Eina_List *l;
907 const Example_Union *un;
908 printf("\t * union list:\n");
909
910 EINA_LIST_FOREACH(data_lists->union_list, l, un)
911 {
912 _print_union(un);
913 }
914 }
915
916 if (eina_list_count(data_lists->variant_list))
917 {
918 const Eina_List *l;
919 const Example_Variant *un;
920 printf("\t * variant list:\n");
921
922 EINA_LIST_FOREACH(data_lists->variant_list, l, un)
923 {
924 _print_variant(un);
925 }
926 }
927
928 printf("\n");
929
930 if (!_data_save(data_lists, argv[2]))
931 ret = -3;
932
933 _data_free(data_lists);
934
935end:
936 if (_cache_file)
937 eet_close(_cache_file);
938 _data_descriptors_shutdown();
939 eet_shutdown();
940 eina_shutdown();
941
942 return ret;
943} /* main */
944
diff --git a/src/examples/eet/eet-data-nested.c b/src/examples/eet/eet-data-nested.c
new file mode 100644
index 0000000000..a6b0e1208a
--- /dev/null
+++ b/src/examples/eet/eet-data-nested.c
@@ -0,0 +1,272 @@
1/*
2 * build: gcc -o eet_data_nested eet-data-nested.c `pkg-config --cflags --libs eet eina`
3 */
4#include <Eina.h>
5#include <Eet.h>
6#include <stdio.h>
7#include <limits.h>
8#include <sys/types.h>
9#include <sys/stat.h>
10#include <unistd.h>
11
12// The struct that will be loaded and saved.
13// note that only the members described in the eet_data_descriptor
14// will be automatically handled. The other members will have their
15// space reserved and zeroed (as it uses calloc()), but not
16// saved or loaded from eet files.
17typedef struct
18{
19 unsigned int version; // it is recommended to use versioned configuration!
20 const char *name;
21 int id;
22 int not_saved_value; // example of not saved data inside!
23 Eina_Bool enabled;
24 Eina_List *subs;
25} My_Conf_Type;
26
27typedef struct
28{
29 const char *server;
30 int port;
31} My_Conf_Subtype;
32
33// string that represents the entry in eet file, you might like to have
34// different profiles or so in the same file, this is possible with
35// different strings
36static const char MY_CONF_FILE_ENTRY[] = "config";
37
38// keep the descriptor static global, so it can be
39// shared by different functions (load/save) of this and only this
40// file.
41static Eet_Data_Descriptor *_my_conf_descriptor;
42static Eet_Data_Descriptor *_my_conf_sub_descriptor;
43
44static void
45_my_conf_descriptor_init(void)
46{
47 Eet_Data_Descriptor_Class eddc;
48
49 // The class describe the functions to use to create the type and its
50 // full allocated size.
51 //
52 // Eina types are very convenient, so use them to create the descriptor,
53 // so we get eina_list, eina_hash and eina_stringshare automatically!
54 //
55 // The STREAM variant is better for configuration files as the values
56 // will likely change a lot.
57 //
58 // The other variant, FILE, is good for caches and things that are just
59 // appended, but needs to take care when changing strings and files must
60 // be kept open so mmap()ed strings will be kept alive.
61 EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, My_Conf_Type);
62 _my_conf_descriptor = eet_data_descriptor_stream_new(&eddc);
63
64 EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, My_Conf_Subtype);
65 _my_conf_sub_descriptor = eet_data_descriptor_stream_new(&eddc);
66
67 // Describe the members to be saved:
68 // Use a temporary macro so we don't type a lot, also avoid errors:
69#define MY_CONF_ADD_BASIC(member, eet_type) \
70 EET_DATA_DESCRIPTOR_ADD_BASIC \
71 (_my_conf_descriptor, My_Conf_Type, # member, member, eet_type)
72#define MY_CONF_SUB_ADD_BASIC(member, eet_type) \
73 EET_DATA_DESCRIPTOR_ADD_BASIC \
74 (_my_conf_sub_descriptor, My_Conf_Subtype, # member, member, eet_type)
75
76 MY_CONF_SUB_ADD_BASIC(server, EET_T_STRING);
77 MY_CONF_SUB_ADD_BASIC(port, EET_T_INT);
78
79 MY_CONF_ADD_BASIC(version, EET_T_UINT);
80 MY_CONF_ADD_BASIC(name, EET_T_STRING);
81 MY_CONF_ADD_BASIC(id, EET_T_INT);
82 MY_CONF_ADD_BASIC(enabled, EET_T_UCHAR);
83
84 // And add the sub descriptor as a linked list at 'subs' in the main struct
85 EET_DATA_DESCRIPTOR_ADD_LIST
86 (_my_conf_descriptor, My_Conf_Type, "subs", subs, _my_conf_sub_descriptor);
87
88#undef MY_CONF_ADD_BASIC
89#undef MY_CONF_SUB_ADD_BASIC
90} /* _my_conf_descriptor_init */
91
92static void
93_my_conf_descriptor_shutdown(void)
94{
95 eet_data_descriptor_free(_my_conf_sub_descriptor);
96 eet_data_descriptor_free(_my_conf_descriptor);
97} /* _my_conf_descriptor_shutdown */
98
99static My_Conf_Type *
100_my_conf_new(void)
101{
102 My_Conf_Type *my_conf = calloc(1, sizeof(My_Conf_Type));
103 My_Conf_Subtype *sub;
104 if (!my_conf)
105 {
106 fprintf(stderr, "ERROR: could not calloc My_Conf_Type\n");
107 return NULL;
108 }
109
110 my_conf->version = 0x112233;
111 my_conf->enabled = EINA_TRUE;
112
113 sub = calloc(1, sizeof(My_Conf_Subtype));
114 if (sub)
115 {
116 sub->server = eina_stringshare_add("my-server.com");
117 sub->port = 1234;
118 my_conf->subs = eina_list_append(my_conf->subs, sub);
119 }
120
121 return my_conf;
122} /* _my_conf_new */
123
124static void
125_my_conf_free(My_Conf_Type *my_conf)
126{
127 My_Conf_Subtype *sub;
128 EINA_LIST_FREE(my_conf->subs, sub)
129 {
130 eina_stringshare_del(sub->server);
131 free(sub);
132 }
133
134 eina_stringshare_del(my_conf->name);
135 free(my_conf);
136} /* _my_conf_free */
137
138static My_Conf_Type *
139_my_conf_load(const char *filename)
140{
141 My_Conf_Type *my_conf;
142 Eet_File *ef = eet_open(filename, EET_FILE_MODE_READ);
143 if (!ef)
144 {
145 fprintf(stderr, "ERROR: could not open '%s' for read\n", filename);
146 return NULL;
147 }
148
149 my_conf = eet_data_read(ef, _my_conf_descriptor, MY_CONF_FILE_ENTRY);
150 if (!my_conf)
151 goto end;
152
153 if (my_conf->version < 0x112233)
154 {
155 fprintf(stderr,
156 "WARNING: version %#x was too old, upgrading it to %#x\n",
157 my_conf->version, 0x112233);
158
159 my_conf->version = 0x112233;
160 my_conf->enabled = EINA_TRUE;
161 }
162
163end:
164 eet_close(ef);
165 return my_conf;
166} /* _my_conf_load */
167
168static Eina_Bool
169_my_conf_save(const My_Conf_Type *my_conf,
170 const char *filename)
171{
172 char tmp[PATH_MAX];
173 Eet_File *ef;
174 Eina_Bool ret;
175 unsigned int i, len;
176 struct stat st;
177
178 len = eina_strlcpy(tmp, filename, sizeof(tmp));
179 if (len + 12 >= (int)sizeof(tmp))
180 {
181 fprintf(stderr, "ERROR: file name is too big: %s\n", filename);
182 return EINA_FALSE;
183 }
184
185 i = 0;
186 do
187 {
188 snprintf(tmp + len, 12, ".%u", i);
189 i++;
190 }
191 while (stat(tmp, &st) == 0);
192
193 ef = eet_open(tmp, EET_FILE_MODE_WRITE);
194 if (!ef)
195 {
196 fprintf(stderr, "ERROR: could not open '%s' for write\n", tmp);
197 return EINA_FALSE;
198 }
199
200 ret = eet_data_write
201 (ef, _my_conf_descriptor, MY_CONF_FILE_ENTRY, my_conf, EINA_TRUE);
202 eet_close(ef);
203
204 if (ret)
205 {
206 unlink(filename);
207 rename(tmp, filename);
208 }
209
210 return ret;
211} /* _my_conf_save */
212
213int
214main(int argc,
215 char *argv[])
216{
217 My_Conf_Type *my_conf;
218 const My_Conf_Subtype *sub;
219 const Eina_List *l;
220 int ret = 0;
221
222 if (argc != 3)
223 {
224 fprintf(stderr, "Usage:\n\t%s <input> <output>\n\n", argv[0]);
225 return -1;
226 }
227
228 eina_init();
229 eet_init();
230 _my_conf_descriptor_init();
231
232 my_conf = _my_conf_load(argv[1]);
233 if (!my_conf)
234 {
235 printf("creating new configuration.\n");
236 my_conf = _my_conf_new();
237 if (!my_conf)
238 {
239 ret = -2;
240 goto end;
241 }
242 }
243
244 printf("My_Conf_Type:\n"
245 "\tversion: %#x\n"
246 "\tname...: '%s'\n"
247 "\tid.....: %d\n"
248 "\tenabled: %hhu\n"
249 "\tsubs...:\n",
250 my_conf->version,
251 my_conf->name ? my_conf->name : "",
252 my_conf->id,
253 my_conf->enabled);
254
255 EINA_LIST_FOREACH(my_conf->subs, l, sub)
256 printf("\t\tserver: '%s', port: %d\n",
257 sub->server ? sub->server : "",
258 sub->port);
259
260 if (!_my_conf_save(my_conf, argv[2]))
261 ret = -3;
262
263 _my_conf_free(my_conf);
264
265end:
266 _my_conf_descriptor_shutdown();
267 eet_shutdown();
268 eina_shutdown();
269
270 return ret;
271} /* main */
272
diff --git a/src/examples/eet/eet-data-simple.c b/src/examples/eet/eet-data-simple.c
new file mode 100644
index 0000000000..1951fc012b
--- /dev/null
+++ b/src/examples/eet/eet-data-simple.c
@@ -0,0 +1,224 @@
1/*
2 * build: gcc -o eet_data_simple eet-data-simple.c `pkg-config --cflags --libs eet eina`
3 */
4#include <Eina.h>
5#include <Eet.h>
6#include <stdio.h>
7#include <limits.h>
8#include <sys/types.h>
9#include <sys/stat.h>
10#include <unistd.h>
11
12// The struct that will be loaded and saved.
13// note that only the members described in the eet_data_descriptor
14// will be automatically handled. The other members will have their
15// space reserved and zeroed (as it uses calloc()), but not
16// saved or loaded from eet files.
17typedef struct
18{
19 unsigned int version; // it is recommended to use versioned configuration!
20 const char *name;
21 int id;
22 int not_saved_value; // example of not saved data inside!
23 Eina_Bool enabled;
24} My_Conf_Type;
25
26// string that represents the entry in eet file, you might like to have
27// different profiles or so in the same file, this is possible with
28// different strings
29static const char MY_CONF_FILE_ENTRY[] = "config";
30
31// keep the descriptor static global, so it can be
32// shared by different functions (load/save) of this and only this
33// file.
34static Eet_Data_Descriptor *_my_conf_descriptor;
35
36static void
37_my_conf_descriptor_init(void)
38{
39 Eet_Data_Descriptor_Class eddc;
40
41 // The class describe the functions to use to create the type and its
42 // full allocated size.
43 //
44 // Eina types are very convenient, so use them to create the descriptor,
45 // so we get eina_list, eina_hash and eina_stringshare automatically!
46 //
47 // The STREAM variant is better for configuration files as the values
48 // will likely change a lot.
49 //
50 // The other variant, FILE, is good for caches and things that are just
51 // appended, but needs to take care when changing strings and files must
52 // be kept open so mmap()ed strings will be kept alive.
53 EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, My_Conf_Type);
54 _my_conf_descriptor = eet_data_descriptor_stream_new(&eddc);
55
56 // Describe the members to be saved:
57 // Use a temporary macro so we don't type a lot, also avoid errors:
58#define MY_CONF_ADD_BASIC(member, eet_type) \
59 EET_DATA_DESCRIPTOR_ADD_BASIC \
60 (_my_conf_descriptor, My_Conf_Type, # member, member, eet_type)
61
62 MY_CONF_ADD_BASIC(version, EET_T_UINT);
63 MY_CONF_ADD_BASIC(name, EET_T_STRING);
64 MY_CONF_ADD_BASIC(id, EET_T_INT);
65 MY_CONF_ADD_BASIC(enabled, EET_T_UCHAR);
66
67#undef MY_CONF_ADD_BASIC
68} /* _my_conf_descriptor_init */
69
70static void
71_my_conf_descriptor_shutdown(void)
72{
73 eet_data_descriptor_free(_my_conf_descriptor);
74} /* _my_conf_descriptor_shutdown */
75
76static My_Conf_Type *
77_my_conf_new(void)
78{
79 My_Conf_Type *my_conf = calloc(1, sizeof(My_Conf_Type));
80 if (!my_conf)
81 {
82 fprintf(stderr, "ERROR: could not calloc My_Conf_Type\n");
83 return NULL;
84 }
85
86 my_conf->version = 0x112233;
87 my_conf->enabled = EINA_TRUE;
88 return my_conf;
89} /* _my_conf_new */
90
91static void
92_my_conf_free(My_Conf_Type *my_conf)
93{
94 eina_stringshare_del(my_conf->name);
95 free(my_conf);
96} /* _my_conf_free */
97
98static My_Conf_Type *
99_my_conf_load(const char *filename)
100{
101 My_Conf_Type *my_conf;
102 Eet_File *ef = eet_open(filename, EET_FILE_MODE_READ);
103 if (!ef)
104 {
105 fprintf(stderr, "ERROR: could not open '%s' for read\n", filename);
106 return NULL;
107 }
108
109 my_conf = eet_data_read(ef, _my_conf_descriptor, MY_CONF_FILE_ENTRY);
110 if (!my_conf)
111 goto end;
112
113 if (my_conf->version < 0x112233)
114 {
115 fprintf(stderr,
116 "WARNING: version %#x was too old, upgrading it to %#x\n",
117 my_conf->version, 0x112233);
118
119 my_conf->version = 0x112233;
120 my_conf->enabled = EINA_TRUE;
121 }
122
123end:
124 eet_close(ef);
125 return my_conf;
126} /* _my_conf_load */
127
128static Eina_Bool
129_my_conf_save(const My_Conf_Type *my_conf,
130 const char *filename)
131{
132 char tmp[PATH_MAX];
133 Eet_File *ef;
134 Eina_Bool ret;
135 unsigned int i, len;
136 struct stat st;
137
138 len = eina_strlcpy(tmp, filename, sizeof(tmp));
139 if (len + 12 >= (int)sizeof(tmp))
140 {
141 fprintf(stderr, "ERROR: file name is too big: %s\n", filename);
142 return EINA_FALSE;
143 }
144
145 i = 0;
146 do
147 {
148 snprintf(tmp + len, 12, ".%u", i);
149 i++;
150 }
151 while (stat(tmp, &st) == 0);
152
153 ef = eet_open(tmp, EET_FILE_MODE_WRITE);
154 if (!ef)
155 {
156 fprintf(stderr, "ERROR: could not open '%s' for write\n", tmp);
157 return EINA_FALSE;
158 }
159
160 ret = eet_data_write
161 (ef, _my_conf_descriptor, MY_CONF_FILE_ENTRY, my_conf, EINA_TRUE);
162 eet_close(ef);
163
164 if (ret)
165 {
166 unlink(filename);
167 rename(tmp, filename);
168 }
169
170 return ret;
171} /* _my_conf_save */
172
173int
174main(int argc,
175 char *argv[])
176{
177 My_Conf_Type *my_conf;
178 int ret = 0;
179
180 if (argc != 3)
181 {
182 fprintf(stderr, "Usage:\n\t%s <input> <output>\n\n", argv[0]);
183 return -1;
184 }
185
186 eina_init();
187 eet_init();
188 _my_conf_descriptor_init();
189
190 my_conf = _my_conf_load(argv[1]);
191 if (!my_conf)
192 {
193 printf("creating new configuration.\n");
194 my_conf = _my_conf_new();
195 if (!my_conf)
196 {
197 ret = -2;
198 goto end;
199 }
200 }
201
202 printf("My_Conf_Type:\n"
203 "\tversion: %#x\n"
204 "\tname...: '%s'\n"
205 "\tid.....: %d\n"
206 "\tenabled: %hhu\n",
207 my_conf->version,
208 my_conf->name ? my_conf->name : "",
209 my_conf->id,
210 my_conf->enabled);
211
212 if (!_my_conf_save(my_conf, argv[2]))
213 ret = -3;
214
215 _my_conf_free(my_conf);
216
217end:
218 _my_conf_descriptor_shutdown();
219 eet_shutdown();
220 eina_shutdown();
221
222 return ret;
223} /* main */
224
diff --git a/src/examples/eet/eet-file.c b/src/examples/eet/eet-file.c
new file mode 100644
index 0000000000..740c179f7b
--- /dev/null
+++ b/src/examples/eet/eet-file.c
@@ -0,0 +1,127 @@
1/*
2 * build: gcc -o eet_file eet-file.c `pkg-config --cflags --libs eet`
3 */
4#include <Eet.h>
5#include <stdio.h>
6#include <string.h>
7
8static int
9create_eet_file(void)
10{
11 Eet_File *ef;
12 char buf[1024], *ptr;
13 int size, len, i;
14 const char *some_strings[] = {
15 "And some more strings",
16 "spread across several",
17 "elements of an array!"
18 };
19 const char some_data[] =
20 "\x1e\xe7\x0f\x42\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x35"
21 "\x00\x00\x00\xa0\x00\x00\x00\xa0\x00\x00\x00\x24\x00\x00\x00\x11"
22 "\x00\x00\x00\x00\x2f\x6d\x69\x73\x74\x65\x72\x69\x6f\x75\x73\x2f"
23 "\x64\x61\x74\x61\x00\x41\x6e\x20\x45\x45\x54\x20\x69\x6e\x73\x69"
24 "\x64\x65\x20\x6f\x66\x20\x61\x6e\x20\x45\x45\x54\x21\x0a\x54\x68"
25 "\x69\x73\x20\x77\x61\x73\x6e\x27\x74\x20\x72\x65\x61\x6c\x6c\x79"
26 "\x20\x75\x73\x65\x66\x75\x6c\x20\x62\x75\x74\x20\x69\x74\x20\x68"
27 "\x65\x6c\x70\x65\x64\x20\x74\x6f\x20\x73\x68\x6f\x77\x20\x68\x6f"
28 "\x77\x0a\x74\x6f\x20\x75\x73\x65\x20\x65\x65\x74\x5f\x6d\x65\x6d"
29 "\x6f\x70\x65\x6e\x5f\x72\x65\x61\x64\x28\x29\x20\x74\x6f\x20\x6f"
30 "\x70\x65\x6e\x20\x61\x6e\x20\x65\x65\x74\x20\x66\x69\x6c\x65\x20"
31 "\x66\x72\x6f\x6d\x0a\x64\x61\x74\x61\x20\x61\x6c\x72\x65\x61\x64"
32 "\x79\x20\x6c\x6f\x61\x64\x65\x64\x20\x69\x6e\x20\x6d\x65\x6d\x6f"
33 "\x72\x79\x2e\x0a\x00";
34
35 ef = eet_open("/tmp/my_file.eet", EET_FILE_MODE_WRITE);
36 if (!ef) return 0;
37
38 strcpy(buf, "Here is a string of data to save!");
39 size = eet_write(ef, "/key/to_store/at", buf, sizeof(buf), 1);
40 if (!size)
41 {
42 fprintf(stderr, "Error writing data!\n");
43 eet_close(ef);
44 return 0;
45 }
46 len = strlen(buf);
47 printf("strlen() = %d, eet_write() = %d\n", len, size);
48
49 ptr = buf;
50 for (i = 0; i < 3; i++)
51 {
52 len = strlen(some_strings[i]) + 1;
53 memcpy(ptr, some_strings[i], len);
54 ptr += len;
55 }
56 eet_write(ef, "/several/strings", buf, sizeof(buf), 1);
57 eet_sync(ef);
58
59 eet_write(ef, "/some/mysterious/data", some_data, sizeof(some_data) - 1, 1);
60
61 eet_delete(ef, "/several/strings");
62
63 return eet_close(ef) == EET_ERROR_NONE;
64}
65
66int
67main(void)
68{
69 Eet_File *ef;
70 char *ret, **list;
71 int size, num, i;
72
73 eet_init();
74
75 if (!create_eet_file())
76 return -1;
77
78 ef = eet_open("/tmp/my_file.eet", EET_FILE_MODE_READ);
79 if (!ef) return -1;
80
81 list = eet_list(ef, "*", &num);
82 if (list)
83 {
84 for (i = 0; i < num; i++)
85 printf("Key stored: %s\n", list[i]);
86 free(list);
87 }
88
89 ret = eet_read(ef, "/key/to_store/at", &size);
90 if (ret)
91 {
92 printf("Data read (%i bytes):\n%s\n", size, ret);
93 free(ret);
94 }
95
96 ret = eet_read(ef, "/several/strings", &size);
97 if (ret)
98 {
99 printf("More data read (%i bytes):\n%s\n", size, ret);
100 free(ret);
101 }
102
103 ret = eet_read(ef, "/some/mysterious/data", &size);
104 if (ret)
105 {
106 Eet_File *ef2;
107
108 ef2 = eet_memopen_read(ret, size);
109
110 num = eet_num_entries(ef2);
111 printf("Mysterious data has %d entries\n", num);
112
113 printf("Mysterious data:\n%s\n",
114 (char *)eet_read_direct(ef2, "/mysterious/data", NULL));
115
116 eet_close(ef2);
117
118 free(ret);
119 }
120
121 eet_close(ef);
122
123 eet_shutdown();
124
125 return 0;
126}
127
diff --git a/src/examples/eina/Makefile.am b/src/examples/eina/Makefile.am
index 4656e47241..96e7735e50 100644
--- a/src/examples/eina/Makefile.am
+++ b/src/examples/eina/Makefile.am
@@ -112,7 +112,7 @@ install-examples:
112 mkdir -p $(pkgdatadir)/examples 112 mkdir -p $(pkgdatadir)/examples
113 $(install_sh_DATA) -c $(SRCS) $(pkgdatadir)/examples 113 $(install_sh_DATA) -c $(SRCS) $(pkgdatadir)/examples
114 114
115unsinstall-local: 115uninstall-local:
116 for f in $(SRCS) ; do \ 116 for f in $(SRCS) ; do \
117 rm -f $(pkgdatadir)/examples/$$f ; \ 117 rm -f $(pkgdatadir)/examples/$$f ; \
118 done 118 done
diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am
index 92c50645f5..8522639495 100644
--- a/src/lib/Makefile.am
+++ b/src/lib/Makefile.am
@@ -8,4 +8,4 @@ SUBDIRS += evil
8 8
9endif 9endif
10 10
11SUBDIRS += eina 11SUBDIRS += eina eet
diff --git a/src/lib/eet/Eet.h b/src/lib/eet/Eet.h
new file mode 100644
index 0000000000..05f80e959f
--- /dev/null
+++ b/src/lib/eet/Eet.h
@@ -0,0 +1,4271 @@
1/**
2 @brief Eet Data Handling Library Public API Calls
3
4 These routines are used for Eet Library interaction
5
6 @mainpage Eet Library Documentation
7
8 @version 1.7.0
9 @date 2000-2012
10
11 Please see the @ref authors page for contact details.
12
13 @section toc Table of Contents
14
15 @li @ref intro
16 @li @ref example
17 @li @ref compiling
18 @li @ref install
19 @li @ref next_steps
20 @li @ref intro_example
21
22 @section intro What is Eet?
23
24 It is a tiny library designed to write an arbitrary set of chunks of data
25 to a file and optionally compress each chunk (very much like a zip file)
26 and allow fast random-access reading of the file later on. It does not
27 do zip as a zip itself has more complexity than is needed, and it was much
28 simpler to implement this once here.
29
30 Eet is extremely fast, small and simple. Eet files can be very small and
31 highly compressed, making them very optimal for just sending across the
32 internet without having to archive, compress or decompress and install them.
33 They allow for lightning-fast random-access reads once created, making them
34 perfect for storing data that is written once (or rarely) and read many
35 times, but the program does not want to have to read it all in at once.
36
37 It also can encode and decode data structures in memory, as well as image
38 data for saving to Eet files or sending across the network to other
39 machines, or just writing to arbitrary files on the system. All data is
40 encoded in a platform independent way and can be written and read by any
41 architecture.
42
43 @section example A simple example on using Eet
44
45 Here is a simple example on how to use Eet to save a series of strings to a
46 file and load them again. The advantage of using Eet over just
47 fprintf() and
48 fscanf() is that not only can these entries be strings, they need no special
49 parsing to handle delimiter characters or escaping, they can be binary data,
50 image data, data structures containing integers, strings, other data
51 structures, linked lists and much more, without the programmer having to
52 worry about parsing, and best of all, Eet is very fast.
53
54 This is just a very simple example that doesn't show all of the capabilities
55 of Eet, but it serves to illustrate its simplicity.
56
57 @include eet-basic.c
58
59 @section compiling How to compile using Eet ?
60
61 Eet is a library your application links to. The procedure for this is very
62 simple. You simply have to compile your application with the appropriate
63 compiler flags that the @p pkg-config script outputs. For example:
64
65 Compiling C or C++ files into object files:
66
67 @verbatim
68 gcc -c -o main.o main.c `pkg-config --cflags eet`
69 @endverbatim
70
71 Linking object files into a binary executable:
72
73 @verbatim
74 gcc -o my_application main.o `pkg-config --libs eet`
75 @endverbatim
76
77 You simply have to make sure that pkg-config is in your shell's PATH (see
78 the manual page for your appropriate shell) and eet.pc in /usr/lib/pkgconfig
79 or its path is in the PKG_CONFIG_PATH environment variable. It's that simple
80 to link and use Eet once you have written your code to use it.
81
82 Since the program is linked to Eet, it is now able to use any advertised
83 API calls to serialize your data.
84
85 You should make sure you add any extra compile and link flags to your
86 compile commands that your application may need as well. The above example
87 is only guaranteed to make Eet add it's own requirements.
88
89
90 @section install How is it installed?
91
92 Simple:
93
94 @verbatim
95 ./configure
96 make
97 su -
98 ...
99 make install
100 @endverbatim
101
102 @section next_steps Next Steps
103
104 After you understood what Eet is and installed it in your system you
105 should proceed understanding the programming interface. We'd recommend
106 you to take a while to learn Eina
107 (http://docs.enlightenment.org/auto/eina/) as it is very convenient
108 and optimized, and Eet provides integration with it.
109
110 Recommended reading:
111
112 @li @ref Eet_File_Group to know the basics to open and save files.
113 @li @ref Eet_Data_Group to know the convenient way to serialize and
114 parse your data structures automatically. Just create your
115 descriptors and let Eet do the work for you.
116
117 @section intro_example Introductory Examples
118
119 @ref Examples
120
121 @todo Document data format for images and data structures.
122
123 */
124
125/**
126 @page authors Authors
127 @author Carsten Haitzler <raster@@rasterman.com>
128 @author David Goodlad <dgoodlad@@gmail.com>
129 @author Cedric Bail <cedric.bail@@free.fr>
130 @author Arnaud de Turckheim <quarium@@gmail.com>
131 @author Luis Felipe Strano Moraes <lfelipe@@profusion.mobi>
132 @author Chidambar Zinnoury <illogict@@online.fr>
133 @author Vincent Torri <vtorri@@univ-evry.fr>
134 @author Gustavo Sverzut Barbieri <barbieri@@profusion.mobi>
135 @author Raphael Kubo da Costa <kubo@@profusion.mobi>
136 @author Mathieu Taillefumier <mathieu.taillefumier@@free.fr>
137 @author Albin "Lutin" Tonnerre <albin.tonnerre@@gmail.com>
138 @author Adam Simpkins <adam@@adamsimpkins.net>
139 @author Mike Blumenkrantz <michael.blumenkrantz@gmail.com>
140
141 Please contact <enlightenment-devel@lists.sourceforge.net> to get in
142 contact with the developers and maintainers.
143 */
144
145#ifndef _EET_H
146#define _EET_H
147
148#include <stdlib.h>
149#include <stdio.h>
150#include <Eina.h>
151
152#ifdef EAPI
153# undef EAPI
154#endif /* ifdef EAPI */
155
156#ifdef _WIN32
157# ifdef EFL_EET_BUILD
158# ifdef DLL_EXPORT
159# define EAPI __declspec(dllexport)
160# else /* ifdef DLL_EXPORT */
161# define EAPI
162# endif /* ! DLL_EXPORT */
163# else /* ifdef EFL_EET_BUILD */
164# define EAPI __declspec(dllimport)
165# endif /* ! EFL_EET_BUILD */
166#else /* ifdef _WIN32 */
167# ifdef __GNUC__
168# if __GNUC__ >= 4
169# define EAPI __attribute__ ((visibility("default")))
170# else /* if __GNUC__ >= 4 */
171# define EAPI
172# endif /* if __GNUC__ >= 4 */
173# else /* ifdef __GNUC__ */
174# define EAPI
175# endif /* ifdef __GNUC__ */
176#endif /* ! _WIN32 */
177
178#ifdef __cplusplus
179extern "C" {
180#endif /* ifdef __cplusplus */
181
182/**
183 * @file Eet.h
184 * @brief The file that provides the eet functions.
185 *
186 * This header provides the Eet management functions.
187 *
188 */
189
190#define EET_VERSION_MAJOR 1
191#define EET_VERSION_MINOR 8
192/**
193 * @typedef Eet_Version
194 *
195 * This is the Eet version information structure that can be used at
196 * runtime to detect which version of eet is being used and adapt
197 * appropriately as follows for example:
198 *
199 * @code
200 * #if defined(EET_VERSION_MAJOR) && (EET_VERSION_MAJOR >= 1) && defined(EET_VERSION_MINOR) && (EET_VERSION_MINOR > 2)
201 * printf("Eet version: %i.%i.%i\n",
202 * eet_version->major,
203 * eet_version->minor,
204 * eet_version->micro);
205 * if (eet_version->revision > 0)
206 * {
207 * printf(" Built from SVN revision # %i\n", eet_version->revision);
208 * }
209 * #endif
210 * @endcode
211 *
212 * Note the \#if check can be dropped if your program refuses to compile or
213 * work with an Eet version less than 1.3.0.
214 */
215typedef struct _Eet_Version
216{
217 int major; /** < major (binary or source incompatible changes) */
218 int minor; /** < minor (new features, bugfixes, major improvements version) */
219 int micro; /** < micro (bugfix, internal improvements, no new features version) */
220 int revision; /** < svn revision (0 if a proper release or the svn revision number Eet is built from) */
221} Eet_Version;
222
223EAPI extern Eet_Version *eet_version;
224
225/**
226 * @defgroup Eet_Group Top level functions
227 * Functions that affect Eet as a whole.
228 *
229 * @{
230 */
231
232/**
233 * @enum _Eet_Error
234 * All the error identifiers known by Eet.
235 */
236typedef enum _Eet_Error
237{
238 EET_ERROR_NONE, /**< No error, it's all fine! */
239 EET_ERROR_BAD_OBJECT, /**< Given object or handle is NULL or invalid */
240 EET_ERROR_EMPTY, /**< There was nothing to do */
241 EET_ERROR_NOT_WRITABLE, /**< Could not write to file or file is #EET_FILE_MODE_READ */
242 EET_ERROR_OUT_OF_MEMORY, /**< Could not allocate memory */
243 EET_ERROR_WRITE_ERROR, /**< Failed to write data to destination */
244 EET_ERROR_WRITE_ERROR_FILE_TOO_BIG, /**< Failed to write file since it is too big */
245 EET_ERROR_WRITE_ERROR_IO_ERROR, /**< Failed to write due a generic Input/Output error */
246 EET_ERROR_WRITE_ERROR_OUT_OF_SPACE, /**< Failed to write due out of space */
247 EET_ERROR_WRITE_ERROR_FILE_CLOSED, /**< Failed to write because file was closed */
248 EET_ERROR_MMAP_FAILED, /**< Could not mmap file */
249 EET_ERROR_X509_ENCODING_FAILED, /**< Could not encode using X509 */
250 EET_ERROR_SIGNATURE_FAILED, /**< Could not validate signature */
251 EET_ERROR_INVALID_SIGNATURE, /**< Signature is invalid */
252 EET_ERROR_NOT_SIGNED, /**< File or contents are not signed */
253 EET_ERROR_NOT_IMPLEMENTED, /**< Function is not implemented */
254 EET_ERROR_PRNG_NOT_SEEDED, /**< Could not introduce random seed */
255 EET_ERROR_ENCRYPT_FAILED, /**< Could not encrypt contents */
256 EET_ERROR_DECRYPT_FAILED /**< Could not decrypt contents */
257} Eet_Error; /**< Eet error identifiers */
258
259/**
260 * @}
261 */
262
263/**
264 * @defgroup Eet_Compression Eet Compression Levels
265 * Compression modes/levels supported by Eet.
266 *
267 * @{
268 */
269
270/**
271 * @enum _Eet_Compression
272 * All the compression modes known by Eet.
273 */
274
275typedef enum _Eet_Compression
276{
277 EET_COMPRESSION_NONE = 0, /**< No compression at all @since 1.7 */
278 EET_COMPRESSION_DEFAULT = 1, /**< Default compression (Zlib) @since 1.7 */
279 EET_COMPRESSION_LOW = 2, /**< Fast but minimal compression (Zlib) @since 1.7 */
280 EET_COMPRESSION_MED = 6, /**< Medium compression level (Zlib) @since 1.7 */
281 EET_COMPRESSION_HI = 9, /**< Slow but high compression level (Zlib) @since 1.7 */
282 EET_COMPRESSION_VERYFAST = 10, /**< Very fast, but lower compression ratio (LZ4HC) @since 1.7 */
283 EET_COMPRESSION_SUPERFAST = 11, /**< Very fast, but lower compression ratio (faster to compress than EET_COMPRESSION_VERYFAST) (LZ4) @since 1.7 */
284
285 EET_COMPRESSION_LOW2 = 3, /**< Space filler for compatibility. Don't use it @since 1.7 */
286 EET_COMPRESSION_MED1 = 4, /**< Space filler for compatibility. Don't use it @since 1.7 */
287 EET_COMPRESSION_MED2 = 5, /**< Space filler for compatibility. Don't use it @since 1.7 */
288 EET_COMPRESSION_HI1 = 7, /**< Space filler for compatibility. Don't use it @since 1.7 */
289 EET_COMPRESSION_HI2 = 8 /**< Space filler for compatibility. Don't use it @since 1.7 */
290} Eet_Compression; /**< Eet compression modes @since 1.7 */
291
292/**
293 * @}
294 */
295
296/**
297 * Initialize the EET library.
298 *
299 * The first time this function is called, it will perform all the internal
300 * initialization required for the library to function properly and increment
301 * the initialization counter. Any subsequent call only increment this counter
302 * and return its new value, so it's safe to call this function more than once.
303 *
304 * @return The new init count. Will be 0 if initialization failed.
305 *
306 * @since 1.0.0
307 * @ingroup Eet_Group
308 */
309EAPI int
310eet_init(void);
311
312/**
313 * Shut down the EET library.
314 *
315 * If eet_init() was called more than once for the running application,
316 * eet_shutdown() will decrement the initialization counter and return its
317 * new value, without doing anything else. When the counter reaches 0, all
318 * of the internal elements will be shutdown and any memory used freed.
319 *
320 * @return The new init count.
321 *
322 * @since 1.0.0
323 * @ingroup Eet_Group
324 */
325EAPI int
326eet_shutdown(void);
327
328/**
329 * Clear eet cache
330 *
331 * For a faster access to previously accessed data, Eet keeps an internal
332 * cache of files. These files will be freed automatically only when
333 * they are unused and the cache gets full, in order based on the last time
334 * they were used.
335 * On systems with little memory this may present an unnecessary constraint,
336 * so eet_clearcache() is available for users to reclaim the memory used by
337 * files that are no longer needed. Those that were open using
338 * ::EET_FILE_MODE_WRITE or ::EET_FILE_MODE_READ_WRITE and have modifications,
339 * will be written down to disk before flushing them from memory.
340 *
341 * @since 1.0.0
342 * @ingroup Eet_Group
343 */
344EAPI void
345eet_clearcache(void);
346
347/**
348 * @defgroup Eet_File_Group Eet File Main Functions
349 *
350 * Functions to create, destroy and do basic manipulation of
351 * #Eet_File handles.
352 *
353 * This sections explains how to use the most basic Eet functions, which
354 * are used to work with eet files, read data from them, store it back in or
355 * take a look at what entries it contains, without making use of the
356 * serialization capabilities explained in @ref Eet_Data_Group.
357 *
358 * The following example will serve as an introduction to most, if not all,
359 * of these functions.
360 *
361 * If you are only using Eet, this is the only header you need to include.
362 * @dontinclude eet-file.c
363 * @skipline Eet.h
364 *
365 * Now let's create ourselves an eet file to play with. The following function
366 * shows step by step how to open a file and write some data in it.
367 * First, we define our file handler and some other things we'll put in it.
368 * @line static int
369 * @skip Eet_File
370 * @until ";
371 * @skip eet_open
372 *
373 * We open a new file in write mode, and if it fails, we just return, since
374 * there's not much more we can do about it..
375 * @until return
376 *
377 * Now, we need to write some data in our file. For now, strings will suffice,
378 * so let's just dump a bunch of them in there.
379 * @until }
380 *
381 * As you can see, we copied a string into our static buffer, which is a bit
382 * bigger than the full length of the string, and then told Eet to write it
383 * into the file, compressed, returning the size of the data written into the
384 * file.
385 * This is all to show that Eet treats data as just data. It doesn't matter
386 * what that data represents (for now), it's all just bytes for it. As running
387 * the following code will show, we took a string of around 30 bytes and put it
388 * in a buffer of 1024 bytes, but the returned size won't be any of those.
389 * @until printf
390 *
391 * Next, we copy into our buffer our set of strings, including their null
392 * terminators and write them into the file. No error checking for the sake
393 * of brevity. And a call to eet_sync() to make sure all out data is
394 * properly written down to disk, even though we haven't yet closed the file.
395 * @until eet_sync
396 *
397 * One more write, this time our large array of binary data and... well, I
398 * couldn't come up with a valid use of the last set of strings we stored,
399 * so let's take it out from the file with eet_delete().
400 * @until eet_delete
401 *
402 * Finally, we close the file, saving any changes back to disk and return.
403 * Notice how, if there's any error closing the file or saving its contents,
404 * the return value from the function will be a false one, which later on
405 * will make the program exit with an error code.
406 * @until return
407 *
408 * Moving onto our main function, we will open the same file and read it back.
409 * Trivial, but it'll show how we can do so in more than one way. We'll skip
410 * the variable declarations, as they aren't very different from what we've
411 * seen already.
412 *
413 * We start from the beginning by initializing Eet so things in general work.
414 * Forgetting to do so will result in weird results or crashes when calling
415 * any eet function, so if you experience something like that, the first thing
416 * to look at is whether eet_init() is missing.
417 * Then we call our @p create_eet_file function, described above, to make
418 * sure we have something to work with. If the function fails it will return
419 * 0 and we just exit, since nothing from here onwards will work anyway.
420 * @skip eet_init
421 * @until return
422 *
423 * Let's take a look now at what entries our file has. For this, we use
424 * eet_list(), which will return a list of strings, each being the name of
425 * one entry. Since we skipped before, it may be worth noting that @p list
426 * is declared as a @p char **.
427 * The @p num parameter will, of course, have the number of entries contained
428 * in our file.
429 * If everything's fine, we'll get our list and print it to the screen, and
430 * once done with it, we free the list. That's just the list, not its contents,
431 * as they are internal strings used by Eet and trying to free them will surely
432 * break things.
433 * @until }
434 *
435 * Reading back plain data is simple. Just a call to eet_read() with the file
436 * to read from, and the name of the entry we are interested in. We get back
437 * our data and the passed @p size parameter will contain the size of it. If
438 * the data was stored compressed, it will decompressed first.
439 * @until }
440 *
441 * Another simple read for the set of strings from before, except those were
442 * deleted, so we should get a NULL return and continue normally.
443 * @until }
444 *
445 * Finally, we'll get our binary data in the same way we got the strings. Once
446 * again, it makes no difference for Eet what the data is, it's up to us to
447 * know how to handle it.
448 * @until {
449 *
450 * Now some cheating, we know that this data is an Eet file because, well...
451 * we just know it. So we are going to open it and take a look at its insides.
452 * For this, eet_open() won't work, as it needs to have a file on disk to read
453 * from and all we have is some data in RAM.
454 *
455 * So how do we do? One way would be to create a normal file and write down
456 * our data, then open it with eet_open(). Another, faster and more efficient
457 * if all we want to do is read the file, is to use eet_memopen_read().
458 * @until memopen
459 *
460 * As you can see, the size we got from our previous read was put to good use
461 * this time. Unlike the first one where all we had were strings, the size
462 * of the data read only serves to demonstrate that we are reading back the
463 * entire size of our original @p buf variable.
464 *
465 * A little peeking to see how many entries the file has and to make an
466 * example of eet_num_entries() to get that number when we don't care about
467 * their names.
468 * @until printf
469 *
470 * More cheating follows. Just like we knew this was an Eet file, we also know
471 * what key to read from, and ontop of that we know that the data in it is not
472 * compressed.
473 * Knowing all this allows us to take some shortcuts.
474 * @until read_direct
475 *
476 * That's a direct print of our data, whatever that data is. We don't want
477 * to worry about having to free it later, so we just used eet_direct_read()
478 * to tell Eet to gives a pointer to the internal data in the file, without
479 * duplicating it. Since we said that data was not compressed, we shouldn't
480 * worry about printing garbage to the screen (and yes, we also know the data
481 * is yet another string).
482 * We also don't care about the size of the data as it was stored in the file,
483 * so we passed NULL as the size parameter.
484 * One very important note about this, however, is that we don't care about
485 * the size parameter because the data in the file contains the null
486 * terminator for the string. So when using Eet to store strings this way,
487 * it's very important to consider whether you will keep that final null
488 * byte, or to always get the size read and do the necessary checks and copies.
489 * It's up to the user and the particular use cases to decide how this will
490 * be done.
491 *
492 * With everything done, close this second file and free the data used to open
493 * it. And this is important, we can't free that data until we are done with
494 * the file, as Eet is using it. When opening with eet_memopen_read(), the data
495 * passed to it must be available for as long as the the file is open.
496 * @until }
497 *
498 * Finally, we close the first file, shutdown all internal resources used by
499 * Eet and leave our main function, thus terminating our program.
500 * @until return
501 *
502 * You can look at the full code of the example @ref eet-file.c "here".
503 * @{
504 */
505
506/**
507 * @enum _Eet_File_Mode
508 * Modes that a file can be opened.
509 */
510typedef enum _Eet_File_Mode
511{
512 EET_FILE_MODE_INVALID = -1,
513 EET_FILE_MODE_READ, /**< File is read-only. */
514 EET_FILE_MODE_WRITE, /**< File is write-only. */
515 EET_FILE_MODE_READ_WRITE /**< File is for both read and write */
516} Eet_File_Mode; /**< Modes that a file can be opened. */
517
518/**
519 * @typedef Eet_File
520 * Opaque handle that defines an Eet file (or memory).
521 *
522 * This handle will be returned by the functions eet_open() and
523 * eet_memopen_read() and is used by every other function that affects the
524 * file in any way. When you are done with it, call eet_close() to close it
525 * and, if the file was open for writing, write down to disk any changes made
526 * to it.
527 *
528 * @see eet_open()
529 * @see eet_memopen_read()
530 * @see eet_close()
531 */
532typedef struct _Eet_File Eet_File;
533
534/**
535 * @typedef Eet_Dictionary
536 * Opaque handle that defines a file-backed (mmaped) dictionary of strings.
537 */
538typedef struct _Eet_Dictionary Eet_Dictionary;
539
540/**
541 * @}
542 */
543
544/**
545 * Open an eet file on disk, and returns a handle to it.
546 * @param file The file path to the eet file. eg: @c "/tmp/file.eet".
547 * @param mode The mode for opening. Either #EET_FILE_MODE_READ,
548 * #EET_FILE_MODE_WRITE or #EET_FILE_MODE_READ_WRITE.
549 * @return An opened eet file handle.
550 * @ingroup Eet_File_Group
551 *
552 * This function will open an exiting eet file for reading, and build
553 * the directory table in memory and return a handle to the file, if it
554 * exists and can be read, and no memory errors occur on the way, otherwise
555 * NULL will be returned.
556 *
557 * It will also open an eet file for writing. This will, if successful,
558 * delete the original file and replace it with a new empty file, till
559 * the eet file handle is closed or flushed. If it cannot be opened for
560 * writing or a memory error occurs, NULL is returned.
561 *
562 * You can also open the file for read/write. If you then write a key that
563 * does not exist it will be created, if the key exists it will be replaced
564 * by the new data.
565 *
566 * If the same file is opened multiple times, then the same file handle will
567 * be returned as eet maintains an internal list of all currently open
568 * files. Note that it considers files opened for read only and those opened
569 * for read/write and write only as 2 separate sets. Those that do not write
570 * to the file and those that do. Eet will allow 2 handles to the same file
571 * if they are in the 2 separate lists/groups. That means opening a file for
572 * read only looks in the read only set, and returns a handle to that file
573 * handle and increments its reference count. If you open a file for read/write
574 * or write only it looks in the write set and returns a handle after
575 * incrementing the reference count. You need to close an eet file handle
576 * as many times as it has been opened to maintain correct reference counts.
577 * Files whose modified timestamp or size do not match those of the existing
578 * referenced file handles will not be returned and a new handle will be
579 * returned instead.
580 *
581 * @since 1.0.0
582 */
583EAPI Eet_File *
584eet_open(const char *file,
585 Eet_File_Mode mode);
586
587/**
588 * Open an eet file directly from a memory location. The data is not copied,
589 * so you must keep it around as long as the eet file is open. There is
590 * currently no cache for this kind of Eet_File, so it's reopened every time
591 * you use eet_memopen_read.
592 * @param data Address of file in memory.
593 * @param size Size of memory to be read.
594 * @return A handle to the file.
595 *
596 * Files opened this way will always be in read-only mode.
597 *
598 * @since 1.1.0
599 * @ingroup Eet_File_Group
600 */
601EAPI Eet_File *
602eet_memopen_read(const void *data,
603 size_t size);
604
605/**
606 * Get the mode an Eet_File was opened with.
607 * @param ef A valid eet file handle.
608 * @return The mode ef was opened with.
609 *
610 * @since 1.0.0
611 * @ingroup Eet_File_Group
612 */
613EAPI Eet_File_Mode
614eet_mode_get(Eet_File *ef);
615
616/**
617 * Close an eet file handle and flush pending writes.
618 * @param ef A valid eet file handle.
619 * @return An eet error identifier.
620 *
621 * This function will flush any pending writes to disk if the eet file
622 * was opened for write, and free all data associated with the file handle
623 * and file, and close the file. If it was opened for read (or read/write),
624 * the file handle may still be held open internally for caching purposes.
625 * To flush speculatively held eet file handles use eet_clearcache().
626 *
627 * If the eet file handle is not valid nothing will be done.
628 *
629 * @since 1.0.0
630 * @ingroup Eet_File_Group
631 *
632 * @see eet_clearcache()
633 */
634EAPI Eet_Error
635eet_close(Eet_File *ef);
636
637/**
638 * Sync content of an eet file handle, flushing pending writes.
639 * @param ef A valid eet file handle.
640 * @return An eet error identifier.
641 *
642 * This function will flush any pending writes to disk. The eet file must
643 * be opened for write.
644 *
645 * If the eet file handle is not valid nothing will be done.
646 *
647 * @since 1.2.4
648 * @ingroup Eet_File_Group
649 */
650EAPI Eet_Error
651eet_sync(Eet_File *ef);
652
653/**
654 * Return a handle to the shared string dictionary of the Eet file
655 * @param ef A valid eet file handle.
656 * @return A handle to the dictionary of the file
657 *
658 * This function returns a handle to the dictionary of an Eet file whose
659 * handle is @p ef, if a dictionary exists. NULL is returned otherwise or
660 * if the file handle is known to be invalid.
661 *
662 * @see eet_dictionary_string_check() to know if given string came
663 * from the dictionary or it was dynamically allocated using
664 * the #Eet_Data_Descriptor_Class instructions.
665 *
666 * @since 1.0.0
667 * @ingroup Eet_File_Group
668 */
669EAPI Eet_Dictionary *
670eet_dictionary_get(Eet_File *ef);
671
672/**
673 * Check if a given string comes from a given dictionary
674 * @param ed A valid dictionary handle
675 * @param string A valid 0 byte terminated C string
676 * @return 1 if it is in the dictionary, 0 otherwise
677 *
678 * This checks the given dictionary to see if the given string is actually
679 * inside that dictionary (i.e. comes from it) and returns 1 if it does.
680 * If the dictionary handle is invalid, the string is NULL or the string is
681 * not in the dictionary, 0 is returned.
682 *
683 * @since 1.0.0
684 * @ingroup Eet_File_Group
685 */
686EAPI int
687eet_dictionary_string_check(Eet_Dictionary *ed,
688 const char *string);
689
690/**
691 * Return the number of strings inside a dictionary
692 * @param ed A valid dictionary handle
693 * @return the number of strings inside a dictionary
694 *
695 * @since 1.6.0
696 * @ingroup Eet_File_Group
697 */
698EAPI int
699eet_dictionary_count(const Eet_Dictionary *ed);
700
701/**
702 * Read a specified entry from an eet file and return data
703 * @param ef A valid eet file handle opened for reading.
704 * @param name Name of the entry. eg: "/base/file_i_want".
705 * @param size_ret Number of bytes read from entry and returned.
706 * @return The data stored in that entry in the eet file.
707 *
708 * This function finds an entry in the eet file that is stored under the
709 * name specified, and returns that data, decompressed, if successful.
710 * NULL is returned if the lookup fails or if memory errors are
711 * encountered. It is the job of the calling program to call free() on
712 * the returned data. The number of bytes in the returned data chunk are
713 * placed in size_ret.
714 *
715 * If the eet file handle is not valid NULL is returned and size_ret is
716 * filled with 0.
717 *
718 * @see eet_read_cipher()
719 *
720 * @since 1.0.0
721 * @ingroup Eet_File_Group
722 */
723EAPI void *
724eet_read(Eet_File *ef,
725 const char *name,
726 int *size_ret);
727
728/**
729 * Read a specified entry from an eet file and return data
730 * @param ef A valid eet file handle opened for reading.
731 * @param name Name of the entry. eg: "/base/file_i_want".
732 * @param size_ret Number of bytes read from entry and returned.
733 * @return The data stored in that entry in the eet file.
734 *
735 * This function finds an entry in the eet file that is stored under the
736 * name specified, and returns that data if not compressed and successful.
737 * NULL is returned if the lookup fails or if memory errors are
738 * encountered or if the data is compressed. The calling program must never
739 * call free() on the returned data. The number of bytes in the returned
740 * data chunk are placed in size_ret.
741 *
742 * If the eet file handle is not valid NULL is returned and size_ret is
743 * filled with 0.
744 *
745 * @since 1.0.0
746 * @ingroup Eet_File_Group
747 */
748EAPI const void *
749eet_read_direct(Eet_File *ef,
750 const char *name,
751 int *size_ret);
752
753/**
754 * Write a specified entry to an eet file handle
755 * @param ef A valid eet file handle opened for writing.
756 * @param name Name of the entry. eg: "/base/file_i_want".
757 * @param data Pointer to the data to be stored.
758 * @param size Length in bytes in the data to be stored.
759 * @param compress Compression flags (1 == compress, 0 = don't compress).
760 * @return bytes written on successful write, 0 on failure.
761 *
762 * This function will write the specified chunk of data to the eet file
763 * and return greater than 0 on success. 0 will be returned on failure.
764 *
765 * The eet file handle must be a valid file handle for an eet file opened
766 * for writing. If it is not, 0 will be returned and no action will be
767 * performed.
768 *
769 * Name, and data must not be NULL, and size must be > 0. If these
770 * conditions are not met, 0 will be returned.
771 *
772 * The data will be copied (and optionally compressed) in ram, pending
773 * a flush to disk (it will stay in ram till the eet file handle is
774 * closed though).
775 *
776 * @see eet_write_cipher()
777 *
778 * @since 1.0.0
779 * @ingroup Eet_File_Group
780 */
781EAPI int
782eet_write(Eet_File *ef,
783 const char *name,
784 const void *data,
785 int size,
786 int compress);
787
788/**
789 * Delete a specified entry from an Eet file being written or re-written
790 * @param ef A valid eet file handle opened for writing.
791 * @param name Name of the entry. eg: "/base/file_i_want".
792 * @return Success or failure of the delete.
793 *
794 * This function will delete the specified chunk of data from the eet file
795 * and return greater than 0 on success. 0 will be returned on failure.
796 *
797 * The eet file handle must be a valid file handle for an eet file opened
798 * for writing. If it is not, 0 will be returned and no action will be
799 * performed.
800 *
801 * Name, must not be NULL, otherwise 0 will be returned.
802 *
803 * @since 1.0.0
804 * @ingroup Eet_File_Group
805 */
806EAPI int
807eet_delete(Eet_File *ef,
808 const char *name);
809
810/**
811 * Alias a specific section to another one. Destination may exist or not,
812 * no checks are done.
813 * @param ef A valid eet file handle opened for writing.
814 * @param name Name of the new entry. eg: "/base/file_i_want".
815 * @param destination Actual source of the aliased entry eg: "/base/the_real_stuff_i_want".
816 * @param compress Compression flags (1 == compress, 0 = don't compress).
817 * @return EINA_TRUE on success, EINA_FALSE on failure.
818 *
819 * Name and Destination must not be NULL, otherwise EINA_FALSE will be returned.
820 * The equivalent of this would be calling 'ln -s destination name'
821 *
822 * @since 1.3.3
823 * @ingroup Eet_File_Group
824 */
825EAPI Eina_Bool
826eet_alias(Eet_File *ef,
827 const char *name,
828 const char *destination,
829 int compress);
830
831/**
832 * Retrieve the filename of an Eet_File
833 * @param ef A valid eet file handle opened for writing.
834 * @return The stringshared file string opened with eet_open(), or NULL on error
835 *
836 * @note This function will return NULL for files opened with eet_memopen_read()
837 *
838 * @since 1.6
839 * @ingroup Eet_File_Group
840 */
841EAPI const char *
842eet_file_get(Eet_File *ef);
843
844/**
845 * Retrieve the destination name of an alias
846 * @param ef A valid eet file handle opened for writing
847 * @param name Name of the entry. eg: "/base/file_i_want"
848 * @return Destination of the alias. eg: "/base/the_real_stuff_i_want", NULL on failure
849 *
850 * Name must not be NULL, otherwise NULL will be returned.
851 *
852 * @since 1.5
853 * @ingroup Eet_File_Group
854 */
855EAPI const char *
856eet_alias_get(Eet_File *ef,
857 const char *name);
858
859/**
860 * List all entries in eet file matching shell glob.
861 * @param ef A valid eet file handle.
862 * @param glob A shell glob to match against.
863 * @param count_ret Number of entries found to match.
864 * @return Pointer to an array of strings.
865 *
866 * This function will list all entries in the eet file matching the
867 * supplied shell glob and return an allocated list of their names, if
868 * there are any, and if no memory errors occur.
869 *
870 * The eet file handle must be valid and glob must not be NULL, or NULL
871 * will be returned and count_ret will be filled with 0.
872 *
873 * The calling program must call free() on the array returned, but NOT
874 * on the string pointers in the array. They are taken as read-only
875