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:
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:
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:
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:
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.
. What is new, here, are the two type matching functions for our unions. There, we must set the
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.
12 typedef enum _Example_Data_Type Example_Data_Type;
13 typedef struct _Example_Variant_Type Example_Variant_Type;
14 typedef struct _Example_Variant Example_Variant;
15 typedef struct _Example_Union Example_Union;
16 typedef struct _Example_Struct1 Example_Struct1;
17 typedef struct _Example_Struct2 Example_Struct2;
18 typedef struct _Example_Struct3 Example_Struct3;
19 typedef struct _Example_Lists Example_Lists;
21 enum _Example_Data_Type
36 { EET_STRUCT1,
"ST1" },
37 { EET_STRUCT2,
"ST2" },
38 { EET_STRUCT3,
"ST3" },
39 { EET_BASIC_FLOAT,
"float" },
40 { EET_BASIC_STRING,
"string" },
44 struct _Example_Struct1
51 struct _Example_Struct2
54 unsigned long long v1;
57 struct _Example_Struct3
64 Example_Data_Type type;
75 struct _Example_Variant_Type
81 struct _Example_Variant
83 Example_Variant_Type t;
97 _st1_set(Example_Struct1 *st1,
108 _st2_set(Example_Struct2 *st2,
110 unsigned long long v2)
117 _st3_set(Example_Struct3 *st3,
126 _union_type_get(
const void *data,
129 const Example_Data_Type *u = data;
135 for (i = 0; eet_mapping[i].name != NULL; ++i)
136 if (*u == eet_mapping[i].u)
137 return eet_mapping[i].name;
146 _union_type_set(
const char *type,
150 Example_Data_Type *u = data;
156 for (i = 0; eet_mapping[i].name != NULL; ++i)
157 if (strcmp(eet_mapping[i].name, type) == 0)
159 *u = eet_mapping[i].u;
167 _variant_type_get(
const void *data,
170 const Example_Variant_Type *type = data;
174 *unknow = type->unknow;
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;
187 _variant_type_set(
const char *type,
191 Example_Variant_Type *vt = data;
209 res, Example_Struct1,
"stuff", stuff,
EET_T_INT);
241 res, Example_Struct3,
"body", body,
EET_T_INT);
250 static const char CACHE_FILE_ENTRY[] =
"cache";
266 static Eet_File *_cache_file = NULL;
271 _data_descriptors_init(
void)
278 _struct_1_descriptor = _st1_dd();
279 _struct_2_descriptor = _st2_dd();
280 _struct_3_descriptor = _st3_dd();
287 eddc.func.
type_get = _union_type_get;
288 eddc.func.
type_set = _union_type_set;
292 _union_unified_descriptor,
"ST1", _struct_1_descriptor);
294 _union_unified_descriptor,
"ST2", _struct_2_descriptor);
296 _union_unified_descriptor,
"ST3", _struct_3_descriptor);
303 _union_descriptor, Example_Union,
"u", u, type,
304 _union_unified_descriptor);
307 _lists_descriptor, Example_Lists,
"union_list", union_list,
315 eddc.func.
type_get = _variant_type_get;
316 eddc.func.
type_set = _variant_type_set;
320 _variant_unified_descriptor,
"ST1", _struct_1_descriptor);
322 _variant_unified_descriptor,
"ST2", _struct_2_descriptor);
324 _variant_unified_descriptor,
"ST3", _struct_3_descriptor);
327 _variant_descriptor, Example_Variant,
"data", data, t,
328 _variant_unified_descriptor);
331 _lists_descriptor, Example_Lists,
"variant_list", variant_list,
332 _variant_descriptor);
336 _data_descriptors_shutdown(
void)
352 _string_free(
const char *str)
363 static Example_Union *
364 _union_1_new(
const char *v1,
368 Example_Union *un = calloc(1,
sizeof(Example_Union));
372 stderr,
"ERROR: could not allocate an Example_Union struct.\n");
376 un->type = EET_STRUCT1;
382 static Example_Union *
383 _union_2_new(
const char *v1,
386 Example_Union *un = calloc(1,
sizeof(Example_Union));
390 stderr,
"ERROR: could not allocate an Example_Union struct.\n");
394 un->type = EET_STRUCT2;
395 _st2_set(&(un->u.st2), atoi(v1), atoi(v2));
400 static Example_Union *
401 _union_3_new(
const char *v1)
403 Example_Union *un = calloc(1,
sizeof(Example_Union));
407 stderr,
"ERROR: could not allocate an Example_Union struct.\n");
411 un->type = EET_STRUCT3;
412 _st3_set(&(un->u.st3), atoi(v1));
417 static Example_Union *
418 _union_float_new(
const char *v1)
420 Example_Union *un = calloc(1,
sizeof(Example_Union));
424 stderr,
"ERROR: could not allocate an Example_Union struct.\n");
428 un->type = EET_BASIC_FLOAT;
434 static Example_Union *
435 _union_string_new(
const char *v1)
437 Example_Union *un = calloc(1,
sizeof(Example_Union));
441 stderr,
"ERROR: could not allocate an Example_Union struct.\n");
445 un->type = EET_BASIC_STRING;
451 static Example_Variant *
452 _variant_1_new(
const char *v1,
456 Example_Struct1 *st1;
457 Example_Variant *va = calloc(1,
sizeof(Example_Variant));
461 stderr,
"ERROR: could not allocate an Example_Variant struct.\n");
465 va = calloc(1,
sizeof (Example_Variant));
466 va->t.type = eet_mapping[0].name;
467 st1 = calloc(1,
sizeof (Example_Struct1));
474 static Example_Variant *
475 _variant_2_new(
const char *v1,
478 printf(
"varinant 2 new\n");
480 Example_Struct2 *st2;
481 Example_Variant *va = calloc(1,
sizeof(Example_Variant));
485 stderr,
"ERROR: could not allocate an Example_Variant struct.\n");
489 va = calloc(1,
sizeof (Example_Variant));
491 va->t.type = eet_mapping[1].name;
493 printf(
"type gets %s\n", va->t.type);
495 st2 = calloc(1,
sizeof (Example_Struct2));
496 _st2_set(st2, atoi(v1), atoi(v2));
502 static Example_Variant *
503 _variant_3_new(
const char *v1)
505 Example_Struct3 *st3;
506 Example_Variant *va = calloc(1,
sizeof(Example_Variant));
510 stderr,
"ERROR: could not allocate an Example_Variant struct.\n");
514 va = calloc(1,
sizeof (Example_Variant));
515 va->t.type = eet_mapping[2].name;
516 st3 = calloc(1,
sizeof (Example_Struct3));
517 _st3_set(st3, atoi(v1));
523 static Example_Lists *
526 Example_Lists *example_lists = calloc(1,
sizeof(Example_Lists));
529 fprintf(stderr,
"ERROR: could not allocate a Example_Lists struct.\n");
533 return example_lists;
537 _union_free(Example_Union *un)
539 if (un->type == EET_STRUCT1)
541 Example_Struct1 *st1 = &(un->u.st1);
542 _string_free(st1->s1);
549 _variant_free(Example_Variant *va)
551 if (!strcmp(va->t.type, eet_mapping[0].name))
553 Example_Struct1 *st1 = va->data;
554 _string_free(st1->s1);
562 _data_free(Example_Lists *cache)
576 static Example_Lists *
577 _data_load(const
char *filename)
583 fprintf(stderr,
"ERROR: could not open '%s' for read\n", filename);
587 data =
eet_data_read(ef, _lists_descriptor, CACHE_FILE_ENTRY);
604 _data_save(
const Example_Lists *cache,
605 const char *filename)
614 if (len + 12 >= (
int)
sizeof(tmp))
616 fprintf(stderr,
"ERROR: file name is too big: %s\n", filename);
623 snprintf(tmp + len, 12,
".%u", i);
626 while (stat(tmp, &st) == 0);
631 fprintf(stderr,
"ERROR: could not open '%s' for write\n", tmp);
636 (ef, _lists_descriptor, CACHE_FILE_ENTRY, cache,
EINA_TRUE);
650 _print_union(
const Example_Union *un)
652 printf(
"\t | type: %s'\n", eet_mapping[un->type - 1].name);
657 printf(
"\t\t val1: %f\n", un->u.st1.val1);
658 printf(
"\t\t stuff: %d\n", un->u.st1.stuff);
659 printf(
"\t\t s1: %s\n", un->u.st1.s1);
663 printf(
"\t\t val1: %i\n", un->u.st2.b1);
664 printf(
"\t\t stuff: %lli\n", un->u.st2.v1);
668 printf(
"\t\t val1: %i\n", un->u.st3.body);
671 case EET_BASIC_FLOAT:
672 printf(
"\t\t float: %f\n", un->u.f);
675 case EET_BASIC_STRING:
676 printf(
"\t\t string: %s\n", un->u.string);
685 _print_variant(
const Example_Variant *va)
687 printf(
"\t | type: %s'\n", va->t.type);
689 switch (va->t.type[2])
693 Example_Struct1 *st1 = va->data;
695 printf(
"\t\t val1: %f\n", st1->val1);
696 printf(
"\t\t stuff: %d\n", st1->stuff);
697 printf(
"\t\t s1: %s\n", st1->s1);
703 Example_Struct2 *st2 = va->data;
705 printf(
"\t\t val1: %i\n", st2->b1);
706 printf(
"\t\t stuff: %lli\n", st2->v1);
712 Example_Struct3 *st3 = va->data;
714 printf(
"\t\t val1: %i\n", st3->body);
727 Example_Lists *data_lists;
733 "Usage:\n\t%s <input> <output> [action action-params]\n\n" 734 "where actions and their parameters are:\n" 735 "\tunion <type> [fields]\n" 736 "\tvariant <type> [fields]\n" 744 _data_descriptors_init();
746 data_lists = _data_load(argv[1]);
749 printf(
"Creating new data lists.\n");
750 data_lists = _data_new();
760 if (strcmp(argv[3],
"union") == 0)
764 int type = atoi(argv[4]);
767 if (type < EET_STRUCT1 || type > EET_BASIC_STRING)
770 "ERROR: invalid type parameter (%s).\n",
781 stderr,
"ERROR: wrong number of parameters" 787 argv[5], argv[6], argv[7]);
791 stderr,
"ERROR: could not create the " 792 "requested union.\n");
795 data_lists->union_list =
803 stderr,
"ERROR: wrong number of parameters" 808 un = _union_2_new(argv[5], argv[6]);
812 stderr,
"ERROR: could not create the " 813 "requested union.\n");
816 data_lists->union_list =
824 stderr,
"ERROR: wrong number of parameters" 829 un = _union_3_new(argv[5]);
833 stderr,
"ERROR: could not create the " 834 "requested union.\n");
837 data_lists->union_list =
841 case EET_BASIC_FLOAT:
845 stderr,
"ERROR: wrong number of parameters" 850 un = _union_float_new(argv[5]);
854 stderr,
"ERROR: could not create the " 855 "requested union.\n");
858 data_lists->union_list =
862 case EET_BASIC_STRING:
866 stderr,
"ERROR: wrong number of parameters" 871 un = _union_string_new(argv[5]);
875 stderr,
"ERROR: could not create the " 876 "requested union.\n");
879 data_lists->union_list =
885 stderr,
"ERROR: bad type of of struct passed\n");
891 "ERROR: wrong number of parameters (%d).\n",
894 else if (strcmp(argv[3],
"variant") == 0)
898 int type = atoi(argv[4]);
901 if (type < EET_STRUCT1 || type > EET_STRUCT3)
904 "ERROR: invalid type parameter (%s).\n",
915 stderr,
"ERROR: wrong number of parameters" 921 argv[5], argv[6], argv[7]);
925 stderr,
"ERROR: could not create the " 926 "requested variant.\n");
929 data_lists->variant_list =
937 stderr,
"ERROR: wrong number of parameters" 942 va = _variant_2_new(argv[5], argv[6]);
946 stderr,
"ERROR: could not create the " 947 "requested variant.\n");
950 data_lists->variant_list =
958 stderr,
"ERROR: wrong number of parameters" 963 va = _variant_3_new(argv[5]);
967 stderr,
"ERROR: could not create the " 968 "requested variant.\n");
971 data_lists->variant_list =
977 stderr,
"ERROR: bad type of of struct passed\n");
983 "ERROR: wrong number of parameters (%d).\n",
987 fprintf(stderr,
"ERROR: unknown action '%s'\n", argv[3]);
991 printf(
"Cached data:\n");
993 printf(
"\tstats: unions=%u, variants=%u\n",
1000 const Example_Union *un;
1001 printf(
"\t * union list:\n");
1012 const Example_Variant *un;
1013 printf(
"\t * variant list:\n");
1023 if (!_data_save(data_lists, argv[2]))
1026 _data_free(data_lists);
1031 _data_descriptors_shutdown();
EAPI void eina_stringshare_del(Eina_Stringshare *str)
Note that the given string has lost an instance.
Definition: eina_stringshare.c:537
EAPI Eina_Stringshare * eina_stringshare_add(const char *str)
Retrieve an instance of a string for use in a program.
Definition: eina_stringshare.c:610
EAPI Eet_File * eet_open(const char *file, Eet_File_Mode mode)
Open an eet file on disk, and returns a handle to it.
Definition: eet_lib.c:1502
#define rename(src, dst)
Wrapper around evil_rename().
Definition: evil_stdio.h:226
int version
ABI version.
Definition: Eet.h:2475
EAPI int eet_data_write(Eet_File *ef, Eet_Data_Descriptor *edd, const char *name, const void *data, int compress)
Write a data structure from memory and store in an eet file.
Definition: eet_data.c:2357
#define EINA_FALSE
boolean value FALSE (numerical value 0)
Definition: eina_types.h:311
struct _Eet_File Eet_File
Opaque handle that defines an Eet file (or memory).
Definition: Eet.h:485
#define EET_DATA_DESCRIPTOR_ADD_UNION(edd, struct_type, name, member, type_member, unified_type)
Add an union type to a data descriptor.
Definition: Eet.h:3403
File is read-only.
Definition: Eet.h:466
EAPI int eet_shutdown(void)
Shut down the EET library.
Definition: eet_lib.c:622
int eina_init(void)
Initialize the Eina library.
Definition: eina_main.c:247
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:2493
static unsigned int eina_list_count(const Eina_List *list)
Get the count of the number of items in a list.
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
#define EET_DATA_DESCRIPTOR_ADD_MAPPING_BASIC(unified_type, name, basic_type)
Add a mapping of a basic type to a data descriptor that will be used by a union type.
Definition: Eet.h:3476
#define EET_T_STRING
Data type: char *.
Definition: Eet.h:2379
struct _Eet_Dictionary Eet_Dictionary
Opaque handle that defines a file-backed (mmaped) dictionary of strings.
Definition: Eet.h:491
#define EET_T_UCHAR
Data type: unsigned char.
Definition: Eet.h:2375
EAPI int eet_dictionary_string_check(Eet_Dictionary *ed, const char *string)
Check if a given string comes from a given dictionary.
Definition: eet_dictionary.c:499
#define EET_T_INT
Data type: int.
Definition: Eet.h:2371
#define EINA_TRUE
boolean value TRUE (numerical value 1)
Definition: eina_types.h:317
int eina_shutdown(void)
Shut down the Eina library.
Definition: eina_main.c:317
Eina_List * eina_list_append(Eina_List *list, const void *data)
Append the given data to the given linked list.
Definition: eina_list.c:530
The file that provides the eet functions.
File is write-only.
Definition: Eet.h:467
#define EET_DATA_DESCRIPTOR_ADD_MAPPING(unified_type, name, subtype)
Add a mapping to a data descriptor that will be used by union, variant or inherited type...
Definition: Eet.h:3456
EAPI size_t eina_strlcpy(char *dst, const char *src, size_t siz) EINA_ARG_NONNULL(1
Copy a c-string to another.
#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:2430
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
#define EET_DATA_DESCRIPTOR_ADD_VARIANT(edd, struct_type, name, member, type_member, unified_type)
Add a automatically selectable type to a data descriptor.
Definition: Eet.h:3435
EAPI void * eet_data_read(Eet_File *ef, Eet_Data_Descriptor *edd, const char *name)
Read a data structure from an eet file and decodes it.
Definition: eet_data.c:2323
Instructs Eet about memory management for different needs under serialization and parse process...
Definition: Eet.h:2473
#define EET_DATA_DESCRIPTOR_ADD_BASIC(edd, struct_type, name, member, type)
Add a basic data element to a data descriptor.
Definition: Eet.h:3066
unsigned char Eina_Bool
Type to mimic a boolean.
Definition: eina_types.h:305
#define EET_T_DOUBLE
Data type: double.
Definition: Eet.h:2374
#define EET_DATA_DESCRIPTOR_ADD_LIST(edd, struct_type, name, member, subtype)
Add a linked list type to a data descriptor.
Definition: Eet.h:3145
EAPI Eet_Error eet_close(Eet_File *ef)
Close an eet file handle and flush pending writes.
Definition: eet_lib.c:1752
#define EET_T_ULONG_LONG
Data type: unsigned long long.
Definition: Eet.h:2378
struct _Eet_Data_Descriptor Eet_Data_Descriptor
Opaque handle that have information on a type members.
Definition: Eet.h:2421
#define EINA_LIST_FREE(list, data)
Macro to remove each list node while having access to each node's data.
Definition: eina_list.h:1599
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
Type for a generic double linked list.
Definition: eina_list.h:320
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:2494
#define EINA_LIST_FOREACH(list, l, data)
Macro to iterate over a list.
Definition: eina_list.h:1387
#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:2720
EAPI Eet_Dictionary * eet_dictionary_get(Eet_File *ef)
Return a handle to the shared string dictionary of the Eet file.
Definition: eet_lib.c:2649
#define EET_T_FLOAT
Data type: float.
Definition: Eet.h:2373
EAPI int eet_init(void)
Initialize the EET library.
Definition: eet_lib.c:539