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 * routines for doing data -> struct and struct -> data conversion
45 * multiple entries ordered as...
47 * fixed size array [ of basic types ]
48 * variable size array [ of basic types ]
49 * linked list [ of basic types ]
50 * hash table [ of basic types ]
52 * need to provide builder/accessor funcs for:
64 typedef struct _Eet_Data_Element Eet_Data_Element;
65 typedef struct _Eet_Data_Basic_Type_Codec Eet_Data_Basic_Type_Codec;
66 typedef struct _Eet_Data_Group_Type_Codec Eet_Data_Group_Type_Codec;
67 typedef struct _Eet_Data_Chunk Eet_Data_Chunk;
68 typedef struct _Eet_Data_Stream Eet_Data_Stream;
69 typedef struct _Eet_Data_Descriptor_Hash Eet_Data_Descriptor_Hash;
70 typedef struct _Eet_Data_Encode_Hash_Info Eet_Data_Encode_Hash_Info;
71 typedef struct _Eet_Free Eet_Free;
72 typedef struct _Eet_Free_Context Eet_Free_Context;
73 typedef struct _Eet_Variant_Unknow Eet_Variant_Unknow;
78 * Eet_Data_Basic_Type_Codec (Coder, Decoder)
79 * Eet_Data_Group_Type_Codec (Coder, Decoder)
81 struct _Eet_Data_Basic_Type_Codec
85 int (*get)(const Eet_Dictionary *ed,
89 void * (*put)(Eet_Dictionary *ed, const void *src, int *size_ret);
92 struct _Eet_Data_Group_Type_Codec
94 int (*get)(Eet_Free_Context *context,
95 const Eet_Dictionary *ed,
96 Eet_Data_Descriptor *edd,
97 Eet_Data_Element *ede,
98 Eet_Data_Chunk *echnk,
104 void (*put)(Eet_Dictionary *ed,
105 Eet_Data_Descriptor *edd,
106 Eet_Data_Element *ede,
111 struct _Eet_Data_Chunk
119 unsigned char group_type;
122 struct _Eet_Data_Stream
129 struct _Eet_Data_Descriptor_Hash
131 Eet_Data_Element *element;
132 Eet_Data_Descriptor_Hash *next;
135 struct _Eet_Data_Descriptor
138 const Eet_Dictionary *ed;
142 void * (*mem_alloc)(size_t size);
143 void (*mem_free)(void *mem);
144 char * (*str_alloc)(const char *str);
145 char * (*str_direct_alloc)(const char *str);
146 void (*str_free)(const char *str);
147 void (*str_direct_free)(const char *str);
148 void * (*list_next)(void *l);
149 void * (*list_append)(void *l, void *d);
150 void * (*list_data)(void *l);
151 void * (*list_free)(void *l);
152 void (*hash_foreach)(void *h,
158 void * (*hash_add)(void *h, const char *k, void *d);
159 void (*hash_free)(void *h);
160 const char *(*type_get)(const void *data, Eina_Bool *unknow);
161 Eina_Bool (*type_set)(const char *type,
164 void * (*array_alloc)(size_t size);
165 void (*array_free)(void *mem);
170 Eet_Data_Element *set;
174 Eet_Data_Descriptor_Hash *buckets;
178 Eina_Bool unified_type : 1;
183 struct _Eet_Data_Element
186 const char *counter_name;
187 const char *directory_name_ptr;
188 Eet_Data_Descriptor *subtype;
189 int offset; /* offset in bytes from the base element */
190 int count; /* number of elements for a fixed array */
191 int counter_offset; /* for a variable array we need the offset of the count variable */
192 unsigned char type; /* EET_T_XXX */
193 unsigned char group_type; /* EET_G_XXX */
196 struct _Eet_Data_Encode_Hash_Info
199 Eet_Data_Element *ede;
203 #define EET_FREE_COUNT 256
207 Eina_Array list[EET_FREE_COUNT];
210 struct _Eet_Free_Context
213 Eet_Free freelist_array;
214 Eet_Free freelist_list;
215 Eet_Free freelist_hash;
216 Eet_Free freelist_str;
217 Eet_Free freelist_direct_str;
220 struct _Eet_Variant_Unknow
231 eet_free_context_init(Eet_Free_Context *context);
233 eet_free_context_shutdown(Eet_Free_Context *context);
236 eet_data_get_char(const Eet_Dictionary *ed,
241 eet_data_put_char(Eet_Dictionary *ed,
245 eet_data_get_short(const Eet_Dictionary *ed,
250 eet_data_put_short(Eet_Dictionary *ed,
254 eet_data_get_int(const Eet_Dictionary *ed,
259 eet_data_put_int(Eet_Dictionary *ed,
263 eet_data_get_long_long(const Eet_Dictionary *ed,
268 eet_data_put_long_long(Eet_Dictionary *ed,
272 eet_data_get_float(const Eet_Dictionary *ed,
277 eet_data_put_float(Eet_Dictionary *ed,
281 eet_data_get_double(const Eet_Dictionary *ed,
286 eet_data_put_double(Eet_Dictionary *ed,
290 eet_data_get_f32p32(const Eet_Dictionary *ed,
295 eet_data_put_f32p32(Eet_Dictionary *ed,
299 eet_data_get_f16p16(const Eet_Dictionary *ed,
304 eet_data_put_f16p16(Eet_Dictionary *ed,
308 eet_data_get_f8p24(const Eet_Dictionary *ed,
313 eet_data_put_f8p24(Eet_Dictionary *ed,
317 eet_data_get_string(const Eet_Dictionary *ed,
322 eet_data_put_string(Eet_Dictionary *ed,
326 eet_data_get_istring(const Eet_Dictionary *ed,
331 eet_data_put_istring(Eet_Dictionary *ed,
335 eet_data_get_null(const Eet_Dictionary *ed,
340 eet_data_put_null(Eet_Dictionary *ed,
345 eet_data_get_type(const Eet_Dictionary *ed,
351 eet_data_put_type(Eet_Dictionary *ed,
357 eet_data_node_simple_type(int type,
362 eet_data_get_unknown(Eet_Free_Context *context,
363 const Eet_Dictionary *ed,
364 Eet_Data_Descriptor *edd,
365 Eet_Data_Element *ede,
366 Eet_Data_Chunk *echnk,
373 eet_data_put_unknown(Eet_Dictionary *ed,
374 Eet_Data_Descriptor *edd,
375 Eet_Data_Element *ede,
379 eet_data_put_array(Eet_Dictionary *ed,
380 Eet_Data_Descriptor *edd,
381 Eet_Data_Element *ede,
385 eet_data_get_array(Eet_Free_Context *context,
386 const Eet_Dictionary *ed,
387 Eet_Data_Descriptor *edd,
388 Eet_Data_Element *ede,
389 Eet_Data_Chunk *echnk,
396 eet_data_get_list(Eet_Free_Context *context,
397 const Eet_Dictionary *ed,
398 Eet_Data_Descriptor *edd,
399 Eet_Data_Element *ede,
400 Eet_Data_Chunk *echnk,
407 eet_data_put_list(Eet_Dictionary *ed,
408 Eet_Data_Descriptor *edd,
409 Eet_Data_Element *ede,
413 eet_data_put_hash(Eet_Dictionary *ed,
414 Eet_Data_Descriptor *edd,
415 Eet_Data_Element *ede,
419 eet_data_get_hash(Eet_Free_Context *context,
420 const Eet_Dictionary *ed,
421 Eet_Data_Descriptor *edd,
422 Eet_Data_Element *ede,
423 Eet_Data_Chunk *echnk,
430 eet_data_put_union(Eet_Dictionary *ed,
431 Eet_Data_Descriptor *edd,
432 Eet_Data_Element *ede,
436 eet_data_get_union(Eet_Free_Context *context,
437 const Eet_Dictionary *ed,
438 Eet_Data_Descriptor *edd,
439 Eet_Data_Element *ede,
440 Eet_Data_Chunk *echnk,
447 eet_data_put_variant(Eet_Dictionary *ed,
448 Eet_Data_Descriptor *edd,
449 Eet_Data_Element *ede,
453 eet_data_get_variant(Eet_Free_Context *context,
454 const Eet_Dictionary *ed,
455 Eet_Data_Descriptor *edd,
456 Eet_Data_Element *ede,
457 Eet_Data_Chunk *echnk,
465 eet_data_chunk_get(const Eet_Dictionary *ed,
466 Eet_Data_Chunk *chnk,
469 static Eet_Data_Chunk *
470 eet_data_chunk_new(void *data,
476 eet_data_chunk_free(Eet_Data_Chunk *chnk);
478 static Eet_Data_Stream *
479 eet_data_stream_new(void);
481 eet_data_stream_write(Eet_Data_Stream *ds,
485 eet_data_stream_free(Eet_Data_Stream *ds);
488 eet_data_chunk_put(Eet_Dictionary *ed,
489 Eet_Data_Chunk *chnk,
490 Eet_Data_Stream *ds);
493 eet_data_descriptor_encode_hash_cb(void *hash,
497 static void *_eet_data_descriptor_encode(Eet_Dictionary *ed,
498 Eet_Data_Descriptor *edd,
501 static void *_eet_data_descriptor_decode(Eet_Free_Context *context,
502 const Eet_Dictionary *ed,
503 Eet_Data_Descriptor *edd,
511 static const Eet_Data_Basic_Type_Codec eet_basic_codec[] =
513 {sizeof(char), "char", eet_data_get_char, eet_data_put_char },
514 {sizeof(short), "short", eet_data_get_short, eet_data_put_short },
515 {sizeof(int), "int", eet_data_get_int, eet_data_put_int },
516 {sizeof(long long), "long_long", eet_data_get_long_long, eet_data_put_long_long},
517 {sizeof(float), "float", eet_data_get_float, eet_data_put_float },
518 {sizeof(double), "double", eet_data_get_double, eet_data_put_double },
519 {sizeof(char), "uchar", eet_data_get_char, eet_data_put_char },
520 {sizeof(short), "ushort", eet_data_get_short, eet_data_put_short },
521 {sizeof(int), "uint", eet_data_get_int, eet_data_put_int },
522 {sizeof(long long), "ulong_long", eet_data_get_long_long, eet_data_put_long_long},
523 {sizeof(char *), "string", eet_data_get_string, eet_data_put_string },
524 {sizeof(char *), "inlined", eet_data_get_istring, eet_data_put_istring },
525 {sizeof(void *), "NULL", eet_data_get_null, eet_data_put_null },
526 {sizeof(Eina_F32p32), "f32p32", eet_data_get_f32p32, eet_data_put_f32p32 },
527 {sizeof(Eina_F16p16), "f16p16", eet_data_get_f16p16, eet_data_put_f16p16 },
528 {sizeof(Eina_F8p24), "f8p24", eet_data_get_f8p24, eet_data_put_f8p24 }
531 static const Eet_Data_Group_Type_Codec eet_group_codec[] =
533 { eet_data_get_unknown, eet_data_put_unknown },
534 { eet_data_get_array, eet_data_put_array },
535 { eet_data_get_array, eet_data_put_array },
536 { eet_data_get_list, eet_data_put_list },
537 { eet_data_get_hash, eet_data_put_hash },
538 { eet_data_get_union, eet_data_put_union },
539 { eet_data_get_variant, eet_data_put_variant }
542 static int _eet_data_words_bigendian = -1;
546 #define SWAP64(x) (x) = \
547 ((((unsigned long long)(x) & 0x00000000000000ffULL) << 56) | \
548 (((unsigned long long)(x) & 0x000000000000ff00ULL) << 40) | \
549 (((unsigned long long)(x) & 0x0000000000ff0000ULL) << 24) | \
550 (((unsigned long long)(x) & 0x00000000ff000000ULL) << 8) | \
551 (((unsigned long long)(x) & 0x000000ff00000000ULL) >> 8) | \
552 (((unsigned long long)(x) & 0x0000ff0000000000ULL) >> 24) | \
553 (((unsigned long long)(x) & 0x00ff000000000000ULL) >> 40) | \
554 (((unsigned long long)(x) & 0xff00000000000000ULL) >> 56))
555 #define SWAP32(x) (x) = \
556 ((((int)(x) & 0x000000ff) << 24) | \
557 (((int)(x) & 0x0000ff00) << 8) | \
558 (((int)(x) & 0x00ff0000) >> 8) | \
559 (((int)(x) & 0xff000000) >> 24))
560 #define SWAP16(x) (x) = \
561 ((((short)(x) & 0x00ff) << 8) | \
562 (((short)(x) & 0xff00) >> 8))
566 #endif /* ifdef CONV8 */
569 #endif /* ifdef CONV16 */
572 #endif /* ifdef CONV32 */
575 #endif /* ifdef CONV64 */
578 #define CONV16(x) {if (_eet_data_words_bigendian) {SWAP16(x); }}
579 #define CONV32(x) {if (_eet_data_words_bigendian) {SWAP32(x); }}
580 #define CONV64(x) {if (_eet_data_words_bigendian) {SWAP64(x); }}
582 #define IS_SIMPLE_TYPE(Type) (Type > EET_T_UNKNOW && Type < EET_T_LAST)
583 #define IS_POINTER_TYPE(Type) (Type >= EET_T_STRING && Type <= EET_T_NULL)
585 #define POINTER_TYPE_DECODE(Context, \
597 ___r = eet_data_get_unknown(Context, \
601 Type, EET_G_UNKNOWN, \
603 if (!___r) { goto Label; } \
606 #define STRUCT_TYPE_DECODE(Data_Ret, Context, Ed, Ede, Data, Size, SubSize, Label) \
608 Data_Ret = _eet_data_descriptor_decode(Context, \
613 SubSize > 0 ? Data_Ret : NULL, \
615 if (!Data_Ret) { goto Label; } \
618 #define EET_I_STRING 1 << 4
619 #define EET_I_INLINED_STRING 2 << 4
620 #define EET_I_NULL 3 << 4
622 #define EET_MAGIC_VARIANT 0xF1234BC
627 eet_data_get_char(const Eet_Dictionary *ed __UNUSED__,
634 if (((char *)src + sizeof(char)) > (char *)src_end)
645 eet_data_put_char(Eet_Dictionary *ed __UNUSED__,
651 d = (char *)malloc(sizeof(char));
658 *size_ret = sizeof(char);
664 eet_data_get_short(const Eet_Dictionary *ed __UNUSED__,
671 if (((char *)src + sizeof(short)) > (char *)src_end)
674 memcpy(dst, src, sizeof(short));
677 return sizeof(short);
681 eet_data_put_short(Eet_Dictionary *ed __UNUSED__,
687 d = (short *)malloc(sizeof(short));
694 *size_ret = sizeof(short);
700 eet_data_get_int(const Eet_Dictionary *ed __UNUSED__,
707 if (((char *)src + sizeof(int)) > (char *)src_end)
710 memcpy(dst, src, sizeof(int));
717 eet_data_put_int(Eet_Dictionary *ed __UNUSED__,
723 d = (int *)malloc(sizeof(int));
730 *size_ret = sizeof(int);
736 eet_data_get_long_long(const Eet_Dictionary *ed __UNUSED__,
741 unsigned long long *d;
743 if (((char *)src + sizeof(unsigned long long)) > (char *)src_end)
746 memcpy(dst, src, sizeof(unsigned long long));
747 d = (unsigned long long *)dst;
749 return sizeof(unsigned long long);
753 eet_data_put_long_long(Eet_Dictionary *ed __UNUSED__,
757 unsigned long long *s, *d;
759 d = (unsigned long long *)malloc(sizeof(unsigned long long));
763 s = (unsigned long long *)src;
766 *size_ret = sizeof(unsigned long long);
772 eet_data_get_string_hash(const Eet_Dictionary *ed,
780 if (eet_data_get_int(ed, src, src_end, &idx) < 0)
783 return eet_dictionary_string_get_hash(ed, idx);
790 eet_data_get_string(const Eet_Dictionary *ed,
804 if (eet_data_get_int(ed, src, src_end, &idx) < 0)
807 str = eet_dictionary_string_get_char(ed, idx);
812 return eet_dictionary_string_get_size(ed, idx);
823 return strlen(s) + 1;
827 eet_data_put_string(Eet_Dictionary *ed,
839 str = *((const char **)src);
843 idx = eet_dictionary_string_add(ed, str);
847 return eet_data_put_int(ed, &idx, size_ret);
850 s = (char *)(*((char **)src));
859 memcpy(d, s, len + 1);
864 /* ALWAYS INLINED STRING TYPE */
866 eet_data_get_istring(const Eet_Dictionary *ed __UNUSED__,
871 return eet_data_get_string(NULL, src, src_end, dst);
875 eet_data_put_istring(Eet_Dictionary *ed __UNUSED__,
879 return eet_data_put_string(NULL, src, size_ret);
882 /* ALWAYS NULL TYPE */
884 eet_data_get_null(const Eet_Dictionary *ed __UNUSED__,
885 const void *src __UNUSED__,
886 const void *src_end __UNUSED__,
898 eet_data_put_null(Eet_Dictionary *ed __UNUSED__,
899 const void *src __UNUSED__,
907 * Fast lookups of simple doubles/floats.
909 * These aren't properly a cache because they don't store pre-calculated
910 * values, but have a so simple math that is almost as fast.
913 _eet_data_float_cache_get(const char *s,
917 /* fast handle of simple case 0xMp+E*/
918 if ((len == 6) && (s[0] == '0') && (s[1] == 'x') && (s[3] == 'p'))
920 int mantisse = (s[2] >= 'a') ? (s[2] - 'a' + 10) : (s[2] - '0');
921 int exponent = (s[5] - '0');
924 *d = (float)(mantisse << exponent);
926 *d = (float)mantisse / (float)(1 << exponent);
935 _eet_data_double_cache_get(const char *s,
939 /* fast handle of simple case 0xMp+E*/
940 if ((len == 6) && (s[0] == '0') && (s[1] == 'x') && (s[3] == 'p'))
942 int mantisse = (s[2] >= 'a') ? (s[2] - 'a' + 10) : (s[2] - '0');
943 int exponent = (s[5] - '0');
946 *d = (double)(mantisse << exponent);
948 *d = (double)mantisse / (double)(1 << exponent);
958 eet_data_get_float(const Eet_Dictionary *ed,
974 s = (const char *)src;
977 while ((p < (const char *)src_end) && (*p != 0)) {len++; p++; }
979 if (_eet_data_float_cache_get(s, len, d) != 0)
982 if (eina_convert_atod(s, len, &mantisse, &exponent) == EINA_FALSE)
985 *d = (float)ldexp((double)mantisse, exponent);
990 if (eet_data_get_int(ed, src, src_end, &idx) < 0)
993 if (!eet_dictionary_string_get_float(ed, idx, d))
1000 eet_data_put_float(Eet_Dictionary *ed,
1007 eina_convert_dtoa((double)(*(float *)src), buf);
1015 d = malloc(len + 1);
1019 memcpy(d, buf, len + 1);
1020 *size_ret = len + 1;
1024 idx = eet_dictionary_string_add(ed, buf);
1028 return eet_data_put_int(ed, &idx, size_ret);
1033 eet_data_get_double(const Eet_Dictionary *ed,
1035 const void *src_end,
1046 long long mantisse = 0;
1050 s = (const char *)src;
1053 while ((p < (const char *)src_end) && (*p != 0)) {len++; p++; }
1055 if (_eet_data_double_cache_get(s, len, d) != 0)
1058 if (eina_convert_atod(s, len, &mantisse, &exponent) == EINA_FALSE)
1061 *d = ldexp((double)mantisse, exponent);
1066 if (eet_data_get_int(ed, src, src_end, &idx) < 0)
1069 if (!eet_dictionary_string_get_double(ed, idx, d))
1076 eet_data_put_double(Eet_Dictionary *ed,
1083 eina_convert_dtoa((double)(*(double *)src), buf);
1091 d = malloc(len + 1);
1095 memcpy(d, buf, len + 1);
1096 *size_ret = len + 1;
1101 idx = eet_dictionary_string_add(ed, buf);
1105 return eet_data_put_int(ed, &idx, size_ret);
1109 eet_data_get_f32p32(const Eet_Dictionary *ed,
1111 const void *src_end,
1117 fp = (Eina_F32p32 *)dst;
1124 s = (const char *)src;
1127 while ((p < (const char *)src_end) && (*p != 0)) { len++; p++; }
1129 if (!(eina_convert_atofp(s, len, fp)))
1135 if (eet_data_get_int(ed, src, src_end, &idx) < 0)
1138 if (!eet_dictionary_string_get_fp(ed, idx, fp))
1145 eet_data_put_f32p32(Eet_Dictionary *ed,
1152 eina_convert_fptoa((Eina_F32p32)(*(Eina_F32p32 *)src), buf);
1160 d = malloc(len + 1);
1164 memcpy(d, buf, len + 1);
1165 *size_ret = len + 1;
1170 idx = eet_dictionary_string_add(ed, buf);
1174 return eet_data_put_int(ed, &idx, size_ret);
1178 eet_data_get_f16p16(const Eet_Dictionary *ed,
1180 const void *src_end,
1186 fp = (Eina_F16p16 *)dst;
1188 if (eet_data_get_f32p32(ed, src, src_end, &tmp) < 0)
1191 *fp = eina_f32p32_to_f16p16(tmp);
1196 eet_data_put_f16p16(Eet_Dictionary *ed,
1202 tmp = eina_f16p16_to_f32p32((Eina_F16p16)(*(Eina_F16p16 *)src));
1203 return eet_data_put_f32p32(ed, &tmp, size_ret);
1207 eet_data_get_f8p24(const Eet_Dictionary *ed,
1209 const void *src_end,
1215 fp = (Eina_F8p24 *)dst;
1217 if (eet_data_get_f32p32(ed, src, src_end, &tmp) < 0)
1220 *fp = eina_f32p32_to_f8p24(tmp);
1225 eet_data_put_f8p24(Eet_Dictionary *ed,
1231 tmp = eina_f8p24_to_f32p32((Eina_F8p24)(*(Eina_F8p24 *)src));
1232 return eet_data_put_f32p32(ed, &tmp, size_ret);
1236 eet_data_get_type(const Eet_Dictionary *ed,
1239 const void *src_end,
1244 ret = eet_basic_codec[type - 1].get(ed, src, src_end, dest);
1248 static inline void *
1249 eet_data_put_type(Eet_Dictionary *ed,
1256 ret = eet_basic_codec[type - 1].put(ed, src, size_ret);
1260 static inline Eina_Bool
1261 eet_data_type_match(int type1,
1267 /* Note: All floating point type are equivalent and could be read
1268 without problem by any other floating point getter. */
1299 * char[4] = "CHnK"; // untyped data ... or
1300 * char[4] = "CHKx"; // typed data - x == type
1302 * int = chunk size (including magic string);
1303 * char[] = chunk magic/name string (0 byte terminated);
1304 * ... sub-chunks (a chunk can contain chuncks recusrively) ...
1306 * ... payload data ...
1311 eet_data_chunk_get(const Eet_Dictionary *ed,
1312 Eet_Data_Chunk *chnk,
1331 if ((s[0] != 'C') || (s[1] != 'H') || (s[2] != 'K'))
1334 chnk->type = (unsigned char)(s[3]);
1335 if (chnk->type >= EET_I_LIMIT)
1338 ((chnk->type - EET_I_LIMIT) & 0xF) + EET_G_UNKNOWN;
1339 switch ((chnk->type - EET_I_LIMIT) & 0xF0)
1341 #define EET_UNMATCH_TYPE(Type) \
1342 case EET_I_ ## Type: chnk->type = EET_T_ ## Type; break;
1344 EET_UNMATCH_TYPE(STRING);
1345 EET_UNMATCH_TYPE(INLINED_STRING);
1346 EET_UNMATCH_TYPE(NULL);
1352 else if (chnk->type > EET_T_LAST)
1354 chnk->group_type = chnk->type;
1355 chnk->type = EET_T_UNKNOW;
1358 chnk->group_type = EET_G_UNKNOWN;
1359 if ((chnk->type >= EET_T_LAST) ||
1360 (chnk->group_type >=
1364 chnk->group_type = 0;
1367 else if ((s[0] != 'C') || (s[1] != 'H') || (s[2] != 'n') || (s[3] != 'K'))
1370 ret1 = eet_data_get_type(ed, EET_T_INT, (s + 4), (s + size), &(chnk->size));
1375 if ((chnk->size < 0) || ((chnk->size + 8) > size))
1378 ret2 = eet_data_get_type(ed, EET_T_STRING, (s + 8), (s + size), &(chnk->name));
1386 chnk->hash = eet_data_get_string_hash(ed, (s + 8), (s + size));
1390 chnk->data = (char *)src + 4 + ret1 + sizeof(int);
1391 chnk->size -= sizeof(int);
1395 chnk->data = (char *)src + 4 + ret1 + chnk->len;
1396 chnk->size -= chnk->len;
1402 static inline Eet_Data_Chunk *
1403 eet_data_chunk_new(void *data,
1409 Eet_Data_Chunk *chnk;
1414 chnk = calloc(1, sizeof(Eet_Data_Chunk));
1418 /* Note: Another security, so older eet library could read file
1419 saved with fixed point value. */
1420 if (type == EET_T_F32P32
1421 || type == EET_T_F16P16
1422 || type == EET_T_F8P24)
1423 type = EET_T_DOUBLE;
1425 chnk->name = strdup(name);
1426 chnk->len = strlen(name) + 1;
1430 chnk->group_type = group_type;
1435 eet_data_chunk_free(Eet_Data_Chunk *chnk)
1443 static inline Eet_Data_Stream *
1444 eet_data_stream_new(void)
1446 Eet_Data_Stream *ds;
1448 ds = calloc(1, sizeof(Eet_Data_Stream));
1456 eet_data_stream_free(Eet_Data_Stream *ds)
1465 eet_data_stream_flush(Eet_Data_Stream *ds)
1471 eet_data_stream_write(Eet_Data_Stream *ds,
1477 if ((ds->pos + size) > ds->size)
1479 ds->data = realloc(ds->data, ds->size + size + 512);
1487 ds->size = ds->size + size + 512;
1491 memcpy(p + ds->pos, data, size);
1496 eet_data_chunk_put(Eet_Dictionary *ed,
1497 Eet_Data_Chunk *chnk,
1498 Eet_Data_Stream *ds)
1505 unsigned char buf[4] = "CHK";
1507 /* disable this check - it will allow empty chunks to be written. this is
1508 * right for corner-cases when y have a struct with empty fields (empty
1509 * strings or empty list ptrs etc.) */
1510 /* if (!chnk->data && chnk->type != EET_T_NULL) return; */
1513 /* eet_data_stream_write(ds, "CHnK", 4);*/
1514 if (chnk->type != EET_T_UNKNOW)
1516 if (chnk->group_type != EET_G_UNKNOWN)
1518 int type = EET_I_LIMIT + chnk->group_type - EET_G_UNKNOWN;
1522 /* Only make sense with pointer type. */
1523 #define EET_MATCH_TYPE(Type) \
1524 case EET_T_ ## Type: type += EET_I_ ## Type; break;
1526 EET_MATCH_TYPE(STRING);
1527 EET_MATCH_TYPE(INLINED_STRING);
1528 EET_MATCH_TYPE(NULL);
1537 buf[3] = chnk->type;
1540 buf[3] = chnk->group_type;
1542 string = eet_data_put_string(ed, &chnk->name, &string_ret);
1546 /* size of chunk payload data + name */
1547 s = chnk->size + string_ret;
1548 size = eet_data_put_int(ed, &s, &size_ret);
1550 /* FIXME: If something goes wrong the resulting file will be corrupted. */
1554 eet_data_stream_write(ds, buf, 4);
1556 /* write chunk length */
1557 eet_data_stream_write(ds, size, size_ret);
1559 /* write chunk name */
1560 eet_data_stream_write(ds, string, string_ret);
1564 eet_data_stream_write(ds, chnk->data, chnk->size);
1574 _eet_descriptor_hash_new(Eet_Data_Descriptor *edd)
1578 edd->elements.hash.size = 1 << 6;
1579 edd->elements.hash.buckets = calloc(
1581 sizeof(Eet_Data_Descriptor_Hash) *
1582 edd->elements.hash.size);
1583 for (i = 0; i < edd->elements.num; i++)
1585 Eet_Data_Element *ede;
1588 ede = &(edd->elements.set[i]);
1589 hash = _eet_hash_gen((char *)ede->name, 6);
1590 if (!edd->elements.hash.buckets[hash].element)
1591 edd->elements.hash.buckets[hash].element = ede;
1594 Eet_Data_Descriptor_Hash *bucket;
1596 bucket = calloc(1, sizeof(Eet_Data_Descriptor_Hash));
1597 bucket->element = ede;
1598 bucket->next = edd->elements.hash.buckets[hash].next;
1599 edd->elements.hash.buckets[hash].next = bucket;
1605 _eet_descriptor_hash_free(Eet_Data_Descriptor *edd)
1609 for (i = 0; i < edd->elements.hash.size; i++)
1611 Eet_Data_Descriptor_Hash *bucket, *pbucket;
1613 bucket = edd->elements.hash.buckets[i].next;
1617 bucket = bucket->next;
1621 if (edd->elements.hash.buckets)
1622 free(edd->elements.hash.buckets);
1625 static Eet_Data_Element *
1626 _eet_descriptor_hash_find(Eet_Data_Descriptor *edd,
1630 Eet_Data_Descriptor_Hash *bucket;
1633 hash = _eet_hash_gen(name, 6);
1637 if (!edd->elements.hash.buckets[hash].element)
1639 When we use the dictionary as a source for chunk name, we will always
1640 have the same pointer in name. It's a good idea to just compare pointer
1641 instead of running strcmp on both string.
1644 if (edd->elements.hash.buckets[hash].element->directory_name_ptr == name)
1645 return edd->elements.hash.buckets[hash].element;
1647 if (!strcmp(edd->elements.hash.buckets[hash].element->name, name))
1649 edd->elements.hash.buckets[hash].element->directory_name_ptr = name;
1650 return edd->elements.hash.buckets[hash].element;
1653 bucket = edd->elements.hash.buckets[hash].next;
1656 if (bucket->element->directory_name_ptr == name)
1657 return bucket->element;
1659 if (!strcmp(bucket->element->name, name))
1661 bucket->element->directory_name_ptr = name;
1662 return bucket->element;
1665 bucket = bucket->next;
1671 _eet_mem_alloc(size_t size)
1673 return calloc(1, size);
1677 _eet_mem_free(void *mem)
1683 _eet_str_alloc(const char *str)
1689 _eet_str_free(const char *str)
1695 _eet_eina_hash_add_alloc(Eina_Hash *hash,
1700 hash = eina_hash_string_small_new(NULL);
1705 eina_hash_add(hash, key, data);
1710 _eet_eina_hash_direct_add_alloc(Eina_Hash *hash,
1715 hash = eina_hash_string_small_new(NULL);
1720 eina_hash_direct_add(hash, key, data);
1725 _eet_str_direct_alloc(const char *str)
1731 _eet_str_direct_free(const char *str __UNUSED__)
1736 _eet_eina_hash_foreach(void *hash,
1737 Eina_Hash_Foreach cb,
1741 eina_hash_foreach(hash, cb, fdata);
1745 _eet_eina_hash_free(void *hash)
1748 eina_hash_free(hash);
1753 eet_eina_stream_data_descriptor_class_set(Eet_Data_Descriptor_Class *eddc,
1754 /* When we change the structure content in the future, we need to handle old structure type too */
1755 unsigned int eddc_size,
1759 if (!eddc || !name || eddc_size != sizeof (Eet_Data_Descriptor_Class))
1764 eddc->version = EET_DATA_DESCRIPTOR_CLASS_VERSION;
1766 eddc->func.mem_alloc = _eet_mem_alloc;
1767 eddc->func.mem_free = _eet_mem_free;
1768 eddc->func.str_alloc = (char *(*)(const char *))eina_stringshare_add;
1769 eddc->func.str_free = eina_stringshare_del;
1770 eddc->func.list_next = (void *(*)(void *))eina_list_next;
1771 eddc->func.list_append = (void *(*)(void *, void *))eina_list_append;
1772 eddc->func.list_data = (void *(*)(void *))eina_list_data_get;
1773 eddc->func.list_free = (void *(*)(void *))eina_list_free;
1774 eddc->func.hash_foreach = (void (*)(void *, int (*)(void *, const char *, void *, void *), void *))_eet_eina_hash_foreach;
1775 eddc->func.hash_add = (void *(*)(void *, const char *, void *))_eet_eina_hash_add_alloc;
1776 eddc->func.hash_free = (void (*)(void *))_eet_eina_hash_free;
1778 /* This will cause an ABI incompatibility */
1779 eddc->func.array_alloc = _eet_mem_alloc;
1780 eddc->func.array_free = _eet_mem_free;
1786 eet_eina_file_data_descriptor_class_set(Eet_Data_Descriptor_Class *eddc,
1787 /* When we change the structure content in the future, we need to handle old structure type too */
1788 unsigned int eddc_size,
1792 if (!eet_eina_stream_data_descriptor_class_set(eddc, eddc_size, name, size))
1795 eddc->version = EET_DATA_DESCRIPTOR_CLASS_VERSION;
1797 eddc->func.hash_add = (void *(*)(void *, const char *, void *))_eet_eina_hash_direct_add_alloc;
1798 eddc->func.str_direct_alloc = _eet_str_direct_alloc;
1799 eddc->func.str_direct_free = _eet_str_direct_free;
1804 static Eet_Data_Descriptor *
1805 _eet_data_descriptor_new(const Eet_Data_Descriptor_Class *eddc,
1808 Eet_Data_Descriptor *edd;
1813 edd = calloc(1, sizeof (Eet_Data_Descriptor));
1817 edd->name = eddc->name;
1819 edd->size = eddc->size;
1820 edd->func.mem_alloc = _eet_mem_alloc;
1821 edd->func.mem_free = _eet_mem_free;
1822 edd->func.str_alloc = _eet_str_alloc;
1823 edd->func.str_free = _eet_str_free;
1824 if (eddc->func.mem_alloc)
1825 edd->func.mem_alloc = eddc->func.mem_alloc;
1827 if (eddc->func.mem_free)
1828 edd->func.mem_free = eddc->func.mem_free;
1830 if (eddc->func.str_alloc)
1831 edd->func.str_alloc = eddc->func.str_alloc;
1833 if (eddc->func.str_free)
1834 edd->func.str_free = eddc->func.str_free;
1836 edd->func.list_next = eddc->func.list_next;
1837 edd->func.list_append = eddc->func.list_append;
1838 edd->func.list_data = eddc->func.list_data;
1839 edd->func.list_free = eddc->func.list_free;
1840 edd->func.hash_foreach = eddc->func.hash_foreach;
1841 edd->func.hash_add = eddc->func.hash_add;
1842 edd->func.hash_free = eddc->func.hash_free;
1844 if (eddc->version > 1 && version > 1)
1846 edd->func.str_direct_alloc = eddc->func.str_direct_alloc;
1847 edd->func.str_direct_free = eddc->func.str_direct_free;
1850 if (eddc->version > 2)
1852 edd->func.type_get = eddc->func.type_get;
1853 edd->func.type_set = eddc->func.type_set;
1856 if (eddc->version > 3)
1858 edd->func.array_alloc = eddc->func.array_alloc;
1859 edd->func.array_free = eddc->func.array_free;
1865 EAPI Eet_Data_Descriptor *
1866 eet_data_descriptor_new(const char *name,
1868 Eet_Descriptor_List_Next_Callback func_list_next,
1869 Eet_Descriptor_List_Append_Callback func_list_append,
1870 Eet_Descriptor_List_Data_Callback func_list_data,
1871 Eet_Descriptor_List_Free_Callback func_list_free,
1872 Eet_Descriptor_Hash_Foreach_Callback func_hash_foreach,
1873 Eet_Descriptor_Hash_Add_Callback func_hash_add,
1874 Eet_Descriptor_Hash_Free_Callback func_hash_free)
1876 Eet_Data_Descriptor_Class eddc;
1881 memset(&eddc, 0, sizeof (Eet_Data_Descriptor_Class));
1887 eddc.func.list_next = func_list_next;
1888 eddc.func.list_append = func_list_append;
1889 eddc.func.list_data = func_list_data;
1890 eddc.func.list_free = func_list_free;
1891 eddc.func.hash_foreach = func_hash_foreach;
1892 eddc.func.hash_add = func_hash_add;
1893 eddc.func.hash_free = func_hash_free;
1895 return _eet_data_descriptor_new(&eddc, 0);
1898 EAPI Eet_Data_Descriptor *
1899 eet_data_descriptor2_new(const Eet_Data_Descriptor_Class *eddc)
1901 return _eet_data_descriptor_new(eddc, 1);
1904 EAPI Eet_Data_Descriptor *
1905 eet_data_descriptor3_new(const Eet_Data_Descriptor_Class *eddc)
1907 return _eet_data_descriptor_new(eddc, 2);
1910 EAPI Eet_Data_Descriptor *
1911 eet_data_descriptor_stream_new(const Eet_Data_Descriptor_Class *eddc)
1913 return _eet_data_descriptor_new(eddc, 1);
1916 EAPI Eet_Data_Descriptor *
1917 eet_data_descriptor_file_new(const Eet_Data_Descriptor_Class *eddc)
1919 return _eet_data_descriptor_new(eddc, 2);
1923 eet_data_descriptor_free(Eet_Data_Descriptor *edd)
1928 _eet_descriptor_hash_free(edd);
1929 if (edd->elements.set)
1930 free(edd->elements.set);
1936 eet_data_descriptor_element_add(Eet_Data_Descriptor *edd,
1942 /* int counter_offset, */
1943 const char *counter_name /* FIXME: Useless should go on a major release */,
1944 Eet_Data_Descriptor *subtype)
1946 Eet_Data_Element *ede;
1947 Eet_Data_Element *tmp;
1949 /* Sanity check to avoid crash later at runtime */
1950 if (type < EET_T_UNKNOW ||
1953 CRIT("Preventing later bug due to unknow type: %i", type);
1958 CRIT("Preventing later buffer underrun : offset = %i", offset);
1961 if (offset > edd->size)
1963 CRIT("Preventing later buffer overrun : offset = %i in a structure of %i bytes", offset, edd->size);
1966 if (group_type == EET_G_UNKNOWN && type != EET_T_UNKNOW)
1968 if (offset + eet_basic_codec[type - 1].size > edd->size)
1970 CRIT("Preventing later buffer overrun : offset = %i, size = %i in a structure of %i bytes", offset, eet_basic_codec[type - 1].size, edd->size);
1974 else if ((offset + sizeof (void*)) > (unsigned int) edd->size)
1976 CRIT("Preventing later buffer overrun : offset = %i, estimated size = %i in a structure of %i bytes", offset, sizeof (void*), edd->size);
1980 /* UNION, VARIANT type would not work with simple type, we need a way to map the type. */
1981 if ((group_type == EET_G_UNION
1982 || group_type == EET_G_VARIANT)
1984 (type != EET_T_UNKNOW
1986 || !subtype->func.type_get
1987 || !subtype->func.type_set))
1990 /* VARIANT type will only work if the map only contains EET_G_*, but not UNION, VARIANT and ARRAY. */
1991 if (group_type == EET_G_VARIANT)
1995 for (i = 0; i < subtype->elements.num; ++i)
1996 if (subtype->elements.set[i].type != EET_T_UNKNOW
1997 && subtype->elements.set[i].group_type > EET_G_VAR_ARRAY
1998 && subtype->elements.set[i].group_type < EET_G_UNION)
2001 subtype->unified_type = EINA_TRUE;
2005 && subtype->unified_type
2006 && (type != EET_T_UNKNOW
2007 || group_type < EET_G_UNION))
2010 /* Sanity check done, let allocate ! */
2011 edd->elements.num++;
2012 tmp = realloc(edd->elements.set, edd->elements.num * sizeof(Eet_Data_Element));
2016 edd->elements.set = tmp;
2017 ede = &(edd->elements.set[edd->elements.num - 1]);
2019 ede->directory_name_ptr = NULL;
2022 * We do a special case when we do list,hash or whatever group of simple type.
2023 * Instead of handling it in encode/decode/dump/undump, we create an
2024 * implicit structure with only the simple type.
2026 if ((group_type > EET_G_UNKNOWN)
2027 && (group_type < EET_G_LAST)
2028 && (((type > EET_T_UNKNOW) && (type < EET_T_STRING))
2029 || ((type > EET_T_NULL) && (type < EET_T_LAST)))
2032 subtype = calloc(1, sizeof (Eet_Data_Descriptor));
2036 subtype->name = "implicit";
2037 subtype->size = eet_basic_codec[type - 1].size;
2038 memcpy(&subtype->func, &edd->func, sizeof(subtype->func));
2040 eet_data_descriptor_element_add(subtype,
2041 eet_basic_codec[type - 1].name,
2048 type = EET_T_UNKNOW;
2052 ede->group_type = group_type;
2053 ede->offset = offset;
2055 /* FIXME: For the time being, VAR_ARRAY, UNION and VARIANT will put the counter_offset in count. */
2056 ede->counter_offset = count;
2057 /* ede->counter_offset = counter_offset; */
2058 ede->counter_name = counter_name;
2060 ede->subtype = subtype;
2064 eet_data_read_cipher(Eet_File *ef,
2065 Eet_Data_Descriptor *edd,
2067 const char *cipher_key)
2069 const Eet_Dictionary *ed = NULL;
2070 const void *data = NULL;
2072 Eet_Free_Context context;
2073 int required_free = 0;
2076 ed = eet_dictionary_get(ef);
2079 data = eet_read_direct(ef, name, &size);
2084 data = eet_read_cipher(ef, name, &size, cipher_key);
2089 eet_free_context_init(&context);
2090 data_dec = _eet_data_descriptor_decode(&context, ed, edd, data, size, NULL, 0);
2091 eet_free_context_shutdown(&context);
2100 eet_data_node_read_cipher(Eet_File *ef,
2102 const char *cipher_key)
2104 const Eet_Dictionary *ed = NULL;
2105 const void *data = NULL;
2107 Eet_Free_Context context;
2108 int required_free = 0;
2111 ed = eet_dictionary_get(ef);
2114 data = eet_read_direct(ef, name, &size);
2119 data = eet_read_cipher(ef, name, &size, cipher_key);
2124 eet_free_context_init(&context);
2125 result = _eet_data_descriptor_decode(&context, ed, NULL, data, size, NULL, 0);
2126 eet_free_context_shutdown(&context);
2135 eet_data_read(Eet_File *ef,
2136 Eet_Data_Descriptor *edd,
2139 return eet_data_read_cipher(ef, edd, name, NULL);
2143 eet_data_write_cipher(Eet_File *ef,
2144 Eet_Data_Descriptor *edd,
2146 const char *cipher_key,
2155 ed = eet_dictionary_get(ef);
2157 data_enc = _eet_data_descriptor_encode(ed, edd, data, &size);
2161 val = eet_write_cipher(ef, name, data_enc, size, comp, cipher_key);
2167 eet_data_write(Eet_File *ef,
2168 Eet_Data_Descriptor *edd,
2173 return eet_data_write_cipher(ef, edd, name, NULL, data, comp);
2177 eet_free_context_init(Eet_Free_Context *context)
2181 memset(context, 0, sizeof (Eet_Free_Context));
2182 for (i = 0; i < EET_FREE_COUNT; ++i)
2184 eina_array_step_set(&context->freelist.list[i],
2185 sizeof (context->freelist.list[i]),
2187 eina_array_step_set(&context->freelist_array.list[i],
2188 sizeof (context->freelist.list[i]),
2190 eina_array_step_set(&context->freelist_list.list[i],
2191 sizeof (context->freelist.list[i]),
2193 eina_array_step_set(&context->freelist_hash.list[i],
2194 sizeof (context->freelist.list[i]),
2196 eina_array_step_set(&context->freelist_str.list[i],
2197 sizeof (context->freelist.list[i]),
2199 eina_array_step_set(&context->freelist_direct_str.list[i],
2200 sizeof (context->freelist.list[i]),
2206 eet_free_context_shutdown(Eet_Free_Context *context)
2210 for (i = 0; i < EET_FREE_COUNT; ++i)
2212 eina_array_flush(&context->freelist.list[i]);
2213 eina_array_flush(&context->freelist_array.list[i]);
2214 eina_array_flush(&context->freelist_list.list[i]);
2215 eina_array_flush(&context->freelist_hash.list[i]);
2216 eina_array_flush(&context->freelist_str.list[i]);
2217 eina_array_flush(&context->freelist_direct_str.list[i]);
2222 _eet_free_hash(void *data)
2225 __int64 ptr = (UINT_PTR)data;
2226 #else /* ifdef _WIN64 */
2227 unsigned long ptr = (unsigned long)(data);
2228 #endif /* ifdef _WIN64 */
2236 #if defined (_WIN64) || ((!defined (_WIN32)) && (LONG_BIT != 32))
2241 #endif /* if defined (_WIN64) || ((!defined (_WIN32)) && (LONG_BIT != 32)) */
2247 _eet_free_add(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)
2261 eina_array_push(&ef->list[hash], data);
2266 _eet_free_del(Eet_Free *ef,
2270 Eina_Array_Iterator it;
2274 hash = _eet_free_hash(data);
2276 EINA_ARRAY_ITER_NEXT(&ef->list[hash], i, track, it)
2279 eina_array_data_set(&ef->list[hash], i, NULL);
2287 _eet_free_reset(Eet_Free *ef)
2294 for (i = 0; i < EET_FREE_COUNT; ++i)
2295 eina_array_clean(&ef->list[i]);
2299 _eet_free_ref(Eet_Free *ef)
2305 _eet_free_unref(Eet_Free *ef)
2310 #define _eet_freelist_add(Ctx, Data) _eet_free_add(&Ctx->freelist, Data);
2311 #define _eet_freelist_del(Ctx, Data) _eet_free_del(&Ctx->freelist, Data);
2312 #define _eet_freelist_reset(Ctx) _eet_free_reset(&Ctx->freelist);
2313 #define _eet_freelist_ref(Ctx) _eet_free_ref(&Ctx->freelist);
2314 #define _eet_freelist_unref(Ctx) _eet_free_unref(&Ctx->freelist);
2317 _eet_freelist_free(Eet_Free_Context *context,
2318 Eet_Data_Descriptor *edd)
2321 Eina_Array_Iterator it;
2325 if (context->freelist.ref > 0)
2328 for (j = 0; j < EET_FREE_COUNT; ++j)
2329 EINA_ARRAY_ITER_NEXT(&context->freelist.list[j], i, track, it)
2333 edd->func.mem_free(track);
2337 _eet_free_reset(&context->freelist);
2340 #define _eet_freelist_array_add(Ctx, Data) _eet_free_add(&Ctx->freelist_array, Data);
2341 #define _eet_freelist_array_del(Ctx, Data) _eet_free_del(&Ctx->freelist_array, Data);
2342 #define _eet_freelist_array_reset(Ctx) _eet_free_reset(&Ctx->freelist_array);
2343 #define _eet_freelist_array_ref(Ctx) _eet_free_ref(&Ctx->freelist_array);
2344 #define _eet_freelist_array_unref(Ctx) _eet_free_unref(&Ctx->freelist_array);
2347 _eet_freelist_array_free(Eet_Free_Context *context,
2348 Eet_Data_Descriptor *edd)
2351 Eina_Array_Iterator it;
2355 if (context->freelist_array.ref > 0)
2358 for (j = 0; j < EET_FREE_COUNT; ++j)
2359 EINA_ARRAY_ITER_NEXT(&context->freelist_array.list[j], i, track, it)
2364 if (edd->func.array_free)
2365 edd->func.array_free(track);
2367 edd->func.mem_free(track);
2372 _eet_free_reset(&context->freelist_array);
2375 #define _eet_freelist_list_add(Ctx, Data) _eet_free_add(&Ctx->freelist_list, Data);
2376 #define _eet_freelist_list_del(Ctx, Data) _eet_free_del(&Ctx->freelist_list, Data);
2377 #define _eet_freelist_list_reset(Ctx) _eet_free_reset(&Ctx->freelist_list);
2378 #define _eet_freelist_list_ref(Ctx) _eet_free_ref(&Ctx->freelist_list);
2379 #define _eet_freelist_list_unref(Ctx) _eet_free_unref(&Ctx->freelist_list);
2382 _eet_freelist_list_free(Eet_Free_Context *context,
2383 Eet_Data_Descriptor *edd)
2386 Eina_Array_Iterator it;
2390 if (context->freelist_list.ref > 0)
2393 for (j = 0; j < EET_FREE_COUNT; ++j)
2394 EINA_ARRAY_ITER_NEXT(&context->freelist_list.list[j], i, track, it)
2398 edd->func.list_free(*((void **)(track)));
2400 _eet_free_reset(&context->freelist_list);
2403 #define _eet_freelist_str_add(Ctx, Data) _eet_free_add(&Ctx->freelist_str, Data);
2404 #define _eet_freelist_str_del(Ctx, Data) _eet_free_del(&Ctx->freelist_str, Data);
2405 #define _eet_freelist_str_reset(Ctx) _eet_free_reset(&Ctx->freelist_str);
2406 #define _eet_freelist_str_ref(Ctx) _eet_free_ref(&Ctx->freelist_str);
2407 #define _eet_freelist_str_unref(Ctx) _eet_free_unref(&Ctx->freelist_str);
2410 _eet_freelist_str_free(Eet_Free_Context *context,
2411 Eet_Data_Descriptor *edd)
2414 Eina_Array_Iterator it;
2418 if (context->freelist_str.ref > 0)
2421 for (j = 0; j < EET_FREE_COUNT; ++j)
2422 EINA_ARRAY_ITER_NEXT(&context->freelist_str.list[j], i, track, it)
2426 edd->func.str_free(track);
2430 _eet_free_reset(&context->freelist_str);
2433 #define _eet_freelist_direct_str_add(Ctx, Data) _eet_free_add(&Ctx->freelist_direct_str, Data);
2434 #define _eet_freelist_direct_str_del(Ctx, Data) _eet_free_del(&Ctx->freelist_direct_str, Data);
2435 #define _eet_freelist_direct_str_reset(Ctx) _eet_free_reset(&Ctx->freelist_direct_str);
2436 #define _eet_freelist_direct_str_ref(Ctx) _eet_free_ref(&Ctx->freelist_direct_str);
2437 #define _eet_freelist_direct_str_unref(Ctx) _eet_free_unref(&Ctx->freelist_direct_str);
2440 _eet_freelist_direct_str_free(Eet_Free_Context *context,
2441 Eet_Data_Descriptor *edd)
2444 Eina_Array_Iterator it;
2448 if (context->freelist_direct_str.ref > 0)
2451 for (j = 0; j < EET_FREE_COUNT; ++j)
2452 EINA_ARRAY_ITER_NEXT(&context->freelist_str.list[j], i, track, it)
2456 edd->func.str_direct_free(track);
2460 _eet_free_reset(&context->freelist_direct_str);
2463 #define _eet_freelist_hash_add(Ctx, Data) _eet_free_add(&Ctx->freelist_hash, Data);
2464 #define _eet_freelist_hash_del(Ctx, Data) _eet_free_del(&Ctx->freelist_hash, Data);
2465 #define _eet_freelist_hash_reset(Ctx) _eet_free_reset(&Ctx->freelist_hash);
2466 #define _eet_freelist_hash_ref(Ctx) _eet_free_ref(&Ctx->freelist_hash);
2467 #define _eet_freelist_hash_unref(Ctx) _eet_free_unref(&Ctx->freelist_hash);
2470 _eet_freelist_hash_free(Eet_Free_Context *context,
2471 Eet_Data_Descriptor *edd)
2474 Eina_Array_Iterator it;
2478 if (context->freelist_hash.ref > 0)
2481 for (j = 0; j < EET_FREE_COUNT; ++j)
2482 EINA_ARRAY_ITER_NEXT(&context->freelist_hash.list[j], i, track, it)
2486 edd->func.hash_free(track);
2490 _eet_free_reset(&context->freelist_hash);
2494 _eet_freelist_all_ref(Eet_Free_Context *freelist_context)
2496 _eet_freelist_ref(freelist_context);
2497 _eet_freelist_str_ref(freelist_context);
2498 _eet_freelist_list_ref(freelist_context);
2499 _eet_freelist_hash_ref(freelist_context);
2500 _eet_freelist_direct_str_ref(freelist_context);
2504 _eet_freelist_all_unref(Eet_Free_Context *freelist_context)
2506 _eet_freelist_unref(freelist_context);
2507 _eet_freelist_str_unref(freelist_context);
2508 _eet_freelist_list_unref(freelist_context);
2509 _eet_freelist_hash_unref(freelist_context);
2510 _eet_freelist_direct_str_unref(freelist_context);
2514 eet_data_descriptor_encode_hash_cb(void *hash __UNUSED__,
2515 const char *cipher_key,
2520 Eet_Data_Encode_Hash_Info *edehi;
2521 Eet_Data_Stream *ds;
2522 Eet_Data_Element *ede;
2523 Eet_Data_Chunk *echnk;
2533 data = eet_data_put_type(ed,
2539 echnk = eet_data_chunk_new(data,
2544 eet_data_chunk_put(ed, echnk, ds);
2545 eet_data_chunk_free(echnk);
2550 EET_ASSERT(!((ede->type > EET_T_UNKNOW) && (ede->type < EET_T_STRING)), return );
2553 if (ede->type >= EET_T_STRING)
2554 eet_data_put_unknown(ed, NULL, ede, ds, &hdata);
2558 data = _eet_data_descriptor_encode(ed,
2565 echnk = eet_data_chunk_new(data,
2570 eet_data_chunk_put(ed, echnk, ds);
2571 eet_data_chunk_free(echnk);
2581 _eet_data_dump_token_get(const char *src,
2588 int tlen = 0, tsize = 0;
2590 #define TOK_ADD(x) \
2593 if (tlen >= tsize) \
2596 tok = realloc(tok, tsize); \
2598 tok[tlen - 1] = x; \
2601 for (p = src; *len > 0; p++, (*len)--)
2607 if ((p[0] == '\"') && (p > src) && (p[-1] != '\\'))
2609 else if ((p[0] == '\\') && (*len > 1) &&
2614 else if ((p[0] == '\\') && (p > src) && (p[-1] == '\\'))
2618 else if ((p[0] == '\\') && (*len > 1) && (p[1] == 'n'))
2622 else if ((p[0] == 'n') && (p > src) && (p[-1] == '\\'))
2633 if ((isspace(p[0])) || (p[0] == ';')) /* token ends here */
2644 else if (!((isspace(p[0])) || (p[0] == ';')))
2664 eet_data_encode(Eet_Dictionary *ed,
2665 Eet_Data_Stream *ds,
2672 Eet_Data_Chunk *echnk;
2677 if (group_type != EET_G_UNKNOWN)
2678 if (type >= EET_T_LAST)
2679 type = EET_T_UNKNOW;
2681 echnk = eet_data_chunk_new(data, size, name, type, group_type);
2682 eet_data_chunk_put(ed, echnk, ds);
2683 eet_data_chunk_free(echnk);
2688 _eet_data_dump_encode(int parent_type,
2693 Eet_Data_Chunk *chnk = NULL;
2694 Eet_Data_Stream *ds;
2701 if (_eet_data_words_bigendian == -1)
2703 unsigned long int v;
2705 v = htonl(0x12345678);
2706 if (v == 0x12345678)
2707 _eet_data_words_bigendian = 1;
2709 _eet_data_words_bigendian = 0;
2715 ds = eet_data_stream_new();
2722 for (n = node->values; n; n = n->next)
2724 data = _eet_data_dump_encode(node->type, ed, n, &size);
2727 eet_data_stream_write(ds, data, size);
2734 case EET_G_VAR_ARRAY:
2735 for (child_type = EET_T_NULL, n = node->values; n; n = n->next)
2737 if (n->type != EET_T_NULL)
2739 child_type = n->type;
2744 data = eet_data_put_type(ed,
2756 count = node->count;
2758 for (n = node->values; n; n = n->next)
2765 case EET_T_INLINED_STRING:
2766 data = eet_data_put_type(ed,
2768 &(n->data.value.str),
2785 data = _eet_data_dump_encode(n->type, ed, n, &size);
2799 for (; count; count--)
2810 /* Array is somekind of special case, so we should embed it inside another chunk. */
2811 *size_ret = ds->pos;
2816 eet_data_stream_free(ds);
2822 for (n = node->values; n; n = n->next)
2827 case EET_T_INLINED_STRING:
2828 data = eet_data_put_type(ed,
2830 &(n->data.value.str),
2847 data = _eet_data_dump_encode(node->type, ed, n, &size);
2858 /* List is another somekind of special case, every chunk is embed inside a list chunk. */
2859 *size_ret = ds->pos;
2864 eet_data_stream_free(ds);
2872 data = eet_data_put_type(ed,
2885 /* A Hash without key will not decode correctly. */
2888 for (n = node->values; n; n = n->next)
2893 case EET_T_INLINED_STRING:
2894 data = eet_data_put_type(ed,
2896 &(n->data.value.str),
2913 data = _eet_data_dump_encode(node->type, ed, n, &size);
2924 /* Hash is somekind of special case, so we should embed it inside another chunk. */
2925 *size_ret = ds->pos;
2928 eet_data_stream_flush(ds);
2935 #define EET_DATA_NODE_ENCODE(Eet_Type, Type) \
2937 data = eet_data_put_type(ed, node->type, &(node->data.value.Type), &size); \
2940 eet_data_encode(ed, \
2948 *size_ret = ds->pos; \
2949 eet_data_stream_flush(ds); \
2954 EET_DATA_NODE_ENCODE(EET_T_CHAR, c);
2955 EET_DATA_NODE_ENCODE(EET_T_SHORT, s);
2956 EET_DATA_NODE_ENCODE(EET_T_INT, i);
2957 EET_DATA_NODE_ENCODE(EET_T_LONG_LONG, l);
2958 EET_DATA_NODE_ENCODE(EET_T_FLOAT, f);
2959 EET_DATA_NODE_ENCODE(EET_T_DOUBLE, d);
2960 EET_DATA_NODE_ENCODE(EET_T_UCHAR, uc);
2961 EET_DATA_NODE_ENCODE(EET_T_USHORT, us);
2962 EET_DATA_NODE_ENCODE(EET_T_UINT, ui);
2963 EET_DATA_NODE_ENCODE(EET_T_ULONG_LONG, ul);
2964 EET_DATA_NODE_ENCODE(EET_T_INLINED_STRING, str);
2965 EET_DATA_NODE_ENCODE(EET_T_STRING, str);
2971 if ((node->type >= EET_G_UNKNOWN) && (node->type < EET_G_LAST))
2972 chnk = eet_data_chunk_new(ds->data,
2978 chnk = eet_data_chunk_new(ds->data,
2984 eet_data_stream_flush(ds);
2986 ds = eet_data_stream_new();
2987 eet_data_chunk_put(ed, chnk, ds);
2991 eet_data_stream_flush(ds);
2995 eet_data_chunk_free(chnk);
3001 _eet_data_dump_parse(Eet_Dictionary *ed,
3007 const char *p = NULL;
3012 Eet_Node *node_base = NULL;
3013 Eet_Node *node = NULL;
3014 Eet_Node *n = NULL, *nn = NULL;
3016 /* FIXME; handle parse errors */
3017 #define TOK_GET(t) \
3018 jump = left; t = _eet_data_dump_token_get(p, &left); p += jump - left;
3020 for (p = src; p < (src + size); )
3022 char *tok1, *tok2, *tok3, *tok4;
3027 if (!strcmp(tok1, "group"))
3038 if (!strcmp(tok4, "{"))
3040 /* we have 'group NAM TYP {' */
3054 for (nn = node->values; nn;
3065 n->name = eina_stringshare_add(tok2);
3066 if (!strcmp(tok3, "struct"))
3067 n->type = EET_G_UNKNOWN;
3068 else if (!strcmp(tok3, "array"))
3069 n->type = EET_G_ARRAY;
3070 else if (!strcmp(tok3, "var_array"))
3071 n->type = EET_G_VAR_ARRAY;
3072 else if (!strcmp(tok3, "list"))
3073 n->type = EET_G_LIST;
3074 else if (!strcmp(tok3, "hash"))
3075 n->type = EET_G_HASH;
3078 "ERROR: group type '%s' invalid.",
3094 else if (!strcmp(tok1, "value"))
3105 /* we have 'value NAME TYP XXX' */
3116 for (nn = node->values; nn;
3126 n->name = eina_stringshare_add(tok2);
3127 if (!strcmp(tok3, "char:"))
3129 n->type = EET_T_CHAR;
3130 sscanf(tok4, "%hhi",
3131 &(n->data.value.c));
3133 else if (!strcmp(tok3, "short:"))
3135 n->type = EET_T_SHORT;
3137 &(n->data.value.s));
3139 else if (!strcmp(tok3, "int:"))
3141 n->type = EET_T_INT;
3143 &(n->data.value.i));
3145 else if (!strcmp(tok3, "long_long:"))
3147 n->type = EET_T_LONG_LONG;
3148 sscanf(tok4, "%lli",
3149 &(n->data.value.l));
3151 else if (!strcmp(tok3, "float:"))
3153 n->type = EET_T_FLOAT;
3155 &(n->data.value.f));
3157 else if (!strcmp(tok3, "double:"))
3159 n->type = EET_T_DOUBLE;
3161 &(n->data.value.d));
3163 else if (!strcmp(tok3, "uchar:"))
3165 n->type = EET_T_UCHAR;
3166 sscanf(tok4, "%hhu",
3167 &(n->data.value.uc));
3169 else if (!strcmp(tok3, "ushort:"))
3171 n->type = EET_T_USHORT;
3173 &(n->data.value.us));
3175 else if (!strcmp(tok3, "uint:"))
3177 n->type = EET_T_UINT;
3179 &(n->data.value.ui));
3181 else if (!strcmp(tok3, "ulong_long:"))
3183 n->type = EET_T_ULONG_LONG;
3184 sscanf(tok4, "%llu",
3185 &(n->data.value.ul));
3187 else if (!strcmp(tok3, "string:"))
3189 n->type = EET_T_STRING;
3191 eina_stringshare_add(tok4);
3193 else if (!strcmp(tok3, "inlined:"))
3195 n->type = EET_T_INLINED_STRING;
3197 eina_stringshare_add(tok4);
3199 else if (!strcmp(tok3, "null"))
3201 n->type = EET_T_NULL;
3202 n->data.value.str = NULL;
3206 "ERROR: value type '%s' invalid.",
3220 else if (!strcmp(tok1, "key"))
3225 /* we have 'key NAME' */
3227 node->key = eina_stringshare_add(tok2);
3232 else if (!strcmp(tok1, "count"))
3237 /* we have a 'count COUNT' */
3239 sscanf(tok2, "%i", &(node->count));
3244 else if (!strcmp(tok1, "}"))
3245 /* we have an end of the group */
3247 node = node->parent;
3255 cdata = _eet_data_dump_encode(EET_G_UNKNOWN, ed, node_base, size_ret);
3256 eet_node_del(node_base);
3262 #define NEXT_CHUNK(P, Size, Echnk, Ed) \
3265 __tmp = Ed ? (int)(sizeof(int) * 2) : Echnk.len + 4; \
3266 P += (4 + Echnk.size + __tmp); \
3267 Size -= (4 + Echnk.size + __tmp); \
3271 _eet_data_descriptor_decode(Eet_Free_Context *context,
3272 const Eet_Dictionary *ed,
3273 Eet_Data_Descriptor *edd,
3274 const void *data_in,
3279 Eet_Node *result = NULL;
3283 Eet_Data_Chunk chnk;
3285 if (_eet_data_words_bigendian == -1)
3287 unsigned long int v;
3289 v = htonl(0x12345678);
3290 if (v == 0x12345678)
3291 _eet_data_words_bigendian = 1;
3293 _eet_data_words_bigendian = 0;
3300 if (size_out <= edd->size)
3305 data = edd->func.mem_alloc(edd->size);
3313 for (i = 0; i < edd->elements.num; i++)
3314 edd->elements.set[i].directory_name_ptr = NULL;
3319 _eet_freelist_all_ref(context);
3320 if (data && !data_out)
3321 _eet_freelist_add(context, data);
3323 memset(&chnk, 0, sizeof(Eet_Data_Chunk));
3324 eet_data_chunk_get(ed, &chnk, data_in, size_in);
3329 if (strcmp(chnk.name, edd->name))
3334 size = size_in - (4 + sizeof(int) * 2);
3336 size = size_in - (4 + 4 + chnk.len);
3340 if (!edd->elements.hash.buckets)
3341 _eet_descriptor_hash_new(edd);
3345 switch (chnk.group_type)
3351 return eet_node_string_new(chnk.name, chnk.data);
3353 case EET_T_INLINED_STRING:
3354 return eet_node_inlined_string_new(chnk.name, chnk.data);
3357 return eet_node_null_new(chnk.name);
3360 result = eet_node_struct_new(chnk.name, NULL);
3364 case EET_G_VAR_ARRAY:
3365 return eet_node_var_array_new(chnk.name, NULL);
3379 Eet_Data_Chunk echnk;
3380 Eet_Data_Element *ede = NULL;
3381 Eet_Node *child = NULL;
3382 int group_type = EET_G_UNKNOWN, type = EET_T_UNKNOW;
3385 /* get next data chunk */
3386 memset(&echnk, 0, sizeof(Eet_Data_Chunk));
3387 eet_data_chunk_get(ed, &echnk, p, size);
3389 goto error; /* FIXME: don't REPLY on edd - work without */
3393 ede = _eet_descriptor_hash_find(edd, echnk.name, echnk.hash);
3396 group_type = ede->group_type;
3398 if ((echnk.type == 0) && (echnk.group_type == 0))
3401 group_type = ede->group_type;
3405 if (IS_SIMPLE_TYPE(echnk.type) &&
3406 eet_data_type_match(echnk.type, ede->type))
3407 /* Needed when converting on the fly from FP to Float */
3409 else if ((echnk.group_type > EET_G_UNKNOWN) &&
3410 (echnk.group_type < EET_G_LAST) &&
3411 (echnk.group_type == ede->group_type))
3412 group_type = echnk.group_type;
3416 /*...... dump to node */
3420 group_type = echnk.group_type;
3423 if (!edd && group_type == EET_G_UNKNOWN && IS_SIMPLE_TYPE(type))
3425 unsigned char dd[128];
3427 ret = eet_data_get_type(ed,
3430 ((char *)echnk.data) + echnk.size,
3435 child = eet_data_node_simple_type(type, echnk.name, dd);
3437 eet_node_struct_append(result, echnk.name, child);
3441 ret = eet_group_codec[group_type - 100].get(
3449 ede ? (void *)(((char *)data) + ede->offset) : (void **)&result,
3457 /* advance to next chunk */
3458 NEXT_CHUNK(p, size, echnk, ed);
3461 _eet_freelist_all_unref(context);
3464 _eet_freelist_str_free(context, edd);
3465 _eet_freelist_direct_str_free(context, edd);
3466 _eet_freelist_list_free(context, edd);
3467 _eet_freelist_hash_free(context, edd);
3468 _eet_freelist_array_free(context, edd);
3469 _eet_freelist_free(context, edd);
3473 _eet_freelist_reset(context);
3474 _eet_freelist_str_reset(context);
3475 _eet_freelist_list_reset(context);
3476 _eet_freelist_hash_reset(context);
3477 _eet_freelist_direct_str_reset(context);
3478 _eet_freelist_array_reset(context);
3487 eet_node_del(result);
3489 _eet_freelist_all_unref(context);
3490 _eet_freelist_str_free(context, edd);
3491 _eet_freelist_direct_str_free(context, edd);
3492 _eet_freelist_list_free(context, edd);
3493 _eet_freelist_hash_free(context, edd);
3494 _eet_freelist_array_free(context, edd);
3495 _eet_freelist_free(context, edd);
3497 /* FIXME: Warn that something goes wrong here. */
3502 eet_data_get_list(Eet_Free_Context *context,
3503 const Eet_Dictionary *ed,
3504 Eet_Data_Descriptor *edd,
3505 Eet_Data_Element *ede,
3506 Eet_Data_Chunk *echnk,
3508 int group_type __UNUSED__,
3513 Eet_Data_Descriptor *subtype = NULL;
3518 EET_ASSERT(!((type > EET_T_UNKNOW) && (type < EET_T_STRING)), return 0);
3522 subtype = ede->subtype;
3524 if (type != ede->type)
3528 ptr = (void **)data;
3532 if (IS_POINTER_TYPE(type))
3533 POINTER_TYPE_DECODE(context,
3544 STRUCT_TYPE_DECODE(data_ret,
3555 list = edd->func.list_append(list, data_ret);
3557 _eet_freelist_list_add(context, ptr);
3560 eet_node_list_append(*((Eet_Node **)data), echnk->name, data_ret);
3569 eet_data_get_hash(Eet_Free_Context *context,
3570 const Eet_Dictionary *ed,
3571 Eet_Data_Descriptor *edd,
3572 Eet_Data_Element *ede,
3573 Eet_Data_Chunk *echnk,
3575 int group_type __UNUSED__,
3583 void *data_ret = NULL;
3586 EET_ASSERT(!((type > EET_T_UNKNOW) && (type < EET_T_STRING)), return 0);
3588 ptr = (void **)data;
3592 ret = eet_data_get_type(ed,
3595 ((char *)echnk->data) + echnk->size,
3603 /* Advance to next chunk */
3604 NEXT_CHUNK((*p), (*size), (*echnk), ed);
3605 memset(echnk, 0, sizeof(Eet_Data_Chunk));
3608 eet_data_chunk_get(ed, echnk, *p, *size);
3613 if ((ede->group_type != echnk->group_type)
3614 || (ede->type != echnk->type))
3617 if (IS_POINTER_TYPE(echnk->type))
3618 POINTER_TYPE_DECODE(context,
3629 STRUCT_TYPE_DECODE(data_ret,
3632 ede ? ede->subtype : NULL,
3640 hash = edd->func.hash_add(hash, key, data_ret);
3642 _eet_freelist_hash_add(context, hash);
3645 eet_node_hash_add(*((Eet_Node **)data), echnk->name, key, data_ret);
3653 /* var arrays and fixed arrays have to
3654 * get all chunks at once. for fixed arrays
3655 * we can get each chunk and increment a
3656 * counter stored on the element itself but
3657 * it wont be thread safe. for var arrays
3658 * we still need a way to get the number of
3659 * elements from the data, so storing the
3660 * number of elements and the element data on
3661 * each chunk is pointless.
3664 eet_data_get_array(Eet_Free_Context *context,
3665 const Eet_Dictionary *ed,
3666 Eet_Data_Descriptor *edd,
3667 Eet_Data_Element *ede,
3668 Eet_Data_Chunk *echnk,
3675 Eina_List *childs = NULL;
3684 EET_ASSERT(!((type > EET_T_UNKNOW) && (type < EET_T_STRING)), return 0);
3687 /* read the number of elements */
3688 ret = eet_data_get_type(ed,
3691 ((char *)echnk->data) + echnk->size,
3700 if (IS_POINTER_TYPE(type))
3701 subsize = eet_basic_codec[ede->type - 1].size;
3703 subsize = ede->subtype->size;
3705 if (group_type == EET_G_VAR_ARRAY)
3707 /* store the number of elements
3708 * on the counter offset */
3709 *(int *)(((char *)data) + ede->count - ede->offset) = count;
3710 /* allocate space for the array of elements */
3711 if (edd->func.array_alloc)
3712 *(void **)ptr = edd->func.array_alloc(count * subsize);
3714 *(void **)ptr = edd->func.mem_alloc(count * subsize);
3719 memset(*(void **)ptr, 0, count * subsize);
3721 _eet_freelist_array_add(context, *(void **)ptr);
3725 /* get all array elements */
3726 for (i = 0; i < count; i++)
3730 /* Advance to next chunk */
3731 NEXT_CHUNK((*p), (*size), (*echnk), ed);
3732 memset(echnk, 0, sizeof(Eet_Data_Chunk));
3734 eet_data_chunk_get(ed, echnk, *p, *size);
3735 if (!echnk->name || strcmp(echnk->name, name) != 0)
3736 goto on_error; /* get the data */
3738 if ((echnk->group_type != group_type)
3739 || ((echnk->type != type) && (echnk->type != EET_T_NULL)))
3743 if ((ede->group_type != echnk->group_type)
3744 || ((echnk->type != ede->type) && (echnk->type != EET_T_NULL)))
3747 /* get the destination pointer */
3750 if (group_type == EET_G_ARRAY)
3751 dst = (char *)ptr + (subsize * i);
3753 dst = *(char **)ptr + (subsize * i);
3756 if (IS_POINTER_TYPE(echnk->type))
3758 void *data_ret = NULL;
3760 POINTER_TYPE_DECODE(context,
3771 memcpy(dst, &data_ret, subsize);
3774 childs = eina_list_append(childs, data_ret);
3778 STRUCT_TYPE_DECODE(dst,
3781 ede ? ede->subtype : NULL,
3788 childs = eina_list_append(childs, dst);
3794 Eet_Node *parent = *((Eet_Node **)data);
3797 if (group_type == EET_G_ARRAY)
3798 array = eet_node_array_new(name, count, childs);
3800 array = eet_node_var_array_new(name, childs);
3805 eet_node_struct_append(parent, name, array);
3811 EINA_LIST_FREE(childs, tmp)
3818 eet_data_put_union(Eet_Dictionary *ed,
3819 Eet_Data_Descriptor *edd __UNUSED__,
3820 Eet_Data_Element *ede,
3821 Eet_Data_Stream *ds,
3824 const char *union_type;
3827 EET_ASSERT(!((ede->type != EET_T_UNKNOW) || (!ede->subtype)), return );
3829 union_type = ede->subtype->func.type_get(
3830 ((char *)data_in) + ede->count - ede->offset,
3836 /* Search the structure of the union to encode. */
3837 for (i = 0; i < ede->subtype->elements.num; ++i)
3838 if (strcmp(ede->subtype->elements.set[i].name, union_type) == 0)
3840 Eet_Data_Element *sede;
3844 /* Yeah we found it ! */
3845 data = eet_data_put_type(ed, EET_T_STRING, &union_type, &size);
3855 sede = &(ede->subtype->elements.set[i]);
3856 data = _eet_data_descriptor_encode(ed,
3874 eet_data_get_union(Eet_Free_Context *context,
3875 const Eet_Dictionary *ed,
3876 Eet_Data_Descriptor *edd __UNUSED__,
3877 Eet_Data_Element *ede,
3878 Eet_Data_Chunk *echnk,
3885 const char *union_type;
3886 void *data_ret = NULL;
3891 ret = eet_data_get_type(ed,
3894 ((char *)echnk->data) + echnk->size,
3899 /* Advance to next chunk */
3900 NEXT_CHUNK((*p), (*size), (*echnk), ed);
3901 memset(echnk, 0, sizeof(Eet_Data_Chunk));
3904 eet_data_chunk_get(ed, echnk, *p, *size);
3910 EET_ASSERT(!(ede->group_type != group_type || ede->type != type),
3913 /* Search the structure of the union to decode */
3914 for (i = 0; i < ede->subtype->elements.num; ++i)
3915 if (strcmp(ede->subtype->elements.set[i].name, union_type) == 0)
3917 Eet_Data_Element *sede;
3920 /* Yeah we found it ! */
3921 sede = &(ede->subtype->elements.set[i]);
3922 EET_ASSERT(sede->subtype, goto on_error);
3924 data_ret = _eet_data_descriptor_decode(context,
3930 sede->subtype->size);
3934 /* Set union type. */
3935 if ((!ed) || (!ede->subtype->func.str_direct_alloc))
3937 ut = ede->subtype->func.str_alloc(union_type);
3938 _eet_freelist_str_add(context, ut);
3942 ut = ede->subtype->func.str_direct_alloc(union_type);
3943 _eet_freelist_direct_str_add(context, ut);
3946 ede->subtype->func.type_set(
3948 ((char *)data) + ede->count -
3957 /* FIXME: generate node structure. */
3958 data_ret = _eet_data_descriptor_decode(context,
3960 echnk->data, echnk->size,
3972 eet_data_put_variant(Eet_Dictionary *ed,
3973 Eet_Data_Descriptor *edd __UNUSED__,
3974 Eet_Data_Element *ede,
3975 Eet_Data_Stream *ds,
3978 const char *union_type;
3980 Eina_Bool unknow = EINA_FALSE;
3984 EET_ASSERT(!((ede->type != EET_T_UNKNOW) || (!ede->subtype)), return );
3986 union_type = ede->subtype->func.type_get(
3987 ((char *)data_in) + ede->count - ede->offset,
3990 if (!union_type && unknow == EINA_FALSE)
3995 /* Handle opaque internal representation */
3996 Eet_Variant_Unknow *evu;
3998 data = eet_data_put_type(ed, EET_T_STRING, &union_type, &size);
4008 evu = (Eet_Variant_Unknow *)data_in;
4009 if (evu && EINA_MAGIC_CHECK(evu, EET_MAGIC_VARIANT))
4019 /* Search the structure of the union to encode. */
4020 for (i = 0; i < ede->subtype->elements.num; ++i)
4021 if (strcmp(ede->subtype->elements.set[i].name, union_type) == 0)
4023 Eet_Data_Element *sede;
4025 /* Yeah we found it ! */
4026 data = eet_data_put_type(ed, EET_T_STRING, &union_type, &size);
4036 sede = &(ede->subtype->elements.set[i]);
4038 if (sede->group_type != EET_G_UNKNOWN)
4040 Eet_Data_Stream *lds;
4042 lds = eet_data_stream_new();
4043 eet_group_codec[sede->group_type - 100].put(ed,
4050 eet_data_encode(ed, ds, lds->data, ede->name, lds->pos,
4051 ede->type, ede->group_type);
4057 eet_data_encode(ed, ds, NULL, ede->name, 0,
4058 EET_T_NULL, ede->group_type);
4060 eet_data_stream_free(lds);
4064 data = _eet_data_descriptor_encode(ed,
4083 eet_data_get_variant(Eet_Free_Context *context,
4084 const Eet_Dictionary *ed,
4085 Eet_Data_Descriptor *edd __UNUSED__,
4086 Eet_Data_Element *ede,
4087 Eet_Data_Chunk *echnk,
4088 int type __UNUSED__,
4089 int group_type __UNUSED__,
4094 const char *union_type;
4095 void *data_ret = NULL;
4100 ret = eet_data_get_type(ed,
4103 ((char *)echnk->data) + echnk->size,
4108 /* Advance to next chunk */
4109 NEXT_CHUNK((*p), (*size), (*echnk), ed);
4110 memset(echnk, 0, sizeof(Eet_Data_Chunk));
4113 eet_data_chunk_get(ed, echnk, *p, *size);
4121 EET_ASSERT(ede->subtype, goto on_error);
4123 if ((!ed) || (!ede->subtype->func.str_direct_alloc))
4125 ut = ede->subtype->func.str_alloc(union_type);
4126 _eet_freelist_str_add(context, ut);
4130 ut = ede->subtype->func.str_direct_alloc(union_type);
4131 _eet_freelist_direct_str_add(context, ut);
4134 /* Search the structure of the union to decode */
4135 for (i = 0; i < ede->subtype->elements.num; ++i)
4136 if (strcmp(ede->subtype->elements.set[i].name, union_type) == 0)
4138 Eet_Data_Element *sede;
4140 /* Yeah we found it ! */
4141 sede = &(ede->subtype->elements.set[i]);
4143 if (sede->group_type != EET_G_UNKNOWN)
4145 Eet_Data_Chunk chnk;
4150 size2 = echnk->size;
4152 /* Didn't find a proper way to provide this
4153 without duplicating code */
4156 memset(&chnk, 0, sizeof(Eet_Data_Chunk));
4157 eet_data_chunk_get(ed, &chnk, p2, size2);
4162 ret = eet_group_codec[sede->group_type - 100].get
4163 (context, ed, sede->subtype, sede, &chnk, sede->type,
4164 sede->group_type, data, &p2, &size2);
4169 /* advance to next chunk */
4170 NEXT_CHUNK(p2, size2, chnk, ed);
4173 /* Put garbage so that we will not put eet_variant_unknow in it */
4174 data_ret = (void *)data;
4176 /* Set variant type. */
4177 ede->subtype->func.type_set
4178 (ut, ((char *)data) + ede->count - ede->offset,
4183 data_ret = _eet_data_descriptor_decode(context,
4192 /* And point to the variant data. */
4193 *(void **)data = data_ret;
4195 /* Set variant type. */
4196 ede->subtype->func.type_set
4197 (ut, ((char *)data) + ede->count - ede->offset, EINA_FALSE);
4203 Eet_Variant_Unknow *evu;
4205 evu = calloc(1, sizeof (Eet_Variant_Unknow) + echnk->size - 1);
4209 evu->size = echnk->size;
4210 memcpy(evu->data, echnk->data, evu->size);
4211 EINA_MAGIC_SET(evu, EET_MAGIC_VARIANT);
4213 /* And point to the opaque internal data scructure */
4214 *(void **)data = evu;
4216 /* Set variant type. */
4217 ede->subtype->func.type_set
4218 (ut, ((char *)data) + ede->count - ede->offset, EINA_TRUE);
4223 /* FIXME: dump node structure. */
4224 data_ret = _eet_data_descriptor_decode(context,
4226 echnk->data, echnk->size,
4238 eet_data_node_simple_type(int type,
4244 #endif /* ifdef EET_T_TYPE */
4246 #define EET_T_TYPE(Eet_Type, Eet_Node_Type, Type) \
4248 return eet_node_ ## Eet_Node_Type ## _new(name, *((Type *)dd)); \
4252 EET_T_TYPE(EET_T_CHAR, char, char);
4253 EET_T_TYPE(EET_T_SHORT, short, short);
4254 EET_T_TYPE(EET_T_INT, int, int);
4255 EET_T_TYPE(EET_T_LONG_LONG, long_long, long long);
4256 EET_T_TYPE(EET_T_FLOAT, float, float);
4257 EET_T_TYPE(EET_T_DOUBLE, double, double);
4258 EET_T_TYPE(EET_T_UCHAR, unsigned_char, unsigned char);
4259 EET_T_TYPE(EET_T_USHORT, unsigned_short, unsigned short);
4260 EET_T_TYPE(EET_T_UINT, unsigned_int, unsigned int);
4261 EET_T_TYPE(EET_T_ULONG_LONG, unsigned_long_long, unsigned long long);
4262 EET_T_TYPE(EET_T_STRING, string, char *);
4263 EET_T_TYPE(EET_T_INLINED_STRING, inlined_string, char *);
4266 return eet_node_null_new(name);
4269 ERR("Unknow type passed to eet_data_node_simple_type");
4275 eet_data_get_unknown(Eet_Free_Context *context,
4276 const Eet_Dictionary *ed,
4277 Eet_Data_Descriptor *edd,
4278 Eet_Data_Element *ede,
4279 Eet_Data_Chunk *echnk,
4281 int group_type __UNUSED__,
4283 char **p __UNUSED__,
4284 int *size __UNUSED__)
4289 if (IS_SIMPLE_TYPE(type))
4291 unsigned char dd[128];
4293 ret = eet_data_get_type(ed,
4296 ((char *)echnk->data) + echnk->size,
4297 edd ? (char *)data : (char *)dd);
4303 Eet_Node **parent = data;
4306 node = eet_data_node_simple_type(type, echnk->name, dd);
4309 eet_node_struct_append(*parent, echnk->name, node);
4315 if (type == EET_T_STRING)
4319 str = (char **)(((char *)data));
4322 if ((!ed) || (!edd->func.str_direct_alloc))
4324 *str = edd->func.str_alloc(*str);
4325 _eet_freelist_str_add(context, *str);
4329 *str = edd->func.str_direct_alloc(*str);
4330 _eet_freelist_direct_str_add(context, *str);
4334 else if (edd && type == EET_T_INLINED_STRING)
4338 str = (char **)(((char *)data));
4341 *str = edd->func.str_alloc(*str);
4342 _eet_freelist_str_add(context, *str);
4349 Eet_Data_Descriptor *subtype;
4351 subtype = ede ? ede->subtype : NULL;
4353 if (subtype || !edd)
4355 Eet_Node **parent = data;
4358 data_ret = _eet_data_descriptor_decode(context,
4369 ptr = (void **)(((char *)data));
4370 *ptr = (void *)data_ret;
4374 Eet_Node *node = data_ret;
4378 node = eet_node_struct_child_new(echnk->name, node);
4379 eet_node_struct_append(*parent, echnk->name, node);
4391 eet_data_put_array(Eet_Dictionary *ed,
4392 Eet_Data_Descriptor *edd __UNUSED__,
4393 Eet_Data_Element *ede,
4394 Eet_Data_Stream *ds,
4404 EET_ASSERT(!((ede->type > EET_T_UNKNOW) && (ede->type < EET_T_STRING)),
4407 if (ede->group_type == EET_G_ARRAY)
4408 count = ede->counter_offset;
4410 count = *(int *)(((char *)data_in) + ede->count - ede->offset);
4413 return; /* Store number of elements */
4415 data = eet_data_put_type(ed, EET_T_INT, &count, &size);
4417 eet_data_encode(ed, ds, data, ede->name, size, ede->type, ede->group_type);
4419 if (IS_POINTER_TYPE(ede->type))
4420 subsize = eet_basic_codec[ede->type - 1].size;
4422 subsize = ede->subtype->size;
4424 for (j = 0; j < count; j++)
4429 if (ede->group_type == EET_G_ARRAY)
4430 d = (void *)(((char *)data_in) + offset);
4432 d = *(((char **)data_in)) + offset;
4434 if (IS_POINTER_TYPE(ede->type))
4437 eet_data_put_unknown(ed, NULL, ede, ds, d);
4441 data = _eet_data_descriptor_encode(ed, ede->subtype, d, &size);
4453 /* Add a NULL element just to have the correct array layout. */
4467 eet_data_put_unknown(Eet_Dictionary *ed,
4468 Eet_Data_Descriptor *edd __UNUSED__,
4469 Eet_Data_Element *ede,
4470 Eet_Data_Stream *ds,
4476 if (IS_SIMPLE_TYPE(ede->type))
4477 data = eet_data_put_type(ed, ede->type, data_in, &size);
4478 else if (ede->subtype)
4479 if (*((char **)data_in))
4480 data = _eet_data_descriptor_encode(ed,
4482 *((char **)((char *)(data_in))),
4496 eet_data_put_list(Eet_Dictionary *ed,
4497 Eet_Data_Descriptor *edd,
4498 Eet_Data_Element *ede,
4499 Eet_Data_Stream *ds,
4506 EET_ASSERT(!(((ede->type > EET_T_UNKNOW) && (ede->type < EET_T_STRING))
4507 || ((ede->type > EET_T_NULL) && (ede->type < EET_T_LAST))),
4510 l = *((void **)(((char *)data_in)));
4511 for (; l; l = edd->func.list_next(l))
4513 if (IS_POINTER_TYPE(ede->type))
4515 const void *str = edd->func.list_data(l);
4516 eet_data_put_unknown(ed, NULL, ede, ds, &str);
4520 data = _eet_data_descriptor_encode(ed,
4522 edd->func.list_data(l),
4537 eet_data_put_hash(Eet_Dictionary *ed,
4538 Eet_Data_Descriptor *edd,
4539 Eet_Data_Element *ede,
4540 Eet_Data_Stream *ds,
4543 Eet_Data_Encode_Hash_Info fdata;
4546 l = *((void **)(((char *)data_in)));
4550 edd->func.hash_foreach(l, eet_data_descriptor_encode_hash_cb, &fdata);
4554 eet_data_dump_cipher(Eet_File *ef,
4556 const char *cipher_key,
4557 Eet_Dump_Callback dumpfunc,
4560 const Eet_Dictionary *ed = NULL;
4561 const void *data = NULL;
4563 Eet_Free_Context context;
4564 int required_free = 0;
4567 ed = eet_dictionary_get(ef);
4570 data = eet_read_direct(ef, name, &size);
4575 data = eet_read_cipher(ef, name, &size, cipher_key);
4580 eet_free_context_init(&context);
4581 result = _eet_data_descriptor_decode(&context, ed, NULL, data, size, NULL, 0);
4582 eet_free_context_shutdown(&context);
4584 eet_node_dump(result, 0, dumpfunc, dumpdata);
4586 eet_node_del(result);
4591 return result ? 1 : 0;
4595 eet_data_dump(Eet_File *ef,
4597 Eet_Dump_Callback dumpfunc,
4600 return eet_data_dump_cipher(ef, name, NULL, dumpfunc, dumpdata);
4604 eet_data_text_dump_cipher(const void *data_in,
4605 const char *cipher_key,
4607 Eet_Dump_Callback dumpfunc,
4612 Eet_Free_Context context;
4613 unsigned int ret_len = 0;
4620 if (eet_decipher(data_in, size_in, cipher_key,
4621 strlen(cipher_key), &ret, &ret_len))
4631 ret = (void *)data_in;
4635 eet_free_context_init(&context);
4636 result = _eet_data_descriptor_decode(&context, NULL, NULL, ret, ret_len, NULL, 0);
4637 eet_free_context_shutdown(&context);
4639 eet_node_dump(result, 0, dumpfunc, dumpdata);
4641 eet_node_del(result);
4645 return result ? 1 : 0;
4649 eet_data_text_dump(const void *data_in,
4651 Eet_Dump_Callback dumpfunc,
4654 return eet_data_text_dump_cipher(data_in, NULL, size_in, dumpfunc, dumpdata);
4658 eet_data_text_undump_cipher(const char *text,
4659 const char *cipher_key,
4665 ret = _eet_data_dump_parse(NULL, size_ret, text, textlen);
4666 if (ret && cipher_key)
4668 void *ciphered = NULL;
4669 unsigned int ciphered_len;
4671 if (eet_cipher(ret, *size_ret, cipher_key,
4672 strlen(cipher_key), &ciphered, &ciphered_len))
4683 *size_ret = ciphered_len;
4691 eet_data_text_undump(const char *text,
4695 return eet_data_text_undump_cipher(text, NULL, textlen, size_ret);
4699 eet_data_undump_cipher(Eet_File *ef,
4701 const char *cipher_key,
4711 ed = eet_dictionary_get(ef);
4713 data_enc = _eet_data_dump_parse(ed, &size, text, textlen);
4717 val = eet_write_cipher(ef, name, data_enc, size, comp, cipher_key);
4723 eet_data_undump(Eet_File *ef,
4729 return eet_data_undump_cipher(ef, name, NULL, text, textlen, comp);
4733 eet_data_descriptor_decode_cipher(Eet_Data_Descriptor *edd,
4734 const void *data_in,
4735 const char *cipher_key,
4738 void *deciphered = (void *)data_in;
4740 Eet_Free_Context context;
4741 unsigned int deciphered_len = size_in;
4743 if (cipher_key && data_in)
4744 if (eet_decipher(data_in, size_in, cipher_key,
4745 strlen(cipher_key), &deciphered, &deciphered_len))
4753 eet_free_context_init(&context);
4754 ret = _eet_data_descriptor_decode(&context,
4760 eet_free_context_shutdown(&context);
4762 if (data_in != deciphered)
4769 eet_data_descriptor_decode(Eet_Data_Descriptor *edd,
4770 const void *data_in,
4773 return eet_data_descriptor_decode_cipher(edd, data_in, NULL, size_in);
4777 eet_data_node_decode_cipher(const void *data_in,
4778 const char *cipher_key,
4781 void *deciphered = (void *)data_in;
4783 Eet_Free_Context context;
4784 unsigned int deciphered_len = size_in;
4786 if (cipher_key && data_in)
4787 if (eet_decipher(data_in, size_in, cipher_key,
4788 strlen(cipher_key), &deciphered, &deciphered_len))
4796 eet_free_context_init(&context);
4797 ret = _eet_data_descriptor_decode(&context,
4803 eet_free_context_shutdown(&context);
4805 if (data_in != deciphered)
4812 _eet_data_descriptor_encode(Eet_Dictionary *ed,
4813 Eet_Data_Descriptor *edd,
4814 const void *data_in,
4817 Eet_Data_Stream *ds;
4818 Eet_Data_Chunk *chnk;
4823 if (_eet_data_words_bigendian == -1)
4825 unsigned long int v;
4827 v = htonl(0x12345678);
4828 if (v == 0x12345678)
4829 _eet_data_words_bigendian = 1;
4831 _eet_data_words_bigendian = 0;
4834 ds = eet_data_stream_new();
4835 for (i = 0; i < edd->elements.num; i++)
4837 Eet_Data_Element *ede;
4839 ede = &(edd->elements.set[i]);
4840 eet_group_codec[ede->group_type - 100].put(
4848 chnk = eet_data_chunk_new(ds->data,
4855 eet_data_stream_free(ds);
4857 ds = eet_data_stream_new();
4858 eet_data_chunk_put(ed, chnk, ds);
4864 eet_data_stream_free(ds);
4868 eet_data_chunk_free(chnk);
4874 eet_data_node_write_cipher(Eet_File *ef,
4876 const char *cipher_key,
4885 ed = eet_dictionary_get(ef);
4887 data_enc = _eet_data_dump_encode(EET_G_UNKNOWN, ed, node, &size);
4891 val = eet_write_cipher(ef, name, data_enc, size, comp, cipher_key);
4897 eet_data_node_encode_cipher(Eet_Node *node,
4898 const char *cipher_key,
4902 void *ciphered = NULL;
4903 unsigned int ciphered_len = 0;
4906 ret = _eet_data_dump_encode(EET_G_UNKNOWN, NULL, node, &size);
4907 if (cipher_key && ret)
4909 if (eet_cipher(ret, size, cipher_key,
4910 strlen(cipher_key), &ciphered, &ciphered_len))
4923 size = (int)ciphered_len;
4934 eet_data_descriptor_encode_cipher(Eet_Data_Descriptor *edd,
4935 const void *data_in,
4936 const char *cipher_key,
4940 void *ciphered = NULL;
4941 unsigned int ciphered_len = 0;
4944 ret = _eet_data_descriptor_encode(NULL, edd, data_in, &size);
4945 if (cipher_key && ret)
4947 if (eet_cipher(ret, size, cipher_key,
4948 strlen(cipher_key), &ciphered, &ciphered_len))
4961 size = ciphered_len;
4972 eet_data_descriptor_encode(Eet_Data_Descriptor *edd,
4973 const void *data_in,
4976 return eet_data_descriptor_encode_cipher(edd, data_in, NULL, size_ret);
4980 eet_data_xattr_cipher_get(const char *filename,
4981 const char *attribute,
4982 Eet_Data_Descriptor *edd,
4983 const char *cipher_key)
4989 blob = eina_xattr_get(filename, attribute, &size);
4990 if (!blob) return NULL;
4992 ret = eet_data_descriptor_decode_cipher(edd, blob, cipher_key, size);
4999 eet_data_xattr_cipher_set(const char *filename,
5000 const char *attribute,
5001 Eet_Data_Descriptor *edd,
5002 const char *cipher_key,
5004 Eina_Xattr_Flags flags)
5010 blob = eet_data_descriptor_encode_cipher(edd, data, cipher_key, &size);
5011 if (!blob) return EINA_FALSE;
5013 ret = eina_xattr_set(filename, attribute, blob, size, flags);