summaryrefslogtreecommitdiff
path: root/legacy/eet/src/examples
diff options
context:
space:
mode:
authorVincent Torri <vincent.torri@gmail.com>2010-03-18 21:09:13 +0000
committerVincent Torri <vincent.torri@gmail.com>2010-03-18 21:09:13 +0000
commitbb2462c3ab681ed79f1d4e93a0d957bc17c7b27f (patch)
tree9691deb5e7c4f745ef1969de8d58ef2e49f0bc21 /legacy/eet/src/examples
parentea4e8a0abbadc47ac9ba2dd2d97f8fe83f991759 (diff)
Add eet examples documentation and update html doc menu to add 'Examples' tab.
Gustavo: documentation of examples should be added in examples.dox. There is one page for each example in that file. SVN revision: 47328
Diffstat (limited to 'legacy/eet/src/examples')
-rw-r--r--legacy/eet/src/examples/Makefile.am32
-rw-r--r--legacy/eet/src/examples/eet-data-file_descriptor.c490
-rw-r--r--legacy/eet/src/examples/eet-data-nested.c264
-rw-r--r--legacy/eet/src/examples/eet-data-simple.c217
4 files changed, 1003 insertions, 0 deletions
diff --git a/legacy/eet/src/examples/Makefile.am b/legacy/eet/src/examples/Makefile.am
new file mode 100644
index 0000000000..c760295898
--- /dev/null
+++ b/legacy/eet/src/examples/Makefile.am
@@ -0,0 +1,32 @@
1MAINTAINERCLEANFILES = Makefile.in
2
3pkglibdir = $(datadir)/$(PACKAGE)/examples
4
5AM_CPPFLAGS = \
6-I. \
7-I$(top_srcdir)/src/lib \
8@EINA_CFLAGS@
9
10pkglib_PROGRAMS = eet_data_simple eet_data_nested eet_data_file_descriptor
11
12eet_data_simple_SOURCES = eet-data-simple.c
13eet_data_simple_LDADD = $(top_builddir)/src/lib/libeet.la @EINA_LIBS@
14
15eet_data_nested_SOURCES = eet-data-nested.c
16eet_data_nested_LDADD = $(top_builddir)/src/lib/libeet.la @EINA_LIBS@
17
18eet_data_file_descriptor_SOURCES = eet-data-file_descriptor.c
19eet_data_file_descriptor_LDADD = $(top_builddir)/src/lib/libeet.la @EINA_LIBS@
20
21
22filesdir = $(datadir)/$(PACKAGE)/examples
23files_DATA =
24
25if INSTALL_EXAMPLES
26
27files_DATA += \
28eet-data-simple.c \
29eet-data-nested.c \
30eet-data-file_descriptor.c
31
32endif
diff --git a/legacy/eet/src/examples/eet-data-file_descriptor.c b/legacy/eet/src/examples/eet-data-file_descriptor.c
new file mode 100644
index 0000000000..c97b3984e5
--- /dev/null
+++ b/legacy/eet/src/examples/eet-data-file_descriptor.c
@@ -0,0 +1,490 @@
1#include <Eina.h>
2#include <Eet.h>
3#include <stdio.h>
4#include <limits.h>
5#include <sys/types.h>
6#include <sys/stat.h>
7#include <unistd.h>
8
9// complex real-world structures based on elmdentica database
10typedef struct {
11 const char *screen_name;
12 const char *name;
13 const char *message;
14 unsigned int id;
15 unsigned int status_id;
16 unsigned int date;
17 unsigned int timeline;
18} My_Message;
19
20typedef struct {
21 const char *dm_to;
22 const char *message;
23} My_Post;
24
25typedef struct {
26 unsigned int id;
27 const char *name;
28 Eina_List *messages;
29 Eina_List *posts;
30} My_Account;
31
32typedef struct {
33 unsigned int version; // it is recommended to use versioned configuration!
34 Eina_List *accounts;
35} My_Cache;
36
37// string that represents the entry in eet file, you might like to have
38// different profiles or so in the same file, this is possible with
39// different strings
40static const char MY_CACHE_FILE_ENTRY[] = "cache";
41
42// keep the descriptor static global, so it can be
43// shared by different functions (load/save) of this and only this
44// file.
45static Eet_Data_Descriptor *_my_cache_descriptor;
46static Eet_Data_Descriptor *_my_account_descriptor;
47static Eet_Data_Descriptor *_my_message_descriptor;
48static Eet_Data_Descriptor *_my_post_descriptor;
49
50// keep file handle alive, so mmap()ed strings are all alive as well
51static Eet_File *_my_cache_file = NULL;
52static Eet_Dictionary *_my_cache_dict = NULL;
53
54static void
55_my_cache_descriptor_init(void)
56{
57 Eet_Data_Descriptor_Class eddc;
58
59 // The FILE variant is good for caches and things that are just
60 // appended, but needs to take care when changing strings and files must
61 // be kept open so mmap()ed strings will be kept alive.
62 EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, My_Cache);
63 _my_cache_descriptor = eet_data_descriptor_file_new(&eddc);
64
65 EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, My_Account);
66 _my_account_descriptor = eet_data_descriptor_file_new(&eddc);
67
68 EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, My_Message);
69 _my_message_descriptor = eet_data_descriptor_file_new(&eddc);
70
71 EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, My_Post);
72 _my_post_descriptor = eet_data_descriptor_file_new(&eddc);
73
74 // Describe the members to be saved:
75 // Use a temporary macro so we don't type a lot, also avoid errors:
76
77#define ADD_BASIC(member, eet_type) \
78 EET_DATA_DESCRIPTOR_ADD_BASIC \
79 (_my_message_descriptor, My_Message, #member, member, eet_type)
80 ADD_BASIC(screen_name, EET_T_STRING);
81 ADD_BASIC(name, EET_T_STRING);
82 ADD_BASIC(message, EET_T_STRING);
83 ADD_BASIC(id, EET_T_UINT);
84 ADD_BASIC(status_id, EET_T_UINT);
85 ADD_BASIC(date, EET_T_UINT);
86 ADD_BASIC(timeline, EET_T_UINT);
87#undef ADD_BASIC
88
89#define ADD_BASIC(member, eet_type) \
90 EET_DATA_DESCRIPTOR_ADD_BASIC \
91 (_my_post_descriptor, My_Post, #member, member, eet_type)
92 ADD_BASIC(dm_to, EET_T_STRING);
93 ADD_BASIC(message, EET_T_STRING);
94#undef ADD_BASIC
95
96#define ADD_BASIC(member, eet_type) \
97 EET_DATA_DESCRIPTOR_ADD_BASIC \
98 (_my_account_descriptor, My_Account, #member, member, eet_type)
99 ADD_BASIC(name, EET_T_STRING);
100 ADD_BASIC(id, EET_T_UINT);
101#undef ADD_BASIC
102
103 EET_DATA_DESCRIPTOR_ADD_LIST
104 (_my_account_descriptor, My_Account, "messages", messages,
105 _my_message_descriptor);
106 EET_DATA_DESCRIPTOR_ADD_LIST
107 (_my_account_descriptor, My_Account, "posts", posts,
108 _my_post_descriptor);
109
110#define ADD_BASIC(member, eet_type) \
111 EET_DATA_DESCRIPTOR_ADD_BASIC \
112 (_my_cache_descriptor, My_Cache, #member, member, eet_type)
113 ADD_BASIC(version, EET_T_UINT);
114#undef ADD_BASIC
115
116 EET_DATA_DESCRIPTOR_ADD_LIST
117 (_my_cache_descriptor, My_Cache, "accounts", accounts,
118 _my_account_descriptor);
119}
120
121static void
122_my_cache_descriptor_shutdown(void)
123{
124 eet_data_descriptor_free(_my_cache_descriptor);
125 eet_data_descriptor_free(_my_account_descriptor);
126 eet_data_descriptor_free(_my_message_descriptor);
127 eet_data_descriptor_free(_my_post_descriptor);
128}
129
130// need to check if the pointer came from mmaped area in eet_dictionary
131// or it was allocated with eina_stringshare_add()
132static void
133_eet_string_free(const char *str)
134{
135 if (!str)
136 return;
137 if ((_my_cache_dict) && (eet_dictionary_string_check(_my_cache_dict, str)))
138 return;
139 eina_stringshare_del(str);
140}
141
142static My_Message *
143_my_message_new(const char *message)
144{
145 My_Message *msg = calloc(1, sizeof(My_Message));
146 if (!msg)
147 {
148 fprintf(stderr, "ERROR: could not calloc My_Message\n");
149 return NULL;
150 }
151 msg->message = eina_stringshare_add(message);
152 return msg;
153}
154
155static void
156_my_message_free(My_Message *msg)
157{
158 _eet_string_free(msg->screen_name);
159 _eet_string_free(msg->name);
160 _eet_string_free(msg->message);
161 free(msg);
162}
163
164static My_Post *
165_my_post_new(const char *message)
166{
167 My_Post *post = calloc(1, sizeof(My_Post));
168 if (!post)
169 {
170 fprintf(stderr, "ERROR: could not calloc My_Post\n");
171 return NULL;
172 }
173 post->message = eina_stringshare_add(message);
174 return post;
175}
176
177static void
178_my_post_free(My_Post *post)
179{
180 _eet_string_free(post->dm_to);
181 _eet_string_free(post->message);
182 free(post);
183}
184
185static My_Account *
186_my_account_new(const char *name)
187{
188 My_Account *acc = calloc(1, sizeof(My_Account));
189 if (!acc)
190 {
191 fprintf(stderr, "ERROR: could not calloc My_Account\n");
192 return NULL;
193 }
194 acc->name = eina_stringshare_add(name);
195 return acc;
196}
197
198static void
199_my_account_free(My_Account *acc)
200{
201 My_Message *m;
202 My_Post *p;
203
204 _eet_string_free(acc->name);
205
206 EINA_LIST_FREE(acc->messages, m)
207 _my_message_free(m);
208
209 EINA_LIST_FREE(acc->posts, p)
210 _my_post_free(p);
211
212 free(acc);
213}
214
215static My_Cache *
216_my_cache_new(void)
217{
218 My_Cache *my_cache = calloc(1, sizeof(My_Cache));
219 if (!my_cache)
220 {
221 fprintf(stderr, "ERROR: could not calloc My_Cache\n");
222 return NULL;
223 }
224
225 my_cache->version = 1;
226 return my_cache;
227}
228
229static void
230_my_cache_free(My_Cache *my_cache)
231{
232 My_Account *acc;
233 EINA_LIST_FREE(my_cache->accounts, acc)
234 _my_account_free(acc);
235 free(my_cache);
236}
237
238static My_Account *
239_my_cache_account_find(My_Cache *my_cache, const char *name)
240{
241 My_Account *acc;
242 Eina_List *l;
243 EINA_LIST_FOREACH(my_cache->accounts, l, acc)
244 if (strcmp(acc->name, name) == 0)
245 return acc;
246 return NULL;
247}
248
249static My_Cache *
250_my_cache_load(const char *filename)
251{
252 My_Cache *my_cache;
253 Eet_File *ef = eet_open(filename, EET_FILE_MODE_READ);
254 if (!ef)
255 {
256 fprintf(stderr, "ERROR: could not open '%s' for read\n", filename);
257 return NULL;
258 }
259
260 my_cache = eet_data_read(ef, _my_cache_descriptor, MY_CACHE_FILE_ENTRY);
261 if (!my_cache)
262 {
263 eet_close(ef);
264 return NULL;
265 }
266
267 if (my_cache->version < 1)
268 {
269 fprintf(stderr,
270 "WARNING: version %#x was too old, upgrading it to %#x\n",
271 my_cache->version, 1);
272
273 my_cache->version = 1;
274 }
275
276 if (_my_cache_file)
277 eet_close(_my_cache_file);
278 _my_cache_file = ef;
279 _my_cache_dict = eet_dictionary_get(ef);
280
281 return my_cache;
282}
283
284static Eina_Bool
285_my_cache_save(const My_Cache *my_cache, const char *filename)
286{
287 char tmp[PATH_MAX];
288 Eet_File *ef;
289 Eina_Bool ret;
290 unsigned int i, len;
291 struct stat st;
292
293 len = eina_strlcpy(tmp, filename, sizeof(tmp));
294 if (len + 12 >= (int)sizeof(tmp))
295 {
296 fprintf(stderr, "ERROR: file name is too big: %s\n", filename);
297 return EINA_FALSE;
298 }
299
300 i = 0;
301 do
302 {
303 snprintf(tmp + len, 12, ".%u", i);
304 i++;
305 }
306 while (stat(tmp, &st) == 0);
307
308 ef = eet_open(tmp, EET_FILE_MODE_WRITE);
309 if (!ef)
310 {
311 fprintf(stderr, "ERROR: could not open '%s' for write\n", tmp);
312 return EINA_FALSE;
313 }
314
315 ret = eet_data_write
316 (ef, _my_cache_descriptor, MY_CACHE_FILE_ENTRY, my_cache, EINA_TRUE);
317
318 // VERY IMPORTANT NOTE:
319 // after eet_close(), all strings mmaped from file will be GONE, invalid!
320 // you'll need to free the old cache and open the new one.
321 // For cache this is okay, as you should be saving not so often or just
322 // at end.
323 //
324 // This is a trade off, you save memory by using mmap()ed strings, but
325 // you have to care about this.
326 eet_close(ef);
327
328 if (ret)
329 {
330 unlink(filename);
331 rename(tmp, filename);
332 }
333
334 return ret;
335}
336
337int main(int argc, char *argv[])
338{
339 My_Cache *my_cache;
340 const Eina_List *l_acc;
341 My_Account *acc;
342 int ret = 0;
343
344 if (argc < 3)
345 {
346 fprintf(stderr,
347 "Usage:\n\t%s <input> <output> [action] [action-params]\n\n"
348 "Where actions and their parameters:\n"
349 "\tacc <name>\n"
350 "\tpost <account-name> <message>\n"
351 "\tmessage <account-name> <message>\n"
352 "\n",
353 argv[0]);
354 return -1;
355 }
356
357 eina_init();
358 eet_init();
359 _my_cache_descriptor_init();
360
361 my_cache = _my_cache_load(argv[1]);
362 if (!my_cache)
363 {
364 printf("creating new cache.\n");
365 my_cache = _my_cache_new();
366 if (!my_cache)
367 {
368 ret = -2;
369 goto end;
370 }
371 }
372
373 if (argc > 3)
374 {
375 if (strcmp(argv[3], "acc") == 0)
376 {
377 if (argc == 5)
378 {
379 My_Account *acc = _my_cache_account_find(my_cache, argv[4]);
380 if (!acc)
381 {
382 acc = _my_account_new(argv[4]);
383 my_cache->accounts = eina_list_append
384 (my_cache->accounts, acc);
385 }
386 else
387 fprintf(stderr, "ERROR: account '%s' already exists.\n",
388 argv[4]);
389 }
390 else
391 fprintf(stderr, "ERROR: wrong number of parameters (%d).\n",
392 argc);
393 }
394 else if (strcmp(argv[3], "post") == 0)
395 {
396 if (argc == 6)
397 {
398 My_Account *acc = _my_cache_account_find(my_cache, argv[4]);
399 if (acc)
400 {
401 My_Post *post = _my_post_new(argv[5]);
402 acc->posts = eina_list_append(acc->posts, post);
403 }
404 else
405 fprintf(stderr, "ERROR: unknown account: '%s'\n", argv[4]);
406 }
407 else
408 fprintf(stderr, "ERROR: wrong number of parameters (%d).\n",
409 argc);
410 }
411 else if (strcmp(argv[3], "message") == 0)
412 {
413 if (argc == 6)
414 {
415 My_Account *acc = _my_cache_account_find(my_cache, argv[4]);
416 if (acc)
417 {
418 My_Message *msg = _my_message_new(argv[5]);
419 acc->messages = eina_list_append(acc->messages, msg);
420 }
421 else
422 fprintf(stderr, "ERROR: unknown account: '%s'\n", argv[4]);
423 }
424 else
425 fprintf(stderr, "ERROR: wrong number of parameters (%d).\n",
426 argc);
427 }
428 else
429 fprintf(stderr, "ERROR: unknown action '%s'\n", argv[2]);
430 }
431
432 printf("My_Cache:\n"
433 "\tversion.: %#x\n"
434 "\taccounts: %u\n",
435 my_cache->version,
436 eina_list_count(my_cache->accounts));
437 EINA_LIST_FOREACH(my_cache->accounts, l_acc, acc)
438 {
439 const My_Post *post;
440
441 printf("\t > %-#8x '%.20s' stats: m=%u, p=%u\n",
442 acc->id, acc->name ? acc->name : "",
443 eina_list_count(acc->messages),
444 eina_list_count(acc->posts));
445
446 if (eina_list_count(acc->messages))
447 {
448 const Eina_List *l;
449 const My_Message *msg;
450 printf("\t |messages:\n");
451
452 EINA_LIST_FOREACH(acc->messages, l, msg)
453 {
454 printf("\t | %-8x '%s' [%s]: '%.20s'\n",
455 msg->id,
456 msg->name ? msg->name : "",
457 msg->screen_name ? msg->screen_name : "",
458 msg->message ? msg->message : "");
459 }
460 }
461
462 if (eina_list_count(acc->posts))
463 {
464 const Eina_List *l;
465 const My_Post *post;
466 printf("\t |posts:\n");
467
468 EINA_LIST_FOREACH(acc->posts, l, post)
469 {
470 if (post->dm_to)
471 printf("\t | @%s: '%.20s'\n", post->dm_to, post->message);
472 else
473 printf("\t | '%.20s'\n", post->message);
474 }
475 }
476 printf("\n");
477 }
478
479 if (!_my_cache_save(my_cache, argv[2]))
480 ret = -3;
481
482 _my_cache_free(my_cache);
483
484 end:
485 _my_cache_descriptor_shutdown();
486 eet_shutdown();
487 eina_shutdown();
488
489 return ret;
490}
diff --git a/legacy/eet/src/examples/eet-data-nested.c b/legacy/eet/src/examples/eet-data-nested.c
new file mode 100644
index 0000000000..52a095d3c1
--- /dev/null
+++ b/legacy/eet/src/examples/eet-data-nested.c
@@ -0,0 +1,264 @@
1#include <Eina.h>
2#include <Eet.h>
3#include <stdio.h>
4#include <limits.h>
5#include <sys/types.h>
6#include <sys/stat.h>
7#include <unistd.h>
8
9// The struct that will be loaded and saved.
10// note that only the members described in the eet_data_descriptor
11// will be automatically handled. The other members will have their
12// space reserved and zeroed (as it uses calloc()), but not
13// saved or loaded from eet files.
14typedef struct {
15 unsigned int version; // it is recommended to use versioned configuration!
16 const char *name;
17 int id;
18 int not_saved_value; // example of not saved data inside!
19 Eina_Bool enabled;
20 Eina_List *subs;
21} My_Conf_Type;
22
23typedef struct {
24 const char *server;
25 int port;
26} My_Conf_Subtype;
27
28// string that represents the entry in eet file, you might like to have
29// different profiles or so in the same file, this is possible with
30// different strings
31static const char MY_CONF_FILE_ENTRY[] = "config";
32
33
34// keep the descriptor static global, so it can be
35// shared by different functions (load/save) of this and only this
36// file.
37static Eet_Data_Descriptor *_my_conf_descriptor;
38static Eet_Data_Descriptor *_my_conf_sub_descriptor;
39
40static void
41_my_conf_descriptor_init(void)
42{
43 Eet_Data_Descriptor_Class eddc;
44
45 // The class describe the functions to use to create the type and its
46 // full allocated size.
47 //
48 // Eina types are very convenient, so use them to create the descriptor,
49 // so we get eina_list, eina_hash and eina_stringshare automatically!
50 //
51 // The STREAM variant is better for configuration files as the values
52 // will likely change a lot.
53 //
54 // The other variant, FILE, is good for caches and things that are just
55 // appended, but needs to take care when changing strings and files must
56 // be kept open so mmap()ed strings will be kept alive.
57 EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, My_Conf_Type);
58 _my_conf_descriptor = eet_data_descriptor_stream_new(&eddc);
59
60 EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, My_Conf_Subtype);
61 _my_conf_sub_descriptor = eet_data_descriptor_stream_new(&eddc);
62
63 // Describe the members to be saved:
64 // Use a temporary macro so we don't type a lot, also avoid errors:
65#define MY_CONF_ADD_BASIC(member, eet_type) \
66 EET_DATA_DESCRIPTOR_ADD_BASIC \
67 (_my_conf_descriptor, My_Conf_Type, #member, member, eet_type)
68#define MY_CONF_SUB_ADD_BASIC(member, eet_type) \
69 EET_DATA_DESCRIPTOR_ADD_BASIC \
70 (_my_conf_sub_descriptor, My_Conf_Subtype, #member, member, eet_type)
71
72 MY_CONF_SUB_ADD_BASIC(server, EET_T_STRING);
73 MY_CONF_SUB_ADD_BASIC(port, EET_T_INT);
74
75 MY_CONF_ADD_BASIC(version, EET_T_UINT);
76 MY_CONF_ADD_BASIC(name, EET_T_STRING);
77 MY_CONF_ADD_BASIC(id, EET_T_INT);
78 MY_CONF_ADD_BASIC(enabled, EET_T_UCHAR);
79
80 // And add the sub descriptor as a linked list at 'subs' in the main struct
81 EET_DATA_DESCRIPTOR_ADD_LIST
82 (_my_conf_descriptor, My_Conf_Type, "subs", subs, _my_conf_sub_descriptor);
83
84#undef MY_CONF_ADD_BASIC
85#undef MY_CONF_SUB_ADD_BASIC
86}
87
88static void
89_my_conf_descriptor_shutdown(void)
90{
91 eet_data_descriptor_free(_my_conf_sub_descriptor);
92 eet_data_descriptor_free(_my_conf_descriptor);
93}
94
95static My_Conf_Type *
96_my_conf_new(void)
97{
98 My_Conf_Type *my_conf = calloc(1, sizeof(My_Conf_Type));
99 My_Conf_Subtype *sub;
100 if (!my_conf)
101 {
102 fprintf(stderr, "ERROR: could not calloc My_Conf_Type\n");
103 return NULL;
104 }
105
106 my_conf->version = 0x112233;
107 my_conf->enabled = EINA_TRUE;
108
109 sub = calloc(1, sizeof(My_Conf_Subtype));
110 if (sub)
111 {
112 sub->server = eina_stringshare_add("my-server.com");
113 sub->port = 1234;
114 my_conf->subs = eina_list_append(my_conf->subs, sub);
115 }
116
117 return my_conf;
118}
119
120static void
121_my_conf_free(My_Conf_Type *my_conf)
122{
123 My_Conf_Subtype *sub;
124 EINA_LIST_FREE(my_conf->subs, sub)
125 {
126 eina_stringshare_del(sub->server);
127 free(sub);
128 }
129
130 eina_stringshare_del(my_conf->name);
131 free(my_conf);
132}
133
134static My_Conf_Type *
135_my_conf_load(const char *filename)
136{
137 My_Conf_Type *my_conf;
138 Eet_File *ef = eet_open(filename, EET_FILE_MODE_READ);
139 if (!ef)
140 {
141 fprintf(stderr, "ERROR: could not open '%s' for read\n", filename);
142 return NULL;
143 }
144
145 my_conf = eet_data_read(ef, _my_conf_descriptor, MY_CONF_FILE_ENTRY);
146 if (!my_conf)
147 goto end;
148
149 if (my_conf->version < 0x112233)
150 {
151 fprintf(stderr,
152 "WARNING: version %#x was too old, upgrading it to %#x\n",
153 my_conf->version, 0x112233);
154
155 my_conf->version = 0x112233;
156 my_conf->enabled = EINA_TRUE;
157 }
158
159 end:
160 eet_close(ef);
161 return my_conf;
162}
163
164static Eina_Bool
165_my_conf_save(const My_Conf_Type *my_conf, const char *filename)
166{
167 char tmp[PATH_MAX];
168 Eet_File *ef;
169 Eina_Bool ret;
170 unsigned int i, len;
171 struct stat st;
172
173 len = eina_strlcpy(tmp, filename, sizeof(tmp));
174 if (len + 12 >= (int)sizeof(tmp))
175 {
176 fprintf(stderr, "ERROR: file name is too big: %s\n", filename);
177 return EINA_FALSE;
178 }
179
180 i = 0;
181 do
182 {
183 snprintf(tmp + len, 12, ".%u", i);
184 i++;
185 }
186 while (stat(tmp, &st) == 0);
187
188 ef = eet_open(tmp, EET_FILE_MODE_WRITE);
189 if (!ef)
190 {
191 fprintf(stderr, "ERROR: could not open '%s' for write\n", tmp);
192 return EINA_FALSE;
193 }
194
195 ret = eet_data_write
196 (ef, _my_conf_descriptor, MY_CONF_FILE_ENTRY, my_conf, EINA_TRUE);
197 eet_close(ef);
198
199 if (ret)
200 {
201 unlink(filename);
202 rename(tmp, filename);
203 }
204
205 return ret;
206}
207
208int main(int argc, char *argv[])
209{
210 My_Conf_Type *my_conf;
211 const My_Conf_Subtype *sub;
212 const Eina_List *l;
213 int ret = 0;
214
215 if (argc != 3)
216 {
217 fprintf(stderr, "Usage:\n\t%s <input> <output>\n\n", argv[0]);
218 return -1;
219 }
220
221 eina_init();
222 eet_init();
223 _my_conf_descriptor_init();
224
225 my_conf = _my_conf_load(argv[1]);
226 if (!my_conf)
227 {
228 printf("creating new configuration.\n");
229 my_conf = _my_conf_new();
230 if (!my_conf)
231 {
232 ret = -2;
233 goto end;
234 }
235 }
236
237 printf("My_Conf_Type:\n"
238 "\tversion: %#x\n"
239 "\tname...: '%s'\n"
240 "\tid.....: %d\n"
241 "\tenabled: %hhu\n"
242 "\tsubs...:\n",
243 my_conf->version,
244 my_conf->name ? my_conf->name : "",
245 my_conf->id,
246 my_conf->enabled);
247
248 EINA_LIST_FOREACH(my_conf->subs, l, sub)
249 printf("\t\tserver: '%s', port: %d\n",
250 sub->server ? sub->server : "",
251 sub->port);
252
253 if (!_my_conf_save(my_conf, argv[2]))
254 ret = -3;
255
256 _my_conf_free(my_conf);
257
258 end:
259 _my_conf_descriptor_shutdown();
260 eet_shutdown();
261 eina_shutdown();
262
263 return ret;
264}
diff --git a/legacy/eet/src/examples/eet-data-simple.c b/legacy/eet/src/examples/eet-data-simple.c
new file mode 100644
index 0000000000..72d00c96d9
--- /dev/null
+++ b/legacy/eet/src/examples/eet-data-simple.c
@@ -0,0 +1,217 @@
1#include <Eina.h>
2#include <Eet.h>
3#include <stdio.h>
4#include <limits.h>
5#include <sys/types.h>
6#include <sys/stat.h>
7#include <unistd.h>
8
9// The struct that will be loaded and saved.
10// note that only the members described in the eet_data_descriptor
11// will be automatically handled. The other members will have their
12// space reserved and zeroed (as it uses calloc()), but not
13// saved or loaded from eet files.
14typedef struct {
15 unsigned int version; // it is recommended to use versioned configuration!
16 const char *name;
17 int id;
18 int not_saved_value; // example of not saved data inside!
19 Eina_Bool enabled;
20} My_Conf_Type;
21
22// string that represents the entry in eet file, you might like to have
23// different profiles or so in the same file, this is possible with
24// different strings
25static const char MY_CONF_FILE_ENTRY[] = "config";
26
27
28// keep the descriptor static global, so it can be
29// shared by different functions (load/save) of this and only this
30// file.
31static Eet_Data_Descriptor *_my_conf_descriptor;
32
33static void
34_my_conf_descriptor_init(void)
35{
36 Eet_Data_Descriptor_Class eddc;
37
38 // The class describe the functions to use to create the type and its
39 // full allocated size.
40 //
41 // Eina types are very convenient, so use them to create the descriptor,
42 // so we get eina_list, eina_hash and eina_stringshare automatically!
43 //
44 // The STREAM variant is better for configuration files as the values
45 // will likely change a lot.
46 //
47 // The other variant, FILE, is good for caches and things that are just
48 // appended, but needs to take care when changing strings and files must
49 // be kept open so mmap()ed strings will be kept alive.
50 EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, My_Conf_Type);
51 _my_conf_descriptor = eet_data_descriptor_stream_new(&eddc);
52
53 // Describe the members to be saved:
54 // Use a temporary macro so we don't type a lot, also avoid errors:
55#define MY_CONF_ADD_BASIC(member, eet_type) \
56 EET_DATA_DESCRIPTOR_ADD_BASIC \
57 (_my_conf_descriptor, My_Conf_Type, #member, member, eet_type)
58
59 MY_CONF_ADD_BASIC(version, EET_T_UINT);
60 MY_CONF_ADD_BASIC(name, EET_T_STRING);
61 MY_CONF_ADD_BASIC(id, EET_T_INT);
62 MY_CONF_ADD_BASIC(enabled, EET_T_UCHAR);
63
64#undef MY_CONF_ADD_BASIC
65}
66
67static void
68_my_conf_descriptor_shutdown(void)
69{
70 eet_data_descriptor_free(_my_conf_descriptor);
71}
72
73static My_Conf_Type *
74_my_conf_new(void)
75{
76 My_Conf_Type *my_conf = calloc(1, sizeof(My_Conf_Type));
77 if (!my_conf)
78 {
79 fprintf(stderr, "ERROR: could not calloc My_Conf_Type\n");
80 return NULL;
81 }
82
83 my_conf->version = 0x112233;
84 my_conf->enabled = EINA_TRUE;
85 return my_conf;
86}
87
88static void
89_my_conf_free(My_Conf_Type *my_conf)
90{
91 eina_stringshare_del(my_conf->name);
92 free(my_conf);
93}
94
95static My_Conf_Type *
96_my_conf_load(const char *filename)
97{
98 My_Conf_Type *my_conf;
99 Eet_File *ef = eet_open(filename, EET_FILE_MODE_READ);
100 if (!ef)
101 {
102 fprintf(stderr, "ERROR: could not open '%s' for read\n", filename);
103 return NULL;
104 }
105
106 my_conf = eet_data_read(ef, _my_conf_descriptor, MY_CONF_FILE_ENTRY);
107 if (!my_conf)
108 goto end;
109
110 if (my_conf->version < 0x112233)
111 {
112 fprintf(stderr,
113 "WARNING: version %#x was too old, upgrading it to %#x\n",
114 my_conf->version, 0x112233);
115
116 my_conf->version = 0x112233;
117 my_conf->enabled = EINA_TRUE;
118 }
119
120 end:
121 eet_close(ef);
122 return my_conf;
123}
124
125static Eina_Bool
126_my_conf_save(const My_Conf_Type *my_conf, const char *filename)
127{
128 char tmp[PATH_MAX];
129 Eet_File *ef;
130 Eina_Bool ret;
131 unsigned int i, len;
132 struct stat st;
133
134 len = eina_strlcpy(tmp, filename, sizeof(tmp));
135 if (len + 12 >= (int)sizeof(tmp))
136 {
137 fprintf(stderr, "ERROR: file name is too big: %s\n", filename);
138 return EINA_FALSE;
139 }
140
141 i = 0;
142 do
143 {
144 snprintf(tmp + len, 12, ".%u", i);
145 i++;
146 }
147 while (stat(tmp, &st) == 0);
148
149 ef = eet_open(tmp, EET_FILE_MODE_WRITE);
150 if (!ef)
151 {
152 fprintf(stderr, "ERROR: could not open '%s' for write\n", tmp);
153 return EINA_FALSE;
154 }
155
156 ret = eet_data_write
157 (ef, _my_conf_descriptor, MY_CONF_FILE_ENTRY, my_conf, EINA_TRUE);
158 eet_close(ef);
159
160 if (ret)
161 {
162 unlink(filename);
163 rename(tmp, filename);
164 }
165
166 return ret;
167}
168
169int main(int argc, char *argv[])
170{
171 My_Conf_Type *my_conf;
172 int ret = 0;
173
174 if (argc != 3)
175 {
176 fprintf(stderr, "Usage:\n\t%s <input> <output>\n\n", argv[0]);
177 return -1;
178 }
179
180 eina_init();
181 eet_init();
182 _my_conf_descriptor_init();
183
184 my_conf = _my_conf_load(argv[1]);
185 if (!my_conf)
186 {
187 printf("creating new configuration.\n");
188 my_conf = _my_conf_new();
189 if (!my_conf)
190 {
191 ret = -2;
192 goto end;
193 }
194 }
195
196 printf("My_Conf_Type:\n"
197 "\tversion: %#x\n"
198 "\tname...: '%s'\n"
199 "\tid.....: %d\n"
200 "\tenabled: %hhu\n",
201 my_conf->version,
202 my_conf->name ? my_conf->name : "",
203 my_conf->id,
204 my_conf->enabled);
205
206 if (!_my_conf_save(my_conf, argv[2]))
207 ret = -3;
208
209 _my_conf_free(my_conf);
210
211 end:
212 _my_conf_descriptor_shutdown();
213 eet_shutdown();
214 eina_shutdown();
215
216 return ret;
217}