3 #endif /* ifdef HAVE_CONFIG_H */
11 #ifdef HAVE_NETINET_IN_H
12 # include <netinet/in.h>
13 #endif /* ifdef HAVE_NETINET_IN_H */
16 # include <winsock2.h>
17 #endif /* ifdef _WIN32 */
22 #include "Eet_private.h"
25 # define FMT_CHAR "%c"
26 # define FMT_UCHAR "%c"
27 # define FMT_LONG_LONG "%I64i"
28 # define FMT_ULONG_LONG "%I64u"
30 # define FMT_CHAR "%hhi"
31 # define FMT_UCHAR "%hhu"
32 # define FMT_LONG_LONG "%lli"
33 # define FMT_ULONG_LONG "%llu"
37 * routines for doing data -> struct and struct -> data conversion
57 * multiple entries ordered as...
59 * fixed size array [ of basic types ]
60 * variable size array [ of basic types ]
61 * linked list [ of basic types ]
62 * hash table [ of basic types ]
64 * need to provide builder/accessor funcs for:
76 typedef struct _Eet_Data_Element Eet_Data_Element;
77 typedef struct _Eet_Data_Basic_Type_Codec Eet_Data_Basic_Type_Codec;
78 typedef struct _Eet_Data_Group_Type_Codec Eet_Data_Group_Type_Codec;
79 typedef struct _Eet_Data_Chunk Eet_Data_Chunk;
80 typedef struct _Eet_Data_Stream Eet_Data_Stream;
81 typedef struct _Eet_Data_Descriptor_Hash Eet_Data_Descriptor_Hash;
82 typedef struct _Eet_Data_Encode_Hash_Info Eet_Data_Encode_Hash_Info;
83 typedef struct _Eet_Free Eet_Free;
84 typedef struct _Eet_Free_Context Eet_Free_Context;
85 typedef struct _Eet_Variant_Unknow Eet_Variant_Unknow;
90 * Eet_Data_Basic_Type_Codec (Coder, Decoder)
91 * Eet_Data_Group_Type_Codec (Coder, Decoder)
93 struct _Eet_Data_Basic_Type_Codec
97 int (*get)(const Eet_Dictionary *ed,
101 void * (*put)(Eet_Dictionary *ed, const void *src, int *size_ret);
104 struct _Eet_Data_Group_Type_Codec
106 int (*get)(Eet_Free_Context *context,
107 const Eet_Dictionary *ed,
108 Eet_Data_Descriptor *edd,
109 Eet_Data_Element *ede,
110 Eet_Data_Chunk *echnk,
116 void (*put)(Eet_Dictionary *ed,
117 Eet_Data_Descriptor *edd,
118 Eet_Data_Element *ede,
123 struct _Eet_Data_Chunk
131 unsigned char group_type;
134 struct _Eet_Data_Stream
141 struct _Eet_Data_Descriptor_Hash
143 Eet_Data_Element *element;
144 Eet_Data_Descriptor_Hash *next;
147 struct _Eet_Data_Descriptor
150 const Eet_Dictionary *ed;
154 void * (*mem_alloc)(size_t size);
155 void (*mem_free)(void *mem);
156 char * (*str_alloc)(const char *str);
157 char * (*str_direct_alloc)(const char *str);
158 void (*str_free)(const char *str);
159 void (*str_direct_free)(const char *str);
160 void * (*list_next)(void *l);
161 void * (*list_append)(void *l, void *d);
162 void * (*list_data)(void *l);
163 void * (*list_free)(void *l);
164 void (*hash_foreach)(void *h,
170 void * (*hash_add)(void *h, const char *k, void *d);
171 void (*hash_free)(void *h);
172 const char *(*type_get)(const void *data, Eina_Bool *unknow);
173 Eina_Bool (*type_set)(const char *type,
176 void * (*array_alloc)(size_t size);
177 void (*array_free)(void *mem);
182 Eet_Data_Element *set;
186 Eet_Data_Descriptor_Hash *buckets;
190 Eina_Bool unified_type : 1;
195 struct _Eet_Data_Element
198 const char *counter_name;
199 const char *directory_name_ptr;
200 Eet_Data_Descriptor *subtype;
201 int offset; /* offset in bytes from the base element */
202 int count; /* number of elements for a fixed array */
203 int counter_offset; /* for a variable array we need the offset of the count variable */
204 unsigned char type; /* EET_T_XXX */
205 unsigned char group_type; /* EET_G_XXX */
208 struct _Eet_Data_Encode_Hash_Info
211 Eet_Data_Element *ede;
215 #define EET_FREE_COUNT 256
219 Eina_Array list[EET_FREE_COUNT];
222 struct _Eet_Free_Context
225 Eet_Free freelist_array;
226 Eet_Free freelist_list;
227 Eet_Free freelist_hash;
228 Eet_Free freelist_str;
229 Eet_Free freelist_direct_str;
232 struct _Eet_Variant_Unknow
243 eet_free_context_init(Eet_Free_Context *context);
245 eet_free_context_shutdown(Eet_Free_Context *context);
248 eet_data_get_char(const Eet_Dictionary *ed,
253 eet_data_put_char(Eet_Dictionary *ed,
257 eet_data_get_short(const Eet_Dictionary *ed,
262 eet_data_put_short(Eet_Dictionary *ed,
266 eet_data_get_int(const Eet_Dictionary *ed,
271 eet_data_put_int(Eet_Dictionary *ed,
275 eet_data_get_long_long(const Eet_Dictionary *ed,
280 eet_data_put_long_long(Eet_Dictionary *ed,
284 eet_data_get_float(const Eet_Dictionary *ed,
289 eet_data_put_float(Eet_Dictionary *ed,
293 eet_data_get_double(const Eet_Dictionary *ed,
298 eet_data_put_double(Eet_Dictionary *ed,
302 eet_data_get_f32p32(const Eet_Dictionary *ed,
307 eet_data_put_f32p32(Eet_Dictionary *ed,
311 eet_data_get_f16p16(const Eet_Dictionary *ed,
316 eet_data_put_f16p16(Eet_Dictionary *ed,
320 eet_data_get_f8p24(const Eet_Dictionary *ed,
325 eet_data_put_f8p24(Eet_Dictionary *ed,
329 eet_data_get_string(const Eet_Dictionary *ed,
334 eet_data_put_string(Eet_Dictionary *ed,
338 eet_data_get_istring(const Eet_Dictionary *ed,
343 eet_data_put_istring(Eet_Dictionary *ed,
347 eet_data_get_null(const Eet_Dictionary *ed,
352 eet_data_put_null(Eet_Dictionary *ed,
357 eet_data_get_type(const Eet_Dictionary *ed,
363 eet_data_put_type(Eet_Dictionary *ed,
369 eet_data_node_simple_type(int type,
374 eet_data_get_unknown(Eet_Free_Context *context,
375 const Eet_Dictionary *ed,
376 Eet_Data_Descriptor *edd,
377 Eet_Data_Element *ede,
378 Eet_Data_Chunk *echnk,
385 eet_data_put_unknown(Eet_Dictionary *ed,
386 Eet_Data_Descriptor *edd,
387 Eet_Data_Element *ede,
391 eet_data_put_array(Eet_Dictionary *ed,
392 Eet_Data_Descriptor *edd,
393 Eet_Data_Element *ede,
397 eet_data_get_array(Eet_Free_Context *context,
398 const Eet_Dictionary *ed,
399 Eet_Data_Descriptor *edd,
400 Eet_Data_Element *ede,
401 Eet_Data_Chunk *echnk,
408 eet_data_get_list(Eet_Free_Context *context,
409 const Eet_Dictionary *ed,
410 Eet_Data_Descriptor *edd,
411 Eet_Data_Element *ede,
412 Eet_Data_Chunk *echnk,
419 eet_data_put_list(Eet_Dictionary *ed,
420 Eet_Data_Descriptor *edd,
421 Eet_Data_Element *ede,
425 eet_data_put_hash(Eet_Dictionary *ed,
426 Eet_Data_Descriptor *edd,
427 Eet_Data_Element *ede,
431 eet_data_get_hash(Eet_Free_Context *context,
432 const Eet_Dictionary *ed,
433 Eet_Data_Descriptor *edd,
434 Eet_Data_Element *ede,
435 Eet_Data_Chunk *echnk,
442 eet_data_put_union(Eet_Dictionary *ed,
443 Eet_Data_Descriptor *edd,
444 Eet_Data_Element *ede,
448 eet_data_get_union(Eet_Free_Context *context,
449 const Eet_Dictionary *ed,
450 Eet_Data_Descriptor *edd,
451 Eet_Data_Element *ede,
452 Eet_Data_Chunk *echnk,
459 eet_data_put_variant(Eet_Dictionary *ed,
460 Eet_Data_Descriptor *edd,
461 Eet_Data_Element *ede,
465 eet_data_get_variant(Eet_Free_Context *context,
466 const Eet_Dictionary *ed,
467 Eet_Data_Descriptor *edd,
468 Eet_Data_Element *ede,
469 Eet_Data_Chunk *echnk,
477 eet_data_chunk_get(const Eet_Dictionary *ed,
478 Eet_Data_Chunk *chnk,
481 static Eet_Data_Chunk *
482 eet_data_chunk_new(void *data,
488 eet_data_chunk_free(Eet_Data_Chunk *chnk);
490 static Eet_Data_Stream *
491 eet_data_stream_new(void);
493 eet_data_stream_write(Eet_Data_Stream *ds,
497 eet_data_stream_free(Eet_Data_Stream *ds);
500 eet_data_chunk_put(Eet_Dictionary *ed,
501 Eet_Data_Chunk *chnk,
502 Eet_Data_Stream *ds);
505 eet_data_descriptor_encode_hash_cb(void *hash,
509 static void *_eet_data_descriptor_encode(Eet_Dictionary *ed,
510 Eet_Data_Descriptor *edd,
513 static void *_eet_data_descriptor_decode(Eet_Free_Context *context,
514 const Eet_Dictionary *ed,
515 Eet_Data_Descriptor *edd,
523 static const Eet_Data_Basic_Type_Codec eet_basic_codec[] =
525 {sizeof(char), "char", eet_data_get_char, eet_data_put_char },
526 {sizeof(short), "short", eet_data_get_short, eet_data_put_short },
527 {sizeof(int), "int", eet_data_get_int, eet_data_put_int },
528 {sizeof(long long), "long_long", eet_data_get_long_long, eet_data_put_long_long},
529 {sizeof(float), "float", eet_data_get_float, eet_data_put_float },
530 {sizeof(double), "double", eet_data_get_double, eet_data_put_double },
531 {sizeof(char), "uchar", eet_data_get_char, eet_data_put_char },
532 {sizeof(short), "ushort", eet_data_get_short, eet_data_put_short },
533 {sizeof(int), "uint", eet_data_get_int, eet_data_put_int },
534 {sizeof(long long), "ulong_long", eet_data_get_long_long, eet_data_put_long_long},
535 {sizeof(char *), "string", eet_data_get_string, eet_data_put_string },
536 {sizeof(char *), "inlined", eet_data_get_istring, eet_data_put_istring },
537 {sizeof(void *), "NULL", eet_data_get_null, eet_data_put_null },
538 {sizeof(Eina_F32p32), "f32p32", eet_data_get_f32p32, eet_data_put_f32p32 },
539 {sizeof(Eina_F16p16), "f16p16", eet_data_get_f16p16, eet_data_put_f16p16 },
540 {sizeof(Eina_F8p24), "f8p24", eet_data_get_f8p24, eet_data_put_f8p24 }
543 static const Eet_Data_Group_Type_Codec eet_group_codec[] =
545 { eet_data_get_unknown, eet_data_put_unknown },
546 { eet_data_get_array, eet_data_put_array },
547 { eet_data_get_array, eet_data_put_array },
548 { eet_data_get_list, eet_data_put_list },
549 { eet_data_get_hash, eet_data_put_hash },
550 { eet_data_get_union, eet_data_put_union },
551 { eet_data_get_variant, eet_data_put_variant }
554 static int _eet_data_words_bigendian = -1;
558 #define SWAP64(x) (x) = \
559 ((((unsigned long long)(x) & 0x00000000000000ffULL) << 56) | \
560 (((unsigned long long)(x) & 0x000000000000ff00ULL) << 40) | \
561 (((unsigned long long)(x) & 0x0000000000ff0000ULL) << 24) | \
562 (((unsigned long long)(x) & 0x00000000ff000000ULL) << 8) | \
563 (((unsigned long long)(x) & 0x000000ff00000000ULL) >> 8) | \
564 (((unsigned long long)(x) & 0x0000ff0000000000ULL) >> 24) | \
565 (((unsigned long long)(x) & 0x00ff000000000000ULL) >> 40) | \
566 (((unsigned long long)(x) & 0xff00000000000000ULL) >> 56))
567 #define SWAP32(x) (x) = \
568 ((((int)(x) & 0x000000ff) << 24) | \
569 (((int)(x) & 0x0000ff00) << 8) | \
570 (((int)(x) & 0x00ff0000) >> 8) | \
571 (((int)(x) & 0xff000000) >> 24))
572 #define SWAP16(x) (x) = \
573 ((((short)(x) & 0x00ff) << 8) | \
574 (((short)(x) & 0xff00) >> 8))
578 #endif /* ifdef CONV8 */
581 #endif /* ifdef CONV16 */
584 #endif /* ifdef CONV32 */
587 #endif /* ifdef CONV64 */
590 #define CONV16(x) {if (_eet_data_words_bigendian) {SWAP16(x); }}
591 #define CONV32(x) {if (_eet_data_words_bigendian) {SWAP32(x); }}
592 #define CONV64(x) {if (_eet_data_words_bigendian) {SWAP64(x); }}
594 #define IS_SIMPLE_TYPE(Type) (Type > EET_T_UNKNOW && Type < EET_T_LAST)
595 #define IS_POINTER_TYPE(Type) (Type >= EET_T_STRING && Type <= EET_T_NULL)
597 #define POINTER_TYPE_DECODE(Context, \
609 ___r = eet_data_get_unknown(Context, \
613 Type, EET_G_UNKNOWN, \
615 if (!___r) { goto Label; } \
618 #define STRUCT_TYPE_DECODE(Data_Ret, Context, Ed, Ede, Data, Size, SubSize, Label) \
620 Data_Ret = _eet_data_descriptor_decode(Context, \
625 SubSize > 0 ? Data_Ret : NULL, \
627 if (!Data_Ret) { goto Label; } \
630 #define EET_I_STRING 1 << 4
631 #define EET_I_INLINED_STRING 2 << 4
632 #define EET_I_NULL 3 << 4
634 #define EET_MAGIC_VARIANT 0xF1234BC
639 eet_data_get_char(const Eet_Dictionary *ed __UNUSED__,
646 if (((char *)src + sizeof(char)) > (char *)src_end)
657 eet_data_put_char(Eet_Dictionary *ed __UNUSED__,
663 d = (char *)malloc(sizeof(char));
670 *size_ret = sizeof(char);
676 eet_data_get_short(const Eet_Dictionary *ed __UNUSED__,
683 if (((char *)src + sizeof(short)) > (char *)src_end)
686 memcpy(dst, src, sizeof(short));
689 return sizeof(short);
693 eet_data_put_short(Eet_Dictionary *ed __UNUSED__,
699 d = (short *)malloc(sizeof(short));
706 *size_ret = sizeof(short);
712 eet_data_get_int(const Eet_Dictionary *ed __UNUSED__,
719 if (((char *)src + sizeof(int)) > (char *)src_end)
722 memcpy(dst, src, sizeof(int));
729 eet_data_put_int(Eet_Dictionary *ed __UNUSED__,
735 d = (int *)malloc(sizeof(int));
742 *size_ret = sizeof(int);
748 eet_data_get_long_long(const Eet_Dictionary *ed __UNUSED__,
753 unsigned long long *d;
755 if (((char *)src + sizeof(unsigned long long)) > (char *)src_end)
758 memcpy(dst, src, sizeof(unsigned long long));
759 d = (unsigned long long *)dst;
761 return sizeof(unsigned long long);
765 eet_data_put_long_long(Eet_Dictionary *ed __UNUSED__,
769 unsigned long long *s, *d;
771 d = (unsigned long long *)malloc(sizeof(unsigned long long));
775 s = (unsigned long long *)src;
778 *size_ret = sizeof(unsigned long long);
784 eet_data_get_string_hash(const Eet_Dictionary *ed,
792 if (eet_data_get_int(ed, src, src_end, &idx) < 0)
795 return eet_dictionary_string_get_hash(ed, idx);
802 eet_data_get_string(const Eet_Dictionary *ed,
816 if (eet_data_get_int(ed, src, src_end, &idx) < 0)
819 str = eet_dictionary_string_get_char(ed, idx);
824 return eet_dictionary_string_get_size(ed, idx);
835 return strlen(s) + 1;
839 eet_data_put_string(Eet_Dictionary *ed,
851 str = *((const char **)src);
855 idx = eet_dictionary_string_add(ed, str);
859 return eet_data_put_int(ed, &idx, size_ret);
862 s = (char *)(*((char **)src));
871 memcpy(d, s, len + 1);
876 /* ALWAYS INLINED STRING TYPE */
878 eet_data_get_istring(const Eet_Dictionary *ed __UNUSED__,
883 return eet_data_get_string(NULL, src, src_end, dst);
887 eet_data_put_istring(Eet_Dictionary *ed __UNUSED__,
891 return eet_data_put_string(NULL, src, size_ret);
894 /* ALWAYS NULL TYPE */
896 eet_data_get_null(const Eet_Dictionary *ed __UNUSED__,
897 const void *src __UNUSED__,
898 const void *src_end __UNUSED__,
910 eet_data_put_null(Eet_Dictionary *ed __UNUSED__,
911 const void *src __UNUSED__,
919 * Fast lookups of simple doubles/floats.
921 * These aren't properly a cache because they don't store pre-calculated
922 * values, but have a so simple math that is almost as fast.
925 _eet_data_float_cache_get(const char *s,
929 /* fast handle of simple case 0xMp+E*/
930 if ((len == 6) && (s[0] == '0') && (s[1] == 'x') && (s[3] == 'p'))
932 int mantisse = (s[2] >= 'a') ? (s[2] - 'a' + 10) : (s[2] - '0');
933 int exponent = (s[5] - '0');
936 *d = (float)(mantisse << exponent);
938 *d = (float)mantisse / (float)(1 << exponent);
947 _eet_data_double_cache_get(const char *s,
951 /* fast handle of simple case 0xMp+E*/
952 if ((len == 6) && (s[0] == '0') && (s[1] == 'x') && (s[3] == 'p'))
954 int mantisse = (s[2] >= 'a') ? (s[2] - 'a' + 10) : (s[2] - '0');
955 int exponent = (s[5] - '0');
958 *d = (double)(mantisse << exponent);
960 *d = (double)mantisse / (double)(1 << exponent);
970 eet_data_get_float(const Eet_Dictionary *ed,
986 s = (const char *)src;
989 while ((p < (const char *)src_end) && (*p != 0)) {len++; p++; }
991 if (_eet_data_float_cache_get(s, len, d) != 0)
994 if (eina_convert_atod(s, len, &mantisse, &exponent) == EINA_FALSE)
997 *d = (float)ldexp((double)mantisse, exponent);
1002 if (eet_data_get_int(ed, src, src_end, &idx) < 0)
1005 if (!eet_dictionary_string_get_float(ed, idx, d))
1012 eet_data_put_float(Eet_Dictionary *ed,
1019 eina_convert_dtoa((double)(*(float *)src), buf);
1027 d = malloc(len + 1);
1031 memcpy(d, buf, len + 1);
1032 *size_ret = len + 1;
1036 idx = eet_dictionary_string_add(ed, buf);
1040 return eet_data_put_int(ed, &idx, size_ret);
1045 eet_data_get_double(const Eet_Dictionary *ed,
1047 const void *src_end,
1058 long long mantisse = 0;
1062 s = (const char *)src;
1065 while ((p < (const char *)src_end) && (*p != 0)) {len++; p++; }
1067 if (_eet_data_double_cache_get(s, len, d) != 0)
1070 if (eina_convert_atod(s, len, &mantisse, &exponent) == EINA_FALSE)
1073 *d = ldexp((double)mantisse, exponent);
1078 if (eet_data_get_int(ed, src, src_end, &idx) < 0)
1081 if (!eet_dictionary_string_get_double(ed, idx, d))
1088 eet_data_put_double(Eet_Dictionary *ed,
1095 eina_convert_dtoa((double)(*(double *)src), buf);
1103 d = malloc(len + 1);
1107 memcpy(d, buf, len + 1);
1108 *size_ret = len + 1;
1113 idx = eet_dictionary_string_add(ed, buf);
1117 return eet_data_put_int(ed, &idx, size_ret);
1121 eet_data_get_f32p32(const Eet_Dictionary *ed,
1123 const void *src_end,
1129 fp = (Eina_F32p32 *)dst;
1136 s = (const char *)src;
1139 while ((p < (const char *)src_end) && (*p != 0)) { len++; p++; }
1141 if (!(eina_convert_atofp(s, len, fp)))
1147 if (eet_data_get_int(ed, src, src_end, &idx) < 0)
1150 if (!eet_dictionary_string_get_fp(ed, idx, fp))
1157 eet_data_put_f32p32(Eet_Dictionary *ed,
1164 eina_convert_fptoa((Eina_F32p32)(*(Eina_F32p32 *)src), buf);
1172 d = malloc(len + 1);
1176 memcpy(d, buf, len + 1);
1177 *size_ret = len + 1;
1182 idx = eet_dictionary_string_add(ed, buf);
1186 return eet_data_put_int(ed, &idx, size_ret);
1190 eet_data_get_f16p16(const Eet_Dictionary *ed,
1192 const void *src_end,
1198 fp = (Eina_F16p16 *)dst;
1200 if (eet_data_get_f32p32(ed, src, src_end, &tmp) < 0)
1203 *fp = eina_f32p32_to_f16p16(tmp);
1208 eet_data_put_f16p16(Eet_Dictionary *ed,
1214 tmp = eina_f16p16_to_f32p32((Eina_F16p16)(*(Eina_F16p16 *)src));
1215 return eet_data_put_f32p32(ed, &tmp, size_ret);
1219 eet_data_get_f8p24(const Eet_Dictionary *ed,
1221 const void *src_end,
1227 fp = (Eina_F8p24 *)dst;
1229 if (eet_data_get_f32p32(ed, src, src_end, &tmp) < 0)
1232 *fp = eina_f32p32_to_f8p24(tmp);
1237 eet_data_put_f8p24(Eet_Dictionary *ed,
1243 tmp = eina_f8p24_to_f32p32((Eina_F8p24)(*(Eina_F8p24 *)src));
1244 return eet_data_put_f32p32(ed, &tmp, size_ret);
1248 eet_data_get_type(const Eet_Dictionary *ed,
1251 const void *src_end,
1256 ret = eet_basic_codec[type - 1].get(ed, src, src_end, dest);
1260 static inline void *
1261 eet_data_put_type(Eet_Dictionary *ed,
1268 ret = eet_basic_codec[type - 1].put(ed, src, size_ret);
1272 static inline Eina_Bool
1273 eet_data_type_match(int type1,
1279 /* Note: All floating point type are equivalent and could be read
1280 without problem by any other floating point getter. */
1311 * char[4] = "CHnK"; // untyped data ... or
1312 * char[4] = "CHKx"; // typed data - x == type
1314 * int = chunk size (including magic string);
1315 * char[] = chunk magic/name string (0 byte terminated);
1316 * ... sub-chunks (a chunk can contain chuncks recusrively) ...
1318 * ... payload data ...
1323 eet_data_chunk_get(const Eet_Dictionary *ed,
1324 Eet_Data_Chunk *chnk,
1343 if ((s[0] != 'C') || (s[1] != 'H') || (s[2] != 'K'))
1346 chnk->type = (unsigned char)(s[3]);
1347 if (chnk->type >= EET_I_LIMIT)
1350 ((chnk->type - EET_I_LIMIT) & 0xF) + EET_G_UNKNOWN;
1351 switch ((chnk->type - EET_I_LIMIT) & 0xF0)
1353 #define EET_UNMATCH_TYPE(Type) \
1354 case EET_I_ ## Type: chnk->type = EET_T_ ## Type; break;
1356 EET_UNMATCH_TYPE(STRING);
1357 EET_UNMATCH_TYPE(INLINED_STRING);
1358 EET_UNMATCH_TYPE(NULL);
1364 else if (chnk->type > EET_T_LAST)
1366 chnk->group_type = chnk->type;
1367 chnk->type = EET_T_UNKNOW;
1370 chnk->group_type = EET_G_UNKNOWN;
1371 if ((chnk->type >= EET_T_LAST) ||
1372 (chnk->group_type >=
1376 chnk->group_type = 0;
1379 else if ((s[0] != 'C') || (s[1] != 'H') || (s[2] != 'n') || (s[3] != 'K'))
1382 ret1 = eet_data_get_type(ed, EET_T_INT, (s + 4), (s + size), &(chnk->size));
1387 if ((chnk->size < 0) || ((chnk->size + 8) > size))
1390 ret2 = eet_data_get_type(ed, EET_T_STRING, (s + 8), (s + size), &(chnk->name));
1398 chnk->hash = eet_data_get_string_hash(ed, (s + 8), (s + size));
1402 chnk->data = (char *)src + 4 + ret1 + sizeof(int);
1403 chnk->size -= sizeof(int);
1407 chnk->data = (char *)src + 4 + ret1 + chnk->len;
1408 chnk->size -= chnk->len;
1414 static inline Eet_Data_Chunk *
1415 eet_data_chunk_new(void *data,
1421 Eet_Data_Chunk *chnk;
1426 chnk = calloc(1, sizeof(Eet_Data_Chunk));
1430 /* Note: Another security, so older eet library could read file
1431 saved with fixed point value. */
1432 if (type == EET_T_F32P32
1433 || type == EET_T_F16P16
1434 || type == EET_T_F8P24)
1435 type = EET_T_DOUBLE;
1437 chnk->name = strdup(name);
1438 chnk->len = strlen(name) + 1;
1442 chnk->group_type = group_type;
1447 eet_data_chunk_free(Eet_Data_Chunk *chnk)
1455 static inline Eet_Data_Stream *
1456 eet_data_stream_new(void)
1458 Eet_Data_Stream *ds;
1460 ds = calloc(1, sizeof(Eet_Data_Stream));
1468 eet_data_stream_free(Eet_Data_Stream *ds)
1477 eet_data_stream_flush(Eet_Data_Stream *ds)
1483 eet_data_stream_write(Eet_Data_Stream *ds,
1489 if ((ds->pos + size) > ds->size)
1491 ds->data = realloc(ds->data, ds->size + size + 512);
1499 ds->size = ds->size + size + 512;
1503 memcpy(p + ds->pos, data, size);
1508 eet_data_chunk_put(Eet_Dictionary *ed,
1509 Eet_Data_Chunk *chnk,
1510 Eet_Data_Stream *ds)
1517 unsigned char buf[4] = "CHK";
1519 /* disable this check - it will allow empty chunks to be written. this is
1520 * right for corner-cases when y have a struct with empty fields (empty
1521 * strings or empty list ptrs etc.) */
1522 /* if (!chnk->data && chnk->type != EET_T_NULL) return; */
1525 /* eet_data_stream_write(ds, "CHnK", 4);*/
1526 if (chnk->type != EET_T_UNKNOW)
1528 if (chnk->group_type != EET_G_UNKNOWN)
1530 int type = EET_I_LIMIT + chnk->group_type - EET_G_UNKNOWN;
1534 /* Only make sense with pointer type. */
1535 #define EET_MATCH_TYPE(Type) \
1536 case EET_T_ ## Type: type += EET_I_ ## Type; break;
1538 EET_MATCH_TYPE(STRING);
1539 EET_MATCH_TYPE(INLINED_STRING);
1540 EET_MATCH_TYPE(NULL);
1549 buf[3] = chnk->type;
1552 buf[3] = chnk->group_type;
1554 string = eet_data_put_string(ed, &chnk->name, &string_ret);
1558 /* size of chunk payload data + name */
1559 s = chnk->size + string_ret;
1560 size = eet_data_put_int(ed, &s, &size_ret);
1562 /* FIXME: If something goes wrong the resulting file will be corrupted. */
1566 eet_data_stream_write(ds, buf, 4);
1568 /* write chunk length */
1569 eet_data_stream_write(ds, size, size_ret);
1571 /* write chunk name */
1572 eet_data_stream_write(ds, string, string_ret);
1576 eet_data_stream_write(ds, chnk->data, chnk->size);
1586 _eet_descriptor_hash_new(Eet_Data_Descriptor *edd)
1590 edd->elements.hash.size = 1 << 6;
1591 edd->elements.hash.buckets = calloc(
1593 sizeof(Eet_Data_Descriptor_Hash) *
1594 edd->elements.hash.size);
1595 for (i = 0; i < edd->elements.num; i++)
1597 Eet_Data_Element *ede;
1600 ede = &(edd->elements.set[i]);
1601 hash = _eet_hash_gen((char *)ede->name, 6);
1602 if (!edd->elements.hash.buckets[hash].element)
1603 edd->elements.hash.buckets[hash].element = ede;
1606 Eet_Data_Descriptor_Hash *bucket;
1608 bucket = calloc(1, sizeof(Eet_Data_Descriptor_Hash));
1609 bucket->element = ede;
1610 bucket->next = edd->elements.hash.buckets[hash].next;
1611 edd->elements.hash.buckets[hash].next = bucket;
1617 _eet_descriptor_hash_free(Eet_Data_Descriptor *edd)
1621 for (i = 0; i < edd->elements.hash.size; i++)
1623 Eet_Data_Descriptor_Hash *bucket, *pbucket;
1625 bucket = edd->elements.hash.buckets[i].next;
1629 bucket = bucket->next;
1633 if (edd->elements.hash.buckets)
1634 free(edd->elements.hash.buckets);
1637 static Eet_Data_Element *
1638 _eet_descriptor_hash_find(Eet_Data_Descriptor *edd,
1642 Eet_Data_Descriptor_Hash *bucket;
1645 hash = _eet_hash_gen(name, 6);
1649 if (!edd->elements.hash.buckets[hash].element)
1651 When we use the dictionary as a source for chunk name, we will always
1652 have the same pointer in name. It's a good idea to just compare pointer
1653 instead of running strcmp on both string.
1656 if (edd->elements.hash.buckets[hash].element->directory_name_ptr == name)
1657 return edd->elements.hash.buckets[hash].element;
1659 if (!strcmp(edd->elements.hash.buckets[hash].element->name, name))
1661 edd->elements.hash.buckets[hash].element->directory_name_ptr = name;
1662 return edd->elements.hash.buckets[hash].element;
1665 bucket = edd->elements.hash.buckets[hash].next;
1668 if (bucket->element->directory_name_ptr == name)
1669 return bucket->element;
1671 if (!strcmp(bucket->element->name, name))
1673 bucket->element->directory_name_ptr = name;
1674 return bucket->element;
1677 bucket = bucket->next;
1683 _eet_mem_alloc(size_t size)
1685 return calloc(1, size);
1689 _eet_mem_free(void *mem)
1695 _eet_str_alloc(const char *str)
1701 _eet_str_free(const char *str)
1707 _eet_eina_hash_add_alloc(Eina_Hash *hash,
1712 hash = eina_hash_string_small_new(NULL);
1717 eina_hash_add(hash, key, data);
1722 _eet_eina_hash_direct_add_alloc(Eina_Hash *hash,
1727 hash = eina_hash_string_small_new(NULL);
1732 eina_hash_direct_add(hash, key, data);
1737 _eet_str_direct_alloc(const char *str)
1743 _eet_str_direct_free(const char *str __UNUSED__)
1748 _eet_eina_hash_foreach(void *hash,
1749 Eina_Hash_Foreach cb,
1753 eina_hash_foreach(hash, cb, fdata);
1757 _eet_eina_hash_free(void *hash)
1760 eina_hash_free(hash);
1765 eet_eina_stream_data_descriptor_class_set(Eet_Data_Descriptor_Class *eddc,
1766 /* When we change the structure content in the future, we need to handle old structure type too */
1767 unsigned int eddc_size,
1771 if (!eddc || !name || eddc_size != sizeof (Eet_Data_Descriptor_Class))
1776 eddc->version = EET_DATA_DESCRIPTOR_CLASS_VERSION;
1778 eddc->func.mem_alloc = _eet_mem_alloc;
1779 eddc->func.mem_free = _eet_mem_free;
1780 eddc->func.str_alloc = (char *(*)(const char *))eina_stringshare_add;
1781 eddc->func.str_free = eina_stringshare_del;
1782 eddc->func.list_next = (void *(*)(void *))eina_list_next;
1783 eddc->func.list_append = (void *(*)(void *, void *))eina_list_append;
1784 eddc->func.list_data = (void *(*)(void *))eina_list_data_get;
1785 eddc->func.list_free = (void *(*)(void *))eina_list_free;
1786 eddc->func.hash_foreach = (void (*)(void *, int (*)(void *, const char *, void *, void *), void *))_eet_eina_hash_foreach;
1787 eddc->func.hash_add = (void *(*)(void *, const char *, void *))_eet_eina_hash_add_alloc;
1788 eddc->func.hash_free = (void (*)(void *))_eet_eina_hash_free;
1790 /* This will cause an ABI incompatibility */
1791 eddc->func.array_alloc = _eet_mem_alloc;
1792 eddc->func.array_free = _eet_mem_free;
1798 eet_eina_file_data_descriptor_class_set(Eet_Data_Descriptor_Class *eddc,
1799 /* When we change the structure content in the future, we need to handle old structure type too */
1800 unsigned int eddc_size,
1804 if (!eet_eina_stream_data_descriptor_class_set(eddc, eddc_size, name, size))
1807 eddc->version = EET_DATA_DESCRIPTOR_CLASS_VERSION;
1809 eddc->func.hash_add = (void *(*)(void *, const char *, void *))_eet_eina_hash_direct_add_alloc;
1810 eddc->func.str_direct_alloc = _eet_str_direct_alloc;
1811 eddc->func.str_direct_free = _eet_str_direct_free;
1816 static Eet_Data_Descriptor *
1817 _eet_data_descriptor_new(const Eet_Data_Descriptor_Class *eddc,
1820 Eet_Data_Descriptor *edd;
1825 edd = calloc(1, sizeof (Eet_Data_Descriptor));
1829 edd->name = eddc->name;
1831 edd->size = eddc->size;
1832 edd->func.mem_alloc = _eet_mem_alloc;
1833 edd->func.mem_free = _eet_mem_free;
1834 edd->func.str_alloc = _eet_str_alloc;
1835 edd->func.str_free = _eet_str_free;
1836 if (eddc->func.mem_alloc)
1837 edd->func.mem_alloc = eddc->func.mem_alloc;
1839 if (eddc->func.mem_free)
1840 edd->func.mem_free = eddc->func.mem_free;
1842 if (eddc->func.str_alloc)
1843 edd->func.str_alloc = eddc->func.str_alloc;
1845 if (eddc->func.str_free)
1846 edd->func.str_free = eddc->func.str_free;
1848 edd->func.list_next = eddc->func.list_next;
1849 edd->func.list_append = eddc->func.list_append;
1850 edd->func.list_data = eddc->func.list_data;
1851 edd->func.list_free = eddc->func.list_free;
1852 edd->func.hash_foreach = eddc->func.hash_foreach;
1853 edd->func.hash_add = eddc->func.hash_add;
1854 edd->func.hash_free = eddc->func.hash_free;
1856 if (eddc->version > 1 && version > 1)
1858 edd->func.str_direct_alloc = eddc->func.str_direct_alloc;
1859 edd->func.str_direct_free = eddc->func.str_direct_free;
1862 if (eddc->version > 2)
1864 edd->func.type_get = eddc->func.type_get;
1865 edd->func.type_set = eddc->func.type_set;
1868 if (eddc->version > 3)
1870 edd->func.array_alloc = eddc->func.array_alloc;
1871 edd->func.array_free = eddc->func.array_free;
1877 EAPI Eet_Data_Descriptor *
1878 eet_data_descriptor_new(const char *name,
1880 Eet_Descriptor_List_Next_Callback func_list_next,
1881 Eet_Descriptor_List_Append_Callback func_list_append,
1882 Eet_Descriptor_List_Data_Callback func_list_data,
1883 Eet_Descriptor_List_Free_Callback func_list_free,
1884 Eet_Descriptor_Hash_Foreach_Callback func_hash_foreach,
1885 Eet_Descriptor_Hash_Add_Callback func_hash_add,
1886 Eet_Descriptor_Hash_Free_Callback func_hash_free)
1888 Eet_Data_Descriptor_Class eddc;
1893 memset(&eddc, 0, sizeof (Eet_Data_Descriptor_Class));
1899 eddc.func.list_next = func_list_next;
1900 eddc.func.list_append = func_list_append;
1901 eddc.func.list_data = func_list_data;
1902 eddc.func.list_free = func_list_free;
1903 eddc.func.hash_foreach = func_hash_foreach;
1904 eddc.func.hash_add = func_hash_add;
1905 eddc.func.hash_free = func_hash_free;
1907 return _eet_data_descriptor_new(&eddc, 0);
1910 EAPI Eet_Data_Descriptor *
1911 eet_data_descriptor2_new(const Eet_Data_Descriptor_Class *eddc)
1913 return _eet_data_descriptor_new(eddc, 1);
1916 EAPI Eet_Data_Descriptor *
1917 eet_data_descriptor3_new(const Eet_Data_Descriptor_Class *eddc)
1919 return _eet_data_descriptor_new(eddc, 2);
1922 EAPI Eet_Data_Descriptor *
1923 eet_data_descriptor_stream_new(const Eet_Data_Descriptor_Class *eddc)
1925 return _eet_data_descriptor_new(eddc, 1);
1928 EAPI Eet_Data_Descriptor *
1929 eet_data_descriptor_file_new(const Eet_Data_Descriptor_Class *eddc)
1931 return _eet_data_descriptor_new(eddc, 2);
1935 eet_data_descriptor_free(Eet_Data_Descriptor *edd)
1940 _eet_descriptor_hash_free(edd);
1941 if (edd->elements.set)
1942 free(edd->elements.set);
1948 eet_data_descriptor_element_add(Eet_Data_Descriptor *edd,
1954 /* int counter_offset, */
1955 const char *counter_name /* FIXME: Useless should go on a major release */,
1956 Eet_Data_Descriptor *subtype)
1958 Eet_Data_Element *ede;
1959 Eet_Data_Element *tmp;
1961 /* UNION, VARIANT type would not work with simple type, we need a way to map the type. */
1962 if ((group_type == EET_G_UNION
1963 || group_type == EET_G_VARIANT)
1965 (type != EET_T_UNKNOW
1967 || !subtype->func.type_get
1968 || !subtype->func.type_set))
1971 /* VARIANT type will only work if the map only contains EET_G_*, but not UNION, VARIANT and ARRAY. */
1972 if (group_type == EET_G_VARIANT)
1976 for (i = 0; i < subtype->elements.num; ++i)
1977 if (subtype->elements.set[i].type != EET_T_UNKNOW
1978 && subtype->elements.set[i].group_type > EET_G_VAR_ARRAY
1979 && subtype->elements.set[i].group_type < EET_G_UNION)
1982 subtype->unified_type = EINA_TRUE;
1986 && subtype->unified_type
1987 && (type != EET_T_UNKNOW
1988 || group_type < EET_G_UNION))
1991 /* Sanity check done, let allocate ! */
1992 edd->elements.num++;
1993 tmp = realloc(edd->elements.set, edd->elements.num * sizeof(Eet_Data_Element));
1997 edd->elements.set = tmp;
1998 ede = &(edd->elements.set[edd->elements.num - 1]);
2000 ede->directory_name_ptr = NULL;
2003 * We do a special case when we do list,hash or whatever group of simple type.
2004 * Instead of handling it in encode/decode/dump/undump, we create an
2005 * implicit structure with only the simple type.
2007 if ((group_type > EET_G_UNKNOWN)
2008 && (group_type < EET_G_LAST)
2009 && (((type > EET_T_UNKNOW) && (type < EET_T_STRING))
2010 || ((type > EET_T_NULL) && (type < EET_T_LAST)))
2013 subtype = calloc(1, sizeof (Eet_Data_Descriptor));
2017 subtype->name = "implicit";
2018 subtype->size = eet_basic_codec[type - 1].size;
2019 memcpy(&subtype->func, &edd->func, sizeof(subtype->func));
2021 eet_data_descriptor_element_add(subtype,
2022 eet_basic_codec[type - 1].name,
2029 type = EET_T_UNKNOW;
2033 ede->group_type = group_type;
2034 ede->offset = offset;
2036 /* FIXME: For the time being, VAR_ARRAY, UNION and VARIANT will put the counter_offset in count. */
2037 ede->counter_offset = count;
2038 /* ede->counter_offset = counter_offset; */
2039 ede->counter_name = counter_name;
2041 ede->subtype = subtype;
2045 eet_data_read_cipher(Eet_File *ef,
2046 Eet_Data_Descriptor *edd,
2048 const char *cipher_key)
2050 const Eet_Dictionary *ed = NULL;
2051 const void *data = NULL;
2053 Eet_Free_Context context;
2054 int required_free = 0;
2057 ed = eet_dictionary_get(ef);
2060 data = eet_read_direct(ef, name, &size);
2065 data = eet_read_cipher(ef, name, &size, cipher_key);
2070 eet_free_context_init(&context);
2071 data_dec = _eet_data_descriptor_decode(&context, ed, edd, data, size, NULL, 0);
2072 eet_free_context_shutdown(&context);
2081 eet_data_node_read_cipher(Eet_File *ef,
2083 const char *cipher_key)
2085 const Eet_Dictionary *ed = NULL;
2086 const void *data = NULL;
2088 Eet_Free_Context context;
2089 int required_free = 0;
2092 ed = eet_dictionary_get(ef);
2095 data = eet_read_direct(ef, name, &size);
2100 data = eet_read_cipher(ef, name, &size, cipher_key);
2105 eet_free_context_init(&context);
2106 result = _eet_data_descriptor_decode(&context, ed, NULL, data, size, NULL, 0);
2107 eet_free_context_shutdown(&context);
2116 eet_data_read(Eet_File *ef,
2117 Eet_Data_Descriptor *edd,
2120 return eet_data_read_cipher(ef, edd, name, NULL);
2124 eet_data_write_cipher(Eet_File *ef,
2125 Eet_Data_Descriptor *edd,
2127 const char *cipher_key,
2136 ed = eet_dictionary_get(ef);
2138 data_enc = _eet_data_descriptor_encode(ed, edd, data, &size);
2142 val = eet_write_cipher(ef, name, data_enc, size, compress, cipher_key);
2148 eet_data_write(Eet_File *ef,
2149 Eet_Data_Descriptor *edd,
2154 return eet_data_write_cipher(ef, edd, name, NULL, data, compress);
2158 eet_free_context_init(Eet_Free_Context *context)
2162 memset(context, 0, sizeof (Eet_Free_Context));
2163 for (i = 0; i < EET_FREE_COUNT; ++i)
2165 eina_array_step_set(&context->freelist.list[i],
2166 sizeof (context->freelist.list[i]),
2168 eina_array_step_set(&context->freelist_array.list[i],
2169 sizeof (context->freelist.list[i]),
2171 eina_array_step_set(&context->freelist_list.list[i],
2172 sizeof (context->freelist.list[i]),
2174 eina_array_step_set(&context->freelist_hash.list[i],
2175 sizeof (context->freelist.list[i]),
2177 eina_array_step_set(&context->freelist_str.list[i],
2178 sizeof (context->freelist.list[i]),
2180 eina_array_step_set(&context->freelist_direct_str.list[i],
2181 sizeof (context->freelist.list[i]),
2187 eet_free_context_shutdown(Eet_Free_Context *context)
2191 for (i = 0; i < EET_FREE_COUNT; ++i)
2193 eina_array_flush(&context->freelist.list[i]);
2194 eina_array_flush(&context->freelist_array.list[i]);
2195 eina_array_flush(&context->freelist_list.list[i]);
2196 eina_array_flush(&context->freelist_hash.list[i]);
2197 eina_array_flush(&context->freelist_str.list[i]);
2198 eina_array_flush(&context->freelist_direct_str.list[i]);
2203 _eet_free_hash(void *data)
2206 __int64 ptr = (UINT_PTR)data;
2207 #else /* ifdef _WIN64 */
2208 unsigned long ptr = (unsigned long)(data);
2209 #endif /* ifdef _WIN64 */
2217 #if defined (_WIN64) || ((!defined (_WIN32)) && (LONG_BIT != 32))
2222 #endif /* if defined (_WIN64) || ((!defined (_WIN32)) && (LONG_BIT != 32)) */
2228 _eet_free_add(Eet_Free *ef,
2232 Eina_Array_Iterator it;
2236 hash = _eet_free_hash(data);
2238 EINA_ARRAY_ITER_NEXT(&ef->list[hash], i, track, it)
2242 eina_array_push(&ef->list[hash], data);
2247 _eet_free_del(Eet_Free *ef,
2251 Eina_Array_Iterator it;
2255 hash = _eet_free_hash(data);
2257 EINA_ARRAY_ITER_NEXT(&ef->list[hash], i, track, it)
2260 eina_array_data_set(&ef->list[hash], i, NULL);
2268 _eet_free_reset(Eet_Free *ef)
2275 for (i = 0; i < EET_FREE_COUNT; ++i)
2276 eina_array_clean(&ef->list[i]);
2280 _eet_free_ref(Eet_Free *ef)
2286 _eet_free_unref(Eet_Free *ef)
2291 #define _eet_freelist_add(Ctx, Data) _eet_free_add(&Ctx->freelist, Data);
2292 #define _eet_freelist_del(Ctx, Data) _eet_free_del(&Ctx->freelist, Data);
2293 #define _eet_freelist_reset(Ctx) _eet_free_reset(&Ctx->freelist);
2294 #define _eet_freelist_ref(Ctx) _eet_free_ref(&Ctx->freelist);
2295 #define _eet_freelist_unref(Ctx) _eet_free_unref(&Ctx->freelist);
2298 _eet_freelist_free(Eet_Free_Context *context,
2299 Eet_Data_Descriptor *edd)
2302 Eina_Array_Iterator it;
2306 if (context->freelist.ref > 0)
2309 for (j = 0; j < EET_FREE_COUNT; ++j)
2310 EINA_ARRAY_ITER_NEXT(&context->freelist.list[j], i, track, it)
2314 edd->func.mem_free(track);
2318 _eet_free_reset(&context->freelist);
2321 #define _eet_freelist_array_add(Ctx, Data) _eet_free_add(&Ctx->freelist_array, Data);
2322 #define _eet_freelist_array_del(Ctx, Data) _eet_free_del(&Ctx->freelist_array, Data);
2323 #define _eet_freelist_array_reset(Ctx) _eet_free_reset(&Ctx->freelist_array);
2324 #define _eet_freelist_array_ref(Ctx) _eet_free_ref(&Ctx->freelist_array);
2325 #define _eet_freelist_array_unref(Ctx) _eet_free_unref(&Ctx->freelist_array);
2328 _eet_freelist_array_free(Eet_Free_Context *context,
2329 Eet_Data_Descriptor *edd)
2332 Eina_Array_Iterator it;
2336 if (context->freelist_array.ref > 0)
2339 for (j = 0; j < EET_FREE_COUNT; ++j)
2340 EINA_ARRAY_ITER_NEXT(&context->freelist_array.list[j], i, track, it)
2345 if (edd->func.array_free)
2346 edd->func.array_free(track);
2348 edd->func.mem_free(track);
2353 _eet_free_reset(&context->freelist_array);
2356 #define _eet_freelist_list_add(Ctx, Data) _eet_free_add(&Ctx->freelist_list, Data);
2357 #define _eet_freelist_list_del(Ctx, Data) _eet_free_del(&Ctx->freelist_list, Data);
2358 #define _eet_freelist_list_reset(Ctx) _eet_free_reset(&Ctx->freelist_list);
2359 #define _eet_freelist_list_ref(Ctx) _eet_free_ref(&Ctx->freelist_list);
2360 #define _eet_freelist_list_unref(Ctx) _eet_free_unref(&Ctx->freelist_list);
2363 _eet_freelist_list_free(Eet_Free_Context *context,
2364 Eet_Data_Descriptor *edd)
2367 Eina_Array_Iterator it;
2371 if (context->freelist_list.ref > 0)
2374 for (j = 0; j < EET_FREE_COUNT; ++j)
2375 EINA_ARRAY_ITER_NEXT(&context->freelist_list.list[j], i, track, it)
2379 edd->func.list_free(*((void **)(track)));
2381 _eet_free_reset(&context->freelist_list);
2384 #define _eet_freelist_str_add(Ctx, Data) _eet_free_add(&Ctx->freelist_str, Data);
2385 #define _eet_freelist_str_del(Ctx, Data) _eet_free_del(&Ctx->freelist_str, Data);
2386 #define _eet_freelist_str_reset(Ctx) _eet_free_reset(&Ctx->freelist_str);
2387 #define _eet_freelist_str_ref(Ctx) _eet_free_ref(&Ctx->freelist_str);
2388 #define _eet_freelist_str_unref(Ctx) _eet_free_unref(&Ctx->freelist_str);
2391 _eet_freelist_str_free(Eet_Free_Context *context,
2392 Eet_Data_Descriptor *edd)
2395 Eina_Array_Iterator it;
2399 if (context->freelist_str.ref > 0)
2402 for (j = 0; j < EET_FREE_COUNT; ++j)
2403 EINA_ARRAY_ITER_NEXT(&context->freelist_str.list[j], i, track, it)
2407 edd->func.str_free(track);
2411 _eet_free_reset(&context->freelist_str);
2414 #define _eet_freelist_direct_str_add(Ctx, Data) _eet_free_add(&Ctx->freelist_direct_str, Data);
2415 #define _eet_freelist_direct_str_del(Ctx, Data) _eet_free_del(&Ctx->freelist_direct_str, Data);
2416 #define _eet_freelist_direct_str_reset(Ctx) _eet_free_reset(&Ctx->freelist_direct_str);
2417 #define _eet_freelist_direct_str_ref(Ctx) _eet_free_ref(&Ctx->freelist_direct_str);
2418 #define _eet_freelist_direct_str_unref(Ctx) _eet_free_unref(&Ctx->freelist_direct_str);
2421 _eet_freelist_direct_str_free(Eet_Free_Context *context,
2422 Eet_Data_Descriptor *edd)
2425 Eina_Array_Iterator it;
2429 if (context->freelist_direct_str.ref > 0)
2432 for (j = 0; j < EET_FREE_COUNT; ++j)
2433 EINA_ARRAY_ITER_NEXT(&context->freelist_str.list[j], i, track, it)
2437 edd->func.str_direct_free(track);
2441 _eet_free_reset(&context->freelist_direct_str);
2444 #define _eet_freelist_hash_add(Ctx, Data) _eet_free_add(&Ctx->freelist_hash, Data);
2445 #define _eet_freelist_hash_del(Ctx, Data) _eet_free_del(&Ctx->freelist_hash, Data);
2446 #define _eet_freelist_hash_reset(Ctx) _eet_free_reset(&Ctx->freelist_hash);
2447 #define _eet_freelist_hash_ref(Ctx) _eet_free_ref(&Ctx->freelist_hash);
2448 #define _eet_freelist_hash_unref(Ctx) _eet_free_unref(&Ctx->freelist_hash);
2451 _eet_freelist_hash_free(Eet_Free_Context *context,
2452 Eet_Data_Descriptor *edd)
2455 Eina_Array_Iterator it;
2459 if (context->freelist_hash.ref > 0)
2462 for (j = 0; j < EET_FREE_COUNT; ++j)
2463 EINA_ARRAY_ITER_NEXT(&context->freelist_hash.list[j], i, track, it)
2467 edd->func.hash_free(track);
2471 _eet_free_reset(&context->freelist_hash);
2475 _eet_freelist_all_ref(Eet_Free_Context *freelist_context)
2477 _eet_freelist_ref(freelist_context);
2478 _eet_freelist_str_ref(freelist_context);
2479 _eet_freelist_list_ref(freelist_context);
2480 _eet_freelist_hash_ref(freelist_context);
2481 _eet_freelist_direct_str_ref(freelist_context);
2485 _eet_freelist_all_unref(Eet_Free_Context *freelist_context)
2487 _eet_freelist_unref(freelist_context);
2488 _eet_freelist_str_unref(freelist_context);
2489 _eet_freelist_list_unref(freelist_context);
2490 _eet_freelist_hash_unref(freelist_context);
2491 _eet_freelist_direct_str_unref(freelist_context);
2495 eet_data_descriptor_encode_hash_cb(void *hash __UNUSED__,
2496 const char *cipher_key,
2501 Eet_Data_Encode_Hash_Info *edehi;
2502 Eet_Data_Stream *ds;
2503 Eet_Data_Element *ede;
2504 Eet_Data_Chunk *echnk;
2514 data = eet_data_put_type(ed,
2520 echnk = eet_data_chunk_new(data,
2525 eet_data_chunk_put(ed, echnk, ds);
2526 eet_data_chunk_free(echnk);
2531 EET_ASSERT(!((ede->type > EET_T_UNKNOW) && (ede->type < EET_T_STRING)), return );
2534 if (ede->type >= EET_T_STRING)
2535 eet_data_put_unknown(ed, NULL, ede, ds, &hdata);
2539 data = _eet_data_descriptor_encode(ed,
2546 echnk = eet_data_chunk_new(data,
2551 eet_data_chunk_put(ed, echnk, ds);
2552 eet_data_chunk_free(echnk);
2562 _eet_data_dump_token_get(const char *src,
2569 int tlen = 0, tsize = 0;
2571 #define TOK_ADD(x) \
2574 if (tlen >= tsize) \
2577 tok = realloc(tok, tsize); \
2579 tok[tlen - 1] = x; \
2582 for (p = src; *len > 0; p++, (*len)--)
2588 if ((p[0] == '\"') && (p > src) && (p[-1] != '\\'))
2590 else if ((p[0] == '\\') && (*len > 1) &&
2595 else if ((p[0] == '\\') && (p > src) && (p[-1] == '\\'))
2599 else if ((p[0] == '\\') && (*len > 1) && (p[1] == 'n'))
2603 else if ((p[0] == 'n') && (p > src) && (p[-1] == '\\'))
2614 if ((isspace(p[0])) || (p[0] == ';')) /* token ends here */
2625 else if (!((isspace(p[0])) || (p[0] == ';')))
2645 eet_data_encode(Eet_Dictionary *ed,
2646 Eet_Data_Stream *ds,
2653 Eet_Data_Chunk *echnk;
2658 if (group_type != EET_G_UNKNOWN)
2659 if (type >= EET_T_LAST)
2660 type = EET_T_UNKNOW;
2662 echnk = eet_data_chunk_new(data, size, name, type, group_type);
2663 eet_data_chunk_put(ed, echnk, ds);
2664 eet_data_chunk_free(echnk);
2669 _eet_data_dump_encode(int parent_type,
2674 Eet_Data_Chunk *chnk = NULL;
2675 Eet_Data_Stream *ds;
2682 if (_eet_data_words_bigendian == -1)
2684 unsigned long int v;
2686 v = htonl(0x12345678);
2687 if (v == 0x12345678)
2688 _eet_data_words_bigendian = 1;
2690 _eet_data_words_bigendian = 0;
2696 ds = eet_data_stream_new();
2703 for (n = node->values; n; n = n->next)
2705 data = _eet_data_dump_encode(node->type, ed, n, &size);
2708 eet_data_stream_write(ds, data, size);
2715 case EET_G_VAR_ARRAY:
2716 for (child_type = EET_T_NULL, n = node->values; n; n = n->next)
2718 if (n->type != EET_T_NULL)
2720 child_type = n->type;
2725 data = eet_data_put_type(ed,
2737 count = node->count;
2739 for (n = node->values; n; n = n->next)
2746 case EET_T_INLINED_STRING:
2747 data = eet_data_put_type(ed,
2749 &(n->data.value.str),
2766 data = _eet_data_dump_encode(n->type, ed, n, &size);
2780 for (; count; count--)
2791 /* Array is somekind of special case, so we should embed it inside another chunk. */
2792 *size_ret = ds->pos;
2797 eet_data_stream_free(ds);
2803 for (n = node->values; n; n = n->next)
2808 case EET_T_INLINED_STRING:
2809 data = eet_data_put_type(ed,
2811 &(n->data.value.str),
2828 data = _eet_data_dump_encode(node->type, ed, n, &size);
2839 /* List is another somekind of special case, every chunk is embed inside a list chunk. */
2840 *size_ret = ds->pos;
2845 eet_data_stream_free(ds);
2853 data = eet_data_put_type(ed,
2866 /* A Hash without key will not decode correctly. */
2869 for (n = node->values; n; n = n->next)
2874 case EET_T_INLINED_STRING:
2875 data = eet_data_put_type(ed,
2877 &(n->data.value.str),
2894 data = _eet_data_dump_encode(node->type, ed, n, &size);
2905 /* Hash is somekind of special case, so we should embed it inside another chunk. */
2906 *size_ret = ds->pos;
2909 eet_data_stream_flush(ds);
2916 #define EET_DATA_NODE_ENCODE(Eet_Type, Type) \
2918 data = eet_data_put_type(ed, node->type, &(node->data.value.Type), &size); \
2921 eet_data_encode(ed, \
2929 *size_ret = ds->pos; \
2930 eet_data_stream_flush(ds); \
2935 EET_DATA_NODE_ENCODE(EET_T_CHAR, c);
2936 EET_DATA_NODE_ENCODE(EET_T_SHORT, s);
2937 EET_DATA_NODE_ENCODE(EET_T_INT, i);
2938 EET_DATA_NODE_ENCODE(EET_T_LONG_LONG, l);
2939 EET_DATA_NODE_ENCODE(EET_T_FLOAT, f);
2940 EET_DATA_NODE_ENCODE(EET_T_DOUBLE, d);
2941 EET_DATA_NODE_ENCODE(EET_T_UCHAR, uc);
2942 EET_DATA_NODE_ENCODE(EET_T_USHORT, us);
2943 EET_DATA_NODE_ENCODE(EET_T_UINT, ui);
2944 EET_DATA_NODE_ENCODE(EET_T_ULONG_LONG, ul);
2945 EET_DATA_NODE_ENCODE(EET_T_INLINED_STRING, str);
2946 EET_DATA_NODE_ENCODE(EET_T_STRING, str);
2952 if ((node->type >= EET_G_UNKNOWN) && (node->type < EET_G_LAST))
2953 chnk = eet_data_chunk_new(ds->data,
2959 chnk = eet_data_chunk_new(ds->data,
2965 eet_data_stream_flush(ds);
2967 ds = eet_data_stream_new();
2968 eet_data_chunk_put(ed, chnk, ds);
2972 eet_data_stream_flush(ds);
2976 eet_data_chunk_free(chnk);
2982 _eet_data_dump_parse(Eet_Dictionary *ed,
2988 const char *p = NULL;
2993 Eet_Node *node_base = NULL;
2994 Eet_Node *node = NULL;
2995 Eet_Node *n = NULL, *nn = NULL;
2997 /* FIXME; handle parse errors */
2998 #define TOK_GET(t) \
2999 jump = left; t = _eet_data_dump_token_get(p, &left); p += jump - left;
3001 for (p = src; p < (src + size); )
3003 char *tok1, *tok2, *tok3, *tok4;
3008 if (!strcmp(tok1, "group"))
3019 if (!strcmp(tok4, "{"))
3021 /* we have 'group NAM TYP {' */
3035 for (nn = node->values; nn;
3046 n->name = eina_stringshare_add(tok2);
3047 if (!strcmp(tok3, "struct"))
3048 n->type = EET_G_UNKNOWN;
3049 else if (!strcmp(tok3, "array"))
3050 n->type = EET_G_ARRAY;
3051 else if (!strcmp(tok3, "var_array"))
3052 n->type = EET_G_VAR_ARRAY;
3053 else if (!strcmp(tok3, "list"))
3054 n->type = EET_G_LIST;
3055 else if (!strcmp(tok3, "hash"))
3056 n->type = EET_G_HASH;
3059 "ERROR: group type '%s' invalid.",
3075 else if (!strcmp(tok1, "value"))
3086 /* we have 'value NAME TYP XXX' */
3097 for (nn = node->values; nn;
3107 n->name = eina_stringshare_add(tok2);
3108 if (!strcmp(tok3, "char:"))
3110 n->type = EET_T_CHAR;
3111 sscanf(tok4, FMT_CHAR,
3112 &(n->data.value.c));
3114 else if (!strcmp(tok3, "short:"))
3116 n->type = EET_T_SHORT;
3118 &(n->data.value.s));
3120 else if (!strcmp(tok3, "int:"))
3122 n->type = EET_T_INT;
3124 &(n->data.value.i));
3126 else if (!strcmp(tok3, "long_long:"))
3128 n->type = EET_T_LONG_LONG;
3129 sscanf(tok4, FMT_LONG_LONG,
3130 &(n->data.value.l));
3132 else if (!strcmp(tok3, "float:"))
3134 n->type = EET_T_FLOAT;
3136 &(n->data.value.f));
3138 else if (!strcmp(tok3, "double:"))
3140 n->type = EET_T_DOUBLE;
3142 &(n->data.value.d));
3144 else if (!strcmp(tok3, "uchar:"))
3146 n->type = EET_T_UCHAR;
3147 sscanf(tok4, FMT_UCHAR,
3148 &(n->data.value.uc));
3150 else if (!strcmp(tok3, "ushort:"))
3152 n->type = EET_T_USHORT;
3154 &(n->data.value.us));
3156 else if (!strcmp(tok3, "uint:"))
3158 n->type = EET_T_UINT;
3160 &(n->data.value.ui));
3162 else if (!strcmp(tok3, "ulong_long:"))
3164 n->type = EET_T_ULONG_LONG;
3165 sscanf(tok4, FMT_ULONG_LONG,
3166 &(n->data.value.ul));
3168 else if (!strcmp(tok3, "string:"))
3170 n->type = EET_T_STRING;
3172 eina_stringshare_add(tok4);
3174 else if (!strcmp(tok3, "inlined:"))
3176 n->type = EET_T_INLINED_STRING;
3178 eina_stringshare_add(tok4);
3180 else if (!strcmp(tok3, "null"))
3182 n->type = EET_T_NULL;
3183 n->data.value.str = NULL;
3187 "ERROR: value type '%s' invalid.",
3201 else if (!strcmp(tok1, "key"))
3206 /* we have 'key NAME' */
3208 node->key = eina_stringshare_add(tok2);
3213 else if (!strcmp(tok1, "count"))
3218 /* we have a 'count COUNT' */
3220 sscanf(tok2, "%i", &(node->count));
3225 else if (!strcmp(tok1, "}"))
3226 /* we have an end of the group */
3228 node = node->parent;
3236 cdata = _eet_data_dump_encode(EET_G_UNKNOWN, ed, node_base, size_ret);
3237 eet_node_del(node_base);
3243 #define NEXT_CHUNK(P, Size, Echnk, Ed) \
3246 __tmp = Ed ? (int)(sizeof(int) * 2) : Echnk.len + 4; \
3247 P += (4 + Echnk.size + __tmp); \
3248 Size -= (4 + Echnk.size + __tmp); \
3252 _eet_data_descriptor_decode(Eet_Free_Context *context,
3253 const Eet_Dictionary *ed,
3254 Eet_Data_Descriptor *edd,
3255 const void *data_in,
3260 Eet_Node *result = NULL;
3264 Eet_Data_Chunk chnk;
3266 if (_eet_data_words_bigendian == -1)
3268 unsigned long int v;
3270 v = htonl(0x12345678);
3271 if (v == 0x12345678)
3272 _eet_data_words_bigendian = 1;
3274 _eet_data_words_bigendian = 0;
3281 if (size_out <= edd->size)
3286 data = edd->func.mem_alloc(edd->size);
3294 for (i = 0; i < edd->elements.num; i++)
3295 edd->elements.set[i].directory_name_ptr = NULL;
3300 _eet_freelist_all_ref(context);
3301 if (data && !data_out)
3302 _eet_freelist_add(context, data);
3304 memset(&chnk, 0, sizeof(Eet_Data_Chunk));
3305 eet_data_chunk_get(ed, &chnk, data_in, size_in);
3310 if (strcmp(chnk.name, edd->name))
3315 size = size_in - (4 + sizeof(int) * 2);
3317 size = size_in - (4 + 4 + chnk.len);
3321 if (!edd->elements.hash.buckets)
3322 _eet_descriptor_hash_new(edd);
3326 switch (chnk.group_type)
3332 return eet_node_string_new(chnk.name, chnk.data);
3334 case EET_T_INLINED_STRING:
3335 return eet_node_inlined_string_new(chnk.name, chnk.data);
3338 return eet_node_null_new(chnk.name);
3341 result = eet_node_struct_new(chnk.name, NULL);
3345 case EET_G_VAR_ARRAY:
3346 return eet_node_var_array_new(chnk.name, NULL);
3360 Eet_Data_Chunk echnk;
3361 Eet_Data_Element *ede = NULL;
3362 Eet_Node *child = NULL;
3363 int group_type = EET_G_UNKNOWN, type = EET_T_UNKNOW;
3366 /* get next data chunk */
3367 memset(&echnk, 0, sizeof(Eet_Data_Chunk));
3368 eet_data_chunk_get(ed, &echnk, p, size);
3370 goto error; /* FIXME: don't REPLY on edd - work without */
3374 ede = _eet_descriptor_hash_find(edd, echnk.name, echnk.hash);
3377 group_type = ede->group_type;
3379 if ((echnk.type == 0) && (echnk.group_type == 0))
3382 group_type = ede->group_type;
3386 if (IS_SIMPLE_TYPE(echnk.type) &&
3387 eet_data_type_match(echnk.type, ede->type))
3388 /* Needed when converting on the fly from FP to Float */
3390 else if ((echnk.group_type > EET_G_UNKNOWN) &&
3391 (echnk.group_type < EET_G_LAST) &&
3392 (echnk.group_type == ede->group_type))
3393 group_type = echnk.group_type;
3397 /*...... dump to node */
3401 group_type = echnk.group_type;
3404 if (!edd && group_type == EET_G_UNKNOWN && IS_SIMPLE_TYPE(type))
3406 unsigned char dd[128];
3408 ret = eet_data_get_type(ed,
3411 ((char *)echnk.data) + echnk.size,
3416 child = eet_data_node_simple_type(type, echnk.name, dd);
3418 eet_node_struct_append(result, echnk.name, child);
3422 ret = eet_group_codec[group_type - 100].get(
3430 ede ? (void *)(((char *)data) + ede->offset) : (void **)&result,
3438 /* advance to next chunk */
3439 NEXT_CHUNK(p, size, echnk, ed);
3442 _eet_freelist_all_unref(context);
3445 _eet_freelist_str_free(context, edd);
3446 _eet_freelist_direct_str_free(context, edd);
3447 _eet_freelist_list_free(context, edd);
3448 _eet_freelist_hash_free(context, edd);
3449 _eet_freelist_array_free(context, edd);
3450 _eet_freelist_free(context, edd);
3454 _eet_freelist_reset(context);
3455 _eet_freelist_str_reset(context);
3456 _eet_freelist_list_reset(context);
3457 _eet_freelist_hash_reset(context);
3458 _eet_freelist_direct_str_reset(context);
3459 _eet_freelist_array_reset(context);
3468 eet_node_del(result);
3470 _eet_freelist_all_unref(context);
3471 _eet_freelist_str_free(context, edd);
3472 _eet_freelist_direct_str_free(context, edd);
3473 _eet_freelist_list_free(context, edd);
3474 _eet_freelist_hash_free(context, edd);
3475 _eet_freelist_array_free(context, edd);
3476 _eet_freelist_free(context, edd);
3478 /* FIXME: Warn that something goes wrong here. */
3483 eet_data_get_list(Eet_Free_Context *context,
3484 const Eet_Dictionary *ed,
3485 Eet_Data_Descriptor *edd,
3486 Eet_Data_Element *ede,
3487 Eet_Data_Chunk *echnk,
3489 int group_type __UNUSED__,
3494 Eet_Data_Descriptor *subtype = NULL;
3499 EET_ASSERT(!((type > EET_T_UNKNOW) && (type < EET_T_STRING)), return 0);
3503 subtype = ede->subtype;
3505 if (type != ede->type)
3509 ptr = (void **)data;
3513 if (IS_POINTER_TYPE(type))
3514 POINTER_TYPE_DECODE(context,
3525 STRUCT_TYPE_DECODE(data_ret,
3536 list = edd->func.list_append(list, data_ret);
3538 _eet_freelist_list_add(context, ptr);
3541 eet_node_list_append(*((Eet_Node **)data), echnk->name, data_ret);
3550 eet_data_get_hash(Eet_Free_Context *context,
3551 const Eet_Dictionary *ed,
3552 Eet_Data_Descriptor *edd,
3553 Eet_Data_Element *ede,
3554 Eet_Data_Chunk *echnk,
3556 int group_type __UNUSED__,
3564 void *data_ret = NULL;
3567 EET_ASSERT(!((type > EET_T_UNKNOW) && (type < EET_T_STRING)), return 0);
3569 ptr = (void **)data;
3573 ret = eet_data_get_type(ed,
3576 ((char *)echnk->data) + echnk->size,
3584 /* Advance to next chunk */
3585 NEXT_CHUNK((*p), (*size), (*echnk), ed);
3586 memset(echnk, 0, sizeof(Eet_Data_Chunk));
3589 eet_data_chunk_get(ed, echnk, *p, *size);
3594 if ((ede->group_type != echnk->group_type)
3595 || (ede->type != echnk->type))
3598 if (IS_POINTER_TYPE(echnk->type))
3599 POINTER_TYPE_DECODE(context,
3610 STRUCT_TYPE_DECODE(data_ret,
3613 ede ? ede->subtype : NULL,
3621 hash = edd->func.hash_add(hash, key, data_ret);
3623 _eet_freelist_hash_add(context, hash);
3626 eet_node_hash_add(*((Eet_Node **)data), echnk->name, key, data_ret);
3634 /* var arrays and fixed arrays have to
3635 * get all chunks at once. for fixed arrays
3636 * we can get each chunk and increment a
3637 * counter stored on the element itself but
3638 * it wont be thread safe. for var arrays
3639 * we still need a way to get the number of
3640 * elements from the data, so storing the
3641 * number of elements and the element data on
3642 * each chunk is pointless.
3645 eet_data_get_array(Eet_Free_Context *context,
3646 const Eet_Dictionary *ed,
3647 Eet_Data_Descriptor *edd,
3648 Eet_Data_Element *ede,
3649 Eet_Data_Chunk *echnk,
3656 Eina_List *childs = NULL;
3665 EET_ASSERT(!((type > EET_T_UNKNOW) && (type < EET_T_STRING)), return 0);
3668 /* read the number of elements */
3669 ret = eet_data_get_type(ed,
3672 ((char *)echnk->data) + echnk->size,
3681 if (IS_POINTER_TYPE(type))
3682 subsize = eet_basic_codec[ede->type].size;
3684 subsize = ede->subtype->size;
3686 if (group_type == EET_G_VAR_ARRAY)
3688 /* store the number of elements
3689 * on the counter offset */
3690 *(int *)(((char *)data) + ede->count - ede->offset) = count;
3691 /* allocate space for the array of elements */
3692 if (edd->func.array_alloc)
3693 *(void **)ptr = edd->func.array_alloc(count * subsize);
3695 *(void **)ptr = edd->func.mem_alloc(count * subsize);
3700 memset(*(void **)ptr, 0, count * subsize);
3702 _eet_freelist_array_add(context, *(void **)ptr);
3706 /* get all array elements */
3707 for (i = 0; i < count; i++)
3711 /* Advance to next chunk */
3712 NEXT_CHUNK((*p), (*size), (*echnk), ed);
3713 memset(echnk, 0, sizeof(Eet_Data_Chunk));
3715 eet_data_chunk_get(ed, echnk, *p, *size);
3716 if (!echnk->name || strcmp(echnk->name, name) != 0)
3717 goto on_error; /* get the data */
3719 if ((echnk->group_type != group_type)
3720 || ((echnk->type != type) && (echnk->type != EET_T_NULL)))
3724 if ((ede->group_type != echnk->group_type)
3725 || ((echnk->type != ede->type) && (echnk->type != EET_T_NULL)))
3728 /* get the destination pointer */
3731 if (group_type == EET_G_ARRAY)
3732 dst = (char *)ptr + (subsize * i);
3734 dst = *(char **)ptr + (subsize * i);
3737 if (IS_POINTER_TYPE(echnk->type))
3739 void *data_ret = NULL;
3741 POINTER_TYPE_DECODE(context,
3752 memcpy(dst, &data_ret, subsize);
3755 childs = eina_list_append(childs, data_ret);
3759 STRUCT_TYPE_DECODE(dst,
3762 ede ? ede->subtype : NULL,
3769 childs = eina_list_append(childs, dst);
3775 Eet_Node *parent = *((Eet_Node **)data);
3778 if (group_type == EET_G_ARRAY)
3779 array = eet_node_array_new(name, count, childs);
3781 array = eet_node_var_array_new(name, childs);
3786 eet_node_struct_append(parent, name, array);
3792 EINA_LIST_FREE(childs, tmp)
3799 eet_data_put_union(Eet_Dictionary *ed,
3800 Eet_Data_Descriptor *edd __UNUSED__,
3801 Eet_Data_Element *ede,
3802 Eet_Data_Stream *ds,
3805 const char *union_type;
3808 EET_ASSERT(!((ede->type != EET_T_UNKNOW) || (!ede->subtype)), return );
3810 union_type = ede->subtype->func.type_get(
3811 ((char *)data_in) + ede->count - ede->offset,
3817 /* Search the structure of the union to encode. */
3818 for (i = 0; i < ede->subtype->elements.num; ++i)
3819 if (strcmp(ede->subtype->elements.set[i].name, union_type) == 0)
3821 Eet_Data_Element *sede;
3825 /* Yeah we found it ! */
3826 data = eet_data_put_type(ed, EET_T_STRING, &union_type, &size);
3836 sede = &(ede->subtype->elements.set[i]);
3837 data = _eet_data_descriptor_encode(ed,
3855 eet_data_get_union(Eet_Free_Context *context,
3856 const Eet_Dictionary *ed,
3857 Eet_Data_Descriptor *edd __UNUSED__,
3858 Eet_Data_Element *ede,
3859 Eet_Data_Chunk *echnk,
3866 const char *union_type;
3867 void *data_ret = NULL;
3872 ret = eet_data_get_type(ed,
3875 ((char *)echnk->data) + echnk->size,
3880 /* Advance to next chunk */
3881 NEXT_CHUNK((*p), (*size), (*echnk), ed);
3882 memset(echnk, 0, sizeof(Eet_Data_Chunk));
3885 eet_data_chunk_get(ed, echnk, *p, *size);
3891 EET_ASSERT(!(ede->group_type != group_type || ede->type != type),
3894 /* Search the structure of the union to decode */
3895 for (i = 0; i < ede->subtype->elements.num; ++i)
3896 if (strcmp(ede->subtype->elements.set[i].name, union_type) == 0)
3898 Eet_Data_Element *sede;
3901 /* Yeah we found it ! */
3902 sede = &(ede->subtype->elements.set[i]);
3903 EET_ASSERT(sede->subtype, goto on_error);
3905 data_ret = _eet_data_descriptor_decode(context,
3911 sede->subtype->size);
3915 /* Set union type. */
3916 if ((!ed) || (!ede->subtype->func.str_direct_alloc))
3918 ut = ede->subtype->func.str_alloc(union_type);
3919 _eet_freelist_str_add(context, ut);
3923 ut = ede->subtype->func.str_direct_alloc(union_type);
3924 _eet_freelist_direct_str_add(context, ut);
3927 ede->subtype->func.type_set(
3929 ((char *)data) + ede->count -
3938 /* FIXME: generate node structure. */
3939 data_ret = _eet_data_descriptor_decode(context,
3941 echnk->data, echnk->size,
3953 eet_data_put_variant(Eet_Dictionary *ed,
3954 Eet_Data_Descriptor *edd __UNUSED__,
3955 Eet_Data_Element *ede,
3956 Eet_Data_Stream *ds,
3959 const char *union_type;
3961 Eina_Bool unknow = EINA_FALSE;
3965 EET_ASSERT(!((ede->type != EET_T_UNKNOW) || (!ede->subtype)), return );
3967 union_type = ede->subtype->func.type_get(
3968 ((char *)data_in) + ede->count - ede->offset,
3971 if (!union_type && unknow == EINA_FALSE)
3976 /* Handle opaque internal representation */
3977 Eet_Variant_Unknow *evu;
3979 data = eet_data_put_type(ed, EET_T_STRING, &union_type, &size);
3989 evu = (Eet_Variant_Unknow *)data_in;
3990 if (evu && EINA_MAGIC_CHECK(evu, EET_MAGIC_VARIANT))
4000 /* Search the structure of the union to encode. */
4001 for (i = 0; i < ede->subtype->elements.num; ++i)
4002 if (strcmp(ede->subtype->elements.set[i].name, union_type) == 0)
4004 Eet_Data_Element *sede;
4006 /* Yeah we found it ! */
4007 data = eet_data_put_type(ed, EET_T_STRING, &union_type, &size);
4017 sede = &(ede->subtype->elements.set[i]);
4019 if (sede->group_type != EET_G_UNKNOWN)
4021 Eet_Data_Stream *lds;
4023 lds = eet_data_stream_new();
4024 eet_group_codec[sede->group_type - 100].put(ed,
4031 eet_data_encode(ed, ds, lds->data, ede->name, lds->pos,
4032 ede->type, ede->group_type);
4038 eet_data_encode(ed, ds, NULL, ede->name, 0,
4039 EET_T_NULL, ede->group_type);
4041 eet_data_stream_free(lds);
4045 data = _eet_data_descriptor_encode(ed,
4064 eet_data_get_variant(Eet_Free_Context *context,
4065 const Eet_Dictionary *ed,
4066 Eet_Data_Descriptor *edd __UNUSED__,
4067 Eet_Data_Element *ede,
4068 Eet_Data_Chunk *echnk,
4069 int type __UNUSED__,
4070 int group_type __UNUSED__,
4075 const char *union_type;
4076 void *data_ret = NULL;
4081 ret = eet_data_get_type(ed,
4084 ((char *)echnk->data) + echnk->size,
4089 /* Advance to next chunk */
4090 NEXT_CHUNK((*p), (*size), (*echnk), ed);
4091 memset(echnk, 0, sizeof(Eet_Data_Chunk));
4094 eet_data_chunk_get(ed, echnk, *p, *size);
4102 EET_ASSERT(ede->subtype, goto on_error);
4104 if ((!ed) || (!ede->subtype->func.str_direct_alloc))
4106 ut = ede->subtype->func.str_alloc(union_type);
4107 _eet_freelist_str_add(context, ut);
4111 ut = ede->subtype->func.str_direct_alloc(union_type);
4112 _eet_freelist_direct_str_add(context, ut);
4115 /* Search the structure of the union to decode */
4116 for (i = 0; i < ede->subtype->elements.num; ++i)
4117 if (strcmp(ede->subtype->elements.set[i].name, union_type) == 0)
4119 Eet_Data_Element *sede;
4121 /* Yeah we found it ! */
4122 sede = &(ede->subtype->elements.set[i]);
4124 if (sede->group_type != EET_G_UNKNOWN)
4126 Eet_Data_Chunk chnk;
4131 size2 = echnk->size;
4133 /* Didn't find a proper way to provide this
4134 without duplicating code */
4137 memset(&chnk, 0, sizeof(Eet_Data_Chunk));
4138 eet_data_chunk_get(ed, &chnk, p2, size2);
4143 ret = eet_group_codec[sede->group_type - 100].get
4144 (context, ed, sede->subtype, sede, &chnk, sede->type,
4145 sede->group_type, data, &p2, &size2);
4150 /* advance to next chunk */
4151 NEXT_CHUNK(p2, size2, chnk, ed);
4154 /* Put garbage so that we will not put eet_variant_unknow in it */
4155 data_ret = (void *)data;
4157 /* Set variant type. */
4158 ede->subtype->func.type_set
4159 (ut, ((char *)data) + ede->count - ede->offset,
4164 data_ret = _eet_data_descriptor_decode(context,
4173 /* And point to the variant data. */
4174 *(void **)data = data_ret;
4176 /* Set variant type. */
4177 ede->subtype->func.type_set
4178 (ut, ((char *)data) + ede->count - ede->offset, EINA_FALSE);
4184 Eet_Variant_Unknow *evu;
4186 evu = calloc(1, sizeof (Eet_Variant_Unknow) + echnk->size - 1);
4190 evu->size = echnk->size;
4191 memcpy(evu->data, echnk->data, evu->size);
4192 EINA_MAGIC_SET(evu, EET_MAGIC_VARIANT);
4194 /* And point to the opaque internal data scructure */
4195 *(void **)data = evu;
4197 /* Set variant type. */
4198 ede->subtype->func.type_set
4199 (ut, ((char *)data) + ede->count - ede->offset, EINA_TRUE);
4204 /* FIXME: dump node structure. */
4205 data_ret = _eet_data_descriptor_decode(context,
4207 echnk->data, echnk->size,
4219 eet_data_node_simple_type(int type,
4225 #endif /* ifdef EET_T_TYPE */
4227 #define EET_T_TYPE(Eet_Type, Eet_Node_Type, Type) \
4229 return eet_node_ ## Eet_Node_Type ## _new(name, *((Type *)dd)); \
4233 EET_T_TYPE(EET_T_CHAR, char, char);
4234 EET_T_TYPE(EET_T_SHORT, short, short);
4235 EET_T_TYPE(EET_T_INT, int, int);
4236 EET_T_TYPE(EET_T_LONG_LONG, long_long, long long);
4237 EET_T_TYPE(EET_T_FLOAT, float, float);
4238 EET_T_TYPE(EET_T_DOUBLE, double, double);
4239 EET_T_TYPE(EET_T_UCHAR, unsigned_char, unsigned char);
4240 EET_T_TYPE(EET_T_USHORT, unsigned_short, unsigned short);
4241 EET_T_TYPE(EET_T_UINT, unsigned_int, unsigned int);
4242 EET_T_TYPE(EET_T_ULONG_LONG, unsigned_long_long, unsigned long long);
4243 EET_T_TYPE(EET_T_STRING, string, char *);
4244 EET_T_TYPE(EET_T_INLINED_STRING, inlined_string, char *);
4247 return eet_node_null_new(name);
4250 ERR("Unknow type passed to eet_data_node_simple_type");
4256 eet_data_get_unknown(Eet_Free_Context *context,
4257 const Eet_Dictionary *ed,
4258 Eet_Data_Descriptor *edd,
4259 Eet_Data_Element *ede,
4260 Eet_Data_Chunk *echnk,
4262 int group_type __UNUSED__,
4264 char **p __UNUSED__,
4265 int *size __UNUSED__)
4270 if (IS_SIMPLE_TYPE(type))
4272 unsigned char dd[128];
4274 ret = eet_data_get_type(ed,
4277 ((char *)echnk->data) + echnk->size,
4278 edd ? (char *)data : (char *)dd);
4284 Eet_Node **parent = data;
4287 node = eet_data_node_simple_type(type, echnk->name, dd);
4290 eet_node_struct_append(*parent, echnk->name, node);
4296 if (type == EET_T_STRING)
4300 str = (char **)(((char *)data));
4303 if ((!ed) || (!edd->func.str_direct_alloc))
4305 *str = edd->func.str_alloc(*str);
4306 _eet_freelist_str_add(context, *str);
4310 *str = edd->func.str_direct_alloc(*str);
4311 _eet_freelist_direct_str_add(context, *str);
4315 else if (edd && type == EET_T_INLINED_STRING)
4319 str = (char **)(((char *)data));
4322 *str = edd->func.str_alloc(*str);
4323 _eet_freelist_str_add(context, *str);
4330 Eet_Data_Descriptor *subtype;
4332 subtype = ede ? ede->subtype : NULL;
4334 if (subtype || !edd)
4336 Eet_Node **parent = data;
4339 data_ret = _eet_data_descriptor_decode(context,
4350 ptr = (void **)(((char *)data));
4351 *ptr = (void *)data_ret;
4355 Eet_Node *node = data_ret;
4359 node = eet_node_struct_child_new(echnk->name, node);
4360 eet_node_struct_append(*parent, echnk->name, node);
4372 eet_data_put_array(Eet_Dictionary *ed,
4373 Eet_Data_Descriptor *edd __UNUSED__,
4374 Eet_Data_Element *ede,
4375 Eet_Data_Stream *ds,
4385 EET_ASSERT(!((ede->type > EET_T_UNKNOW) && (ede->type < EET_T_STRING)),
4388 if (ede->group_type == EET_G_ARRAY)
4389 count = ede->counter_offset;
4391 count = *(int *)(((char *)data_in) + ede->count - ede->offset);
4394 return; /* Store number of elements */
4396 data = eet_data_put_type(ed, EET_T_INT, &count, &size);
4398 eet_data_encode(ed, ds, data, ede->name, size, ede->type, ede->group_type);
4400 if (IS_POINTER_TYPE(ede->type))
4401 subsize = eet_basic_codec[ede->type].size;
4403 subsize = ede->subtype->size;
4405 for (j = 0; j < count; j++)
4410 if (ede->group_type == EET_G_ARRAY)
4411 d = (void *)(((char *)data_in) + offset);
4413 d = *(((char **)data_in)) + offset;
4415 if (IS_POINTER_TYPE(ede->type))
4418 eet_data_put_unknown(ed, NULL, ede, ds, d);
4422 data = _eet_data_descriptor_encode(ed, ede->subtype, d, &size);
4434 /* Add a NULL element just to have the correct array layout. */
4448 eet_data_put_unknown(Eet_Dictionary *ed,
4449 Eet_Data_Descriptor *edd __UNUSED__,
4450 Eet_Data_Element *ede,
4451 Eet_Data_Stream *ds,
4457 if (IS_SIMPLE_TYPE(ede->type))
4458 data = eet_data_put_type(ed, ede->type, data_in, &size);
4459 else if (ede->subtype)
4460 if (*((char **)data_in))
4461 data = _eet_data_descriptor_encode(ed,
4463 *((char **)((char *)(data_in))),
4477 eet_data_put_list(Eet_Dictionary *ed,
4478 Eet_Data_Descriptor *edd,
4479 Eet_Data_Element *ede,
4480 Eet_Data_Stream *ds,
4487 EET_ASSERT(!(((ede->type > EET_T_UNKNOW) && (ede->type < EET_T_STRING))
4488 || ((ede->type > EET_T_NULL) && (ede->type < EET_T_LAST))),
4491 l = *((void **)(((char *)data_in)));
4492 for (; l; l = edd->func.list_next(l))
4494 if (IS_POINTER_TYPE(ede->type))
4496 const void *str = edd->func.list_data(l);
4497 eet_data_put_unknown(ed, NULL, ede, ds, &str);
4501 data = _eet_data_descriptor_encode(ed,
4503 edd->func.list_data(l),
4518 eet_data_put_hash(Eet_Dictionary *ed,
4519 Eet_Data_Descriptor *edd,
4520 Eet_Data_Element *ede,
4521 Eet_Data_Stream *ds,
4524 Eet_Data_Encode_Hash_Info fdata;
4527 l = *((void **)(((char *)data_in)));
4531 edd->func.hash_foreach(l, eet_data_descriptor_encode_hash_cb, &fdata);
4535 eet_data_dump_cipher(Eet_File *ef,
4537 const char *cipher_key,
4538 Eet_Dump_Callback dumpfunc,
4541 const Eet_Dictionary *ed = NULL;
4542 const void *data = NULL;
4544 Eet_Free_Context context;
4545 int required_free = 0;
4548 ed = eet_dictionary_get(ef);
4551 data = eet_read_direct(ef, name, &size);
4556 data = eet_read_cipher(ef, name, &size, cipher_key);
4561 eet_free_context_init(&context);
4562 result = _eet_data_descriptor_decode(&context, ed, NULL, data, size, NULL, 0);
4563 eet_free_context_shutdown(&context);
4565 eet_node_dump(result, 0, dumpfunc, dumpdata);
4567 eet_node_del(result);
4572 return result ? 1 : 0;
4576 eet_data_dump(Eet_File *ef,
4578 Eet_Dump_Callback dumpfunc,
4581 return eet_data_dump_cipher(ef, name, NULL, dumpfunc, dumpdata);
4585 eet_data_text_dump_cipher(const void *data_in,
4586 const char *cipher_key,
4588 Eet_Dump_Callback dumpfunc,
4593 Eet_Free_Context context;
4594 unsigned int ret_len = 0;
4601 if (eet_decipher(data_in, size_in, cipher_key,
4602 strlen(cipher_key), &ret, &ret_len))
4612 ret = (void *)data_in;
4616 eet_free_context_init(&context);
4617 result = _eet_data_descriptor_decode(&context, NULL, NULL, ret, ret_len, NULL, 0);
4618 eet_free_context_shutdown(&context);
4620 eet_node_dump(result, 0, dumpfunc, dumpdata);
4622 eet_node_del(result);
4626 return result ? 1 : 0;
4630 eet_data_text_dump(const void *data_in,
4632 Eet_Dump_Callback dumpfunc,
4635 return eet_data_text_dump_cipher(data_in, NULL, size_in, dumpfunc, dumpdata);
4639 eet_data_text_undump_cipher(const char *text,
4640 const char *cipher_key,
4646 ret = _eet_data_dump_parse(NULL, size_ret, text, textlen);
4647 if (ret && cipher_key)
4649 void *ciphered = NULL;
4650 unsigned int ciphered_len;
4652 if (eet_cipher(ret, *size_ret, cipher_key,
4653 strlen(cipher_key), &ciphered, &ciphered_len))
4664 *size_ret = ciphered_len;
4672 eet_data_text_undump(const char *text,
4676 return eet_data_text_undump_cipher(text, NULL, textlen, size_ret);
4680 eet_data_undump_cipher(Eet_File *ef,
4682 const char *cipher_key,
4692 ed = eet_dictionary_get(ef);
4694 data_enc = _eet_data_dump_parse(ed, &size, text, textlen);
4698 val = eet_write_cipher(ef, name, data_enc, size, compress, cipher_key);
4704 eet_data_undump(Eet_File *ef,
4710 return eet_data_undump_cipher(ef, name, NULL, text, textlen, compress);
4714 eet_data_descriptor_decode_cipher(Eet_Data_Descriptor *edd,
4715 const void *data_in,
4716 const char *cipher_key,
4719 void *deciphered = (void *)data_in;
4721 Eet_Free_Context context;
4722 unsigned int deciphered_len = size_in;
4724 if (cipher_key && data_in)
4725 if (eet_decipher(data_in, size_in, cipher_key,
4726 strlen(cipher_key), &deciphered, &deciphered_len))
4734 eet_free_context_init(&context);
4735 ret = _eet_data_descriptor_decode(&context,
4741 eet_free_context_shutdown(&context);
4743 if (data_in != deciphered)
4750 eet_data_descriptor_decode(Eet_Data_Descriptor *edd,
4751 const void *data_in,
4754 return eet_data_descriptor_decode_cipher(edd, data_in, NULL, size_in);
4758 eet_data_node_decode_cipher(const void *data_in,
4759 const char *cipher_key,
4762 void *deciphered = (void *)data_in;
4764 Eet_Free_Context context;
4765 unsigned int deciphered_len = size_in;
4767 if (cipher_key && data_in)
4768 if (eet_decipher(data_in, size_in, cipher_key,
4769 strlen(cipher_key), &deciphered, &deciphered_len))
4777 eet_free_context_init(&context);
4778 ret = _eet_data_descriptor_decode(&context,
4784 eet_free_context_shutdown(&context);
4786 if (data_in != deciphered)
4793 _eet_data_descriptor_encode(Eet_Dictionary *ed,
4794 Eet_Data_Descriptor *edd,
4795 const void *data_in,
4798 Eet_Data_Stream *ds;
4799 Eet_Data_Chunk *chnk;
4804 if (_eet_data_words_bigendian == -1)
4806 unsigned long int v;
4808 v = htonl(0x12345678);
4809 if (v == 0x12345678)
4810 _eet_data_words_bigendian = 1;
4812 _eet_data_words_bigendian = 0;
4815 ds = eet_data_stream_new();
4816 for (i = 0; i < edd->elements.num; i++)
4818 Eet_Data_Element *ede;
4820 ede = &(edd->elements.set[i]);
4821 eet_group_codec[ede->group_type - 100].put(
4829 chnk = eet_data_chunk_new(ds->data,
4836 eet_data_stream_free(ds);
4838 ds = eet_data_stream_new();
4839 eet_data_chunk_put(ed, chnk, ds);
4845 eet_data_stream_free(ds);
4849 eet_data_chunk_free(chnk);
4855 eet_data_node_write_cipher(Eet_File *ef,
4857 const char *cipher_key,
4866 ed = eet_dictionary_get(ef);
4868 data_enc = _eet_data_dump_encode(EET_G_UNKNOWN, ed, node, &size);
4872 val = eet_write_cipher(ef, name, data_enc, size, compress, cipher_key);
4878 eet_data_node_encode_cipher(Eet_Node *node,
4879 const char *cipher_key,
4883 void *ciphered = NULL;
4884 unsigned int ciphered_len = 0;
4887 ret = _eet_data_dump_encode(EET_G_UNKNOWN, NULL, node, &size);
4888 if (cipher_key && ret)
4890 if (eet_cipher(ret, size, cipher_key,
4891 strlen(cipher_key), &ciphered, &ciphered_len))
4904 size = (int)ciphered_len;
4915 eet_data_descriptor_encode_cipher(Eet_Data_Descriptor *edd,
4916 const void *data_in,
4917 const char *cipher_key,
4921 void *ciphered = NULL;
4922 unsigned int ciphered_len = 0;
4925 ret = _eet_data_descriptor_encode(NULL, edd, data_in, &size);
4926 if (cipher_key && ret)
4928 if (eet_cipher(ret, size, cipher_key,
4929 strlen(cipher_key), &ciphered, &ciphered_len))
4942 size = ciphered_len;
4953 eet_data_descriptor_encode(Eet_Data_Descriptor *edd,
4954 const void *data_in,
4957 return eet_data_descriptor_encode_cipher(edd, data_in, NULL, size_ret);
4961 eet_data_xattr_cipher_get(const char *filename,
4962 const char *attribute,
4963 Eet_Data_Descriptor *edd,
4964 const char *cipher_key)
4970 blob = eina_xattr_get(filename, attribute, &size);
4971 if (!blob) return NULL;
4973 ret = eet_data_descriptor_decode_cipher(edd, blob, cipher_key, size);
4980 eet_data_xattr_cipher_set(const char *filename,
4981 const char *attribute,
4982 Eet_Data_Descriptor *edd,
4983 const char *cipher_key,
4985 Eina_Xattr_Flags flags)
4991 blob = eet_data_descriptor_encode_cipher(edd, data, cipher_key, &size);
4992 if (!blob) return EINA_FALSE;
4994 ret = eina_xattr_set(filename, attribute, blob, size, flags);