File descriptor data example, with Eet unions and variants

- Main Page
- Related Pages
- Topics
- Data Structures
- Files
- Examples

File descriptor data example, with Eet unions and variants

This is an example much like the one shown in Advanced use of Eet Data Descriptors. The difference is that here we're attaining ourselves to two new data types to store in an Eet file – unions and variants. We don't try to come with data mapping to real world use cases, here. Instead, we're defining 3 different simple structures to be used throughout the example:

typedef struct _Example_Struct1 Example_Struct1;
typedef struct _Example_Struct2 Example_Struct2;
typedef struct _Example_Struct3 Example_Struct3;
struct _Example_Struct1
{
double val1;
int stuff;
const char *s1;
};
struct _Example_Struct2
{
Eina_Bool b1;
unsigned long long v1;
};
struct _Example_Struct3
{
int body;
Eina_Bool
unsigned char Eina_Bool
Type to mimic a boolean.
Definition eina_types.h:527
};

To identify, for both union and variant data cases, the type of each chunk of data, we're defining types to point to each of those structs:

typedef enum _Example_Data_Type Example_Data_Type;
enum _Example_Data_Type
{
EET_UNKNOWN = 0,
EET_STRUCT1,
EET_STRUCT2,
EET_STRUCT3,
EET_BASIC_FLOAT,
EET_BASIC_STRING
};

We have also a mapping from those types to name strings, to be used in the Eet unions and variants `type_get()` and `type_set()` type identifying callbacks:

struct
{
Example_Data_Type u;
const char *name;
} eet_mapping[] = {
{ EET_STRUCT1, "ST1" },
{ EET_STRUCT2, "ST2" },
{ EET_STRUCT3, "ST3" },
{ EET_BASIC_FLOAT, "float" },
{ EET_BASIC_STRING, "string" },
{ EET_UNKNOWN, NULL }
};

In this example, we have no fancy hash to store our data into profiles/accounts, but just two lists for union and variant data nodes:

typedef struct _Example_Lists Example_Lists;
struct _Example_Lists
{
Eina_List *union_list;
Eina_List *variant_list;
};
_Eina_List
Type for a generic double linked list.
Definition eina_list.h:318

Let's begin with our unions, then, which look like:

typedef struct _Example_Union Example_Union;
struct _Example_Union
{
Example_Data_Type type;
union {
Example_Struct1 st1;
Example_Struct2 st2;
Example_Struct3 st3;
float f;
const char* string;
} u;
};

The first interesting part of the code is where we define our data descriptors for the main lists, the unions and all of structures upon which those two depend.

/* declaring types */
_data_descriptors_init(void)
{
Eet_Data_Descriptor_Class eddc;
EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Example_Lists);
_lists_descriptor = eet_data_descriptor_file_new(&eddc);
_struct_1_descriptor = _st1_dd();
_struct_2_descriptor = _st2_dd();
_struct_3_descriptor = _st3_dd();
/* for union */
EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Example_Union);
_union_descriptor = eet_data_descriptor_file_new(&eddc);
eddc.version = EET_DATA_DESCRIPTOR_CLASS_VERSION;
eddc.func.type_get = _union_type_get;
eddc.func.type_set = _union_type_set;
_union_unified_descriptor = eet_data_descriptor_file_new(&eddc);
EET_DATA_DESCRIPTOR_ADD_MAPPING(
_union_unified_descriptor, "ST1", _struct_1_descriptor);
EET_DATA_DESCRIPTOR_ADD_MAPPING(
_union_unified_descriptor, "ST2", _struct_2_descriptor);
EET_DATA_DESCRIPTOR_ADD_MAPPING(
_union_unified_descriptor, "ST3", _struct_3_descriptor);
EET_DATA_DESCRIPTOR_ADD_MAPPING_BASIC(
_union_unified_descriptor, "float", EET_T_FLOAT);
EET_DATA_DESCRIPTOR_ADD_MAPPING_BASIC(
_union_unified_descriptor, "string", EET_T_STRING);
EET_DATA_DESCRIPTOR_ADD_UNION(
_union_descriptor, Example_Union, "u", u, type,
_union_unified_descriptor);
EET_DATA_DESCRIPTOR_ADD_LIST(
_lists_descriptor, Example_Lists, "union_list", union_list,
_union_descriptor);
EET_DATA_DESCRIPTOR_ADD_UNION
#define EET_DATA_DESCRIPTOR_ADD_UNION(edd, struct_type, name, member, type_member, unified_type)
Adds an union type to a data descriptor.
Definition Eet.h:3834
EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET
#define EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(clas, type)
This macro is an helper that set all the parameter of an Eet_Data_Descriptor_Class correctly when you...
Definition Eet.h:3092
EET_T_STRING
#define EET_T_STRING
Data type: char *.
Definition Eet.h:2606
EET_T_FLOAT
#define EET_T_FLOAT
Data type: float.
Definition Eet.h:2600
EET_DATA_DESCRIPTOR_CLASS_VERSION
#define EET_DATA_DESCRIPTOR_CLASS_VERSION
The version of Eet_Data_Descriptor_Class at the time of the distribution of the sources.
Definition Eet.h:2657
eet_data_descriptor_file_new
EAPI Eet_Data_Descriptor * eet_data_descriptor_file_new(const Eet_Data_Descriptor_Class *eddc)
This function creates a new data descriptor and returns a handle to the new data descriptor.
Definition eet_data.c:2090
EET_DATA_DESCRIPTOR_ADD_MAPPING_BASIC
#define EET_DATA_DESCRIPTOR_ADD_MAPPING_BASIC(unified_type, name, basic_type)
Adds a mapping of a basic type to a data descriptor that will be used by a union type.
Definition Eet.h:3907
EET_DATA_DESCRIPTOR_ADD_LIST
#define EET_DATA_DESCRIPTOR_ADD_LIST(edd, struct_type, name, member, subtype)
Adds a linked list type to a data descriptor.
Definition Eet.h:3528
EET_DATA_DESCRIPTOR_ADD_MAPPING
#define EET_DATA_DESCRIPTOR_ADD_MAPPING(unified_type, name, subtype)
Adds a mapping to a data descriptor that will be used by union, variant or inherited type.
Definition Eet.h:3887
_Eet_Data_Descriptor_Class
Instructs Eet about memory management for different needs under serialization and parse process.
Definition Eet.h:2845
_Eet_Data_Descriptor_Class::type_set
Eet_Descriptor_Type_Set_Callback type_set
called when loading a mapped type with the given type used to describe the type in the descriptor
Definition Eet.h:2865
_Eet_Data_Descriptor_Class::version
int version
ABI version.
Definition Eet.h:2846
_Eet_Data_Descriptor_Class::type_get
Eet_Descriptor_Type_Get_Callback type_get
get the type, as used in the union or variant mapping, that should be used to store the given data in...
Definition Eet.h:2864

