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->t.type = eet_mapping[0].name;
   466    st1 = calloc(1, 
sizeof (Example_Struct1));
   473 static Example_Variant *
   474 _variant_2_new(
const char *v1,
   477    printf(
"varinant 2 new\n");
   479    Example_Struct2 *st2;
   480    Example_Variant *va = calloc(1, 
sizeof(Example_Variant));
   484           stderr, 
"ERROR: could not allocate an Example_Variant struct.\n");
   488    va->t.type = eet_mapping[1].name;
   490    printf(
"type gets %s\n", va->t.type);
   492    st2 = calloc(1, 
sizeof (Example_Struct2));
   493    _st2_set(st2, atoi(v1), atoi(v2));
   499 static Example_Variant *
   500 _variant_3_new(
const char *v1)
   502    Example_Struct3 *st3;
   503    Example_Variant *va = calloc(1, 
sizeof(Example_Variant));
   507           stderr, 
"ERROR: could not allocate an Example_Variant struct.\n");
   511    va->t.type = eet_mapping[2].name;
   512    st3 = calloc(1, 
sizeof (Example_Struct3));
   513    _st3_set(st3, atoi(v1));
   519 static Example_Lists *
   522    Example_Lists *example_lists = calloc(1, 
sizeof(Example_Lists));
   525         fprintf(stderr, 
"ERROR: could not allocate a Example_Lists struct.\n");
   529    return example_lists;
   533 _union_free(Example_Union *un)
   535    if (un->type == EET_STRUCT1)
   537         Example_Struct1 *st1 = &(un->u.st1);
   538         _string_free(st1->s1);
   545 _variant_free(Example_Variant *va)
   547    if (!strcmp(va->t.type, eet_mapping[0].name))
   549         Example_Struct1 *st1 = va->data;
   550         _string_free(st1->s1);
   558 _data_free(Example_Lists *cache)
   572 static Example_Lists *
   573 _data_load(
const char *filename)
   579         fprintf(stderr, 
"ERROR: could not open '%s' for read\n", filename);
   583    data = 
eet_data_read(ef, _lists_descriptor, CACHE_FILE_ENTRY);
   600 _data_save(
const Example_Lists *cache,
   601            const char          *filename)
   610    if (len + 12 >= (
int)
sizeof(tmp))
   612         fprintf(stderr, 
"ERROR: file name is too big: %s\n", filename);
   619         snprintf(tmp + len, 12, 
".%u", i);
   622    while (stat(tmp, &st) == 0);
   627         fprintf(stderr, 
"ERROR: could not open '%s' for write\n", tmp);
   632        (ef, _lists_descriptor, CACHE_FILE_ENTRY, cache, 
EINA_TRUE);
   639         rename(tmp, filename);
   646 _print_union(
const Example_Union *un)
   648    printf(
"\t  |   type: %s'\n", eet_mapping[un->type - 1].name);
   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);
   659         printf(
"\t\t  val1: %i\n", un->u.st2.b1);
   660         printf(
"\t\t  stuff: %lli\n", un->u.st2.v1);
   664         printf(
"\t\t  val1: %i\n", un->u.st3.body);
   667       case EET_BASIC_FLOAT:
   668         printf(
"\t\t  float: %f\n", un->u.f);
   671       case EET_BASIC_STRING:
   672         printf(
"\t\t  string: %s\n", un->u.string);
   681 _print_variant(
const Example_Variant *va)
   683    printf(
"\t  |   type: %s'\n", va->t.type);
   685    switch (va->t.type[2])
   689          Example_Struct1 *st1 = va->data;
   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);
   699          Example_Struct2 *st2 = va->data;
   701          printf(
"\t\t  val1: %i\n", st2->b1);
   702          printf(
"\t\t  stuff: %lli\n", st2->v1);
   708          Example_Struct3 *st3 = va->data;
   710          printf(
"\t\t  val1: %i\n", st3->body);
   723    Example_Lists *data_lists;
   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"   740    _data_descriptors_init();
   742    data_lists = _data_load(argv[1]);
   745         printf(
"Creating new data lists.\n");
   746         data_lists = _data_new();
   756         if (strcmp(argv[3], 
"union") == 0)
   760                   int type = atoi(argv[4]);
   763                   if (type < EET_STRUCT1 || type > EET_BASIC_STRING)
   766                                "ERROR: invalid type parameter (%s).\n",
   777                               stderr, 
"ERROR: wrong number of parameters"   783                            argv[5], argv[6], argv[7]);
   787                               stderr, 
"ERROR: could not create the "   788                                       "requested union.\n");
   791                        data_lists->union_list =
   799                               stderr, 
"ERROR: wrong number of parameters"   804                        un = _union_2_new(argv[5], argv[6]);
   808                               stderr, 
"ERROR: could not create the "   809                                       "requested union.\n");
   812                        data_lists->union_list =
   820                               stderr, 
"ERROR: wrong number of parameters"   825                        un = _union_3_new(argv[5]);
   829                               stderr, 
"ERROR: could not create the "   830                                       "requested union.\n");
   833                        data_lists->union_list =
   837                      case EET_BASIC_FLOAT:
   841                               stderr, 
"ERROR: wrong number of parameters"   846                        un = _union_float_new(argv[5]);
   850                               stderr, 
"ERROR: could not create the "   851                                       "requested union.\n");
   854                        data_lists->union_list =
   858                      case EET_BASIC_STRING:
   862                               stderr, 
