2 * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
15 #ifdef HAVE_NETINET_IN_H
16 # include <netinet/in.h>
20 # include <winsock2.h>
26 #include "Eet_private.h"
29 * routines for doing data -> struct and struct -> data conversion
49 * multiple entries ordered as...
51 * fixed size array [ of basic types ]
52 * variable size array [ of basic types ]
53 * linked list [ of basic types ]
54 * hash table [ of basic types ]
56 * need to provide builder/accessor funcs for:
68 typedef struct _Eet_Data_Element Eet_Data_Element;
69 typedef struct _Eet_Data_Basic_Type_Codec Eet_Data_Basic_Type_Codec;
70 typedef struct _Eet_Data_Group_Type_Codec Eet_Data_Group_Type_Codec;
71 typedef struct _Eet_Data_Chunk Eet_Data_Chunk;
72 typedef struct _Eet_Data_Stream Eet_Data_Stream;
73 typedef struct _Eet_Data_Descriptor_Hash Eet_Data_Descriptor_Hash;
74 typedef struct _Eet_Data_Encode_Hash_Info Eet_Data_Encode_Hash_Info;
75 typedef struct _Eet_Free Eet_Free;
76 typedef struct _Eet_Free_Context Eet_Free_Context;
77 typedef struct _Eet_Variant_Unknow Eet_Variant_Unknow;
82 * Eet_Data_Basic_Type_Codec (Coder, Decoder)
83 * Eet_Data_Group_Type_Codec (Coder, Decoder)
85 struct _Eet_Data_Basic_Type_Codec
89 int (*get) (const Eet_Dictionary *ed, const void *src, const void *src_end, 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;
129 void *(*mem_alloc) (size_t size);
130 void (*mem_free) (void *mem);
131 char *(*str_alloc) (const char *str);
132 char *(*str_direct_alloc) (const char *str);
133 void (*str_free) (const char *str);
134 void (*str_direct_free) (const char *str);
135 void *(*list_next) (void *l);
136 void *(*list_append) (void *l, void *d);
137 void *(*list_data) (void *l);
138 void *(*list_free) (void *l);
139 void (*hash_foreach) (void *h, int (*func) (void *h, const char *k, void *dt, void *fdt), void *fdt);
140 void *(*hash_add) (void *h, const char *k, void *d);
141 void (*hash_free) (void *h);
142 const char *(*type_get) (const void *data, Eina_Bool *unknow);
143 Eina_Bool (*type_set) (const char *type, void *data, Eina_Bool unknow);
147 Eet_Data_Element *set;
150 Eet_Data_Descriptor_Hash *buckets;
154 Eina_Bool unified_type : 1;
159 struct _Eet_Data_Element
162 const char *counter_name;
163 const char *directory_name_ptr;
164 Eet_Data_Descriptor *subtype;
165 int offset; /* offset in bytes from the base element */
166 int count; /* number of elements for a fixed array */
167 int counter_offset; /* for a variable array we need the offset of the count variable */
168 unsigned char type; /* EET_T_XXX */
169 unsigned char group_type; /* EET_G_XXX */
172 struct _Eet_Data_Encode_Hash_Info
175 Eet_Data_Element *ede;
187 struct _Eet_Free_Context
190 Eet_Free freelist_list;
191 Eet_Free freelist_hash;
192 Eet_Free freelist_str;
193 Eet_Free freelist_direct_str;
196 struct _Eet_Variant_Unknow
206 static int eet_data_get_char(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dest);
207 static void *eet_data_put_char(Eet_Dictionary *ed, const void *src, int *size_ret);
208 static int eet_data_get_short(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dest);
209 static void *eet_data_put_short(Eet_Dictionary *ed, const void *src, int *size_ret);
210 static inline int eet_data_get_int(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dest);
211 static void *eet_data_put_int(Eet_Dictionary *ed, const void *src, int *size_ret);
212 static int eet_data_get_long_long(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dest);
213 static void *eet_data_put_long_long(Eet_Dictionary *ed, const void *src, int *size_ret);
214 static int eet_data_get_float(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dest);
215 static void *eet_data_put_float(Eet_Dictionary *ed, const void *src, int *size_ret);
216 static int eet_data_get_double(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dest);
217 static void *eet_data_put_double(Eet_Dictionary *ed, const void *src, int *size_ret);
218 static int eet_data_get_f32p32(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dest);
219 static void *eet_data_put_f32p32(Eet_Dictionary *ed, const void *src, int *size_ret);
220 static int eet_data_get_f16p16(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dest);
221 static void *eet_data_put_f16p16(Eet_Dictionary *ed, const void *src, int *size_ret);
222 static int eet_data_get_f8p24(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dest);
223 static void *eet_data_put_f8p24(Eet_Dictionary *ed, const void *src, int *size_ret);
224 static inline int eet_data_get_string(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dest);
225 static void *eet_data_put_string(Eet_Dictionary *ed, const void *src, int *size_ret);
226 static int eet_data_get_istring(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dest);
227 static void *eet_data_put_istring(Eet_Dictionary *ed, const void *src, int *size_ret);
228 static int eet_data_get_null(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dest);
229 static void *eet_data_put_null(Eet_Dictionary *ed, const void *src, int *size_ret);
231 static int eet_data_get_type(const Eet_Dictionary *ed, int type, const void *src, const void *src_end, void *dest);
232 static void *eet_data_put_type(Eet_Dictionary *ed, int type, const void *src, int *size_ret);
234 static Eet_Node *eet_data_node_simple_type(int type, const char *name, void *dd);
236 static int eet_data_get_unknown(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);
237 static void eet_data_put_unknown(Eet_Dictionary *ed, Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Stream *ds, void *data_in);
238 static void eet_data_put_array(Eet_Dictionary *ed, Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Stream *ds, void *data_in);
239 static int eet_data_get_array(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, char **p, int *size);
240 static int eet_data_get_list(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);
241 static void eet_data_put_list(Eet_Dictionary *ed, Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Stream *ds, void *data_in);
242 static void eet_data_put_hash(Eet_Dictionary *ed, Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Stream *ds, void *data_in);
243 static int eet_data_get_hash(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, char **p, int *size);
244 static void eet_data_put_union(Eet_Dictionary *ed, Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Stream *ds, void *data_in);
245 static int eet_data_get_union(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, char **p, int *size);
246 static void eet_data_put_inherit(Eet_Dictionary *ed, Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Stream *ds, void *data_in);
247 static int eet_data_get_inherit(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, char **p, int *size);
248 static void eet_data_put_variant(Eet_Dictionary *ed, Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Stream *ds, void *data_in);
249 static int eet_data_get_variant(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, char **p, int *size);
251 static void eet_data_chunk_get(const Eet_Dictionary *ed, Eet_Data_Chunk *chnk, const void *src, int size);
252 static Eet_Data_Chunk *eet_data_chunk_new(void *data, int size, const char *name, int type, int group_type);
253 static void eet_data_chunk_free(Eet_Data_Chunk *chnk);
255 static Eet_Data_Stream *eet_data_stream_new(void);
256 static void eet_data_stream_write(Eet_Data_Stream *ds, const void *data, int size);
257 static void eet_data_stream_free(Eet_Data_Stream *ds);
259 static void eet_data_chunk_put(Eet_Dictionary *ed, Eet_Data_Chunk *chnk, Eet_Data_Stream *ds);
261 static int eet_data_descriptor_encode_hash_cb(void *hash, const char *key, void *hdata, void *fdata);
262 static void *_eet_data_descriptor_encode(Eet_Dictionary *ed, Eet_Data_Descriptor *edd, const void *data_in, int *size_ret);
263 static void *_eet_data_descriptor_decode(Eet_Free_Context *context,
264 const Eet_Dictionary *ed,
265 Eet_Data_Descriptor *edd,
271 static const Eet_Data_Basic_Type_Codec eet_basic_codec[] =
273 {sizeof(char), "char", eet_data_get_char, eet_data_put_char },
274 {sizeof(short), "short", eet_data_get_short, eet_data_put_short },
275 {sizeof(int), "int", eet_data_get_int, eet_data_put_int },
276 {sizeof(long long), "long_long", eet_data_get_long_long, eet_data_put_long_long},
277 {sizeof(float), "float", eet_data_get_float, eet_data_put_float },
278 {sizeof(double), "double", eet_data_get_double, eet_data_put_double },
279 {sizeof(char), "uchar", eet_data_get_char, eet_data_put_char },
280 {sizeof(short), "ushort", eet_data_get_short, eet_data_put_short },
281 {sizeof(int), "uint", eet_data_get_int, eet_data_put_int },
282 {sizeof(long long), "ulong_long", eet_data_get_long_long, eet_data_put_long_long},
283 {sizeof(char *), "string", eet_data_get_string, eet_data_put_string },
284 {sizeof(char *), "inlined", eet_data_get_istring, eet_data_put_istring },
285 {sizeof(void *), "NULL", eet_data_get_null, eet_data_put_null },
286 {sizeof(Eina_F32p32),"f32p32", eet_data_get_f32p32, eet_data_put_f32p32 },
287 {sizeof(Eina_F16p16),"f16p16", eet_data_get_f16p16, eet_data_put_f16p16 },
288 {sizeof(Eina_F8p24),"f8p24", eet_data_get_f8p24, eet_data_put_f8p24 }
291 static const Eet_Data_Group_Type_Codec eet_group_codec[] =
293 { eet_data_get_unknown, eet_data_put_unknown },
294 { eet_data_get_array, eet_data_put_array },
295 { eet_data_get_array, eet_data_put_array },
296 { eet_data_get_list, eet_data_put_list },
297 { eet_data_get_hash, eet_data_put_hash },
298 { eet_data_get_union, eet_data_put_union },
299 { eet_data_get_inherit, eet_data_put_inherit },
300 { eet_data_get_variant, eet_data_put_variant }
303 static int _eet_data_words_bigendian = -1;
307 #define SWAP64(x) (x) = \
308 ((((unsigned long long)(x) & 0x00000000000000ffULL ) << 56) |\
309 (((unsigned long long)(x) & 0x000000000000ff00ULL ) << 40) |\
310 (((unsigned long long)(x) & 0x0000000000ff0000ULL ) << 24) |\
311 (((unsigned long long)(x) & 0x00000000ff000000ULL ) << 8) |\
312 (((unsigned long long)(x) & 0x000000ff00000000ULL ) >> 8) |\
313 (((unsigned long long)(x) & 0x0000ff0000000000ULL ) >> 24) |\
314 (((unsigned long long)(x) & 0x00ff000000000000ULL ) >> 40) |\
315 (((unsigned long long)(x) & 0xff00000000000000ULL ) >> 56))
316 #define SWAP32(x) (x) = \
317 ((((int)(x) & 0x000000ff ) << 24) |\
318 (((int)(x) & 0x0000ff00 ) << 8) |\
319 (((int)(x) & 0x00ff0000 ) >> 8) |\
320 (((int)(x) & 0xff000000 ) >> 24))
321 #define SWAP16(x) (x) = \
322 ((((short)(x) & 0x00ff ) << 8) |\
323 (((short)(x) & 0xff00 ) >> 8))
339 #define CONV16(x) {if (_eet_data_words_bigendian) SWAP16(x);}
340 #define CONV32(x) {if (_eet_data_words_bigendian) SWAP32(x);}
341 #define CONV64(x) {if (_eet_data_words_bigendian) SWAP64(x);}
343 #define IS_SIMPLE_TYPE(Type) (Type > EET_T_UNKNOW && Type < EET_T_LAST)
344 #define IS_POINTER_TYPE(Type) (Type >= EET_T_STRING && Type <= EET_T_NULL)
346 #define EET_I_STRING 1 << 4
347 #define EET_I_INLINED_STRING 2 << 4
348 #define EET_I_NULL 3 << 4
350 #define EET_MAGIC_VARIANT 0xF1234BC
355 eet_data_get_char(const Eet_Dictionary *ed __UNUSED__, const void *src, const void *src_end, void *dst)
359 if (((char *)src + sizeof(char)) > (char *)src_end) return -1;
368 eet_data_put_char(Eet_Dictionary *ed __UNUSED__, const void *src, int *size_ret)
372 d = (char *)malloc(sizeof(char));
377 *size_ret = sizeof(char);
383 eet_data_get_short(const Eet_Dictionary *ed __UNUSED__, const void *src, const void *src_end, void *dst)
387 if (((char *)src + sizeof(short)) > (char *)src_end) return -1;
388 memcpy(dst, src, sizeof(short));
391 return sizeof(short);
395 eet_data_put_short(Eet_Dictionary *ed __UNUSED__, const void *src, int *size_ret)
399 d = (short *)malloc(sizeof(short));
404 *size_ret = sizeof(short);
410 eet_data_get_int(const Eet_Dictionary *ed __UNUSED__, const void *src, const void *src_end, void *dst)
414 if (((char *)src + sizeof(int)) > (char *)src_end) return -1;
415 memcpy(dst, src, sizeof(int));
422 eet_data_put_int(Eet_Dictionary *ed __UNUSED__, const void *src, int *size_ret)
426 d = (int *)malloc(sizeof(int));
431 *size_ret = sizeof(int);
437 eet_data_get_long_long(const Eet_Dictionary *ed __UNUSED__, const void *src, const void *src_end, void *dst)
439 unsigned long long *d;
441 if (((char *)src + sizeof(unsigned long long)) > (char *)src_end) return -1;
442 memcpy(dst, src, sizeof(unsigned long long));
443 d = (unsigned long long *)dst;
445 return sizeof(unsigned long long);
449 eet_data_put_long_long(Eet_Dictionary *ed __UNUSED__, const void *src, int *size_ret)
451 unsigned long long *s, *d;
453 d = (unsigned long long *)malloc(sizeof(unsigned long long));
455 s = (unsigned long long *)src;
458 *size_ret = sizeof(unsigned long long);
464 eet_data_get_string_hash(const Eet_Dictionary *ed, const void *src, const void *src_end)
470 if (eet_data_get_int(ed, src, src_end, &idx) < 0) return -1;
472 return eet_dictionary_string_get_hash(ed, idx);
479 eet_data_get_string(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dst)
490 if (eet_data_get_int(ed, src, src_end, &idx) < 0) return -1;
492 str = eet_dictionary_string_get_char(ed, idx);
497 return eet_dictionary_string_get_size(ed, idx);
508 return strlen(s) + 1;
512 eet_data_put_string(Eet_Dictionary *ed, const void *src, int *size_ret)
522 str = *((const char **) src);
523 if (!str) return NULL;
525 idx = eet_dictionary_string_add(ed, str);
526 if (idx == -1) return NULL;
528 return eet_data_put_int(ed, &idx, size_ret);
531 s = (char *)(*((char **)src));
536 memcpy(d, s, len + 1);
541 /* ALWAYS INLINED STRING TYPE */
543 eet_data_get_istring(const Eet_Dictionary *ed __UNUSED__, const void *src, const void *src_end, void *dst)
545 return eet_data_get_string(NULL, src, src_end, dst);
549 eet_data_put_istring(Eet_Dictionary *ed __UNUSED__, const void *src, int *size_ret)
551 return eet_data_put_string(NULL, src, size_ret);
554 /* ALWAYS NULL TYPE */
556 eet_data_get_null(const Eet_Dictionary *ed __UNUSED__, const void *src __UNUSED__, const void *src_end __UNUSED__, void *dst)
567 eet_data_put_null(Eet_Dictionary *ed __UNUSED__, const void *src __UNUSED__, int *size_ret)
574 * Fast lookups of simple doubles/floats.
576 * These aren't properly a cache because they don't store pre-calculated
577 * values, but have a so simple math that is almost as fast.
580 _eet_data_float_cache_get(const char *s, int len, float *d)
582 /* fast handle of simple case 0xMp+E*/
583 if ((len == 6) && (s[0] == '0') && (s[1] == 'x') && (s[3] == 'p'))
585 int mantisse = (s[2] >= 'a') ? (s[2] - 'a' + 10) : (s[2] - '0');
586 int exponent = (s[5] - '0');
588 if (s[4] == '+') *d = (float)(mantisse << exponent);
589 else *d = (float)mantisse / (float)(1 << exponent);
597 _eet_data_double_cache_get(const char *s, int len, double *d)
599 /* fast handle of simple case 0xMp+E*/
600 if ((len == 6) && (s[0] == '0') && (s[1] == 'x') && (s[3] == 'p'))
602 int mantisse = (s[2] >= 'a') ? (s[2] - 'a' + 10) : (s[2] - '0');
603 int exponent = (s[5] - '0');
605 if (s[4] == '+') *d = (double)(mantisse << exponent);
606 else *d = (double)mantisse / (double)(1 << exponent);
615 eet_data_get_float(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dst)
628 s = (const char *)src;
631 while ((p < (const char *)src_end) && (*p != 0)) {len++; p++;}
633 if (_eet_data_float_cache_get(s, len, d) != 0) return len + 1;
635 if (eina_convert_atod(s, len, &mantisse, &exponent) == EINA_FALSE) return -1;
636 *d = (float)ldexp((double)mantisse, exponent);
641 if (eet_data_get_int(ed, src, src_end, &idx) < 0) return -1;
643 if (!eet_dictionary_string_get_float(ed, idx, d))
649 eet_data_put_float(Eet_Dictionary *ed, const void *src, int *size_ret)
654 eina_convert_dtoa((double)(*(float *)src), buf);
664 memcpy(d, buf, len + 1);
669 idx = eet_dictionary_string_add(ed, buf);
670 if (idx == -1) return NULL;
672 return eet_data_put_int(ed, &idx, size_ret);
677 eet_data_get_double(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dst)
687 long long mantisse = 0;
691 s = (const char *) src;
694 while ((p < (const char *)src_end) && (*p != 0)) {len++; p++;}
696 if (_eet_data_double_cache_get(s, len, d) != 0) return len + 1;
698 if (eina_convert_atod(s, len, &mantisse, &exponent) == EINA_FALSE) return -1;
699 *d = ldexp((double) mantisse, exponent);
704 if (eet_data_get_int(ed, src, src_end, &idx) < 0) return -1;
706 if (!eet_dictionary_string_get_double(ed, idx, d))
712 eet_data_put_double(Eet_Dictionary *ed, const void *src, int *size_ret)
717 eina_convert_dtoa((double)(*(double *)src), buf);
727 memcpy(d, buf, len + 1);
733 idx = eet_dictionary_string_add(ed, buf);
734 if (idx == -1) return NULL;
736 return eet_data_put_int(ed, &idx, size_ret);
740 eet_data_get_f32p32(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dst)
745 fp = (Eina_F32p32*) dst;
752 s = (const char *) src;
755 while ((p < (const char *)src_end) && (*p != 0)) { len++; p++; }
757 if (!(eina_convert_atofp(s, len, fp)))
762 if (eet_data_get_int(ed, src, src_end, &idx) < 0) return -1;
764 if (!eet_dictionary_string_get_fp(ed, idx, fp))
770 eet_data_put_f32p32(Eet_Dictionary *ed, const void *src, int *size_ret)
775 eina_convert_fptoa((Eina_F32p32)(*(Eina_F32p32 *)src), buf);
785 memcpy(d, buf, len + 1);
791 idx = eet_dictionary_string_add(ed, buf);
792 if (idx == -1) return NULL;
794 return eet_data_put_int(ed, &idx, size_ret);
798 eet_data_get_f16p16(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dst)
803 fp = (Eina_F16p16*) dst;
805 if (eet_data_get_f32p32(ed, src, src_end, &tmp) < 0) return -1;
807 *fp = eina_f32p32_to_f16p16(tmp);
812 eet_data_put_f16p16(Eet_Dictionary *ed, const void *src, int *size_ret)
816 tmp = eina_f16p16_to_f32p32((Eina_F16p16)(*(Eina_F16p16 *)src));
817 return eet_data_put_f32p32(ed, &tmp, size_ret);
821 eet_data_get_f8p24(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dst)
826 fp = (Eina_F8p24*) dst;
828 if (eet_data_get_f32p32(ed, src, src_end, &tmp) < 0) return -1;
830 *fp = eina_f32p32_to_f8p24(tmp);
835 eet_data_put_f8p24(Eet_Dictionary *ed, const void *src, int *size_ret)
839 tmp = eina_f8p24_to_f32p32((Eina_F8p24)(*(Eina_F8p24 *)src));
840 return eet_data_put_f32p32(ed, &tmp, size_ret);
844 eet_data_get_type(const Eet_Dictionary *ed, int type, const void *src, const void *src_end, void *dest)
848 ret = eet_basic_codec[type - 1].get(ed, src, src_end, dest);
853 eet_data_put_type(Eet_Dictionary *ed, int type, const void *src, int *size_ret)
857 ret = eet_basic_codec[type - 1].put(ed, src, size_ret);
861 static inline Eina_Bool
862 eet_data_type_match(int type1, int type2)
864 if (type1 == type2) return EINA_TRUE;
866 /* Note: All floating point type are equivalent and could be read
867 without problem by any other floating point getter. */
896 * char[4] = "CHnK"; // untyped data ... or
897 * char[4] = "CHKx"; // typed data - x == type
899 * int = chunk size (including magic string);
900 * char[] = chunk magic/name string (0 byte terminated);
901 * ... sub-chunks (a chunk can contain chuncks recusrively) ...
903 * ... payload data ...
908 eet_data_chunk_get(const Eet_Dictionary *ed, Eet_Data_Chunk *chnk,
909 const void *src, int size)
915 if (size <= 8) return;
921 if ((s[0] != 'C') || (s[1] != 'H') || (s[2] != 'K'))
924 chnk->type = (unsigned char)(s[3]);
925 if (chnk->type >= EET_I_LIMIT)
927 chnk->group_type = ((chnk->type - EET_I_LIMIT) & 0xF) + EET_G_UNKNOWN;
928 switch ((chnk->type - EET_I_LIMIT) & 0xF0)
930 #define EET_UNMATCH_TYPE(Type) \
931 case EET_I_##Type: chnk->type = EET_T_##Type; break;
933 EET_UNMATCH_TYPE(STRING);
934 EET_UNMATCH_TYPE(INLINED_STRING);
935 EET_UNMATCH_TYPE(NULL);
940 else if (chnk->type > EET_T_LAST)
942 chnk->group_type = chnk->type;
943 chnk->type = EET_T_UNKNOW;
946 chnk->group_type = EET_G_UNKNOWN;
947 if ((chnk->type >= EET_T_LAST) ||
948 (chnk->group_type >= EET_G_LAST))
951 chnk->group_type = 0;
956 if ((s[0] != 'C') || (s[1] != 'H') || (s[2] != 'n') || (s[3] != 'K'))
959 ret1 = eet_data_get_type(ed, EET_T_INT, (s + 4), (s + size), &(chnk->size));
961 if (ret1 <= 0) return;
962 if ((chnk->size < 0) || ((chnk->size + 8) > size)) return;
963 ret2 = eet_data_get_type(ed, EET_T_STRING, (s + 8), (s + size), &(chnk->name));
965 if (ret2 <= 0) return;
970 chnk->hash = eet_data_get_string_hash(ed, (s + 8), (s + size));
974 chnk->data = (char *)src + 4 + ret1 + sizeof(int);
975 chnk->size -= sizeof(int);
979 chnk->data = (char *)src + 4 + ret1 + chnk->len;
980 chnk->size -= chnk->len;
986 static inline Eet_Data_Chunk *
987 eet_data_chunk_new(void *data, int size, const char *name, int type, int group_type)
989 Eet_Data_Chunk *chnk;
991 if (!name) return NULL;
992 chnk = calloc(1, sizeof(Eet_Data_Chunk));
993 if (!chnk) return NULL;
995 /* Note: Another security, so older eet library could read file
996 saved with fixed point value. */
997 if (type == EET_T_F32P32
998 || type == EET_T_F16P16
999 || type == EET_T_F8P24)
1000 type = EET_T_DOUBLE;
1002 chnk->name = strdup(name);
1003 chnk->len = strlen(name) + 1;
1007 chnk->group_type = group_type;
1012 eet_data_chunk_free(Eet_Data_Chunk *chnk)
1014 if (chnk->name) free(chnk->name);
1018 static inline Eet_Data_Stream *
1019 eet_data_stream_new(void)
1021 Eet_Data_Stream *ds;
1023 ds = calloc(1, sizeof(Eet_Data_Stream));
1024 if (!ds) return NULL;
1029 eet_data_stream_free(Eet_Data_Stream *ds)
1031 if (ds->data) free(ds->data);
1036 eet_data_stream_flush(Eet_Data_Stream *ds)
1042 eet_data_stream_write(Eet_Data_Stream *ds, const void *data, int size)
1046 if ((ds->pos + size) > ds->size)
1048 ds->data = realloc(ds->data, ds->size + size + 512);
1055 ds->size = ds->size + size + 512;
1058 memcpy(p + ds->pos, data, size);
1063 eet_data_chunk_put(Eet_Dictionary *ed, Eet_Data_Chunk *chnk, Eet_Data_Stream *ds)
1070 unsigned char buf[4] = "CHK";
1072 /* disable this check - it will allow empty chunks to be written. this is
1073 * right for corner-cases when y have a struct with empty fields (empty
1074 * strings or empty list ptrs etc.) */
1075 /* if (!chnk->data && chnk->type != EET_T_NULL) return; */
1078 /* eet_data_stream_write(ds, "CHnK", 4);*/
1079 if (chnk->type != EET_T_UNKNOW)
1081 if (chnk->group_type != EET_G_UNKNOWN)
1083 int type = EET_I_LIMIT + chnk->group_type - EET_G_UNKNOWN;
1087 /* Only make sense with pointer type. */
1088 #define EET_MATCH_TYPE(Type) \
1089 case EET_T_##Type: type += EET_I_##Type; break;
1091 EET_MATCH_TYPE(STRING);
1092 EET_MATCH_TYPE(INLINED_STRING);
1093 EET_MATCH_TYPE(NULL);
1101 buf[3] = chnk->type;
1103 else buf[3] = chnk->group_type;
1105 string = eet_data_put_string(ed, &chnk->name, &string_ret);
1109 /* size of chunk payload data + name */
1110 s = chnk->size + string_ret;
1111 size = eet_data_put_int(ed, &s, &size_ret);
1113 /* FIXME: If something goes wrong the resulting file will be corrupted. */
1117 eet_data_stream_write(ds, buf, 4);
1119 /* write chunk length */
1120 eet_data_stream_write(ds, size, size_ret);
1122 /* write chunk name */
1123 eet_data_stream_write(ds, string, string_ret);
1127 eet_data_stream_write(ds, chnk->data, chnk->size);
1137 _eet_descriptor_hash_new(Eet_Data_Descriptor *edd)
1141 edd->elements.hash.size = 1 << 6;
1142 edd->elements.hash.buckets = calloc(1, sizeof(Eet_Data_Descriptor_Hash) * edd->elements.hash.size);
1143 for (i = 0; i < edd->elements.num; i++)
1145 Eet_Data_Element *ede;
1148 ede = &(edd->elements.set[i]);
1149 hash = _eet_hash_gen((char *) ede->name, 6);
1150 if (!edd->elements.hash.buckets[hash].element)
1151 edd->elements.hash.buckets[hash].element = ede;
1154 Eet_Data_Descriptor_Hash *bucket;
1156 bucket = calloc(1, sizeof(Eet_Data_Descriptor_Hash));
1157 bucket->element = ede;
1158 bucket->next = edd->elements.hash.buckets[hash].next;
1159 edd->elements.hash.buckets[hash].next = bucket;
1165 _eet_descriptor_hash_free(Eet_Data_Descriptor *edd)
1169 for (i = 0; i < edd->elements.hash.size; i++)
1171 Eet_Data_Descriptor_Hash *bucket, *pbucket;
1173 bucket = edd->elements.hash.buckets[i].next;
1177 bucket = bucket->next;
1181 if (edd->elements.hash.buckets) free(edd->elements.hash.buckets);
1184 static Eet_Data_Element *
1185 _eet_descriptor_hash_find(Eet_Data_Descriptor *edd, char *name, int hash)
1187 Eet_Data_Descriptor_Hash *bucket;
1189 if (hash < 0) hash = _eet_hash_gen(name, 6);
1191 if (!edd->elements.hash.buckets[hash].element) return NULL;
1193 When we use the dictionnary as a source for chunk name, we will always
1194 have the same pointer in name. It's a good idea to just compare pointer
1195 instead of running strcmp on both string.
1197 if (edd->elements.hash.buckets[hash].element->directory_name_ptr == name)
1198 return edd->elements.hash.buckets[hash].element;
1199 if (!strcmp(edd->elements.hash.buckets[hash].element->name, name))
1201 edd->elements.hash.buckets[hash].element->directory_name_ptr = name;
1202 return edd->elements.hash.buckets[hash].element;
1204 bucket = edd->elements.hash.buckets[hash].next;
1207 if (bucket->element->directory_name_ptr == name) return bucket->element;
1208 if (!strcmp(bucket->element->name, name))
1210 bucket->element->directory_name_ptr = name;
1211 return bucket->element;
1213 bucket = bucket->next;
1219 _eet_mem_alloc(size_t size)
1221 return calloc(1, size);
1225 _eet_mem_free(void *mem)
1231 _eet_str_alloc(const char *str)
1237 _eet_str_free(const char *str)
1243 _eet_eina_hash_add_alloc(Eina_Hash *hash, const char *key, void *data)
1245 if (!hash) hash = eina_hash_string_small_new(NULL);
1246 if (!hash) return NULL;
1248 eina_hash_add(hash, key, data);
1253 _eet_eina_hash_direct_add_alloc(Eina_Hash *hash, const char *key, void *data)
1255 if (!hash) hash = eina_hash_string_small_new(NULL);
1256 if (!hash) return NULL;
1258 eina_hash_direct_add(hash, key, data);
1263 _eet_str_direct_alloc(const char *str)
1269 _eet_str_direct_free(__UNUSED__ const char *str)
1274 _eet_eina_hash_foreach(void *hash, Eina_Hash_Foreach cb, void *fdata)
1276 if (hash) eina_hash_foreach(hash, cb, fdata);
1280 _eet_eina_hash_free(void *hash)
1282 if (hash) eina_hash_free(hash);
1287 eet_eina_stream_data_descriptor_class_set(Eet_Data_Descriptor_Class *eddc, const char *name, int size)
1289 if (!eddc || !name) return EINA_FALSE;
1295 eddc->func.mem_alloc = _eet_mem_alloc;
1296 eddc->func.mem_free = _eet_mem_free;
1297 eddc->func.str_alloc = (char *(*)(const char *))eina_stringshare_add;
1298 eddc->func.str_free = eina_stringshare_del;
1299 eddc->func.list_next = (void *(*)(void *))eina_list_next;
1300 eddc->func.list_append = (void *(*)(void *, void *))eina_list_append;
1301 eddc->func.list_data = (void *(*)(void *))eina_list_data_get;
1302 eddc->func.list_free = (void *(*)(void *))eina_list_free;
1303 eddc->func.hash_foreach = (void (*)(void *, int (*)(void *, const char *, void *, void *), void *))_eet_eina_hash_foreach;
1304 eddc->func.hash_add = (void* (*)(void *, const char *, void *)) _eet_eina_hash_add_alloc;
1305 eddc->func.hash_free = (void (*)(void *))_eet_eina_hash_free;
1311 eet_eina_file_data_descriptor_class_set(Eet_Data_Descriptor_Class *eddc, const char *name, int size)
1313 if (!eet_eina_stream_data_descriptor_class_set(eddc, name, size))
1318 eddc->func.hash_add = (void* (*)(void *, const char *, void *)) _eet_eina_hash_direct_add_alloc;
1319 eddc->func.str_direct_alloc = _eet_str_direct_alloc;
1320 eddc->func.str_direct_free = _eet_str_direct_free;
1325 static Eet_Data_Descriptor *
1326 _eet_data_descriptor_new(const Eet_Data_Descriptor_Class *eddc, int version)
1328 Eet_Data_Descriptor *edd;
1330 if (!eddc) return NULL;
1332 edd = calloc(1, sizeof (Eet_Data_Descriptor));
1333 if (!edd) return NULL;
1335 edd->name = eddc->name;
1337 edd->size = eddc->size;
1338 edd->func.mem_alloc = _eet_mem_alloc;
1339 edd->func.mem_free = _eet_mem_free;
1340 edd->func.str_alloc = _eet_str_alloc;
1341 edd->func.str_free = _eet_str_free;
1342 if (eddc->func.mem_alloc)
1343 edd->func.mem_alloc = eddc->func.mem_alloc;
1344 if (eddc->func.mem_free)
1345 edd->func.mem_free = eddc->func.mem_free;
1346 if (eddc->func.str_alloc)
1347 edd->func.str_alloc = eddc->func.str_alloc;
1348 if (eddc->func.str_free)
1349 edd->func.str_free = eddc->func.str_free;
1350 edd->func.list_next = eddc->func.list_next;
1351 edd->func.list_append = eddc->func.list_append;
1352 edd->func.list_data = eddc->func.list_data;
1353 edd->func.list_free = eddc->func.list_free;
1354 edd->func.hash_foreach = eddc->func.hash_foreach;
1355 edd->func.hash_add = eddc->func.hash_add;
1356 edd->func.hash_free = eddc->func.hash_free;
1358 if (eddc->version > 1 && version > 1)
1360 edd->func.str_direct_alloc = eddc->func.str_direct_alloc;
1361 edd->func.str_direct_free = eddc->func.str_direct_free;
1363 if (eddc->version > 2)
1365 edd->func.type_get = eddc->func.type_get;
1366 edd->func.type_set = eddc->func.type_set;
1372 EAPI Eet_Data_Descriptor *
1373 eet_data_descriptor_new(const char *name,
1375 void *(*func_list_next) (void *l),
1376 void *(*func_list_append) (void *l, void *d),
1377 void *(*func_list_data) (void *l),
1378 void *(*func_list_free) (void *l),
1379 void (*func_hash_foreach) (void *h, int (*func) (void *h, const char *k, void *dt, void *fdt), void *fdt),
1380 void *(*func_hash_add) (void *h, const char *k, void *d),
1381 void (*func_hash_free) (void *h))
1383 Eet_Data_Descriptor_Class eddc;
1385 if (!name) return NULL;
1387 memset(&eddc, 0, sizeof (Eet_Data_Descriptor_Class));
1393 eddc.func.list_next = func_list_next;
1394 eddc.func.list_append = func_list_append;
1395 eddc.func.list_data = func_list_data;
1396 eddc.func.list_free = func_list_free;
1397 eddc.func.hash_foreach = func_hash_foreach;
1398 eddc.func.hash_add = func_hash_add;
1399 eddc.func.hash_free = func_hash_free;
1401 return _eet_data_descriptor_new(&eddc, 0);
1404 EAPI Eet_Data_Descriptor *
1405 eet_data_descriptor2_new(const Eet_Data_Descriptor_Class *eddc)
1407 return _eet_data_descriptor_new(eddc, 1);
1410 EAPI Eet_Data_Descriptor *
1411 eet_data_descriptor3_new(const Eet_Data_Descriptor_Class *eddc)
1413 return _eet_data_descriptor_new(eddc, 2);
1416 EAPI Eet_Data_Descriptor *
1417 eet_data_descriptor_stream_new(const Eet_Data_Descriptor_Class *eddc)
1419 return _eet_data_descriptor_new(eddc, 1);
1422 EAPI Eet_Data_Descriptor *
1423 eet_data_descriptor_file_new(const Eet_Data_Descriptor_Class *eddc)
1425 return _eet_data_descriptor_new(eddc, 2);
1429 eet_data_descriptor_free(Eet_Data_Descriptor *edd)
1432 _eet_descriptor_hash_free(edd);
1433 if (edd->elements.set) free(edd->elements.set);
1438 eet_data_descriptor_element_add(Eet_Data_Descriptor *edd,
1444 /* int counter_offset, */
1445 const char *counter_name /* FIXME: Useless should go on a major release */,
1446 Eet_Data_Descriptor *subtype)
1448 Eet_Data_Element *ede;
1449 Eet_Data_Element *tmp;
1451 /* UNION, INHERITED or VARIANT type would not work with simple type, we need a way to map the type. */
1452 if ((group_type == EET_G_INHERIT
1453 || group_type == EET_G_UNION
1454 || group_type == EET_G_VARIANT)
1456 (type != EET_T_UNKNOW
1458 || subtype->func.type_get == NULL
1459 || subtype->func.type_set == NULL))
1462 /* Only one element is allowed with INHERITED type */
1463 if (group_type == EET_G_INHERIT && edd->elements.num != 0)
1465 if (edd->elements.num > 0 && edd->elements.set[0].group_type == EET_G_INHERIT)
1468 /* VARIANT type will only work if the map only contains EET_G_*, but not INHERIT, UNION, VARIANT and ARRAY. */
1469 if (group_type == EET_G_VARIANT)
1473 for (i = 0; i < subtype->elements.num; ++i)
1474 if (subtype->elements.set[i].type != EET_T_UNKNOW
1475 && subtype->elements.set[i].group_type > EET_G_VAR_ARRAY
1476 && subtype->elements.set[i].group_type < EET_G_UNION)
1479 subtype->unified_type = EINA_TRUE;
1482 && subtype->unified_type
1483 && (type != EET_T_UNKNOW
1484 || group_type < EET_G_UNION))
1487 /* Sanity check done, let allocate ! */
1488 edd->elements.num++;
1489 tmp = realloc(edd->elements.set, edd->elements.num * sizeof(Eet_Data_Element));
1491 edd->elements.set = tmp;
1492 ede = &(edd->elements.set[edd->elements.num - 1]);
1494 ede->directory_name_ptr = NULL;
1497 * We do a special case when we do list,hash or whatever group of simple type.
1498 * Instead of handling it in encode/decode/dump/undump, we create an
1499 * implicit structure with only the simple type.
1501 if (group_type > EET_G_UNKNOWN
1502 && group_type < EET_G_LAST
1503 && ((type > EET_T_UNKNOW && type < EET_T_STRING)
1504 || (type > EET_T_NULL && type < EET_T_LAST))
1507 subtype = calloc(1, sizeof (Eet_Data_Descriptor));
1508 if (!subtype) return ;
1509 subtype->name = "implicit";
1510 subtype->size = eet_basic_codec[type - 1].size;
1511 memcpy(&subtype->func, &edd->func, sizeof(subtype->func));
1513 eet_data_descriptor_element_add(subtype, eet_basic_codec[type - 1].name, type,
1514 EET_G_UNKNOWN, 0, 0, /* 0, */NULL, NULL);
1515 type = EET_T_UNKNOW;
1519 ede->group_type = group_type;
1520 ede->offset = offset;
1522 /* FIXME: For the time being, VAR_ARRAY, INHERIT, UNION and VARIANT will put the counter_offset in count. */
1523 ede->counter_offset = count;
1524 /* ede->counter_offset = counter_offset; */
1525 ede->counter_name = counter_name;
1527 ede->subtype = subtype;
1531 eet_data_read_cipher(Eet_File *ef, Eet_Data_Descriptor *edd, const char *name, const char *cipher_key)
1533 const Eet_Dictionary *ed = NULL;
1534 const void *data = NULL;
1536 Eet_Free_Context context;
1537 int required_free = 0;
1540 ed = eet_dictionary_get(ef);
1543 data = eet_read_direct(ef, name, &size);
1547 data = eet_read_cipher(ef, name, &size, cipher_key);
1548 if (!data) return NULL;
1551 memset(&context, 0, sizeof (context));
1552 data_dec = _eet_data_descriptor_decode(&context, ed, edd, data, size);
1560 eet_data_node_read_cipher(Eet_File *ef, const char *name, const char *cipher_key)
1562 const Eet_Dictionary *ed = NULL;
1563 const void *data = NULL;
1565 Eet_Free_Context context;
1566 int required_free = 0;
1569 ed = eet_dictionary_get(ef);
1572 data = eet_read_direct(ef, name, &size);
1576 data = eet_read_cipher(ef, name, &size, cipher_key);
1577 if (!data) return NULL;
1580 memset(&context, 0, sizeof (context));
1581 result = _eet_data_descriptor_decode(&context, ed, NULL, data, size);
1589 eet_data_read(Eet_File *ef, Eet_Data_Descriptor *edd, const char *name)
1591 return eet_data_read_cipher(ef, edd, name, NULL);
1595 eet_data_write_cipher(Eet_File *ef, Eet_Data_Descriptor *edd, const char *name, const char *cipher_key, const void *data, int compress)
1602 ed = eet_dictionary_get(ef);
1604 data_enc = _eet_data_descriptor_encode(ed, edd, data, &size);
1605 if (!data_enc) return 0;
1606 val = eet_write_cipher(ef, name, data_enc, size, compress, cipher_key);
1612 eet_data_write(Eet_File *ef, Eet_Data_Descriptor *edd, const char *name, const void *data, int compress)
1614 return eet_data_write_cipher(ef, edd, name, NULL, data, compress);
1618 _eet_free_hash(void *data)
1620 unsigned long ptr = (unsigned long)(data);
1639 _eet_free_add(Eet_Free *ef, void *data)
1644 hash = _eet_free_hash(data);
1646 for (i = 0; i < ef->num[hash]; ++i)
1647 if (ef->list[hash][i] == data) return;
1650 if (ef->num[hash] > ef->len[hash])
1654 tmp = realloc(ef->list[hash], (ef->len[hash] + 16) * sizeof(void*));
1657 ef->len[hash] += 16;
1658 ef->list[hash] = tmp;
1660 ef->list[hash][ef->num[hash] - 1] = data;
1663 _eet_free_reset(Eet_Free *ef)
1667 if (ef->ref > 0) return ;
1668 for (i = 0; i < 256; ++i)
1672 if (ef->list[i]) free(ef->list[i]);
1677 _eet_free_ref(Eet_Free *ef)
1682 _eet_free_unref(Eet_Free *ef)
1687 #define _eet_freelist_add(Ctx, Data) _eet_free_add(&Ctx->freelist, Data);
1688 #define _eet_freelist_reset(Ctx) _eet_free_reset(&Ctx->freelist);
1689 #define _eet_freelist_ref(Ctx) _eet_free_ref(&Ctx->freelist);
1690 #define _eet_freelist_unref(Ctx) _eet_free_unref(&Ctx->freelist);
1693 _eet_freelist_free(Eet_Free_Context *context, Eet_Data_Descriptor *edd)
1698 if (context->freelist.ref > 0) return;
1699 for (j = 0; j < 256; ++j)
1700 for (i = 0; i < context->freelist.num[j]; ++i)
1703 edd->func.mem_free(context->freelist.list[j][i]);
1705 free(context->freelist.list[j][i]);
1707 _eet_free_reset(&context->freelist);
1710 #define _eet_freelist_list_add(Ctx, Data) _eet_free_add(&Ctx->freelist_list, Data);
1711 #define _eet_freelist_list_reset(Ctx) _eet_free_reset(&Ctx->freelist_list);
1712 #define _eet_freelist_list_ref(Ctx) _eet_free_ref(&Ctx->freelist_list);
1713 #define _eet_freelist_list_unref(Ctx) _eet_free_unref(&Ctx->freelist_list);
1716 _eet_freelist_list_free(Eet_Free_Context *context, Eet_Data_Descriptor *edd)
1721 if (context->freelist_list.ref > 0) return;
1722 for (j = 0; j < 256; ++j)
1723 for (i = 0; i < context->freelist_list.num[j]; ++i)
1726 edd->func.list_free(*((void**)(context->freelist_list.list[j][i])));
1728 _eet_free_reset(&context->freelist_list);
1731 #define _eet_freelist_str_add(Ctx, Data) _eet_free_add(&Ctx->freelist_str, Data);
1732 #define _eet_freelist_str_reset(Ctx) _eet_free_reset(&Ctx->freelist_str);
1733 #define _eet_freelist_str_ref(Ctx) _eet_free_ref(&Ctx->freelist_str);
1734 #define _eet_freelist_str_unref(Ctx) _eet_free_unref(&Ctx->freelist_str);
1737 _eet_freelist_str_free(Eet_Free_Context *context, Eet_Data_Descriptor *edd)
1742 if (context->freelist_str.ref > 0) return;
1743 for (j = 0; j < 256; ++j)
1744 for (i = 0; i < context->freelist_str.num[j]; ++i)
1747 edd->func.str_free(context->freelist_str.list[j][i]);
1749 free(context->freelist_str.list[j][i]);
1751 _eet_free_reset(&context->freelist_str);
1754 #define _eet_freelist_direct_str_add(Ctx, Data) _eet_free_add(&Ctx->freelist_direct_str, Data);
1755 #define _eet_freelist_direct_str_reset(Ctx) _eet_free_reset(&Ctx->freelist_direct_str);
1756 #define _eet_freelist_direct_str_ref(Ctx) _eet_free_ref(&Ctx->freelist_direct_str);
1757 #define _eet_freelist_direct_str_unref(Ctx) _eet_free_unref(&Ctx->freelist_direct_str);
1760 _eet_freelist_direct_str_free(Eet_Free_Context *context, Eet_Data_Descriptor *edd)
1765 if (context->freelist_direct_str.ref > 0) return;
1766 for (j = 0; j < 256; ++j)
1767 for (i = 0; i < context->freelist_direct_str.num[j]; ++i)
1770 edd->func.str_direct_free(context->freelist_direct_str.list[j][i]);
1772 free(context->freelist_direct_str.list[j][i]);
1774 _eet_free_reset(&context->freelist_direct_str);
1777 #define _eet_freelist_hash_add(Ctx, Data) _eet_free_add(&Ctx->freelist_hash, Data);
1778 #define _eet_freelist_hash_reset(Ctx) _eet_free_reset(&Ctx->freelist_hash);
1779 #define _eet_freelist_hash_ref(Ctx) _eet_free_ref(&Ctx->freelist_hash);
1780 #define _eet_freelist_hash_unref(Ctx) _eet_free_unref(&Ctx->freelist_hash);
1783 _eet_freelist_hash_free(Eet_Free_Context *context, Eet_Data_Descriptor *edd)
1788 if (context->freelist_hash.ref > 0) return;
1789 for (j = 0; j < 256; ++j)
1790 for (i = 0; i < context->freelist_hash.num[j]; ++i)
1793 edd->func.hash_free(context->freelist_hash.list[j][i]);
1795 free(context->freelist_hash.list[j][i]);
1797 _eet_free_reset(&context->freelist_hash);
1801 _eet_freelist_all_ref(Eet_Free_Context *freelist_context)
1803 _eet_freelist_ref(freelist_context);
1804 _eet_freelist_str_ref(freelist_context);
1805 _eet_freelist_list_ref(freelist_context);
1806 _eet_freelist_hash_ref(freelist_context);
1807 _eet_freelist_direct_str_ref(freelist_context);
1811 _eet_freelist_all_unref(Eet_Free_Context *freelist_context)
1813 _eet_freelist_unref(freelist_context);
1814 _eet_freelist_str_unref(freelist_context);
1815 _eet_freelist_list_unref(freelist_context);
1816 _eet_freelist_hash_unref(freelist_context);
1817 _eet_freelist_direct_str_unref(freelist_context);
1821 eet_data_descriptor_encode_hash_cb(void *hash __UNUSED__, const char *cipher_key, void *hdata, void *fdata)
1824 Eet_Data_Encode_Hash_Info *edehi;
1825 Eet_Data_Stream *ds;
1826 Eet_Data_Element *ede;
1827 Eet_Data_Chunk *echnk;
1837 data = eet_data_put_type(ed,
1843 echnk = eet_data_chunk_new(data, size, ede->name, ede->type, ede->group_type);
1844 eet_data_chunk_put(ed, echnk, ds);
1845 eet_data_chunk_free(echnk);
1850 EET_ASSERT(!((ede->type > EET_T_UNKNOW) && (ede->type < EET_T_STRING)), return );
1853 if (ede->type >= EET_T_STRING)
1854 eet_data_put_unknown(ed, NULL, ede, ds, &hdata);
1858 data = _eet_data_descriptor_encode(ed,
1864 echnk = eet_data_chunk_new(data, size, ede->name, ede->type, ede->group_type);
1865 eet_data_chunk_put(ed, echnk, ds);
1866 eet_data_chunk_free(echnk);
1876 _eet_data_dump_token_get(const char *src, int *len)
1882 int tlen = 0, tsize = 0;
1884 #define TOK_ADD(x) \
1887 if (tlen >= tsize) \
1890 tok = realloc(tok, tsize); \
1892 tok[tlen - 1] = x; \
1895 for (p = src; *len > 0; p++, (*len)--)
1901 if ((p[0] == '\"') && (p > src) && (p[-1] != '\\'))
1905 else if ((p[0] == '\\') && (*len > 1) && (p[1] == '\"'))
1909 else if ((p[0] == '\\') && (p > src) && (p[-1] == '\\'))
1913 else if ((p[0] == '\\') && (*len > 1) && (p[1] == 'n'))
1917 else if ((p[0] == 'n') && (p > src) && (p[-1] == '\\'))
1926 if (p[0] == '\"') in_quote = 1;
1929 if ((isspace(p[0])) || (p[0] == ';')) /* token ends here */
1942 if (!((isspace(p[0])) || (p[0] == ';')))
1960 eet_data_encode(Eet_Dictionary *ed, Eet_Data_Stream *ds, void *data, const char *name, int size, int type, int group_type)
1962 Eet_Data_Chunk *echnk;
1964 if (!data) type = EET_T_NULL;
1966 if (group_type != EET_G_UNKNOWN)
1967 if (type >= EET_T_LAST)
1968 type = EET_T_UNKNOW;
1970 echnk = eet_data_chunk_new(data, size, name, type, group_type);
1971 eet_data_chunk_put(ed, echnk, ds);
1972 eet_data_chunk_free(echnk);
1977 _eet_data_dump_encode(int parent_type,
1982 Eet_Data_Chunk *chnk = NULL;
1983 Eet_Data_Stream *ds;
1990 if (_eet_data_words_bigendian == -1)
1992 unsigned long int v;
1994 v = htonl(0x12345678);
1995 if (v == 0x12345678) _eet_data_words_bigendian = 1;
1996 else _eet_data_words_bigendian = 0;
1999 if (node == NULL) return NULL;
2001 ds = eet_data_stream_new();
2002 if (!ds) return NULL;
2007 for (n = node->values; n; n = n->next)
2009 data = _eet_data_dump_encode(node->type, ed, n, &size);
2012 eet_data_stream_write(ds, data, size);
2018 case EET_G_VAR_ARRAY:
2019 for (child_type = EET_T_NULL, n = node->values; n; n = n->next)
2021 if (n->type != EET_T_NULL)
2023 child_type = n->type;
2028 data = eet_data_put_type(ed,
2032 eet_data_encode(ed, ds, data, node->name, size, child_type, node->type);
2034 count = node->count;
2036 for (n = node->values; n; n = n->next)
2043 case EET_T_INLINED_STRING:
2044 data = eet_data_put_type(ed, n->type, &(n->data.value.str), &size);
2045 if (data) eet_data_encode(ed, ds, data, node->name, size, n->type, node->type);
2050 data = _eet_data_dump_encode(n->type, ed, n, &size);
2051 eet_data_encode(ed, ds, data, node->name, size, n->type, node->type);
2054 if (ds->pos != pos) count--;
2057 for (; count; count--)
2059 eet_data_encode(ed, ds, NULL, node->name, 0, EET_T_NULL, node->type);
2062 /* Array is somekind of special case, so we should embed it inside another chunk. */
2063 *size_ret = ds->pos;
2068 eet_data_stream_free(ds);
2073 for (n = node->values; n; n = n->next)
2078 case EET_T_INLINED_STRING:
2079 data = eet_data_put_type(ed, n->type, &(n->data.value.str), &size);
2080 if (data) eet_data_encode(ed, ds, data, node->name, size, n->type, node->type);
2085 data = _eet_data_dump_encode(node->type, ed, n, &size);
2086 eet_data_encode(ed, ds, data, node->name, size, n->type, node->type);
2090 /* List is another somekind of special case, every chunk is embed inside a list chunk. */
2091 *size_ret = ds->pos;
2096 eet_data_stream_free(ds);
2103 data = eet_data_put_type(ed,
2107 eet_data_encode(ed, ds, data, node->name, size, node->type, node->type);
2110 /* A Hash without key will not decode correctly. */
2113 for (n = node->values; n; n = n->next)
2118 case EET_T_INLINED_STRING:
2119 data = eet_data_put_type(ed, n->type, &(n->data.value.str), &size);
2120 if (data) eet_data_encode(ed, ds, data, node->name, size, n->type, node->type);
2125 data = _eet_data_dump_encode(node->type, ed, n, &size);
2126 eet_data_encode(ed, ds, data, node->name, size, n->type, node->type);
2130 /* Hash is somekind of special case, so we should embed it inside another chunk. */
2131 *size_ret = ds->pos;
2134 eet_data_stream_flush(ds);
2140 #define EET_DATA_NODE_ENCODE(Eet_Type, Type) \
2142 data = eet_data_put_type(ed, node->type, &(node->data.value.Type), &size); \
2145 eet_data_encode(ed, ds, data, node->name, size, node->type, parent_type); \
2147 *size_ret = ds->pos; \
2148 eet_data_stream_flush(ds); \
2153 EET_DATA_NODE_ENCODE(EET_T_CHAR, c);
2154 EET_DATA_NODE_ENCODE(EET_T_SHORT, s);
2155 EET_DATA_NODE_ENCODE(EET_T_INT, i);
2156 EET_DATA_NODE_ENCODE(EET_T_LONG_LONG, l);
2157 EET_DATA_NODE_ENCODE(EET_T_FLOAT, f);
2158 EET_DATA_NODE_ENCODE(EET_T_DOUBLE, d);
2159 EET_DATA_NODE_ENCODE(EET_T_UCHAR, uc);
2160 EET_DATA_NODE_ENCODE(EET_T_USHORT, us);
2161 EET_DATA_NODE_ENCODE(EET_T_UINT, ui);
2162 EET_DATA_NODE_ENCODE(EET_T_ULONG_LONG, ul);
2163 EET_DATA_NODE_ENCODE(EET_T_INLINED_STRING, str);
2164 EET_DATA_NODE_ENCODE(EET_T_STRING, str);
2169 if ((node->type >= EET_G_UNKNOWN) && (node->type < EET_G_LAST))
2170 chnk = eet_data_chunk_new(ds->data, ds->pos, node->name, EET_T_UNKNOW, node->type);
2172 chnk = eet_data_chunk_new(ds->data, ds->pos, node->name, node->type, EET_G_UNKNOWN);
2173 eet_data_stream_flush(ds);
2175 ds = eet_data_stream_new();
2176 eet_data_chunk_put(ed, chnk, ds);
2180 eet_data_stream_flush(ds);
2184 eet_data_chunk_free(chnk);
2190 _eet_data_dump_parse(Eet_Dictionary *ed,
2196 const char *p = NULL;
2201 Eet_Node *node_base = NULL;
2202 Eet_Node *node = NULL;
2203 Eet_Node *n = NULL, *nn = NULL;
2205 /* FIXME; handle parse errors */
2206 #define TOK_GET(t) \
2207 jump = left; t = _eet_data_dump_token_get(p, &left); p += jump - left;
2209 for (p = src; p < (src + size);)
2211 char *tok1, *tok2, *tok3, *tok4;
2216 if (!strcmp(tok1, "group"))
2227 if (!strcmp(tok4, "{"))
2229 /* we have 'group NAM TYP {' */
2245 for (nn = node->values; nn; nn = nn->next)
2255 n->name = eina_stringshare_add(tok2);
2256 if (!strcmp(tok3, "struct")) n->type = EET_G_UNKNOWN;
2257 else if (!strcmp(tok3, "array")) n->type = EET_G_ARRAY;
2258 else if (!strcmp(tok3, "var_array")) n->type = EET_G_VAR_ARRAY;
2259 else if (!strcmp(tok3, "list")) n->type = EET_G_LIST;
2260 else if (!strcmp(tok3, "hash")) n->type = EET_G_HASH;
2263 ERR("ERROR: group type '%s' invalid.", tok3);
2275 else if (!strcmp(tok1, "value"))
2286 /* we have 'value NAME TYP XXX' */
2298 for (nn = node->values; nn; nn = nn->next)
2307 n->name = eina_stringshare_add(tok2);
2308 if (!strcmp(tok3, "char:"))
2310 n->type = EET_T_CHAR;
2311 sscanf(tok4, "%hhi", &(n->data.value.c));
2313 else if (!strcmp(tok3, "short:"))
2315 n->type = EET_T_SHORT;
2316 sscanf(tok4, "%hi", &(n->data.value.s));
2318 else if (!strcmp(tok3, "int:"))
2320 n->type = EET_T_INT;
2321 sscanf(tok4, "%i", &(n->data.value.i));
2323 else if (!strcmp(tok3, "long_long:"))
2325 n->type = EET_T_LONG_LONG;
2326 sscanf(tok4, "%lli", &(n->data.value.l));
2328 else if (!strcmp(tok3, "float:"))
2330 n->type = EET_T_FLOAT;
2331 sscanf(tok4, "%f", &(n->data.value.f));
2333 else if (!strcmp(tok3, "double:"))
2335 n->type = EET_T_DOUBLE;
2336 sscanf(tok4, "%lf", &(n->data.value.d));
2338 else if (!strcmp(tok3, "uchar:"))
2340 n->type = EET_T_UCHAR;
2341 sscanf(tok4, "%hhu", &(n->data.value.uc));
2343 else if (!strcmp(tok3, "ushort:"))
2345 n->type = EET_T_USHORT;
2346 sscanf(tok4, "%hu", &(n->data.value.us));
2348 else if (!strcmp(tok3, "uint:"))
2350 n->type = EET_T_UINT;
2351 sscanf(tok4, "%u", &(n->data.value.ui));
2353 else if (!strcmp(tok3, "ulong_long:"))
2355 n->type = EET_T_ULONG_LONG;
2356 sscanf(tok4, "%llu", &(n->data.value.ul));
2358 else if (!strcmp(tok3, "string:"))
2360 n->type = EET_T_STRING;
2361 n->data.value.str = eina_stringshare_add(tok4);
2363 else if (!strcmp(tok3, "inlined:"))
2365 n->type = EET_T_INLINED_STRING;
2366 n->data.value.str = eina_stringshare_add(tok4);
2368 else if (!strcmp(tok3, "null"))
2370 n->type = EET_T_NULL;
2371 n->data.value.str = NULL;
2375 ERR("ERROR: value type '%s' invalid.", tok4);
2386 else if (!strcmp(tok1, "key"))
2391 /* we have 'key NAME' */
2394 node->key = eina_stringshare_add(tok2);
2399 else if (!strcmp(tok1, "count"))
2404 /* we have a 'count COUNT' */
2407 sscanf(tok2, "%i", &(node->count));
2412 else if (!strcmp(tok1, "}"))
2414 /* we have an end of the group */
2415 if (node) node = node->parent;
2423 cdata = _eet_data_dump_encode(EET_G_UNKNOWN, ed, node_base, size_ret);
2424 eet_node_del(node_base);
2429 #define NEXT_CHUNK(P, Size, Echnk, Ed) \
2432 tmp = Ed ? (int) (sizeof(int) * 2) : Echnk.len + 4;\
2433 P += (4 + Echnk.size + tmp); \
2434 Size -= (4 + Echnk.size + tmp); \
2438 _eet_data_descriptor_decode(Eet_Free_Context *context,
2439 const Eet_Dictionary *ed,
2440 Eet_Data_Descriptor *edd,
2441 const void *data_in,
2444 Eet_Node *result = NULL;
2448 Eet_Data_Chunk chnk;
2450 if (_eet_data_words_bigendian == -1)
2452 unsigned long int v;
2454 v = htonl(0x12345678);
2455 if (v == 0x12345678) _eet_data_words_bigendian = 1;
2456 else _eet_data_words_bigendian = 0;
2461 data = edd->func.mem_alloc(edd->size);
2462 if (!data) return NULL;
2465 for (i = 0; i < edd->elements.num; i++)
2466 edd->elements.set[i].directory_name_ptr = NULL;
2470 _eet_freelist_all_ref(context);
2471 if (data) _eet_freelist_add(context, data);
2472 memset(&chnk, 0, sizeof(Eet_Data_Chunk));
2473 eet_data_chunk_get(ed, &chnk, data_in, size_in);
2474 if (!chnk.name) goto error;
2477 if (strcmp(chnk.name, edd->name)) goto error;
2481 size = size_in - (4 + sizeof(int) * 2);
2483 size = size_in - (4 + 4 + chnk.len);
2486 if (!edd->elements.hash.buckets) _eet_descriptor_hash_new(edd);
2490 switch (chnk.group_type)
2496 return eet_node_string_new(chnk.name, chnk.data);
2497 case EET_T_INLINED_STRING:
2498 return eet_node_inlined_string_new(chnk.name, chnk.data);
2500 return eet_node_null_new(chnk.name);
2502 result = eet_node_struct_new(chnk.name, NULL);
2505 case EET_G_VAR_ARRAY:
2506 return eet_node_var_array_new(chnk.name, NULL);
2508 /* This one should work */
2521 Eet_Data_Chunk echnk;
2522 Eet_Data_Element *ede = NULL;
2523 Eet_Node *child = NULL;
2524 int group_type = EET_G_UNKNOWN, type = EET_T_UNKNOW;
2527 /* get next data chunk */
2528 memset(&echnk, 0, sizeof(Eet_Data_Chunk));
2529 eet_data_chunk_get(ed, &echnk, p, size);
2530 if (!echnk.name) goto error;
2531 /* FIXME: don't REPLY on edd - work without */
2534 ede = _eet_descriptor_hash_find(edd, echnk.name, echnk.hash);
2537 group_type = ede->group_type;
2539 if ((echnk.type == 0) && (echnk.group_type == 0))
2542 group_type = ede->group_type;
2546 if (IS_SIMPLE_TYPE(echnk.type) &&
2547 eet_data_type_match(echnk.type, ede->type))
2548 /* Needed when converting on the fly from FP to Float */
2550 else if ((echnk.group_type > EET_G_UNKNOWN) &&
2551 (echnk.group_type < EET_G_LAST) &&
2552 (echnk.group_type == ede->group_type))
2553 group_type = echnk.group_type;
2557 /*...... dump to node */
2561 group_type = echnk.group_type;
2564 if (!edd && group_type == EET_G_UNKNOWN && IS_SIMPLE_TYPE(type))
2566 unsigned char dd[128];
2568 ret = eet_data_get_type(ed,
2571 ((char *)echnk.data) + echnk.size,
2573 if (ret <= 0) goto error;
2575 child = eet_data_node_simple_type(type, echnk.name, dd);
2577 eet_node_struct_append(result, echnk.name, child);
2581 ret = eet_group_codec[group_type - 100].get(context,
2582 ed, edd, ede, &echnk,
2583 type, group_type, ede ? (void*) (((char *)data) + ede->offset) : (void**) &result,
2586 if (ret <= 0) goto error;
2589 /* advance to next chunk */
2590 NEXT_CHUNK(p, size, echnk, ed);
2593 _eet_freelist_all_unref(context);
2596 _eet_freelist_str_free(context, edd);
2597 _eet_freelist_direct_str_free(context, edd);
2598 _eet_freelist_list_free(context, edd);
2599 _eet_freelist_hash_free(context, edd);
2600 _eet_freelist_free(context, edd);
2604 _eet_freelist_reset(context);
2605 _eet_freelist_str_reset(context);
2606 _eet_freelist_list_reset(context);
2607 _eet_freelist_hash_reset(context);
2608 _eet_freelist_direct_str_reset(context);
2617 eet_node_del(result);
2619 _eet_freelist_all_unref(context);
2620 _eet_freelist_str_free(context, edd);
2621 _eet_freelist_direct_str_free(context, edd);
2622 _eet_freelist_list_free(context, edd);
2623 _eet_freelist_hash_free(context, edd);
2624 _eet_freelist_free(context, edd);
2626 /* FIXME: Warn that something goes wrong here. */
2631 eet_data_get_list(Eet_Free_Context *context, const Eet_Dictionary *ed, Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Chunk *echnk,
2632 int type, int group_type __UNUSED__, void *data,
2633 char **p, int *size)
2635 Eet_Data_Descriptor *subtype = NULL;
2640 EET_ASSERT(!((type > EET_T_UNKNOW) && (type < EET_T_STRING)), return 0);
2644 subtype = ede->subtype;
2646 if (type != ede->type)
2650 ptr = (void **)data;
2654 if (IS_POINTER_TYPE(type))
2658 ret = eet_data_get_unknown(context, ed, edd, ede, echnk, type, EET_G_UNKNOWN,
2659 &data_ret, p, size);
2664 data_ret = _eet_data_descriptor_decode(context, ed, subtype,
2665 echnk->data, echnk->size);
2666 if (!data_ret) return 0;
2671 list = edd->func.list_append(list, data_ret);
2673 _eet_freelist_list_add(context, ptr);
2677 eet_node_list_append(*((Eet_Node**) data), echnk->name, data_ret);
2684 eet_data_get_hash(Eet_Free_Context *context, const Eet_Dictionary *ed, Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Chunk *echnk,
2685 int type, int group_type __UNUSED__, void *data,
2686 char **p, int *size)
2691 void *data_ret = NULL;
2694 EET_ASSERT(!((type > EET_T_UNKNOW) && (type < EET_T_STRING)), return 0);
2696 ptr = (void **)data;
2700 ret = eet_data_get_type(ed,
2703 ((char *)echnk->data) + echnk->size,
2705 if (ret <= 0) goto on_error;
2707 /* Advance to next chunk */
2708 NEXT_CHUNK((*p), (*size), (*echnk), ed);
2709 memset(echnk, 0, sizeof(Eet_Data_Chunk));
2712 eet_data_chunk_get(ed, echnk, *p, *size);
2713 if (!echnk->name) goto on_error;
2715 if (IS_POINTER_TYPE(echnk->type))
2717 ret = eet_data_get_unknown(context, ed, edd, ede, echnk, echnk->type, EET_G_UNKNOWN,
2718 &data_ret, p, size);
2719 if (!ret) goto on_error;
2723 data_ret = _eet_data_descriptor_decode(context,
2725 ede ? ede->subtype : NULL,
2728 if (!data_ret) goto on_error;
2733 hash = edd->func.hash_add(hash, key, data_ret);
2735 _eet_freelist_hash_add(context, hash);
2739 eet_node_hash_add(*((Eet_Node **) data), echnk->name, key, data_ret);
2748 /* var arrays and fixed arrays have to
2749 * get all chunks at once. for fixed arrays
2750 * we can get each chunk and increment a
2751 * counter stored on the element itself but
2752 * it wont be thread safe. for var arrays
2753 * we still need a way to get the number of
2754 * elements from the data, so storing the
2755 * number of elements and the element data on
2756 * each chunk is pointless.
2759 eet_data_get_array(Eet_Free_Context *context, const Eet_Dictionary *ed, Eet_Data_Descriptor *edd,
2760 Eet_Data_Element *ede, Eet_Data_Chunk *echnk,
2761 int type, int group_type, void *data,
2762 char **p, int *size)
2764 Eina_List *childs = NULL;
2773 EET_ASSERT(!((type > EET_T_UNKNOW) && (type < EET_T_STRING)), return 0);
2776 /* read the number of elements */
2777 ret = eet_data_get_type(ed,
2780 ((char *)echnk->data) + echnk->size,
2782 if (ret <= 0) return ret;
2788 if (IS_POINTER_TYPE(type))
2789 subsize = eet_basic_codec[ede->type].size;
2791 subsize = ede->subtype->size;
2793 if (group_type == EET_G_VAR_ARRAY)
2795 /* store the number of elements
2796 * on the counter offset */
2797 *(int *)(((char *)data) + ede->count - ede->offset) = count;
2798 /* allocate space for the array of elements */
2799 *(void **)ptr = edd->func.mem_alloc(count * subsize);
2801 if (!*(void **)ptr) return 0;
2803 memset(*(void **)ptr, 0, count * subsize);
2805 _eet_freelist_add(context, *(void **)ptr);
2809 /* get all array elements */
2810 for (i = 0; i < count; i++)
2813 void *data_ret = NULL;
2815 /* Advance to next chunk */
2816 NEXT_CHUNK((*p), (*size), (*echnk), ed);
2817 memset(echnk, 0, sizeof(Eet_Data_Chunk));
2819 eet_data_chunk_get(ed, echnk, *p, *size);
2820 if (!echnk->name || strcmp(echnk->name, name) != 0) goto on_error;
2823 if (echnk->group_type != group_type
2824 || (echnk->type != type && echnk->type != EET_T_NULL))
2828 if (ede->group_type != echnk->group_type
2829 || (echnk->type != ede->type && echnk->type != EET_T_NULL))
2832 /* get the destination pointer */
2835 if (group_type == EET_G_ARRAY)
2836 dst = (char *)ptr + (subsize * i);
2838 dst = *(char **)ptr + (subsize * i);
2841 if (IS_POINTER_TYPE(echnk->type))
2843 ret = eet_data_get_unknown(context, ed, edd, ede, echnk, echnk->type, EET_G_UNKNOWN,
2844 &data_ret, p, size);
2845 if (!ret) goto on_error;
2846 if (dst) memcpy(dst, &data_ret, subsize);
2847 if (!edd) childs = eina_list_append(childs, data_ret);
2851 data_ret = _eet_data_descriptor_decode(context, ed, ede ? ede->subtype : NULL,
2852 echnk->data, echnk->size);
2853 if (!data_ret) goto on_error;
2856 memcpy(dst, data_ret, subsize);
2857 _eet_freelist_add(context, data_ret);
2859 if (!edd) childs = eina_list_append(childs, data_ret);
2865 Eet_Node *parent = *((Eet_Node **) data);
2868 if (group_type == EET_G_ARRAY)
2869 array = eet_node_array_new(name, count, childs);
2871 array = eet_node_var_array_new(name, childs);
2873 if (!array) goto on_error;
2875 eet_node_struct_append(parent, name, array);
2881 EINA_LIST_FREE(childs, tmp)
2888 eet_data_put_union(Eet_Dictionary *ed,
2889 __UNUSED__ Eet_Data_Descriptor *edd,
2890 Eet_Data_Element *ede, Eet_Data_Stream *ds, void *data_in)
2892 const char *union_type;
2895 EET_ASSERT(!((ede->type != EET_T_UNKNOW) || (!ede->subtype)), return );
2897 union_type = ede->subtype->func.type_get(((char*) data_in) + ede->count - ede->offset,
2900 if (!union_type) return ;
2902 /* Search the structure of the union to encode. */
2903 for (i = 0; i < ede->subtype->elements.num; ++i)
2904 if (strcmp(ede->subtype->elements.set[i].name, union_type) == 0)
2906 Eet_Data_Element *sede;
2910 /* Yeah we found it ! */
2911 data = eet_data_put_type(ed, EET_T_STRING, &union_type, &size);
2912 if (data) eet_data_encode(ed, ds, data, ede->name, size, ede->type, ede->group_type);
2914 sede = &(ede->subtype->elements.set[i]);
2915 data = _eet_data_descriptor_encode(ed,
2919 if (data) eet_data_encode(ed, ds, data, ede->name, size, ede->type, ede->group_type);
2925 eet_data_get_union(Eet_Free_Context *context, const Eet_Dictionary *ed,
2926 __UNUSED__ Eet_Data_Descriptor *edd,
2927 Eet_Data_Element *ede, Eet_Data_Chunk *echnk,
2928 int type, int group_type, void *data,
2929 char **p, int *size)
2931 const char *union_type;
2932 void *data_ret = NULL;
2937 ret = eet_data_get_type(ed,
2940 ((char *)echnk->data) + echnk->size,
2942 if (ret <= 0) goto on_error;
2944 /* Advance to next chunk */
2945 NEXT_CHUNK((*p), (*size), (*echnk), ed);
2946 memset(echnk, 0, sizeof(Eet_Data_Chunk));
2949 eet_data_chunk_get(ed, echnk, *p, *size);
2950 if (!echnk->name) goto on_error;
2954 EET_ASSERT(!(ede->group_type != group_type || ede->type != type), goto on_error);
2956 /* Search the structure of the union to decode */
2957 for (i = 0; i < ede->subtype->elements.num; ++i)
2958 if (strcmp(ede->subtype->elements.set[i].name, union_type) == 0)
2960 Eet_Data_Element *sede;
2963 /* Yeah we found it ! */
2964 sede = &(ede->subtype->elements.set[i]);
2965 EET_ASSERT(sede->subtype, goto on_error);
2967 data_ret = _eet_data_descriptor_decode(context,
2972 if (!data_ret) goto on_error;
2974 /* Memcopy the structure content to remove pointer indirection. */
2975 memcpy(data, data_ret, sede->subtype->size);
2977 /* data_ret is now useless. */
2978 sede->subtype->func.mem_free(data_ret);
2980 /* Set union type. */
2981 if ((!ed) || (!ede->subtype->func.str_direct_alloc))
2983 ut = ede->subtype->func.str_alloc(union_type);
2984 _eet_freelist_str_add(context, ut);
2988 ut = ede->subtype->func.str_direct_alloc(union_type);
2989 _eet_freelist_direct_str_add(context, ut);
2992 ede->subtype->func.type_set(ut,
2993 ((char*) data) + ede->count - ede->offset,
3001 /* FIXME: generate node structure. */
3002 data_ret = _eet_data_descriptor_decode(context,
3004 echnk->data, echnk->size);
3015 eet_data_put_inherit(Eet_Dictionary *ed, Eet_Data_Descriptor *edd, Eet_Data_Element *ede,
3016 Eet_Data_Stream *ds, void *data_in)
3019 fprintf(stderr, "wrong !!!\n");
3023 eet_data_get_inherit(Eet_Free_Context *context, const Eet_Dictionary *ed, Eet_Data_Descriptor *edd,
3024 Eet_Data_Element *ede, Eet_Data_Chunk *echnk,
3025 int type, int group_type, void *data,
3026 char **p, int *size)
3033 eet_data_put_variant(Eet_Dictionary *ed,
3034 __UNUSED__ Eet_Data_Descriptor *edd,
3035 Eet_Data_Element *ede, Eet_Data_Stream *ds, void *data_in)
3037 const char *union_type;
3039 Eina_Bool unknow = EINA_FALSE;
3043 EET_ASSERT(!((ede->type != EET_T_UNKNOW) || (!ede->subtype)), return );
3045 union_type = ede->subtype->func.type_get(((char*) data_in) + ede->count - ede->offset,
3048 if (!union_type && unknow == EINA_FALSE) return ;
3052 /* Handle opaque internal representation */
3053 Eet_Variant_Unknow *evu;
3055 data = eet_data_put_type(ed, EET_T_STRING, &union_type, &size);
3056 if (data) eet_data_encode(ed, ds, data, ede->name, size, ede->type, ede->group_type);
3058 evu = (Eet_Variant_Unknow*) data_in;
3059 if (evu && EINA_MAGIC_CHECK(evu, EET_MAGIC_VARIANT))
3060 eet_data_encode(ed, ds, evu->data, ede->name, evu->size, ede->type, ede->group_type);
3064 /* Search the structure of the union to encode. */
3065 for (i = 0; i < ede->subtype->elements.num; ++i)
3066 if (strcmp(ede->subtype->elements.set[i].name, union_type) == 0)
3068 Eet_Data_Element *sede;
3070 /* Yeah we found it ! */
3071 data = eet_data_put_type(ed, EET_T_STRING, &union_type, &size);
3072 if (data) eet_data_encode(ed, ds, data, ede->name, size, ede->type, ede->group_type);
3074 sede = &(ede->subtype->elements.set[i]);
3076 if (sede->group_type != EET_G_UNKNOWN)
3078 Eet_Data_Stream *lds;
3080 lds = eet_data_stream_new();
3081 eet_group_codec[sede->group_type - 100].put(ed,
3088 eet_data_encode(ed, ds, lds->data, ede->name, lds->pos,
3089 ede->type, ede->group_type);
3096 eet_data_encode(ed, ds, NULL, ede->name, 0,
3097 EET_T_NULL, ede->group_type);
3100 eet_data_stream_free(lds);
3104 data = _eet_data_descriptor_encode(ed,
3108 if (data) eet_data_encode(ed, ds, data, ede->name, size, ede->type, ede->group_type);
3117 eet_data_get_variant(Eet_Free_Context *context, const Eet_Dictionary *ed,
3118 __UNUSED__ Eet_Data_Descriptor *edd,
3119 Eet_Data_Element *ede, Eet_Data_Chunk *echnk,
3120 int type, int group_type, void *data,
3121 char **p, int *size)
3123 const char *union_type;
3124 void *data_ret = NULL;
3129 ret = eet_data_get_type(ed,
3132 ((char *)echnk->data) + echnk->size,
3134 if (ret <= 0) goto on_error;
3136 /* Advance to next chunk */
3137 NEXT_CHUNK((*p), (*size), (*echnk), ed);
3138 memset(echnk, 0, sizeof(Eet_Data_Chunk));
3141 eet_data_chunk_get(ed, echnk, *p, *size);
3142 if (!echnk->name) goto on_error;
3148 EET_ASSERT(ede->subtype, goto on_error);
3150 if ((!ed) || (!ede->subtype->func.str_direct_alloc))
3152 ut = ede->subtype->func.str_alloc(union_type);
3153 _eet_freelist_str_add(context, ut);
3157 ut = ede->subtype->func.str_direct_alloc(union_type);
3158 _eet_freelist_direct_str_add(context, ut);
3161 /* Search the structure of the union to decode */
3162 for (i = 0; i < ede->subtype->elements.num; ++i)
3163 if (strcmp(ede->subtype->elements.set[i].name, union_type) == 0)
3165 Eet_Data_Element *sede;
3167 /* Yeah we found it ! */
3168 sede = &(ede->subtype->elements.set[i]);
3170 if (sede->group_type != EET_G_UNKNOWN)
3172 Eet_Data_Chunk chnk;
3178 size2 = echnk->size;
3180 /* Didn't find a proper way to provide this
3181 without duplicating code */
3184 memset(&chnk, 0, sizeof(Eet_Data_Chunk));
3185 eet_data_chunk_get(ed, &chnk, p2, size2);
3187 if (!chnk.name) goto on_error;
3189 ret = eet_group_codec[sede->group_type - 100].get(context,
3192 sede->type, sede->group_type,
3195 if (ret <= 0) goto on_error;
3197 /* advance to next chunk */
3198 NEXT_CHUNK(p2, size2, chnk, ed);
3201 /* Put garbage so that we will not put eet_variant_unknow in it */
3202 data_ret = (void*) data;
3204 /* Set variant type. */
3205 ede->subtype->func.type_set(ut,
3206 ((char*) data) + ede->count - ede->offset,
3211 data_ret = _eet_data_descriptor_decode(context,
3216 if (!data_ret) break;
3218 /* And point to the variant data. */
3219 *(void**) data = data_ret;
3221 /* Set variant type. */
3222 ede->subtype->func.type_set(ut,
3223 ((char*) data) + ede->count - ede->offset,
3230 Eet_Variant_Unknow *evu;
3232 evu = calloc(1, sizeof (Eet_Variant_Unknow) + echnk->size - 1);
3233 if (!evu) goto on_error;
3235 evu->size = echnk->size;
3236 memcpy(evu->data, echnk->data, evu->size);
3237 EINA_MAGIC_SET(evu, EET_MAGIC_VARIANT);
3239 /* And point to the opaque internal data scructure */
3240 *(void**) data = evu;
3242 /* Set variant type. */
3243 ede->subtype->func.type_set(ut,
3244 ((char*) data) + ede->count - ede->offset,
3250 /* FIXME: dump node structure. */
3251 data_ret = _eet_data_descriptor_decode(context,
3253 echnk->data, echnk->size);
3264 eet_data_node_simple_type(int type, const char *name, void *dd)
3270 #define EET_T_TYPE(Eet_Type, Eet_Node_Type, Type) \
3272 return eet_node_##Eet_Node_Type##_new(name, *((Type *) dd)); \
3276 EET_T_TYPE(EET_T_CHAR, char, char);
3277 EET_T_TYPE(EET_T_SHORT, short, short);
3278 EET_T_TYPE(EET_T_INT, int, int);
3279 EET_T_TYPE(EET_T_LONG_LONG, long_long, long long);
3280 EET_T_TYPE(EET_T_FLOAT, float, float);
3281 EET_T_TYPE(EET_T_DOUBLE, double, double);
3282 EET_T_TYPE(EET_T_UCHAR, unsigned_char, unsigned char);
3283 EET_T_TYPE(EET_T_USHORT, unsigned_short, unsigned short);
3284 EET_T_TYPE(EET_T_UINT, unsigned_int, unsigned int);
3285 EET_T_TYPE(EET_T_ULONG_LONG, unsigned_long_long, unsigned long long);
3286 EET_T_TYPE(EET_T_STRING, string, char*);
3287 EET_T_TYPE(EET_T_INLINED_STRING, inlined_string, char*);
3289 return eet_node_null_new(name);
3291 ERR("Unknow type passed to eet_data_node_simple_type");
3297 eet_data_get_unknown(Eet_Free_Context *context, const Eet_Dictionary *ed, Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Chunk *echnk,
3298 int type, int group_type __UNUSED__, void *data,
3299 char **p __UNUSED__, int *size __UNUSED__)
3304 if (IS_SIMPLE_TYPE(type))
3306 unsigned char dd[128];
3308 ret = eet_data_get_type(ed, type, echnk->data, ((char *)echnk->data) + echnk->size, edd ? (char*) data : (char*) dd);
3309 if (ret <= 0) return ret;
3313 Eet_Node **parent = data;
3316 node = eet_data_node_simple_type(type, echnk->name, dd);
3318 if (*parent) eet_node_struct_append(*parent, echnk->name, node);
3319 else *parent = node;
3323 if (type == EET_T_STRING)
3327 str = (char **)(((char *)data));
3330 if ((ed == NULL) || (edd->func.str_direct_alloc == NULL))
3332 *str = edd->func.str_alloc(*str);
3333 _eet_freelist_str_add(context, *str);
3337 *str = edd->func.str_direct_alloc(*str);
3338 _eet_freelist_direct_str_add(context, *str);
3342 else if (edd && type == EET_T_INLINED_STRING)
3346 str = (char **)(((char *)data));
3349 *str = edd->func.str_alloc(*str);
3350 _eet_freelist_str_add(context, *str);
3357 Eet_Data_Descriptor *subtype;
3359 subtype = ede ? ede->subtype : NULL;
3361 if (subtype || !edd)
3363 Eet_Node **parent = data;
3366 data_ret = _eet_data_descriptor_decode(context, ed, subtype, echnk->data, echnk->size);
3367 if (!data_ret) return 0;
3371 ptr = (void **)(((char *)data));
3372 *ptr = (void *)data_ret;
3376 Eet_Node *node = data_ret;
3380 node = eet_node_struct_child_new(echnk->name, node);
3381 eet_node_struct_append(*parent, echnk->name, node);
3383 else *parent = node;
3392 eet_data_put_array(Eet_Dictionary *ed, Eet_Data_Descriptor *edd __UNUSED__, Eet_Data_Element *ede, Eet_Data_Stream *ds, void *data_in)
3401 EET_ASSERT(!((ede->type > EET_T_UNKNOW) && (ede->type < EET_T_STRING)), return );
3403 if (ede->group_type == EET_G_ARRAY)
3404 count = ede->counter_offset;
3406 count = *(int *)(((char *)data_in) + ede->count - ede->offset);
3408 if (count <= 0) return;
3409 /* Store number of elements */
3410 data = eet_data_put_type(ed, EET_T_INT, &count, &size);
3411 if (data) eet_data_encode(ed, ds, data, ede->name, size, ede->type, ede->group_type);
3413 if (IS_POINTER_TYPE(ede->type))
3414 subsize = eet_basic_codec[ede->type].size;
3416 subsize = ede->subtype->size;
3418 for (j = 0; j < count; j++)
3423 if (ede->group_type == EET_G_ARRAY)
3424 d = (void *)(((char *)data_in) + offset);
3426 d = *(((char **)data_in)) + offset;
3428 if (IS_POINTER_TYPE(ede->type))
3431 eet_data_put_unknown(ed, NULL, ede, ds, d);
3435 data = _eet_data_descriptor_encode(ed, ede->subtype, d, &size);
3436 if (data) eet_data_encode(ed, ds, data, ede->name, size, ede->type, ede->group_type);
3441 /* Add a NULL element just to have the correct array layout. */
3442 eet_data_encode(ed, ds, NULL, ede->name, 0, EET_T_NULL, ede->group_type);
3450 eet_data_put_unknown(Eet_Dictionary *ed, Eet_Data_Descriptor *edd __UNUSED__, Eet_Data_Element *ede, Eet_Data_Stream *ds, void *data_in)
3455 if (IS_SIMPLE_TYPE(ede->type))
3456 data = eet_data_put_type(ed, ede->type, data_in, &size);
3457 else if (ede->subtype)
3459 if (*((char **)data_in))
3460 data = _eet_data_descriptor_encode(ed,
3462 *((char **)((char *)(data_in))),
3465 if (data) eet_data_encode(ed, ds, data, ede->name, size, ede->type, ede->group_type);
3469 eet_data_put_list(Eet_Dictionary *ed, Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Stream *ds, void *data_in)
3475 EET_ASSERT(!(((ede->type > EET_T_UNKNOW) && (ede->type < EET_T_STRING))
3476 || ((ede->type > EET_T_NULL) && (ede->type < EET_T_LAST))),
3479 l = *((void **)(((char *)data_in)));
3480 for (; l; l = edd->func.list_next(l))
3482 if (IS_POINTER_TYPE(ede->type))
3484 const void *str = edd->func.list_data(l);
3485 eet_data_put_unknown(ed, NULL, ede, ds, &str);
3489 data = _eet_data_descriptor_encode(ed,
3491 edd->func.list_data(l),
3493 if (data) eet_data_encode(ed, ds, data, ede->name, size, ede->type, ede->group_type);
3499 eet_data_put_hash(Eet_Dictionary *ed, Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Stream *ds, void *data_in)
3501 Eet_Data_Encode_Hash_Info fdata;
3504 l = *((void **)(((char *)data_in)));
3508 edd->func.hash_foreach(l, eet_data_descriptor_encode_hash_cb, &fdata);
3512 eet_data_dump_cipher(Eet_File *ef,
3513 const char *name, const char *cipher_key,
3514 void (*dumpfunc) (void *data, const char *str),
3517 const Eet_Dictionary *ed = NULL;
3518 const void *data = NULL;
3520 Eet_Free_Context context;
3521 int required_free = 0;
3524 ed = eet_dictionary_get(ef);
3527 data = eet_read_direct(ef, name, &size);
3531 data = eet_read_cipher(ef, name, &size, cipher_key);
3532 if (!data) return 0;
3535 memset(&context, 0, sizeof (context));
3536 result = _eet_data_descriptor_decode(&context, ed, NULL, data, size);
3538 eet_node_dump(result, 0, dumpfunc, dumpdata);
3540 eet_node_del(result);
3545 return result ? 1 : 0;
3549 eet_data_dump(Eet_File *ef,
3551 void (*dumpfunc) (void *data, const char *str),
3554 return eet_data_dump_cipher(ef, name, NULL, dumpfunc, dumpdata);
3559 eet_data_text_dump_cipher(const void *data_in,
3560 const char *cipher_key, int size_in,
3561 void (*dumpfunc) (void *data, const char *str),
3566 Eet_Free_Context context;
3567 unsigned int ret_len = 0;
3569 if (!data_in) return 0;
3573 if (eet_decipher(data_in, size_in, cipher_key,
3574 strlen(cipher_key), &ret, &ret_len))
3582 ret = (void*) data_in;
3586 memset(&context, 0, sizeof (context));
3587 result = _eet_data_descriptor_decode(&context, NULL, NULL, ret, ret_len);
3589 eet_node_dump(result, 0, dumpfunc, dumpdata);
3591 eet_node_del(result);
3592 if (cipher_key) free(ret);
3594 return result ? 1 : 0;
3598 eet_data_text_dump(const void *data_in,
3600 void (*dumpfunc) (void *data, const char *str),
3603 return eet_data_text_dump_cipher(data_in, NULL, size_in, dumpfunc, dumpdata);
3607 eet_data_text_undump_cipher(const char *text,
3608 const char *cipher_key,
3614 ret = _eet_data_dump_parse(NULL, size_ret, text, textlen);
3615 if (ret && cipher_key)
3617 void *ciphered = NULL;
3618 unsigned int ciphered_len;
3620 if (eet_cipher(ret, *size_ret, cipher_key,
3621 strlen(cipher_key), &ciphered, &ciphered_len))
3623 if (ciphered) free(ciphered);
3629 *size_ret = ciphered_len;
3636 eet_data_text_undump(const char *text,
3640 return eet_data_text_undump_cipher(text, NULL, textlen, size_ret);
3644 eet_data_undump_cipher(Eet_File *ef,
3646 const char *cipher_key,
3656 ed = eet_dictionary_get(ef);
3658 data_enc = _eet_data_dump_parse(ed, &size, text, textlen);
3659 if (!data_enc) return 0;
3660 val = eet_write_cipher(ef, name, data_enc, size, compress, cipher_key);
3666 eet_data_undump(Eet_File *ef,
3672 return eet_data_undump_cipher(ef, name, NULL, text, textlen, compress);
3676 eet_data_descriptor_decode_cipher(Eet_Data_Descriptor *edd,
3677 const void *data_in,
3678 const char *cipher_key,
3681 void *deciphered = (void*) data_in;
3683 Eet_Free_Context context;
3684 unsigned int deciphered_len = size_in;
3686 if (cipher_key && data_in)
3688 if (eet_decipher(data_in, size_in, cipher_key,
3689 strlen(cipher_key), &deciphered, &deciphered_len))
3691 if (deciphered) free(deciphered);
3696 memset(&context, 0, sizeof (context));
3697 ret = _eet_data_descriptor_decode(&context, NULL, edd, deciphered, deciphered_len);
3699 if (data_in != deciphered) free(deciphered);
3705 eet_data_descriptor_decode(Eet_Data_Descriptor *edd,
3706 const void *data_in,
3709 return eet_data_descriptor_decode_cipher(edd, data_in, NULL, size_in);
3713 eet_data_node_decode_cipher(const void *data_in, const char *cipher_key, int size_in)
3715 void *deciphered = (void*) data_in;
3717 Eet_Free_Context context;
3718 unsigned int deciphered_len = size_in;
3720 if (cipher_key && data_in)
3722 if (eet_decipher(data_in, size_in, cipher_key,
3723 strlen(cipher_key), &deciphered, &deciphered_len))
3725 if (deciphered) free(deciphered);
3730 memset(&context, 0, sizeof (context));
3731 ret = _eet_data_descriptor_decode(&context, NULL, NULL, deciphered, deciphered_len);
3733 if (data_in != deciphered) free(deciphered);
3739 _eet_data_descriptor_encode(Eet_Dictionary *ed,
3740 Eet_Data_Descriptor *edd,
3741 const void *data_in,
3744 Eet_Data_Stream *ds;
3745 Eet_Data_Chunk *chnk;
3750 if (_eet_data_words_bigendian == -1)
3752 unsigned long int v;
3754 v = htonl(0x12345678);
3755 if (v == 0x12345678) _eet_data_words_bigendian = 1;
3756 else _eet_data_words_bigendian = 0;
3759 ds = eet_data_stream_new();
3760 for (i = 0; i < edd->elements.num; i++)
3762 Eet_Data_Element *ede;
3764 ede = &(edd->elements.set[i]);
3765 eet_group_codec[ede->group_type - 100].put(ed, edd, ede, ds, ((char *)data_in) + ede->offset);
3767 chnk = eet_data_chunk_new(ds->data, ds->pos, edd->name, EET_T_UNKNOW, EET_G_UNKNOWN);
3770 eet_data_stream_free(ds);
3772 ds = eet_data_stream_new();
3773 eet_data_chunk_put(ed, chnk, ds);
3779 eet_data_stream_free(ds);
3783 eet_data_chunk_free(chnk);
3789 eet_data_node_write_cipher(Eet_File *ef, const char *name, const char *cipher_key, Eet_Node *node, int compress)
3796 ed = eet_dictionary_get(ef);
3798 data_enc = _eet_data_dump_encode(EET_G_UNKNOWN, ed, node, &size);
3799 if (!data_enc) return 0;
3800 val = eet_write_cipher(ef, name, data_enc, size, compress, cipher_key);
3806 eet_data_node_encode_cipher(Eet_Node *node,
3807 const char *cipher_key,
3811 void *ciphered = NULL;
3812 unsigned int ciphered_len = 0;
3815 ret = _eet_data_dump_encode(EET_G_UNKNOWN, NULL, node, &size);
3816 if (cipher_key && ret)
3818 if (eet_cipher(ret, size, cipher_key,
3819 strlen(cipher_key), &ciphered, &ciphered_len))
3821 if (ciphered) free(ciphered);
3822 if (size_ret) *size_ret = 0;
3827 size = (int) ciphered_len;
3831 if (size_ret) *size_ret = size;
3836 eet_data_descriptor_encode_cipher(Eet_Data_Descriptor *edd,
3837 const void *data_in,
3838 const char *cipher_key,
3842 void *ciphered = NULL;
3843 unsigned int ciphered_len = 0;
3846 ret = _eet_data_descriptor_encode(NULL, edd, data_in, &size);
3847 if (cipher_key && ret)
3849 if (eet_cipher(ret, size, cipher_key,
3850 strlen(cipher_key), &ciphered, &ciphered_len))
3852 if (ciphered) free(ciphered);
3853 if (size_ret) *size_ret = 0;
3858 size = ciphered_len;
3862 if (size_ret) *size_ret = size;
3867 eet_data_descriptor_encode(Eet_Data_Descriptor *edd,
3868 const void *data_in,
3871 return eet_data_descriptor_encode_cipher(edd, data_in, NULL, size_ret);