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, const void *src, const void *src_end, void *dest);
86 void * (*put)(Eet_Dictionary *ed, const void *src, int *size_ret);
89 struct _Eet_Data_Group_Type_Codec
91 int (*get)(Eet_Free_Context *context, const Eet_Dictionary *ed, Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Chunk *echnk, int type, int group_type, void *data_in, char **p, int *size);
92 void (*put)(Eet_Dictionary *ed, Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Stream *ds, void *data_in);
95 struct _Eet_Data_Chunk
103 unsigned char group_type;
106 struct _Eet_Data_Stream
113 struct _Eet_Data_Descriptor_Hash
115 Eet_Data_Element *element;
116 Eet_Data_Descriptor_Hash *next;
119 struct _Eet_Data_Descriptor
122 const Eet_Dictionary *ed;
126 void * (*mem_alloc)(size_t size);
127 void (*mem_free)(void *mem);
128 char * (*str_alloc)(const char *str);
129 char * (*str_direct_alloc)(const char *str);
130 void (*str_free)(const char *str);
131 void (*str_direct_free)(const char *str);
132 void * (*list_next)(void *l);
133 void * (*list_append)(void *l, void *d);
134 void * (*list_data)(void *l);
135 void * (*list_free)(void *l);
136 void (*hash_foreach)(void *h, int (*func)(void *h, const char *k, void *dt, void *fdt), void *fdt);
137 void * (*hash_add)(void *h, const char *k, void *d);
138 void (*hash_free)(void *h);
139 const char *(*type_get)(const void *data, Eina_Bool *unknow);
140 Eina_Bool (*type_set)(const char *type, void *data, Eina_Bool unknow);
141 void * (*array_alloc)(size_t size);
142 void (*array_free)(void *mem);
147 Eet_Data_Element *set;
151 Eet_Data_Descriptor_Hash *buckets;
155 Eina_Bool unified_type : 1;
160 struct _Eet_Data_Element
163 const char *counter_name;
164 const char *directory_name_ptr;
165 Eet_Data_Descriptor *subtype;
166 int offset; /* offset in bytes from the base element */
167 int count; /* number of elements for a fixed array */
168 int counter_offset; /* for a variable array we need the offset of the count variable */
169 unsigned char type; /* EET_T_XXX */
170 unsigned char group_type; /* EET_G_XXX */
173 struct _Eet_Data_Encode_Hash_Info
176 Eet_Data_Element *ede;
188 struct _Eet_Free_Context
191 Eet_Free freelist_array;
192 Eet_Free freelist_list;
193 Eet_Free freelist_hash;
194 Eet_Free freelist_str;
195 Eet_Free freelist_direct_str;
198 struct _Eet_Variant_Unknow
208 static int eet_data_get_char(const Eet_Dictionary *ed,
212 static void * eet_data_put_char(Eet_Dictionary *ed,
215 static int eet_data_get_short(const Eet_Dictionary *ed,
219 static void * eet_data_put_short(Eet_Dictionary *ed,
222 static inline int eet_data_get_int(const Eet_Dictionary *ed,
226 static void * eet_data_put_int(Eet_Dictionary *ed,
229 static int eet_data_get_long_long(const Eet_Dictionary *ed,
233 static void * eet_data_put_long_long(Eet_Dictionary *ed,
236 static int eet_data_get_float(const Eet_Dictionary *ed,
240 static void * eet_data_put_float(Eet_Dictionary *ed,
243 static int eet_data_get_double(const Eet_Dictionary *ed,
247 static void * eet_data_put_double(Eet_Dictionary *ed,
250 static int eet_data_get_f32p32(const Eet_Dictionary *ed,
254 static void * eet_data_put_f32p32(Eet_Dictionary *ed,
257 static int eet_data_get_f16p16(const Eet_Dictionary *ed,
261 static void * eet_data_put_f16p16(Eet_Dictionary *ed,
264 static int eet_data_get_f8p24(const Eet_Dictionary *ed,
268 static void * eet_data_put_f8p24(Eet_Dictionary *ed,
271 static inline int eet_data_get_string(const Eet_Dictionary *ed,
275 static void * eet_data_put_string(Eet_Dictionary *ed,
278 static int eet_data_get_istring(const Eet_Dictionary *ed,
282 static void * eet_data_put_istring(Eet_Dictionary *ed,
285 static int eet_data_get_null(const Eet_Dictionary *ed,
289 static void * eet_data_put_null(Eet_Dictionary *ed,
293 static int eet_data_get_type(const Eet_Dictionary *ed,
298 static void * eet_data_put_type(Eet_Dictionary *ed,
303 static Eet_Node * eet_data_node_simple_type(int type,
307 static int eet_data_get_unknown(Eet_Free_Context *context,
308 const Eet_Dictionary *ed,
309 Eet_Data_Descriptor *edd,
310 Eet_Data_Element *ede,
311 Eet_Data_Chunk *echnk,
317 static void eet_data_put_unknown(Eet_Dictionary *ed,
318 Eet_Data_Descriptor *edd,
319 Eet_Data_Element *ede,
322 static void eet_data_put_array(Eet_Dictionary *ed,
323 Eet_Data_Descriptor *edd,
324 Eet_Data_Element *ede,
327 static int eet_data_get_array(Eet_Free_Context *context,
328 const Eet_Dictionary *ed,
329 Eet_Data_Descriptor *edd,
330 Eet_Data_Element *ede,
331 Eet_Data_Chunk *echnk,
337 static int eet_data_get_list(Eet_Free_Context *context,
338 const Eet_Dictionary *ed,
339 Eet_Data_Descriptor *edd,
340 Eet_Data_Element *ede,
341 Eet_Data_Chunk *echnk,
347 static void eet_data_put_list(Eet_Dictionary *ed,
348 Eet_Data_Descriptor *edd,
349 Eet_Data_Element *ede,
352 static void eet_data_put_hash(Eet_Dictionary *ed,
353 Eet_Data_Descriptor *edd,
354 Eet_Data_Element *ede,
357 static int eet_data_get_hash(Eet_Free_Context *context,
358 const Eet_Dictionary *ed,
359 Eet_Data_Descriptor *edd,
360 Eet_Data_Element *ede,
361 Eet_Data_Chunk *echnk,
367 static void eet_data_put_union(Eet_Dictionary *ed,
368 Eet_Data_Descriptor *edd,
369 Eet_Data_Element *ede,
372 static int eet_data_get_union(Eet_Free_Context *context,
373 const Eet_Dictionary *ed,
374 Eet_Data_Descriptor *edd,
375 Eet_Data_Element *ede,
376 Eet_Data_Chunk *echnk,
382 static void eet_data_put_variant(Eet_Dictionary *ed,
383 Eet_Data_Descriptor *edd,
384 Eet_Data_Element *ede,
387 static int eet_data_get_variant(Eet_Free_Context *context,
388 const Eet_Dictionary *ed,
389 Eet_Data_Descriptor *edd,
390 Eet_Data_Element *ede,
391 Eet_Data_Chunk *echnk,
398 static void eet_data_chunk_get(const Eet_Dictionary *ed,
399 Eet_Data_Chunk *chnk,
402 static Eet_Data_Chunk * eet_data_chunk_new(void *data,
407 static void eet_data_chunk_free(Eet_Data_Chunk *chnk);
409 static Eet_Data_Stream * eet_data_stream_new(void);
410 static void eet_data_stream_write(Eet_Data_Stream *ds,
413 static void eet_data_stream_free(Eet_Data_Stream *ds);
415 static void eet_data_chunk_put(Eet_Dictionary *ed,
416 Eet_Data_Chunk *chnk,
417 Eet_Data_Stream *ds);
419 static int eet_data_descriptor_encode_hash_cb(void *hash,
423 static void * _eet_data_descriptor_encode(Eet_Dictionary *ed,
424 Eet_Data_Descriptor *edd,
427 static void * _eet_data_descriptor_decode(Eet_Free_Context *context,
428 const Eet_Dictionary *ed,
429 Eet_Data_Descriptor *edd,
435 static const Eet_Data_Basic_Type_Codec eet_basic_codec[] =
437 {sizeof(char), "char", eet_data_get_char, eet_data_put_char },
438 {sizeof(short), "short", eet_data_get_short, eet_data_put_short },
439 {sizeof(int), "int", eet_data_get_int, eet_data_put_int },
440 {sizeof(long long), "long_long", eet_data_get_long_long, eet_data_put_long_long},
441 {sizeof(float), "float", eet_data_get_float, eet_data_put_float },
442 {sizeof(double), "double", eet_data_get_double, eet_data_put_double },
443 {sizeof(char), "uchar", eet_data_get_char, eet_data_put_char },
444 {sizeof(short), "ushort", eet_data_get_short, eet_data_put_short },
445 {sizeof(int), "uint", eet_data_get_int, eet_data_put_int },
446 {sizeof(long long), "ulong_long", eet_data_get_long_long, eet_data_put_long_long},
447 {sizeof(char *), "string", eet_data_get_string, eet_data_put_string },
448 {sizeof(char *), "inlined", eet_data_get_istring, eet_data_put_istring },
449 {sizeof(void *), "NULL", eet_data_get_null, eet_data_put_null },
450 {sizeof(Eina_F32p32),"f32p32", eet_data_get_f32p32, eet_data_put_f32p32 },
451 {sizeof(Eina_F16p16),"f16p16", eet_data_get_f16p16, eet_data_put_f16p16 },
452 {sizeof(Eina_F8p24),"f8p24", eet_data_get_f8p24, eet_data_put_f8p24 }
455 static const Eet_Data_Group_Type_Codec eet_group_codec[] =
457 { eet_data_get_unknown, eet_data_put_unknown },
458 { eet_data_get_array, eet_data_put_array },
459 { eet_data_get_array, eet_data_put_array },
460 { eet_data_get_list, eet_data_put_list },
461 { eet_data_get_hash, eet_data_put_hash },
462 { eet_data_get_union, eet_data_put_union },
463 { eet_data_get_variant, eet_data_put_variant }
466 static int _eet_data_words_bigendian = -1;
470 #define SWAP64(x) (x) =\
471 ((((unsigned long long)(x) & 0x00000000000000ffULL) << 56) |\
472 (((unsigned long long)(x) & 0x000000000000ff00ULL) << 40) |\
473 (((unsigned long long)(x) & 0x0000000000ff0000ULL) << 24) |\
474 (((unsigned long long)(x) & 0x00000000ff000000ULL) << 8) |\
475 (((unsigned long long)(x) & 0x000000ff00000000ULL) >> 8) |\
476 (((unsigned long long)(x) & 0x0000ff0000000000ULL) >> 24) |\
477 (((unsigned long long)(x) & 0x00ff000000000000ULL) >> 40) |\
478 (((unsigned long long)(x) & 0xff00000000000000ULL) >> 56))
479 #define SWAP32(x) (x) =\
480 ((((int)(x) & 0x000000ff) << 24) |\
481 (((int)(x) & 0x0000ff00) << 8) |\
482 (((int)(x) & 0x00ff0000) >> 8) |\
483 (((int)(x) & 0xff000000) >> 24))
484 #define SWAP16(x) (x) =\
485 ((((short)(x) & 0x00ff) << 8) |\
486 (((short)(x) & 0xff00) >> 8))
490 #endif /* ifdef CONV8 */
493 #endif /* ifdef CONV16 */
496 #endif /* ifdef CONV32 */
499 #endif /* ifdef CONV64 */
502 #define CONV16(x) {if (_eet_data_words_bigendian) {SWAP16(x); }}
503 #define CONV32(x) {if (_eet_data_words_bigendian) {SWAP32(x); }}
504 #define CONV64(x) {if (_eet_data_words_bigendian) {SWAP64(x); }}
506 #define IS_SIMPLE_TYPE(Type) (Type > EET_T_UNKNOW && Type < EET_T_LAST)
507 #define IS_POINTER_TYPE(Type) (Type >= EET_T_STRING && Type <= EET_T_NULL)
509 #define POINTER_TYPE_DECODE(Context,\
521 ___r = eet_data_get_unknown(Context,\
525 Type, EET_G_UNKNOWN,\
527 if (!___r) { goto Label; }\
530 #define STRUCT_TYPE_DECODE(Data_Ret, Context, Ed, Ede, Data, Size, Label)\
532 Data_Ret = _eet_data_descriptor_decode(Context,\
537 if (!Data_Ret) { goto Label; }\
540 #define EET_I_STRING 1 << 4
541 #define EET_I_INLINED_STRING 2 << 4
542 #define EET_I_NULL 3 << 4
544 #define EET_MAGIC_VARIANT 0xF1234BC
549 eet_data_get_char(const Eet_Dictionary *ed __UNUSED__,
556 if (((char *)src + sizeof(char)) > (char *)src_end)
564 } /* eet_data_get_char */
567 eet_data_put_char(Eet_Dictionary *ed __UNUSED__,
573 d = (char *)malloc(sizeof(char));
580 *size_ret = sizeof(char);
582 } /* eet_data_put_char */
586 eet_data_get_short(const Eet_Dictionary *ed __UNUSED__,
593 if (((char *)src + sizeof(short)) > (char *)src_end)
596 memcpy(dst, src, sizeof(short));
599 return sizeof(short);
600 } /* eet_data_get_short */
603 eet_data_put_short(Eet_Dictionary *ed __UNUSED__,
609 d = (short *)malloc(sizeof(short));
616 *size_ret = sizeof(short);
618 } /* eet_data_put_short */
622 eet_data_get_int(const Eet_Dictionary *ed __UNUSED__,
629 if (((char *)src + sizeof(int)) > (char *)src_end)
632 memcpy(dst, src, sizeof(int));
636 } /* eet_data_get_int */
639 eet_data_put_int(Eet_Dictionary *ed __UNUSED__,
645 d = (int *)malloc(sizeof(int));
652 *size_ret = sizeof(int);
654 } /* eet_data_put_int */
658 eet_data_get_long_long(const Eet_Dictionary *ed __UNUSED__,
663 unsigned long long *d;
665 if (((char *)src + sizeof(unsigned long long)) > (char *)src_end)
668 memcpy(dst, src, sizeof(unsigned long long));
669 d = (unsigned long long *)dst;
671 return sizeof(unsigned long long);
672 } /* eet_data_get_long_long */
675 eet_data_put_long_long(Eet_Dictionary *ed __UNUSED__,
679 unsigned long long *s, *d;
681 d = (unsigned long long *)malloc(sizeof(unsigned long long));
685 s = (unsigned long long *)src;
688 *size_ret = sizeof(unsigned long long);
690 } /* eet_data_put_long_long */
694 eet_data_get_string_hash(const Eet_Dictionary *ed,
702 if (eet_data_get_int(ed, src, src_end, &idx) < 0)
705 return eet_dictionary_string_get_hash(ed, idx);
709 } /* eet_data_get_string_hash */
712 eet_data_get_string(const Eet_Dictionary *ed,
726 if (eet_data_get_int(ed, src, src_end, &idx) < 0)
729 str = eet_dictionary_string_get_char(ed, idx);
734 return eet_dictionary_string_get_size(ed, idx);
745 return strlen(s) + 1;
746 } /* eet_data_get_string */
749 eet_data_put_string(Eet_Dictionary *ed,
761 str = *((const char **)src);
765 idx = eet_dictionary_string_add(ed, str);
769 return eet_data_put_int(ed, &idx, size_ret);
772 s = (char *)(*((char **)src));
781 memcpy(d, s, len + 1);
784 } /* eet_data_put_string */
786 /* ALWAYS INLINED STRING TYPE */
788 eet_data_get_istring(const Eet_Dictionary *ed __UNUSED__,
793 return eet_data_get_string(NULL, src, src_end, dst);
794 } /* eet_data_get_istring */
797 eet_data_put_istring(Eet_Dictionary *ed __UNUSED__,
801 return eet_data_put_string(NULL, src, size_ret);
802 } /* eet_data_put_istring */
804 /* ALWAYS NULL TYPE */
806 eet_data_get_null(const Eet_Dictionary *ed __UNUSED__,
807 const void *src __UNUSED__,
808 const void *src_end __UNUSED__,
817 } /* eet_data_get_null */
820 eet_data_put_null(Eet_Dictionary *ed __UNUSED__,
821 const void *src __UNUSED__,
826 } /* eet_data_put_null */
829 * Fast lookups of simple doubles/floats.
831 * These aren't properly a cache because they don't store pre-calculated
832 * values, but have a so simple math that is almost as fast.
835 _eet_data_float_cache_get(const char *s,
839 /* fast handle of simple case 0xMp+E*/
840 if ((len == 6) && (s[0] == '0') && (s[1] == 'x') && (s[3] == 'p'))
842 int mantisse = (s[2] >= 'a') ? (s[2] - 'a' + 10) : (s[2] - '0');
843 int exponent = (s[5] - '0');
846 *d = (float)(mantisse << exponent);
848 *d = (float)mantisse / (float)(1 << exponent);
854 } /* _eet_data_float_cache_get */
857 _eet_data_double_cache_get(const char *s,
861 /* fast handle of simple case 0xMp+E*/
862 if ((len == 6) && (s[0] == '0') && (s[1] == 'x') && (s[3] == 'p'))
864 int mantisse = (s[2] >= 'a') ? (s[2] - 'a' + 10) : (s[2] - '0');
865 int exponent = (s[5] - '0');
868 *d = (double)(mantisse << exponent);
870 *d = (double)mantisse / (double)(1 << exponent);
876 } /* _eet_data_double_cache_get */
880 eet_data_get_float(const Eet_Dictionary *ed,
896 s = (const char *)src;
899 while ((p < (const char *)src_end) && (*p != 0)) {len++; p++; }
901 if (_eet_data_float_cache_get(s, len, d) != 0)
904 if (eina_convert_atod(s, len, &mantisse, &exponent) == EINA_FALSE)
907 *d = (float)ldexp((double)mantisse, exponent);
912 if (eet_data_get_int(ed, src, src_end, &idx) < 0)
915 if (!eet_dictionary_string_get_float(ed, idx, d))
919 } /* eet_data_get_float */
922 eet_data_put_float(Eet_Dictionary *ed,
929 eina_convert_dtoa((double)(*(float *)src), buf);
941 memcpy(d, buf, len + 1);
946 idx = eet_dictionary_string_add(ed, buf);
950 return eet_data_put_int(ed, &idx, size_ret);
951 } /* eet_data_put_float */
955 eet_data_get_double(const Eet_Dictionary *ed,
968 long long mantisse = 0;
972 s = (const char *)src;
975 while ((p < (const char *)src_end) && (*p != 0)) {len++; p++; }
977 if (_eet_data_double_cache_get(s, len, d) != 0)
980 if (eina_convert_atod(s, len, &mantisse, &exponent) == EINA_FALSE)
983 *d = ldexp((double)mantisse, exponent);
988 if (eet_data_get_int(ed, src, src_end, &idx) < 0)
991 if (!eet_dictionary_string_get_double(ed, idx, d))
995 } /* eet_data_get_double */
998 eet_data_put_double(Eet_Dictionary *ed,
1005 eina_convert_dtoa((double)(*(double *)src), buf);
1013 d = malloc(len + 1);
1017 memcpy(d, buf, len + 1);
1018 *size_ret = len + 1;
1023 idx = eet_dictionary_string_add(ed, buf);
1027 return eet_data_put_int(ed, &idx, size_ret);
1028 } /* eet_data_put_double */
1031 eet_data_get_f32p32(const Eet_Dictionary *ed,
1033 const void *src_end,
1039 fp = (Eina_F32p32 *)dst;
1046 s = (const char *)src;
1049 while ((p < (const char *)src_end) && (*p != 0)) { len++; p++; }
1051 if (!(eina_convert_atofp(s, len, fp)))
1057 if (eet_data_get_int(ed, src, src_end, &idx) < 0)
1060 if (!eet_dictionary_string_get_fp(ed, idx, fp))
1064 } /* eet_data_get_f32p32 */
1067 eet_data_put_f32p32(Eet_Dictionary *ed,
1074 eina_convert_fptoa((Eina_F32p32)(*(Eina_F32p32 *)src), buf);
1082 d = malloc(len + 1);
1086 memcpy(d, buf, len + 1);
1087 *size_ret = len + 1;
1092 idx = eet_dictionary_string_add(ed, buf);
1096 return eet_data_put_int(ed, &idx, size_ret);
1097 } /* eet_data_put_f32p32 */
1100 eet_data_get_f16p16(const Eet_Dictionary *ed,
1102 const void *src_end,
1108 fp = (Eina_F16p16 *)dst;
1110 if (eet_data_get_f32p32(ed, src, src_end, &tmp) < 0)
1113 *fp = eina_f32p32_to_f16p16(tmp);
1115 } /* eet_data_get_f16p16 */
1118 eet_data_put_f16p16(Eet_Dictionary *ed,
1124 tmp = eina_f16p16_to_f32p32((Eina_F16p16)(*(Eina_F16p16 *)src));
1125 return eet_data_put_f32p32(ed, &tmp, size_ret);
1126 } /* eet_data_put_f16p16 */
1129 eet_data_get_f8p24(const Eet_Dictionary *ed,
1131 const void *src_end,
1137 fp = (Eina_F8p24 *)dst;
1139 if (eet_data_get_f32p32(ed, src, src_end, &tmp) < 0)
1142 *fp = eina_f32p32_to_f8p24(tmp);
1144 } /* eet_data_get_f8p24 */
1147 eet_data_put_f8p24(Eet_Dictionary *ed,
1153 tmp = eina_f8p24_to_f32p32((Eina_F8p24)(*(Eina_F8p24 *)src));
1154 return eet_data_put_f32p32(ed, &tmp, size_ret);
1155 } /* eet_data_put_f8p24 */
1158 eet_data_get_type(const Eet_Dictionary *ed,
1161 const void *src_end,
1166 ret = eet_basic_codec[type - 1].get(ed, src, src_end, dest);
1168 } /* eet_data_get_type */
1170 static inline void *
1171 eet_data_put_type(Eet_Dictionary *ed,
1178 ret = eet_basic_codec[type - 1].put(ed, src, size_ret);
1180 } /* eet_data_put_type */
1182 static inline Eina_Bool
1183 eet_data_type_match(int type1,
1189 /* Note: All floating point type are equivalent and could be read
1190 without problem by any other floating point getter. */
1217 } /* eet_data_type_match */
1221 * char[4] = "CHnK"; // untyped data ... or
1222 * char[4] = "CHKx"; // typed data - x == type
1224 * int = chunk size (including magic string);
1225 * char[] = chunk magic/name string (0 byte terminated);
1226 * ... sub-chunks (a chunk can contain chuncks recusrively) ...
1228 * ... payload data ...
1233 eet_data_chunk_get(const Eet_Dictionary *ed,
1234 Eet_Data_Chunk *chnk,
1253 if ((s[0] != 'C') || (s[1] != 'H') || (s[2] != 'K'))
1256 chnk->type = (unsigned char)(s[3]);
1257 if (chnk->type >= EET_I_LIMIT)
1260 ((chnk->type - EET_I_LIMIT) & 0xF) + EET_G_UNKNOWN;
1261 switch ((chnk->type - EET_I_LIMIT) & 0xF0)
1263 #define EET_UNMATCH_TYPE(Type)\
1264 case EET_I_ ## Type: chnk->type = EET_T_ ## Type; break;
1266 EET_UNMATCH_TYPE(STRING);
1267 EET_UNMATCH_TYPE(INLINED_STRING);
1268 EET_UNMATCH_TYPE(NULL);
1274 else if (chnk->type > EET_T_LAST)
1276 chnk->group_type = chnk->type;
1277 chnk->type = EET_T_UNKNOW;
1280 chnk->group_type = EET_G_UNKNOWN;
1281 if ((chnk->type >= EET_T_LAST) ||
1282 (chnk->group_type >=
1286 chnk->group_type = 0;
1289 else if ((s[0] != 'C') || (s[1] != 'H') || (s[2] != 'n') || (s[3] != 'K'))
1292 ret1 = eet_data_get_type(ed, EET_T_INT, (s + 4), (s + size), &(chnk->size));
1297 if ((chnk->size < 0) || ((chnk->size + 8) > size))
1300 ret2 = eet_data_get_type(ed, EET_T_STRING, (s + 8), (s + size), &(chnk->name));
1308 chnk->hash = eet_data_get_string_hash(ed, (s + 8), (s + size));
1312 chnk->data = (char *)src + 4 + ret1 + sizeof(int);
1313 chnk->size -= sizeof(int);
1317 chnk->data = (char *)src + 4 + ret1 + chnk->len;
1318 chnk->size -= chnk->len;
1322 } /* eet_data_chunk_get */
1324 static inline Eet_Data_Chunk *
1325 eet_data_chunk_new(void *data,
1331 Eet_Data_Chunk *chnk;
1336 chnk = calloc(1, sizeof(Eet_Data_Chunk));
1340 /* Note: Another security, so older eet library could read file
1341 saved with fixed point value. */
1342 if (type == EET_T_F32P32
1343 || type == EET_T_F16P16
1344 || type == EET_T_F8P24)
1345 type = EET_T_DOUBLE;
1347 chnk->name = strdup(name);
1348 chnk->len = strlen(name) + 1;
1352 chnk->group_type = group_type;
1354 } /* eet_data_chunk_new */
1357 eet_data_chunk_free(Eet_Data_Chunk *chnk)
1363 } /* eet_data_chunk_free */
1365 static inline Eet_Data_Stream *
1366 eet_data_stream_new(void)
1368 Eet_Data_Stream *ds;
1370 ds = calloc(1, sizeof(Eet_Data_Stream));
1375 } /* eet_data_stream_new */
1378 eet_data_stream_free(Eet_Data_Stream *ds)
1384 } /* eet_data_stream_free */
1387 eet_data_stream_flush(Eet_Data_Stream *ds)
1390 } /* eet_data_stream_flush */
1393 eet_data_stream_write(Eet_Data_Stream *ds,
1399 if ((ds->pos + size) > ds->size)
1401 ds->data = realloc(ds->data, ds->size + size + 512);
1409 ds->size = ds->size + size + 512;
1413 memcpy(p + ds->pos, data, size);
1415 } /* eet_data_stream_write */
1418 eet_data_chunk_put(Eet_Dictionary *ed,
1419 Eet_Data_Chunk *chnk,
1420 Eet_Data_Stream *ds)
1427 unsigned char buf[4] = "CHK";
1429 /* disable this check - it will allow empty chunks to be written. this is
1430 * right for corner-cases when y have a struct with empty fields (empty
1431 * strings or empty list ptrs etc.) */
1432 /* if (!chnk->data && chnk->type != EET_T_NULL) return; */
1435 /* eet_data_stream_write(ds, "CHnK", 4);*/
1436 if (chnk->type != EET_T_UNKNOW)
1438 if (chnk->group_type != EET_G_UNKNOWN)
1440 int type = EET_I_LIMIT + chnk->group_type - EET_G_UNKNOWN;
1444 /* Only make sense with pointer type. */
1445 #define EET_MATCH_TYPE(Type)\
1446 case EET_T_ ## Type: type += EET_I_ ## Type; break;
1448 EET_MATCH_TYPE(STRING);
1449 EET_MATCH_TYPE(INLINED_STRING);
1450 EET_MATCH_TYPE(NULL);
1459 buf[3] = chnk->type;
1462 buf[3] = chnk->group_type;
1464 string = eet_data_put_string(ed, &chnk->name, &string_ret);
1468 /* size of chunk payload data + name */
1469 s = chnk->size + string_ret;
1470 size = eet_data_put_int(ed, &s, &size_ret);
1472 /* FIXME: If something goes wrong the resulting file will be corrupted. */
1476 eet_data_stream_write(ds, buf, 4);
1478 /* write chunk length */
1479 eet_data_stream_write(ds, size, size_ret);
1481 /* write chunk name */
1482 eet_data_stream_write(ds, string, string_ret);
1486 eet_data_stream_write(ds, chnk->data, chnk->size);
1491 } /* eet_data_chunk_put */
1496 _eet_descriptor_hash_new(Eet_Data_Descriptor *edd)
1500 edd->elements.hash.size = 1 << 6;
1501 edd->elements.hash.buckets = calloc(
1503 sizeof(Eet_Data_Descriptor_Hash) *
1504 edd->elements.hash.size);
1505 for (i = 0; i < edd->elements.num; i++)
1507 Eet_Data_Element *ede;
1510 ede = &(edd->elements.set[i]);
1511 hash = _eet_hash_gen((char *)ede->name, 6);
1512 if (!edd->elements.hash.buckets[hash].element)
1513 edd->elements.hash.buckets[hash].element = ede;
1516 Eet_Data_Descriptor_Hash *bucket;
1518 bucket = calloc(1, sizeof(Eet_Data_Descriptor_Hash));
1519 bucket->element = ede;
1520 bucket->next = edd->elements.hash.buckets[hash].next;
1521 edd->elements.hash.buckets[hash].next = bucket;
1524 } /* _eet_descriptor_hash_new */
1527 _eet_descriptor_hash_free(Eet_Data_Descriptor *edd)
1531 for (i = 0; i < edd->elements.hash.size; i++)
1533 Eet_Data_Descriptor_Hash *bucket, *pbucket;
1535 bucket = edd->elements.hash.buckets[i].next;
1539 bucket = bucket->next;
1543 if (edd->elements.hash.buckets)
1544 free(edd->elements.hash.buckets);
1545 } /* _eet_descriptor_hash_free */
1547 static Eet_Data_Element *
1548 _eet_descriptor_hash_find(Eet_Data_Descriptor *edd,
1552 Eet_Data_Descriptor_Hash *bucket;
1555 hash = _eet_hash_gen(name, 6);
1559 if (!edd->elements.hash.buckets[hash].element)
1561 When we use the dictionnary as a source for chunk name, we will always
1562 have the same pointer in name. It's a good idea to just compare pointer
1563 instead of running strcmp on both string.
1566 if (edd->elements.hash.buckets[hash].element->directory_name_ptr == name)
1567 return edd->elements.hash.buckets[hash].element;
1569 if (!strcmp(edd->elements.hash.buckets[hash].element->name, name))
1571 edd->elements.hash.buckets[hash].element->directory_name_ptr = name;
1572 return edd->elements.hash.buckets[hash].element;
1575 bucket = edd->elements.hash.buckets[hash].next;
1578 if (bucket->element->directory_name_ptr == name)
1579 return bucket->element;
1581 if (!strcmp(bucket->element->name, name))
1583 bucket->element->directory_name_ptr = name;
1584 return bucket->element;
1587 bucket = bucket->next;
1590 } /* _eet_descriptor_hash_find */
1593 _eet_mem_alloc(size_t size)
1595 return calloc(1, size);
1596 } /* _eet_mem_alloc */
1599 _eet_mem_free(void *mem)
1602 } /* _eet_mem_free */
1605 _eet_str_alloc(const char *str)
1608 } /* _eet_str_alloc */
1611 _eet_str_free(const char *str)
1614 } /* _eet_str_free */
1617 _eet_eina_hash_add_alloc(Eina_Hash *hash,
1622 hash = eina_hash_string_small_new(NULL);
1627 eina_hash_add(hash, key, data);
1629 } /* _eet_eina_hash_add_alloc */
1632 _eet_eina_hash_direct_add_alloc(Eina_Hash *hash,
1637 hash = eina_hash_string_small_new(NULL);
1642 eina_hash_direct_add(hash, key, data);
1644 } /* _eet_eina_hash_direct_add_alloc */
1647 _eet_str_direct_alloc(const char *str)
1650 } /* _eet_str_direct_alloc */
1653 _eet_str_direct_free(const char *str __UNUSED__)
1655 } /* _eet_str_direct_free */
1658 _eet_eina_hash_foreach(void *hash,
1659 Eina_Hash_Foreach cb,
1663 eina_hash_foreach(hash, cb, fdata);
1664 } /* _eet_eina_hash_foreach */
1667 _eet_eina_hash_free(void *hash)
1670 eina_hash_free(hash);
1671 } /* _eet_eina_hash_free */
1675 eet_eina_stream_data_descriptor_class_set(Eet_Data_Descriptor_Class *eddc,
1676 /* When we change the structure content in the future, we need to handle old structure type too */
1677 unsigned int eddc_size,
1681 if (!eddc || !name || eddc_size != sizeof (Eet_Data_Descriptor_Class))
1686 eddc->version = EET_DATA_DESCRIPTOR_CLASS_VERSION;
1688 eddc->func.mem_alloc = _eet_mem_alloc;
1689 eddc->func.mem_free = _eet_mem_free;
1690 eddc->func.str_alloc = (char *(*)(const char *))eina_stringshare_add;
1691 eddc->func.str_free = eina_stringshare_del;
1692 eddc->func.list_next = (void *(*)(void *))eina_list_next;
1693 eddc->func.list_append = (void *(*)(void *, void *))eina_list_append;
1694 eddc->func.list_data = (void *(*)(void *))eina_list_data_get;
1695 eddc->func.list_free = (void *(*)(void *))eina_list_free;
1696 eddc->func.hash_foreach = (void (*)(void *, int (*)(void *, const char *, void *, void *), void *))_eet_eina_hash_foreach;
1697 eddc->func.hash_add = (void * (*)(void *, const char *, void *))_eet_eina_hash_add_alloc;
1698 eddc->func.hash_free = (void (*)(void *))_eet_eina_hash_free;
1700 /* This will cause an ABI incompatibility */
1701 eddc->func.array_alloc = _eet_mem_alloc;
1702 eddc->func.array_free = _eet_mem_free;
1705 } /* eet_eina_stream_data_descriptor_class_set */
1708 eet_eina_file_data_descriptor_class_set(Eet_Data_Descriptor_Class *eddc,
1709 /* When we change the structure content in the future, we need to handle old structure type too */
1710 unsigned int eddc_size,
1714 if (!eet_eina_stream_data_descriptor_class_set(eddc, eddc_size, name, size))
1717 eddc->version = EET_DATA_DESCRIPTOR_CLASS_VERSION;
1719 eddc->func.hash_add = (void * (*)(void *, const char *, void *))_eet_eina_hash_direct_add_alloc;
1720 eddc->func.str_direct_alloc = _eet_str_direct_alloc;
1721 eddc->func.str_direct_free = _eet_str_direct_free;
1724 } /* eet_eina_file_data_descriptor_class_set */
1726 static Eet_Data_Descriptor *
1727 _eet_data_descriptor_new(const Eet_Data_Descriptor_Class *eddc,
1730 Eet_Data_Descriptor *edd;
1735 edd = calloc(1, sizeof (Eet_Data_Descriptor));
1739 edd->name = eddc->name;
1741 edd->size = eddc->size;
1742 edd->func.mem_alloc = _eet_mem_alloc;
1743 edd->func.mem_free = _eet_mem_free;
1744 edd->func.str_alloc = _eet_str_alloc;
1745 edd->func.str_free = _eet_str_free;
1746 if (eddc->func.mem_alloc)
1747 edd->func.mem_alloc = eddc->func.mem_alloc;
1749 if (eddc->func.mem_free)
1750 edd->func.mem_free = eddc->func.mem_free;
1752 if (eddc->func.str_alloc)
1753 edd->func.str_alloc = eddc->func.str_alloc;
1755 if (eddc->func.str_free)
1756 edd->func.str_free = eddc->func.str_free;
1758 edd->func.list_next = eddc->func.list_next;
1759 edd->func.list_append = eddc->func.list_append;
1760 edd->func.list_data = eddc->func.list_data;
1761 edd->func.list_free = eddc->func.list_free;
1762 edd->func.hash_foreach = eddc->func.hash_foreach;
1763 edd->func.hash_add = eddc->func.hash_add;
1764 edd->func.hash_free = eddc->func.hash_free;
1766 if (eddc->version > 1 && version > 1)
1768 edd->func.str_direct_alloc = eddc->func.str_direct_alloc;
1769 edd->func.str_direct_free = eddc->func.str_direct_free;
1772 if (eddc->version > 2)
1774 edd->func.type_get = eddc->func.type_get;
1775 edd->func.type_set = eddc->func.type_set;
1778 if (eddc->version > 3)
1780 edd->func.array_alloc = eddc->func.array_alloc;
1781 edd->func.array_free = eddc->func.array_free;
1785 } /* _eet_data_descriptor_new */
1787 EAPI Eet_Data_Descriptor *
1788 eet_data_descriptor_new(const char *name,
1790 void *(*func_list_next)(void *l),
1791 void *(*func_list_append)(void *l, void *d),
1792 void *(*func_list_data)(void *l),
1793 void *(*func_list_free)(void *l),
1794 void (*func_hash_foreach)(void *h, int (*func)(void *h, const char *k, void *dt, void *fdt), void *fdt),
1795 void *(*func_hash_add)(void *h, const char *k, void *d),
1796 void (*func_hash_free)(void *h))
1798 Eet_Data_Descriptor_Class eddc;
1803 memset(&eddc, 0, sizeof (Eet_Data_Descriptor_Class));
1809 eddc.func.list_next = func_list_next;
1810 eddc.func.list_append = func_list_append;
1811 eddc.func.list_data = func_list_data;
1812 eddc.func.list_free = func_list_free;
1813 eddc.func.hash_foreach = func_hash_foreach;
1814 eddc.func.hash_add = func_hash_add;
1815 eddc.func.hash_free = func_hash_free;
1817 return _eet_data_descriptor_new(&eddc, 0);
1818 } /* eet_data_descriptor_new */
1820 EAPI Eet_Data_Descriptor *
1821 eet_data_descriptor2_new(const Eet_Data_Descriptor_Class *eddc)
1823 return _eet_data_descriptor_new(eddc, 1);
1824 } /* eet_data_descriptor2_new */
1826 EAPI Eet_Data_Descriptor *
1827 eet_data_descriptor3_new(const Eet_Data_Descriptor_Class *eddc)
1829 return _eet_data_descriptor_new(eddc, 2);
1830 } /* eet_data_descriptor3_new */
1832 EAPI Eet_Data_Descriptor *
1833 eet_data_descriptor_stream_new(const Eet_Data_Descriptor_Class *eddc)
1835 return _eet_data_descriptor_new(eddc, 1);
1836 } /* eet_data_descriptor_stream_new */
1838 EAPI Eet_Data_Descriptor *
1839 eet_data_descriptor_file_new(const Eet_Data_Descriptor_Class *eddc)
1841 return _eet_data_descriptor_new(eddc, 2);
1842 } /* eet_data_descriptor_file_new */
1845 eet_data_descriptor_free(Eet_Data_Descriptor *edd)
1850 _eet_descriptor_hash_free(edd);
1851 if (edd->elements.set)
1852 free(edd->elements.set);
1855 } /* eet_data_descriptor_free */
1858 eet_data_descriptor_element_add(Eet_Data_Descriptor *edd,
1864 /* int counter_offset, */
1865 const char *counter_name /* FIXME: Useless should go on a major release */,
1866 Eet_Data_Descriptor *subtype)
1868 Eet_Data_Element *ede;
1869 Eet_Data_Element *tmp;
1871 /* UNION, VARIANT type would not work with simple type, we need a way to map the type. */
1872 if ((group_type == EET_G_UNION
1873 || group_type == EET_G_VARIANT)
1875 (type != EET_T_UNKNOW
1877 || !subtype->func.type_get
1878 || !subtype->func.type_set))
1881 /* VARIANT type will only work if the map only contains EET_G_*, but not UNION, VARIANT and ARRAY. */
1882 if (group_type == EET_G_VARIANT)
1886 for (i = 0; i < subtype->elements.num; ++i)
1887 if (subtype->elements.set[i].type != EET_T_UNKNOW
1888 && subtype->elements.set[i].group_type > EET_G_VAR_ARRAY
1889 && subtype->elements.set[i].group_type < EET_G_UNION)
1892 subtype->unified_type = EINA_TRUE;
1896 && subtype->unified_type
1897 && (type != EET_T_UNKNOW
1898 || group_type < EET_G_UNION))
1901 /* Sanity check done, let allocate ! */
1902 edd->elements.num++;
1903 tmp = realloc(edd->elements.set, edd->elements.num * sizeof(Eet_Data_Element));
1907 edd->elements.set = tmp;
1908 ede = &(edd->elements.set[edd->elements.num - 1]);
1910 ede->directory_name_ptr = NULL;
1913 * We do a special case when we do list,hash or whatever group of simple type.
1914 * Instead of handling it in encode/decode/dump/undump, we create an
1915 * implicit structure with only the simple type.
1917 if ((group_type > EET_G_UNKNOWN)
1918 && (group_type < EET_G_LAST)
1919 && (((type > EET_T_UNKNOW) && (type < EET_T_STRING))
1920 || ((type > EET_T_NULL) && (type < EET_T_LAST)))
1923 subtype = calloc(1, sizeof (Eet_Data_Descriptor));
1927 subtype->name = "implicit";
1928 subtype->size = eet_basic_codec[type - 1].size;
1929 memcpy(&subtype->func, &edd->func, sizeof(subtype->func));
1931 eet_data_descriptor_element_add(subtype,
1932 eet_basic_codec[type - 1].name,
1939 type = EET_T_UNKNOW;
1943 ede->group_type = group_type;
1944 ede->offset = offset;
1946 /* FIXME: For the time being, VAR_ARRAY, UNION and VARIANT will put the counter_offset in count. */
1947 ede->counter_offset = count;
1948 /* ede->counter_offset = counter_offset; */
1949 ede->counter_name = counter_name;
1951 ede->subtype = subtype;
1952 } /* eet_data_descriptor_element_add */
1955 eet_data_read_cipher(Eet_File *ef,
1956 Eet_Data_Descriptor *edd,
1958 const char *cipher_key)
1960 const Eet_Dictionary *ed = NULL;
1961 const void *data = NULL;
1963 Eet_Free_Context context;
1964 int required_free = 0;
1967 ed = eet_dictionary_get(ef);
1970 data = eet_read_direct(ef, name, &size);
1975 data = eet_read_cipher(ef, name, &size, cipher_key);
1980 memset(&context, 0, sizeof (context));
1981 data_dec = _eet_data_descriptor_decode(&context, ed, edd, data, size);
1986 } /* eet_data_read_cipher */
1989 eet_data_node_read_cipher(Eet_File *ef,
1991 const char *cipher_key)
1993 const Eet_Dictionary *ed = NULL;
1994 const void *data = NULL;
1996 Eet_Free_Context context;
1997 int required_free = 0;
2000 ed = eet_dictionary_get(ef);
2003 data = eet_read_direct(ef, name, &size);
2008 data = eet_read_cipher(ef, name, &size, cipher_key);
2013 memset(&context, 0, sizeof (context));
2014 result = _eet_data_descriptor_decode(&context, ed, NULL, data, size);
2019 } /* eet_data_node_read_cipher */
2022 eet_data_read(Eet_File *ef,
2023 Eet_Data_Descriptor *edd,
2026 return eet_data_read_cipher(ef, edd, name, NULL);
2027 } /* eet_data_read */
2030 eet_data_write_cipher(Eet_File *ef,
2031 Eet_Data_Descriptor *edd,
2033 const char *cipher_key,
2042 ed = eet_dictionary_get(ef);
2044 data_enc = _eet_data_descriptor_encode(ed, edd, data, &size);
2048 val = eet_write_cipher(ef, name, data_enc, size, compress, cipher_key);
2051 } /* eet_data_write_cipher */
2054 eet_data_write(Eet_File *ef,
2055 Eet_Data_Descriptor *edd,
2060 return eet_data_write_cipher(ef, edd, name, NULL, data, compress);
2061 } /* eet_data_write */
2064 _eet_free_hash(void *data)
2067 __int64 ptr = (UINT_PTR)data;
2068 #else /* ifdef _WIN64 */
2069 unsigned long ptr = (unsigned long)(data);
2070 #endif /* ifdef _WIN64 */
2078 #if defined (_WIN64) || ((!defined (_WIN32)) && (LONG_BIT != 32))
2083 #endif /* if defined (_WIN64) || ((!defined (_WIN32)) && (LONG_BIT != 32)) */
2086 } /* _eet_free_hash */
2089 _eet_free_add(Eet_Free *ef,
2095 hash = _eet_free_hash(data);
2097 for (i = 0; i < ef->num[hash]; ++i)
2098 if (ef->list[hash][i] == data)
2102 if (ef->num[hash] > ef->len[hash])
2106 tmp = realloc(ef->list[hash], (ef->len[hash] + 16) * sizeof(void *));
2110 ef->len[hash] += 16;
2111 ef->list[hash] = tmp;
2114 ef->list[hash][ef->num[hash] - 1] = data;
2115 } /* _eet_free_add */
2118 _eet_free_del(Eet_Free *ef,
2124 hash = _eet_free_hash(data);
2126 for (i = 0; i < ef->num[hash]; ++i)
2127 if (ef->list[hash][i] == data)
2129 ef->list[hash][i] = NULL;
2135 _eet_free_reset(Eet_Free *ef)
2142 for (i = 0; i < 256; ++i)
2151 } /* _eet_free_reset */
2154 _eet_free_ref(Eet_Free *ef)
2157 } /* _eet_free_ref */
2160 _eet_free_unref(Eet_Free *ef)
2163 } /* _eet_free_unref */
2165 #define _eet_freelist_add(Ctx, Data) _eet_free_add(&Ctx->freelist, Data);
2166 #define _eet_freelist_del(Ctx, Data) _eet_free_del(&Ctx->freelist, Data);
2167 #define _eet_freelist_reset(Ctx) _eet_free_reset(&Ctx->freelist);
2168 #define _eet_freelist_ref(Ctx) _eet_free_ref(&Ctx->freelist);
2169 #define _eet_freelist_unref(Ctx) _eet_free_unref(&Ctx->freelist);
2172 _eet_freelist_free(Eet_Free_Context *context,
2173 Eet_Data_Descriptor *edd)
2178 if (context->freelist.ref > 0)
2181 for (j = 0; j < 256; ++j)
2182 for (i = 0; i < context->freelist.num[j]; ++i)
2183 if (context->freelist.list[j][i])
2186 edd->func.mem_free(context->freelist.list[j][i]);
2188 free(context->freelist.list[j][i]);
2190 _eet_free_reset(&context->freelist);
2191 } /* _eet_freelist_free */
2193 #define _eet_freelist_array_add(Ctx, Data) _eet_free_add(&Ctx->freelist_array, Data);
2194 #define _eet_freelist_array_del(Ctx, Data) _eet_free_del(&Ctx->freelist_array, Data);
2195 #define _eet_freelist_array_reset(Ctx) _eet_free_reset(&Ctx->freelist_array);
2196 #define _eet_freelist_array_ref(Ctx) _eet_free_ref(&Ctx->freelist_array);
2197 #define _eet_freelist_array_unref(Ctx) _eet_free_unref(&Ctx->freelist_array);
2200 _eet_freelist_array_free(Eet_Free_Context *context,
2201 Eet_Data_Descriptor *edd)
2206 if (context->freelist_array.ref > 0)
2209 for (j = 0; j < 256; ++j)
2210 for (i = 0; i < context->freelist_array.num[j]; ++i)
2211 if (context->freelist_array.list[j][i])
2215 if (edd->func.array_free)
2216 edd->func.array_free(context->freelist_array.list[j][i]);
2218 edd->func.mem_free(context->freelist_array.list[j][i]);
2221 free(context->freelist_array.list[j][i]);
2223 _eet_free_reset(&context->freelist_array);
2224 } /* _eet_freelist_array_free */
2226 #define _eet_freelist_list_add(Ctx, Data) _eet_free_add(&Ctx->freelist_list, Data);
2227 #define _eet_freelist_list_del(Ctx, Data) _eet_free_del(&Ctx->freelist_list, Data);
2228 #define _eet_freelist_list_reset(Ctx) _eet_free_reset(&Ctx->freelist_list);
2229 #define _eet_freelist_list_ref(Ctx) _eet_free_ref(&Ctx->freelist_list);
2230 #define _eet_freelist_list_unref(Ctx) _eet_free_unref(&Ctx->freelist_list);
2233 _eet_freelist_list_free(Eet_Free_Context *context,
2234 Eet_Data_Descriptor *edd)
2239 if (context->freelist_list.ref > 0)
2242 for (j = 0; j < 256; ++j)
2243 for (i = 0; i < context->freelist_list.num[j]; ++i)
2244 if (context->freelist_list.list[j][i])
2247 edd->func.list_free(*((void **)(context->freelist_list.list[j][i])));
2249 _eet_free_reset(&context->freelist_list);
2250 } /* _eet_freelist_list_free */
2252 #define _eet_freelist_str_add(Ctx, Data) _eet_free_add(&Ctx->freelist_str, Data);
2253 #define _eet_freelist_str_del(Ctx, Data) _eet_free_del(&Ctx->freelist_str, Data);
2254 #define _eet_freelist_str_reset(Ctx) _eet_free_reset(&Ctx->freelist_str);
2255 #define _eet_freelist_str_ref(Ctx) _eet_free_ref(&Ctx->freelist_str);
2256 #define _eet_freelist_str_unref(Ctx) _eet_free_unref(&Ctx->freelist_str);
2259 _eet_freelist_str_free(Eet_Free_Context *context, Eet_Data_Descriptor *edd)
2264 if (context->freelist_str.ref > 0)
2267 for (j = 0; j < 256; ++j)
2268 for (i = 0; i < context->freelist_str.num[j]; ++i)
2269 if (context->freelist_str.list[j][i])
2272 edd->func.str_free(context->freelist_str.list[j][i]);
2274 free(context->freelist_str.list[j][i]);
2276 _eet_free_reset(&context->freelist_str);
2277 } /* _eet_freelist_str_free */
2279 #define _eet_freelist_direct_str_add(Ctx, Data) _eet_free_add(&Ctx->freelist_direct_str, Data);
2280 #define _eet_freelist_direct_str_del(Ctx, Data) _eet_free_del(&Ctx->freelist_direct_str, Data);
2281 #define _eet_freelist_direct_str_reset(Ctx) _eet_free_reset(&Ctx->freelist_direct_str);
2282 #define _eet_freelist_direct_str_ref(Ctx) _eet_free_ref(&Ctx->freelist_direct_str);
2283 #define _eet_freelist_direct_str_unref(Ctx) _eet_free_unref(&Ctx->freelist_direct_str);
2286 _eet_freelist_direct_str_free(Eet_Free_Context *context,
2287 Eet_Data_Descriptor *edd)
2292 if (context->freelist_direct_str.ref > 0)
2295 for (j = 0; j < 256; ++j)
2296 for (i = 0; i < context->freelist_direct_str.num[j]; ++i)
2297 if (context->freelist_direct_str.list[j][i])
2300 edd->func.str_direct_free(context->freelist_direct_str.list[j][i]);
2302 free(context->freelist_direct_str.list[j][i]);
2304 _eet_free_reset(&context->freelist_direct_str);
2305 } /* _eet_freelist_direct_str_free */
2307 #define _eet_freelist_hash_add(Ctx, Data) _eet_free_add(&Ctx->freelist_hash, Data);
2308 #define _eet_freelist_hash_del(Ctx, Data) _eet_free_del(&Ctx->freelist_hash, Data);
2309 #define _eet_freelist_hash_reset(Ctx) _eet_free_reset(&Ctx->freelist_hash);
2310 #define _eet_freelist_hash_ref(Ctx) _eet_free_ref(&Ctx->freelist_hash);
2311 #define _eet_freelist_hash_unref(Ctx) _eet_free_unref(&Ctx->freelist_hash);
2314 _eet_freelist_hash_free(Eet_Free_Context *context,
2315 Eet_Data_Descriptor *edd)
2320 if (context->freelist_hash.ref > 0)
2323 for (j = 0; j < 256; ++j)
2324 for (i = 0; i < context->freelist_hash.num[j]; ++i)
2325 if (context->freelist_hash.list[j][i])
2328 edd->func.hash_free(context->freelist_hash.list[j][i]);
2330 free(context->freelist_hash.list[j][i]);
2332 _eet_free_reset(&context->freelist_hash);
2333 } /* _eet_freelist_hash_free */
2336 _eet_freelist_all_ref(Eet_Free_Context *freelist_context)
2338 _eet_freelist_ref(freelist_context);
2339 _eet_freelist_str_ref(freelist_context);
2340 _eet_freelist_list_ref(freelist_context);
2341 _eet_freelist_hash_ref(freelist_context);
2342 _eet_freelist_direct_str_ref(freelist_context);
2343 } /* _eet_freelist_all_ref */
2346 _eet_freelist_all_unref(Eet_Free_Context *freelist_context)
2348 _eet_freelist_unref(freelist_context);
2349 _eet_freelist_str_unref(freelist_context);
2350 _eet_freelist_list_unref(freelist_context);
2351 _eet_freelist_hash_unref(freelist_context);
2352 _eet_freelist_direct_str_unref(freelist_context);
2353 } /* _eet_freelist_all_unref */
2356 eet_data_descriptor_encode_hash_cb(void *hash __UNUSED__,
2357 const char *cipher_key,
2362 Eet_Data_Encode_Hash_Info *edehi;
2363 Eet_Data_Stream *ds;
2364 Eet_Data_Element *ede;
2365 Eet_Data_Chunk *echnk;
2375 data = eet_data_put_type(ed,
2381 echnk = eet_data_chunk_new(data,
2386 eet_data_chunk_put(ed, echnk, ds);
2387 eet_data_chunk_free(echnk);
2392 EET_ASSERT(!((ede->type > EET_T_UNKNOW) && (ede->type < EET_T_STRING)), return );
2395 if (ede->type >= EET_T_STRING)
2396 eet_data_put_unknown(ed, NULL, ede, ds, &hdata);
2400 data = _eet_data_descriptor_encode(ed,
2407 echnk = eet_data_chunk_new(data,
2412 eet_data_chunk_put(ed, echnk, ds);
2413 eet_data_chunk_free(echnk);
2420 } /* eet_data_descriptor_encode_hash_cb */
2423 _eet_data_dump_token_get(const char *src,
2430 int tlen = 0, tsize = 0;
2438 tok = realloc(tok, tsize);\
2443 for (p = src; *len > 0; p++, (*len)--)
2449 if ((p[0] == '\"') && (p > src) && (p[-1] != '\\'))
2451 else if ((p[0] == '\\') && (*len > 1) &&
2456 else if ((p[0] == '\\') && (p > src) && (p[-1] == '\\'))
2460 else if ((p[0] == '\\') && (*len > 1) && (p[1] == 'n'))
2464 else if ((p[0] == 'n') && (p > src) && (p[-1] == '\\'))
2475 if ((isspace(p[0])) || (p[0] == ';')) /* token ends here */
2486 else if (!((isspace(p[0])) || (p[0] == ';')))
2503 } /* _eet_data_dump_token_get */
2506 eet_data_encode(Eet_Dictionary *ed,
2507 Eet_Data_Stream *ds,
2514 Eet_Data_Chunk *echnk;
2519 if (group_type != EET_G_UNKNOWN)
2520 if (type >= EET_T_LAST)
2521 type = EET_T_UNKNOW;
2523 echnk = eet_data_chunk_new(data, size, name, type, group_type);
2524 eet_data_chunk_put(ed, echnk, ds);
2525 eet_data_chunk_free(echnk);
2527 } /* eet_data_encode */
2530 _eet_data_dump_encode(int parent_type,
2535 Eet_Data_Chunk *chnk = NULL;
2536 Eet_Data_Stream *ds;
2543 if (_eet_data_words_bigendian == -1)
2545 unsigned long int v;
2547 v = htonl(0x12345678);
2548 if (v == 0x12345678)
2549 _eet_data_words_bigendian = 1;
2551 _eet_data_words_bigendian = 0;
2557 ds = eet_data_stream_new();
2564 for (n = node->values; n; n = n->next)
2566 data = _eet_data_dump_encode(node->type, ed, n, &size);
2569 eet_data_stream_write(ds, data, size);
2576 case EET_G_VAR_ARRAY:
2577 for (child_type = EET_T_NULL, n = node->values; n; n = n->next)
2579 if (n->type != EET_T_NULL)
2581 child_type = n->type;
2586 data = eet_data_put_type(ed,
2598 count = node->count;
2600 for (n = node->values; n; n = n->next)
2607 case EET_T_INLINED_STRING:
2608 data = eet_data_put_type(ed,
2610 &(n->data.value.str),
2627 data = _eet_data_dump_encode(n->type, ed, n, &size);
2641 for (; count; count--)
2652 /* Array is somekind of special case, so we should embed it inside another chunk. */
2653 *size_ret = ds->pos;
2658 eet_data_stream_free(ds);
2664 for (n = node->values; n; n = n->next)
2669 case EET_T_INLINED_STRING:
2670 data = eet_data_put_type(ed,
2672 &(n->data.value.str),
2689 data = _eet_data_dump_encode(node->type, ed, n, &size);
2700 /* List is another somekind of special case, every chunk is embed inside a list chunk. */
2701 *size_ret = ds->pos;
2706 eet_data_stream_free(ds);
2714 data = eet_data_put_type(ed,
2727 /* A Hash without key will not decode correctly. */
2730 for (n = node->values; n; n = n->next)
2735 case EET_T_INLINED_STRING:
2736 data = eet_data_put_type(ed,
2738 &(n->data.value.str),
2755 data = _eet_data_dump_encode(node->type, ed, n, &size);
2766 /* Hash is somekind of special case, so we should embed it inside another chunk. */
2767 *size_ret = ds->pos;
2770 eet_data_stream_flush(ds);
2777 #define EET_DATA_NODE_ENCODE(Eet_Type, Type)\
2779 data = eet_data_put_type(ed, node->type, &(node->data.value.Type), &size);\
2782 eet_data_encode(ed,\
2790 *size_ret = ds->pos;\
2791 eet_data_stream_flush(ds);\
2796 EET_DATA_NODE_ENCODE(EET_T_CHAR, c);
2797 EET_DATA_NODE_ENCODE(EET_T_SHORT, s);
2798 EET_DATA_NODE_ENCODE(EET_T_INT, i);
2799 EET_DATA_NODE_ENCODE(EET_T_LONG_LONG, l);
2800 EET_DATA_NODE_ENCODE(EET_T_FLOAT, f);
2801 EET_DATA_NODE_ENCODE(EET_T_DOUBLE, d);
2802 EET_DATA_NODE_ENCODE(EET_T_UCHAR, uc);
2803 EET_DATA_NODE_ENCODE(EET_T_USHORT, us);
2804 EET_DATA_NODE_ENCODE(EET_T_UINT, ui);
2805 EET_DATA_NODE_ENCODE(EET_T_ULONG_LONG, ul);
2806 EET_DATA_NODE_ENCODE(EET_T_INLINED_STRING, str);
2807 EET_DATA_NODE_ENCODE(EET_T_STRING, str);
2813 if ((node->type >= EET_G_UNKNOWN) && (node->type < EET_G_LAST))
2814 chnk = eet_data_chunk_new(ds->data,
2820 chnk = eet_data_chunk_new(ds->data,
2826 eet_data_stream_flush(ds);
2828 ds = eet_data_stream_new();
2829 eet_data_chunk_put(ed, chnk, ds);
2833 eet_data_stream_flush(ds);
2837 eet_data_chunk_free(chnk);
2840 } /* _eet_data_dump_encode */
2843 _eet_data_dump_parse(Eet_Dictionary *ed,
2849 const char *p = NULL;
2854 Eet_Node *node_base = NULL;
2855 Eet_Node *node = NULL;
2856 Eet_Node *n = NULL, *nn = NULL;
2858 /* FIXME; handle parse errors */
2860 jump = left; t = _eet_data_dump_token_get(p, &left); p += jump - left;
2862 for (p = src; p < (src + size); )
2864 char *tok1, *tok2, *tok3, *tok4;
2869 if (!strcmp(tok1, "group"))
2880 if (!strcmp(tok4, "{"))
2882 /* we have 'group NAM TYP {' */
2896 for (nn = node->values; nn;
2907 n->name = eina_stringshare_add(tok2);
2908 if (!strcmp(tok3, "struct"))
2909 n->type = EET_G_UNKNOWN;
2910 else if (!strcmp(tok3, "array"))
2911 n->type = EET_G_ARRAY;
2912 else if (!strcmp(tok3, "var_array"))
2913 n->type = EET_G_VAR_ARRAY;
2914 else if (!strcmp(tok3, "list"))
2915 n->type = EET_G_LIST;
2916 else if (!strcmp(tok3, "hash"))
2917 n->type = EET_G_HASH;
2920 "ERROR: group type '%s' invalid.",
2936 else if (!strcmp(tok1, "value"))
2947 /* we have 'value NAME TYP XXX' */
2958 for (nn = node->values; nn;
2968 n->name = eina_stringshare_add(tok2);
2969 if (!strcmp(tok3, "char:"))
2971 n->type = EET_T_CHAR;
2972 sscanf(tok4, "%hhi",
2973 &(n->data.value.c));
2975 else if (!strcmp(tok3, "short:"))
2977 n->type = EET_T_SHORT;
2979 &(n->data.value.s));
2981 else if (!strcmp(tok3, "int:"))
2983 n->type = EET_T_INT;
2985 &(n->data.value.i));
2987 else if (!strcmp(tok3, "long_long:"))
2989 n->type = EET_T_LONG_LONG;
2990 sscanf(tok4, "%lli",
2991 &(n->data.value.l));
2993 else if (!strcmp(tok3, "float:"))
2995 n->type = EET_T_FLOAT;
2997 &(n->data.value.f));
2999 else if (!strcmp(tok3, "double:"))
3001 n->type = EET_T_DOUBLE;
3003 &(n->data.value.d));
3005 else if (!strcmp(tok3, "uchar:"))
3007 n->type = EET_T_UCHAR;
3008 sscanf(tok4, "%hhu",
3009 &(n->data.value.uc));
3011 else if (!strcmp(tok3, "ushort:"))
3013 n->type = EET_T_USHORT;
3015 &(n->data.value.us));
3017 else if (!strcmp(tok3, "uint:"))
3019 n->type = EET_T_UINT;
3021 &(n->data.value.ui));
3023 else if (!strcmp(tok3, "ulong_long:"))
3025 n->type = EET_T_ULONG_LONG;
3026 sscanf(tok4, "%llu",
3027 &(n->data.value.ul));
3029 else if (!strcmp(tok3, "string:"))
3031 n->type = EET_T_STRING;
3033 eina_stringshare_add(tok4);
3035 else if (!strcmp(tok3, "inlined:"))
3037 n->type = EET_T_INLINED_STRING;
3039 eina_stringshare_add(tok4);
3041 else if (!strcmp(tok3, "null"))
3043 n->type = EET_T_NULL;
3044 n->data.value.str = NULL;
3048 "ERROR: value type '%s' invalid.",
3062 else if (!strcmp(tok1, "key"))
3067 /* we have 'key NAME' */
3069 node->key = eina_stringshare_add(tok2);
3074 else if (!strcmp(tok1, "count"))
3079 /* we have a 'count COUNT' */
3081 sscanf(tok2, "%i", &(node->count));
3086 else if (!strcmp(tok1, "}"))
3087 /* we have an end of the group */
3089 node = node->parent;
3097 cdata = _eet_data_dump_encode(EET_G_UNKNOWN, ed, node_base, size_ret);
3098 eet_node_del(node_base);
3102 } /* _eet_data_dump_parse */
3104 #define NEXT_CHUNK(P, Size, Echnk, Ed)\
3107 tmp = Ed ? (int)(sizeof(int) * 2) : Echnk.len + 4;\
3108 P += (4 + Echnk.size + tmp);\
3109 Size -= (4 + Echnk.size + tmp);\
3113 _eet_data_descriptor_decode(Eet_Free_Context *context,
3114 const Eet_Dictionary *ed,
3115 Eet_Data_Descriptor *edd,
3116 const void *data_in,
3119 Eet_Node *result = NULL;
3123 Eet_Data_Chunk chnk;
3125 if (_eet_data_words_bigendian == -1)
3127 unsigned long int v;
3129 v = htonl(0x12345678);
3130 if (v == 0x12345678)
3131 _eet_data_words_bigendian = 1;
3133 _eet_data_words_bigendian = 0;
3138 data = edd->func.mem_alloc(edd->size);
3144 for (i = 0; i < edd->elements.num; i++)
3145 edd->elements.set[i].directory_name_ptr = NULL;
3150 _eet_freelist_all_ref(context);
3152 _eet_freelist_add(context, data);
3154 memset(&chnk, 0, sizeof(Eet_Data_Chunk));
3155 eet_data_chunk_get(ed, &chnk, data_in, size_in);
3160 if (strcmp(chnk.name, edd->name))
3165 size = size_in - (4 + sizeof(int) * 2);
3167 size = size_in - (4 + 4 + chnk.len);
3171 if (!edd->elements.hash.buckets)
3172 _eet_descriptor_hash_new(edd);
3176 switch (chnk.group_type)
3182 return eet_node_string_new(chnk.name, chnk.data);
3184 case EET_T_INLINED_STRING:
3185 return eet_node_inlined_string_new(chnk.name, chnk.data);
3188 return eet_node_null_new(chnk.name);
3191 result = eet_node_struct_new(chnk.name, NULL);
3195 case EET_G_VAR_ARRAY:
3196 return eet_node_var_array_new(chnk.name, NULL);
3210 Eet_Data_Chunk echnk;
3211 Eet_Data_Element *ede = NULL;
3212 Eet_Node *child = NULL;
3213 int group_type = EET_G_UNKNOWN, type = EET_T_UNKNOW;
3216 /* get next data chunk */
3217 memset(&echnk, 0, sizeof(Eet_Data_Chunk));
3218 eet_data_chunk_get(ed, &echnk, p, size);
3220 goto error; /* FIXME: don't REPLY on edd - work without */
3224 ede = _eet_descriptor_hash_find(edd, echnk.name, echnk.hash);
3227 group_type = ede->group_type;
3229 if ((echnk.type == 0) && (echnk.group_type == 0))
3232 group_type = ede->group_type;
3236 if (IS_SIMPLE_TYPE(echnk.type) &&
3237 eet_data_type_match(echnk.type, ede->type))
3238 /* Needed when converting on the fly from FP to Float */
3240 else if ((echnk.group_type > EET_G_UNKNOWN) &&
3241 (echnk.group_type < EET_G_LAST) &&
3242 (echnk.group_type == ede->group_type))
3243 group_type = echnk.group_type;
3247 /*...... dump to node */
3251 group_type = echnk.group_type;
3254 if (!edd && group_type == EET_G_UNKNOWN && IS_SIMPLE_TYPE(type))
3256 unsigned char dd[128];
3258 ret = eet_data_get_type(ed,
3261 ((char *)echnk.data) + echnk.size,
3266 child = eet_data_node_simple_type(type, echnk.name, dd);
3268 eet_node_struct_append(result, echnk.name, child);
3272 ret = eet_group_codec[group_type - 100].get(
3280 ede ? (void *)(((char*) data) + ede->offset) : (void **)&result,
3288 /* advance to next chunk */
3289 NEXT_CHUNK(p, size, echnk, ed);
3292 _eet_freelist_all_unref(context);
3295 _eet_freelist_str_free(context, edd);
3296 _eet_freelist_direct_str_free(context, edd);
3297 _eet_freelist_list_free(context, edd);
3298 _eet_freelist_hash_free(context, edd);
3299 _eet_freelist_array_free(context, edd);
3300 _eet_freelist_free(context, edd);
3304 _eet_freelist_reset(context);
3305 _eet_freelist_str_reset(context);
3306 _eet_freelist_list_reset(context);
3307 _eet_freelist_hash_reset(context);
3308 _eet_freelist_direct_str_reset(context);
3309 _eet_freelist_array_reset(context);
3318 eet_node_del(result);
3320 _eet_freelist_all_unref(context);
3321 _eet_freelist_str_free(context, edd);
3322 _eet_freelist_direct_str_free(context, edd);
3323 _eet_freelist_list_free(context, edd);
3324 _eet_freelist_hash_free(context, edd);
3325 _eet_freelist_array_free(context, edd);
3326 _eet_freelist_free(context, edd);
3328 /* FIXME: Warn that something goes wrong here. */
3330 } /* _eet_data_descriptor_decode */
3333 eet_data_get_list(Eet_Free_Context *context,
3334 const Eet_Dictionary *ed,
3335 Eet_Data_Descriptor *edd,
3336 Eet_Data_Element *ede,
3337 Eet_Data_Chunk *echnk,
3339 int group_type __UNUSED__,
3344 Eet_Data_Descriptor *subtype = NULL;
3349 EET_ASSERT(!((type > EET_T_UNKNOW) && (type < EET_T_STRING)), return 0);
3353 subtype = ede->subtype;
3355 if (type != ede->type)
3359 ptr = (void **)data;
3363 if (IS_POINTER_TYPE(type))
3364 POINTER_TYPE_DECODE(context,
3375 STRUCT_TYPE_DECODE(data_ret,
3385 list = edd->func.list_append(list, data_ret);
3387 _eet_freelist_list_add(context, ptr);
3390 eet_node_list_append(*((Eet_Node **)data), echnk->name, data_ret);
3396 } /* eet_data_get_list */
3399 eet_data_get_hash(Eet_Free_Context *context,
3400 const Eet_Dictionary *ed,
3401 Eet_Data_Descriptor *edd,
3402 Eet_Data_Element *ede,
3403 Eet_Data_Chunk *echnk,
3405 int group_type __UNUSED__,
3413 void *data_ret = NULL;
3416 EET_ASSERT(!((type > EET_T_UNKNOW) && (type < EET_T_STRING)), return 0);
3418 ptr = (void **)data;
3422 ret = eet_data_get_type(ed,
3425 ((char *)echnk->data) + echnk->size,
3433 /* Advance to next chunk */
3434 NEXT_CHUNK((*p), (*size), (*echnk), ed);
3435 memset(echnk, 0, sizeof(Eet_Data_Chunk));
3438 eet_data_chunk_get(ed, echnk, *p, *size);
3443 if ((ede->group_type != echnk->group_type)
3444 || (ede->type != echnk->type))
3447 if (IS_POINTER_TYPE(echnk->type))
3448 POINTER_TYPE_DECODE(context,
3459 STRUCT_TYPE_DECODE(data_ret,
3462 ede ? ede->subtype : NULL,
3469 hash = edd->func.hash_add(hash, key, data_ret);
3471 _eet_freelist_hash_add(context, hash);
3474 eet_node_hash_add(*((Eet_Node **)data), echnk->name, key, data_ret);
3480 } /* eet_data_get_hash */
3482 /* var arrays and fixed arrays have to
3483 * get all chunks at once. for fixed arrays
3484 * we can get each chunk and increment a
3485 * counter stored on the element itself but
3486 * it wont be thread safe. for var arrays
3487 * we still need a way to get the number of
3488 * elements from the data, so storing the
3489 * number of elements and the element data on
3490 * each chunk is pointless.
3493 eet_data_get_array(Eet_Free_Context *context,
3494 const Eet_Dictionary *ed,
3495 Eet_Data_Descriptor *edd,
3496 Eet_Data_Element *ede,
3497 Eet_Data_Chunk *echnk,
3504 Eina_List *childs = NULL;
3513 EET_ASSERT(!((type > EET_T_UNKNOW) && (type < EET_T_STRING)), return 0);
3516 /* read the number of elements */
3517 ret = eet_data_get_type(ed,
3520 ((char *)echnk->data) + echnk->size,
3529 if (IS_POINTER_TYPE(type))
3530 subsize = eet_basic_codec[ede->type].size;
3532 subsize = ede->subtype->size;
3534 if (group_type == EET_G_VAR_ARRAY)
3536 /* store the number of elements
3537 * on the counter offset */
3538 *(int *)(((char *)data) + ede->count - ede->offset) = count;
3539 /* allocate space for the array of elements */
3540 if (edd->func.array_alloc)
3541 *(void **) ptr = edd->func.array_alloc(count * subsize);
3543 *(void **) ptr = edd->func.mem_alloc(count * subsize);
3548 memset(*(void **)ptr, 0, count * subsize);
3550 _eet_freelist_array_add(context, *(void **)ptr);
3554 /* get all array elements */
3555 for (i = 0; i < count; i++)
3558 void *data_ret = NULL;
3560 /* Advance to next chunk */
3561 NEXT_CHUNK((*p), (*size), (*echnk), ed);
3562 memset(echnk, 0, sizeof(Eet_Data_Chunk));
3564 eet_data_chunk_get(ed, echnk, *p, *size);
3565 if (!echnk->name || strcmp(echnk->name, name) != 0)
3566 goto on_error; /* get the data */
3568 if ((echnk->group_type != group_type)
3569 || ((echnk->type != type) && (echnk->type != EET_T_NULL)))
3573 if ((ede->group_type != echnk->group_type)
3574 || ((echnk->type != ede->type) && (echnk->type != EET_T_NULL)))
3577 /* get the destination pointer */
3580 if (group_type == EET_G_ARRAY)
3581 dst = (char *)ptr + (subsize * i);
3583 dst = *(char **)ptr + (subsize * i);
3586 if (IS_POINTER_TYPE(echnk->type))
3588 POINTER_TYPE_DECODE(context,
3599 memcpy(dst, &data_ret, subsize);
3602 childs = eina_list_append(childs, data_ret);
3606 STRUCT_TYPE_DECODE(data_ret,
3609 ede ? ede->subtype : NULL,
3615 memcpy(dst, data_ret, subsize);
3616 if ((ede) && (ede->subtype))
3617 ede->subtype->func.mem_free(data_ret);
3619 edd->func.mem_free(data_ret);
3620 else free(data_ret);
3621 _eet_freelist_del(context, data_ret);
3625 childs = eina_list_append(childs, data_ret);
3631 Eet_Node *parent = *((Eet_Node **)data);
3634 if (group_type == EET_G_ARRAY)
3635 array = eet_node_array_new(name, count, childs);
3637 array = eet_node_var_array_new(name, childs);
3642 eet_node_struct_append(parent, name, array);
3648 EINA_LIST_FREE(childs, tmp)
3652 } /* eet_data_get_array */
3655 eet_data_put_union(Eet_Dictionary *ed,
3656 Eet_Data_Descriptor *edd __UNUSED__,
3657 Eet_Data_Element *ede,
3658 Eet_Data_Stream *ds,
3661 const char *union_type;
3664 EET_ASSERT(!((ede->type != EET_T_UNKNOW) || (!ede->subtype)), return );
3666 union_type = ede->subtype->func.type_get(
3667 ((char *)data_in) + ede->count - ede->offset,
3673 /* Search the structure of the union to encode. */
3674 for (i = 0; i < ede->subtype->elements.num; ++i)
3675 if (strcmp(ede->subtype->elements.set[i].name, union_type) == 0)
3677 Eet_Data_Element *sede;
3681 /* Yeah we found it ! */
3682 data = eet_data_put_type(ed, EET_T_STRING, &union_type, &size);
3692 sede = &(ede->subtype->elements.set[i]);
3693 data = _eet_data_descriptor_encode(ed,
3709 } /* eet_data_put_union */
3712 eet_data_get_union(Eet_Free_Context *context,
3713 const Eet_Dictionary *ed,
3714 Eet_Data_Descriptor *edd __UNUSED__,
3715 Eet_Data_Element *ede,
3716 Eet_Data_Chunk *echnk,
3723 const char *union_type;
3724 void *data_ret = NULL;
3729 ret = eet_data_get_type(ed,
3732 ((char *)echnk->data) + echnk->size,
3737 /* Advance to next chunk */
3738 NEXT_CHUNK((*p), (*size), (*echnk), ed);
3739 memset(echnk, 0, sizeof(Eet_Data_Chunk));
3742 eet_data_chunk_get(ed, echnk, *p, *size);
3748 EET_ASSERT(!(ede->group_type != group_type || ede->type != type),
3751 /* Search the structure of the union to decode */
3752 for (i = 0; i < ede->subtype->elements.num; ++i)
3753 if (strcmp(ede->subtype->elements.set[i].name, union_type) == 0)
3755 Eet_Data_Element *sede;
3758 /* Yeah we found it ! */
3759 sede = &(ede->subtype->elements.set[i]);
3760 EET_ASSERT(sede->subtype, goto on_error);
3762 data_ret = _eet_data_descriptor_decode(context,
3770 /* Memcopy the structure content to remove pointer indirection. */
3771 memcpy(data, data_ret, sede->subtype->size);
3773 /* data_ret is now useless. */
3774 sede->subtype->func.mem_free(data_ret);
3776 /* Set union type. */
3777 if ((!ed) || (!ede->subtype->func.str_direct_alloc))
3779 ut = ede->subtype->func.str_alloc(union_type);
3780 _eet_freelist_str_add(context, ut);
3784 ut = ede->subtype->func.str_direct_alloc(union_type);
3785 _eet_freelist_direct_str_add(context, ut);
3788 ede->subtype->func.type_set(
3790 ((char *)data) + ede->count -
3800 /* FIXME: generate node structure. */
3801 data_ret = _eet_data_descriptor_decode(context,
3803 echnk->data, echnk->size);
3811 } /* eet_data_get_union */
3814 eet_data_put_variant(Eet_Dictionary *ed,
3815 Eet_Data_Descriptor *edd __UNUSED__,
3816 Eet_Data_Element *ede,
3817 Eet_Data_Stream *ds,
3820 const char *union_type;
3822 Eina_Bool unknow = EINA_FALSE;
3826 EET_ASSERT(!((ede->type != EET_T_UNKNOW) || (!ede->subtype)), return );
3828 union_type = ede->subtype->func.type_get(
3829 ((char *)data_in) + ede->count - ede->offset,
3832 if (!union_type && unknow == EINA_FALSE)
3837 /* Handle opaque internal representation */
3838 Eet_Variant_Unknow *evu;
3840 data = eet_data_put_type(ed, EET_T_STRING, &union_type, &size);
3850 evu = (Eet_Variant_Unknow *)data_in;
3851 if (evu && EINA_MAGIC_CHECK(evu, EET_MAGIC_VARIANT))
3861 /* Search the structure of the union to encode. */
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 data = eet_data_put_type(ed, EET_T_STRING, &union_type, &size);
3878 sede = &(ede->subtype->elements.set[i]);
3880 if (sede->group_type != EET_G_UNKNOWN)
3882 Eet_Data_Stream *lds;
3884 lds = eet_data_stream_new();
3885 eet_group_codec[sede->group_type - 100].put(ed,
3892 eet_data_encode(ed, ds, lds->data, ede->name, lds->pos,
3893 ede->type, ede->group_type);
3899 eet_data_encode(ed, ds, NULL, ede->name, 0,
3900 EET_T_NULL, ede->group_type);
3902 eet_data_stream_free(lds);
3906 data = _eet_data_descriptor_encode(ed,
3923 } /* eet_data_put_variant */
3926 eet_data_get_variant(Eet_Free_Context *context,
3927 const Eet_Dictionary *ed,
3928 Eet_Data_Descriptor *edd __UNUSED__,
3929 Eet_Data_Element *ede,
3930 Eet_Data_Chunk *echnk,
3931 int type __UNUSED__,
3932 int group_type __UNUSED__,
3937 const char *union_type;
3938 void *data_ret = NULL;
3943 ret = eet_data_get_type(ed,
3946 ((char *)echnk->data) + echnk->size,
3951 /* Advance to next chunk */
3952 NEXT_CHUNK((*p), (*size), (*echnk), ed);
3953 memset(echnk, 0, sizeof(Eet_Data_Chunk));
3956 eet_data_chunk_get(ed, echnk, *p, *size);
3964 EET_ASSERT(ede->subtype, goto on_error);
3966 if ((!ed) || (!ede->subtype->func.str_direct_alloc))
3968 ut = ede->subtype->func.str_alloc(union_type);
3969 _eet_freelist_str_add(context, ut);
3973 ut = ede->subtype->func.str_direct_alloc(union_type);
3974 _eet_freelist_direct_str_add(context, ut);
3977 /* Search the structure of the union to decode */
3978 for (i = 0; i < ede->subtype->elements.num; ++i)
3979 if (strcmp(ede->subtype->elements.set[i].name, union_type) == 0)
3981 Eet_Data_Element *sede;
3983 /* Yeah we found it ! */
3984 sede = &(ede->subtype->elements.set[i]);
3986 if (sede->group_type != EET_G_UNKNOWN)
3988 Eet_Data_Chunk chnk;
3994 size2 = echnk->size;
3996 /* Didn't find a proper way to provide this
3997 without duplicating code */
4000 memset(&chnk, 0, sizeof(Eet_Data_Chunk));
4001 eet_data_chunk_get(ed, &chnk, p2, size2);
4006 ret = eet_group_codec[sede->group_type - 100].get
4007 (context, ed, sede->subtype, sede, &chnk, sede->type,
4008 sede->group_type, data, &p2, &size2);
4013 /* advance to next chunk */
4014 NEXT_CHUNK(p2, size2, chnk, ed);
4017 /* Put garbage so that we will not put eet_variant_unknow in it */
4018 data_ret = (void *)data;
4020 /* Set variant type. */
4021 ede->subtype->func.type_set
4022 (ut, ((char *)data) + ede->count - ede->offset,
4027 data_ret = _eet_data_descriptor_decode(context,
4035 /* And point to the variant data. */
4036 *(void **)data = data_ret;
4038 /* Set variant type. */
4039 ede->subtype->func.type_set
4040 (ut, ((char *)data) + ede->count - ede->offset, EINA_FALSE);
4046 Eet_Variant_Unknow *evu;
4048 evu = calloc(1, sizeof (Eet_Variant_Unknow) + echnk->size - 1);
4052 evu->size = echnk->size;
4053 memcpy(evu->data, echnk->data, evu->size);
4054 EINA_MAGIC_SET(evu, EET_MAGIC_VARIANT);
4056 /* And point to the opaque internal data scructure */
4057 *(void **)data = evu;
4059 /* Set variant type. */
4060 ede->subtype->func.type_set
4061 (ut, ((char *)data) + ede->count - ede->offset, EINA_TRUE);
4066 /* FIXME: dump node structure. */
4067 data_ret = _eet_data_descriptor_decode(context,
4069 echnk->data, echnk->size);
4077 } /* eet_data_get_variant */
4080 eet_data_node_simple_type(int type, const char *name, void *dd)
4084 #endif /* ifdef EET_T_TYPE */
4086 #define EET_T_TYPE(Eet_Type, Eet_Node_Type, Type)\
4088 return eet_node_ ## Eet_Node_Type ## _new(name, *((Type *)dd));\
4092 EET_T_TYPE(EET_T_CHAR, char, char);
4093 EET_T_TYPE(EET_T_SHORT, short, short);
4094 EET_T_TYPE(EET_T_INT, int, int);
4095 EET_T_TYPE(EET_T_LONG_LONG, long_long, long long);
4096 EET_T_TYPE(EET_T_FLOAT, float, float);
4097 EET_T_TYPE(EET_T_DOUBLE, double, double);
4098 EET_T_TYPE(EET_T_UCHAR, unsigned_char, unsigned char);
4099 EET_T_TYPE(EET_T_USHORT, unsigned_short, unsigned short);
4100 EET_T_TYPE(EET_T_UINT, unsigned_int, unsigned int);
4101 EET_T_TYPE(EET_T_ULONG_LONG, unsigned_long_long, unsigned long long);
4102 EET_T_TYPE(EET_T_STRING, string, char *);
4103 EET_T_TYPE(EET_T_INLINED_STRING, inlined_string, char *);
4106 return eet_node_null_new(name);
4109 ERR("Unknow type passed to eet_data_node_simple_type");
4112 } /* eet_data_node_simple_type */
4115 eet_data_get_unknown(Eet_Free_Context *context,
4116 const Eet_Dictionary *ed,
4117 Eet_Data_Descriptor *edd,
4118 Eet_Data_Element *ede,
4119 Eet_Data_Chunk *echnk,
4121 int group_type __UNUSED__,
4123 char **p __UNUSED__,
4124 int *size __UNUSED__)
4129 if (IS_SIMPLE_TYPE(type))
4131 unsigned char dd[128];
4133 ret = eet_data_get_type(ed,
4136 ((char *)echnk->data) + echnk->size,
4137 edd ? (char *)data : (char *)dd);
4143 Eet_Node **parent = data;
4146 node = eet_data_node_simple_type(type, echnk->name, dd);
4149 eet_node_struct_append(*parent, echnk->name, node);
4155 if (type == EET_T_STRING)
4159 str = (char **)(((char *)data));
4162 if ((!ed) || (!edd->func.str_direct_alloc))
4164 *str = edd->func.str_alloc(*str);
4165 _eet_freelist_str_add(context, *str);
4169 *str = edd->func.str_direct_alloc(*str);
4170 _eet_freelist_direct_str_add(context, *str);
4174 else if (edd && type == EET_T_INLINED_STRING)
4178 str = (char **)(((char *)data));
4181 *str = edd->func.str_alloc(*str);
4182 _eet_freelist_str_add(context, *str);
4189 Eet_Data_Descriptor *subtype;
4191 subtype = ede ? ede->subtype : NULL;
4193 if (subtype || !edd)
4195 Eet_Node **parent = data;
4198 data_ret = _eet_data_descriptor_decode(context,
4208 ptr = (void **)(((char *)data));
4209 *ptr = (void *)data_ret;
4213 Eet_Node *node = data_ret;
4217 node = eet_node_struct_child_new(echnk->name, node);
4218 eet_node_struct_append(*parent, echnk->name, node);
4227 } /* eet_data_get_unknown */
4230 eet_data_put_array(Eet_Dictionary *ed,
4231 Eet_Data_Descriptor *edd __UNUSED__,
4232 Eet_Data_Element *ede,
4233 Eet_Data_Stream *ds,
4243 EET_ASSERT(!((ede->type > EET_T_UNKNOW) && (ede->type < EET_T_STRING)),
4246 if (ede->group_type == EET_G_ARRAY)
4247 count = ede->counter_offset;
4249 count = *(int *)(((char *)data_in) + ede->count - ede->offset);
4252 return; /* Store number of elements */
4254 data = eet_data_put_type(ed, EET_T_INT, &count, &size);
4256 eet_data_encode(ed, ds, data, ede->name, size, ede->type, ede->group_type);
4258 if (IS_POINTER_TYPE(ede->type))
4259 subsize = eet_basic_codec[ede->type].size;
4261 subsize = ede->subtype->size;
4263 for (j = 0; j < count; j++)
4268 if (ede->group_type == EET_G_ARRAY)
4269 d = (void *)(((char *)data_in) + offset);
4271 d = *(((char **)data_in)) + offset;
4273 if (IS_POINTER_TYPE(ede->type))
4276 eet_data_put_unknown(ed, NULL, ede, ds, d);
4280 data = _eet_data_descriptor_encode(ed, ede->subtype, d, &size);
4292 /* Add a NULL element just to have the correct array layout. */
4303 } /* eet_data_put_array */
4306 eet_data_put_unknown(Eet_Dictionary *ed,
4307 Eet_Data_Descriptor *edd __UNUSED__,
4308 Eet_Data_Element *ede,
4309 Eet_Data_Stream *ds,
4315 if (IS_SIMPLE_TYPE(ede->type))
4316 data = eet_data_put_type(ed, ede->type, data_in, &size);
4317 else if (ede->subtype)
4318 if (*((char **)data_in))
4319 data = _eet_data_descriptor_encode(ed,
4321 *((char **)((char *)(data_in))),
4332 } /* eet_data_put_unknown */
4335 eet_data_put_list(Eet_Dictionary *ed,
4336 Eet_Data_Descriptor *edd,
4337 Eet_Data_Element *ede,
4338 Eet_Data_Stream *ds,
4345 EET_ASSERT(!(((ede->type > EET_T_UNKNOW) && (ede->type < EET_T_STRING))
4346 || ((ede->type > EET_T_NULL) && (ede->type < EET_T_LAST))),
4349 l = *((void **)(((char *)data_in)));
4350 for (; l; l = edd->func.list_next(l))
4352 if (IS_POINTER_TYPE(ede->type))
4354 const void *str = edd->func.list_data(l);
4355 eet_data_put_unknown(ed, NULL, ede, ds, &str);
4359 data = _eet_data_descriptor_encode(ed,
4361 edd->func.list_data(l),
4373 } /* eet_data_put_list */
4376 eet_data_put_hash(Eet_Dictionary *ed,
4377 Eet_Data_Descriptor *edd,
4378 Eet_Data_Element *ede,
4379 Eet_Data_Stream *ds,
4382 Eet_Data_Encode_Hash_Info fdata;
4385 l = *((void **)(((char *)data_in)));
4389 edd->func.hash_foreach(l, eet_data_descriptor_encode_hash_cb, &fdata);
4390 } /* eet_data_put_hash */
4393 eet_data_dump_cipher(Eet_File *ef,
4395 const char *cipher_key,
4396 void (*dumpfunc)(void *data, const char *str),
4399 const Eet_Dictionary *ed = NULL;
4400 const void *data = NULL;
4402 Eet_Free_Context context;
4403 int required_free = 0;
4406 ed = eet_dictionary_get(ef);
4409 data = eet_read_direct(ef, name, &size);
4414 data = eet_read_cipher(ef, name, &size, cipher_key);
4419 memset(&context, 0, sizeof (context));
4420 result = _eet_data_descriptor_decode(&context, ed, NULL, data, size);
4422 eet_node_dump(result, 0, dumpfunc, dumpdata);
4424 eet_node_del(result);
4429 return result ? 1 : 0;
4430 } /* eet_data_dump_cipher */
4433 eet_data_dump(Eet_File *ef,
4435 void (*dumpfunc)(void *data, const char *str),
4438 return eet_data_dump_cipher(ef, name, NULL, dumpfunc, dumpdata);
4439 } /* eet_data_dump */
4442 eet_data_text_dump_cipher(const void *data_in,
4443 const char *cipher_key,
4445 void (*dumpfunc)(void *data, const char *str),
4450 Eet_Free_Context context;
4451 unsigned int ret_len = 0;
4458 if (eet_decipher(data_in, size_in, cipher_key,
4459 strlen(cipher_key), &ret, &ret_len))
4469 ret = (void *)data_in;
4473 memset(&context, 0, sizeof (context));
4474 result = _eet_data_descriptor_decode(&context, NULL, NULL, ret, ret_len);
4476 eet_node_dump(result, 0, dumpfunc, dumpdata);
4478 eet_node_del(result);
4482 return result ? 1 : 0;
4483 } /* eet_data_text_dump_cipher */
4486 eet_data_text_dump(const void *data_in,
4488 void (*dumpfunc)(void *data, const char *str),
4491 return eet_data_text_dump_cipher(data_in, NULL, size_in, dumpfunc, dumpdata);
4492 } /* eet_data_text_dump */
4495 eet_data_text_undump_cipher(const char *text,
4496 const char *cipher_key,
4502 ret = _eet_data_dump_parse(NULL, size_ret, text, textlen);
4503 if (ret && cipher_key)
4505 void *ciphered = NULL;
4506 unsigned int ciphered_len;
4508 if (eet_cipher(ret, *size_ret, cipher_key,
4509 strlen(cipher_key), &ciphered, &ciphered_len))
4520 *size_ret = ciphered_len;
4525 } /* eet_data_text_undump_cipher */
4528 eet_data_text_undump(const char *text,
4532 return eet_data_text_undump_cipher(text, NULL, textlen, size_ret);
4533 } /* eet_data_text_undump */
4536 eet_data_undump_cipher(Eet_File *ef,
4538 const char *cipher_key,
4548 ed = eet_dictionary_get(ef);
4550 data_enc = _eet_data_dump_parse(ed, &size, text, textlen);
4554 val = eet_write_cipher(ef, name, data_enc, size, compress, cipher_key);
4557 } /* eet_data_undump_cipher */
4560 eet_data_undump(Eet_File *ef,
4566 return eet_data_undump_cipher(ef, name, NULL, text, textlen, compress);
4567 } /* eet_data_undump */
4570 eet_data_descriptor_decode_cipher(Eet_Data_Descriptor *edd,
4571 const void *data_in,
4572 const char *cipher_key,
4575 void *deciphered = (void *)data_in;
4577 Eet_Free_Context context;
4578 unsigned int deciphered_len = size_in;
4580 if (cipher_key && data_in)
4581 if (eet_decipher(data_in, size_in, cipher_key,
4582 strlen(cipher_key), &deciphered, &deciphered_len))
4590 memset(&context, 0, sizeof (context));
4591 ret = _eet_data_descriptor_decode(&context,
4597 if (data_in != deciphered)
4601 } /* eet_data_descriptor_decode_cipher */
4604 eet_data_descriptor_decode(Eet_Data_Descriptor *edd,
4605 const void *data_in,
4608 return eet_data_descriptor_decode_cipher(edd, data_in, NULL, size_in);
4609 } /* eet_data_descriptor_decode */
4612 eet_data_node_decode_cipher(const void *data_in,
4613 const char *cipher_key,
4616 void *deciphered = (void *)data_in;
4618 Eet_Free_Context context;
4619 unsigned int deciphered_len = size_in;
4621 if (cipher_key && data_in)
4622 if (eet_decipher(data_in, size_in, cipher_key,
4623 strlen(cipher_key), &deciphered, &deciphered_len))
4631 memset(&context, 0, sizeof (context));
4632 ret = _eet_data_descriptor_decode(&context,
4638 if (data_in != deciphered)
4642 } /* eet_data_node_decode_cipher */
4645 _eet_data_descriptor_encode(Eet_Dictionary *ed,
4646 Eet_Data_Descriptor *edd,
4647 const void *data_in,
4650 Eet_Data_Stream *ds;
4651 Eet_Data_Chunk *chnk;
4656 if (_eet_data_words_bigendian == -1)
4658 unsigned long int v;
4660 v = htonl(0x12345678);
4661 if (v == 0x12345678)
4662 _eet_data_words_bigendian = 1;
4664 _eet_data_words_bigendian = 0;
4667 ds = eet_data_stream_new();
4668 for (i = 0; i < edd->elements.num; i++)
4670 Eet_Data_Element *ede;
4672 ede = &(edd->elements.set[i]);
4673 eet_group_codec[ede->group_type - 100].put(
4681 chnk = eet_data_chunk_new(ds->data,
4688 eet_data_stream_free(ds);
4690 ds = eet_data_stream_new();
4691 eet_data_chunk_put(ed, chnk, ds);
4697 eet_data_stream_free(ds);
4701 eet_data_chunk_free(chnk);
4704 } /* _eet_data_descriptor_encode */
4707 eet_data_node_write_cipher(Eet_File *ef,
4709 const char *cipher_key,
4718 ed = eet_dictionary_get(ef);
4720 data_enc = _eet_data_dump_encode(EET_G_UNKNOWN, ed, node, &size);
4724 val = eet_write_cipher(ef, name, data_enc, size, compress, cipher_key);
4727 } /* eet_data_node_write_cipher */
4730 eet_data_node_encode_cipher(Eet_Node *node,
4731 const char *cipher_key,
4735 void *ciphered = NULL;
4736 unsigned int ciphered_len = 0;
4739 ret = _eet_data_dump_encode(EET_G_UNKNOWN, NULL, node, &size);
4740 if (cipher_key && ret)
4742 if (eet_cipher(ret, size, cipher_key,
4743 strlen(cipher_key), &ciphered, &ciphered_len))
4756 size = (int)ciphered_len;
4764 } /* eet_data_node_encode_cipher */
4767 eet_data_descriptor_encode_cipher(Eet_Data_Descriptor *edd,
4768 const void *data_in,
4769 const char *cipher_key,
4773 void *ciphered = NULL;
4774 unsigned int ciphered_len = 0;
4777 ret = _eet_data_descriptor_encode(NULL, edd, data_in, &size);
4778 if (cipher_key && ret)
4780 if (eet_cipher(ret, size, cipher_key,
4781 strlen(cipher_key), &ciphered, &ciphered_len))
4794 size = ciphered_len;
4802 } /* eet_data_descriptor_encode_cipher */
4805 eet_data_descriptor_encode(Eet_Data_Descriptor *edd,
4806 const void *data_in,
4809 return eet_data_descriptor_encode_cipher(edd, data_in, NULL, size_ret);
4810 } /* eet_data_descriptor_encode */