"ERROR: wrong number of parameters"   867                        un = _union_string_new(argv[5]);
   871                               stderr, 
"ERROR: could not create the "   872                                       "requested union.\n");
   875                        data_lists->union_list =
   881                          stderr, 
"ERROR: bad type of of struct passed\n");
   887                        "ERROR: wrong number of parameters (%d).\n",
   890         else if (strcmp(argv[3], 
"variant") == 0)
   894                   int type = atoi(argv[4]);
   897                   if (type < EET_STRUCT1 || type > EET_STRUCT3)
   900                                "ERROR: invalid type parameter (%s).\n",
   911                               stderr, 
"ERROR: wrong number of parameters"   917                            argv[5], argv[6], argv[7]);
   921                               stderr, 
"ERROR: could not create the "   922                                       "requested variant.\n");
   925                        data_lists->variant_list =
   933                               stderr, 
"ERROR: wrong number of parameters"   938                        va = _variant_2_new(argv[5], argv[6]);
   942                               stderr, 
"ERROR: could not create the "   943                                       "requested variant.\n");
   946                        data_lists->variant_list =
   954                               stderr, 
"ERROR: wrong number of parameters"   959                        va = _variant_3_new(argv[5]);
   963                               stderr, 
"ERROR: could not create the "   964                                       "requested variant.\n");
   967                        data_lists->variant_list =
   973                          stderr, 
"ERROR: bad type of of struct passed\n");
   979                        "ERROR: wrong number of parameters (%d).\n",
   983           fprintf(stderr, 
"ERROR: unknown action '%s'\n", argv[3]);
   987    printf(
"Cached data:\n");
   989    printf(
"\tstats: unions=%u, variants=%u\n",
   996         const Example_Union *un;
   997         printf(
"\t  * union list:\n");
  1008         const Example_Variant *un;
  1009         printf(
"\t  * variant list:\n");
  1019    if (!_data_save(data_lists, argv[2]))
  1022    _data_free(data_lists);
  1027    _data_descriptors_shutdown();
 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:1511
int version
ABI version. 
Definition: Eet.h:2825
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:2415
#define EINA_FALSE
boolean value FALSE (numerical value 0) 
Definition: eina_types.h:484
struct _Eet_File Eet_File
Opaque handle that defines an Eet file (or memory). 
Definition: Eet.h:523
#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:3790
EAPI int eina_init(void)
Initializes the Eina library. 
Definition: eina_main.c:281
EAPI int eina_shutdown(void)
Shuts down the Eina library. 
Definition: eina_main.c:352
File is read-only. 
Definition: Eet.h:475
EAPI int eet_shutdown(void)
Shuts down the EET library. 
Definition: eet_lib.c:606
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:2843
static unsigned int eina_list_count(const Eina_List *list)
Gets 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:2111
#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:3863
#define EET_T_STRING
Data type: char *. 
Definition: Eet.h:2585
struct _Eet_Dictionary Eet_Dictionary
Opaque handle that defines a file-backed (mmaped) dictionary of strings. 
Definition: Eet.h:529
#define EET_T_UCHAR
Data type: unsigned char. 
Definition: Eet.h:2581
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:489
#define EET_T_INT
Data type: int. 
Definition: Eet.h:2577
#define EINA_TRUE
boolean value TRUE (numerical value 1) 
Definition: eina_types.h:490
EAPI Eina_List * eina_list_append(Eina_List *list, const void *data)
Appends the given data to the given linked list. 
Definition: eina_list.c:587
The file that provides the eet functions. 
File is write-only. 
Definition: Eet.h:476
#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:3843
EAPI size_t eina_strlcpy(char *dst, const char *src, size_t siz) EINA_ARG_NONNULL(1
Copies 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:2636
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:2091
#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:3822
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:2380
void eina_stringshare_del(Eina_Stringshare *str)
Notes that the given string has lost an instance. 
Definition: eina_stringshare.c:537
Instructs Eet about memory management for different needs under serialization and parse process...
Definition: Eet.h:2823
#define EET_DATA_DESCRIPTOR_ADD_BASIC(edd, struct_type, name, member, type)
Adds a basic data element to a data descriptor. 
Definition: Eet.h:3428
unsigned char Eina_Bool
Type to mimic a boolean. 
Definition: eina_types.h:478
#define EET_T_DOUBLE
Data type: double. 
Definition: Eet.h:2580
#define EINA_LIST_FOREACH(list, l, _data)
Definition for the macro to iterate over a list. 
Definition: eina_list.h:1420
#define EET_DATA_DESCRIPTOR_ADD_LIST(edd, struct_type, name, member, subtype)
Adds a linked list type to a data descriptor. 
Definition: Eet.h:3507
EAPI Eet_Error eet_close(Eet_File *ef)
Closes an eet file handle and flush pending writes. 
Definition: eet_lib.c:1911
#define EET_T_ULONG_LONG
Data type: unsigned long long. 
Definition: Eet.h:2584
struct _Eet_Data_Descriptor Eet_Data_Descriptor
Opaque handle that have information on a type members. 
Definition: Eet.h:2627
#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:1646
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:2097
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:2844
Eina_Stringshare * eina_stringshare_add(const char *str)
Retrieves an instance of a string for use in a program. 
Definition: eina_stringshare.c:610
#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:3071
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:2576
#define EET_T_FLOAT
Data type: float. 
Definition: Eet.h:2579
EAPI int eet_init(void)
Initializes the EET library. 
Definition: eet_lib.c:552