2 * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
15 #ifdef HAVE_NETINET_IN_H
16 # include <netinet/in.h>
20 # include <winsock2.h>
26 #include "Eet_private.h"
29 * routines for doing data -> struct and struct -> data conversion
49 * multiple entries ordered as...
51 * fixed size array [ of basic types ]
52 * variable size array [ of basic types ]
53 * linked list [ of basic types ]
54 * hash table [ of basic types ]
56 * need to provide builder/accessor funcs for:
68 typedef struct _Eet_Data_Element Eet_Data_Element;
69 typedef struct _Eet_Data_Basic_Type_Codec Eet_Data_Basic_Type_Codec;
70 typedef struct _Eet_Data_Group_Type_Codec Eet_Data_Group_Type_Codec;
71 typedef struct _Eet_Data_Chunk Eet_Data_Chunk;
72 typedef struct _Eet_Data_Stream Eet_Data_Stream;
73 typedef struct _Eet_Data_Descriptor_Hash Eet_Data_Descriptor_Hash;
74 typedef struct _Eet_Data_Encode_Hash_Info Eet_Data_Encode_Hash_Info;
75 typedef struct _Eet_Free Eet_Free;
76 typedef struct _Eet_Free_Context Eet_Free_Context;
77 typedef struct _Eet_Variant_Unknow Eet_Variant_Unknow;
82 * Eet_Data_Basic_Type_Codec (Coder, Decoder)
83 * Eet_Data_Group_Type_Codec (Coder, Decoder)
85 struct _Eet_Data_Basic_Type_Codec
89 int (*get)(const Eet_Dictionary *ed, const void *src, const void *src_end,
91 void *(*put)(Eet_Dictionary *ed, const void *src, int *size_ret);
94 struct _Eet_Data_Group_Type_Codec
96 int (*get)(Eet_Free_Context *context, const Eet_Dictionary *ed,
97 Eet_Data_Descriptor *edd, Eet_Data_Element *ede,
98 Eet_Data_Chunk *echnk,
99 int type, int group_type, void *data_in, char **p, int *size);
100 void (*put)(Eet_Dictionary *ed, Eet_Data_Descriptor *edd,
101 Eet_Data_Element *ede, Eet_Data_Stream *ds, void *data_in);
104 struct _Eet_Data_Chunk
112 unsigned char group_type;
115 struct _Eet_Data_Stream
122 struct _Eet_Data_Descriptor_Hash
124 Eet_Data_Element *element;
125 Eet_Data_Descriptor_Hash *next;
128 struct _Eet_Data_Descriptor
131 const Eet_Dictionary *ed;
135 void *(*mem_alloc)(size_t size);
136 void (*mem_free)(void *mem);
137 char *(*str_alloc)(const char *str);
138 char *(*str_direct_alloc)(const char *str);
139 void (*str_free)(const char *str);
140 void (*str_direct_free)(const char *str);
141 void *(*list_next)(void *l);
142 void *(*list_append)(void *l, void *d);
143 void *(*list_data)(void *l);
144 void *(*list_free)(void *l);
145 void (*hash_foreach)(void *h,
146 int (*func)(void *h, const char *k, void *dt,
147 void *fdt), void *fdt);
148 void *(*hash_add)(void *h, const char *k, void *d);
149 void (*hash_free)(void *h);
150 const char *(*type_get)(const void *data, Eina_Bool *unknow);
151 Eina_Bool (*type_set)(const char *type, void *data, Eina_Bool unknow);
156 Eet_Data_Element *set;
160 Eet_Data_Descriptor_Hash *buckets;
164 Eina_Bool unified_type : 1;
169 struct _Eet_Data_Element
172 const char *counter_name;
173 const char *directory_name_ptr;
174 Eet_Data_Descriptor *subtype;
175 int offset; /* offset in bytes from the base element */
176 int count; /* number of elements for a fixed array */
177 int counter_offset; /* for a variable array we need the offset of the count variable */
178 unsigned char type; /* EET_T_XXX */
179 unsigned char group_type; /* EET_G_XXX */
182 struct _Eet_Data_Encode_Hash_Info
185 Eet_Data_Element *ede;
197 struct _Eet_Free_Context
200 Eet_Free freelist_list;
201 Eet_Free freelist_hash;
202 Eet_Free freelist_str;
203 Eet_Free freelist_direct_str;
206 struct _Eet_Variant_Unknow
216 static int eet_data_get_char(const Eet_Dictionary *ed,
220 static void * eet_data_put_char(Eet_Dictionary *ed,
223 static int eet_data_get_short(const Eet_Dictionary *ed,
227 static void * eet_data_put_short(Eet_Dictionary *ed,
230 static inline int eet_data_get_int(const Eet_Dictionary *ed,
234 static void * eet_data_put_int(Eet_Dictionary *ed,
237 static int eet_data_get_long_long(const Eet_Dictionary *ed,
241 static void * eet_data_put_long_long(Eet_Dictionary *ed,
244 static int eet_data_get_float(const Eet_Dictionary *ed,
248 static void * eet_data_put_float(Eet_Dictionary *ed,
251 static int eet_data_get_double(const Eet_Dictionary *ed,
255 static void * eet_data_put_double(Eet_Dictionary *ed,
258 static int eet_data_get_f32p32(const Eet_Dictionary *ed,
262 static void * eet_data_put_f32p32(Eet_Dictionary *ed,
265 static int eet_data_get_f16p16(const Eet_Dictionary *ed,
269 static void * eet_data_put_f16p16(Eet_Dictionary *ed,
272 static int eet_data_get_f8p24(const Eet_Dictionary *ed,
276 static void * eet_data_put_f8p24(Eet_Dictionary *ed,
279 static inline int eet_data_get_string(const Eet_Dictionary *ed,
283 static void * eet_data_put_string(Eet_Dictionary *ed,
286 static int eet_data_get_istring(const Eet_Dictionary *ed,
290 static void * eet_data_put_istring(Eet_Dictionary *ed,
293 static int eet_data_get_null(const Eet_Dictionary *ed,
297 static void * eet_data_put_null(Eet_Dictionary *ed,
301 static int eet_data_get_type(const Eet_Dictionary *ed,
306 static void * eet_data_put_type(Eet_Dictionary *ed,
311 static Eet_Node * eet_data_node_simple_type(int type,
315 static int eet_data_get_unknown(Eet_Free_Context *context,
316 const Eet_Dictionary *ed,
317 Eet_Data_Descriptor *edd,
318 Eet_Data_Element *ede,
319 Eet_Data_Chunk *echnk,
325 static void eet_data_put_unknown(Eet_Dictionary *ed,
326 Eet_Data_Descriptor *edd,
327 Eet_Data_Element *ede,
330 static void eet_data_put_array(Eet_Dictionary *ed,
331 Eet_Data_Descriptor *edd,
332 Eet_Data_Element *ede,
335 static int eet_data_get_array(Eet_Free_Context *context,
336 const Eet_Dictionary *ed,
337 Eet_Data_Descriptor *edd,
338 Eet_Data_Element *ede,
339 Eet_Data_Chunk *echnk,
345 static int eet_data_get_list(Eet_Free_Context *context,
346 const Eet_Dictionary *ed,
347 Eet_Data_Descriptor *edd,
348 Eet_Data_Element *ede,
349 Eet_Data_Chunk *echnk,
355 static void eet_data_put_list(Eet_Dictionary *ed,
356 Eet_Data_Descriptor *edd,
357 Eet_Data_Element *ede,
360 static void eet_data_put_hash(Eet_Dictionary *ed,
361 Eet_Data_Descriptor *edd,
362 Eet_Data_Element *ede,
365 static int eet_data_get_hash(Eet_Free_Context *context,
366 const Eet_Dictionary *ed,
367 Eet_Data_Descriptor *edd,
368 Eet_Data_Element *ede,
369 Eet_Data_Chunk *echnk,
375 static void eet_data_put_union(Eet_Dictionary *ed,
376 Eet_Data_Descriptor *edd,
377 Eet_Data_Element *ede,
380 static int eet_data_get_union(Eet_Free_Context *context,
381 const Eet_Dictionary *ed,
382 Eet_Data_Descriptor *edd,
383 Eet_Data_Element *ede,
384 Eet_Data_Chunk *echnk,
390 static void eet_data_put_variant(Eet_Dictionary *ed,
391 Eet_Data_Descriptor *edd,
392 Eet_Data_Element *ede,
395 static int eet_data_get_variant(Eet_Free_Context *context,
396 const Eet_Dictionary *ed,
397 Eet_Data_Descriptor *edd,
398 Eet_Data_Element *ede,
399 Eet_Data_Chunk *echnk,
406 static void eet_data_chunk_get(const Eet_Dictionary *ed,
407 Eet_Data_Chunk *chnk,
410 static Eet_Data_Chunk * eet_data_chunk_new(void *data,
415 static void eet_data_chunk_free(Eet_Data_Chunk *chnk);
417 static Eet_Data_Stream *eet_data_stream_new(void);
418 static void eet_data_stream_write(Eet_Data_Stream *ds,
421 static void eet_data_stream_free(Eet_Data_Stream *ds);
423 static void eet_data_chunk_put(Eet_Dictionary *ed,
424 Eet_Data_Chunk *chnk,
425 Eet_Data_Stream *ds);
427 static int eet_data_descriptor_encode_hash_cb(void *hash,
431 static void * _eet_data_descriptor_encode(Eet_Dictionary *ed,
432 Eet_Data_Descriptor *edd,
435 static void * _eet_data_descriptor_decode(Eet_Free_Context *context,
436 const Eet_Dictionary *ed,
437 Eet_Data_Descriptor *edd,
443 static const Eet_Data_Basic_Type_Codec eet_basic_codec[] =
445 {sizeof(char), "char", eet_data_get_char, eet_data_put_char },
446 {sizeof(short), "short", eet_data_get_short, eet_data_put_short },
447 {sizeof(int), "int", eet_data_get_int, eet_data_put_int },
448 {sizeof(long long), "long_long", eet_data_get_long_long,
449 eet_data_put_long_long},
450 {sizeof(float), "float", eet_data_get_float, eet_data_put_float },
451 {sizeof(double), "double", eet_data_get_double,
452 eet_data_put_double },
453 {sizeof(char), "uchar", eet_data_get_char, eet_data_put_char },
454 {sizeof(short), "ushort", eet_data_get_short, eet_data_put_short },
455 {sizeof(int), "uint", eet_data_get_int, eet_data_put_int },
456 {sizeof(long long), "ulong_long", eet_data_get_long_long,
457 eet_data_put_long_long},
458 {sizeof(char *), "string", eet_data_get_string,
459 eet_data_put_string },
460 {sizeof(char *), "inlined", eet_data_get_istring,
461 eet_data_put_istring },
462 {sizeof(void *), "NULL", eet_data_get_null, eet_data_put_null },
463 {sizeof(Eina_F32p32),"f32p32", eet_data_get_f32p32,
464 eet_data_put_f32p32 },
465 {sizeof(Eina_F16p16),"f16p16", eet_data_get_f16p16,
466 eet_data_put_f16p16 },
467 {sizeof(Eina_F8p24),"f8p24", eet_data_get_f8p24, eet_data_put_f8p24 }
470 static const Eet_Data_Group_Type_Codec eet_group_codec[] =
472 { eet_data_get_unknown, eet_data_put_unknown },
473 { eet_data_get_array, eet_data_put_array },
474 { eet_data_get_array, eet_data_put_array },
475 { eet_data_get_list, eet_data_put_list },
476 { eet_data_get_hash, eet_data_put_hash },
477 { eet_data_get_union, eet_data_put_union },
478 { eet_data_get_variant, eet_data_put_variant }
481 static int _eet_data_words_bigendian = -1;
485 #define SWAP64(x) (x) = \
486 ((((unsigned long long)(x) & 0x00000000000000ffULL) << 56) | \
487 (((unsigned long long)(x) & 0x000000000000ff00ULL) << 40) | \
488 (((unsigned long long)(x) & 0x0000000000ff0000ULL) << 24) | \
489 (((unsigned long long)(x) & 0x00000000ff000000ULL) << 8) | \
490 (((unsigned long long)(x) & 0x000000ff00000000ULL) >> 8) | \
491 (((unsigned long long)(x) & 0x0000ff0000000000ULL) >> 24) | \
492 (((unsigned long long)(x) & 0x00ff000000000000ULL) >> 40) | \
493 (((unsigned long long)(x) & 0xff00000000000000ULL) >> 56))
494 #define SWAP32(x) (x) = \
495 ((((int)(x) & 0x000000ff) << 24) | \
496 (((int)(x) & 0x0000ff00) << 8) | \
497 (((int)(x) & 0x00ff0000) >> 8) | \
498 (((int)(x) & 0xff000000) >> 24))
499 #define SWAP16(x) (x) = \
500 ((((short)(x) & 0x00ff) << 8) | \
501 (((short)(x) & 0xff00) >> 8))
517 #define CONV16(x) {if (_eet_data_words_bigendian) {SWAP16(x); }}
518 #define CONV32(x) {if (_eet_data_words_bigendian) {SWAP32(x); }}
519 #define CONV64(x) {if (_eet_data_words_bigendian) {SWAP64(x); }}
521 #define IS_SIMPLE_TYPE(Type) (Type > EET_T_UNKNOW && Type < EET_T_LAST)
522 #define IS_POINTER_TYPE(Type) (Type >= EET_T_STRING && Type <= EET_T_NULL)
524 #define POINTER_TYPE_DECODE(Context, \
536 ___r = eet_data_get_unknown(Context, \
540 Type, EET_G_UNKNOWN, \
542 if (!___r) { goto Label; } \
545 #define STRUCT_TYPE_DECODE(Data_Ret, Context, Ed, Ede, Data, Size, Label) \
547 Data_Ret = _eet_data_descriptor_decode(Context, \
552 if (!Data_Ret) { goto Label; } \
555 #define EET_I_STRING 1 << 4
556 #define EET_I_INLINED_STRING 2 << 4
557 #define EET_I_NULL 3 << 4
559 #define EET_MAGIC_VARIANT 0xF1234BC
564 eet_data_get_char(const Eet_Dictionary *ed __UNUSED__,
571 if (((char *)src + sizeof(char)) > (char *)src_end)
582 eet_data_put_char(Eet_Dictionary *ed __UNUSED__, const void *src, int *size_ret)
586 d = (char *)malloc(sizeof(char));
593 *size_ret = sizeof(char);
599 eet_data_get_short(const Eet_Dictionary *ed __UNUSED__,
606 if (((char *)src + sizeof(short)) > (char *)src_end)
609 memcpy(dst, src, sizeof(short));
612 return sizeof(short);
616 eet_data_put_short(Eet_Dictionary *ed __UNUSED__,
622 d = (short *)malloc(sizeof(short));
629 *size_ret = sizeof(short);
635 eet_data_get_int(const Eet_Dictionary *ed __UNUSED__,
642 if (((char *)src + sizeof(int)) > (char *)src_end)
645 memcpy(dst, src, sizeof(int));
652 eet_data_put_int(Eet_Dictionary *ed __UNUSED__, const void *src, int *size_ret)
656 d = (int *)malloc(sizeof(int));
663 *size_ret = sizeof(int);
669 eet_data_get_long_long(const Eet_Dictionary *ed __UNUSED__,
674 unsigned long long *d;
676 if (((char *)src + sizeof(unsigned long long)) > (char *)src_end)
679 memcpy(dst, src, sizeof(unsigned long long));
680 d = (unsigned long long *)dst;
682 return sizeof(unsigned long long);
686 eet_data_put_long_long(Eet_Dictionary *ed __UNUSED__,
690 unsigned long long *s, *d;
692 d = (unsigned long long *)malloc(sizeof(unsigned long long));
696 s = (unsigned long long *)src;
699 *size_ret = sizeof(unsigned long long);
705 eet_data_get_string_hash(const Eet_Dictionary *ed,
713 if (eet_data_get_int(ed, src, src_end, &idx) < 0)
716 return eet_dictionary_string_get_hash(ed, idx);
723 eet_data_get_string(const Eet_Dictionary *ed,
737 if (eet_data_get_int(ed, src, src_end, &idx) < 0)
740 str = eet_dictionary_string_get_char(ed, idx);
745 return eet_dictionary_string_get_size(ed, idx);
756 return strlen(s) + 1;
760 eet_data_put_string(Eet_Dictionary *ed, const void *src, int *size_ret)
770 str = *((const char **)src);
774 idx = eet_dictionary_string_add(ed, str);
778 return eet_data_put_int(ed, &idx, size_ret);
781 s = (char *)(*((char **)src));
790 memcpy(d, s, len + 1);
795 /* ALWAYS INLINED STRING TYPE */
797 eet_data_get_istring(const Eet_Dictionary *ed __UNUSED__,
802 return eet_data_get_string(NULL, src, src_end, dst);
806 eet_data_put_istring(Eet_Dictionary *ed __UNUSED__,
810 return eet_data_put_string(NULL, src, size_ret);
813 /* ALWAYS NULL TYPE */
815 eet_data_get_null(const Eet_Dictionary *ed __UNUSED__,
816 const void *src __UNUSED__,
817 const void *src_end __UNUSED__,
829 eet_data_put_null(Eet_Dictionary *ed __UNUSED__,
830 const void *src __UNUSED__,
838 * Fast lookups of simple doubles/floats.
840 * These aren't properly a cache because they don't store pre-calculated
841 * values, but have a so simple math that is almost as fast.
844 _eet_data_float_cache_get(const char *s, int len, float *d)
846 /* fast handle of simple case 0xMp+E*/
847 if ((len == 6) && (s[0] == '0') && (s[1] == 'x') && (s[3] == 'p'))
849 int mantisse = (s[2] >= 'a') ? (s[2] - 'a' + 10) : (s[2] - '0');
850 int exponent = (s[5] - '0');
853 *d = (float)(mantisse << exponent);
855 *d = (float)mantisse / (float)(1 << exponent);
864 _eet_data_double_cache_get(const char *s, int len, double *d)
866 /* fast handle of simple case 0xMp+E*/
867 if ((len == 6) && (s[0] == '0') && (s[1] == 'x') && (s[3] == 'p'))
869 int mantisse = (s[2] >= 'a') ? (s[2] - 'a' + 10) : (s[2] - '0');
870 int exponent = (s[5] - '0');
873 *d = (double)(mantisse << exponent);
875 *d = (double)mantisse / (double)(1 << exponent);
885 eet_data_get_float(const Eet_Dictionary *ed,
901 s = (const char *)src;
904 while ((p < (const char *)src_end) && (*p != 0)) {len++; p++; }
906 if (_eet_data_float_cache_get(s, len, d) != 0)
909 if (eina_convert_atod(s, len, &mantisse, &exponent) == EINA_FALSE)
912 *d = (float)ldexp((double)mantisse, exponent);
917 if (eet_data_get_int(ed, src, src_end, &idx) < 0)
920 if (!eet_dictionary_string_get_float(ed, idx, d))
927 eet_data_put_float(Eet_Dictionary *ed, const void *src, int *size_ret)
932 eina_convert_dtoa((double)(*(float *)src), buf);
944 memcpy(d, buf, len + 1);
949 idx = eet_dictionary_string_add(ed, buf);
953 return eet_data_put_int(ed, &idx, size_ret);
958 eet_data_get_double(const Eet_Dictionary *ed,
971 long long mantisse = 0;
975 s = (const char *)src;
978 while ((p < (const char *)src_end) && (*p != 0)) {len++; p++; }
980 if (_eet_data_double_cache_get(s, len, d) != 0)
983 if (eina_convert_atod(s, len, &mantisse, &exponent) == EINA_FALSE)
986 *d = ldexp((double)mantisse, exponent);
991 if (eet_data_get_int(ed, src, src_end, &idx) < 0)
994 if (!eet_dictionary_string_get_double(ed, idx, d))
1001 eet_data_put_double(Eet_Dictionary *ed, const void *src, int *size_ret)
1006 eina_convert_dtoa((double)(*(double *)src), buf);
1014 d = malloc(len + 1);
1018 memcpy(d, buf, len + 1);
1019 *size_ret = len + 1;
1024 idx = eet_dictionary_string_add(ed, buf);
1028 return eet_data_put_int(ed, &idx, size_ret);
1032 eet_data_get_f32p32(const Eet_Dictionary *ed,
1034 const void *src_end,
1040 fp = (Eina_F32p32 *)dst;
1047 s = (const char *)src;
1050 while ((p < (const char *)src_end) && (*p != 0)) { len++; p++; }
1052 if (!(eina_convert_atofp(s, len, fp)))
1058 if (eet_data_get_int(ed, src, src_end, &idx) < 0)
1061 if (!eet_dictionary_string_get_fp(ed, idx, fp))
1068 eet_data_put_f32p32(Eet_Dictionary *ed, const void *src, int *size_ret)
1073 eina_convert_fptoa((Eina_F32p32)(*(Eina_F32p32 *)src), buf);
1081 d = malloc(len + 1);
1085 memcpy(d, buf, len + 1);
1086 *size_ret = len + 1;
1091 idx = eet_dictionary_string_add(ed, buf);
1095 return eet_data_put_int(ed, &idx, size_ret);
1099 eet_data_get_f16p16(const Eet_Dictionary *ed,
1101 const void *src_end,
1107 fp = (Eina_F16p16 *)dst;
1109 if (eet_data_get_f32p32(ed, src, src_end, &tmp) < 0)
1112 *fp = eina_f32p32_to_f16p16(tmp);
1117 eet_data_put_f16p16(Eet_Dictionary *ed, const void *src, int *size_ret)
1121 tmp = eina_f16p16_to_f32p32((Eina_F16p16)(*(Eina_F16p16 *)src));
1122 return eet_data_put_f32p32(ed, &tmp, size_ret);
1126 eet_data_get_f8p24(const Eet_Dictionary *ed,
1128 const void *src_end,
1134 fp = (Eina_F8p24 *)dst;
1136 if (eet_data_get_f32p32(ed, src, src_end, &tmp) < 0)
1139 *fp = eina_f32p32_to_f8p24(tmp);
1144 eet_data_put_f8p24(Eet_Dictionary *ed, const void *src, int *size_ret)
1148 tmp = eina_f8p24_to_f32p32((Eina_F8p24)(*(Eina_F8p24 *)src));
1149 return eet_data_put_f32p32(ed, &tmp, size_ret);
1153 eet_data_get_type(const Eet_Dictionary *ed,
1156 const void *src_end,
1161 ret = eet_basic_codec[type - 1].get(ed, src, src_end, dest);
1165 static inline void *
1166 eet_data_put_type(Eet_Dictionary *ed, int type, const void *src, int *size_ret)
1170 ret = eet_basic_codec[type - 1].put(ed, src, size_ret);
1174 static inline Eina_Bool
1175 eet_data_type_match(int type1, int type2)
1180 /* Note: All floating point type are equivalent and could be read
1181 without problem by any other floating point getter. */
1212 * char[4] = "CHnK"; // untyped data ... or
1213 * char[4] = "CHKx"; // typed data - x == type
1215 * int = chunk size (including magic string);
1216 * char[] = chunk magic/name string (0 byte terminated);
1217 * ... sub-chunks (a chunk can contain chuncks recusrively) ...
1219 * ... payload data ...
1224 eet_data_chunk_get(const Eet_Dictionary *ed, Eet_Data_Chunk *chnk,
1225 const void *src, int size)
1242 if ((s[0] != 'C') || (s[1] != 'H') || (s[2] != 'K'))
1245 chnk->type = (unsigned char)(s[3]);
1246 if (chnk->type >= EET_I_LIMIT)
1249 ((chnk->type - EET_I_LIMIT) & 0xF) + EET_G_UNKNOWN;
1250 switch ((chnk->type - EET_I_LIMIT) & 0xF0)
1252 #define EET_UNMATCH_TYPE(Type) \
1253 case EET_I_ ## Type: chnk->type = EET_T_ ## Type; break;
1255 EET_UNMATCH_TYPE(STRING);
1256 EET_UNMATCH_TYPE(INLINED_STRING);
1257 EET_UNMATCH_TYPE(NULL);
1263 else if (chnk->type > EET_T_LAST)
1265 chnk->group_type = chnk->type;
1266 chnk->type = EET_T_UNKNOW;
1269 chnk->group_type = EET_G_UNKNOWN;
1270 if ((chnk->type >= EET_T_LAST) ||
1271 (chnk->group_type >= EET_G_LAST))
1274 chnk->group_type = 0;
1277 else if ((s[0] != 'C') || (s[1] != 'H') || (s[2] != 'n') || (s[3] != 'K'))
1280 ret1 = eet_data_get_type(ed, EET_T_INT, (s + 4), (s + size), &(chnk->size));
1285 if ((chnk->size < 0) || ((chnk->size + 8) > size))
1288 ret2 = eet_data_get_type(ed, EET_T_STRING, (s + 8), (s + size), &(chnk->name));
1296 chnk->hash = eet_data_get_string_hash(ed, (s + 8), (s + size));
1300 chnk->data = (char *)src + 4 + ret1 + sizeof(int);
1301 chnk->size -= sizeof(int);
1305 chnk->data = (char *)src + 4 + ret1 + chnk->len;
1306 chnk->size -= chnk->len;
1312 static inline Eet_Data_Chunk *
1313 eet_data_chunk_new(void *data,
1319 Eet_Data_Chunk *chnk;
1324 chnk = calloc(1, sizeof(Eet_Data_Chunk));
1328 /* Note: Another security, so older eet library could read file
1329 saved with fixed point value. */
1330 if (type == EET_T_F32P32
1331 || type == EET_T_F16P16
1332 || type == EET_T_F8P24)
1333 type = EET_T_DOUBLE;
1335 chnk->name = strdup(name);
1336 chnk->len = strlen(name) + 1;
1340 chnk->group_type = group_type;
1345 eet_data_chunk_free(Eet_Data_Chunk *chnk)
1353 static inline Eet_Data_Stream *
1354 eet_data_stream_new(void)
1356 Eet_Data_Stream *ds;
1358 ds = calloc(1, sizeof(Eet_Data_Stream));
1366 eet_data_stream_free(Eet_Data_Stream *ds)
1375 eet_data_stream_flush(Eet_Data_Stream *ds)
1381 eet_data_stream_write(Eet_Data_Stream *ds, const void *data, int size)
1385 if ((ds->pos + size) > ds->size)
1387 ds->data = realloc(ds->data, ds->size + size + 512);
1395 ds->size = ds->size + size + 512;
1399 memcpy(p + ds->pos, data, size);
1404 eet_data_chunk_put(Eet_Dictionary *ed,
1405 Eet_Data_Chunk *chnk,
1406 Eet_Data_Stream *ds)
1413 unsigned char buf[4] = "CHK";
1415 /* disable this check - it will allow empty chunks to be written. this is
1416 * right for corner-cases when y have a struct with empty fields (empty
1417 * strings or empty list ptrs etc.) */
1418 /* if (!chnk->data && chnk->type != EET_T_NULL) return; */
1421 /* eet_data_stream_write(ds, "CHnK", 4);*/
1422 if (chnk->type != EET_T_UNKNOW)
1424 if (chnk->group_type != EET_G_UNKNOWN)
1426 int type = EET_I_LIMIT + chnk->group_type - EET_G_UNKNOWN;
1430 /* Only make sense with pointer type. */
1431 #define EET_MATCH_TYPE(Type) \
1432 case EET_T_ ## Type: type += EET_I_ ## Type; break;
1434 EET_MATCH_TYPE(STRING);
1435 EET_MATCH_TYPE(INLINED_STRING);
1436 EET_MATCH_TYPE(NULL);
1445 buf[3] = chnk->type;
1448 buf[3] = chnk->group_type;
1450 string = eet_data_put_string(ed, &chnk->name, &string_ret);
1454 /* size of chunk payload data + name */
1455 s = chnk->size + string_ret;
1456 size = eet_data_put_int(ed, &s, &size_ret);
1458 /* FIXME: If something goes wrong the resulting file will be corrupted. */
1462 eet_data_stream_write(ds, buf, 4);
1464 /* write chunk length */
1465 eet_data_stream_write(ds, size, size_ret);
1467 /* write chunk name */
1468 eet_data_stream_write(ds, string, string_ret);
1472 eet_data_stream_write(ds, chnk->data, chnk->size);
1482 _eet_descriptor_hash_new(Eet_Data_Descriptor *edd)
1486 edd->elements.hash.size = 1 << 6;
1487 edd->elements.hash.buckets = calloc(
1489 sizeof(Eet_Data_Descriptor_Hash) *
1490 edd->elements.hash.size);
1491 for (i = 0; i < edd->elements.num; i++)
1493 Eet_Data_Element *ede;
1496 ede = &(edd->elements.set[i]);
1497 hash = _eet_hash_gen((char *)ede->name, 6);
1498 if (!edd->elements.hash.buckets[hash].element)
1499 edd->elements.hash.buckets[hash].element = ede;
1502 Eet_Data_Descriptor_Hash *bucket;
1504 bucket = calloc(1, sizeof(Eet_Data_Descriptor_Hash));
1505 bucket->element = ede;
1506 bucket->next = edd->elements.hash.buckets[hash].next;
1507 edd->elements.hash.buckets[hash].next = bucket;
1513 _eet_descriptor_hash_free(Eet_Data_Descriptor *edd)
1517 for (i = 0; i < edd->elements.hash.size; i++)
1519 Eet_Data_Descriptor_Hash *bucket, *pbucket;
1521 bucket = edd->elements.hash.buckets[i].next;
1525 bucket = bucket->next;
1529 if (edd->elements.hash.buckets)
1530 free(edd->elements.hash.buckets);
1533 static Eet_Data_Element *
1534 _eet_descriptor_hash_find(Eet_Data_Descriptor *edd, char *name, int hash)
1536 Eet_Data_Descriptor_Hash *bucket;
1539 hash = _eet_hash_gen(name, 6);
1543 if (!edd->elements.hash.buckets[hash].element)
1545 When we use the dictionnary as a source for chunk name, we will always
1546 have the same pointer in name. It's a good idea to just compare pointer
1547 instead of running strcmp on both string.
1550 if (edd->elements.hash.buckets[hash].element->directory_name_ptr == name)
1551 return edd->elements.hash.buckets[hash].element;
1553 if (!strcmp(edd->elements.hash.buckets[hash].element->name, name))
1555 edd->elements.hash.buckets[hash].element->directory_name_ptr = name;
1556 return edd->elements.hash.buckets[hash].element;
1559 bucket = edd->elements.hash.buckets[hash].next;
1562 if (bucket->element->directory_name_ptr == name)
1563 return bucket->element;
1565 if (!strcmp(bucket->element->name, name))
1567 bucket->element->directory_name_ptr = name;
1568 return bucket->element;
1571 bucket = bucket->next;
1577 _eet_mem_alloc(size_t size)
1579 return calloc(1, size);
1583 _eet_mem_free(void *mem)
1589 _eet_str_alloc(const char *str)
1595 _eet_str_free(const char *str)
1601 _eet_eina_hash_add_alloc(Eina_Hash *hash, const char *key, void *data)
1604 hash = eina_hash_string_small_new(NULL);
1609 eina_hash_add(hash, key, data);
1614 _eet_eina_hash_direct_add_alloc(Eina_Hash *hash, const char *key, void *data)
1617 hash = eina_hash_string_small_new(NULL);
1622 eina_hash_direct_add(hash, key, data);
1627 _eet_str_direct_alloc(const char *str)
1633 _eet_str_direct_free(const char *str __UNUSED__)
1638 _eet_eina_hash_foreach(void *hash, Eina_Hash_Foreach cb, void *fdata)
1641 eina_hash_foreach(hash, cb, fdata);
1645 _eet_eina_hash_free(void *hash)
1648 eina_hash_free(hash);
1653 eet_eina_stream_data_descriptor_class_set(Eet_Data_Descriptor_Class *eddc,
1664 eddc->func.mem_alloc = _eet_mem_alloc;
1665 eddc->func.mem_free = _eet_mem_free;
1666 eddc->func.str_alloc = (char *(*)(const char *))eina_stringshare_add;
1667 eddc->func.str_free = eina_stringshare_del;
1668 eddc->func.list_next = (void *(*)(void *))eina_list_next;
1669 eddc->func.list_append = (void *(*)(void *, void *))eina_list_append;
1670 eddc->func.list_data = (void *(*)(void *))eina_list_data_get;
1671 eddc->func.list_free = (void *(*)(void *))eina_list_free;
1672 eddc->func.hash_foreach =
1674 int (*)(void *, const char *, void *,
1675 void *), void *))_eet_eina_hash_foreach;
1676 eddc->func.hash_add =
1677 (void * (*)(void *, const char *, void *))_eet_eina_hash_add_alloc;
1678 eddc->func.hash_free = (void (*)(void *))_eet_eina_hash_free;
1684 eet_eina_file_data_descriptor_class_set(Eet_Data_Descriptor_Class *eddc,
1688 if (!eet_eina_stream_data_descriptor_class_set(eddc, name, size))
1693 eddc->func.hash_add =
1694 (void * (*)(void *, const char *, void *))_eet_eina_hash_direct_add_alloc;
1695 eddc->func.str_direct_alloc = _eet_str_direct_alloc;
1696 eddc->func.str_direct_free = _eet_str_direct_free;
1701 static Eet_Data_Descriptor *
1702 _eet_data_descriptor_new(const Eet_Data_Descriptor_Class *eddc, int version)
1704 Eet_Data_Descriptor *edd;
1709 edd = calloc(1, sizeof (Eet_Data_Descriptor));
1713 edd->name = eddc->name;
1715 edd->size = eddc->size;
1716 edd->func.mem_alloc = _eet_mem_alloc;
1717 edd->func.mem_free = _eet_mem_free;
1718 edd->func.str_alloc = _eet_str_alloc;
1719 edd->func.str_free = _eet_str_free;
1720 if (eddc->func.mem_alloc)
1721 edd->func.mem_alloc = eddc->func.mem_alloc;
1723 if (eddc->func.mem_free)
1724 edd->func.mem_free = eddc->func.mem_free;
1726 if (eddc->func.str_alloc)
1727 edd->func.str_alloc = eddc->func.str_alloc;
1729 if (eddc->func.str_free)
1730 edd->func.str_free = eddc->func.str_free;
1732 edd->func.list_next = eddc->func.list_next;
1733 edd->func.list_append = eddc->func.list_append;
1734 edd->func.list_data = eddc->func.list_data;
1735 edd->func.list_free = eddc->func.list_free;
1736 edd->func.hash_foreach = eddc->func.hash_foreach;
1737 edd->func.hash_add = eddc->func.hash_add;
1738 edd->func.hash_free = eddc->func.hash_free;
1740 if (eddc->version > 1 && version > 1)
1742 edd->func.str_direct_alloc = eddc->func.str_direct_alloc;
1743 edd->func.str_direct_free = eddc->func.str_direct_free;
1746 if (eddc->version > 2)
1748 edd->func.type_get = eddc->func.type_get;
1749 edd->func.type_set = eddc->func.type_set;
1755 EAPI Eet_Data_Descriptor *
1756 eet_data_descriptor_new(const char *name,
1758 void *(*func_list_next)(void *l),
1759 void *(*func_list_append)(void *l, void *d),
1760 void *(*func_list_data)(void *l),
1761 void *(*func_list_free)(void *l),
1762 void (*func_hash_foreach)(void *h, int (*func)(
1769 void *(*func_hash_add)(void *h, const char *k, void *d),
1770 void (*func_hash_free)(void *h))
1772 Eet_Data_Descriptor_Class eddc;
1777 memset(&eddc, 0, sizeof (Eet_Data_Descriptor_Class));
1783 eddc.func.list_next = func_list_next;
1784 eddc.func.list_append = func_list_append;
1785 eddc.func.list_data = func_list_data;
1786 eddc.func.list_free = func_list_free;
1787 eddc.func.hash_foreach = func_hash_foreach;
1788 eddc.func.hash_add = func_hash_add;
1789 eddc.func.hash_free = func_hash_free;
1791 return _eet_data_descriptor_new(&eddc, 0);
1794 EAPI Eet_Data_Descriptor *
1795 eet_data_descriptor2_new(const Eet_Data_Descriptor_Class *eddc)
1797 return _eet_data_descriptor_new(eddc, 1);
1800 EAPI Eet_Data_Descriptor *
1801 eet_data_descriptor3_new(const Eet_Data_Descriptor_Class *eddc)
1803 return _eet_data_descriptor_new(eddc, 2);
1806 EAPI Eet_Data_Descriptor *
1807 eet_data_descriptor_stream_new(const Eet_Data_Descriptor_Class *eddc)
1809 return _eet_data_descriptor_new(eddc, 1);
1812 EAPI Eet_Data_Descriptor *
1813 eet_data_descriptor_file_new(const Eet_Data_Descriptor_Class *eddc)
1815 return _eet_data_descriptor_new(eddc, 2);
1819 eet_data_descriptor_free(Eet_Data_Descriptor *edd)
1824 _eet_descriptor_hash_free(edd);
1825 if (edd->elements.set)
1826 free(edd->elements.set);
1832 eet_data_descriptor_element_add(Eet_Data_Descriptor *edd,
1838 /* int counter_offset, */
1839 const char *counter_name /* FIXME: Useless should go on a major release */,
1840 Eet_Data_Descriptor *subtype)
1842 Eet_Data_Element *ede;
1843 Eet_Data_Element *tmp;
1845 /* UNION, VARIANT type would not work with simple type, we need a way to map the type. */
1846 if ((group_type == EET_G_UNION
1847 || group_type == EET_G_VARIANT)
1849 (type != EET_T_UNKNOW
1851 || subtype->func.type_get == NULL
1852 || subtype->func.type_set == NULL))
1855 /* VARIANT type will only work if the map only contains EET_G_*, but not UNION, VARIANT and ARRAY. */
1856 if (group_type == EET_G_VARIANT)
1860 for (i = 0; i < subtype->elements.num; ++i)
1861 if (subtype->elements.set[i].type != EET_T_UNKNOW
1862 && subtype->elements.set[i].group_type > EET_G_VAR_ARRAY
1863 && subtype->elements.set[i].group_type < EET_G_UNION)
1866 subtype->unified_type = EINA_TRUE;
1870 && subtype->unified_type
1871 && (type != EET_T_UNKNOW
1872 || group_type < EET_G_UNION))
1875 /* Sanity check done, let allocate ! */
1876 edd->elements.num++;
1877 tmp = realloc(edd->elements.set, edd->elements.num * sizeof(Eet_Data_Element));
1881 edd->elements.set = tmp;
1882 ede = &(edd->elements.set[edd->elements.num - 1]);
1884 ede->directory_name_ptr = NULL;
1887 * We do a special case when we do list,hash or whatever group of simple type.
1888 * Instead of handling it in encode/decode/dump/undump, we create an
1889 * implicit structure with only the simple type.
1891 if (group_type > EET_G_UNKNOWN
1892 && group_type < EET_G_LAST
1893 && ((type > EET_T_UNKNOW && type < EET_T_STRING)
1894 || (type > EET_T_NULL && type < EET_T_LAST))
1897 subtype = calloc(1, sizeof (Eet_Data_Descriptor));
1901 subtype->name = "implicit";
1902 subtype->size = eet_basic_codec[type - 1].size;
1903 memcpy(&subtype->func, &edd->func, sizeof(subtype->func));
1905 eet_data_descriptor_element_add(subtype,
1906 eet_basic_codec[type - 1].name,
1913 type = EET_T_UNKNOW;
1917 ede->group_type = group_type;
1918 ede->offset = offset;
1920 /* FIXME: For the time being, VAR_ARRAY, UNION and VARIANT will put the counter_offset in count. */
1921 ede->counter_offset = count;
1922 /* ede->counter_offset = counter_offset; */
1923 ede->counter_name = counter_name;
1925 ede->subtype = subtype;
1929 eet_data_read_cipher(Eet_File *ef,
1930 Eet_Data_Descriptor *edd,
1932 const char *cipher_key)
1934 const Eet_Dictionary *ed = NULL;
1935 const void *data = NULL;
1937 Eet_Free_Context context;
1938 int required_free = 0;
1941 ed = eet_dictionary_get(ef);
1944 data = eet_read_direct(ef, name, &size);
1949 data = eet_read_cipher(ef, name, &size, cipher_key);
1954 memset(&context, 0, sizeof (context));
1955 data_dec = _eet_data_descriptor_decode(&context, ed, edd, data, size);
1963 eet_data_node_read_cipher(Eet_File *ef,
1965 const char *cipher_key)
1967 const Eet_Dictionary *ed = NULL;
1968 const void *data = NULL;
1970 Eet_Free_Context context;
1971 int required_free = 0;
1974 ed = eet_dictionary_get(ef);
1977 data = eet_read_direct(ef, name, &size);
1982 data = eet_read_cipher(ef, name, &size, cipher_key);
1987 memset(&context, 0, sizeof (context));
1988 result = _eet_data_descriptor_decode(&context, ed, NULL, data, size);
1996 eet_data_read(Eet_File *ef, Eet_Data_Descriptor *edd, const char *name)
1998 return eet_data_read_cipher(ef, edd, name, NULL);
2002 eet_data_write_cipher(Eet_File *ef,
2003 Eet_Data_Descriptor *edd,
2005 const char *cipher_key,
2014 ed = eet_dictionary_get(ef);
2016 data_enc = _eet_data_descriptor_encode(ed, edd, data, &size);
2020 val = eet_write_cipher(ef, name, data_enc, size, compress, cipher_key);
2026 eet_data_write(Eet_File *ef,
2027 Eet_Data_Descriptor *edd,
2032 return eet_data_write_cipher(ef, edd, name, NULL, data, compress);
2036 _eet_free_hash(void *data)
2039 __int64 ptr = (UINT_PTR)data;
2041 unsigned long ptr = (unsigned long)(data);
2050 #if defined (_WIN64) || ((!defined (_WIN32)) && (LONG_BIT != 32))
2061 _eet_free_add(Eet_Free *ef, void *data)
2066 hash = _eet_free_hash(data);
2068 for (i = 0; i < ef->num[hash]; ++i)
2069 if (ef->list[hash][i] == data)
2073 if (ef->num[hash] > ef->len[hash])
2077 tmp = realloc(ef->list[hash], (ef->len[hash] + 16) * sizeof(void *));
2081 ef->len[hash] += 16;
2082 ef->list[hash] = tmp;
2085 ef->list[hash][ef->num[hash] - 1] = data;
2088 _eet_free_reset(Eet_Free *ef)
2095 for (i = 0; i < 256; ++i)
2106 _eet_free_ref(Eet_Free *ef)
2111 _eet_free_unref(Eet_Free *ef)
2116 #define _eet_freelist_add(Ctx, Data) _eet_free_add(&Ctx->freelist, Data);
2117 #define _eet_freelist_reset(Ctx) _eet_free_reset(&Ctx->freelist);
2118 #define _eet_freelist_ref(Ctx) _eet_free_ref(&Ctx->freelist);
2119 #define _eet_freelist_unref(Ctx) _eet_free_unref(&Ctx->freelist);
2122 _eet_freelist_free(Eet_Free_Context *context, Eet_Data_Descriptor *edd)
2127 if (context->freelist.ref > 0)
2130 for (j = 0; j < 256; ++j)
2131 for (i = 0; i < context->freelist.num[j]; ++i)
2134 edd->func.mem_free(context->freelist.list[j][i]);
2136 free(context->freelist.list[j][i]);
2138 _eet_free_reset(&context->freelist);
2141 #define _eet_freelist_list_add(Ctx, Data) _eet_free_add(&Ctx->freelist_list, \
2143 #define _eet_freelist_list_reset(Ctx) _eet_free_reset(&Ctx->freelist_list);
2144 #define _eet_freelist_list_ref(Ctx) _eet_free_ref(&Ctx->freelist_list);
2145 #define _eet_freelist_list_unref(Ctx) _eet_free_unref(&Ctx->freelist_list);
2148 _eet_freelist_list_free(Eet_Free_Context *context, Eet_Data_Descriptor *edd)
2153 if (context->freelist_list.ref > 0)
2156 for (j = 0; j < 256; ++j)
2157 for (i = 0; i < context->freelist_list.num[j]; ++i)
2160 edd->func.list_free(*((void **)(context->freelist_list.list[j][i])));
2162 _eet_free_reset(&context->freelist_list);
2165 #define _eet_freelist_str_add(Ctx, Data) _eet_free_add(&Ctx->freelist_str, \
2167 #define _eet_freelist_str_reset(Ctx) _eet_free_reset(&Ctx->freelist_str);
2168 #define _eet_freelist_str_ref(Ctx) _eet_free_ref(&Ctx->freelist_str);
2169 #define _eet_freelist_str_unref(Ctx) _eet_free_unref(&Ctx->freelist_str);
2172 _eet_freelist_str_free(Eet_Free_Context *context, Eet_Data_Descriptor *edd)
2177 if (context->freelist_str.ref > 0)
2180 for (j = 0; j < 256; ++j)
2181 for (i = 0; i < context->freelist_str.num[j]; ++i)
2184 edd->func.str_free(context->freelist_str.list[j][i]);
2186 free(context->freelist_str.list[j][i]);
2188 _eet_free_reset(&context->freelist_str);
2191 #define _eet_freelist_direct_str_add(Ctx, Data) _eet_free_add( \
2192 &Ctx->freelist_direct_str, \
2194 #define _eet_freelist_direct_str_reset(Ctx) _eet_free_reset( \
2195 &Ctx->freelist_direct_str);
2196 #define _eet_freelist_direct_str_ref(Ctx) _eet_free_ref( \
2197 &Ctx->freelist_direct_str);
2198 #define _eet_freelist_direct_str_unref(Ctx) _eet_free_unref( \
2199 &Ctx->freelist_direct_str);
2202 _eet_freelist_direct_str_free(Eet_Free_Context *context,
2203 Eet_Data_Descriptor *edd)
2208 if (context->freelist_direct_str.ref > 0)
2211 for (j = 0; j < 256; ++j)
2212 for (i = 0; i < context->freelist_direct_str.num[j]; ++i)
2215 edd->func.str_direct_free(context->freelist_direct_str.list[j][i]);
2217 free(context->freelist_direct_str.list[j][i]);
2219 _eet_free_reset(&context->freelist_direct_str);
2222 #define _eet_freelist_hash_add(Ctx, Data) _eet_free_add(&Ctx->freelist_hash, \
2224 #define _eet_freelist_hash_reset(Ctx) _eet_free_reset(&Ctx->freelist_hash);
2225 #define _eet_freelist_hash_ref(Ctx) _eet_free_ref(&Ctx->freelist_hash);
2226 #define _eet_freelist_hash_unref(Ctx) _eet_free_unref(&Ctx->freelist_hash);
2229 _eet_freelist_hash_free(Eet_Free_Context *context, Eet_Data_Descriptor *edd)
2234 if (context->freelist_hash.ref > 0)
2237 for (j = 0; j < 256; ++j)
2238 for (i = 0; i < context->freelist_hash.num[j]; ++i)
2241 edd->func.hash_free(context->freelist_hash.list[j][i]);
2243 free(context->freelist_hash.list[j][i]);
2245 _eet_free_reset(&context->freelist_hash);
2249 _eet_freelist_all_ref(Eet_Free_Context *freelist_context)
2251 _eet_freelist_ref(freelist_context);
2252 _eet_freelist_str_ref(freelist_context);
2253 _eet_freelist_list_ref(freelist_context);
2254 _eet_freelist_hash_ref(freelist_context);
2255 _eet_freelist_direct_str_ref(freelist_context);
2259 _eet_freelist_all_unref(Eet_Free_Context *freelist_context)
2261 _eet_freelist_unref(freelist_context);
2262 _eet_freelist_str_unref(freelist_context);
2263 _eet_freelist_list_unref(freelist_context);
2264 _eet_freelist_hash_unref(freelist_context);
2265 _eet_freelist_direct_str_unref(freelist_context);
2269 eet_data_descriptor_encode_hash_cb(void *hash __UNUSED__,
2270 const char *cipher_key,
2275 Eet_Data_Encode_Hash_Info *edehi;
2276 Eet_Data_Stream *ds;
2277 Eet_Data_Element *ede;
2278 Eet_Data_Chunk *echnk;
2288 data = eet_data_put_type(ed,
2294 echnk = eet_data_chunk_new(data,
2299 eet_data_chunk_put(ed, echnk, ds);
2300 eet_data_chunk_free(echnk);
2305 EET_ASSERT(!((ede->type > EET_T_UNKNOW) && (ede->type < EET_T_STRING)),
2309 if (ede->type >= EET_T_STRING)
2310 eet_data_put_unknown(ed, NULL, ede, ds, &hdata);
2314 data = _eet_data_descriptor_encode(ed,
2321 echnk = eet_data_chunk_new(data,
2326 eet_data_chunk_put(ed, echnk, ds);
2327 eet_data_chunk_free(echnk);
2337 _eet_data_dump_token_get(const char *src, int *len)
2343 int tlen = 0, tsize = 0;
2345 #define TOK_ADD(x) \
2348 if (tlen >= tsize) \
2351 tok = realloc(tok, tsize); \
2353 tok[tlen - 1] = x; \
2356 for (p = src; *len > 0; p++, (*len)--)
2362 if ((p[0] == '\"') && (p > src) && (p[-1] != '\\'))
2364 else if ((p[0] == '\\') && (*len > 1) && (p[1] == '\"'))
2368 else if ((p[0] == '\\') && (p > src) && (p[-1] == '\\'))
2372 else if ((p[0] == '\\') && (*len > 1) && (p[1] == 'n'))
2376 else if ((p[0] == 'n') && (p > src) && (p[-1] == '\\'))
2387 if ((isspace(p[0])) || (p[0] == ';')) /* token ends here */
2398 else if (!((isspace(p[0])) || (p[0] == ';')))
2418 eet_data_encode(Eet_Dictionary *ed,
2419 Eet_Data_Stream *ds,
2426 Eet_Data_Chunk *echnk;
2431 if (group_type != EET_G_UNKNOWN)
2432 if (type >= EET_T_LAST)
2433 type = EET_T_UNKNOW;
2435 echnk = eet_data_chunk_new(data, size, name, type, group_type);
2436 eet_data_chunk_put(ed, echnk, ds);
2437 eet_data_chunk_free(echnk);
2442 _eet_data_dump_encode(int parent_type,
2447 Eet_Data_Chunk *chnk = NULL;
2448 Eet_Data_Stream *ds;
2455 if (_eet_data_words_bigendian == -1)
2457 unsigned long int v;
2459 v = htonl(0x12345678);
2460 if (v == 0x12345678)
2461 _eet_data_words_bigendian = 1;
2463 _eet_data_words_bigendian = 0;
2469 ds = eet_data_stream_new();
2476 for (n = node->values; n; n = n->next)
2478 data = _eet_data_dump_encode(node->type, ed, n, &size);
2481 eet_data_stream_write(ds, data, size);
2488 case EET_G_VAR_ARRAY:
2489 for (child_type = EET_T_NULL, n = node->values; n; n = n->next)
2491 if (n->type != EET_T_NULL)
2493 child_type = n->type;
2498 data = eet_data_put_type(ed,
2510 count = node->count;
2512 for (n = node->values; n; n = n->next)
2519 case EET_T_INLINED_STRING:
2520 data = eet_data_put_type(ed,
2522 &(n->data.value.str),
2539 data = _eet_data_dump_encode(n->type, ed, n, &size);
2553 for (; count; count--)
2564 /* Array is somekind of special case, so we should embed it inside another chunk. */
2565 *size_ret = ds->pos;
2570 eet_data_stream_free(ds);
2576 for (n = node->values; n; n = n->next)
2581 case EET_T_INLINED_STRING:
2582 data = eet_data_put_type(ed,
2584 &(n->data.value.str),
2601 data = _eet_data_dump_encode(node->type, ed, n, &size);
2612 /* List is another somekind of special case, every chunk is embed inside a list chunk. */
2613 *size_ret = ds->pos;
2618 eet_data_stream_free(ds);
2626 data = eet_data_put_type(ed,
2639 /* A Hash without key will not decode correctly. */
2642 for (n = node->values; n; n = n->next)
2647 case EET_T_INLINED_STRING:
2648 data = eet_data_put_type(ed,
2650 &(n->data.value.str),
2667 data = _eet_data_dump_encode(node->type, ed, n, &size);
2678 /* Hash is somekind of special case, so we should embed it inside another chunk. */
2679 *size_ret = ds->pos;
2682 eet_data_stream_flush(ds);
2689 #define EET_DATA_NODE_ENCODE(Eet_Type, Type) \
2691 data = eet_data_put_type(ed, node->type, &(node->data.value.Type), &size); \
2694 eet_data_encode(ed, \
2702 *size_ret = ds->pos; \
2703 eet_data_stream_flush(ds); \
2708 EET_DATA_NODE_ENCODE(EET_T_CHAR, c);
2709 EET_DATA_NODE_ENCODE(EET_T_SHORT, s);
2710 EET_DATA_NODE_ENCODE(EET_T_INT, i);
2711 EET_DATA_NODE_ENCODE(EET_T_LONG_LONG, l);
2712 EET_DATA_NODE_ENCODE(EET_T_FLOAT, f);
2713 EET_DATA_NODE_ENCODE(EET_T_DOUBLE, d);
2714 EET_DATA_NODE_ENCODE(EET_T_UCHAR, uc);
2715 EET_DATA_NODE_ENCODE(EET_T_USHORT, us);
2716 EET_DATA_NODE_ENCODE(EET_T_UINT, ui);
2717 EET_DATA_NODE_ENCODE(EET_T_ULONG_LONG, ul);
2718 EET_DATA_NODE_ENCODE(EET_T_INLINED_STRING, str);
2719 EET_DATA_NODE_ENCODE(EET_T_STRING, str);
2725 if ((node->type >= EET_G_UNKNOWN) && (node->type < EET_G_LAST))
2726 chnk = eet_data_chunk_new(ds->data,
2732 chnk = eet_data_chunk_new(ds->data,
2738 eet_data_stream_flush(ds);
2740 ds = eet_data_stream_new();
2741 eet_data_chunk_put(ed, chnk, ds);
2745 eet_data_stream_flush(ds);
2749 eet_data_chunk_free(chnk);
2755 _eet_data_dump_parse(Eet_Dictionary *ed,
2761 const char *p = NULL;
2766 Eet_Node *node_base = NULL;
2767 Eet_Node *node = NULL;
2768 Eet_Node *n = NULL, *nn = NULL;
2770 /* FIXME; handle parse errors */
2771 #define TOK_GET(t) \
2772 jump = left; t = _eet_data_dump_token_get(p, &left); p += jump - left;
2774 for (p = src; p < (src + size); )
2776 char *tok1, *tok2, *tok3, *tok4;
2781 if (!strcmp(tok1, "group"))
2792 if (!strcmp(tok4, "{"))
2794 /* we have 'group NAM TYP {' */
2808 for (nn = node->values; nn;
2819 n->name = eina_stringshare_add(tok2);
2820 if (!strcmp(tok3, "struct"))
2821 n->type = EET_G_UNKNOWN;
2822 else if (!strcmp(tok3, "array"))
2823 n->type = EET_G_ARRAY;
2824 else if (!strcmp(tok3, "var_array"))
2825 n->type = EET_G_VAR_ARRAY;
2826 else if (!strcmp(tok3, "list"))
2827 n->type = EET_G_LIST;
2828 else if (!strcmp(tok3, "hash"))
2829 n->type = EET_G_HASH;
2832 "ERROR: group type '%s' invalid.",
2848 else if (!strcmp(tok1, "value"))
2859 /* we have 'value NAME TYP XXX' */
2870 for (nn = node->values; nn;
2880 n->name = eina_stringshare_add(tok2);
2881 if (!strcmp(tok3, "char:"))
2883 n->type = EET_T_CHAR;
2884 sscanf(tok4, "%hhi",
2885 &(n->data.value.c));
2887 else if (!strcmp(tok3, "short:"))
2889 n->type = EET_T_SHORT;
2891 &(n->data.value.s));
2893 else if (!strcmp(tok3, "int:"))
2895 n->type = EET_T_INT;
2897 &(n->data.value.i));
2899 else if (!strcmp(tok3, "long_long:"))
2901 n->type = EET_T_LONG_LONG;
2902 sscanf(tok4, "%lli",
2903 &(n->data.value.l));
2905 else if (!strcmp(tok3, "float:"))
2907 n->type = EET_T_FLOAT;
2909 &(n->data.value.f));
2911 else if (!strcmp(tok3, "double:"))
2913 n->type = EET_T_DOUBLE;
2915 &(n->data.value.d));
2917 else if (!strcmp(tok3, "uchar:"))
2919 n->type = EET_T_UCHAR;
2920 sscanf(tok4, "%hhu",
2921 &(n->data.value.uc));
2923 else if (!strcmp(tok3, "ushort:"))
2925 n->type = EET_T_USHORT;
2927 &(n->data.value.us));
2929 else if (!strcmp(tok3, "uint:"))
2931 n->type = EET_T_UINT;
2933 &(n->data.value.ui));
2935 else if (!strcmp(tok3, "ulong_long:"))
2937 n->type = EET_T_ULONG_LONG;
2938 sscanf(tok4, "%llu",
2939 &(n->data.value.ul));
2941 else if (!strcmp(tok3, "string:"))
2943 n->type = EET_T_STRING;
2945 eina_stringshare_add(tok4);
2947 else if (!strcmp(tok3, "inlined:"))
2949 n->type = EET_T_INLINED_STRING;
2951 eina_stringshare_add(tok4);
2953 else if (!strcmp(tok3, "null"))
2955 n->type = EET_T_NULL;
2956 n->data.value.str = NULL;
2960 "ERROR: value type '%s' invalid.",
2974 else if (!strcmp(tok1, "key"))
2979 /* we have 'key NAME' */
2981 node->key = eina_stringshare_add(tok2);
2986 else if (!strcmp(tok1, "count"))
2991 /* we have a 'count COUNT' */
2993 sscanf(tok2, "%i", &(node->count));
2998 else if (!strcmp(tok1, "}"))
2999 /* we have an end of the group */
3001 node = node->parent;
3009 cdata = _eet_data_dump_encode(EET_G_UNKNOWN, ed, node_base, size_ret);
3010 eet_node_del(node_base);
3016 #define NEXT_CHUNK(P, Size, Echnk, Ed) \
3019 tmp = Ed ? (int)(sizeof(int) * 2) : Echnk.len + 4; \
3020 P += (4 + Echnk.size + tmp); \
3021 Size -= (4 + Echnk.size + tmp); \
3025 _eet_data_descriptor_decode(Eet_Free_Context *context,
3026 const Eet_Dictionary *ed,
3027 Eet_Data_Descriptor *edd,
3028 const void *data_in,
3031 Eet_Node *result = NULL;
3035 Eet_Data_Chunk chnk;
3037 if (_eet_data_words_bigendian == -1)
3039 unsigned long int v;
3041 v = htonl(0x12345678);
3042 if (v == 0x12345678)
3043 _eet_data_words_bigendian = 1;
3045 _eet_data_words_bigendian = 0;
3050 data = edd->func.mem_alloc(edd->size);
3056 for (i = 0; i < edd->elements.num; i++)
3057 edd->elements.set[i].directory_name_ptr = NULL;
3062 _eet_freelist_all_ref(context);
3064 _eet_freelist_add(context, data);
3066 memset(&chnk, 0, sizeof(Eet_Data_Chunk));
3067 eet_data_chunk_get(ed, &chnk, data_in, size_in);
3072 if (strcmp(chnk.name, edd->name))
3077 size = size_in - (4 + sizeof(int) * 2);
3079 size = size_in - (4 + 4 + chnk.len);
3083 if (!edd->elements.hash.buckets)
3084 _eet_descriptor_hash_new(edd);
3088 switch (chnk.group_type)
3094 return eet_node_string_new(chnk.name, chnk.data);
3096 case EET_T_INLINED_STRING:
3097 return eet_node_inlined_string_new(chnk.name, chnk.data);
3100 return eet_node_null_new(chnk.name);
3103 result = eet_node_struct_new(chnk.name, NULL);
3107 case EET_G_VAR_ARRAY:
3108 return eet_node_var_array_new(chnk.name, NULL);
3122 Eet_Data_Chunk echnk;
3123 Eet_Data_Element *ede = NULL;
3124 Eet_Node *child = NULL;
3125 int group_type = EET_G_UNKNOWN, type = EET_T_UNKNOW;
3128 /* get next data chunk */
3129 memset(&echnk, 0, sizeof(Eet_Data_Chunk));
3130 eet_data_chunk_get(ed, &echnk, p, size);
3132 goto error; /* FIXME: don't REPLY on edd - work without */
3136 ede = _eet_descriptor_hash_find(edd, echnk.name, echnk.hash);
3139 group_type = ede->group_type;
3141 if ((echnk.type == 0) && (echnk.group_type == 0))
3144 group_type = ede->group_type;
3148 if (IS_SIMPLE_TYPE(echnk.type) &&
3149 eet_data_type_match(echnk.type, ede->type))
3150 /* Needed when converting on the fly from FP to Float */
3152 else if ((echnk.group_type > EET_G_UNKNOWN) &&
3153 (echnk.group_type < EET_G_LAST) &&
3154 (echnk.group_type == ede->group_type))
3155 group_type = echnk.group_type;
3159 /*...... dump to node */
3163 group_type = echnk.group_type;
3166 if (!edd && group_type == EET_G_UNKNOWN && IS_SIMPLE_TYPE(type))
3168 unsigned char dd[128];
3170 ret = eet_data_get_type(ed,
3173 ((char *)echnk.data) + echnk.size,
3178 child = eet_data_node_simple_type(type, echnk.name, dd);
3180 eet_node_struct_append(result, echnk.name, child);
3184 ret = eet_group_codec[group_type - 100].get(
3192 ede ? (void *)(((char
3205 /* advance to next chunk */
3206 NEXT_CHUNK(p, size, echnk, ed);
3209 _eet_freelist_all_unref(context);
3212 _eet_freelist_str_free(context, edd);
3213 _eet_freelist_direct_str_free(context, edd);
3214 _eet_freelist_list_free(context, edd);
3215 _eet_freelist_hash_free(context, edd);
3216 _eet_freelist_free(context, edd);
3220 _eet_freelist_reset(context);
3221 _eet_freelist_str_reset(context);
3222 _eet_freelist_list_reset(context);
3223 _eet_freelist_hash_reset(context);
3224 _eet_freelist_direct_str_reset(context);
3233 eet_node_del(result);
3235 _eet_freelist_all_unref(context);
3236 _eet_freelist_str_free(context, edd);
3237 _eet_freelist_direct_str_free(context, edd);
3238 _eet_freelist_list_free(context, edd);
3239 _eet_freelist_hash_free(context, edd);
3240 _eet_freelist_free(context, edd);
3242 /* FIXME: Warn that something goes wrong here. */
3247 eet_data_get_list(Eet_Free_Context *context,
3248 const Eet_Dictionary *ed,
3249 Eet_Data_Descriptor *edd,
3250 Eet_Data_Element *ede,
3251 Eet_Data_Chunk *echnk,
3253 int group_type __UNUSED__,
3258 Eet_Data_Descriptor *subtype = NULL;
3263 EET_ASSERT(!((type > EET_T_UNKNOW) && (type < EET_T_STRING)), return 0);
3267 subtype = ede->subtype;
3269 if (type != ede->type)
3273 ptr = (void **)data;
3277 if (IS_POINTER_TYPE(type))
3278 POINTER_TYPE_DECODE(context,
3289 STRUCT_TYPE_DECODE(data_ret,
3299 list = edd->func.list_append(list, data_ret);
3301 _eet_freelist_list_add(context, ptr);
3304 eet_node_list_append(*((Eet_Node **)data), echnk->name, data_ret);
3313 eet_data_get_hash(Eet_Free_Context *context,
3314 const Eet_Dictionary *ed,
3315 Eet_Data_Descriptor *edd,
3316 Eet_Data_Element *ede,
3317 Eet_Data_Chunk *echnk,
3319 int group_type __UNUSED__,
3327 void *data_ret = NULL;
3330 EET_ASSERT(!((type > EET_T_UNKNOW) && (type < EET_T_STRING)), return 0);
3332 ptr = (void **)data;
3336 ret = eet_data_get_type(ed,
3339 ((char *)echnk->data) + echnk->size,
3344 /* Advance to next chunk */
3345 NEXT_CHUNK((*p), (*size), (*echnk), ed);
3346 memset(echnk, 0, sizeof(Eet_Data_Chunk));
3349 eet_data_chunk_get(ed, echnk, *p, *size);
3353 if (IS_POINTER_TYPE(echnk->type))
3354 POINTER_TYPE_DECODE(context,
3365 STRUCT_TYPE_DECODE(data_ret,
3368 ede ? ede->subtype : NULL,
3375 hash = edd->func.hash_add(hash, key, data_ret);
3377 _eet_freelist_hash_add(context, hash);
3380 eet_node_hash_add(*((Eet_Node **)data), echnk->name, key, data_ret);
3388 /* var arrays and fixed arrays have to
3389 * get all chunks at once. for fixed arrays
3390 * we can get each chunk and increment a
3391 * counter stored on the element itself but
3392 * it wont be thread safe. for var arrays
3393 * we still need a way to get the number of
3394 * elements from the data, so storing the
3395 * number of elements and the element data on
3396 * each chunk is pointless.
3399 eet_data_get_array(Eet_Free_Context *context,
3400 const Eet_Dictionary *ed,
3401 Eet_Data_Descriptor *edd,
3402 Eet_Data_Element *ede,
3403 Eet_Data_Chunk *echnk,
3410 Eina_List *childs = NULL;
3419 EET_ASSERT(!((type > EET_T_UNKNOW) && (type < EET_T_STRING)), return 0);
3422 /* read the number of elements */
3423 ret = eet_data_get_type(ed,
3426 ((char *)echnk->data) + echnk->size,
3435 if (IS_POINTER_TYPE(type))
3436 subsize = eet_basic_codec[ede->type].size;
3438 subsize = ede->subtype->size;
3440 if (group_type == EET_G_VAR_ARRAY)
3442 /* store the number of elements
3443 * on the counter offset */
3444 *(int *)(((char *)data) + ede->count - ede->offset) = count;
3445 /* allocate space for the array of elements */
3446 *(void **)ptr = edd->func.mem_alloc(count * subsize);
3451 memset(*(void **)ptr, 0, count * subsize);
3453 _eet_freelist_add(context, *(void **)ptr);
3457 /* get all array elements */
3458 for (i = 0; i < count; i++)
3461 void *data_ret = NULL;
3463 /* Advance to next chunk */
3464 NEXT_CHUNK((*p), (*size), (*echnk), ed);
3465 memset(echnk, 0, sizeof(Eet_Data_Chunk));
3467 eet_data_chunk_get(ed, echnk, *p, *size);
3468 if (!echnk->name || strcmp(echnk->name, name) != 0)
3469 goto on_error; /* get the data */
3471 if (echnk->group_type != group_type
3472 || (echnk->type != type && echnk->type != EET_T_NULL))
3476 if (ede->group_type != echnk->group_type
3477 || (echnk->type != ede->type && echnk->type != EET_T_NULL))
3480 /* get the destination pointer */
3483 if (group_type == EET_G_ARRAY)
3484 dst = (char *)ptr + (subsize * i);
3486 dst = *(char **)ptr + (subsize * i);
3489 if (IS_POINTER_TYPE(echnk->type))
3491 POINTER_TYPE_DECODE(context,
3502 memcpy(dst, &data_ret, subsize);
3505 childs = eina_list_append(childs, data_ret);
3509 STRUCT_TYPE_DECODE(data_ret,
3512 ede ? ede->subtype : NULL,
3518 memcpy(dst, data_ret, subsize);
3519 _eet_freelist_add(context, data_ret);
3523 childs = eina_list_append(childs, data_ret);
3529 Eet_Node *parent = *((Eet_Node **)data);
3532 if (group_type == EET_G_ARRAY)
3533 array = eet_node_array_new(name, count, childs);
3535 array = eet_node_var_array_new(name, childs);
3540 eet_node_struct_append(parent, name, array);
3546 EINA_LIST_FREE(childs, tmp)
3553 eet_data_put_union(Eet_Dictionary *ed,
3554 Eet_Data_Descriptor *edd __UNUSED__,
3555 Eet_Data_Element *ede, Eet_Data_Stream *ds, void *data_in)
3557 const char *union_type;
3560 EET_ASSERT(!((ede->type != EET_T_UNKNOW) || (!ede->subtype)), return );
3562 union_type = ede->subtype->func.type_get(
3563 ((char *)data_in) + ede->count - ede->offset,
3569 /* Search the structure of the union to encode. */
3570 for (i = 0; i < ede->subtype->elements.num; ++i)
3571 if (strcmp(ede->subtype->elements.set[i].name, union_type) == 0)
3573 Eet_Data_Element *sede;
3577 /* Yeah we found it ! */
3578 data = eet_data_put_type(ed, EET_T_STRING, &union_type, &size);
3588 sede = &(ede->subtype->elements.set[i]);
3589 data = _eet_data_descriptor_encode(ed,
3608 eet_data_get_union(Eet_Free_Context *context, const Eet_Dictionary *ed,
3609 Eet_Data_Descriptor *edd __UNUSED__,
3610 Eet_Data_Element *ede, Eet_Data_Chunk *echnk,
3611 int type, int group_type, void *data,
3612 char **p, int *size)
3614 const char *union_type;
3615 void *data_ret = NULL;
3620 ret = eet_data_get_type(ed,
3623 ((char *)echnk->data) + echnk->size,
3628 /* Advance to next chunk */
3629 NEXT_CHUNK((*p), (*size), (*echnk), ed);
3630 memset(echnk, 0, sizeof(Eet_Data_Chunk));
3633 eet_data_chunk_get(ed, echnk, *p, *size);
3639 EET_ASSERT(!(ede->group_type != group_type || ede->type != type),
3642 /* Search the structure of the union to decode */
3643 for (i = 0; i < ede->subtype->elements.num; ++i)
3644 if (strcmp(ede->subtype->elements.set[i].name, union_type) == 0)
3646 Eet_Data_Element *sede;
3649 /* Yeah we found it ! */
3650 sede = &(ede->subtype->elements.set[i]);
3651 EET_ASSERT(sede->subtype, goto on_error);
3653 data_ret = _eet_data_descriptor_decode(context,
3661 /* Memcopy the structure content to remove pointer indirection. */
3662 memcpy(data, data_ret, sede->subtype->size);
3664 /* data_ret is now useless. */
3665 sede->subtype->func.mem_free(data_ret);
3667 /* Set union type. */
3668 if ((!ed) || (!ede->subtype->func.str_direct_alloc))
3670 ut = ede->subtype->func.str_alloc(union_type);
3671 _eet_freelist_str_add(context, ut);
3675 ut = ede->subtype->func.str_direct_alloc(union_type);
3676 _eet_freelist_direct_str_add(context, ut);
3679 ede->subtype->func.type_set(
3681 ((char *)data) + ede->count -
3691 /* FIXME: generate node structure. */
3692 data_ret = _eet_data_descriptor_decode(context,
3694 echnk->data, echnk->size);
3705 eet_data_put_variant(Eet_Dictionary *ed,
3706 Eet_Data_Descriptor *edd __UNUSED__,
3707 Eet_Data_Element *ede, Eet_Data_Stream *ds, void *data_in)
3709 const char *union_type;
3711 Eina_Bool unknow = EINA_FALSE;
3715 EET_ASSERT(!((ede->type != EET_T_UNKNOW) || (!ede->subtype)), return );
3717 union_type = ede->subtype->func.type_get(
3718 ((char *)data_in) + ede->count - ede->offset,
3721 if (!union_type && unknow == EINA_FALSE)
3726 /* Handle opaque internal representation */
3727 Eet_Variant_Unknow *evu;
3729 data = eet_data_put_type(ed, EET_T_STRING, &union_type, &size);
3739 evu = (Eet_Variant_Unknow *)data_in;
3740 if (evu && EINA_MAGIC_CHECK(evu, EET_MAGIC_VARIANT))
3750 /* Search the structure of the union to encode. */
3751 for (i = 0; i < ede->subtype->elements.num; ++i)
3752 if (strcmp(ede->subtype->elements.set[i].name, union_type) == 0)
3754 Eet_Data_Element *sede;
3756 /* Yeah we found it ! */
3757 data = eet_data_put_type(ed, EET_T_STRING, &union_type, &size);
3767 sede = &(ede->subtype->elements.set[i]);
3769 if (sede->group_type != EET_G_UNKNOWN)
3771 Eet_Data_Stream *lds;
3773 lds = eet_data_stream_new();
3774 eet_group_codec[sede->group_type - 100].put(ed,
3781 eet_data_encode(ed, ds, lds->data, ede->name, lds->pos,
3782 ede->type, ede->group_type);
3788 eet_data_encode(ed, ds, NULL, ede->name, 0,
3789 EET_T_NULL, ede->group_type);
3791 eet_data_stream_free(lds);
3795 data = _eet_data_descriptor_encode(ed,
3815 eet_data_get_variant(Eet_Free_Context *context, const Eet_Dictionary *ed,
3816 Eet_Data_Descriptor *edd __UNUSED__,
3817 Eet_Data_Element *ede, Eet_Data_Chunk *echnk,
3818 int type __UNUSED__, int group_type __UNUSED__, void *data,
3819 char **p, int *size)
3821 const char *union_type;
3822 void *data_ret = NULL;
3827 ret = eet_data_get_type(ed,
3830 ((char *)echnk->data) + echnk->size,
3835 /* Advance to next chunk */
3836 NEXT_CHUNK((*p), (*size), (*echnk), ed);
3837 memset(echnk, 0, sizeof(Eet_Data_Chunk));
3840 eet_data_chunk_get(ed, echnk, *p, *size);
3848 EET_ASSERT(ede->subtype, goto on_error);
3850 if ((!ed) || (!ede->subtype->func.str_direct_alloc))
3852 ut = ede->subtype->func.str_alloc(union_type);
3853 _eet_freelist_str_add(context, ut);
3857 ut = ede->subtype->func.str_direct_alloc(union_type);
3858 _eet_freelist_direct_str_add(context, ut);
3861 /* Search the structure of the union to decode */
3862 for (i = 0; i < ede->subtype->elements.num; ++i)
3863 if (strcmp(ede->subtype->elements.set[i].name, union_type) == 0)
3865 Eet_Data_Element *sede;
3867 /* Yeah we found it ! */
3868 sede = &(ede->subtype->elements.set[i]);
3870 if (sede->group_type != EET_G_UNKNOWN)
3872 Eet_Data_Chunk chnk;
3878 size2 = echnk->size;
3880 /* Didn't find a proper way to provide this
3881 without duplicating code */
3884 memset(&chnk, 0, sizeof(Eet_Data_Chunk));
3885 eet_data_chunk_get(ed, &chnk, p2, size2);
3890 ret = eet_group_codec[sede->group_type - 100].get(
3906 /* advance to next chunk */
3907 NEXT_CHUNK(p2, size2, chnk, ed);
3910 /* Put garbage so that we will not put eet_variant_unknow in it */
3911 data_ret = (void *)data;
3913 /* Set variant type. */
3914 ede->subtype->func.type_set(
3916 ((char *)data) + ede->count -
3922 data_ret = _eet_data_descriptor_decode(context,
3930 /* And point to the variant data. */
3931 *(void **)data = data_ret;
3933 /* Set variant type. */
3934 ede->subtype->func.type_set(
3936 ((char *)data) + ede->count -
3944 Eet_Variant_Unknow *evu;
3946 evu = calloc(1, sizeof (Eet_Variant_Unknow) + echnk->size - 1);
3950 evu->size = echnk->size;
3951 memcpy(evu->data, echnk->data, evu->size);
3952 EINA_MAGIC_SET(evu, EET_MAGIC_VARIANT);
3954 /* And point to the opaque internal data scructure */
3955 *(void **)data = evu;
3957 /* Set variant type. */
3958 ede->subtype->func.type_set(
3960 ((char *)data) + ede->count -
3967 /* FIXME: dump node structure. */
3968 data_ret = _eet_data_descriptor_decode(context,
3970 echnk->data, echnk->size);
3981 eet_data_node_simple_type(int type, const char *name, void *dd)
3987 #define EET_T_TYPE(Eet_Type, Eet_Node_Type, Type) \
3989 return eet_node_ ## Eet_Node_Type ## _new(name, *((Type *)dd)); \
3993 EET_T_TYPE(EET_T_CHAR, char, char);
3994 EET_T_TYPE(EET_T_SHORT, short, short);
3995 EET_T_TYPE(EET_T_INT, int, int);
3996 EET_T_TYPE(EET_T_LONG_LONG, long_long, long long);
3997 EET_T_TYPE(EET_T_FLOAT, float, float);
3998 EET_T_TYPE(EET_T_DOUBLE, double, double);
3999 EET_T_TYPE(EET_T_UCHAR, unsigned_char, unsigned char);
4000 EET_T_TYPE(EET_T_USHORT, unsigned_short, unsigned short);
4001 EET_T_TYPE(EET_T_UINT, unsigned_int, unsigned int);
4002 EET_T_TYPE(EET_T_ULONG_LONG, unsigned_long_long, unsigned long long);
4003 EET_T_TYPE(EET_T_STRING, string, char *);
4004 EET_T_TYPE(EET_T_INLINED_STRING, inlined_string, char *);
4007 return eet_node_null_new(name);
4010 ERR("Unknow type passed to eet_data_node_simple_type");
4016 eet_data_get_unknown(Eet_Free_Context *context,
4017 const Eet_Dictionary *ed,
4018 Eet_Data_Descriptor *edd,
4019 Eet_Data_Element *ede,
4020 Eet_Data_Chunk *echnk,
4022 int group_type __UNUSED__,
4024 char **p __UNUSED__,
4025 int *size __UNUSED__)
4030 if (IS_SIMPLE_TYPE(type))
4032 unsigned char dd[128];
4034 ret = eet_data_get_type(ed,
4037 ((char *)echnk->data) + echnk->size,
4038 edd ? (char *)data : (char *)dd);
4044 Eet_Node **parent = data;
4047 node = eet_data_node_simple_type(type, echnk->name, dd);
4050 eet_node_struct_append(*parent, echnk->name, node);
4056 if (type == EET_T_STRING)
4060 str = (char **)(((char *)data));
4063 if ((ed == NULL) || (edd->func.str_direct_alloc == NULL))
4065 *str = edd->func.str_alloc(*str);
4066 _eet_freelist_str_add(context, *str);
4070 *str = edd->func.str_direct_alloc(*str);
4071 _eet_freelist_direct_str_add(context, *str);
4075 else if (edd && type == EET_T_INLINED_STRING)
4079 str = (char **)(((char *)data));
4082 *str = edd->func.str_alloc(*str);
4083 _eet_freelist_str_add(context, *str);
4090 Eet_Data_Descriptor *subtype;
4092 subtype = ede ? ede->subtype : NULL;
4094 if (subtype || !edd)
4096 Eet_Node **parent = data;
4099 data_ret = _eet_data_descriptor_decode(context,
4109 ptr = (void **)(((char *)data));
4110 *ptr = (void *)data_ret;
4114 Eet_Node *node = data_ret;
4118 node = eet_node_struct_child_new(echnk->name, node);
4119 eet_node_struct_append(*parent, echnk->name, node);
4131 eet_data_put_array(Eet_Dictionary *ed,
4132 Eet_Data_Descriptor *edd __UNUSED__,
4133 Eet_Data_Element *ede,
4134 Eet_Data_Stream *ds,
4144 EET_ASSERT(!((ede->type > EET_T_UNKNOW) && (ede->type < EET_T_STRING)),
4147 if (ede->group_type == EET_G_ARRAY)
4148 count = ede->counter_offset;
4150 count = *(int *)(((char *)data_in) + ede->count - ede->offset);
4153 return; /* Store number of elements */
4155 data = eet_data_put_type(ed, EET_T_INT, &count, &size);
4157 eet_data_encode(ed, ds, data, ede->name, size, ede->type, ede->group_type);
4159 if (IS_POINTER_TYPE(ede->type))
4160 subsize = eet_basic_codec[ede->type].size;
4162 subsize = ede->subtype->size;
4164 for (j = 0; j < count; j++)
4169 if (ede->group_type == EET_G_ARRAY)
4170 d = (void *)(((char *)data_in) + offset);
4172 d = *(((char **)data_in)) + offset;
4174 if (IS_POINTER_TYPE(ede->type))
4177 eet_data_put_unknown(ed, NULL, ede, ds, d);
4181 data = _eet_data_descriptor_encode(ed, ede->subtype, d, &size);
4193 /* Add a NULL element just to have the correct array layout. */
4207 eet_data_put_unknown(Eet_Dictionary *ed,
4208 Eet_Data_Descriptor *edd __UNUSED__,
4209 Eet_Data_Element *ede,
4210 Eet_Data_Stream *ds,
4216 if (IS_SIMPLE_TYPE(ede->type))
4217 data = eet_data_put_type(ed, ede->type, data_in, &size);
4218 else if (ede->subtype)
4219 if (*((char **)data_in))
4220 data = _eet_data_descriptor_encode(ed,
4222 *((char **)((char *)(data_in))),
4236 eet_data_put_list(Eet_Dictionary *ed,
4237 Eet_Data_Descriptor *edd,
4238 Eet_Data_Element *ede,
4239 Eet_Data_Stream *ds,
4246 EET_ASSERT(!(((ede->type > EET_T_UNKNOW) && (ede->type < EET_T_STRING))
4247 || ((ede->type > EET_T_NULL) && (ede->type < EET_T_LAST))),
4250 l = *((void **)(((char *)data_in)));
4251 for (; l; l = edd->func.list_next(l))
4253 if (IS_POINTER_TYPE(ede->type))
4255 const void *str = edd->func.list_data(l);
4256 eet_data_put_unknown(ed, NULL, ede, ds, &str);
4260 data = _eet_data_descriptor_encode(ed,
4262 edd->func.list_data(l),
4277 eet_data_put_hash(Eet_Dictionary *ed,
4278 Eet_Data_Descriptor *edd,
4279 Eet_Data_Element *ede,
4280 Eet_Data_Stream *ds,
4283 Eet_Data_Encode_Hash_Info fdata;
4286 l = *((void **)(((char *)data_in)));
4290 edd->func.hash_foreach(l, eet_data_descriptor_encode_hash_cb, &fdata);
4294 eet_data_dump_cipher(Eet_File *ef,
4295 const char *name, const char *cipher_key,
4296 void (*dumpfunc)(void *data, const char *str),
4299 const Eet_Dictionary *ed = NULL;
4300 const void *data = NULL;
4302 Eet_Free_Context context;
4303 int required_free = 0;
4306 ed = eet_dictionary_get(ef);
4309 data = eet_read_direct(ef, name, &size);
4314 data = eet_read_cipher(ef, name, &size, cipher_key);
4319 memset(&context, 0, sizeof (context));
4320 result = _eet_data_descriptor_decode(&context, ed, NULL, data, size);
4322 eet_node_dump(result, 0, dumpfunc, dumpdata);
4324 eet_node_del(result);
4329 return result ? 1 : 0;
4333 eet_data_dump(Eet_File *ef,
4335 void (*dumpfunc)(void *data, const char *str),
4338 return eet_data_dump_cipher(ef, name, NULL, dumpfunc, dumpdata);
4343 eet_data_text_dump_cipher(const void *data_in,
4344 const char *cipher_key, int size_in,
4345 void (*dumpfunc)(void *data, const char *str),
4350 Eet_Free_Context context;
4351 unsigned int ret_len = 0;
4358 if (eet_decipher(data_in, size_in, cipher_key,
4359 strlen(cipher_key), &ret, &ret_len))
4369 ret = (void *)data_in;
4373 memset(&context, 0, sizeof (context));
4374 result = _eet_data_descriptor_decode(&context, NULL, NULL, ret, ret_len);
4376 eet_node_dump(result, 0, dumpfunc, dumpdata);
4378 eet_node_del(result);
4382 return result ? 1 : 0;
4386 eet_data_text_dump(const void *data_in,
4388 void (*dumpfunc)(void *data, const char *str),
4391 return eet_data_text_dump_cipher(data_in, NULL, size_in, dumpfunc, dumpdata);
4395 eet_data_text_undump_cipher(const char *text,
4396 const char *cipher_key,
4402 ret = _eet_data_dump_parse(NULL, size_ret, text, textlen);
4403 if (ret && cipher_key)
4405 void *ciphered = NULL;
4406 unsigned int ciphered_len;
4408 if (eet_cipher(ret, *size_ret, cipher_key,
4409 strlen(cipher_key), &ciphered, &ciphered_len))
4420 *size_ret = ciphered_len;
4428 eet_data_text_undump(const char *text,
4432 return eet_data_text_undump_cipher(text, NULL, textlen, size_ret);
4436 eet_data_undump_cipher(Eet_File *ef,
4438 const char *cipher_key,
4448 ed = eet_dictionary_get(ef);
4450 data_enc = _eet_data_dump_parse(ed, &size, text, textlen);
4454 val = eet_write_cipher(ef, name, data_enc, size, compress, cipher_key);
4460 eet_data_undump(Eet_File *ef,
4466 return eet_data_undump_cipher(ef, name, NULL, text, textlen, compress);
4470 eet_data_descriptor_decode_cipher(Eet_Data_Descriptor *edd,
4471 const void *data_in,
4472 const char *cipher_key,
4475 void *deciphered = (void *)data_in;
4477 Eet_Free_Context context;
4478 unsigned int deciphered_len = size_in;
4480 if (cipher_key && data_in)
4481 if (eet_decipher(data_in, size_in, cipher_key,
4482 strlen(cipher_key), &deciphered, &deciphered_len))
4490 memset(&context, 0, sizeof (context));
4491 ret = _eet_data_descriptor_decode(&context,
4497 if (data_in != deciphered)
4504 eet_data_descriptor_decode(Eet_Data_Descriptor *edd,
4505 const void *data_in,
4508 return eet_data_descriptor_decode_cipher(edd, data_in, NULL, size_in);
4512 eet_data_node_decode_cipher(const void *data_in,
4513 const char *cipher_key,
4516 void *deciphered = (void *)data_in;
4518 Eet_Free_Context context;
4519 unsigned int deciphered_len = size_in;
4521 if (cipher_key && data_in)
4522 if (eet_decipher(data_in, size_in, cipher_key,
4523 strlen(cipher_key), &deciphered, &deciphered_len))
4531 memset(&context, 0, sizeof (context));
4532 ret = _eet_data_descriptor_decode(&context,
4538 if (data_in != deciphered)
4545 _eet_data_descriptor_encode(Eet_Dictionary *ed,
4546 Eet_Data_Descriptor *edd,
4547 const void *data_in,
4550 Eet_Data_Stream *ds;
4551 Eet_Data_Chunk *chnk;
4556 if (_eet_data_words_bigendian == -1)
4558 unsigned long int v;
4560 v = htonl(0x12345678);
4561 if (v == 0x12345678)
4562 _eet_data_words_bigendian = 1;
4564 _eet_data_words_bigendian = 0;
4567 ds = eet_data_stream_new();
4568 for (i = 0; i < edd->elements.num; i++)
4570 Eet_Data_Element *ede;
4572 ede = &(edd->elements.set[i]);
4573 eet_group_codec[ede->group_type - 100].put(
4581 chnk = eet_data_chunk_new(ds->data,
4588 eet_data_stream_free(ds);
4590 ds = eet_data_stream_new();
4591 eet_data_chunk_put(ed, chnk, ds);
4597 eet_data_stream_free(ds);
4601 eet_data_chunk_free(chnk);
4607 eet_data_node_write_cipher(Eet_File *ef,
4609 const char *cipher_key,
4618 ed = eet_dictionary_get(ef);
4620 data_enc = _eet_data_dump_encode(EET_G_UNKNOWN, ed, node, &size);
4624 val = eet_write_cipher(ef, name, data_enc, size, compress, cipher_key);
4630 eet_data_node_encode_cipher(Eet_Node *node,
4631 const char *cipher_key,
4635 void *ciphered = NULL;
4636 unsigned int ciphered_len = 0;
4639 ret = _eet_data_dump_encode(EET_G_UNKNOWN, NULL, node, &size);
4640 if (cipher_key && ret)
4642 if (eet_cipher(ret, size, cipher_key,
4643 strlen(cipher_key), &ciphered, &ciphered_len))
4656 size = (int)ciphered_len;
4667 eet_data_descriptor_encode_cipher(Eet_Data_Descriptor *edd,
4668 const void *data_in,
4669 const char *cipher_key,
4673 void *ciphered = NULL;
4674 unsigned int ciphered_len = 0;
4677 ret = _eet_data_descriptor_encode(NULL, edd, data_in, &size);
4678 if (cipher_key && ret)
4680 if (eet_cipher(ret, size, cipher_key,
4681 strlen(cipher_key), &ciphered, &ciphered_len))
4694 size = ciphered_len;
4705 eet_data_descriptor_encode(Eet_Data_Descriptor *edd,
4706 const void *data_in,
4709 return eet_data_descriptor_encode_cipher(edd, data_in, NULL, size_ret);