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);
145 Eet_Data_Element *set;
149 Eet_Data_Descriptor_Hash *buckets;
153 Eina_Bool unified_type : 1;
158 struct _Eet_Data_Element
161 const char *counter_name;
162 const char *directory_name_ptr;
163 Eet_Data_Descriptor *subtype;
164 int offset; /* offset in bytes from the base element */
165 int count; /* number of elements for a fixed array */
166 int counter_offset; /* for a variable array we need the offset of the count variable */
167 unsigned char type; /* EET_T_XXX */
168 unsigned char group_type; /* EET_G_XXX */
171 struct _Eet_Data_Encode_Hash_Info
174 Eet_Data_Element *ede;
186 struct _Eet_Free_Context
189 Eet_Free freelist_list;
190 Eet_Free freelist_hash;
191 Eet_Free freelist_str;
192 Eet_Free freelist_direct_str;
195 struct _Eet_Variant_Unknow
205 static int eet_data_get_char(const Eet_Dictionary *ed,
209 static void * eet_data_put_char(Eet_Dictionary *ed,
212 static int eet_data_get_short(const Eet_Dictionary *ed,
216 static void * eet_data_put_short(Eet_Dictionary *ed,
219 static inline int eet_data_get_int(const Eet_Dictionary *ed,
223 static void * eet_data_put_int(Eet_Dictionary *ed,
226 static int eet_data_get_long_long(const Eet_Dictionary *ed,
230 static void * eet_data_put_long_long(Eet_Dictionary *ed,
233 static int eet_data_get_float(const Eet_Dictionary *ed,
237 static void * eet_data_put_float(Eet_Dictionary *ed,
240 static int eet_data_get_double(const Eet_Dictionary *ed,
244 static void * eet_data_put_double(Eet_Dictionary *ed,
247 static int eet_data_get_f32p32(const Eet_Dictionary *ed,
251 static void * eet_data_put_f32p32(Eet_Dictionary *ed,
254 static int eet_data_get_f16p16(const Eet_Dictionary *ed,
258 static void * eet_data_put_f16p16(Eet_Dictionary *ed,
261 static int eet_data_get_f8p24(const Eet_Dictionary *ed,
265 static void * eet_data_put_f8p24(Eet_Dictionary *ed,
268 static inline int eet_data_get_string(const Eet_Dictionary *ed,
272 static void * eet_data_put_string(Eet_Dictionary *ed,
275 static int eet_data_get_istring(const Eet_Dictionary *ed,
279 static void * eet_data_put_istring(Eet_Dictionary *ed,
282 static int eet_data_get_null(const Eet_Dictionary *ed,
286 static void * eet_data_put_null(Eet_Dictionary *ed,
290 static int eet_data_get_type(const Eet_Dictionary *ed,
295 static void * eet_data_put_type(Eet_Dictionary *ed,
300 static Eet_Node * eet_data_node_simple_type(int type,
304 static int eet_data_get_unknown(Eet_Free_Context *context,
305 const Eet_Dictionary *ed,
306 Eet_Data_Descriptor *edd,
307 Eet_Data_Element *ede,
308 Eet_Data_Chunk *echnk,
314 static void eet_data_put_unknown(Eet_Dictionary *ed,
315 Eet_Data_Descriptor *edd,
316 Eet_Data_Element *ede,
319 static void eet_data_put_array(Eet_Dictionary *ed,
320 Eet_Data_Descriptor *edd,
321 Eet_Data_Element *ede,
324 static int eet_data_get_array(Eet_Free_Context *context,
325 const Eet_Dictionary *ed,
326 Eet_Data_Descriptor *edd,
327 Eet_Data_Element *ede,
328 Eet_Data_Chunk *echnk,
334 static int eet_data_get_list(Eet_Free_Context *context,
335 const Eet_Dictionary *ed,
336 Eet_Data_Descriptor *edd,
337 Eet_Data_Element *ede,
338 Eet_Data_Chunk *echnk,
344 static void eet_data_put_list(Eet_Dictionary *ed,
345 Eet_Data_Descriptor *edd,
346 Eet_Data_Element *ede,
349 static void eet_data_put_hash(Eet_Dictionary *ed,
350 Eet_Data_Descriptor *edd,
351 Eet_Data_Element *ede,
354 static int eet_data_get_hash(Eet_Free_Context *context,
355 const Eet_Dictionary *ed,
356 Eet_Data_Descriptor *edd,
357 Eet_Data_Element *ede,
358 Eet_Data_Chunk *echnk,
364 static void eet_data_put_union(Eet_Dictionary *ed,
365 Eet_Data_Descriptor *edd,
366 Eet_Data_Element *ede,
369 static int eet_data_get_union(Eet_Free_Context *context,
370 const Eet_Dictionary *ed,
371 Eet_Data_Descriptor *edd,
372 Eet_Data_Element *ede,
373 Eet_Data_Chunk *echnk,
379 static void eet_data_put_variant(Eet_Dictionary *ed,
380 Eet_Data_Descriptor *edd,
381 Eet_Data_Element *ede,
384 static int eet_data_get_variant(Eet_Free_Context *context,
385 const Eet_Dictionary *ed,
386 Eet_Data_Descriptor *edd,
387 Eet_Data_Element *ede,
388 Eet_Data_Chunk *echnk,
395 static void eet_data_chunk_get(const Eet_Dictionary *ed,
396 Eet_Data_Chunk *chnk,
399 static Eet_Data_Chunk * eet_data_chunk_new(void *data,
404 static void eet_data_chunk_free(Eet_Data_Chunk *chnk);
406 static Eet_Data_Stream * eet_data_stream_new(void);
407 static void eet_data_stream_write(Eet_Data_Stream *ds,
410 static void eet_data_stream_free(Eet_Data_Stream *ds);
412 static void eet_data_chunk_put(Eet_Dictionary *ed,
413 Eet_Data_Chunk *chnk,
414 Eet_Data_Stream *ds);
416 static int eet_data_descriptor_encode_hash_cb(void *hash,
420 static void * _eet_data_descriptor_encode(Eet_Dictionary *ed,
421 Eet_Data_Descriptor *edd,
424 static void * _eet_data_descriptor_decode(Eet_Free_Context *context,
425 const Eet_Dictionary *ed,
426 Eet_Data_Descriptor *edd,
432 static const Eet_Data_Basic_Type_Codec eet_basic_codec[] =
434 {sizeof(char), "char", eet_data_get_char, eet_data_put_char },
435 {sizeof(short), "short", eet_data_get_short, eet_data_put_short },
436 {sizeof(int), "int", eet_data_get_int, eet_data_put_int },
437 {sizeof(long long), "long_long", eet_data_get_long_long, eet_data_put_long_long},
438 {sizeof(float), "float", eet_data_get_float, eet_data_put_float },
439 {sizeof(double), "double", eet_data_get_double, eet_data_put_double },
440 {sizeof(char), "uchar", eet_data_get_char, eet_data_put_char },
441 {sizeof(short), "ushort", eet_data_get_short, eet_data_put_short },
442 {sizeof(int), "uint", eet_data_get_int, eet_data_put_int },
443 {sizeof(long long), "ulong_long", eet_data_get_long_long, eet_data_put_long_long},
444 {sizeof(char *), "string", eet_data_get_string, eet_data_put_string },
445 {sizeof(char *), "inlined", eet_data_get_istring, eet_data_put_istring },
446 {sizeof(void *), "NULL", eet_data_get_null, eet_data_put_null },
447 {sizeof(Eina_F32p32),"f32p32", eet_data_get_f32p32, eet_data_put_f32p32 },
448 {sizeof(Eina_F16p16),"f16p16", eet_data_get_f16p16, eet_data_put_f16p16 },
449 {sizeof(Eina_F8p24),"f8p24", eet_data_get_f8p24, eet_data_put_f8p24 }
452 static const Eet_Data_Group_Type_Codec eet_group_codec[] =
454 { eet_data_get_unknown, eet_data_put_unknown },
455 { eet_data_get_array, eet_data_put_array },
456 { eet_data_get_array, eet_data_put_array },
457 { eet_data_get_list, eet_data_put_list },
458 { eet_data_get_hash, eet_data_put_hash },
459 { eet_data_get_union, eet_data_put_union },
460 { eet_data_get_variant, eet_data_put_variant }
463 static int _eet_data_words_bigendian = -1;
467 #define SWAP64(x) (x) =\
468 ((((unsigned long long)(x) & 0x00000000000000ffULL) << 56) |\
469 (((unsigned long long)(x) & 0x000000000000ff00ULL) << 40) |\
470 (((unsigned long long)(x) & 0x0000000000ff0000ULL) << 24) |\
471 (((unsigned long long)(x) & 0x00000000ff000000ULL) << 8) |\
472 (((unsigned long long)(x) & 0x000000ff00000000ULL) >> 8) |\
473 (((unsigned long long)(x) & 0x0000ff0000000000ULL) >> 24) |\
474 (((unsigned long long)(x) & 0x00ff000000000000ULL) >> 40) |\
475 (((unsigned long long)(x) & 0xff00000000000000ULL) >> 56))
476 #define SWAP32(x) (x) =\
477 ((((int)(x) & 0x000000ff) << 24) |\
478 (((int)(x) & 0x0000ff00) << 8) |\
479 (((int)(x) & 0x00ff0000) >> 8) |\
480 (((int)(x) & 0xff000000) >> 24))
481 #define SWAP16(x) (x) =\
482 ((((short)(x) & 0x00ff) << 8) |\
483 (((short)(x) & 0xff00) >> 8))
487 #endif /* ifdef CONV8 */
490 #endif /* ifdef CONV16 */
493 #endif /* ifdef CONV32 */
496 #endif /* ifdef CONV64 */
499 #define CONV16(x) {if (_eet_data_words_bigendian) {SWAP16(x); }}
500 #define CONV32(x) {if (_eet_data_words_bigendian) {SWAP32(x); }}
501 #define CONV64(x) {if (_eet_data_words_bigendian) {SWAP64(x); }}
503 #define IS_SIMPLE_TYPE(Type) (Type > EET_T_UNKNOW && Type < EET_T_LAST)
504 #define IS_POINTER_TYPE(Type) (Type >= EET_T_STRING && Type <= EET_T_NULL)
506 #define POINTER_TYPE_DECODE(Context,\
518 ___r = eet_data_get_unknown(Context,\
522 Type, EET_G_UNKNOWN,\
524 if (!___r) { goto Label; }\
527 #define STRUCT_TYPE_DECODE(Data_Ret, Context, Ed, Ede, Data, Size, Label)\
529 Data_Ret = _eet_data_descriptor_decode(Context,\
534 if (!Data_Ret) { goto Label; }\
537 #define EET_I_STRING 1 << 4
538 #define EET_I_INLINED_STRING 2 << 4
539 #define EET_I_NULL 3 << 4
541 #define EET_MAGIC_VARIANT 0xF1234BC
546 eet_data_get_char(const Eet_Dictionary *ed __UNUSED__,
553 if (((char *)src + sizeof(char)) > (char *)src_end)
561 } /* eet_data_get_char */
564 eet_data_put_char(Eet_Dictionary *ed __UNUSED__,
570 d = (char *)malloc(sizeof(char));
577 *size_ret = sizeof(char);
579 } /* eet_data_put_char */
583 eet_data_get_short(const Eet_Dictionary *ed __UNUSED__,
590 if (((char *)src + sizeof(short)) > (char *)src_end)
593 memcpy(dst, src, sizeof(short));
596 return sizeof(short);
597 } /* eet_data_get_short */
600 eet_data_put_short(Eet_Dictionary *ed __UNUSED__,
606 d = (short *)malloc(sizeof(short));
613 *size_ret = sizeof(short);
615 } /* eet_data_put_short */
619 eet_data_get_int(const Eet_Dictionary *ed __UNUSED__,
626 if (((char *)src + sizeof(int)) > (char *)src_end)
629 memcpy(dst, src, sizeof(int));
633 } /* eet_data_get_int */
636 eet_data_put_int(Eet_Dictionary *ed __UNUSED__,
642 d = (int *)malloc(sizeof(int));
649 *size_ret = sizeof(int);
651 } /* eet_data_put_int */
655 eet_data_get_long_long(const Eet_Dictionary *ed __UNUSED__,
660 unsigned long long *d;
662 if (((char *)src + sizeof(unsigned long long)) > (char *)src_end)
665 memcpy(dst, src, sizeof(unsigned long long));
666 d = (unsigned long long *)dst;
668 return sizeof(unsigned long long);
669 } /* eet_data_get_long_long */
672 eet_data_put_long_long(Eet_Dictionary *ed __UNUSED__,
676 unsigned long long *s, *d;
678 d = (unsigned long long *)malloc(sizeof(unsigned long long));
682 s = (unsigned long long *)src;
685 *size_ret = sizeof(unsigned long long);
687 } /* eet_data_put_long_long */
691 eet_data_get_string_hash(const Eet_Dictionary *ed,
699 if (eet_data_get_int(ed, src, src_end, &idx) < 0)
702 return eet_dictionary_string_get_hash(ed, idx);
706 } /* eet_data_get_string_hash */
709 eet_data_get_string(const Eet_Dictionary *ed,
723 if (eet_data_get_int(ed, src, src_end, &idx) < 0)
726 str = eet_dictionary_string_get_char(ed, idx);
731 return eet_dictionary_string_get_size(ed, idx);
742 return strlen(s) + 1;
743 } /* eet_data_get_string */
746 eet_data_put_string(Eet_Dictionary *ed,
758 str = *((const char **)src);
762 idx = eet_dictionary_string_add(ed, str);
766 return eet_data_put_int(ed, &idx, size_ret);
769 s = (char *)(*((char **)src));
778 memcpy(d, s, len + 1);
781 } /* eet_data_put_string */
783 /* ALWAYS INLINED STRING TYPE */
785 eet_data_get_istring(const Eet_Dictionary *ed __UNUSED__,
790 return eet_data_get_string(NULL, src, src_end, dst);
791 } /* eet_data_get_istring */
794 eet_data_put_istring(Eet_Dictionary *ed __UNUSED__,
798 return eet_data_put_string(NULL, src, size_ret);
799 } /* eet_data_put_istring */
801 /* ALWAYS NULL TYPE */
803 eet_data_get_null(const Eet_Dictionary *ed __UNUSED__,
804 const void *src __UNUSED__,
805 const void *src_end __UNUSED__,
814 } /* eet_data_get_null */
817 eet_data_put_null(Eet_Dictionary *ed __UNUSED__,
818 const void *src __UNUSED__,
823 } /* eet_data_put_null */
826 * Fast lookups of simple doubles/floats.
828 * These aren't properly a cache because they don't store pre-calculated
829 * values, but have a so simple math that is almost as fast.
832 _eet_data_float_cache_get(const char *s,
836 /* fast handle of simple case 0xMp+E*/
837 if ((len == 6) && (s[0] == '0') && (s[1] == 'x') && (s[3] == 'p'))
839 int mantisse = (s[2] >= 'a') ? (s[2] - 'a' + 10) : (s[2] - '0');
840 int exponent = (s[5] - '0');
843 *d = (float)(mantisse << exponent);
845 *d = (float)mantisse / (float)(1 << exponent);
851 } /* _eet_data_float_cache_get */
854 _eet_data_double_cache_get(const char *s,
858 /* fast handle of simple case 0xMp+E*/
859 if ((len == 6) && (s[0] == '0') && (s[1] == 'x') && (s[3] == 'p'))
861 int mantisse = (s[2] >= 'a') ? (s[2] - 'a' + 10) : (s[2] - '0');
862 int exponent = (s[5] - '0');
865 *d = (double)(mantisse << exponent);
867 *d = (double)mantisse / (double)(1 << exponent);
873 } /* _eet_data_double_cache_get */
877 eet_data_get_float(const Eet_Dictionary *ed,
893 s = (const char *)src;
896 while ((p < (const char *)src_end) && (*p != 0)) {len++; p++; }
898 if (_eet_data_float_cache_get(s, len, d) != 0)
901 if (eina_convert_atod(s, len, &mantisse, &exponent) == EINA_FALSE)
904 *d = (float)ldexp((double)mantisse, exponent);
909 if (eet_data_get_int(ed, src, src_end, &idx) < 0)
912 if (!eet_dictionary_string_get_float(ed, idx, d))
916 } /* eet_data_get_float */
919 eet_data_put_float(Eet_Dictionary *ed,
926 eina_convert_dtoa((double)(*(float *)src), buf);
938 memcpy(d, buf, len + 1);
943 idx = eet_dictionary_string_add(ed, buf);
947 return eet_data_put_int(ed, &idx, size_ret);
948 } /* eet_data_put_float */
952 eet_data_get_double(const Eet_Dictionary *ed,
965 long long mantisse = 0;
969 s = (const char *)src;
972 while ((p < (const char *)src_end) && (*p != 0)) {len++; p++; }
974 if (_eet_data_double_cache_get(s, len, d) != 0)
977 if (eina_convert_atod(s, len, &mantisse, &exponent) == EINA_FALSE)
980 *d = ldexp((double)mantisse, exponent);
985 if (eet_data_get_int(ed, src, src_end, &idx) < 0)
988 if (!eet_dictionary_string_get_double(ed, idx, d))
992 } /* eet_data_get_double */
995 eet_data_put_double(Eet_Dictionary *ed,
1002 eina_convert_dtoa((double)(*(double *)src), buf);
1010 d = malloc(len + 1);
1014 memcpy(d, buf, len + 1);
1015 *size_ret = len + 1;
1020 idx = eet_dictionary_string_add(ed, buf);
1024 return eet_data_put_int(ed, &idx, size_ret);
1025 } /* eet_data_put_double */
1028 eet_data_get_f32p32(const Eet_Dictionary *ed,
1030 const void *src_end,
1036 fp = (Eina_F32p32 *)dst;
1043 s = (const char *)src;
1046 while ((p < (const char *)src_end) && (*p != 0)) { len++; p++; }
1048 if (!(eina_convert_atofp(s, len, fp)))
1054 if (eet_data_get_int(ed, src, src_end, &idx) < 0)
1057 if (!eet_dictionary_string_get_fp(ed, idx, fp))
1061 } /* eet_data_get_f32p32 */
1064 eet_data_put_f32p32(Eet_Dictionary *ed,
1071 eina_convert_fptoa((Eina_F32p32)(*(Eina_F32p32 *)src), buf);
1079 d = malloc(len + 1);
1083 memcpy(d, buf, len + 1);
1084 *size_ret = len + 1;
1089 idx = eet_dictionary_string_add(ed, buf);
1093 return eet_data_put_int(ed, &idx, size_ret);
1094 } /* eet_data_put_f32p32 */
1097 eet_data_get_f16p16(const Eet_Dictionary *ed,
1099 const void *src_end,
1105 fp = (Eina_F16p16 *)dst;
1107 if (eet_data_get_f32p32(ed, src, src_end, &tmp) < 0)
1110 *fp = eina_f32p32_to_f16p16(tmp);
1112 } /* eet_data_get_f16p16 */
1115 eet_data_put_f16p16(Eet_Dictionary *ed,
1121 tmp = eina_f16p16_to_f32p32((Eina_F16p16)(*(Eina_F16p16 *)src));
1122 return eet_data_put_f32p32(ed, &tmp, size_ret);
1123 } /* eet_data_put_f16p16 */
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);
1141 } /* eet_data_get_f8p24 */
1144 eet_data_put_f8p24(Eet_Dictionary *ed,
1150 tmp = eina_f8p24_to_f32p32((Eina_F8p24)(*(Eina_F8p24 *)src));
1151 return eet_data_put_f32p32(ed, &tmp, size_ret);
1152 } /* eet_data_put_f8p24 */
1155 eet_data_get_type(const Eet_Dictionary *ed,
1158 const void *src_end,
1163 ret = eet_basic_codec[type - 1].get(ed, src, src_end, dest);
1165 } /* eet_data_get_type */
1167 static inline void *
1168 eet_data_put_type(Eet_Dictionary *ed,
1175 ret = eet_basic_codec[type - 1].put(ed, src, size_ret);
1177 } /* eet_data_put_type */
1179 static inline Eina_Bool
1180 eet_data_type_match(int type1,
1186 /* Note: All floating point type are equivalent and could be read
1187 without problem by any other floating point getter. */
1214 } /* eet_data_type_match */
1218 * char[4] = "CHnK"; // untyped data ... or
1219 * char[4] = "CHKx"; // typed data - x == type
1221 * int = chunk size (including magic string);
1222 * char[] = chunk magic/name string (0 byte terminated);
1223 * ... sub-chunks (a chunk can contain chuncks recusrively) ...
1225 * ... payload data ...
1230 eet_data_chunk_get(const Eet_Dictionary *ed,
1231 Eet_Data_Chunk *chnk,
1250 if ((s[0] != 'C') || (s[1] != 'H') || (s[2] != 'K'))
1253 chnk->type = (unsigned char)(s[3]);
1254 if (chnk->type >= EET_I_LIMIT)
1257 ((chnk->type - EET_I_LIMIT) & 0xF) + EET_G_UNKNOWN;
1258 switch ((chnk->type - EET_I_LIMIT) & 0xF0)
1260 #define EET_UNMATCH_TYPE(Type)\
1261 case EET_I_ ## Type: chnk->type = EET_T_ ## Type; break;
1263 EET_UNMATCH_TYPE(STRING);
1264 EET_UNMATCH_TYPE(INLINED_STRING);
1265 EET_UNMATCH_TYPE(NULL);
1271 else if (chnk->type > EET_T_LAST)
1273 chnk->group_type = chnk->type;
1274 chnk->type = EET_T_UNKNOW;
1277 chnk->group_type = EET_G_UNKNOWN;
1278 if ((chnk->type >= EET_T_LAST) ||
1279 (chnk->group_type >=
1283 chnk->group_type = 0;
1286 else if ((s[0] != 'C') || (s[1] != 'H') || (s[2] != 'n') || (s[3] != 'K'))
1289 ret1 = eet_data_get_type(ed, EET_T_INT, (s + 4), (s + size), &(chnk->size));
1294 if ((chnk->size < 0) || ((chnk->size + 8) > size))
1297 ret2 = eet_data_get_type(ed, EET_T_STRING, (s + 8), (s + size), &(chnk->name));
1305 chnk->hash = eet_data_get_string_hash(ed, (s + 8), (s + size));
1309 chnk->data = (char *)src + 4 + ret1 + sizeof(int);
1310 chnk->size -= sizeof(int);
1314 chnk->data = (char *)src + 4 + ret1 + chnk->len;
1315 chnk->size -= chnk->len;
1319 } /* eet_data_chunk_get */
1321 static inline Eet_Data_Chunk *
1322 eet_data_chunk_new(void *data,
1328 Eet_Data_Chunk *chnk;
1333 chnk = calloc(1, sizeof(Eet_Data_Chunk));
1337 /* Note: Another security, so older eet library could read file
1338 saved with fixed point value. */
1339 if (type == EET_T_F32P32
1340 || type == EET_T_F16P16
1341 || type == EET_T_F8P24)
1342 type = EET_T_DOUBLE;
1344 chnk->name = strdup(name);
1345 chnk->len = strlen(name) + 1;
1349 chnk->group_type = group_type;
1351 } /* eet_data_chunk_new */
1354 eet_data_chunk_free(Eet_Data_Chunk *chnk)
1360 } /* eet_data_chunk_free */
1362 static inline Eet_Data_Stream *
1363 eet_data_stream_new(void)
1365 Eet_Data_Stream *ds;
1367 ds = calloc(1, sizeof(Eet_Data_Stream));
1372 } /* eet_data_stream_new */
1375 eet_data_stream_free(Eet_Data_Stream *ds)
1381 } /* eet_data_stream_free */
1384 eet_data_stream_flush(Eet_Data_Stream *ds)
1387 } /* eet_data_stream_flush */
1390 eet_data_stream_write(Eet_Data_Stream *ds,
1396 if ((ds->pos + size) > ds->size)
1398 ds->data = realloc(ds->data, ds->size + size + 512);
1406 ds->size = ds->size + size + 512;
1410 memcpy(p + ds->pos, data, size);
1412 } /* eet_data_stream_write */
1415 eet_data_chunk_put(Eet_Dictionary *ed,
1416 Eet_Data_Chunk *chnk,
1417 Eet_Data_Stream *ds)
1424 unsigned char buf[4] = "CHK";
1426 /* disable this check - it will allow empty chunks to be written. this is
1427 * right for corner-cases when y have a struct with empty fields (empty
1428 * strings or empty list ptrs etc.) */
1429 /* if (!chnk->data && chnk->type != EET_T_NULL) return; */
1432 /* eet_data_stream_write(ds, "CHnK", 4);*/
1433 if (chnk->type != EET_T_UNKNOW)
1435 if (chnk->group_type != EET_G_UNKNOWN)
1437 int type = EET_I_LIMIT + chnk->group_type - EET_G_UNKNOWN;
1441 /* Only make sense with pointer type. */
1442 #define EET_MATCH_TYPE(Type)\
1443 case EET_T_ ## Type: type += EET_I_ ## Type; break;
1445 EET_MATCH_TYPE(STRING);
1446 EET_MATCH_TYPE(INLINED_STRING);
1447 EET_MATCH_TYPE(NULL);
1456 buf[3] = chnk->type;
1459 buf[3] = chnk->group_type;
1461 string = eet_data_put_string(ed, &chnk->name, &string_ret);
1465 /* size of chunk payload data + name */
1466 s = chnk->size + string_ret;
1467 size = eet_data_put_int(ed, &s, &size_ret);
1469 /* FIXME: If something goes wrong the resulting file will be corrupted. */
1473 eet_data_stream_write(ds, buf, 4);
1475 /* write chunk length */
1476 eet_data_stream_write(ds, size, size_ret);
1478 /* write chunk name */
1479 eet_data_stream_write(ds, string, string_ret);
1483 eet_data_stream_write(ds, chnk->data, chnk->size);
1488 } /* eet_data_chunk_put */
1493 _eet_descriptor_hash_new(Eet_Data_Descriptor *edd)
1497 edd->elements.hash.size = 1 << 6;
1498 edd->elements.hash.buckets = calloc(
1500 sizeof(Eet_Data_Descriptor_Hash) *
1501 edd->elements.hash.size);
1502 for (i = 0; i < edd->elements.num; i++)
1504 Eet_Data_Element *ede;
1507 ede = &(edd->elements.set[i]);
1508 hash = _eet_hash_gen((char *)ede->name, 6);
1509 if (!edd->elements.hash.buckets[hash].element)
1510 edd->elements.hash.buckets[hash].element = ede;
1513 Eet_Data_Descriptor_Hash *bucket;
1515 bucket = calloc(1, sizeof(Eet_Data_Descriptor_Hash));
1516 bucket->element = ede;
1517 bucket->next = edd->elements.hash.buckets[hash].next;
1518 edd->elements.hash.buckets[hash].next = bucket;
1521 } /* _eet_descriptor_hash_new */
1524 _eet_descriptor_hash_free(Eet_Data_Descriptor *edd)
1528 for (i = 0; i < edd->elements.hash.size; i++)
1530 Eet_Data_Descriptor_Hash *bucket, *pbucket;
1532 bucket = edd->elements.hash.buckets[i].next;
1536 bucket = bucket->next;
1540 if (edd->elements.hash.buckets)
1541 free(edd->elements.hash.buckets);
1542 } /* _eet_descriptor_hash_free */
1544 static Eet_Data_Element *
1545 _eet_descriptor_hash_find(Eet_Data_Descriptor *edd,
1549 Eet_Data_Descriptor_Hash *bucket;
1552 hash = _eet_hash_gen(name, 6);
1556 if (!edd->elements.hash.buckets[hash].element)
1558 When we use the dictionnary as a source for chunk name, we will always
1559 have the same pointer in name. It's a good idea to just compare pointer
1560 instead of running strcmp on both string.
1563 if (edd->elements.hash.buckets[hash].element->directory_name_ptr == name)
1564 return edd->elements.hash.buckets[hash].element;
1566 if (!strcmp(edd->elements.hash.buckets[hash].element->name, name))
1568 edd->elements.hash.buckets[hash].element->directory_name_ptr = name;
1569 return edd->elements.hash.buckets[hash].element;
1572 bucket = edd->elements.hash.buckets[hash].next;
1575 if (bucket->element->directory_name_ptr == name)
1576 return bucket->element;
1578 if (!strcmp(bucket->element->name, name))
1580 bucket->element->directory_name_ptr = name;
1581 return bucket->element;
1584 bucket = bucket->next;
1587 } /* _eet_descriptor_hash_find */
1590 _eet_mem_alloc(size_t size)
1592 return calloc(1, size);
1593 } /* _eet_mem_alloc */
1596 _eet_mem_free(void *mem)
1599 } /* _eet_mem_free */
1602 _eet_str_alloc(const char *str)
1605 } /* _eet_str_alloc */
1608 _eet_str_free(const char *str)
1611 } /* _eet_str_free */
1614 _eet_eina_hash_add_alloc(Eina_Hash *hash,
1619 hash = eina_hash_string_small_new(NULL);
1624 eina_hash_add(hash, key, data);
1626 } /* _eet_eina_hash_add_alloc */
1629 _eet_eina_hash_direct_add_alloc(Eina_Hash *hash,
1634 hash = eina_hash_string_small_new(NULL);
1639 eina_hash_direct_add(hash, key, data);
1641 } /* _eet_eina_hash_direct_add_alloc */
1644 _eet_str_direct_alloc(const char *str)
1647 } /* _eet_str_direct_alloc */
1650 _eet_str_direct_free(const char *str __UNUSED__)
1652 } /* _eet_str_direct_free */
1655 _eet_eina_hash_foreach(void *hash,
1656 Eina_Hash_Foreach cb,
1660 eina_hash_foreach(hash, cb, fdata);
1661 } /* _eet_eina_hash_foreach */
1664 _eet_eina_hash_free(void *hash)
1667 eina_hash_free(hash);
1668 } /* _eet_eina_hash_free */
1672 eet_eina_stream_data_descriptor_class_set(Eet_Data_Descriptor_Class *eddc,
1683 eddc->func.mem_alloc = _eet_mem_alloc;
1684 eddc->func.mem_free = _eet_mem_free;
1685 eddc->func.str_alloc = (char *(*)(const char *))eina_stringshare_add;
1686 eddc->func.str_free = eina_stringshare_del;
1687 eddc->func.list_next = (void *(*)(void *))eina_list_next;
1688 eddc->func.list_append = (void *(*)(void *, void *))eina_list_append;
1689 eddc->func.list_data = (void *(*)(void *))eina_list_data_get;
1690 eddc->func.list_free = (void *(*)(void *))eina_list_free;
1691 eddc->func.hash_foreach = (void (*)(void *, int (*)(void *, const char *, void *, void *), void *))_eet_eina_hash_foreach;
1692 eddc->func.hash_add = (void * (*)(void *, const char *, void *))_eet_eina_hash_add_alloc;
1693 eddc->func.hash_free = (void (*)(void *))_eet_eina_hash_free;
1696 } /* eet_eina_stream_data_descriptor_class_set */
1699 eet_eina_file_data_descriptor_class_set(Eet_Data_Descriptor_Class *eddc,
1703 if (!eet_eina_stream_data_descriptor_class_set(eddc, name, size))
1708 eddc->func.hash_add = (void * (*)(void *, const char *, void *))_eet_eina_hash_direct_add_alloc;
1709 eddc->func.str_direct_alloc = _eet_str_direct_alloc;
1710 eddc->func.str_direct_free = _eet_str_direct_free;
1713 } /* eet_eina_file_data_descriptor_class_set */
1715 static Eet_Data_Descriptor *
1716 _eet_data_descriptor_new(const Eet_Data_Descriptor_Class *eddc,
1719 Eet_Data_Descriptor *edd;
1724 edd = calloc(1, sizeof (Eet_Data_Descriptor));
1728 edd->name = eddc->name;
1730 edd->size = eddc->size;
1731 edd->func.mem_alloc = _eet_mem_alloc;
1732 edd->func.mem_free = _eet_mem_free;
1733 edd->func.str_alloc = _eet_str_alloc;
1734 edd->func.str_free = _eet_str_free;
1735 if (eddc->func.mem_alloc)
1736 edd->func.mem_alloc = eddc->func.mem_alloc;
1738 if (eddc->func.mem_free)
1739 edd->func.mem_free = eddc->func.mem_free;
1741 if (eddc->func.str_alloc)
1742 edd->func.str_alloc = eddc->func.str_alloc;
1744 if (eddc->func.str_free)
1745 edd->func.str_free = eddc->func.str_free;
1747 edd->func.list_next = eddc->func.list_next;
1748 edd->func.list_append = eddc->func.list_append;
1749 edd->func.list_data = eddc->func.list_data;
1750 edd->func.list_free = eddc->func.list_free;
1751 edd->func.hash_foreach = eddc->func.hash_foreach;
1752 edd->func.hash_add = eddc->func.hash_add;
1753 edd->func.hash_free = eddc->func.hash_free;
1755 if (eddc->version > 1 && version > 1)
1757 edd->func.str_direct_alloc = eddc->func.str_direct_alloc;
1758 edd->func.str_direct_free = eddc->func.str_direct_free;
1761 if (eddc->version > 2)
1763 edd->func.type_get = eddc->func.type_get;
1764 edd->func.type_set = eddc->func.type_set;
1768 } /* _eet_data_descriptor_new */
1770 EAPI Eet_Data_Descriptor *
1771 eet_data_descriptor_new(const char *name,
1773 void *(*func_list_next)(void *l),
1774 void *(*func_list_append)(void *l, void *d),
1775 void *(*func_list_data)(void *l),
1776 void *(*func_list_free)(void *l),
1777 void (*func_hash_foreach)(void *h, int (*func)(void *h, const char *k, void *dt, void *fdt), void *fdt),
1778 void *(*func_hash_add)(void *h, const char *k, void *d),
1779 void (*func_hash_free)(void *h))
1781 Eet_Data_Descriptor_Class eddc;
1786 memset(&eddc, 0, sizeof (Eet_Data_Descriptor_Class));
1792 eddc.func.list_next = func_list_next;
1793 eddc.func.list_append = func_list_append;
1794 eddc.func.list_data = func_list_data;
1795 eddc.func.list_free = func_list_free;
1796 eddc.func.hash_foreach = func_hash_foreach;
1797 eddc.func.hash_add = func_hash_add;
1798 eddc.func.hash_free = func_hash_free;
1800 return _eet_data_descriptor_new(&eddc, 0);
1801 } /* eet_data_descriptor_new */
1803 EAPI Eet_Data_Descriptor *
1804 eet_data_descriptor2_new(const Eet_Data_Descriptor_Class *eddc)
1806 return _eet_data_descriptor_new(eddc, 1);
1807 } /* eet_data_descriptor2_new */
1809 EAPI Eet_Data_Descriptor *
1810 eet_data_descriptor3_new(const Eet_Data_Descriptor_Class *eddc)
1812 return _eet_data_descriptor_new(eddc, 2);
1813 } /* eet_data_descriptor3_new */
1815 EAPI Eet_Data_Descriptor *
1816 eet_data_descriptor_stream_new(const Eet_Data_Descriptor_Class *eddc)
1818 return _eet_data_descriptor_new(eddc, 1);
1819 } /* eet_data_descriptor_stream_new */
1821 EAPI Eet_Data_Descriptor *
1822 eet_data_descriptor_file_new(const Eet_Data_Descriptor_Class *eddc)
1824 return _eet_data_descriptor_new(eddc, 2);
1825 } /* eet_data_descriptor_file_new */
1828 eet_data_descriptor_free(Eet_Data_Descriptor *edd)
1833 _eet_descriptor_hash_free(edd);
1834 if (edd->elements.set)
1835 free(edd->elements.set);
1838 } /* eet_data_descriptor_free */
1841 eet_data_descriptor_element_add(Eet_Data_Descriptor *edd,
1847 /* int counter_offset, */
1848 const char *counter_name /* FIXME: Useless should go on a major release */,
1849 Eet_Data_Descriptor *subtype)
1851 Eet_Data_Element *ede;
1852 Eet_Data_Element *tmp;
1854 /* UNION, VARIANT type would not work with simple type, we need a way to map the type. */
1855 if ((group_type == EET_G_UNION
1856 || group_type == EET_G_VARIANT)
1858 (type != EET_T_UNKNOW
1860 || subtype->func.type_get == NULL
1861 || subtype->func.type_set == NULL))
1864 /* VARIANT type will only work if the map only contains EET_G_*, but not UNION, VARIANT and ARRAY. */
1865 if (group_type == EET_G_VARIANT)
1869 for (i = 0; i < subtype->elements.num; ++i)
1870 if (subtype->elements.set[i].type != EET_T_UNKNOW
1871 && subtype->elements.set[i].group_type > EET_G_VAR_ARRAY
1872 && subtype->elements.set[i].group_type < EET_G_UNION)
1875 subtype->unified_type = EINA_TRUE;
1879 && subtype->unified_type
1880 && (type != EET_T_UNKNOW
1881 || group_type < EET_G_UNION))
1884 /* Sanity check done, let allocate ! */
1885 edd->elements.num++;
1886 tmp = realloc(edd->elements.set, edd->elements.num * sizeof(Eet_Data_Element));
1890 edd->elements.set = tmp;
1891 ede = &(edd->elements.set[edd->elements.num - 1]);
1893 ede->directory_name_ptr = NULL;
1896 * We do a special case when we do list,hash or whatever group of simple type.
1897 * Instead of handling it in encode/decode/dump/undump, we create an
1898 * implicit structure with only the simple type.
1900 if ((group_type > EET_G_UNKNOWN)
1901 && (group_type < EET_G_LAST)
1902 && (((type > EET_T_UNKNOW) && (type < EET_T_STRING))
1903 || ((type > EET_T_NULL) && (type < EET_T_LAST)))
1904 && (subtype == NULL))
1906 subtype = calloc(1, sizeof (Eet_Data_Descriptor));
1910 subtype->name = "implicit";
1911 subtype->size = eet_basic_codec[type - 1].size;
1912 memcpy(&subtype->func, &edd->func, sizeof(subtype->func));
1914 eet_data_descriptor_element_add(subtype,
1915 eet_basic_codec[type - 1].name,
1922 type = EET_T_UNKNOW;
1926 ede->group_type = group_type;
1927 ede->offset = offset;
1929 /* FIXME: For the time being, VAR_ARRAY, UNION and VARIANT will put the counter_offset in count. */
1930 ede->counter_offset = count;
1931 /* ede->counter_offset = counter_offset; */
1932 ede->counter_name = counter_name;
1934 ede->subtype = subtype;
1935 } /* eet_data_descriptor_element_add */
1938 eet_data_read_cipher(Eet_File *ef,
1939 Eet_Data_Descriptor *edd,
1941 const char *cipher_key)
1943 const Eet_Dictionary *ed = NULL;
1944 const void *data = NULL;
1946 Eet_Free_Context context;
1947 int required_free = 0;
1950 ed = eet_dictionary_get(ef);
1953 data = eet_read_direct(ef, name, &size);
1958 data = eet_read_cipher(ef, name, &size, cipher_key);
1963 memset(&context, 0, sizeof (context));
1964 data_dec = _eet_data_descriptor_decode(&context, ed, edd, data, size);
1969 } /* eet_data_read_cipher */
1972 eet_data_node_read_cipher(Eet_File *ef,
1974 const char *cipher_key)
1976 const Eet_Dictionary *ed = NULL;
1977 const void *data = NULL;
1979 Eet_Free_Context context;
1980 int required_free = 0;
1983 ed = eet_dictionary_get(ef);
1986 data = eet_read_direct(ef, name, &size);
1991 data = eet_read_cipher(ef, name, &size, cipher_key);
1996 memset(&context, 0, sizeof (context));
1997 result = _eet_data_descriptor_decode(&context, ed, NULL, data, size);
2002 } /* eet_data_node_read_cipher */
2005 eet_data_read(Eet_File *ef,
2006 Eet_Data_Descriptor *edd,
2009 return eet_data_read_cipher(ef, edd, name, NULL);
2010 } /* eet_data_read */
2013 eet_data_write_cipher(Eet_File *ef,
2014 Eet_Data_Descriptor *edd,
2016 const char *cipher_key,
2025 ed = eet_dictionary_get(ef);
2027 data_enc = _eet_data_descriptor_encode(ed, edd, data, &size);
2031 val = eet_write_cipher(ef, name, data_enc, size, compress, cipher_key);
2034 } /* eet_data_write_cipher */
2037 eet_data_write(Eet_File *ef,
2038 Eet_Data_Descriptor *edd,
2043 return eet_data_write_cipher(ef, edd, name, NULL, data, compress);
2044 } /* eet_data_write */
2047 _eet_free_hash(void *data)
2050 __int64 ptr = (UINT_PTR)data;
2051 #else /* ifdef _WIN64 */
2052 unsigned long ptr = (unsigned long)(data);
2053 #endif /* ifdef _WIN64 */
2061 #if defined (_WIN64) || ((!defined (_WIN32)) && (LONG_BIT != 32))
2066 #endif /* if defined (_WIN64) || ((!defined (_WIN32)) && (LONG_BIT != 32)) */
2069 } /* _eet_free_hash */
2072 _eet_free_add(Eet_Free *ef,
2078 hash = _eet_free_hash(data);
2080 for (i = 0; i < ef->num[hash]; ++i)
2081 if (ef->list[hash][i] == data)
2085 if (ef->num[hash] > ef->len[hash])
2089 tmp = realloc(ef->list[hash], (ef->len[hash] + 16) * sizeof(void *));
2093 ef->len[hash] += 16;
2094 ef->list[hash] = tmp;
2097 ef->list[hash][ef->num[hash] - 1] = data;
2098 } /* _eet_free_add */
2101 _eet_free_reset(Eet_Free *ef)
2108 for (i = 0; i < 256; ++i)
2117 } /* _eet_free_reset */
2120 _eet_free_ref(Eet_Free *ef)
2123 } /* _eet_free_ref */
2126 _eet_free_unref(Eet_Free *ef)
2129 } /* _eet_free_unref */
2131 #define _eet_freelist_add(Ctx, Data) _eet_free_add(&Ctx->freelist, Data);
2132 #define _eet_freelist_reset(Ctx) _eet_free_reset(&Ctx->freelist);
2133 #define _eet_freelist_ref(Ctx) _eet_free_ref(&Ctx->freelist);
2134 #define _eet_freelist_unref(Ctx) _eet_free_unref(&Ctx->freelist);
2137 _eet_freelist_free(Eet_Free_Context *context,
2138 Eet_Data_Descriptor *edd)
2143 if (context->freelist.ref > 0)
2146 for (j = 0; j < 256; ++j)
2147 for (i = 0; i < context->freelist.num[j]; ++i)
2150 edd->func.mem_free(context->freelist.list[j][i]);
2152 free(context->freelist.list[j][i]);
2154 _eet_free_reset(&context->freelist);
2155 } /* _eet_freelist_free */
2157 #define _eet_freelist_list_add(Ctx, Data) _eet_free_add(&Ctx->freelist_list, Data);
2158 #define _eet_freelist_list_reset(Ctx) _eet_free_reset(&Ctx->freelist_list);
2159 #define _eet_freelist_list_ref(Ctx) _eet_free_ref(&Ctx->freelist_list);
2160 #define _eet_freelist_list_unref(Ctx) _eet_free_unref(&Ctx->freelist_list);
2163 _eet_freelist_list_free(Eet_Free_Context *context,
2164 Eet_Data_Descriptor *edd)
2169 if (context->freelist_list.ref > 0)
2172 for (j = 0; j < 256; ++j)
2173 for (i = 0; i < context->freelist_list.num[j]; ++i)
2176 edd->func.list_free(*((void **)(context->freelist_list.list[j][i])));
2178 _eet_free_reset(&context->freelist_list);
2179 } /* _eet_freelist_list_free */
2181 #define _eet_freelist_str_add(Ctx, Data) _eet_free_add(&Ctx->freelist_str, Data);
2182 #define _eet_freelist_str_reset(Ctx) _eet_free_reset(&Ctx->freelist_str);
2183 #define _eet_freelist_str_ref(Ctx) _eet_free_ref(&Ctx->freelist_str);
2184 #define _eet_freelist_str_unref(Ctx) _eet_free_unref(&Ctx->freelist_str);
2187 _eet_freelist_str_free(Eet_Free_Context *context, Eet_Data_Descriptor *edd)
2192 if (context->freelist_str.ref > 0)
2195 for (j = 0; j < 256; ++j)
2196 for (i = 0; i < context->freelist_str.num[j]; ++i)
2199 edd->func.str_free(context->freelist_str.list[j][i]);
2201 free(context->freelist_str.list[j][i]);
2203 _eet_free_reset(&context->freelist_str);
2204 } /* _eet_freelist_str_free */
2206 #define _eet_freelist_direct_str_add(Ctx, Data) _eet_free_add(&Ctx->freelist_direct_str, Data);
2207 #define _eet_freelist_direct_str_reset(Ctx) _eet_free_reset(&Ctx->freelist_direct_str);
2208 #define _eet_freelist_direct_str_ref(Ctx) _eet_free_ref(&Ctx->freelist_direct_str);
2209 #define _eet_freelist_direct_str_unref(Ctx) _eet_free_unref(&Ctx->freelist_direct_str);
2212 _eet_freelist_direct_str_free(Eet_Free_Context *context,
2213 Eet_Data_Descriptor *edd)
2218 if (context->freelist_direct_str.ref > 0)
2221 for (j = 0; j < 256; ++j)
2222 for (i = 0; i < context->freelist_direct_str.num[j]; ++i)
2225 edd->func.str_direct_free(context->freelist_direct_str.list[j][i]);
2227 free(context->freelist_direct_str.list[j][i]);
2229 _eet_free_reset(&context->freelist_direct_str);
2230 } /* _eet_freelist_direct_str_free */
2232 #define _eet_freelist_hash_add(Ctx, Data) _eet_free_add(&Ctx->freelist_hash, Data);
2233 #define _eet_freelist_hash_reset(Ctx) _eet_free_reset(&Ctx->freelist_hash);
2234 #define _eet_freelist_hash_ref(Ctx) _eet_free_ref(&Ctx->freelist_hash);
2235 #define _eet_freelist_hash_unref(Ctx) _eet_free_unref(&Ctx->freelist_hash);
2238 _eet_freelist_hash_free(Eet_Free_Context *context,
2239 Eet_Data_Descriptor *edd)
2244 if (context->freelist_hash.ref > 0)
2247 for (j = 0; j < 256; ++j)
2248 for (i = 0; i < context->freelist_hash.num[j]; ++i)
2251 edd->func.hash_free(context->freelist_hash.list[j][i]);
2253 free(context->freelist_hash.list[j][i]);
2255 _eet_free_reset(&context->freelist_hash);
2256 } /* _eet_freelist_hash_free */
2259 _eet_freelist_all_ref(Eet_Free_Context *freelist_context)
2261 _eet_freelist_ref(freelist_context);
2262 _eet_freelist_str_ref(freelist_context);
2263 _eet_freelist_list_ref(freelist_context);
2264 _eet_freelist_hash_ref(freelist_context);
2265 _eet_freelist_direct_str_ref(freelist_context);
2266 } /* _eet_freelist_all_ref */
2269 _eet_freelist_all_unref(Eet_Free_Context *freelist_context)
2271 _eet_freelist_unref(freelist_context);
2272 _eet_freelist_str_unref(freelist_context);
2273 _eet_freelist_list_unref(freelist_context);
2274 _eet_freelist_hash_unref(freelist_context);
2275 _eet_freelist_direct_str_unref(freelist_context);
2276 } /* _eet_freelist_all_unref */
2279 eet_data_descriptor_encode_hash_cb(void *hash __UNUSED__,
2280 const char *cipher_key,
2285 Eet_Data_Encode_Hash_Info *edehi;
2286 Eet_Data_Stream *ds;
2287 Eet_Data_Element *ede;
2288 Eet_Data_Chunk *echnk;
2298 data = eet_data_put_type(ed,
2304 echnk = eet_data_chunk_new(data,
2309 eet_data_chunk_put(ed, echnk, ds);
2310 eet_data_chunk_free(echnk);
2315 EET_ASSERT(!((ede->type > EET_T_UNKNOW) && (ede->type < EET_T_STRING)), return );
2318 if (ede->type >= EET_T_STRING)
2319 eet_data_put_unknown(ed, NULL, ede, ds, &hdata);
2323 data = _eet_data_descriptor_encode(ed,
2330 echnk = eet_data_chunk_new(data,
2335 eet_data_chunk_put(ed, echnk, ds);
2336 eet_data_chunk_free(echnk);
2343 } /* eet_data_descriptor_encode_hash_cb */
2346 _eet_data_dump_token_get(const char *src,
2353 int tlen = 0, tsize = 0;
2361 tok = realloc(tok, tsize);\
2366 for (p = src; *len > 0; p++, (*len)--)
2372 if ((p[0] == '\"') && (p > src) && (p[-1] != '\\'))
2374 else if ((p[0] == '\\') && (*len > 1) &&
2379 else if ((p[0] == '\\') && (p > src) && (p[-1] == '\\'))
2383 else if ((p[0] == '\\') && (*len > 1) && (p[1] == 'n'))
2387 else if ((p[0] == 'n') && (p > src) && (p[-1] == '\\'))
2398 if ((isspace(p[0])) || (p[0] == ';')) /* token ends here */
2409 else if (!((isspace(p[0])) || (p[0] == ';')))
2426 } /* _eet_data_dump_token_get */
2429 eet_data_encode(Eet_Dictionary *ed,
2430 Eet_Data_Stream *ds,
2437 Eet_Data_Chunk *echnk;
2442 if (group_type != EET_G_UNKNOWN)
2443 if (type >= EET_T_LAST)
2444 type = EET_T_UNKNOW;
2446 echnk = eet_data_chunk_new(data, size, name, type, group_type);
2447 eet_data_chunk_put(ed, echnk, ds);
2448 eet_data_chunk_free(echnk);
2450 } /* eet_data_encode */
2453 _eet_data_dump_encode(int parent_type,
2458 Eet_Data_Chunk *chnk = NULL;
2459 Eet_Data_Stream *ds;
2466 if (_eet_data_words_bigendian == -1)
2468 unsigned long int v;
2470 v = htonl(0x12345678);
2471 if (v == 0x12345678)
2472 _eet_data_words_bigendian = 1;
2474 _eet_data_words_bigendian = 0;
2480 ds = eet_data_stream_new();
2487 for (n = node->values; n; n = n->next)
2489 data = _eet_data_dump_encode(node->type, ed, n, &size);
2492 eet_data_stream_write(ds, data, size);
2499 case EET_G_VAR_ARRAY:
2500 for (child_type = EET_T_NULL, n = node->values; n; n = n->next)
2502 if (n->type != EET_T_NULL)
2504 child_type = n->type;
2509 data = eet_data_put_type(ed,
2521 count = node->count;
2523 for (n = node->values; n; n = n->next)
2530 case EET_T_INLINED_STRING:
2531 data = eet_data_put_type(ed,
2533 &(n->data.value.str),
2550 data = _eet_data_dump_encode(n->type, ed, n, &size);
2564 for (; count; count--)
2575 /* Array is somekind of special case, so we should embed it inside another chunk. */
2576 *size_ret = ds->pos;
2581 eet_data_stream_free(ds);
2587 for (n = node->values; n; n = n->next)
2592 case EET_T_INLINED_STRING:
2593 data = eet_data_put_type(ed,
2595 &(n->data.value.str),
2612 data = _eet_data_dump_encode(node->type, ed, n, &size);
2623 /* List is another somekind of special case, every chunk is embed inside a list chunk. */
2624 *size_ret = ds->pos;
2629 eet_data_stream_free(ds);
2637 data = eet_data_put_type(ed,
2650 /* A Hash without key will not decode correctly. */
2653 for (n = node->values; n; n = n->next)
2658 case EET_T_INLINED_STRING:
2659 data = eet_data_put_type(ed,
2661 &(n->data.value.str),
2678 data = _eet_data_dump_encode(node->type, ed, n, &size);
2689 /* Hash is somekind of special case, so we should embed it inside another chunk. */
2690 *size_ret = ds->pos;
2693 eet_data_stream_flush(ds);
2700 #define EET_DATA_NODE_ENCODE(Eet_Type, Type)\
2702 data = eet_data_put_type(ed, node->type, &(node->data.value.Type), &size);\
2705 eet_data_encode(ed,\
2713 *size_ret = ds->pos;\
2714 eet_data_stream_flush(ds);\
2719 EET_DATA_NODE_ENCODE(EET_T_CHAR, c);
2720 EET_DATA_NODE_ENCODE(EET_T_SHORT, s);
2721 EET_DATA_NODE_ENCODE(EET_T_INT, i);
2722 EET_DATA_NODE_ENCODE(EET_T_LONG_LONG, l);
2723 EET_DATA_NODE_ENCODE(EET_T_FLOAT, f);
2724 EET_DATA_NODE_ENCODE(EET_T_DOUBLE, d);
2725 EET_DATA_NODE_ENCODE(EET_T_UCHAR, uc);
2726 EET_DATA_NODE_ENCODE(EET_T_USHORT, us);
2727 EET_DATA_NODE_ENCODE(EET_T_UINT, ui);
2728 EET_DATA_NODE_ENCODE(EET_T_ULONG_LONG, ul);
2729 EET_DATA_NODE_ENCODE(EET_T_INLINED_STRING, str);
2730 EET_DATA_NODE_ENCODE(EET_T_STRING, str);
2736 if ((node->type >= EET_G_UNKNOWN) && (node->type < EET_G_LAST))
2737 chnk = eet_data_chunk_new(ds->data,
2743 chnk = eet_data_chunk_new(ds->data,
2749 eet_data_stream_flush(ds);
2751 ds = eet_data_stream_new();
2752 eet_data_chunk_put(ed, chnk, ds);
2756 eet_data_stream_flush(ds);
2760 eet_data_chunk_free(chnk);
2763 } /* _eet_data_dump_encode */
2766 _eet_data_dump_parse(Eet_Dictionary *ed,
2772 const char *p = NULL;
2777 Eet_Node *node_base = NULL;
2778 Eet_Node *node = NULL;
2779 Eet_Node *n = NULL, *nn = NULL;
2781 /* FIXME; handle parse errors */
2783 jump = left; t = _eet_data_dump_token_get(p, &left); p += jump - left;
2785 for (p = src; p < (src + size); )
2787 char *tok1, *tok2, *tok3, *tok4;
2792 if (!strcmp(tok1, "group"))
2803 if (!strcmp(tok4, "{"))
2805 /* we have 'group NAM TYP {' */
2819 for (nn = node->values; nn;
2830 n->name = eina_stringshare_add(tok2);
2831 if (!strcmp(tok3, "struct"))
2832 n->type = EET_G_UNKNOWN;
2833 else if (!strcmp(tok3, "array"))
2834 n->type = EET_G_ARRAY;
2835 else if (!strcmp(tok3, "var_array"))
2836 n->type = EET_G_VAR_ARRAY;
2837 else if (!strcmp(tok3, "list"))
2838 n->type = EET_G_LIST;
2839 else if (!strcmp(tok3, "hash"))
2840 n->type = EET_G_HASH;
2843 "ERROR: group type '%s' invalid.",
2859 else if (!strcmp(tok1, "value"))
2870 /* we have 'value NAME TYP XXX' */
2881 for (nn = node->values; nn;
2891 n->name = eina_stringshare_add(tok2);
2892 if (!strcmp(tok3, "char:"))
2894 n->type = EET_T_CHAR;
2895 sscanf(tok4, "%hhi",
2896 &(n->data.value.c));
2898 else if (!strcmp(tok3, "short:"))
2900 n->type = EET_T_SHORT;
2902 &(n->data.value.s));
2904 else if (!strcmp(tok3, "int:"))
2906 n->type = EET_T_INT;
2908 &(n->data.value.i));
2910 else if (!strcmp(tok3, "long_long:"))
2912 n->type = EET_T_LONG_LONG;
2913 sscanf(tok4, "%lli",
2914 &(n->data.value.l));
2916 else if (!strcmp(tok3, "float:"))
2918 n->type = EET_T_FLOAT;
2920 &(n->data.value.f));
2922 else if (!strcmp(tok3, "double:"))
2924 n->type = EET_T_DOUBLE;
2926 &(n->data.value.d));
2928 else if (!strcmp(tok3, "uchar:"))
2930 n->type = EET_T_UCHAR;
2931 sscanf(tok4, "%hhu",
2932 &(n->data.value.uc));
2934 else if (!strcmp(tok3, "ushort:"))
2936 n->type = EET_T_USHORT;
2938 &(n->data.value.us));
2940 else if (!strcmp(tok3, "uint:"))
2942 n->type = EET_T_UINT;
2944 &(n->data.value.ui));
2946 else if (!strcmp(tok3, "ulong_long:"))
2948 n->type = EET_T_ULONG_LONG;
2949 sscanf(tok4, "%llu",
2950 &(n->data.value.ul));
2952 else if (!strcmp(tok3, "string:"))
2954 n->type = EET_T_STRING;
2956 eina_stringshare_add(tok4);
2958 else if (!strcmp(tok3, "inlined:"))
2960 n->type = EET_T_INLINED_STRING;
2962 eina_stringshare_add(tok4);
2964 else if (!strcmp(tok3, "null"))
2966 n->type = EET_T_NULL;
2967 n->data.value.str = NULL;
2971 "ERROR: value type '%s' invalid.",
2985 else if (!strcmp(tok1, "key"))
2990 /* we have 'key NAME' */
2992 node->key = eina_stringshare_add(tok2);
2997 else if (!strcmp(tok1, "count"))
3002 /* we have a 'count COUNT' */
3004 sscanf(tok2, "%i", &(node->count));
3009 else if (!strcmp(tok1, "}"))
3010 /* we have an end of the group */
3012 node = node->parent;
3020 cdata = _eet_data_dump_encode(EET_G_UNKNOWN, ed, node_base, size_ret);
3021 eet_node_del(node_base);
3025 } /* _eet_data_dump_parse */
3027 #define NEXT_CHUNK(P, Size, Echnk, Ed)\
3030 tmp = Ed ? (int)(sizeof(int) * 2) : Echnk.len + 4;\
3031 P += (4 + Echnk.size + tmp);\
3032 Size -= (4 + Echnk.size + tmp);\
3036 _eet_data_descriptor_decode(Eet_Free_Context *context,
3037 const Eet_Dictionary *ed,
3038 Eet_Data_Descriptor *edd,
3039 const void *data_in,
3042 Eet_Node *result = NULL;
3046 Eet_Data_Chunk chnk;
3048 if (_eet_data_words_bigendian == -1)
3050 unsigned long int v;
3052 v = htonl(0x12345678);
3053 if (v == 0x12345678)
3054 _eet_data_words_bigendian = 1;
3056 _eet_data_words_bigendian = 0;
3061 data = edd->func.mem_alloc(edd->size);
3067 for (i = 0; i < edd->elements.num; i++)
3068 edd->elements.set[i].directory_name_ptr = NULL;
3073 _eet_freelist_all_ref(context);
3075 _eet_freelist_add(context, data);
3077 memset(&chnk, 0, sizeof(Eet_Data_Chunk));
3078 eet_data_chunk_get(ed, &chnk, data_in, size_in);
3083 if (strcmp(chnk.name, edd->name))
3088 size = size_in - (4 + sizeof(int) * 2);
3090 size = size_in - (4 + 4 + chnk.len);
3094 if (!edd->elements.hash.buckets)
3095 _eet_descriptor_hash_new(edd);
3099 switch (chnk.group_type)
3105 return eet_node_string_new(chnk.name, chnk.data);
3107 case EET_T_INLINED_STRING:
3108 return eet_node_inlined_string_new(chnk.name, chnk.data);
3111 return eet_node_null_new(chnk.name);
3114 result = eet_node_struct_new(chnk.name, NULL);
3118 case EET_G_VAR_ARRAY:
3119 return eet_node_var_array_new(chnk.name, NULL);
3133 Eet_Data_Chunk echnk;
3134 Eet_Data_Element *ede = NULL;
3135 Eet_Node *child = NULL;
3136 int group_type = EET_G_UNKNOWN, type = EET_T_UNKNOW;
3139 /* get next data chunk */
3140 memset(&echnk, 0, sizeof(Eet_Data_Chunk));
3141 eet_data_chunk_get(ed, &echnk, p, size);
3143 goto error; /* FIXME: don't REPLY on edd - work without */
3147 ede = _eet_descriptor_hash_find(edd, echnk.name, echnk.hash);
3150 group_type = ede->group_type;
3152 if ((echnk.type == 0) && (echnk.group_type == 0))
3155 group_type = ede->group_type;
3159 if (IS_SIMPLE_TYPE(echnk.type) &&
3160 eet_data_type_match(echnk.type, ede->type))
3161 /* Needed when converting on the fly from FP to Float */
3163 else if ((echnk.group_type > EET_G_UNKNOWN) &&
3164 (echnk.group_type < EET_G_LAST) &&
3165 (echnk.group_type == ede->group_type))
3166 group_type = echnk.group_type;
3170 /*...... dump to node */
3174 group_type = echnk.group_type;
3177 if (!edd && group_type == EET_G_UNKNOWN && IS_SIMPLE_TYPE(type))
3179 unsigned char dd[128];
3181 ret = eet_data_get_type(ed,
3184 ((char *)echnk.data) + echnk.size,
3189 child = eet_data_node_simple_type(type, echnk.name, dd);
3191 eet_node_struct_append(result, echnk.name, child);
3195 ret = eet_group_codec[group_type - 100].get(
3203 ede ? (void *)(((char
3216 /* advance to next chunk */
3217 NEXT_CHUNK(p, size, echnk, ed);
3220 _eet_freelist_all_unref(context);
3223 _eet_freelist_str_free(context, edd);
3224 _eet_freelist_direct_str_free(context, edd);
3225 _eet_freelist_list_free(context, edd);
3226 _eet_freelist_hash_free(context, edd);
3227 _eet_freelist_free(context, edd);
3231 _eet_freelist_reset(context);
3232 _eet_freelist_str_reset(context);
3233 _eet_freelist_list_reset(context);
3234 _eet_freelist_hash_reset(context);
3235 _eet_freelist_direct_str_reset(context);
3244 eet_node_del(result);
3246 _eet_freelist_all_unref(context);
3247 _eet_freelist_str_free(context, edd);
3248 _eet_freelist_direct_str_free(context, edd);
3249 _eet_freelist_list_free(context, edd);
3250 _eet_freelist_hash_free(context, edd);
3251 _eet_freelist_free(context, edd);
3253 /* FIXME: Warn that something goes wrong here. */
3255 } /* _eet_data_descriptor_decode */
3258 eet_data_get_list(Eet_Free_Context *context,
3259 const Eet_Dictionary *ed,
3260 Eet_Data_Descriptor *edd,
3261 Eet_Data_Element *ede,
3262 Eet_Data_Chunk *echnk,
3264 int group_type __UNUSED__,
3269 Eet_Data_Descriptor *subtype = NULL;
3274 EET_ASSERT(!((type > EET_T_UNKNOW) && (type < EET_T_STRING)), return 0);
3278 subtype = ede->subtype;
3280 if (type != ede->type)
3284 ptr = (void **)data;
3288 if (IS_POINTER_TYPE(type))
3289 POINTER_TYPE_DECODE(context,
3300 STRUCT_TYPE_DECODE(data_ret,
3310 list = edd->func.list_append(list, data_ret);
3312 _eet_freelist_list_add(context, ptr);
3315 eet_node_list_append(*((Eet_Node **)data), echnk->name, data_ret);
3321 } /* eet_data_get_list */
3324 eet_data_get_hash(Eet_Free_Context *context,
3325 const Eet_Dictionary *ed,
3326 Eet_Data_Descriptor *edd,
3327 Eet_Data_Element *ede,
3328 Eet_Data_Chunk *echnk,
3330 int group_type __UNUSED__,
3338 void *data_ret = NULL;
3341 EET_ASSERT(!((type > EET_T_UNKNOW) && (type < EET_T_STRING)), return 0);
3343 ptr = (void **)data;
3347 ret = eet_data_get_type(ed,
3350 ((char *)echnk->data) + echnk->size,
3355 /* Advance to next chunk */
3356 NEXT_CHUNK((*p), (*size), (*echnk), ed);
3357 memset(echnk, 0, sizeof(Eet_Data_Chunk));
3360 eet_data_chunk_get(ed, echnk, *p, *size);
3364 if (IS_POINTER_TYPE(echnk->type))
3365 POINTER_TYPE_DECODE(context,
3376 STRUCT_TYPE_DECODE(data_ret,
3379 ede ? ede->subtype : NULL,
3386 hash = edd->func.hash_add(hash, key, data_ret);
3388 _eet_freelist_hash_add(context, hash);
3391 eet_node_hash_add(*((Eet_Node **)data), echnk->name, key, data_ret);
3397 } /* eet_data_get_hash */
3399 /* var arrays and fixed arrays have to
3400 * get all chunks at once. for fixed arrays
3401 * we can get each chunk and increment a
3402 * counter stored on the element itself but
3403 * it wont be thread safe. for var arrays
3404 * we still need a way to get the number of
3405 * elements from the data, so storing the
3406 * number of elements and the element data on
3407 * each chunk is pointless.
3410 eet_data_get_array(Eet_Free_Context *context,
3411 const Eet_Dictionary *ed,
3412 Eet_Data_Descriptor *edd,
3413 Eet_Data_Element *ede,
3414 Eet_Data_Chunk *echnk,
3421 Eina_List *childs = NULL;
3430 EET_ASSERT(!((type > EET_T_UNKNOW) && (type < EET_T_STRING)), return 0);
3433 /* read the number of elements */
3434 ret = eet_data_get_type(ed,
3437 ((char *)echnk->data) + echnk->size,
3446 if (IS_POINTER_TYPE(type))
3447 subsize = eet_basic_codec[ede->type].size;
3449 subsize = ede->subtype->size;
3451 if (group_type == EET_G_VAR_ARRAY)
3453 /* store the number of elements
3454 * on the counter offset */
3455 *(int *)(((char *)data) + ede->count - ede->offset) = count;
3456 /* allocate space for the array of elements */
3457 *(void **)ptr = edd->func.mem_alloc(count * subsize);
3462 memset(*(void **)ptr, 0, count * subsize);
3464 _eet_freelist_add(context, *(void **)ptr);
3468 /* get all array elements */
3469 for (i = 0; i < count; i++)
3472 void *data_ret = NULL;
3474 /* Advance to next chunk */
3475 NEXT_CHUNK((*p), (*size), (*echnk), ed);
3476 memset(echnk, 0, sizeof(Eet_Data_Chunk));
3478 eet_data_chunk_get(ed, echnk, *p, *size);
3479 if (!echnk->name || strcmp(echnk->name, name) != 0)
3480 goto on_error; /* get the data */
3482 if ((echnk->group_type != group_type)
3483 || ((echnk->type != type) && (echnk->type != EET_T_NULL)))
3487 if ((ede->group_type != echnk->group_type)
3488 || ((echnk->type != ede->type) && (echnk->type != EET_T_NULL)))
3491 /* get the destination pointer */
3494 if (group_type == EET_G_ARRAY)
3495 dst = (char *)ptr + (subsize * i);
3497 dst = *(char **)ptr + (subsize * i);
3500 if (IS_POINTER_TYPE(echnk->type))
3502 POINTER_TYPE_DECODE(context,
3513 memcpy(dst, &data_ret, subsize);
3516 childs = eina_list_append(childs, data_ret);
3520 STRUCT_TYPE_DECODE(data_ret,
3523 ede ? ede->subtype : NULL,
3529 memcpy(dst, data_ret, subsize);
3530 if (edd) edd->func.mem_free(data_ret);
3531 else free(data_ret);
3535 childs = eina_list_append(childs, data_ret);
3541 Eet_Node *parent = *((Eet_Node **)data);
3544 if (group_type == EET_G_ARRAY)
3545 array = eet_node_array_new(name, count, childs);
3547 array = eet_node_var_array_new(name, childs);
3552 eet_node_struct_append(parent, name, array);
3558 EINA_LIST_FREE(childs, tmp)
3562 } /* eet_data_get_array */
3565 eet_data_put_union(Eet_Dictionary *ed,
3566 Eet_Data_Descriptor *edd __UNUSED__,
3567 Eet_Data_Element *ede,
3568 Eet_Data_Stream *ds,
3571 const char *union_type;
3574 EET_ASSERT(!((ede->type != EET_T_UNKNOW) || (!ede->subtype)), return );
3576 union_type = ede->subtype->func.type_get(
3577 ((char *)data_in) + ede->count - ede->offset,
3583 /* Search the structure of the union to encode. */
3584 for (i = 0; i < ede->subtype->elements.num; ++i)
3585 if (strcmp(ede->subtype->elements.set[i].name, union_type) == 0)
3587 Eet_Data_Element *sede;
3591 /* Yeah we found it ! */
3592 data = eet_data_put_type(ed, EET_T_STRING, &union_type, &size);
3602 sede = &(ede->subtype->elements.set[i]);
3603 data = _eet_data_descriptor_encode(ed,
3619 } /* eet_data_put_union */
3622 eet_data_get_union(Eet_Free_Context *context,
3623 const Eet_Dictionary *ed,
3624 Eet_Data_Descriptor *edd __UNUSED__,
3625 Eet_Data_Element *ede,
3626 Eet_Data_Chunk *echnk,
3633 const char *union_type;
3634 void *data_ret = NULL;
3639 ret = eet_data_get_type(ed,
3642 ((char *)echnk->data) + echnk->size,
3647 /* Advance to next chunk */
3648 NEXT_CHUNK((*p), (*size), (*echnk), ed);
3649 memset(echnk, 0, sizeof(Eet_Data_Chunk));
3652 eet_data_chunk_get(ed, echnk, *p, *size);
3658 EET_ASSERT(!(ede->group_type != group_type || ede->type != type),
3661 /* Search the structure of the union to decode */
3662 for (i = 0; i < ede->subtype->elements.num; ++i)
3663 if (strcmp(ede->subtype->elements.set[i].name, union_type) == 0)
3665 Eet_Data_Element *sede;
3668 /* Yeah we found it ! */
3669 sede = &(ede->subtype->elements.set[i]);
3670 EET_ASSERT(sede->subtype, goto on_error);
3672 data_ret = _eet_data_descriptor_decode(context,
3680 /* Memcopy the structure content to remove pointer indirection. */
3681 memcpy(data, data_ret, sede->subtype->size);
3683 /* data_ret is now useless. */
3684 sede->subtype->func.mem_free(data_ret);
3686 /* Set union type. */
3687 if ((!ed) || (!ede->subtype->func.str_direct_alloc))
3689 ut = ede->subtype->func.str_alloc(union_type);
3690 _eet_freelist_str_add(context, ut);
3694 ut = ede->subtype->func.str_direct_alloc(union_type);
3695 _eet_freelist_direct_str_add(context, ut);
3698 ede->subtype->func.type_set(
3700 ((char *)data) + ede->count -
3710 /* FIXME: generate node structure. */
3711 data_ret = _eet_data_descriptor_decode(context,
3713 echnk->data, echnk->size);
3721 } /* eet_data_get_union */
3724 eet_data_put_variant(Eet_Dictionary *ed,
3725 Eet_Data_Descriptor *edd __UNUSED__,
3726 Eet_Data_Element *ede,
3727 Eet_Data_Stream *ds,
3730 const char *union_type;
3732 Eina_Bool unknow = EINA_FALSE;
3736 EET_ASSERT(!((ede->type != EET_T_UNKNOW) || (!ede->subtype)), return );
3738 union_type = ede->subtype->func.type_get(
3739 ((char *)data_in) + ede->count - ede->offset,
3742 if (!union_type && unknow == EINA_FALSE)
3747 /* Handle opaque internal representation */
3748 Eet_Variant_Unknow *evu;
3750 data = eet_data_put_type(ed, EET_T_STRING, &union_type, &size);
3760 evu = (Eet_Variant_Unknow *)data_in;
3761 if (evu && EINA_MAGIC_CHECK(evu, EET_MAGIC_VARIANT))
3771 /* Search the structure of the union to encode. */
3772 for (i = 0; i < ede->subtype->elements.num; ++i)
3773 if (strcmp(ede->subtype->elements.set[i].name, union_type) == 0)
3775 Eet_Data_Element *sede;
3777 /* Yeah we found it ! */
3778 data = eet_data_put_type(ed, EET_T_STRING, &union_type, &size);
3788 sede = &(ede->subtype->elements.set[i]);
3790 if (sede->group_type != EET_G_UNKNOWN)
3792 Eet_Data_Stream *lds;
3794 lds = eet_data_stream_new();
3795 eet_group_codec[sede->group_type - 100].put(ed,
3802 eet_data_encode(ed, ds, lds->data, ede->name, lds->pos,
3803 ede->type, ede->group_type);
3809 eet_data_encode(ed, ds, NULL, ede->name, 0,
3810 EET_T_NULL, ede->group_type);
3812 eet_data_stream_free(lds);
3816 data = _eet_data_descriptor_encode(ed,
3833 } /* eet_data_put_variant */
3836 eet_data_get_variant(Eet_Free_Context *context,
3837 const Eet_Dictionary *ed,
3838 Eet_Data_Descriptor *edd __UNUSED__,
3839 Eet_Data_Element *ede,
3840 Eet_Data_Chunk *echnk,
3841 int type __UNUSED__,
3842 int group_type __UNUSED__,
3847 const char *union_type;
3848 void *data_ret = NULL;
3853 ret = eet_data_get_type(ed,
3856 ((char *)echnk->data) + echnk->size,
3861 /* Advance to next chunk */
3862 NEXT_CHUNK((*p), (*size), (*echnk), ed);
3863 memset(echnk, 0, sizeof(Eet_Data_Chunk));
3866 eet_data_chunk_get(ed, echnk, *p, *size);
3874 EET_ASSERT(ede->subtype, goto on_error);
3876 if ((!ed) || (!ede->subtype->func.str_direct_alloc))
3878 ut = ede->subtype->func.str_alloc(union_type);
3879 _eet_freelist_str_add(context, ut);
3883 ut = ede->subtype->func.str_direct_alloc(union_type);
3884 _eet_freelist_direct_str_add(context, ut);
3887 /* Search the structure of the union to decode */
3888 for (i = 0; i < ede->subtype->elements.num; ++i)
3889 if (strcmp(ede->subtype->elements.set[i].name, union_type) == 0)
3891 Eet_Data_Element *sede;
3893 /* Yeah we found it ! */
3894 sede = &(ede->subtype->elements.set[i]);
3896 if (sede->group_type != EET_G_UNKNOWN)
3898 Eet_Data_Chunk chnk;
3904 size2 = echnk->size;
3906 /* Didn't find a proper way to provide this
3907 without duplicating code */
3910 memset(&chnk, 0, sizeof(Eet_Data_Chunk));
3911 eet_data_chunk_get(ed, &chnk, p2, size2);
3916 ret = eet_group_codec[sede->group_type - 100].get
3917 (context, ed, sede->subtype, sede, &chnk, sede->type,
3918 sede->group_type, data, &p2, &size2);
3923 /* advance to next chunk */
3924 NEXT_CHUNK(p2, size2, chnk, ed);
3927 /* Put garbage so that we will not put eet_variant_unknow in it */
3928 data_ret = (void *)data;
3930 /* Set variant type. */
3931 ede->subtype->func.type_set
3932 (ut, ((char *)data) + ede->count - ede->offset,
3937 data_ret = _eet_data_descriptor_decode(context,
3945 /* And point to the variant data. */
3946 *(void **)data = data_ret;
3948 /* Set variant type. */
3949 ede->subtype->func.type_set
3950 (ut, ((char *)data) + ede->count - ede->offset, EINA_FALSE);
3956 Eet_Variant_Unknow *evu;
3958 evu = calloc(1, sizeof (Eet_Variant_Unknow) + echnk->size - 1);
3962 evu->size = echnk->size;
3963 memcpy(evu->data, echnk->data, evu->size);
3964 EINA_MAGIC_SET(evu, EET_MAGIC_VARIANT);
3966 /* And point to the opaque internal data scructure */
3967 *(void **)data = evu;
3969 /* Set variant type. */
3970 ede->subtype->func.type_set
3971 (ut, ((char *)data) + ede->count - ede->offset, EINA_TRUE);
3976 /* FIXME: dump node structure. */
3977 data_ret = _eet_data_descriptor_decode(context,
3979 echnk->data, echnk->size);
3987 } /* eet_data_get_variant */
3990 eet_data_node_simple_type(int type, const char *name, void *dd)
3994 #endif /* ifdef EET_T_TYPE */
3996 #define EET_T_TYPE(Eet_Type, Eet_Node_Type, Type)\
3998 return eet_node_ ## Eet_Node_Type ## _new(name, *((Type *)dd));\
4002 EET_T_TYPE(EET_T_CHAR, char, char);
4003 EET_T_TYPE(EET_T_SHORT, short, short);
4004 EET_T_TYPE(EET_T_INT, int, int);
4005 EET_T_TYPE(EET_T_LONG_LONG, long_long, long long);
4006 EET_T_TYPE(EET_T_FLOAT, float, float);
4007 EET_T_TYPE(EET_T_DOUBLE, double, double);
4008 EET_T_TYPE(EET_T_UCHAR, unsigned_char, unsigned char);
4009 EET_T_TYPE(EET_T_USHORT, unsigned_short, unsigned short);
4010 EET_T_TYPE(EET_T_UINT, unsigned_int, unsigned int);
4011 EET_T_TYPE(EET_T_ULONG_LONG, unsigned_long_long, unsigned long long);
4012 EET_T_TYPE(EET_T_STRING, string, char *);
4013 EET_T_TYPE(EET_T_INLINED_STRING, inlined_string, char *);
4016 return eet_node_null_new(name);
4019 ERR("Unknow type passed to eet_data_node_simple_type");
4022 } /* eet_data_node_simple_type */
4025 eet_data_get_unknown(Eet_Free_Context *context,
4026 const Eet_Dictionary *ed,
4027 Eet_Data_Descriptor *edd,
4028 Eet_Data_Element *ede,
4029 Eet_Data_Chunk *echnk,
4031 int group_type __UNUSED__,
4033 char **p __UNUSED__,
4034 int *size __UNUSED__)
4039 if (IS_SIMPLE_TYPE(type))
4041 unsigned char dd[128];
4043 ret = eet_data_get_type(ed,
4046 ((char *)echnk->data) + echnk->size,
4047 edd ? (char *)data : (char *)dd);
4053 Eet_Node **parent = data;
4056 node = eet_data_node_simple_type(type, echnk->name, dd);
4059 eet_node_struct_append(*parent, echnk->name, node);
4065 if (type == EET_T_STRING)
4069 str = (char **)(((char *)data));
4072 if ((ed == NULL) || (edd->func.str_direct_alloc == NULL))
4074 *str = edd->func.str_alloc(*str);
4075 _eet_freelist_str_add(context, *str);
4079 *str = edd->func.str_direct_alloc(*str);
4080 _eet_freelist_direct_str_add(context, *str);
4084 else if (edd && type == EET_T_INLINED_STRING)
4088 str = (char **)(((char *)data));
4091 *str = edd->func.str_alloc(*str);
4092 _eet_freelist_str_add(context, *str);
4099 Eet_Data_Descriptor *subtype;
4101 subtype = ede ? ede->subtype : NULL;
4103 if (subtype || !edd)
4105 Eet_Node **parent = data;
4108 data_ret = _eet_data_descriptor_decode(context,
4118 ptr = (void **)(((char *)data));
4119 *ptr = (void *)data_ret;
4123 Eet_Node *node = data_ret;
4127 node = eet_node_struct_child_new(echnk->name, node);
4128 eet_node_struct_append(*parent, echnk->name, node);
4137 } /* eet_data_get_unknown */
4140 eet_data_put_array(Eet_Dictionary *ed,
4141 Eet_Data_Descriptor *edd __UNUSED__,
4142 Eet_Data_Element *ede,
4143 Eet_Data_Stream *ds,
4153 EET_ASSERT(!((ede->type > EET_T_UNKNOW) && (ede->type < EET_T_STRING)),
4156 if (ede->group_type == EET_G_ARRAY)
4157 count = ede->counter_offset;
4159 count = *(int *)(((char *)data_in) + ede->count - ede->offset);
4162 return; /* Store number of elements */
4164 data = eet_data_put_type(ed, EET_T_INT, &count, &size);
4166 eet_data_encode(ed, ds, data, ede->name, size, ede->type, ede->group_type);
4168 if (IS_POINTER_TYPE(ede->type))
4169 subsize = eet_basic_codec[ede->type].size;
4171 subsize = ede->subtype->size;
4173 for (j = 0; j < count; j++)
4178 if (ede->group_type == EET_G_ARRAY)
4179 d = (void *)(((char *)data_in) + offset);
4181 d = *(((char **)data_in)) + offset;
4183 if (IS_POINTER_TYPE(ede->type))
4186 eet_data_put_unknown(ed, NULL, ede, ds, d);
4190 data = _eet_data_descriptor_encode(ed, ede->subtype, d, &size);
4202 /* Add a NULL element just to have the correct array layout. */
4213 } /* eet_data_put_array */
4216 eet_data_put_unknown(Eet_Dictionary *ed,
4217 Eet_Data_Descriptor *edd __UNUSED__,
4218 Eet_Data_Element *ede,
4219 Eet_Data_Stream *ds,
4225 if (IS_SIMPLE_TYPE(ede->type))
4226 data = eet_data_put_type(ed, ede->type, data_in, &size);
4227 else if (ede->subtype)
4228 if (*((char **)data_in))
4229 data = _eet_data_descriptor_encode(ed,
4231 *((char **)((char *)(data_in))),
4242 } /* eet_data_put_unknown */
4245 eet_data_put_list(Eet_Dictionary *ed,
4246 Eet_Data_Descriptor *edd,
4247 Eet_Data_Element *ede,
4248 Eet_Data_Stream *ds,
4255 EET_ASSERT(!(((ede->type > EET_T_UNKNOW) && (ede->type < EET_T_STRING))
4256 || ((ede->type > EET_T_NULL) && (ede->type < EET_T_LAST))),
4259 l = *((void **)(((char *)data_in)));
4260 for (; l; l = edd->func.list_next(l))
4262 if (IS_POINTER_TYPE(ede->type))
4264 const void *str = edd->func.list_data(l);
4265 eet_data_put_unknown(ed, NULL, ede, ds, &str);
4269 data = _eet_data_descriptor_encode(ed,
4271 edd->func.list_data(l),
4283 } /* eet_data_put_list */
4286 eet_data_put_hash(Eet_Dictionary *ed,
4287 Eet_Data_Descriptor *edd,
4288 Eet_Data_Element *ede,
4289 Eet_Data_Stream *ds,
4292 Eet_Data_Encode_Hash_Info fdata;
4295 l = *((void **)(((char *)data_in)));
4299 edd->func.hash_foreach(l, eet_data_descriptor_encode_hash_cb, &fdata);
4300 } /* eet_data_put_hash */
4303 eet_data_dump_cipher(Eet_File *ef,
4305 const char *cipher_key,
4306 void (*dumpfunc)(void *data, const char *str),
4309 const Eet_Dictionary *ed = NULL;
4310 const void *data = NULL;
4312 Eet_Free_Context context;
4313 int required_free = 0;
4316 ed = eet_dictionary_get(ef);
4319 data = eet_read_direct(ef, name, &size);
4324 data = eet_read_cipher(ef, name, &size, cipher_key);
4329 memset(&context, 0, sizeof (context));
4330 result = _eet_data_descriptor_decode(&context, ed, NULL, data, size);
4332 eet_node_dump(result, 0, dumpfunc, dumpdata);
4334 eet_node_del(result);
4339 return result ? 1 : 0;
4340 } /* eet_data_dump_cipher */
4343 eet_data_dump(Eet_File *ef,
4345 void (*dumpfunc)(void *data, const char *str),
4348 return eet_data_dump_cipher(ef, name, NULL, dumpfunc, dumpdata);
4349 } /* eet_data_dump */
4352 eet_data_text_dump_cipher(const void *data_in,
4353 const char *cipher_key,
4355 void (*dumpfunc)(void *data, const char *str),
4360 Eet_Free_Context context;
4361 unsigned int ret_len = 0;
4368 if (eet_decipher(data_in, size_in, cipher_key,
4369 strlen(cipher_key), &ret, &ret_len))
4379 ret = (void *)data_in;
4383 memset(&context, 0, sizeof (context));
4384 result = _eet_data_descriptor_decode(&context, NULL, NULL, ret, ret_len);
4386 eet_node_dump(result, 0, dumpfunc, dumpdata);
4388 eet_node_del(result);
4392 return result ? 1 : 0;
4393 } /* eet_data_text_dump_cipher */
4396 eet_data_text_dump(const void *data_in,
4398 void (*dumpfunc)(void *data, const char *str),
4401 return eet_data_text_dump_cipher(data_in, NULL, size_in, dumpfunc, dumpdata);
4402 } /* eet_data_text_dump */
4405 eet_data_text_undump_cipher(const char *text,
4406 const char *cipher_key,
4412 ret = _eet_data_dump_parse(NULL, size_ret, text, textlen);
4413 if (ret && cipher_key)
4415 void *ciphered = NULL;
4416 unsigned int ciphered_len;
4418 if (eet_cipher(ret, *size_ret, cipher_key,
4419 strlen(cipher_key), &ciphered, &ciphered_len))
4430 *size_ret = ciphered_len;
4435 } /* eet_data_text_undump_cipher */
4438 eet_data_text_undump(const char *text,
4442 return eet_data_text_undump_cipher(text, NULL, textlen, size_ret);
4443 } /* eet_data_text_undump */
4446 eet_data_undump_cipher(Eet_File *ef,
4448 const char *cipher_key,
4458 ed = eet_dictionary_get(ef);
4460 data_enc = _eet_data_dump_parse(ed, &size, text, textlen);
4464 val = eet_write_cipher(ef, name, data_enc, size, compress, cipher_key);
4467 } /* eet_data_undump_cipher */
4470 eet_data_undump(Eet_File *ef,
4476 return eet_data_undump_cipher(ef, name, NULL, text, textlen, compress);
4477 } /* eet_data_undump */
4480 eet_data_descriptor_decode_cipher(Eet_Data_Descriptor *edd,
4481 const void *data_in,
4482 const char *cipher_key,
4485 void *deciphered = (void *)data_in;
4487 Eet_Free_Context context;
4488 unsigned int deciphered_len = size_in;
4490 if (cipher_key && data_in)
4491 if (eet_decipher(data_in, size_in, cipher_key,
4492 strlen(cipher_key), &deciphered, &deciphered_len))
4500 memset(&context, 0, sizeof (context));
4501 ret = _eet_data_descriptor_decode(&context,
4507 if (data_in != deciphered)
4511 } /* eet_data_descriptor_decode_cipher */
4514 eet_data_descriptor_decode(Eet_Data_Descriptor *edd,
4515 const void *data_in,
4518 return eet_data_descriptor_decode_cipher(edd, data_in, NULL, size_in);
4519 } /* eet_data_descriptor_decode */
4522 eet_data_node_decode_cipher(const void *data_in,
4523 const char *cipher_key,
4526 void *deciphered = (void *)data_in;
4528 Eet_Free_Context context;
4529 unsigned int deciphered_len = size_in;
4531 if (cipher_key && data_in)
4532 if (eet_decipher(data_in, size_in, cipher_key,
4533 strlen(cipher_key), &deciphered, &deciphered_len))
4541 memset(&context, 0, sizeof (context));
4542 ret = _eet_data_descriptor_decode(&context,
4548 if (data_in != deciphered)
4552 } /* eet_data_node_decode_cipher */
4555 _eet_data_descriptor_encode(Eet_Dictionary *ed,
4556 Eet_Data_Descriptor *edd,
4557 const void *data_in,
4560 Eet_Data_Stream *ds;
4561 Eet_Data_Chunk *chnk;
4566 if (_eet_data_words_bigendian == -1)
4568 unsigned long int v;
4570 v = htonl(0x12345678);
4571 if (v == 0x12345678)
4572 _eet_data_words_bigendian = 1;
4574 _eet_data_words_bigendian = 0;
4577 ds = eet_data_stream_new();
4578 for (i = 0; i < edd->elements.num; i++)
4580 Eet_Data_Element *ede;
4582 ede = &(edd->elements.set[i]);
4583 eet_group_codec[ede->group_type - 100].put(
4591 chnk = eet_data_chunk_new(ds->data,
4598 eet_data_stream_free(ds);
4600 ds = eet_data_stream_new();
4601 eet_data_chunk_put(ed, chnk, ds);
4607 eet_data_stream_free(ds);
4611 eet_data_chunk_free(chnk);
4614 } /* _eet_data_descriptor_encode */
4617 eet_data_node_write_cipher(Eet_File *ef,
4619 const char *cipher_key,
4628 ed = eet_dictionary_get(ef);
4630 data_enc = _eet_data_dump_encode(EET_G_UNKNOWN, ed, node, &size);
4634 val = eet_write_cipher(ef, name, data_enc, size, compress, cipher_key);
4637 } /* eet_data_node_write_cipher */
4640 eet_data_node_encode_cipher(Eet_Node *node,
4641 const char *cipher_key,
4645 void *ciphered = NULL;
4646 unsigned int ciphered_len = 0;
4649 ret = _eet_data_dump_encode(EET_G_UNKNOWN, NULL, node, &size);
4650 if (cipher_key && ret)
4652 if (eet_cipher(ret, size, cipher_key,
4653 strlen(cipher_key), &ciphered, &ciphered_len))
4666 size = (int)ciphered_len;
4674 } /* eet_data_node_encode_cipher */
4677 eet_data_descriptor_encode_cipher(Eet_Data_Descriptor *edd,
4678 const void *data_in,
4679 const char *cipher_key,
4683 void *ciphered = NULL;
4684 unsigned int ciphered_len = 0;
4687 ret = _eet_data_descriptor_encode(NULL, edd, data_in, &size);
4688 if (cipher_key && ret)
4690 if (eet_cipher(ret, size, cipher_key,
4691 strlen(cipher_key), &ciphered, &ciphered_len))
4704 size = ciphered_len;
4712 } /* eet_data_descriptor_encode_cipher */
4715 eet_data_descriptor_encode(Eet_Data_Descriptor *edd,
4716 const void *data_in,
4719 return eet_data_descriptor_encode_cipher(edd, data_in, NULL, size_ret);
4720 } /* eet_data_descriptor_encode */