The code for descriptors on `Example_Struct1`, `Example_Struct2` and `Example_Struct3` is straightforward, a matter already covered on Advanced use of Eet Data Descriptors. What is new, here, are the two type matching functions for our unions. There, we must set the `data` pointer to its matching type, on `_union_type_set` and return the correct matching type, on `_union_type_get:`

With the EET_DATA_DESCRIPTOR_ADD_MAPPING calls, which follow, we make the the link between our type names and their respective structs. The code handling actual data is pretty much the same as in Advanced use of Eet Data Descriptors – one uses command line arguments to enter new data chunks (or just to visualize the contents of an Eet file), signalling if they are unions or variants. One must also pass the type of the data chuck to enter, with integers 1, 2 or

1. Then, come the fields for each type:
   "Usage:\n\t%s <input> <output> [action action-params]\n\n"
   "where actions and their parameters are:\n"
   "\tunion <type> [fields]\n"
   "\tvariant <type> [fields]\n"
   "\n",
   argv[0]);
   Variants are very similar to unions, except that data chunks need not contain previously allocated space for each of the possible types of data going in them:
   typedef struct _Example_Variant_Type Example_Variant_Type;
   struct _Example_Variant_Type
   {
   const char *type;
   Eina_Bool unknow : 1;
   };
   struct _Example_Variant
   {
   Example_Variant_Type t;
   void *data; /* differently than the union type, we
   * don't need to pre-allocate the memory
   * for the field*/
   };
   The code declaring the data descriptors and handling the data is very similar to the unions part, and is left for the reader to check for him/herself. The complete code of the example follows.

