2 * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
7 #endif /* ifdef HAVE_CONFIG_H */
15 #ifdef HAVE_NETINET_IN_H
16 # include <netinet/in.h>
17 #endif /* ifdef HAVE_NETINET_IN_H */
20 # include <winsock2.h>
21 #endif /* ifdef _WIN32 */
26 #include "Eet_private.h"
29 * routines for doing data -> struct and struct -> data conversion
49 * multiple entries ordered as...
51 * fixed size array [ of basic types ]
52 * variable size array [ of basic types ]
53 * linked list [ of basic types ]
54 * hash table [ of basic types ]
56 * need to provide builder/accessor funcs for:
68 typedef struct _Eet_Data_Element Eet_Data_Element;
69 typedef struct _Eet_Data_Basic_Type_Codec Eet_Data_Basic_Type_Codec;
70 typedef struct _Eet_Data_Group_Type_Codec Eet_Data_Group_Type_Codec;
71 typedef struct _Eet_Data_Chunk Eet_Data_Chunk;
72 typedef struct _Eet_Data_Stream Eet_Data_Stream;
73 typedef struct _Eet_Data_Descriptor_Hash Eet_Data_Descriptor_Hash;
74 typedef struct _Eet_Data_Encode_Hash_Info Eet_Data_Encode_Hash_Info;
75 typedef struct _Eet_Free Eet_Free;
76 typedef struct _Eet_Free_Context Eet_Free_Context;
77 typedef struct _Eet_Variant_Unknow Eet_Variant_Unknow;
82 * Eet_Data_Basic_Type_Codec (Coder, Decoder)
83 * Eet_Data_Group_Type_Codec (Coder, Decoder)
85 struct _Eet_Data_Basic_Type_Codec
89 int (*get)(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dest);
90 void * (*put)(Eet_Dictionary *ed, const void *src, int *size_ret);
93 struct _Eet_Data_Group_Type_Codec
95 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);
96 void (*put)(Eet_Dictionary *ed, Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Stream *ds, void *data_in);
99 struct _Eet_Data_Chunk
107 unsigned char group_type;
110 struct _Eet_Data_Stream
117 struct _Eet_Data_Descriptor_Hash
119 Eet_Data_Element *element;
120 Eet_Data_Descriptor_Hash *next;
123 struct _Eet_Data_Descriptor
126 const Eet_Dictionary *ed;
130 void * (*mem_alloc)(size_t size);
131 void (*mem_free)(void *mem);
132 char * (*str_alloc)(const char *str);
133 char * (*str_direct_alloc)(const char *str);
134 void (*str_free)(const char *str);
135 void (*str_direct_free)(const char *str);
136 void * (*list_next)(void *l);
137 void * (*list_append)(void *l, void *d);
138 void * (*list_data)(void *l);
139 void * (*list_free)(void *l);
140 void (*hash_foreach)(void *h, int (*func)(void *h, const char *k, void *dt, void *fdt), void *fdt);
141 void * (*hash_add)(void *h, const char *k, void *d);
142 void (*hash_free)(void *h);
143 const char *(*type_get)(const void *data, Eina_Bool *unknow);
144 Eina_Bool (*type_set)(const char *type, void *data, Eina_Bool unknow);
149 Eet_Data_Element *set;
153 Eet_Data_Descriptor_Hash *buckets;
157 Eina_Bool unified_type : 1;
162 struct _Eet_Data_Element
165 const char *counter_name;
166 const char *directory_name_ptr;
167 Eet_Data_Descriptor *subtype;
168 int offset; /* offset in bytes from the base element */
169 int count; /* number of elements for a fixed array */
170 int counter_offset; /* for a variable array we need the offset of the count variable */
171 unsigned char type; /* EET_T_XXX */
172 unsigned char group_type; /* EET_G_XXX */
175 struct _Eet_Data_Encode_Hash_Info
178 Eet_Data_Element *ede;
190 struct _Eet_Free_Context
193 Eet_Free freelist_list;
194 Eet_Free freelist_hash;
195 Eet_Free freelist_str;
196 Eet_Free freelist_direct_str;
199 struct _Eet_Variant_Unknow
209 static int eet_data_get_char(const Eet_Dictionary *ed,
213 static void * eet_data_put_char(Eet_Dictionary *ed,
216 static int eet_data_get_short(const Eet_Dictionary *ed,
220 static void * eet_data_put_short(Eet_Dictionary *ed,
223 static inline int eet_data_get_int(const Eet_Dictionary *ed,
227 static void * eet_data_put_int(Eet_Dictionary *ed,
230 static int eet_data_get_long_long(const Eet_Dictionary *ed,
234 static void * eet_data_put_long_long(Eet_Dictionary *ed,
237 static int eet_data_get_float(const Eet_Dictionary *ed,
241 static void * eet_data_put_float(Eet_Dictionary *ed,
244 static int eet_data_get_double(const Eet_Dictionary *ed,
248 static void * eet_data_put_double(Eet_Dictionary *ed,
251 static int eet_data_get_f32p32(const Eet_Dictionary *ed,
255 static void * eet_data_put_f32p32(Eet_Dictionary *ed,
258 static int eet_data_get_f16p16(const Eet_Dictionary *ed,
262 static void * eet_data_put_f16p16(Eet_Dictionary *ed,
265 static int eet_data_get_f8p24(const Eet_Dictionary *ed,
269 static void * eet_data_put_f8p24(Eet_Dictionary *ed,
272 static inline int eet_data_get_string(const Eet_Dictionary *ed,
276 static void * eet_data_put_string(Eet_Dictionary *ed,
279 static int eet_data_get_istring(const Eet_Dictionary *ed,
283 static void * eet_data_put_istring(Eet_Dictionary *ed,
286 static int eet_data_get_null(const Eet_Dictionary *ed,
290 static void * eet_data_put_null(Eet_Dictionary *ed,
294 static int eet_data_get_type(const Eet_Dictionary *ed,
299 static void * eet_data_put_type(Eet_Dictionary *ed,
304 static Eet_Node * eet_data_node_simple_type(int type,
308 static int eet_data_get_unknown(Eet_Free_Context *context,
309 const Eet_Dictionary *ed,
310 Eet_Data_Descriptor *edd,
311 Eet_Data_Element *ede,
312 Eet_Data_Chunk *echnk,
318 static void eet_data_put_unknown(Eet_Dictionary *ed,
319 Eet_Data_Descriptor *edd,
320 Eet_Data_Element *ede,
323 static void eet_data_put_array(Eet_Dictionary *ed,
324 Eet_Data_Descriptor *edd,
325 Eet_Data_Element *ede,
328 static int eet_data_get_array(Eet_Free_Context *context,
329 const Eet_Dictionary *ed,
330 Eet_Data_Descriptor *edd,
331 Eet_Data_Element *ede,
332 Eet_Data_Chunk *echnk,
338 static int eet_data_get_list(Eet_Free_Context *context,
339 const Eet_Dictionary *ed,
340 Eet_Data_Descriptor *edd,
341 Eet_Data_Element *ede,
342 Eet_Data_Chunk *echnk,
348 static void eet_data_put_list(Eet_Dictionary *ed,
349 Eet_Data_Descriptor *edd,
350 Eet_Data_Element *ede,
353 static void eet_data_put_hash(Eet_Dictionary *ed,
354 Eet_Data_Descriptor *edd,
355 Eet_Data_Element *ede,
358 static int eet_data_get_hash(Eet_Free_Context *context,
359 const Eet_Dictionary *ed,
360 Eet_Data_Descriptor *edd,
361 Eet_Data_Element *ede,
362 Eet_Data_Chunk *echnk,
368 static void eet_data_put_union(Eet_Dictionary *ed,
369 Eet_Data_Descriptor *edd,
370 Eet_Data_Element *ede,
373 static int eet_data_get_union(Eet_Free_Context *context,
374 const Eet_Dictionary *ed,
375 Eet_Data_Descriptor *edd,
376 Eet_Data_Element *ede,
377 Eet_Data_Chunk *echnk,
383 static void eet_data_put_variant(Eet_Dictionary *ed,
384 Eet_Data_Descriptor *edd,
385 Eet_Data_Element *ede,
388 static int eet_data_get_variant(Eet_Free_Context *context,
389 const Eet_Dictionary *ed,
390 Eet_Data_Descriptor *edd,
391 Eet_Data_Element *ede,
392 Eet_Data_Chunk *echnk,
399 static void eet_data_chunk_get(const Eet_Dictionary *ed,
400 Eet_Data_Chunk *chnk,
403 static Eet_Data_Chunk * eet_data_chunk_new(void *data,
408 static void eet_data_chunk_free(Eet_Data_Chunk *chnk);
410 static Eet_Data_Stream * eet_data_stream_new(void);
411 static void eet_data_stream_write(Eet_Data_Stream *ds,
414 static void eet_data_stream_free(Eet_Data_Stream *ds);
416 static void eet_data_chunk_put(Eet_Dictionary *ed,
417 Eet_Data_Chunk *chnk,
418 Eet_Data_Stream *ds);
420 static int eet_data_descriptor_encode_hash_cb(void *hash,
424 static void * _eet_data_descriptor_encode(Eet_Dictionary *ed,
425 Eet_Data_Descriptor *edd,
428 static void * _eet_data_descriptor_decode(Eet_Free_Context *context,
429 const Eet_Dictionary *ed,
430 Eet_Data_Descriptor *edd,
436 static const Eet_Data_Basic_Type_Codec eet_basic_codec[] =
438 {sizeof(char), "char", eet_data_get_char, eet_data_put_char },
439 {sizeof(short), "short", eet_data_get_short, eet_data_put_short },
440 {sizeof(int), "int", eet_data_get_int, eet_data_put_int },
441 {sizeof(long long), "long_long", eet_data_get_long_long, eet_data_put_long_long},
442 {sizeof(float), "float", eet_data_get_float, eet_data_put_float },
443 {sizeof(double), "double", eet_data_get_double, eet_data_put_double },
444 {sizeof(char), "uchar", eet_data_get_char, eet_data_put_char },
445 {sizeof(short), "ushort", eet_data_get_short, eet_data_put_short },
446 {sizeof(int), "uint", eet_data_get_int, eet_data_put_int },
447 {sizeof(long long), "ulong_long", eet_data_get_long_long, eet_data_put_long_long},
448 {sizeof(char *), "string", eet_data_get_string, eet_data_put_string },
449 {sizeof(char *), "inlined", eet_data_get_istring, eet_data_put_istring },
450 {sizeof(void *), "NULL", eet_data_get_null, eet_data_put_null },
451 {sizeof(Eina_F32p32),"f32p32", eet_data_get_f32p32, eet_data_put_f32p32 },
452 {sizeof(Eina_F16p16),"f16p16", eet_data_get_f16p16, eet_data_put_f16p16 },
453 {sizeof(Eina_F8p24),"f8p24", eet_data_get_f8p24, eet_data_put_f8p24 }
456 static const Eet_Data_Group_Type_Codec eet_group_codec[] =
458 { eet_data_get_unknown, eet_data_put_unknown },
459 { eet_data_get_array, eet_data_put_array },
460 { eet_data_get_array, eet_data_put_array },
461 { eet_data_get_list, eet_data_put_list },
462 { eet_data_get_hash, eet_data_put_hash },
463 { eet_data_get_union, eet_data_put_union },
464 { eet_data_get_variant, eet_data_put_variant }
467 static int _eet_data_words_bigendian = -1;
471 #define SWAP64(x) (x) =\
472 ((((unsigned long long)(x) & 0x00000000000000ffULL) << 56) |\
473 (((unsigned long long)(x) & 0x000000000000ff00ULL) << 40) |\
474 (((unsigned long long)(x) & 0x0000000000ff0000ULL) << 24) |\
475 (((unsigned long long)(x) & 0x00000000ff000000ULL) << 8) |\
476 (((unsigned long long)(x) & 0x000000ff00000000ULL) >> 8) |\
477 (((unsigned long long)(x) & 0x0000ff0000000000ULL) >> 24) |\
478 (((unsigned long long)(x) & 0x00ff000000000000ULL) >> 40) |\
479 (((unsigned long long)(x) & 0xff00000000000000ULL) >> 56))
480 #define SWAP32(x) (x) =\
481 ((((int)(x) & 0x000000ff) << 24) |\
482 (((int)(x) & 0x0000ff00) << 8) |\
483 (((int)(x) & 0x00ff0000) >> 8) |\
484 (((int)(x) & 0xff000000) >> 24))
485 #define SWAP16(x) (x) =\
486 ((((short)(x) & 0x00ff) << 8) |\
487 (((short)(x) & 0xff00) >> 8))
491 #endif /* ifdef CONV8 */
494 #endif /* ifdef CONV16 */
497 #endif /* ifdef CONV32 */
500 #endif /* ifdef CONV64 */
503 #define CONV16(x) {if (_eet_data_words_bigendian) {SWAP16(x); }}
504 #define CONV32(x) {if (_eet_data_words_bigendian) {SWAP32(x); }}
505 #define CONV64(x) {if (_eet_data_words_bigendian) {SWAP64(x); }}
507 #define IS_SIMPLE_TYPE(Type) (Type > EET_T_UNKNOW && Type < EET_T_LAST)
508 #define IS_POINTER_TYPE(Type) (Type >= EET_T_STRING && Type <= EET_T_NULL)
510 #define POINTER_TYPE_DECODE(Context,\
522 ___r = eet_data_get_unknown(Context,\
526 Type, EET_G_UNKNOWN,\
528 if (!___r) { goto Label; }\
531 #define STRUCT_TYPE_DECODE(Data_Ret, Context, Ed, Ede, Data, Size, Label)\
533 Data_Ret = _eet_data_descriptor_decode(Context,\
538 if (!Data_Ret) { goto Label; }\
541 #define EET_I_STRING 1 << 4
542 #define EET_I_INLINED_STRING 2 << 4
543 #define EET_I_NULL 3 << 4
545 #define EET_MAGIC_VARIANT 0xF1234BC
550 eet_data_get_char(const Eet_Dictionary *ed __UNUSED__,
557 if (((char *)src + sizeof(char)) > (char *)src_end)
565 } /* eet_data_get_char */
568 eet_data_put_char(Eet_Dictionary *ed __UNUSED__,
574 d = (char *)malloc(sizeof(char));
581 *size_ret = sizeof(char);
583 } /* eet_data_put_char */
587 eet_data_get_short(const Eet_Dictionary *ed __UNUSED__,
594 if (((char *)src + sizeof(short)) > (char *)src_end)
597 memcpy(dst, src, sizeof(short));
600 return sizeof(short);
601 } /* eet_data_get_short */
604 eet_data_put_short(Eet_Dictionary *ed __UNUSED__,
610 d = (short *)malloc(sizeof(short));
617 *size_ret = sizeof(short);
619 } /* eet_data_put_short */
623 eet_data_get_int(const Eet_Dictionary *ed __UNUSED__,
630 if (((char *)src + sizeof(int)) > (char *)src_end)
633 memcpy(dst, src, sizeof(int));
637 } /* eet_data_get_int */
640 eet_data_put_int(Eet_Dictionary *ed __UNUSED__,
646 d = (int *)malloc(sizeof(int));
653 *size_ret = sizeof(int);
655 } /* eet_data_put_int */
659 eet_data_get_long_long(const Eet_Dictionary *ed __UNUSED__,
664 unsigned long long *d;
666 if (((char *)src + sizeof(unsigned long long)) > (char *)src_end)
669 memcpy(dst, src, sizeof(unsigned long long));
670 d = (unsigned long long *)dst;
672 return sizeof(unsigned long long);
673 } /* eet_data_get_long_long */
676 eet_data_put_long_long(Eet_Dictionary *ed __UNUSED__,
680 unsigned long long *s, *d;
682 d = (unsigned long long *)malloc(sizeof(unsigned long long));
686 s = (unsigned long long *)src;
689 *size_ret = sizeof(unsigned long long);
691 } /* eet_data_put_long_long */
695 eet_data_get_string_hash(const Eet_Dictionary *ed,
703 if (eet_data_get_int(ed, src, src_end, &idx) < 0)
706 return eet_dictionary_string_get_hash(ed, idx);
710 } /* eet_data_get_string_hash */
713 eet_data_get_string(const Eet_Dictionary *ed,
727 if (eet_data_get_int(ed, src, src_end, &idx) < 0)
730 str = eet_dictionary_string_get_char(ed, idx);
735 return eet_dictionary_string_get_size(ed, idx);
746 return strlen(s) + 1;
747 } /* eet_data_get_string */
750 eet_data_put_string(Eet_Dictionary *ed,
762 str = *((const char **)src);
766 idx = eet_dictionary_string_add(ed, str);
770 return eet_data_put_int(ed, &idx, size_ret);
773 s = (char *)(*((char **)src));
782 memcpy(d, s, len + 1);
785 } /* eet_data_put_string */
787 /* ALWAYS INLINED STRING TYPE */
789 eet_data_get_istring(const Eet_Dictionary *ed __UNUSED__,
794 return eet_data_get_string(NULL, src, src_end, dst);
795 } /* eet_data_get_istring */
798 eet_data_put_istring(Eet_Dictionary *ed __UNUSED__,
802 return eet_data_put_string(NULL, src, size_ret);
803 } /* eet_data_put_istring */
805 /* ALWAYS NULL TYPE */
807 eet_data_get_null(const Eet_Dictionary *ed __UNUSED__,
808 const void *src __UNUSED__,
809 const void *src_end __UNUSED__,
818 } /* eet_data_get_null */
821 eet_data_put_null(Eet_Dictionary *ed __UNUSED__,
822 const void *src __UNUSED__,
827 } /* eet_data_put_null */
830 * Fast lookups of simple doubles/floats.
832 * These aren't properly a cache because they don't store pre-calculated
833 * values, but have a so simple math that is almost as fast.
836 _eet_data_float_cache_get(const char *s,
840 /* fast handle of simple case 0xMp+E*/
841 if ((len == 6) && (s[0] == '0') && (s[1] == 'x') && (s[3] == 'p'))
843 int mantisse = (s[2] >= 'a') ? (s[2] - 'a' + 10) : (s[2] - '0');
844 int exponent = (s[5] - '0');
847 *d = (float)(mantisse << exponent);
849 *d = (float)mantisse / (float)(1 << exponent);
855 } /* _eet_data_float_cache_get */
858 _eet_data_double_cache_get(const char *s,
862 /* fast handle of simple case 0xMp+E*/
863 if ((len == 6) && (s[0] == '0') && (s[1] == 'x') && (s[3] == 'p'))
865 int mantisse = (s[2] >= 'a') ? (s[2] - 'a' + 10) : (s[2] - '0');
866 int exponent = (s[5] - '0');
869 *d = (double)(mantisse << exponent);
871 *d = (double)mantisse / (double)(1 << exponent);
877 } /* _eet_data_double_cache_get */
881 eet_data_get_float(const Eet_Dictionary *ed,
897 s = (const char *)src;
900 while ((p < (const char *)src_end) && (*p != 0)) {len++; p++; }
902 if (_eet_data_float_cache_get(s, len, d) != 0)
905 if (eina_convert_atod(s, len, &mantisse, &exponent) == EINA_FALSE)
908 *d = (float)ldexp((double)mantisse, exponent);
913 if (eet_data_get_int(ed, src, src_end, &idx) < 0)
916 if (!eet_dictionary_string_get_float(ed, idx, d))
920 } /* eet_data_get_float */
923 eet_data_put_float(Eet_Dictionary *ed,
930 eina_convert_dtoa((double)(*(float *)src), buf);
942 memcpy(d, buf, len + 1);
947 idx = eet_dictionary_string_add(ed, buf);
951 return eet_data_put_int(ed, &idx, size_ret);
952 } /* eet_data_put_float */
956 eet_data_get_double(const Eet_Dictionary *ed,
969 long long mantisse = 0;
973 s = (const char *)src;
976 while ((p < (const char *)src_end) && (*p != 0)) {len++; p++; }
978 if (_eet_data_double_cache_get(s, len, d) != 0)
981 if (eina_convert_atod(s, len, &mantisse, &exponent) == EINA_FALSE)
984 *d = ldexp((double)mantisse, exponent);
989 if (eet_data_get_int(ed, src, src_end, &idx) < 0)
992 if (!eet_dictionary_string_get_double(ed, idx, d))
996 } /* eet_data_get_double */
999 eet_data_put_double(Eet_Dictionary *ed,
1006 eina_convert_dtoa((double)(*(double *)src), buf);
1014 d = malloc(len + 1);
1018 memcpy(d, buf, len + 1);
1019 *size_ret = len + 1;
1024 idx = eet_dictionary_string_add(ed, buf);
1028 return eet_data_put_int(ed, &idx, size_ret);
1029 } /* eet_data_put_double */
1032 eet_data_get_f32p32(const Eet_Dictionary *ed,
1034 const void *src_end,
1040 fp = (Eina_F32p32 *)dst;
1047 s = (const char *)src;
1050 while ((p < (const char *)src_end) && (*p != 0)) { len++; p++; }
1052 if (!(eina_convert_atofp(s, len, fp)))
1058 if (eet_data_get_int(ed, src, src_end, &idx) < 0)
1061 if (!eet_dictionary_string_get_fp(ed, idx, fp))
1065 } /* eet_data_get_f32p32 */
1068 eet_data_put_f32p32(Eet_Dictionary *ed,
1075 eina_convert_fptoa((Eina_F32p32)(*(Eina_F32p32 *)src), buf);
1083 d = malloc(len + 1);
1087 memcpy(d, buf, len + 1);
1088 *size_ret = len + 1;
1093 idx = eet_dictionary_string_add(ed, buf);
1097 return eet_data_put_int(ed, &idx, size_ret);
1098 } /* eet_data_put_f32p32 */
1101 eet_data_get_f16p16(const Eet_Dictionary *ed,
1103 const void *src_end,
1109 fp = (Eina_F16p16 *)dst;
1111 if (eet_data_get_f32p32(ed, src, src_end, &tmp) < 0)
1114 *fp = eina_f32p32_to_f16p16(tmp);
1116 } /* eet_data_get_f16p16 */
1119 eet_data_put_f16p16(Eet_Dictionary *ed,
1125 tmp = eina_f16p16_to_f32p32((Eina_F16p16)(*(Eina_F16p16 *)src));
1126 return eet_data_put_f32p32(ed, &tmp, size_ret);
1127 } /* eet_data_put_f16p16 */
1130 eet_data_get_f8p24(const Eet_Dictionary *ed,
1132 const void *src_end,
1138 fp = (Eina_F8p24 *)dst;
1140 if (eet_data_get_f32p32(ed, src, src_end, &tmp) < 0)
1143 *fp = eina_f32p32_to_f8p24(tmp);
1145 } /* eet_data_get_f8p24 */
1148 eet_data_put_f8p24(Eet_Dictionary *ed,
1154 tmp = eina_f8p24_to_f32p32((Eina_F8p24)(*(Eina_F8p24 *)src));
1155 return eet_data_put_f32p32(ed, &tmp, size_ret);
1156 } /* eet_data_put_f8p24 */
1159 eet_data_get_type(const Eet_Dictionary *ed,
1162 const void *src_end,
1167 ret = eet_basic_codec[type - 1].get(ed, src, src_end, dest);
1169 } /* eet_data_get_type */
1171 static inline void *
1172 eet_data_put_type(Eet_Dictionary *ed,
1179 ret = eet_basic_codec[type - 1].put(ed, src, size_ret);
1181 } /* eet_data_put_type */
1183 static inline Eina_Bool
1184 eet_data_type_match(int type1,
1190 /* Note: All floating point type are equivalent and could be read
1191 without problem by any other floating point getter. */
1218 } /* eet_data_type_match */
1222 * char[4] = "CHnK"; // untyped data ... or
1223 * char[4] = "CHKx"; // typed data - x == type
1225 * int = chunk size (including magic string);
1226 * char[] = chunk magic/name string (0 byte terminated);
1227 * ... sub-chunks (a chunk can contain chuncks recusrively) ...
1229 * ... payload data ...
1234 eet_data_chunk_get(const Eet_Dictionary *ed,
1235 Eet_Data_Chunk *chnk,
1254 if ((s[0] != 'C') || (s[1] != 'H') || (s[2] != 'K'))
1257 chnk->type = (unsigned char)(s[3]);
1258 if (chnk->type >= EET_I_LIMIT)
1261 ((chnk->type - EET_I_LIMIT) & 0xF) + EET_G_UNKNOWN;
1262 switch ((chnk->type - EET_I_LIMIT) & 0xF0)
1264 #define EET_UNMATCH_TYPE(Type)\
1265 case EET_I_ ## Type: chnk->type = EET_T_ ## Type; break;
1267 EET_UNMATCH_TYPE(STRING);
1268 EET_UNMATCH_TYPE(INLINED_STRING);
1269 EET_UNMATCH_TYPE(NULL);
1275 else if (chnk->type > EET_T_LAST)
1277 chnk->group_type = chnk->type;
1278 chnk->type = EET_T_UNKNOW;
1281 chnk->group_type = EET_G_UNKNOWN;
1282 if ((chnk->type >= EET_T_LAST) ||
1283 (chnk->group_type >=
1287 chnk->group_type = 0;
1290 else if ((s[0] != 'C') || (s[1] != 'H') || (s[2] != 'n') || (s[3] != 'K'))
1293 ret1 = eet_data_get_type(ed, EET_T_INT, (s + 4), (s + size), &(chnk->size));
1298 if ((chnk->size < 0) || ((chnk->size + 8) > size))
1301 ret2 = eet_data_get_type(ed, EET_T_STRING, (s + 8), (s + size), &(chnk->name));
1309 chnk->hash = eet_data_get_string_hash(ed, (s + 8), (s + size));
1313 chnk->data = (char *)src + 4 + ret1 + sizeof(int);
1314 chnk->size -= sizeof(int);
1318 chnk->data = (char *)src + 4 + ret1 + chnk->len;
1319 chnk->size -= chnk->len;
1323 } /* eet_data_chunk_get */
1325 static inline Eet_Data_Chunk *
1326 eet_data_chunk_new(void *data,
1332 Eet_Data_Chunk *chnk;
1337 chnk = calloc(1, sizeof(Eet_Data_Chunk));
1341 /* Note: Another security, so older eet library could read file
1342 saved with fixed point value. */
1343 if (type == EET_T_F32P32
1344 || type == EET_T_F16P16
1345 || type == EET_T_F8P24)
1346 type = EET_T_DOUBLE;
1348 chnk->name = strdup(name);
1349 chnk->len = strlen(name) + 1;
1353 chnk->group_type = group_type;
1355 } /* eet_data_chunk_new */
1358 eet_data_chunk_free(Eet_Data_Chunk *chnk)
1364 } /* eet_data_chunk_free */
1366 static inline Eet_Data_Stream *
1367 eet_data_stream_new(void)
1369 Eet_Data_Stream *ds;
1371 ds = calloc(1, sizeof(Eet_Data_Stream));
1376 } /* eet_data_stream_new */
1379 eet_data_stream_free(Eet_Data_Stream *ds)
1385 } /* eet_data_stream_free */
1388 eet_data_stream_flush(Eet_Data_Stream *ds)
1391 } /* eet_data_stream_flush */
1394 eet_data_stream_write(Eet_Data_Stream *ds,
1400 if ((ds->pos + size) > ds->size)
1402 ds->data = realloc(ds->data, ds->size + size + 512);
1410 ds->size = ds->size + size + 512;
1414 memcpy(p + ds->pos, data, size);
1416 } /* eet_data_stream_write */
1419 eet_data_chunk_put(Eet_Dictionary *ed,
1420 Eet_Data_Chunk *chnk,
1421 Eet_Data_Stream *ds)
1428 unsigned char buf[4] = "CHK";
1430 /* disable this check - it will allow empty chunks to be written. this is
1431 * right for corner-cases when y have a struct with empty fields (empty
1432 * strings or empty list ptrs etc.) */
1433 /* if (!chnk->data && chnk->type != EET_T_NULL) return; */
1436 /* eet_data_stream_write(ds, "CHnK", 4);*/
1437 if (chnk->type != EET_T_UNKNOW)
1439 if (chnk->group_type != EET_G_UNKNOWN)
1441 int type = EET_I_LIMIT + chnk->group_type - EET_G_UNKNOWN;
1445 /* Only make sense with pointer type. */
1446 #define EET_MATCH_TYPE(Type)\
1447 case EET_T_ ## Type: type += EET_I_ ## Type; break;
1449 EET_MATCH_TYPE(STRING);
1450 EET_MATCH_TYPE(INLINED_STRING);
1451 EET_MATCH_TYPE(NULL);
1460 buf[3] = chnk->type;
1463 buf[3] = chnk->group_type;
1465 string = eet_data_put_string(ed, &chnk->name, &string_ret);
1469 /* size of chunk payload data + name */
1470 s = chnk->size + string_ret;
1471 size = eet_data_put_int(ed, &s, &size_ret);
1473 /* FIXME: If something goes wrong the resulting file will be corrupted. */
1477 eet_data_stream_write(ds, buf, 4);
1479 /* write chunk length */
1480 eet_data_stream_write(ds, size, size_ret);
1482 /* write chunk name */
1483 eet_data_stream_write(ds, string, string_ret);
1487 eet_data_stream_write(ds, chnk->data, chnk->size);
1492 } /* eet_data_chunk_put */
1497 _eet_descriptor_hash_new(Eet_Data_Descriptor *edd)
1501 edd->elements.hash.size = 1 << 6;
1502 edd->elements.hash.buckets = calloc(
1504 sizeof(Eet_Data_Descriptor_Hash) *
1505 edd->elements.hash.size);
1506 for (i = 0; i < edd->elements.num; i++)
1508 Eet_Data_Element *ede;
1511 ede = &(edd->elements.set[i]);
1512 hash = _eet_hash_gen((char *)ede->name, 6);
1513 if (!edd->elements.hash.buckets[hash].element)
1514 edd->elements.hash.buckets[hash].element = ede;
1517 Eet_Data_Descriptor_Hash *bucket;
1519 bucket = calloc(1, sizeof(Eet_Data_Descriptor_Hash));
1520 bucket->element = ede;
1521 bucket->next = edd->elements.hash.buckets[hash].next;
1522 edd->elements.hash.buckets[hash].next = bucket;
1525 } /* _eet_descriptor_hash_new */
1528 _eet_descriptor_hash_free(Eet_Data_Descriptor *edd)
1532 for (i = 0; i < edd->elements.hash.size; i++)
1534 Eet_Data_Descriptor_Hash *bucket, *pbucket;
1536 bucket = edd->elements.hash.buckets[i].next;
1540 bucket = bucket->next;
1544 if (edd->elements.hash.buckets)
1545 free(edd->elements.hash.buckets);
1546 } /* _eet_descriptor_hash_free */
1548 static Eet_Data_Element *
1549 _eet_descriptor_hash_find(Eet_Data_Descriptor *edd,
1553 Eet_Data_Descriptor_Hash *bucket;
1556 hash = _eet_hash_gen(name, 6);
1560 if (!edd->elements.hash.buckets[hash].element)
1562 When we use the dictionnary as a source for chunk name, we will always
1563 have the same pointer in name. It's a good idea to just compare pointer
1564 instead of running strcmp on both string.
1567 if (edd->elements.hash.buckets[hash].element->directory_name_ptr == name)
1568 return edd->elements.hash.buckets[hash].element;
1570 if (!strcmp(edd->elements.hash.buckets[hash].element->name, name))
1572 edd->elements.hash.buckets[hash].element->directory_name_ptr = name;
1573 return edd->elements.hash.buckets[hash].element;
1576 bucket = edd->elements.hash.buckets[hash].next;
1579 if (bucket->element->directory_name_ptr == name)
1580 return bucket->element;
1582 if (!strcmp(bucket->element->name, name))
1584 bucket->element->directory_name_ptr = name;
1585 return bucket->element;
1588 bucket = bucket->next;
1591 } /* _eet_descriptor_hash_find */
1594 _eet_mem_alloc(size_t size)
1596 return calloc(1, size);
1597 } /* _eet_mem_alloc */
1600 _eet_mem_free(void *mem)
1603 } /* _eet_mem_free */
1606 _eet_str_alloc(const char *str)
1609 } /* _eet_str_alloc */
1612 _eet_str_free(const char *str)
1615 } /* _eet_str_free */
1618 _eet_eina_hash_add_alloc(Eina_Hash *hash,
1623 hash = eina_hash_string_small_new(NULL);
1628 eina_hash_add(hash, key, data);
1630 } /* _eet_eina_hash_add_alloc */
1633 _eet_eina_hash_direct_add_alloc(Eina_Hash *hash,
1638 hash = eina_hash_string_small_new(NULL);
1643 eina_hash_direct_add(hash, key, data);
1645 } /* _eet_eina_hash_direct_add_alloc */
1648 _eet_str_direct_alloc(const char *str)
1651 } /* _eet_str_direct_alloc */
1654 _eet_str_direct_free(const char *str __UNUSED__)
1656 } /* _eet_str_direct_free */
1659 _eet_eina_hash_foreach(void *hash,
1660 Eina_Hash_Foreach cb,
1664 eina_hash_foreach(hash, cb, fdata);
1665 } /* _eet_eina_hash_foreach */
1668 _eet_eina_hash_free(void *hash)
1671 eina_hash_free(hash);
1672 } /* _eet_eina_hash_free */
1676 eet_eina_stream_data_descriptor_class_set(Eet_Data_Descriptor_Class *eddc,
1687 eddc->func.mem_alloc = _eet_mem_alloc;
1688 eddc->func.mem_free = _eet_mem_free;
1689 eddc->func.str_alloc = (char *(*)(const char *))eina_stringshare_add;
1690 eddc->func.str_free = eina_stringshare_del;
1691 eddc->func.list_next = (void *(*)(void *))eina_list_next;
1692 eddc->func.list_append = (void *(*)(void *, void *))eina_list_append;
1693 eddc->func.list_data = (void *(*)(void *))eina_list_data_get;
1694 eddc->func.list_free = (void *(*)(void *))eina_list_free;
1695 eddc->func.hash_foreach = (void (*)(void *, int (*)(void *, const char *, void *, void *), void *))_eet_eina_hash_foreach;
1696 eddc->func.hash_add = (void * (*)(void *, const char *, void *))_eet_eina_hash_add_alloc;
1697 eddc->func.hash_free = (void (*)(void *))_eet_eina_hash_free;
1700 } /* eet_eina_stream_data_descriptor_class_set */
1703 eet_eina_file_data_descriptor_class_set(Eet_Data_Descriptor_Class *eddc,
1707 if (!eet_eina_stream_data_descriptor_class_set(eddc, name, size))
1712 eddc->func.hash_add = (void * (*)(void *, const char *, void *))_eet_eina_hash_direct_add_alloc;
1713 eddc->func.str_direct_alloc = _eet_str_direct_alloc;
1714 eddc->func.str_direct_free = _eet_str_direct_free;
1717 } /* eet_eina_file_data_descriptor_class_set */
1719 static Eet_Data_Descriptor *
1720 _eet_data_descriptor_new(const Eet_Data_Descriptor_Class *eddc,
1723 Eet_Data_Descriptor *edd;
1728 edd = calloc(1, sizeof (Eet_Data_Descriptor));
1732 edd->name = eddc->name;
1734 edd->size = eddc->size;
1735 edd->func.mem_alloc = _eet_mem_alloc;
1736 edd->func.mem_free = _eet_mem_free;
1737 edd->func.str_alloc = _eet_str_alloc;
1738 edd->func.str_free = _eet_str_free;
1739 if (eddc->func.mem_alloc)
1740 edd->func.mem_alloc = eddc->func.mem_alloc;
1742 if (eddc->func.mem_free)
1743 edd->func.mem_free = eddc->func.mem_free;
1745 if (eddc->func.str_alloc)
1746 edd->func.str_alloc = eddc->func.str_alloc;
1748 if (eddc->func.str_free)
1749 edd->func.str_free = eddc->func.str_free;
1751 edd->func.list_next = eddc->func.list_next;
1752 edd->func.list_append = eddc->func.list_append;
1753 edd->func.list_data = eddc->func.list_data;
1754 edd->func.list_free = eddc->func.list_free;
1755 edd->func.hash_foreach = eddc->func.hash_foreach;
1756 edd->func.hash_add = eddc->func.hash_add;
1757 edd->func.hash_free = eddc->func.hash_free;
1759 if (eddc->version > 1 && version > 1)
1761 edd->func.str_direct_alloc = eddc->func.str_direct_alloc;
1762 edd->func.str_direct_free = eddc->func.str_direct_free;
1765 if (eddc->version > 2)
1767 edd->func.type_get = eddc->func.type_get;
1768 edd->func.type_set = eddc->func.type_set;
1772 } /* _eet_data_descriptor_new */
1774 EAPI Eet_Data_Descriptor *
1775 eet_data_descriptor_new(const char *name,
1777 void *(*func_list_next)(void *l),
1778 void *(*func_list_append)(void *l, void *d),
1779 void *(*func_list_data)(void *l),
1780 void *(*func_list_free)(void *l),
1781 void (*func_hash_foreach)(void *h, int (*func)(void *h, const char *k, void *dt, void *fdt), void *fdt),
1782 void *(*func_hash_add)(void *h, const char *k, void *d),
1783 void (*func_hash_free)(void *h))
1785 Eet_Data_Descriptor_Class eddc;
1790 memset(&eddc, 0, sizeof (Eet_Data_Descriptor_Class));
1796 eddc.func.list_next = func_list_next;
1797 eddc.func.list_append = func_list_append;
1798 eddc.func.list_data = func_list_data;
1799 eddc.func.list_free = func_list_free;
1800 eddc.func.hash_foreach = func_hash_foreach;
1801 eddc.func.hash_add = func_hash_add;
1802 eddc.func.hash_free = func_hash_free;
1804 return _eet_data_descriptor_new(&eddc, 0);
1805 } /* eet_data_descriptor_new */
1807 EAPI Eet_Data_Descriptor *
1808 eet_data_descriptor2_new(const Eet_Data_Descriptor_Class *eddc)
1810 return _eet_data_descriptor_new(eddc, 1);
1811 } /* eet_data_descriptor2_new */
1813 EAPI Eet_Data_Descriptor *
1814 eet_data_descriptor3_new(const Eet_Data_Descriptor_Class *eddc)
1816 return _eet_data_descriptor_new(eddc, 2);
1817 } /* eet_data_descriptor3_new */
1819 EAPI Eet_Data_Descriptor *
1820 eet_data_descriptor_stream_new(const Eet_Data_Descriptor_Class *eddc)
1822 return _eet_data_descriptor_new(eddc, 1);
1823 } /* eet_data_descriptor_stream_new */
1825 EAPI Eet_Data_Descriptor *
1826 eet_data_descriptor_file_new(const Eet_Data_Descriptor_Class *eddc)
1828 return _eet_data_descriptor_new(eddc, 2);
1829 } /* eet_data_descriptor_file_new */
1832 eet_data_descriptor_free(Eet_Data_Descriptor *edd)
1837 _eet_descriptor_hash_free(edd);
1838 if (edd->elements.set)
1839 free(edd->elements.set);
1842 } /* eet_data_descriptor_free */
1845 eet_data_descriptor_element_add(Eet_Data_Descriptor *edd,
1851 /* int counter_offset, */
1852 const char *counter_name /* FIXME: Useless should go on a major release */,
1853 Eet_Data_Descriptor *subtype)
1855 Eet_Data_Element *ede;
1856 Eet_Data_Element *tmp;
1858 /* UNION, VARIANT type would not work with simple type, we need a way to map the type. */
1859 if ((group_type == EET_G_UNION
1860 || group_type == EET_G_VARIANT)
1862 (type != EET_T_UNKNOW
1864 || subtype->func.type_get == NULL
1865 || subtype->func.type_set == NULL))
1868 /* VARIANT type will only work if the map only contains EET_G_*, but not UNION, VARIANT and ARRAY. */
1869 if (group_type == EET_G_VARIANT)
1873 for (i = 0; i < subtype->elements.num; ++i)
1874 if (subtype->elements.set[i].type != EET_T_UNKNOW
1875 && subtype->elements.set[i].group_type > EET_G_VAR_ARRAY
1876 && subtype->elements.set[i].group_type < EET_G_UNION)
1879 subtype->unified_type = EINA_TRUE;
1883 && subtype->unified_type
1884 && (type != EET_T_UNKNOW
1885 || group_type < EET_G_UNION))
1888 /* Sanity check done, let allocate ! */
1889 edd->elements.num++;
1890 tmp = realloc(edd->elements.set, edd->elements.num * sizeof(Eet_Data_Element));
1894 edd->elements.set = tmp;
1895 ede = &(edd->elements.set[edd->elements.num - 1]);
1897 ede->directory_name_ptr = NULL;
1900 * We do a special case when we do list,hash or whatever group of simple type.
1901 * Instead of handling it in encode/decode/dump/undump, we create an
1902 * implicit structure with only the simple type.
1904 if ((group_type > EET_G_UNKNOWN)
1905 && (group_type < EET_G_LAST)
1906 && (((type > EET_T_UNKNOW) && (type < EET_T_STRING))
1907 || ((type > EET_T_NULL) && (type < EET_T_LAST)))
1908 && (subtype == NULL))
1910 subtype = calloc(1, sizeof (Eet_Data_Descriptor));
1914 subtype->name = "implicit";
1915 subtype->size = eet_basic_codec[type - 1].size;
1916 memcpy(&subtype->func, &edd->func, sizeof(subtype->func));
1918 eet_data_descriptor_element_add(subtype,
1919 eet_basic_codec[type - 1].name,
1926 type = EET_T_UNKNOW;
1930 ede->group_type = group_type;
1931 ede->offset = offset;
1933 /* FIXME: For the time being, VAR_ARRAY, UNION and VARIANT will put the counter_offset in count. */
1934 ede->counter_offset = count;
1935 /* ede->counter_offset = counter_offset; */
1936 ede->counter_name = counter_name;
1938 ede->subtype = subtype;
1939 } /* eet_data_descriptor_element_add */
1942 eet_data_read_cipher(Eet_File *ef,
1943 Eet_Data_Descriptor *edd,
1945 const char *cipher_key)
1947 const Eet_Dictionary *ed = NULL;
1948 const void *data = NULL;
1950 Eet_Free_Context context;
1951 int required_free = 0;
1954 ed = eet_dictionary_get(ef);
1957 data = eet_read_direct(ef, name, &size);
1962 data = eet_read_cipher(ef, name, &size, cipher_key);
1967 memset(&context, 0, sizeof (context));
1968 data_dec = _eet_data_descriptor_decode(&context, ed, edd, data, size);
1973 } /* eet_data_read_cipher */
1976 eet_data_node_read_cipher(Eet_File *ef,
1978 const char *cipher_key)
1980 const Eet_Dictionary *ed = NULL;
1981 const void *data = NULL;
1983 Eet_Free_Context context;
1984 int required_free = 0;
1987 ed = eet_dictionary_get(ef);
1990 data = eet_read_direct(ef, name, &size);
1995 data = eet_read_cipher(ef, name, &size, cipher_key);
2000 memset(&context, 0, sizeof (context));
2001 result = _eet_data_descriptor_decode(&context, ed, NULL, data, size);
2006 } /* eet_data_node_read_cipher */
2009 eet_data_read(Eet_File *ef,
2010 Eet_Data_Descriptor *edd,
2013 return eet_data_read_cipher(ef, edd, name, NULL);
2014 } /* eet_data_read */
2017 eet_data_write_cipher(Eet_File *ef,
2018 Eet_Data_Descriptor *edd,
2020 const char *cipher_key,
2029 ed = eet_dictionary_get(ef);
2031 data_enc = _eet_data_descriptor_encode(ed, edd, data, &size);
2035 val = eet_write_cipher(ef, name, data_enc, size, compress, cipher_key);
2038 } /* eet_data_write_cipher */
2041 eet_data_write(Eet_File *ef,
2042 Eet_Data_Descriptor *edd,
2047 return eet_data_write_cipher(ef, edd, name, NULL, data, compress);
2048 } /* eet_data_write */
2051 _eet_free_hash(void *data)
2054 __int64 ptr = (UINT_PTR)data;
2055 #else /* ifdef _WIN64 */
2056 unsigned long ptr = (unsigned long)(data);
2057 #endif /* ifdef _WIN64 */
2065 #if defined (_WIN64) || ((!defined (_WIN32)) && (LONG_BIT != 32))
2070 #endif /* if defined (_WIN64) || ((!defined (_WIN32)) && (LONG_BIT != 32)) */
2073 } /* _eet_free_hash */
2076 _eet_free_add(Eet_Free *ef,
2082 hash = _eet_free_hash(data);
2084 for (i = 0; i < ef->num[hash]; ++i)
2085 if (ef->list[hash][i] == data)
2089 if (ef->num[hash] > ef->len[hash])
2093 tmp = realloc(ef->list[hash], (ef->len[hash] + 16) * sizeof(void *));
2097 ef->len[hash] += 16;
2098 ef->list[hash] = tmp;
2101 ef->list[hash][ef->num[hash] - 1] = data;
2102 } /* _eet_free_add */
2105 _eet_free_reset(Eet_Free *ef)
2112 for (i = 0; i < 256; ++i)
2121 } /* _eet_free_reset */
2124 _eet_free_ref(Eet_Free *ef)
2127 } /* _eet_free_ref */
2130 _eet_free_unref(Eet_Free *ef)
2133 } /* _eet_free_unref */
2135 #define _eet_freelist_add(Ctx, Data) _eet_free_add(&Ctx->freelist, Data);
2136 #define _eet_freelist_reset(Ctx) _eet_free_reset(&Ctx->freelist);
2137 #define _eet_freelist_ref(Ctx) _eet_free_ref(&Ctx->freelist);
2138 #define _eet_freelist_unref(Ctx) _eet_free_unref(&Ctx->freelist);
2141 _eet_freelist_free(Eet_Free_Context *context,
2142 Eet_Data_Descriptor *edd)
2147 if (context->freelist.ref > 0)
2150 for (j = 0; j < 256; ++j)
2151 for (i = 0; i < context->freelist.num[j]; ++i)
2154 edd->func.mem_free(context->freelist.list[j][i]);
2156 free(context->freelist.list[j][i]);
2158 _eet_free_reset(&context->freelist);
2159 } /* _eet_freelist_free */
2161 #define _eet_freelist_list_add(Ctx, Data) _eet_free_add(&Ctx->freelist_list, Data);
2162 #define _eet_freelist_list_reset(Ctx) _eet_free_reset(&Ctx->freelist_list);
2163 #define _eet_freelist_list_ref(Ctx) _eet_free_ref(&Ctx->freelist_list);
2164 #define _eet_freelist_list_unref(Ctx) _eet_free_unref(&Ctx->freelist_list);
2167 _eet_freelist_list_free(Eet_Free_Context *context,
2168 Eet_Data_Descriptor *edd)
2173 if (context->freelist_list.ref > 0)
2176 for (j = 0; j < 256; ++j)
2177 for (i = 0; i < context->freelist_list.num[j]; ++i)
2180 edd->func.list_free(*((void **)(context->freelist_list.list[j][i])));
2182 _eet_free_reset(&context->freelist_list);
2183 } /* _eet_freelist_list_free */
2185 #define _eet_freelist_str_add(Ctx, Data) _eet_free_add(&Ctx->freelist_str, Data);
2186 #define _eet_freelist_str_reset(Ctx) _eet_free_reset(&Ctx->freelist_str);
2187 #define _eet_freelist_str_ref(Ctx) _eet_free_ref(&Ctx->freelist_str);
2188 #define _eet_freelist_str_unref(Ctx) _eet_free_unref(&Ctx->freelist_str);
2191 _eet_freelist_str_free(Eet_Free_Context *context, Eet_Data_Descriptor *edd)
2196 if (context->freelist_str.ref > 0)
2199 for (j = 0; j < 256; ++j)
2200 for (i = 0; i < context->freelist_str.num[j]; ++i)
2203 edd->func.str_free(context->freelist_str.list[j][i]);
2205 free(context->freelist_str.list[j][i]);
2207 _eet_free_reset(&context->freelist_str);
2208 } /* _eet_freelist_str_free */
2210 #define _eet_freelist_direct_str_add(Ctx, Data) _eet_free_add(&Ctx->freelist_direct_str, Data);
2211 #define _eet_freelist_direct_str_reset(Ctx) _eet_free_reset(&Ctx->freelist_direct_str);
2212 #define _eet_freelist_direct_str_ref(Ctx) _eet_free_ref(&Ctx->freelist_direct_str);
2213 #define _eet_freelist_direct_str_unref(Ctx) _eet_free_unref(&Ctx->freelist_direct_str);
2216 _eet_freelist_direct_str_free(Eet_Free_Context *context,
2217 Eet_Data_Descriptor *edd)
2222 if (context->freelist_direct_str.ref > 0)
2225 for (j = 0; j < 256; ++j)
2226 for (i = 0; i < context->freelist_direct_str.num[j]; ++i)
2229 edd->func.str_direct_free(context->freelist_direct_str.list[j][i]);
2231 free(context->freelist_direct_str.list[j][i]);
2233 _eet_free_reset(&context->freelist_direct_str);
2234 } /* _eet_freelist_direct_str_free */
2236 #define _eet_freelist_hash_add(Ctx, Data) _eet_free_add(&Ctx->freelist_hash, Data);
2237 #define _eet_freelist_hash_reset(Ctx) _eet_free_reset(&Ctx->freelist_hash);
2238 #define _eet_freelist_hash_ref(Ctx) _eet_free_ref(&Ctx->freelist_hash);
2239 #define _eet_freelist_hash_unref(Ctx) _eet_free_unref(&Ctx->freelist_hash);
2242 _eet_freelist_hash_free(Eet_Free_Context *context,
2243 Eet_Data_Descriptor *edd)
2248 if (context->freelist_hash.ref > 0)
2251 for (j = 0; j < 256; ++j)
2252 for (i = 0; i < context->freelist_hash.num[j]; ++i)
2255 edd->func.hash_free(context->freelist_hash.list[j][i]);
2257 free(context->freelist_hash.list[j][i]);
2259 _eet_free_reset(&context->freelist_hash);
2260 } /* _eet_freelist_hash_free */
2263 _eet_freelist_all_ref(Eet_Free_Context *freelist_context)
2265 _eet_freelist_ref(freelist_context);
2266 _eet_freelist_str_ref(freelist_context);
2267 _eet_freelist_list_ref(freelist_context);
2268 _eet_freelist_hash_ref(freelist_context);
2269 _eet_freelist_direct_str_ref(freelist_context);
2270 } /* _eet_freelist_all_ref */
2273 _eet_freelist_all_unref(Eet_Free_Context *freelist_context)
2275 _eet_freelist_unref(freelist_context);
2276 _eet_freelist_str_unref(freelist_context);
2277 _eet_freelist_list_unref(freelist_context);
2278 _eet_freelist_hash_unref(freelist_context);
2279 _eet_freelist_direct_str_unref(freelist_context);
2280 } /* _eet_freelist_all_unref */
2283 eet_data_descriptor_encode_hash_cb(void *hash __UNUSED__,
2284 const char *cipher_key,
2289 Eet_Data_Encode_Hash_Info *edehi;
2290 Eet_Data_Stream *ds;
2291 Eet_Data_Element *ede;
2292 Eet_Data_Chunk *echnk;
2302 data = eet_data_put_type(ed,
2308 echnk = eet_data_chunk_new(data,
2313 eet_data_chunk_put(ed, echnk, ds);
2314 eet_data_chunk_free(echnk);
2319 EET_ASSERT(!((ede->type > EET_T_UNKNOW) && (ede->type < EET_T_STRING)), return );
2322 if (ede->type >= EET_T_STRING)
2323 eet_data_put_unknown(ed, NULL, ede, ds, &hdata);
2327 data = _eet_data_descriptor_encode(ed,
2334 echnk = eet_data_chunk_new(data,
2339 eet_data_chunk_put(ed, echnk, ds);
2340 eet_data_chunk_free(echnk);
2347 } /* eet_data_descriptor_encode_hash_cb */
2350 _eet_data_dump_token_get(const char *src,
2357 int tlen = 0, tsize = 0;
2365 tok = realloc(tok, tsize);\
2370 for (p = src; *len > 0; p++, (*len)--)
2376 if ((p[0] == '\"') && (p > src) && (p[-1] != '\\'))
2378 else if ((p[0] == '\\') && (*len > 1) &&
2383 else if ((p[0] == '\\') && (p > src) && (p[-1] == '\\'))
2387 else if ((p[0] == '\\') && (*len > 1) && (p[1] == 'n'))
2391 else if ((p[0] == 'n') && (p > src) && (p[-1] == '\\'))
2402 if ((isspace(p[0])) || (p[0] == ';')) /* token ends here */
2413 else if (!((isspace(p[0])) || (p[0] == ';')))
2430 } /* _eet_data_dump_token_get */
2433 eet_data_encode(Eet_Dictionary *ed,
2434 Eet_Data_Stream *ds,
2441 Eet_Data_Chunk *echnk;
2446 if (group_type != EET_G_UNKNOWN)
2447 if (type >= EET_T_LAST)
2448 type = EET_T_UNKNOW;
2450 echnk = eet_data_chunk_new(data, size, name, type, group_type);
2451 eet_data_chunk_put(ed, echnk, ds);
2452 eet_data_chunk_free(echnk);
2454 } /* eet_data_encode */
2457 _eet_data_dump_encode(int parent_type,
2462 Eet_Data_Chunk *chnk = NULL;
2463 Eet_Data_Stream *ds;
2470 if (_eet_data_words_bigendian == -1)
2472 unsigned long int v;
2474 v = htonl(0x12345678);
2475 if (v == 0x12345678)
2476 _eet_data_words_bigendian = 1;
2478 _eet_data_words_bigendian = 0;
2484 ds = eet_data_stream_new();
2491 for (n = node->values; n; n = n->next)
2493 data = _eet_data_dump_encode(node->type, ed, n, &size);
2496 eet_data_stream_write(ds, data, size);
2503 case EET_G_VAR_ARRAY:
2504 for (child_type = EET_T_NULL, n = node->values; n; n = n->next)
2506 if (n->type != EET_T_NULL)
2508 child_type = n->type;
2513 data = eet_data_put_type(ed,
2525 count = node->count;
2527 for (n = node->values; n; n = n->next)
2534 case EET_T_INLINED_STRING:
2535 data = eet_data_put_type(ed,
2537 &(n->data.value.str),
2554 data = _eet_data_dump_encode(n->type, ed, n, &size);
2568 for (; count; count--)
2579 /* Array is somekind of special case, so we should embed it inside another chunk. */
2580 *size_ret = ds->pos;
2585 eet_data_stream_free(ds);
2591 for (n = node->values; n; n = n->next)
2596 case EET_T_INLINED_STRING:
2597 data = eet_data_put_type(ed,
2599 &(n->data.value.str),
2616 data = _eet_data_dump_encode(node->type, ed, n, &size);
2627 /* List is another somekind of special case, every chunk is embed inside a list chunk. */
2628 *size_ret = ds->pos;
2633 eet_data_stream_free(ds);
2641 data = eet_data_put_type(ed,
2654 /* A Hash without key will not decode correctly. */
2657 for (n = node->values; n; n = n->next)
2662 case EET_T_INLINED_STRING:
2663 data = eet_data_put_type(ed,
2665 &(n->data.value.str),
2682 data = _eet_data_dump_encode(node->type, ed, n, &size);
2693 /* Hash is somekind of special case, so we should embed it inside another chunk. */
2694 *size_ret = ds->pos;
2697 eet_data_stream_flush(ds);
2704 #define EET_DATA_NODE_ENCODE(Eet_Type, Type)\
2706 data = eet_data_put_type(ed, node->type, &(node->data.value.Type), &size);\
2709 eet_data_encode(ed,\
2717 *size_ret = ds->pos;\
2718 eet_data_stream_flush(ds);\
2723 EET_DATA_NODE_ENCODE(EET_T_CHAR, c);
2724 EET_DATA_NODE_ENCODE(EET_T_SHORT, s);
2725 EET_DATA_NODE_ENCODE(EET_T_INT, i);
2726 EET_DATA_NODE_ENCODE(EET_T_LONG_LONG, l);
2727 EET_DATA_NODE_ENCODE(EET_T_FLOAT, f);
2728 EET_DATA_NODE_ENCODE(EET_T_DOUBLE, d);
2729 EET_DATA_NODE_ENCODE(EET_T_UCHAR, uc);
2730 EET_DATA_NODE_ENCODE(EET_T_USHORT, us);
2731 EET_DATA_NODE_ENCODE(EET_T_UINT, ui);
2732 EET_DATA_NODE_ENCODE(EET_T_ULONG_LONG, ul);
2733 EET_DATA_NODE_ENCODE(EET_T_INLINED_STRING, str);
2734 EET_DATA_NODE_ENCODE(EET_T_STRING, str);
2740 if ((node->type >= EET_G_UNKNOWN) && (node->type < EET_G_LAST))
2741 chnk = eet_data_chunk_new(ds->data,
2747 chnk = eet_data_chunk_new(ds->data,
2753 eet_data_stream_flush(ds);
2755 ds = eet_data_stream_new();
2756 eet_data_chunk_put(ed, chnk, ds);
2760 eet_data_stream_flush(ds);
2764 eet_data_chunk_free(chnk);
2767 } /* _eet_data_dump_encode */
2770 _eet_data_dump_parse(Eet_Dictionary *ed,
2776 const char *p = NULL;
2781 Eet_Node *node_base = NULL;
2782 Eet_Node *node = NULL;
2783 Eet_Node *n = NULL, *nn = NULL;
2785 /* FIXME; handle parse errors */
2787 jump = left; t = _eet_data_dump_token_get(p, &left); p += jump - left;
2789 for (p = src; p < (src + size); )
2791 char *tok1, *tok2, *tok3, *tok4;
2796 if (!strcmp(tok1, "group"))
2807 if (!strcmp(tok4, "{"))
2809 /* we have 'group NAM TYP {' */
2823 for (nn = node->values; nn;
2834 n->name = eina_stringshare_add(tok2);
2835 if (!strcmp(tok3, "struct"))
2836 n->type = EET_G_UNKNOWN;
2837 else if (!strcmp(tok3, "array"))
2838 n->type = EET_G_ARRAY;
2839 else if (!strcmp(tok3, "var_array"))
2840 n->type = EET_G_VAR_ARRAY;
2841 else if (!strcmp(tok3, "list"))
2842 n->type = EET_G_LIST;
2843 else if (!strcmp(tok3, "hash"))
2844 n->type = EET_G_HASH;
2847 "ERROR: group type '%s' invalid.",
2863 else if (!strcmp(tok1, "value"))
2874 /* we have 'value NAME TYP XXX' */
2885 for (nn = node->values; nn;
2895 n->name = eina_stringshare_add(tok2);
2896 if (!strcmp(tok3, "char:"))
2898 n->type = EET_T_CHAR;
2899 sscanf(tok4, "%hhi",
2900 &(n->data.value.c));
2902 else if (!strcmp(tok3, "short:"))
2904 n->type = EET_T_SHORT;
2906 &(n->data.value.s));
2908 else if (!strcmp(tok3, "int:"))
2910 n->type = EET_T_INT;
2912 &(n->data.value.i));
2914 else if (!strcmp(tok3, "long_long:"))
2916 n->type = EET_T_LONG_LONG;
2917 sscanf(tok4, "%lli",
2918 &(n->data.value.l));
2920 else if (!strcmp(tok3, "float:"))
2922 n->type = EET_T_FLOAT;
2924 &(n->data.value.f));
2926 else if (!strcmp(tok3, "double:"))
2928 n->type = EET_T_DOUBLE;
2930 &(n->data.value.d));
2932 else if (!strcmp(tok3, "uchar:"))
2934 n->type = EET_T_UCHAR;
2935 sscanf(tok4, "%hhu",
2936 &(n->data.value.uc));
2938 else if (!strcmp(tok3, "ushort:"))
2940 n->type = EET_T_USHORT;
2942 &(n->data.value.us));
2944 else if (!strcmp(tok3, "uint:"))
2946 n->type = EET_T_UINT;
2948 &(n->data.value.ui));
2950 else if (!strcmp(tok3, "ulong_long:"))
2952 n->type = EET_T_ULONG_LONG;
2953 sscanf(tok4, "%llu",
2954 &(n->data.value.ul));
2956 else if (!strcmp(tok3, "string:"))
2958 n->type = EET_T_STRING;
2960 eina_stringshare_add(tok4);
2962 else if (!strcmp(tok3, "inlined:"))
2964 n->type = EET_T_INLINED_STRING;
2966 eina_stringshare_add(tok4);
2968 else if (!strcmp(tok3, "null"))
2970 n->type = EET_T_NULL;
2971 n->data.value.str = NULL;
2975 "ERROR: value type '%s' invalid.",
2989 else if (!strcmp(tok1, "key"))
2994 /* we have 'key NAME' */
2996 node->key = eina_stringshare_add(tok2);
3001 else if (!strcmp(tok1, "count"))
3006 /* we have a 'count COUNT' */
3008 sscanf(tok2, "%i", &(node->count));
3013 else if (!strcmp(tok1, "}"))
3014 /* we have an end of the group */
3016 node = node->parent;
3024 cdata = _eet_data_dump_encode(EET_G_UNKNOWN, ed, node_base, size_ret);
3025 eet_node_del(node_base);
3029 } /* _eet_data_dump_parse */
3031 #define NEXT_CHUNK(P, Size, Echnk, Ed)\
3034 tmp = Ed ? (int)(sizeof(int) * 2) : Echnk.len + 4;\
3035 P += (4 + Echnk.size + tmp);\
3036 Size -= (4 + Echnk.size + tmp);\
3040 _eet_data_descriptor_decode(Eet_Free_Context *context,
3041 const Eet_Dictionary *ed,
3042 Eet_Data_Descriptor *edd,
3043 const void *data_in,
3046 Eet_Node *result = NULL;
3050 Eet_Data_Chunk chnk;
3052 if (_eet_data_words_bigendian == -1)
3054 unsigned long int v;
3056 v = htonl(0x12345678);
3057 if (v == 0x12345678)
3058 _eet_data_words_bigendian = 1;
3060 _eet_data_words_bigendian = 0;
3065 data = edd->func.mem_alloc(edd->size);
3071 for (i = 0; i < edd->elements.num; i++)
3072 edd->elements.set[i].directory_name_ptr = NULL;
3077 _eet_freelist_all_ref(context);
3079 _eet_freelist_add(context, data);
3081 memset(&chnk, 0, sizeof(Eet_Data_Chunk));
3082 eet_data_chunk_get(ed, &chnk, data_in, size_in);
3087 if (strcmp(chnk.name, edd->name))
3092 size = size_in - (4 + sizeof(int) * 2);
3094 size = size_in - (4 + 4 + chnk.len);
3098 if (!edd->elements.hash.buckets)
3099 _eet_descriptor_hash_new(edd);
3103 switch (chnk.group_type)
3109 return eet_node_string_new(chnk.name, chnk.data);
3111 case EET_T_INLINED_STRING:
3112 return eet_node_inlined_string_new(chnk.name, chnk.data);
3115 return eet_node_null_new(chnk.name);
3118 result = eet_node_struct_new(chnk.name, NULL);
3122 case EET_G_VAR_ARRAY:
3123 return eet_node_var_array_new(chnk.name, NULL);
3137 Eet_Data_Chunk echnk;
3138 Eet_Data_Element *ede = NULL;
3139 Eet_Node *child = NULL;
3140 int group_type = EET_G_UNKNOWN, type = EET_T_UNKNOW;
3143 /* get next data chunk */
3144 memset(&echnk, 0, sizeof(Eet_Data_Chunk));
3145 eet_data_chunk_get(ed, &echnk, p, size);
3147 goto error; /* FIXME: don't REPLY on edd - work without */
3151 ede = _eet_descriptor_hash_find(edd, echnk.name, echnk.hash);
3154 group_type = ede->group_type;
3156 if ((echnk.type == 0) && (echnk.group_type == 0))
3159 group_type = ede->group_type;
3163 if (IS_SIMPLE_TYPE(echnk.type) &&
3164 eet_data_type_match(echnk.type, ede->type))
3165 /* Needed when converting on the fly from FP to Float */
3167 else if ((echnk.group_type > EET_G_UNKNOWN) &&
3168 (echnk.group_type < EET_G_LAST) &&
3169 (echnk.group_type == ede->group_type))
3170 group_type = echnk.group_type;
3174 /*...... dump to node */
3178 group_type = echnk.group_type;
3181 if (!edd && group_type == EET_G_UNKNOWN && IS_SIMPLE_TYPE(type))
3183 unsigned char dd[128];
3185 ret = eet_data_get_type(ed,
3188 ((char *)echnk.data) + echnk.size,
3193 child = eet_data_node_simple_type(type, echnk.name, dd);
3195 eet_node_struct_append(result, echnk.name, child);
3199 ret = eet_group_codec[group_type - 100].get(
3207 ede ? (void *)(((char
3220 /* advance to next chunk */
3221 NEXT_CHUNK(p, size, echnk, ed);
3224 _eet_freelist_all_unref(context);
3227 _eet_freelist_str_free(context, edd);
3228 _eet_freelist_direct_str_free(context, edd);
3229 _eet_freelist_list_free(context, edd);
3230 _eet_freelist_hash_free(context, edd);
3231 _eet_freelist_free(context, edd);
3235 _eet_freelist_reset(context);
3236 _eet_freelist_str_reset(context);
3237 _eet_freelist_list_reset(context);
3238 _eet_freelist_hash_reset(context);
3239 _eet_freelist_direct_str_reset(context);
3248 eet_node_del(result);
3250 _eet_freelist_all_unref(context);
3251 _eet_freelist_str_free(context, edd);
3252 _eet_freelist_direct_str_free(context, edd);
3253 _eet_freelist_list_free(context, edd);
3254 _eet_freelist_hash_free(context, edd);
3255 _eet_freelist_free(context, edd);
3257 /* FIXME: Warn that something goes wrong here. */
3259 } /* _eet_data_descriptor_decode */
3262 eet_data_get_list(Eet_Free_Context *context,
3263 const Eet_Dictionary *ed,
3264 Eet_Data_Descriptor *edd,
3265 Eet_Data_Element *ede,
3266 Eet_Data_Chunk *echnk,
3268 int group_type __UNUSED__,
3273 Eet_Data_Descriptor *subtype = NULL;
3278 EET_ASSERT(!((type > EET_T_UNKNOW) && (type < EET_T_STRING)), return 0);
3282 subtype = ede->subtype;
3284 if (type != ede->type)
3288 ptr = (void **)data;
3292 if (IS_POINTER_TYPE(type))
3293 POINTER_TYPE_DECODE(context,
3304 STRUCT_TYPE_DECODE(data_ret,
3314 list = edd->func.list_append(list, data_ret);
3316 _eet_freelist_list_add(context, ptr);
3319 eet_node_list_append(*((Eet_Node **)data), echnk->name, data_ret);
3325 } /* eet_data_get_list */
3328 eet_data_get_hash(Eet_Free_Context *context,
3329 const Eet_Dictionary *ed,
3330 Eet_Data_Descriptor *edd,
3331 Eet_Data_Element *ede,
3332 Eet_Data_Chunk *echnk,
3334 int group_type __UNUSED__,
3342 void *data_ret = NULL;
3345 EET_ASSERT(!((type > EET_T_UNKNOW) && (type < EET_T_STRING)), return 0);
3347 ptr = (void **)data;
3351 ret = eet_data_get_type(ed,
3354 ((char *)echnk->data) + echnk->size,
3359 /* Advance to next chunk */
3360 NEXT_CHUNK((*p), (*size), (*echnk), ed);
3361 memset(echnk, 0, sizeof(Eet_Data_Chunk));
3364 eet_data_chunk_get(ed, echnk, *p, *size);
3368 if (IS_POINTER_TYPE(echnk->type))
3369 POINTER_TYPE_DECODE(context,
3380 STRUCT_TYPE_DECODE(data_ret,
3383 ede ? ede->subtype : NULL,
3390 hash = edd->func.hash_add(hash, key, data_ret);
3392 _eet_freelist_hash_add(context, hash);
3395 eet_node_hash_add(*((Eet_Node **)data), echnk->name, key, data_ret);
3401 } /* eet_data_get_hash */
3403 /* var arrays and fixed arrays have to
3404 * get all chunks at once. for fixed arrays
3405 * we can get each chunk and increment a
3406 * counter stored on the element itself but
3407 * it wont be thread safe. for var arrays
3408 * we still need a way to get the number of
3409 * elements from the data, so storing the
3410 * number of elements and the element data on
3411 * each chunk is pointless.
3414 eet_data_get_array(Eet_Free_Context *context,
3415 const Eet_Dictionary *ed,
3416 Eet_Data_Descriptor *edd,
3417 Eet_Data_Element *ede,
3418 Eet_Data_Chunk *echnk,
3425 Eina_List *childs = NULL;
3434 EET_ASSERT(!((type > EET_T_UNKNOW) && (type < EET_T_STRING)), return 0);
3437 /* read the number of elements */
3438 ret = eet_data_get_type(ed,
3441 ((char *)echnk->data) + echnk->size,
3450 if (IS_POINTER_TYPE(type))
3451 subsize = eet_basic_codec[ede->type].size;
3453 subsize = ede->subtype->size;
3455 if (group_type == EET_G_VAR_ARRAY)
3457 /* store the number of elements
3458 * on the counter offset */
3459 *(int *)(((char *)data) + ede->count - ede->offset) = count;
3460 /* allocate space for the array of elements */
3461 *(void **)ptr = edd->func.mem_alloc(count * subsize);
3466 memset(*(void **)ptr, 0, count * subsize);
3468 _eet_freelist_add(context, *(void **)ptr);
3472 /* get all array elements */
3473 for (i = 0; i < count; i++)
3476 void *data_ret = NULL;
3478 /* Advance to next chunk */
3479 NEXT_CHUNK((*p), (*size), (*echnk), ed);
3480 memset(echnk, 0, sizeof(Eet_Data_Chunk));
3482 eet_data_chunk_get(ed, echnk, *p, *size);
3483 if (!echnk->name || strcmp(echnk->name, name) != 0)
3484 goto on_error; /* get the data */
3486 if ((echnk->group_type != group_type)
3487 || ((echnk->type != type) && (echnk->type != EET_T_NULL)))
3491 if ((ede->group_type != echnk->group_type)
3492 || ((echnk->type != ede->type) && (echnk->type != EET_T_NULL)))
3495 /* get the destination pointer */
3498 if (group_type == EET_G_ARRAY)
3499 dst = (char *)ptr + (subsize * i);
3501 dst = *(char **)ptr + (subsize * i);
3504 if (IS_POINTER_TYPE(echnk->type))
3506 POINTER_TYPE_DECODE(context,
3517 memcpy(dst, &data_ret, subsize);
3520 childs = eina_list_append(childs, data_ret);
3524 STRUCT_TYPE_DECODE(data_ret,
3527 ede ? ede->subtype : NULL,
3533 memcpy(dst, data_ret, subsize);
3534 _eet_freelist_add(context, data_ret);
3538 childs = eina_list_append(childs, data_ret);
3544 Eet_Node *parent = *((Eet_Node **)data);
3547 if (group_type == EET_G_ARRAY)
3548 array = eet_node_array_new(name, count, childs);
3550 array = eet_node_var_array_new(name, childs);
3555 eet_node_struct_append(parent, name, array);
3561 EINA_LIST_FREE(childs, tmp)
3565 } /* eet_data_get_array */
3568 eet_data_put_union(Eet_Dictionary *ed,
3569 Eet_Data_Descriptor *edd __UNUSED__,
3570 Eet_Data_Element *ede,
3571 Eet_Data_Stream *ds,
3574 const char *union_type;
3577 EET_ASSERT(!((ede->type != EET_T_UNKNOW) || (!ede->subtype)), return );
3579 union_type = ede->subtype->func.type_get(
3580 ((char *)data_in) + ede->count - ede->offset,
3586 /* Search the structure of the union to encode. */
3587 for (i = 0; i < ede->subtype->elements.num; ++i)
3588 if (strcmp(ede->subtype->elements.set[i].name, union_type) == 0)
3590 Eet_Data_Element *sede;
3594 /* Yeah we found it ! */
3595 data = eet_data_put_type(ed, EET_T_STRING, &union_type, &size);
3605 sede = &(ede->subtype->elements.set[i]);
3606 data = _eet_data_descriptor_encode(ed,
3622 } /* eet_data_put_union */
3625 eet_data_get_union(Eet_Free_Context *context,
3626 const Eet_Dictionary *ed,
3627 Eet_Data_Descriptor *edd __UNUSED__,
3628 Eet_Data_Element *ede,
3629 Eet_Data_Chunk *echnk,
3636 const char *union_type;
3637 void *data_ret = NULL;
3642 ret = eet_data_get_type(ed,
3645 ((char *)echnk->data) + echnk->size,
3650 /* Advance to next chunk */
3651 NEXT_CHUNK((*p), (*size), (*echnk), ed);
3652 memset(echnk, 0, sizeof(Eet_Data_Chunk));
3655 eet_data_chunk_get(ed, echnk, *p, *size);
3661 EET_ASSERT(!(ede->group_type != group_type || ede->type != type),
3664 /* Search the structure of the union to decode */
3665 for (i = 0; i < ede->subtype->elements.num; ++i)
3666 if (strcmp(ede->subtype->elements.set[i].name, union_type) == 0)
3668 Eet_Data_Element *sede;
3671 /* Yeah we found it ! */
3672 sede = &(ede->subtype->elements.set[i]);
3673 EET_ASSERT(sede->subtype, goto on_error);
3675 data_ret = _eet_data_descriptor_decode(context,
3683 /* Memcopy the structure content to remove pointer indirection. */
3684 memcpy(data, data_ret, sede->subtype->size);
3686 /* data_ret is now useless. */
3687 sede->subtype->func.mem_free(data_ret);
3689 /* Set union type. */
3690 if ((!ed) || (!ede->subtype->func.str_direct_alloc))
3692 ut = ede->subtype->func.str_alloc(union_type);
3693 _eet_freelist_str_add(context, ut);
3697 ut = ede->subtype->func.str_direct_alloc(union_type);
3698 _eet_freelist_direct_str_add(context, ut);
3701 ede->subtype->func.type_set(
3703 ((char *)data) + ede->count -
3713 /* FIXME: generate node structure. */
3714 data_ret = _eet_data_descriptor_decode(context,
3716 echnk->data, echnk->size);
3724 } /* eet_data_get_union */
3727 eet_data_put_variant(Eet_Dictionary *ed,
3728 Eet_Data_Descriptor *edd __UNUSED__,
3729 Eet_Data_Element *ede,
3730 Eet_Data_Stream *ds,
3733 const char *union_type;
3735 Eina_Bool unknow = EINA_FALSE;
3739 EET_ASSERT(!((ede->type != EET_T_UNKNOW) || (!ede->subtype)), return );
3741 union_type = ede->subtype->func.type_get(
3742 ((char *)data_in) + ede->count - ede->offset,
3745 if (!union_type && unknow == EINA_FALSE)
3750 /* Handle opaque internal representation */
3751 Eet_Variant_Unknow *evu;
3753 data = eet_data_put_type(ed, EET_T_STRING, &union_type, &size);
3763 evu = (Eet_Variant_Unknow *)data_in;
3764 if (evu && EINA_MAGIC_CHECK(evu, EET_MAGIC_VARIANT))
3774 /* Search the structure of the union to encode. */
3775 for (i = 0; i < ede->subtype->elements.num; ++i)
3776 if (strcmp(ede->subtype->elements.set[i].name, union_type) == 0)
3778 Eet_Data_Element *sede;
3780 /* Yeah we found it ! */
3781 data = eet_data_put_type(ed, EET_T_STRING, &union_type, &size);
3791 sede = &(ede->subtype->elements.set[i]);
3793 if (sede->group_type != EET_G_UNKNOWN)
3795 Eet_Data_Stream *lds;
3797 lds = eet_data_stream_new();
3798 eet_group_codec[sede->group_type - 100].put(ed,
3805 eet_data_encode(ed, ds, lds->data, ede->name, lds->pos,
3806 ede->type, ede->group_type);
3812 eet_data_encode(ed, ds, NULL, ede->name, 0,
3813 EET_T_NULL, ede->group_type);
3815 eet_data_stream_free(lds);
3819 data = _eet_data_descriptor_encode(ed,
3836 } /* eet_data_put_variant */
3839 eet_data_get_variant(Eet_Free_Context *context,
3840 const Eet_Dictionary *ed,
3841 Eet_Data_Descriptor *edd __UNUSED__,
3842 Eet_Data_Element *ede,
3843 Eet_Data_Chunk *echnk,
3844 int type __UNUSED__,
3845 int group_type __UNUSED__,
3850 const char *union_type;
3851 void *data_ret = NULL;
3856 ret = eet_data_get_type(ed,
3859 ((char *)echnk->data) + echnk->size,
3864 /* Advance to next chunk */
3865 NEXT_CHUNK((*p), (*size), (*echnk), ed);
3866 memset(echnk, 0, sizeof(Eet_Data_Chunk));
3869 eet_data_chunk_get(ed, echnk, *p, *size);
3877 EET_ASSERT(ede->subtype, goto on_error);
3879 if ((!ed) || (!ede->subtype->func.str_direct_alloc))
3881 ut = ede->subtype->func.str_alloc(union_type);
3882 _eet_freelist_str_add(context, ut);
3886 ut = ede->subtype->func.str_direct_alloc(union_type);
3887 _eet_freelist_direct_str_add(context, ut);
3890 /* Search the structure of the union to decode */
3891 for (i = 0; i < ede->subtype->elements.num; ++i)
3892 if (strcmp(ede->subtype->elements.set[i].name, union_type) == 0)
3894 Eet_Data_Element *sede;
3896 /* Yeah we found it ! */
3897 sede = &(ede->subtype->elements.set[i]);
3899 if (sede->group_type != EET_G_UNKNOWN)
3901 Eet_Data_Chunk chnk;
3907 size2 = echnk->size;
3909 /* Didn't find a proper way to provide this
3910 without duplicating code */
3913 memset(&chnk, 0, sizeof(Eet_Data_Chunk));
3914 eet_data_chunk_get(ed, &chnk, p2, size2);
3919 ret = eet_group_codec[sede->group_type - 100].get
3920 (context, ed, sede->subtype, sede, &chnk, sede->type,
3921 sede->group_type, data, &p2, &size2);
3926 /* advance to next chunk */
3927 NEXT_CHUNK(p2, size2, chnk, ed);
3930 /* Put garbage so that we will not put eet_variant_unknow in it */
3931 data_ret = (void *)data;
3933 /* Set variant type. */
3934 ede->subtype->func.type_set
3935 (ut, ((char *)data) + ede->count - ede->offset,
3940 data_ret = _eet_data_descriptor_decode(context,
3948 /* And point to the variant data. */
3949 *(void **)data = data_ret;
3951 /* Set variant type. */
3952 ede->subtype->func.type_set
3953 (ut, ((char *)data) + ede->count - ede->offset, EINA_FALSE);
3959 Eet_Variant_Unknow *evu;
3961 evu = calloc(1, sizeof (Eet_Variant_Unknow) + echnk->size - 1);
3965 evu->size = echnk->size;
3966 memcpy(evu->data, echnk->data, evu->size);
3967 EINA_MAGIC_SET(evu, EET_MAGIC_VARIANT);
3969 /* And point to the opaque internal data scructure */
3970 *(void **)data = evu;
3972 /* Set variant type. */
3973 ede->subtype->func.type_set
3974 (ut, ((char *)data) + ede->count - ede->offset, EINA_TRUE);
3979 /* FIXME: dump node structure. */
3980 data_ret = _eet_data_descriptor_decode(context,
3982 echnk->data, echnk->size);
3990 } /* eet_data_get_variant */
3993 eet_data_node_simple_type(int type, const char *name, void *dd)
3997 #endif /* ifdef EET_T_TYPE */
3999 #define EET_T_TYPE(Eet_Type, Eet_Node_Type, Type)\
4001 return eet_node_ ## Eet_Node_Type ## _new(name, *((Type *)dd));\
4005 EET_T_TYPE(EET_T_CHAR, char, char);
4006 EET_T_TYPE(EET_T_SHORT, short, short);
4007 EET_T_TYPE(EET_T_INT, int, int);
4008 EET_T_TYPE(EET_T_LONG_LONG, long_long, long long);
4009 EET_T_TYPE(EET_T_FLOAT, float, float);
4010 EET_T_TYPE(EET_T_DOUBLE, double, double);
4011 EET_T_TYPE(EET_T_UCHAR, unsigned_char, unsigned char);
4012 EET_T_TYPE(EET_T_USHORT, unsigned_short, unsigned short);
4013 EET_T_TYPE(EET_T_UINT, unsigned_int, unsigned int);
4014 EET_T_TYPE(EET_T_ULONG_LONG, unsigned_long_long, unsigned long long);
4015 EET_T_TYPE(EET_T_STRING, string, char *);
4016 EET_T_TYPE(EET_T_INLINED_STRING, inlined_string, char *);
4019 return eet_node_null_new(name);
4022 ERR("Unknow type passed to eet_data_node_simple_type");
4025 } /* eet_data_node_simple_type */
4028 eet_data_get_unknown(Eet_Free_Context *context,
4029 const Eet_Dictionary *ed,
4030 Eet_Data_Descriptor *edd,
4031 Eet_Data_Element *ede,
4032 Eet_Data_Chunk *echnk,
4034 int group_type __UNUSED__,
4036 char **p __UNUSED__,
4037 int *size __UNUSED__)
4042 if (IS_SIMPLE_TYPE(type))
4044 unsigned char dd[128];
4046 ret = eet_data_get_type(ed,
4049 ((char *)echnk->data) + echnk->size,
4050 edd ? (char *)data : (char *)dd);
4056 Eet_Node **parent = data;
4059 node = eet_data_node_simple_type(type, echnk->name, dd);
4062 eet_node_struct_append(*parent, echnk->name, node);
4068 if (type == EET_T_STRING)
4072 str = (char **)(((char *)data));
4075 if ((ed == NULL) || (edd->func.str_direct_alloc == NULL))
4077 *str = edd->func.str_alloc(*str);
4078 _eet_freelist_str_add(context, *str);
4082 *str = edd->func.str_direct_alloc(*str);
4083 _eet_freelist_direct_str_add(context, *str);
4087 else if (edd && type == EET_T_INLINED_STRING)
4091 str = (char **)(((char *)data));
4094 *str = edd->func.str_alloc(*str);
4095 _eet_freelist_str_add(context, *str);
4102 Eet_Data_Descriptor *subtype;
4104 subtype = ede ? ede->subtype : NULL;
4106 if (subtype || !edd)
4108 Eet_Node **parent = data;
4111 data_ret = _eet_data_descriptor_decode(context,
4121 ptr = (void **)(((char *)data));
4122 *ptr = (void *)data_ret;
4126 Eet_Node *node = data_ret;
4130 node = eet_node_struct_child_new(echnk->name, node);
4131 eet_node_struct_append(*parent, echnk->name, node);
4140 } /* eet_data_get_unknown */
4143 eet_data_put_array(Eet_Dictionary *ed,
4144 Eet_Data_Descriptor *edd __UNUSED__,
4145 Eet_Data_Element *ede,
4146 Eet_Data_Stream *ds,
4156 EET_ASSERT(!((ede->type > EET_T_UNKNOW) && (ede->type < EET_T_STRING)),
4159 if (ede->group_type == EET_G_ARRAY)
4160 count = ede->counter_offset;
4162 count = *(int *)(((char *)data_in) + ede->count - ede->offset);
4165 return; /* Store number of elements */
4167 data = eet_data_put_type(ed, EET_T_INT, &count, &size);
4169 eet_data_encode(ed, ds, data, ede->name, size, ede->type, ede->group_type);
4171 if (IS_POINTER_TYPE(ede->type))
4172 subsize = eet_basic_codec[ede->type].size;
4174 subsize = ede->subtype->size;
4176 for (j = 0; j < count; j++)
4181 if (ede->group_type == EET_G_ARRAY)
4182 d = (void *)(((char *)data_in) + offset);
4184 d = *(((char **)data_in)) + offset;
4186 if (IS_POINTER_TYPE(ede->type))
4189 eet_data_put_unknown(ed, NULL, ede, ds, d);
4193 data = _eet_data_descriptor_encode(ed, ede->subtype, d, &size);
4205 /* Add a NULL element just to have the correct array layout. */
4216 } /* eet_data_put_array */
4219 eet_data_put_unknown(Eet_Dictionary *ed,
4220 Eet_Data_Descriptor *edd __UNUSED__,
4221 Eet_Data_Element *ede,
4222 Eet_Data_Stream *ds,
4228 if (IS_SIMPLE_TYPE(ede->type))
4229 data = eet_data_put_type(ed, ede->type, data_in, &size);
4230 else if (ede->subtype)
4231 if (*((char **)data_in))
4232 data = _eet_data_descriptor_encode(ed,
4234 *((char **)((char *)(data_in))),
4245 } /* eet_data_put_unknown */
4248 eet_data_put_list(Eet_Dictionary *ed,
4249 Eet_Data_Descriptor *edd,
4250 Eet_Data_Element *ede,
4251 Eet_Data_Stream *ds,
4258 EET_ASSERT(!(((ede->type > EET_T_UNKNOW) && (ede->type < EET_T_STRING))
4259 || ((ede->type > EET_T_NULL) && (ede->type < EET_T_LAST))),
4262 l = *((void **)(((char *)data_in)));
4263 for (; l; l = edd->func.list_next(l))
4265 if (IS_POINTER_TYPE(ede->type))
4267 const void *str = edd->func.list_data(l);
4268 eet_data_put_unknown(ed, NULL, ede, ds, &str);
4272 data = _eet_data_descriptor_encode(ed,
4274 edd->func.list_data(l),
4286 } /* eet_data_put_list */
4289 eet_data_put_hash(Eet_Dictionary *ed,
4290 Eet_Data_Descriptor *edd,
4291 Eet_Data_Element *ede,
4292 Eet_Data_Stream *ds,
4295 Eet_Data_Encode_Hash_Info fdata;
4298 l = *((void **)(((char *)data_in)));
4302 edd->func.hash_foreach(l, eet_data_descriptor_encode_hash_cb, &fdata);
4303 } /* eet_data_put_hash */
4306 eet_data_dump_cipher(Eet_File *ef,
4308 const char *cipher_key,
4309 void (*dumpfunc)(void *data, const char *str),
4312 const Eet_Dictionary *ed = NULL;
4313 const void *data = NULL;
4315 Eet_Free_Context context;
4316 int required_free = 0;
4319 ed = eet_dictionary_get(ef);
4322 data = eet_read_direct(ef, name, &size);
4327 data = eet_read_cipher(ef, name, &size, cipher_key);
4332 memset(&context, 0, sizeof (context));
4333 result = _eet_data_descriptor_decode(&context, ed, NULL, data, size);
4335 eet_node_dump(result, 0, dumpfunc, dumpdata);
4337 eet_node_del(result);
4342 return result ? 1 : 0;
4343 } /* eet_data_dump_cipher */
4346 eet_data_dump(Eet_File *ef,
4348 void (*dumpfunc)(void *data, const char *str),
4351 return eet_data_dump_cipher(ef, name, NULL, dumpfunc, dumpdata);
4352 } /* eet_data_dump */
4355 eet_data_text_dump_cipher(const void *data_in,
4356 const char *cipher_key,
4358 void (*dumpfunc)(void *data, const char *str),
4363 Eet_Free_Context context;
4364 unsigned int ret_len = 0;
4371 if (eet_decipher(data_in, size_in, cipher_key,
4372 strlen(cipher_key), &ret, &ret_len))
4382 ret = (void *)data_in;
4386 memset(&context, 0, sizeof (context));
4387 result = _eet_data_descriptor_decode(&context, NULL, NULL, ret, ret_len);
4389 eet_node_dump(result, 0, dumpfunc, dumpdata);
4391 eet_node_del(result);
4395 return result ? 1 : 0;
4396 } /* eet_data_text_dump_cipher */
4399 eet_data_text_dump(const void *data_in,
4401 void (*dumpfunc)(void *data, const char *str),
4404 return eet_data_text_dump_cipher(data_in, NULL, size_in, dumpfunc, dumpdata);
4405 } /* eet_data_text_dump */
4408 eet_data_text_undump_cipher(const char *text,
4409 const char *cipher_key,
4415 ret = _eet_data_dump_parse(NULL, size_ret, text, textlen);
4416 if (ret && cipher_key)
4418 void *ciphered = NULL;
4419 unsigned int ciphered_len;
4421 if (eet_cipher(ret, *size_ret, cipher_key,
4422 strlen(cipher_key), &ciphered, &ciphered_len))
4433 *size_ret = ciphered_len;
4438 } /* eet_data_text_undump_cipher */
4441 eet_data_text_undump(const char *text,
4445 return eet_data_text_undump_cipher(text, NULL, textlen, size_ret);
4446 } /* eet_data_text_undump */
4449 eet_data_undump_cipher(Eet_File *ef,
4451 const char *cipher_key,
4461 ed = eet_dictionary_get(ef);
4463 data_enc = _eet_data_dump_parse(ed, &size, text, textlen);
4467 val = eet_write_cipher(ef, name, data_enc, size, compress, cipher_key);
4470 } /* eet_data_undump_cipher */
4473 eet_data_undump(Eet_File *ef,
4479 return eet_data_undump_cipher(ef, name, NULL, text, textlen, compress);
4480 } /* eet_data_undump */
4483 eet_data_descriptor_decode_cipher(Eet_Data_Descriptor *edd,
4484 const void *data_in,
4485 const char *cipher_key,
4488 void *deciphered = (void *)data_in;
4490 Eet_Free_Context context;
4491 unsigned int deciphered_len = size_in;
4493 if (cipher_key && data_in)
4494 if (eet_decipher(data_in, size_in, cipher_key,
4495 strlen(cipher_key), &deciphered, &deciphered_len))
4503 memset(&context, 0, sizeof (context));
4504 ret = _eet_data_descriptor_decode(&context,
4510 if (data_in != deciphered)
4514 } /* eet_data_descriptor_decode_cipher */
4517 eet_data_descriptor_decode(Eet_Data_Descriptor *edd,
4518 const void *data_in,
4521 return eet_data_descriptor_decode_cipher(edd, data_in, NULL, size_in);
4522 } /* eet_data_descriptor_decode */
4525 eet_data_node_decode_cipher(const void *data_in,
4526 const char *cipher_key,
4529 void *deciphered = (void *)data_in;
4531 Eet_Free_Context context;
4532 unsigned int deciphered_len = size_in;
4534 if (cipher_key && data_in)
4535 if (eet_decipher(data_in, size_in, cipher_key,
4536 strlen(cipher_key), &deciphered, &deciphered_len))
4544 memset(&context, 0, sizeof (context));
4545 ret = _eet_data_descriptor_decode(&context,
4551 if (data_in != deciphered)
4555 } /* eet_data_node_decode_cipher */
4558 _eet_data_descriptor_encode(Eet_Dictionary *ed,
4559 Eet_Data_Descriptor *edd,
4560 const void *data_in,
4563 Eet_Data_Stream *ds;
4564 Eet_Data_Chunk *chnk;
4569 if (_eet_data_words_bigendian == -1)
4571 unsigned long int v;
4573 v = htonl(0x12345678);
4574 if (v == 0x12345678)
4575 _eet_data_words_bigendian = 1;
4577 _eet_data_words_bigendian = 0;
4580 ds = eet_data_stream_new();
4581 for (i = 0; i < edd->elements.num; i++)
4583 Eet_Data_Element *ede;
4585 ede = &(edd->elements.set[i]);
4586 eet_group_codec[ede->group_type - 100].put(
4594 chnk = eet_data_chunk_new(ds->data,
4601 eet_data_stream_free(ds);
4603 ds = eet_data_stream_new();
4604 eet_data_chunk_put(ed, chnk, ds);
4610 eet_data_stream_free(ds);
4614 eet_data_chunk_free(chnk);
4617 } /* _eet_data_descriptor_encode */
4620 eet_data_node_write_cipher(Eet_File *ef,
4622 const char *cipher_key,
4631 ed = eet_dictionary_get(ef);
4633 data_enc = _eet_data_dump_encode(EET_G_UNKNOWN, ed, node, &size);
4637 val = eet_write_cipher(ef, name, data_enc, size, compress, cipher_key);
4640 } /* eet_data_node_write_cipher */
4643 eet_data_node_encode_cipher(Eet_Node *node,
4644 const char *cipher_key,
4648 void *ciphered = NULL;
4649 unsigned int ciphered_len = 0;
4652 ret = _eet_data_dump_encode(EET_G_UNKNOWN, NULL, node, &size);
4653 if (cipher_key && ret)
4655 if (eet_cipher(ret, size, cipher_key,
4656 strlen(cipher_key), &ciphered, &ciphered_len))
4669 size = (int)ciphered_len;
4677 } /* eet_data_node_encode_cipher */
4680 eet_data_descriptor_encode_cipher(Eet_Data_Descriptor *edd,
4681 const void *data_in,
4682 const char *cipher_key,
4686 void *ciphered = NULL;
4687 unsigned int ciphered_len = 0;
4690 ret = _eet_data_descriptor_encode(NULL, edd, data_in, &size);
4691 if (cipher_key && ret)
4693 if (eet_cipher(ret, size, cipher_key,
4694 strlen(cipher_key), &ciphered, &ciphered_len))
4707 size = ciphered_len;
4715 } /* eet_data_descriptor_encode_cipher */
4718 eet_data_descriptor_encode(Eet_Data_Descriptor *edd,
4719 const void *data_in,
4722 return eet_data_descriptor_encode_cipher(edd, data_in, NULL, size_ret);
4723 } /* eet_data_descriptor_encode */