1//Compile with:
2// gcc -o eet-data-file_descriptor_02 eet-data-file_descriptor_02.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
12typedef enum _Example_Data_Type Example_Data_Type;
13typedef struct _Example_Variant_Type Example_Variant_Type;
14typedef struct _Example_Variant Example_Variant;
15typedef struct _Example_Union Example_Union;
16typedef struct _Example_Struct1 Example_Struct1;
17typedef struct _Example_Struct2 Example_Struct2;
18typedef struct _Example_Struct3 Example_Struct3;
19typedef struct _Example_Lists Example_Lists;
20
21enum _Example_Data_Type
22{
23 EET_UNKNOWN = 0,
24 EET_STRUCT1,
25 EET_STRUCT2,
26 EET_STRUCT3,
27 EET_BASIC_FLOAT,
28 EET_BASIC_STRING
29};
30
31struct
32{
33 Example_Data_Type u;
34 const char *name;
35} eet_mapping[] = {
36 { EET_STRUCT1, "ST1" },
37 { EET_STRUCT2, "ST2" },
38 { EET_STRUCT3, "ST3" },
39 { EET_BASIC_FLOAT, "float" },
40 { EET_BASIC_STRING, "string" },
41 { EET_UNKNOWN, NULL }
42};
43
44struct _Example_Struct1
45{
46 double val1;
47 int stuff;
48 const char *s1;
49};
50
51struct _Example_Struct2
52{
53 Eina_Bool b1;
54 unsigned long long v1;
55};
56
57struct _Example_Struct3
58{
59 int body;
60};
61
62struct _Example_Union
63{
64 Example_Data_Type type;
65
66 union {
67 Example_Struct1 st1;
68 Example_Struct2 st2;
69 Example_Struct3 st3;
70 float f;
71 const char* string;
72 } u;
73};
74
75struct _Example_Variant_Type
76{
77 const char *type;
78 Eina_Bool unknow : 1;
79};
80
81struct _Example_Variant
82{
83 Example_Variant_Type t;
84
85 void *data; /* differently than the union type, we
86 * don't need to pre-allocate the memory
87 * for the field*/
88};
89
90struct _Example_Lists
91{
92 Eina_List *union_list;
93 Eina_List *variant_list;
94};
95
96static void
97_st1_set(Example_Struct1 *st1,
98 double v1,
99 int v2,
100 const char *v3)
101{
102 st1->val1 = v1;
103 st1->stuff = v2;
104 st1->s1 = v3;
105} /* _st1_set */
106
107static void
108_st2_set(Example_Struct2 *st2,
109 Eina_Bool v1,
110 unsigned long long v2)
111{
112 st2->b1 = v1;
113 st2->v1 = v2;
114} /* _st2_set */
115
116static void
117_st3_set(Example_Struct3 *st3,
118 int v1)
119{
120 st3->body = v1;
121} /* _st3_set */
122
123static const char *
124/* union
125 type_get() */
126_union_type_get(const void *data,
127 Eina_Bool *unknow)
128{
129 const Example_Data_Type *u = data;
130 int i;
131
132 if (unknow)
133 *unknow = EINA_FALSE;
134
135 for (i = 0; eet_mapping[i].name != NULL; ++i)
136 if (*u == eet_mapping[i].u)
137 return eet_mapping[i].name;
138
139 if (unknow)
140 *unknow = EINA_TRUE;
141
142 return NULL;
143} /* _union_type_get */
144
145static Eina_Bool
146_union_type_set(const char *type,
147 void *data,
148 Eina_Bool unknow)
149{
150 Example_Data_Type *u = data;
151 int i;
152
153 if (unknow)
154 return EINA_FALSE;
155
156 for (i = 0; eet_mapping[i].name != NULL; ++i)
157 if (strcmp(eet_mapping[i].name, type) == 0)
158 {
159 *u = eet_mapping[i].u;
160 return EINA_TRUE;
161 }
162
163 return EINA_FALSE;
164} /* _union_type_set */
165
166static const char *
167_variant_type_get(const void *data,
168 Eina_Bool *unknow)
169{
170 const Example_Variant_Type *type = data;
171 int i;
172
173 if (unknow)
174 *unknow = type->unknow;
175
176 for (i = 0; eet_mapping[i].name != NULL; ++i)
177 if (strcmp(type->type, eet_mapping[i].name) == 0)
178 return eet_mapping[i].name;
179
180 if (unknow)
181 *unknow = EINA_FALSE;
182
183 return type->type;
184} /* _variant_type_get */
185
186static Eina_Bool
187_variant_type_set(const char *type,
188 void *data,
189 Eina_Bool unknow)
190{
191 Example_Variant_Type *vt = data;
192
193 vt->type = type;
194 vt->unknow = unknow;
195 return EINA_TRUE;
196} /* _variant_type_set */
197
198static Eet_Data_Descriptor *
199_st1_dd(void)
200{
201 Eet_Data_Descriptor_Class eddc;
202 Eet_Data_Descriptor *res;
203
204 EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Example_Struct1);
205 res = eet_data_descriptor_file_new(&eddc);
206 EET_DATA_DESCRIPTOR_ADD_BASIC(
207 res, Example_Struct1, "val1", val1, EET_T_DOUBLE);
208 EET_DATA_DESCRIPTOR_ADD_BASIC(
209 res, Example_Struct1, "stuff", stuff, EET_T_INT);
210 EET_DATA_DESCRIPTOR_ADD_BASIC(
211 res, Example_Struct1, "s1", s1, EET_T_STRING);
212
213 return res;
214} /* _st1_dd */
215
216static Eet_Data_Descriptor *
217_st2_dd(void)
218{
219 Eet_Data_Descriptor_Class eddc;
220 Eet_Data_Descriptor *res;
221
222 EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Example_Struct2);
223 res = eet_data_descriptor_file_new(&eddc);
224 EET_DATA_DESCRIPTOR_ADD_BASIC(
225 res, Example_Struct2, "b1", b1, EET_T_UCHAR);
226 EET_DATA_DESCRIPTOR_ADD_BASIC(
227 res, Example_Struct2, "v1", v1, EET_T_ULONG_LONG);
228
229 return res;
230} /* _st2_dd */
231
232static Eet_Data_Descriptor *
233_st3_dd(void)
234{
235 Eet_Data_Descriptor_Class eddc;
236 Eet_Data_Descriptor *res;
237
238 EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Example_Struct3);
239 res = eet_data_descriptor_file_new(&eddc);
240 EET_DATA_DESCRIPTOR_ADD_BASIC(
241 res, Example_Struct3, "body", body, EET_T_INT);
242
243 return res;
244} /* _st3_dd */
245
246/* string that represents the entry in the eet file. you might like to
247 * have different profiles or so in the same file, this is possible
248 * with different strings
249 */
250static const char CACHE_FILE_ENTRY[] = "cache";
251
252/* keep the descriptor static global, so it can be shared by different
253 * functions (load/save) of this and only this file.
254 */
255static Eet_Data_Descriptor *_lists_descriptor;
256static Eet_Data_Descriptor *_struct_1_descriptor;
257static Eet_Data_Descriptor *_struct_2_descriptor;
258static Eet_Data_Descriptor *_struct_3_descriptor;
259static Eet_Data_Descriptor *_union_descriptor;
260static Eet_Data_Descriptor *_variant_descriptor;
261static Eet_Data_Descriptor *_union_unified_descriptor;
262static Eet_Data_Descriptor *_variant_unified_descriptor;
263
264/* keep file handle alive, so mmap()ed strings are all alive as
265 * well */
266static Eet_File *_cache_file = NULL;
267static Eet_Dictionary *_cache_dict = NULL;
268
269static void
270/* declaring types */
271_data_descriptors_init(void)
272{
273 Eet_Data_Descriptor_Class eddc;
274
275 EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Example_Lists);
276 _lists_descriptor = eet_data_descriptor_file_new(&eddc);
277
278 _struct_1_descriptor = _st1_dd();
279 _struct_2_descriptor = _st2_dd();
280 _struct_3_descriptor = _st3_dd();
281
282 /* for union */
283 EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Example_Union);
284 _union_descriptor = eet_data_descriptor_file_new(&eddc);
285
286 eddc.version = EET_DATA_DESCRIPTOR_CLASS_VERSION;
287 eddc.func.type_get = _union_type_get;
288 eddc.func.type_set = _union_type_set;
289 _union_unified_descriptor = eet_data_descriptor_file_new(&eddc);
290
291 EET_DATA_DESCRIPTOR_ADD_MAPPING(
292 _union_unified_descriptor, "ST1", _struct_1_descriptor);
293 EET_DATA_DESCRIPTOR_ADD_MAPPING(
294 _union_unified_descriptor, "ST2", _struct_2_descriptor);
295 EET_DATA_DESCRIPTOR_ADD_MAPPING(
296 _union_unified_descriptor, "ST3", _struct_3_descriptor);
297 EET_DATA_DESCRIPTOR_ADD_MAPPING_BASIC(
298 _union_unified_descriptor, "float", EET_T_FLOAT);
299 EET_DATA_DESCRIPTOR_ADD_MAPPING_BASIC(
300 _union_unified_descriptor, "string", EET_T_STRING);
301
302 EET_DATA_DESCRIPTOR_ADD_UNION(
303 _union_descriptor, Example_Union, "u", u, type,
304 _union_unified_descriptor);
305
306 EET_DATA_DESCRIPTOR_ADD_LIST(
307 _lists_descriptor, Example_Lists, "union_list", union_list,
308 _union_descriptor);
309
310 /* for variant */
311 EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Example_Variant);
312 _variant_descriptor = eet_data_descriptor_file_new(&eddc);
313
314 eddc.version = EET_DATA_DESCRIPTOR_CLASS_VERSION;
315 eddc.func.type_get = _variant_type_get;
316 eddc.func.type_set = _variant_type_set;
317 _variant_unified_descriptor = eet_data_descriptor_stream_new(&eddc);
318
319 EET_DATA_DESCRIPTOR_ADD_MAPPING(
320 _variant_unified_descriptor, "ST1", _struct_1_descriptor);
321 EET_DATA_DESCRIPTOR_ADD_MAPPING(
322 _variant_unified_descriptor, "ST2", _struct_2_descriptor);
323 EET_DATA_DESCRIPTOR_ADD_MAPPING(
324 _variant_unified_descriptor, "ST3", _struct_3_descriptor);
325
326 EET_DATA_DESCRIPTOR_ADD_VARIANT(
327 _variant_descriptor, Example_Variant, "data", data, t,
328 _variant_unified_descriptor);
329
330 EET_DATA_DESCRIPTOR_ADD_LIST(
331 _lists_descriptor, Example_Lists, "variant_list", variant_list,
332 _variant_descriptor);
333} /* _data_descriptors_init */
334
335static void
336_data_descriptors_shutdown(void)
337{
338 eet_data_descriptor_free(_lists_descriptor);
339 eet_data_descriptor_free(_struct_1_descriptor);
340 eet_data_descriptor_free(_struct_2_descriptor);
341 eet_data_descriptor_free(_struct_3_descriptor);
342 eet_data_descriptor_free(_union_descriptor);
343 eet_data_descriptor_free(_variant_descriptor);
344 eet_data_descriptor_free(_union_unified_descriptor);
345 eet_data_descriptor_free(_variant_unified_descriptor);
346} /* _data_descriptors_shutdown */
347
348/* need to check if the pointer came from mmap()ed area in
349 * eet_dictionary or it was allocated with eina_stringshare_add()
350 */
351static void
352_string_free(const char *str)
353{
354 if (!str)
355 return;
356
357 if ((_cache_dict) && (eet_dictionary_string_check(_cache_dict, str)))
358 return;
359
360 eina_stringshare_del(str);
361} /* _string_free */
362
363static Example_Union *
364_union_1_new(const char *v1,
365 const char *v2,
366 const char *v3)
367{
368 Example_Union *un = calloc(1, sizeof(Example_Union));
369 if (!un)
370 {
371 fprintf(
372 stderr, "ERROR: could not allocate an Example_Union struct.\n");
373 return NULL;
374 }
375
376 un->type = EET_STRUCT1;
377 _st1_set(&(un->u.st1), atof(v1), atoi(v2), eina_stringshare_add(v3));
378
379 return un;
380}
381
382static Example_Union *
383_union_2_new(const char *v1,
384 const char *v2)
385{
386 Example_Union *un = calloc(1, sizeof(Example_Union));
387 if (!un)
388 {
389 fprintf(
390 stderr, "ERROR: could not allocate an Example_Union struct.\n");
391 return NULL;
392 }
393
394 un->type = EET_STRUCT2;
395 _st2_set(&(un->u.st2), atoi(v1), atoi(v2));
396
397 return un;
398}
399
400static Example_Union *
401_union_3_new(const char *v1)
402{
403 Example_Union *un = calloc(1, sizeof(Example_Union));
404 if (!un)
405 {
406 fprintf(
407 stderr, "ERROR: could not allocate an Example_Union struct.\n");
408 return NULL;
409 }
410
411 un->type = EET_STRUCT3;
412 _st3_set(&(un->u.st3), atoi(v1));
413
414 return un;
415}
416
417static Example_Union *
418_union_float_new(const char *v1)
419{
420 Example_Union *un = calloc(1, sizeof(Example_Union));
421 if (!un)
422 {
423 fprintf(
424 stderr, "ERROR: could not allocate an Example_Union struct.\n");
425 return NULL;
426 }
427
428 un->type = EET_BASIC_FLOAT;
429 un->u.f = atof(v1);
430
431 return un;
432}
433
434static Example_Union *
435_union_string_new(const char *v1)
436{
437 Example_Union *un = calloc(1, sizeof(Example_Union));
438 if (!un)
439 {
440 fprintf(
441 stderr, "ERROR: could not allocate an Example_Union struct.\n");
442 return NULL;
443 }
444
445 un->type = EET_BASIC_STRING;
446 un->u.string = v1;
447
448 return un;
449}
450
451static Example_Variant *
452_variant_1_new(const char *v1,
453 const char *v2,
454 const char *v3)
455{
456 Example_Struct1 *st1;
457 Example_Variant *va = calloc(1, sizeof(Example_Variant));
458 if (!va)
459 {
460 fprintf(
461 stderr, "ERROR: could not allocate an Example_Variant struct.\n");
462 return NULL;
463 }
464
465 va->t.type = eet_mapping[0].name;
466 st1 = calloc(1, sizeof (Example_Struct1));
467 _st1_set(st1, atof(v1), atoi(v2), eina_stringshare_add(v3));
468 va->data = st1;
469
470 return va;
471}
472
473static Example_Variant *
474_variant_2_new(const char *v1,
475 const char *v2)
476{
477 printf("varinant 2 new\n");
478
479 Example_Struct2 *st2;
480 Example_Variant *va = calloc(1, sizeof(Example_Variant));
481 if (!va)
482 {
483 fprintf(
484 stderr, "ERROR: could not allocate an Example_Variant struct.\n");
485 return NULL;
486 }
487
488 va->t.type = eet_mapping[1].name;
489
490 printf("type gets %s\n", va->t.type);
491
492 st2 = calloc(1, sizeof (Example_Struct2));
493 _st2_set(st2, atoi(v1), atoi(v2));
494 va->data = st2;
495
496 return va;
497}
498
499static Example_Variant *
500_variant_3_new(const char *v1)
501{
502 Example_Struct3 *st3;
503 Example_Variant *va = calloc(1, sizeof(Example_Variant));
504 if (!va)
505 {
506 fprintf(
507 stderr, "ERROR: could not allocate an Example_Variant struct.\n");
508 return NULL;
509 }
510
511 va->t.type = eet_mapping[2].name;
512 st3 = calloc(1, sizeof (Example_Struct3));
513 _st3_set(st3, atoi(v1));
514 va->data = st3;
515
516 return va;
517}
518
519static Example_Lists *
520_data_new(void)
521{
522 Example_Lists *example_lists = calloc(1, sizeof(Example_Lists));
523 if (!example_lists)
524 {
525 fprintf(stderr, "ERROR: could not allocate a Example_Lists struct.\n");
526 return NULL;
527 }
528
529 return example_lists;
530} /* _data_new */
531
532static void
533_union_free(Example_Union *un)
534{
535 if (un->type == EET_STRUCT1)
536 {
537 Example_Struct1 *st1 = &(un->u.st1);
538 _string_free(st1->s1);
539 }
540
541 free(un);
542}
543
544static void
545_variant_free(Example_Variant *va)
546{
547 if (!strcmp(va->t.type, eet_mapping[0].name))
548 {
549 Example_Struct1 *st1 = va->data;
550 _string_free(st1->s1);
551 }
552
553 free(va->data);
554 free(va);
555}
556
557static void
558_data_free(Example_Lists *cache)
559{
560 Example_Union *un;
561 Example_Variant *va;
562
563 EINA_LIST_FREE(cache->union_list, un)
564 _union_free(un);
565
566 EINA_LIST_FREE(cache->variant_list, va)
567 _variant_free(va);
568
569 free(cache);
570} /* _data_free */
571
572static Example_Lists *
573_data_load(const char *filename)
574{
575 Example_Lists *data;
576 Eet_File *ef = eet_open(filename, EET_FILE_MODE_READ);
577 if (!ef)
578 {
579 fprintf(stderr, "ERROR: could not open '%s' for read\n", filename);
580 return NULL;
581 }
582
583 data = eet_data_read(ef, _lists_descriptor, CACHE_FILE_ENTRY);
584 if (!data)
585 {
586 eet_close(ef);
587 return NULL;
588 }
589
590 if (_cache_file)
591 eet_close(_cache_file);
592
593 _cache_file = ef;
594 _cache_dict = eet_dictionary_get(ef);
595
596 return data;
597} /* _data_load */
598
599static Eina_Bool
600_data_save(const Example_Lists *cache,
601 const char *filename)
602{
603 char tmp[PATH_MAX];
604 Eet_File *ef;
605 Eina_Bool ret;
606 unsigned int i, len;
607 struct stat st;
608
609 len = eina_strlcpy(tmp, filename, sizeof(tmp));
610 if (len + 12 >= (int)sizeof(tmp))
611 {
612 fprintf(stderr, "ERROR: file name is too big: %s\n", filename);
613 return EINA_FALSE;
614 }
615
616 i = 0;
617 do
618 {
619 snprintf(tmp + len, 12, ".%u", i);
620 i++;
621 }
622 while (stat(tmp, &st) == 0);
623
624 ef = eet_open(tmp, EET_FILE_MODE_WRITE);
625 if (!ef)
626 {
627 fprintf(stderr, "ERROR: could not open '%s' for write\n", tmp);
628 return EINA_FALSE;
629 }
630
631 ret = eet_data_write
632 (ef, _lists_descriptor, CACHE_FILE_ENTRY, cache, EINA_TRUE);
633
634 eet_close(ef);
635
636 if (ret)
637 {
638 unlink(filename);
639 rename(tmp, filename);
640 }
641
642 return ret;
643} /* _data_save */
644
645static void
646_print_union(const Example_Union *un)
647{
648 printf("\t | type: %s'\n", eet_mapping[un->type - 1].name);
649
650 switch (un->type)
651 {
652 case EET_STRUCT1:
653 printf("\t\t val1: %f\n", un->u.st1.val1);
654 printf("\t\t stuff: %d\n", un->u.st1.stuff);
655 printf("\t\t s1: %s\n", un->u.st1.s1);
656 break;
657
658 case EET_STRUCT2:
659 printf("\t\t val1: %i\n", un->u.st2.b1);
660 printf("\t\t stuff: %lli\n", un->u.st2.v1);
661 break;
662
663 case EET_STRUCT3:
664 printf("\t\t val1: %i\n", un->u.st3.body);
665 break;
666
667 case EET_BASIC_FLOAT:
668 printf("\t\t float: %f\n", un->u.f);
669 break;
670
671 case EET_BASIC_STRING:
672 printf("\t\t string: %s\n", un->u.string);
673 break;
674
675 default:
676 return;
677 }
678}
679
680static void
681_print_variant(const Example_Variant *va)
682{
683 printf("\t | type: %s'\n", va->t.type);
684
685 switch (va->t.type[2])
686 {
687 case '1':
688 {
689 Example_Struct1 *st1 = va->data;
690
691 printf("\t\t val1: %f\n", st1->val1);
692 printf("\t\t stuff: %d\n", st1->stuff);
693 printf("\t\t s1: %s\n", st1->s1);
694 }
695 break;
696
697 case '2':
698 {
699 Example_Struct2 *st2 = va->data;
700
701 printf("\t\t val1: %i\n", st2->b1);
702 printf("\t\t stuff: %lli\n", st2->v1);
703 }
704 break;
705
706 case '3':
707 {
708 Example_Struct3 *st3 = va->data;
709
710 printf("\t\t val1: %i\n", st3->body);
711 }
712 break;
713
714 default:
715 return;
716 }
717}
718
719int
720main(int argc,
721 char *argv[])
722{
723 Example_Lists *data_lists;
724 int ret = 0;
725
726 if (argc < 3)
727 {
728 fprintf(stderr,
729 "Usage:\n\t%s <input> <output> [action action-params]\n\n"
730 "where actions and their parameters are:\n"
731 "\tunion <type> [fields]\n"
732 "\tvariant <type> [fields]\n"
733 "\n",
734 argv[0]);
735 return -1;
736 }
737
738 eina_init();
739 eet_init();
740 _data_descriptors_init();
741
742 data_lists = _data_load(argv[1]);
743 if (!data_lists)
744 {
745 printf("Creating new data lists.\n");
746 data_lists = _data_new();
747 if (!data_lists)
748 {
749 ret = -2;
750 goto end;
751 }
752 }
753
754 if (argc > 3)
755 {
756 if (strcmp(argv[3], "union") == 0)
757 {
758 if (argc > 4)
759 {
760 int type = atoi(argv[4]);
761 Example_Union *un;
762
763 if (type < EET_STRUCT1 || type > EET_BASIC_STRING)
764 {
765 fprintf(stderr,
766 "ERROR: invalid type parameter (%s).\n",
767 argv[4]);
768 goto cont;
769 }
770
771 switch (type)
772 {
773 case 1:
774 if (argc != 8)
775 {
776 fprintf(
777 stderr, "ERROR: wrong number of parameters"
778 " (%d).\n", argc);
779 goto cont;
780 }
781
782 un = _union_1_new(
783 argv[5], argv[6], argv[7]);
784 if (!un)
785 {
786 fprintf(
787 stderr, "ERROR: could not create the "
788 "requested union.\n");
789 goto cont;
790 }
791 data_lists->union_list =
792 eina_list_append(data_lists->union_list, un);
793 break;
794
795 case 2:
796 if (argc != 7)
797 {
798 fprintf(
799 stderr, "ERROR: wrong number of parameters"
800 " (%d).\n", argc);
801 goto cont;
802 }
803
804 un = _union_2_new(argv[5], argv[6]);
805 if (!un)
806 {
807 fprintf(
808 stderr, "ERROR: could not create the "
809 "requested union.\n");
810 goto cont;
811 }
812 data_lists->union_list =
813 eina_list_append(data_lists->union_list, un);
814 break;
815
816 case 3:
817 if (argc != 6)
818 {
819 fprintf(
820 stderr, "ERROR: wrong number of parameters"
821 " (%d).\n", argc);
822 goto cont;
823 }
824
825 un = _union_3_new(argv[5]);
826 if (!un)
827 {
828 fprintf(
829 stderr, "ERROR: could not create the "
830 "requested union.\n");
831 goto cont;
832 }
833 data_lists->union_list =
834 eina_list_append(data_lists->union_list, un);
835 break;
836
837 case EET_BASIC_FLOAT:
838 if (argc != 6)
839 {
840 fprintf(
841 stderr, "ERROR: wrong number of parameters"
842 " (%d).\n", argc);
843 goto cont;
844 }
845
846 un = _union_float_new(argv[5]);
847 if (!un)
848 {
849 fprintf(
850 stderr, "ERROR: could not create the "
851 "requested union.\n");
852 goto cont;
853 }
854 data_lists->union_list =
855 eina_list_append(data_lists->union_list, un);
856 break;
857
858 case EET_BASIC_STRING:
859 if (argc != 6)
860 {
861 fprintf(
862 stderr, "ERROR: wrong number of parameters"
863 " (%d).\n", argc);
864 goto cont;
865 }
866
867 un = _union_string_new(argv[5]);
868 if (!un)
869 {
870 fprintf(
871 stderr, "ERROR: could not create the "
872 "requested union.\n");
873 goto cont;
874 }
875 data_lists->union_list =
876 eina_list_append(data_lists->union_list, un);
877 break;
878
879 default:
880 fprintf(
881 stderr, "ERROR: bad type of of struct passed\n");
882 goto cont;
883 }
884 }
885 else
886 fprintf(stderr,
887 "ERROR: wrong number of parameters (%d).\n",
888 argc);
889 }
890 else if (strcmp(argv[3], "variant") == 0)
891 {
892 if (argc > 4)
893 {
894 int type = atoi(argv[4]);
895 Example_Variant *va;
896
897 if (type < EET_STRUCT1 || type > EET_STRUCT3)
898 {
899 fprintf(stderr,
900 "ERROR: invalid type parameter (%s).\n",
901 argv[4]);
902 goto cont;
903 }
904
905 switch (type)
906 {
907 case 1:
908 if (argc != 8)
909 {
910 fprintf(
911 stderr, "ERROR: wrong number of parameters"
912 " (%d).\n", argc);
913 goto cont;
914 }
915
916 va = _variant_1_new(
917 argv[5], argv[6], argv[7]);
918 if (!va)
919 {
920 fprintf(
921 stderr, "ERROR: could not create the "
922 "requested variant.\n");
923 goto cont;
924 }
925 data_lists->variant_list =
926 eina_list_append(data_lists->variant_list, va);
927 break;
928
929 case 2:
930 if (argc != 7)
931 {
932 fprintf(
933 stderr, "ERROR: wrong number of parameters"
934 " (%d).\n", argc);
935 goto cont;
936 }
937
938 va = _variant_2_new(argv[5], argv[6]);
939 if (!va)
940 {
941 fprintf(
942 stderr, "ERROR: could not create the "
943 "requested variant.\n");
944 goto cont;
945 }
946 data_lists->variant_list =
947 eina_list_append(data_lists->variant_list, va);
948 break;
949
950 case 3:
951 if (argc != 6)
952 {
953 fprintf(
954 stderr, "ERROR: wrong number of parameters"
955 " (%d).\n", argc);
956 goto cont;
957 }
958
959 va = _variant_3_new(argv[5]);
960 if (!va)
961 {
962 fprintf(
963 stderr, "ERROR: could not create the "
964 "requested variant.\n");
965 goto cont;
966 }
967 data_lists->variant_list =
968 eina_list_append(data_lists->variant_list, va);
969 break;
970
971 default:
972 fprintf(
973 stderr, "ERROR: bad type of of struct passed\n");
974 goto cont;
975 }
976 }
977 else
978 fprintf(stderr,
979 "ERROR: wrong number of parameters (%d).\n",
980 argc);
981 }
982 else
983 fprintf(stderr, "ERROR: unknown action '%s'\n", argv[3]);
984 }
985
986cont:
987 printf("Cached data:\n");
988
989 printf("\tstats: unions=%u, variants=%u\n",
990 eina_list_count(data_lists->union_list),
991 eina_list_count(data_lists->variant_list));
992
993 if (eina_list_count(data_lists->union_list))
994 {
995 const Eina_List *l;
996 const Example_Union *un;
997 printf("\t * union list:\n");
998
999 EINA_LIST_FOREACH(data_lists->union_list, l, un)
1000 {
1001 _print_union(un);
1002 }
1003 }
1004
1005 if (eina_list_count(data_lists->variant_list))
1006 {
1007 const Eina_List *l;
1008 const Example_Variant *un;
1009 printf("\t * variant list:\n");
1010
1011 EINA_LIST_FOREACH(data_lists->variant_list, l, un)
1012 {
1013 _print_variant(un);
1014 }
1015 }
1016
1017 printf("\n");
1018
1019 if (!_data_save(data_lists, argv[2]))
1020 ret = -3;
1021
1022 _data_free(data_lists);
1023
1024end:
1025 if (_cache_file)
1026 eet_close(_cache_file);
1027 _data_descriptors_shutdown();
1028 eet_shutdown();
1029 eina_shutdown();
1030
1031 return ret;
1032} /* main */
1033
Eet.h
The file that provides the eet functions.
Eina.h
Eina Utility library.
EET_T_UCHAR
#define EET_T_UCHAR
Data type: unsigned char.
Definition Eet.h:2602
eet_data_descriptor_free
EAPI void eet_data_descriptor_free(Eet_Data_Descriptor *edd)
This function frees a data descriptor when it is not needed anymore.
Definition eet_data.c:2104
Eet_Data_Descriptor
struct _Eet_Data_Descriptor Eet_Data_Descriptor
Opaque handle that have information on a type members.
Definition Eet.h:2648
eet_data_read
EAPI void * eet_data_read(Eet_File *ef, Eet_Data_Descriptor *edd, const char *name)
Reads a data structure from an eet file and decodes it.
Definition eet_data.c:2379
EET_T_INT
#define EET_T_INT
Data type: int.
Definition Eet.h:2598
eet_data_descriptor_stream_new
EAPI Eet_Data_Descriptor * eet_data_descriptor_stream_new(const Eet_Data_Descriptor_Class *eddc)
This function creates a new data descriptor and returns a handle to the new data descriptor.
Definition eet_data.c:2084
EET_DATA_DESCRIPTOR_ADD_VARIANT
#define EET_DATA_DESCRIPTOR_ADD_VARIANT(edd, struct_type, name, member, type_member, unified_type)
Adds a automatically selectable type to a data descriptor.
Definition Eet.h:3866
EET_T_DOUBLE
#define EET_T_DOUBLE
Data type: double.
Definition Eet.h:2601
EET_DATA_DESCRIPTOR_ADD_BASIC
#define EET_DATA_DESCRIPTOR_ADD_BASIC(edd, struct_type, name, member, type)
Adds a basic data element to a data descriptor.
Definition Eet.h:3449
eet_data_write
EAPI int eet_data_write(Eet_File *ef, Eet_Data_Descriptor *edd, const char *name, const void *data, int compress)
Writes a data structure from memory and store in an eet file.
Definition eet_data.c:2416
EET_T_ULONG_LONG
#define EET_T_ULONG_LONG
Data type: unsigned long long.
Definition Eet.h:2605
eet_close
EAPI Eet_Error eet_close(Eet_File *ef)
Closes an eet file handle and flush pending writes.
Definition eet_lib.c:1932
eet_dictionary_string_check
EAPI int eet_dictionary_string_check(Eet_Dictionary *ed, const char *string)
Checks if a given string comes from a given dictionary.
Definition eet_dictionary.c:601
eet_open
EAPI Eet_File * eet_open(const char *file, Eet_File_Mode mode)
Opens an eet file on disk, and returns a handle to it.
Definition eet_lib.c:1525
Eet_File
struct _Eet_File Eet_File
Opaque handle that defines an Eet file (or memory).
Definition Eet.h:527
eet_dictionary_get
EAPI Eet_Dictionary * eet_dictionary_get(Eet_File *ef)
Returns a handle to the shared string dictionary of the Eet file.
Definition eet_lib.c:2597
Eet_Dictionary
struct _Eet_Dictionary Eet_Dictionary
Opaque handle that defines a file-backed (mmaped) dictionary of strings.
Definition Eet.h:533
EET_FILE_MODE_READ
@ EET_FILE_MODE_READ
File is read-only.
Definition Eet.h:479
EET_FILE_MODE_WRITE
@ EET_FILE_MODE_WRITE
File is write-only.
Definition Eet.h:480
eet_init
EAPI int eet_init(void)
Initializes the EET library.
Definition eet_lib.c:543
eet_shutdown
EAPI int eet_shutdown(void)
Shuts down the EET library.
Definition eet_lib.c:597
eina_list_append
EINA_API Eina_List * eina_list_append(Eina_List *list, const void *data)
Appends the given data to the given linked list.
Definition eina_list.c:584
EINA_LIST_FOREACH
#define EINA_LIST_FOREACH(list, l, _data)
Definition for the macro to iterate over a list.
Definition eina_list.h:1415
EINA_LIST_FREE
#define EINA_LIST_FREE(list, data)
Definition for the macro to remove each list node while having access to each node's data.
Definition eina_list.h:1629
eina_shutdown
EINA_API int eina_shutdown(void)
Shuts down the Eina library.
Definition eina_main.c:379
eina_init
EINA_API int eina_init(void)
Initializes the Eina library.
Definition eina_main.c:291
eina_strlcpy
EINA_API size_t eina_strlcpy(char *dst, const char *src, size_t siz)
Copies a c-string to another.
Definition eina_str.c:317
eina_stringshare_add
EINA_API Eina_Stringshare * eina_stringshare_add(const char *str)
Retrieves an instance of a string for use in a program.
Definition eina_stringshare.c:606
eina_stringshare_del
EINA_API void eina_stringshare_del(Eina_Stringshare *str)
Notes that the given string has lost an instance.
Definition eina_stringshare.c:533
EINA_TRUE
#define EINA_TRUE
boolean value TRUE (numerical value 1)
Definition eina_types.h:539
EINA_FALSE
#define EINA_FALSE
boolean value FALSE (numerical value 0)
Definition eina_types.h:533