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_variant(Eet_Dictionary *ed, Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Stream *ds, void *data_in);
247 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);
249 static void eet_data_chunk_get(const Eet_Dictionary *ed, Eet_Data_Chunk *chnk, const void *src, int size);
250 static Eet_Data_Chunk *eet_data_chunk_new(void *data, int size, const char *name, int type, int group_type);
251 static void eet_data_chunk_free(Eet_Data_Chunk *chnk);
253 static Eet_Data_Stream *eet_data_stream_new(void);
254 static void eet_data_stream_write(Eet_Data_Stream *ds, const void *data, int size);
255 static void eet_data_stream_free(Eet_Data_Stream *ds);
257 static void eet_data_chunk_put(Eet_Dictionary *ed, Eet_Data_Chunk *chnk, Eet_Data_Stream *ds);
259 static int eet_data_descriptor_encode_hash_cb(void *hash, const char *key, void *hdata, void *fdata);
260 static void *_eet_data_descriptor_encode(Eet_Dictionary *ed, Eet_Data_Descriptor *edd, const void *data_in, int *size_ret);
261 static void *_eet_data_descriptor_decode(Eet_Free_Context *context,
262 const Eet_Dictionary *ed,
263 Eet_Data_Descriptor *edd,
269 static const Eet_Data_Basic_Type_Codec eet_basic_codec[] =
271 {sizeof(char), "char", eet_data_get_char, eet_data_put_char },
272 {sizeof(short), "short", eet_data_get_short, eet_data_put_short },
273 {sizeof(int), "int", eet_data_get_int, eet_data_put_int },
274 {sizeof(long long), "long_long", eet_data_get_long_long, eet_data_put_long_long},
275 {sizeof(float), "float", eet_data_get_float, eet_data_put_float },
276 {sizeof(double), "double", eet_data_get_double, eet_data_put_double },
277 {sizeof(char), "uchar", eet_data_get_char, eet_data_put_char },
278 {sizeof(short), "ushort", eet_data_get_short, eet_data_put_short },
279 {sizeof(int), "uint", eet_data_get_int, eet_data_put_int },
280 {sizeof(long long), "ulong_long", eet_data_get_long_long, eet_data_put_long_long},
281 {sizeof(char *), "string", eet_data_get_string, eet_data_put_string },
282 {sizeof(char *), "inlined", eet_data_get_istring, eet_data_put_istring },
283 {sizeof(void *), "NULL", eet_data_get_null, eet_data_put_null },
284 {sizeof(Eina_F32p32),"f32p32", eet_data_get_f32p32, eet_data_put_f32p32 },
285 {sizeof(Eina_F16p16),"f16p16", eet_data_get_f16p16, eet_data_put_f16p16 },
286 {sizeof(Eina_F8p24),"f8p24", eet_data_get_f8p24, eet_data_put_f8p24 }
289 static const Eet_Data_Group_Type_Codec eet_group_codec[] =
291 { eet_data_get_unknown, eet_data_put_unknown },
292 { eet_data_get_array, eet_data_put_array },
293 { eet_data_get_array, eet_data_put_array },
294 { eet_data_get_list, eet_data_put_list },
295 { eet_data_get_hash, eet_data_put_hash },
296 { eet_data_get_union, eet_data_put_union },
297 { eet_data_get_variant, eet_data_put_variant }
300 static int _eet_data_words_bigendian = -1;
304 #define SWAP64(x) (x) = \
305 ((((unsigned long long)(x) & 0x00000000000000ffULL ) << 56) |\
306 (((unsigned long long)(x) & 0x000000000000ff00ULL ) << 40) |\
307 (((unsigned long long)(x) & 0x0000000000ff0000ULL ) << 24) |\
308 (((unsigned long long)(x) & 0x00000000ff000000ULL ) << 8) |\
309 (((unsigned long long)(x) & 0x000000ff00000000ULL ) >> 8) |\
310 (((unsigned long long)(x) & 0x0000ff0000000000ULL ) >> 24) |\
311 (((unsigned long long)(x) & 0x00ff000000000000ULL ) >> 40) |\
312 (((unsigned long long)(x) & 0xff00000000000000ULL ) >> 56))
313 #define SWAP32(x) (x) = \
314 ((((int)(x) & 0x000000ff ) << 24) |\
315 (((int)(x) & 0x0000ff00 ) << 8) |\
316 (((int)(x) & 0x00ff0000 ) >> 8) |\
317 (((int)(x) & 0xff000000 ) >> 24))
318 #define SWAP16(x) (x) = \
319 ((((short)(x) & 0x00ff ) << 8) |\
320 (((short)(x) & 0xff00 ) >> 8))
336 #define CONV16(x) {if (_eet_data_words_bigendian) SWAP16(x);}
337 #define CONV32(x) {if (_eet_data_words_bigendian) SWAP32(x);}
338 #define CONV64(x) {if (_eet_data_words_bigendian) SWAP64(x);}
340 #define IS_SIMPLE_TYPE(Type) (Type > EET_T_UNKNOW && Type < EET_T_LAST)
341 #define IS_POINTER_TYPE(Type) (Type >= EET_T_STRING && Type <= EET_T_NULL)
343 #define POINTER_TYPE_DECODE(Context, Ed, Edd, Ede, Echnk, Type, Data, P, Size, Label) \
346 ___r = eet_data_get_unknown(Context, \
350 Type, EET_G_UNKNOWN, \
352 if (!___r) goto Label; \
355 #define STRUCT_TYPE_DECODE(Data_Ret, Context, Ed, Ede, Data, Size, Label) \
356 Data_Ret = _eet_data_descriptor_decode(Context, \
361 if (!Data_Ret) goto Label;
363 #define EET_I_STRING 1 << 4
364 #define EET_I_INLINED_STRING 2 << 4
365 #define EET_I_NULL 3 << 4
367 #define EET_MAGIC_VARIANT 0xF1234BC
372 eet_data_get_char(const Eet_Dictionary *ed __UNUSED__, const void *src, const void *src_end, void *dst)
376 if (((char *)src + sizeof(char)) > (char *)src_end) return -1;
385 eet_data_put_char(Eet_Dictionary *ed __UNUSED__, const void *src, int *size_ret)
389 d = (char *)malloc(sizeof(char));
394 *size_ret = sizeof(char);
400 eet_data_get_short(const Eet_Dictionary *ed __UNUSED__, const void *src, const void *src_end, void *dst)
404 if (((char *)src + sizeof(short)) > (char *)src_end) return -1;
405 memcpy(dst, src, sizeof(short));
408 return sizeof(short);
412 eet_data_put_short(Eet_Dictionary *ed __UNUSED__, const void *src, int *size_ret)
416 d = (short *)malloc(sizeof(short));
421 *size_ret = sizeof(short);
427 eet_data_get_int(const Eet_Dictionary *ed __UNUSED__, const void *src, const void *src_end, void *dst)
431 if (((char *)src + sizeof(int)) > (char *)src_end) return -1;
432 memcpy(dst, src, sizeof(int));
439 eet_data_put_int(Eet_Dictionary *ed __UNUSED__, const void *src, int *size_ret)
443 d = (int *)malloc(sizeof(int));
448 *size_ret = sizeof(int);
454 eet_data_get_long_long(const Eet_Dictionary *ed __UNUSED__, const void *src, const void *src_end, void *dst)
456 unsigned long long *d;
458 if (((char *)src + sizeof(unsigned long long)) > (char *)src_end) return -1;
459 memcpy(dst, src, sizeof(unsigned long long));
460 d = (unsigned long long *)dst;
462 return sizeof(unsigned long long);
466 eet_data_put_long_long(Eet_Dictionary *ed __UNUSED__, const void *src, int *size_ret)
468 unsigned long long *s, *d;
470 d = (unsigned long long *)malloc(sizeof(unsigned long long));
472 s = (unsigned long long *)src;
475 *size_ret = sizeof(unsigned long long);
481 eet_data_get_string_hash(const Eet_Dictionary *ed, const void *src, const void *src_end)
487 if (eet_data_get_int(ed, src, src_end, &idx) < 0) return -1;
489 return eet_dictionary_string_get_hash(ed, idx);
496 eet_data_get_string(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dst)
507 if (eet_data_get_int(ed, src, src_end, &idx) < 0) return -1;
509 str = eet_dictionary_string_get_char(ed, idx);
514 return eet_dictionary_string_get_size(ed, idx);
525 return strlen(s) + 1;
529 eet_data_put_string(Eet_Dictionary *ed, const void *src, int *size_ret)
539 str = *((const char **) src);
540 if (!str) return NULL;
542 idx = eet_dictionary_string_add(ed, str);
543 if (idx == -1) return NULL;
545 return eet_data_put_int(ed, &idx, size_ret);
548 s = (char *)(*((char **)src));
553 memcpy(d, s, len + 1);
558 /* ALWAYS INLINED STRING TYPE */
560 eet_data_get_istring(const Eet_Dictionary *ed __UNUSED__, const void *src, const void *src_end, void *dst)
562 return eet_data_get_string(NULL, src, src_end, dst);
566 eet_data_put_istring(Eet_Dictionary *ed __UNUSED__, const void *src, int *size_ret)
568 return eet_data_put_string(NULL, src, size_ret);
571 /* ALWAYS NULL TYPE */
573 eet_data_get_null(const Eet_Dictionary *ed __UNUSED__, const void *src __UNUSED__, const void *src_end __UNUSED__, void *dst)
584 eet_data_put_null(Eet_Dictionary *ed __UNUSED__, const void *src __UNUSED__, int *size_ret)
591 * Fast lookups of simple doubles/floats.
593 * These aren't properly a cache because they don't store pre-calculated
594 * values, but have a so simple math that is almost as fast.
597 _eet_data_float_cache_get(const char *s, int len, float *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 = (float)(mantisse << exponent);
606 else *d = (float)mantisse / (float)(1 << exponent);
614 _eet_data_double_cache_get(const char *s, int len, double *d)
616 /* fast handle of simple case 0xMp+E*/
617 if ((len == 6) && (s[0] == '0') && (s[1] == 'x') && (s[3] == 'p'))
619 int mantisse = (s[2] >= 'a') ? (s[2] - 'a' + 10) : (s[2] - '0');
620 int exponent = (s[5] - '0');
622 if (s[4] == '+') *d = (double)(mantisse << exponent);
623 else *d = (double)mantisse / (double)(1 << exponent);
632 eet_data_get_float(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dst)
645 s = (const char *)src;
648 while ((p < (const char *)src_end) && (*p != 0)) {len++; p++;}
650 if (_eet_data_float_cache_get(s, len, d) != 0) return len + 1;
652 if (eina_convert_atod(s, len, &mantisse, &exponent) == EINA_FALSE) return -1;
653 *d = (float)ldexp((double)mantisse, exponent);
658 if (eet_data_get_int(ed, src, src_end, &idx) < 0) return -1;
660 if (!eet_dictionary_string_get_float(ed, idx, d))
666 eet_data_put_float(Eet_Dictionary *ed, const void *src, int *size_ret)
671 eina_convert_dtoa((double)(*(float *)src), buf);
681 memcpy(d, buf, len + 1);
686 idx = eet_dictionary_string_add(ed, buf);
687 if (idx == -1) return NULL;
689 return eet_data_put_int(ed, &idx, size_ret);
694 eet_data_get_double(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dst)
704 long long mantisse = 0;
708 s = (const char *) src;
711 while ((p < (const char *)src_end) && (*p != 0)) {len++; p++;}
713 if (_eet_data_double_cache_get(s, len, d) != 0) return len + 1;
715 if (eina_convert_atod(s, len, &mantisse, &exponent) == EINA_FALSE) return -1;
716 *d = ldexp((double) mantisse, exponent);
721 if (eet_data_get_int(ed, src, src_end, &idx) < 0) return -1;
723 if (!eet_dictionary_string_get_double(ed, idx, d))
729 eet_data_put_double(Eet_Dictionary *ed, const void *src, int *size_ret)
734 eina_convert_dtoa((double)(*(double *)src), buf);
744 memcpy(d, buf, len + 1);
750 idx = eet_dictionary_string_add(ed, buf);
751 if (idx == -1) return NULL;
753 return eet_data_put_int(ed, &idx, size_ret);
757 eet_data_get_f32p32(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dst)
762 fp = (Eina_F32p32*) dst;
769 s = (const char *) src;
772 while ((p < (const char *)src_end) && (*p != 0)) { len++; p++; }
774 if (!(eina_convert_atofp(s, len, fp)))
779 if (eet_data_get_int(ed, src, src_end, &idx) < 0) return -1;
781 if (!eet_dictionary_string_get_fp(ed, idx, fp))
787 eet_data_put_f32p32(Eet_Dictionary *ed, const void *src, int *size_ret)
792 eina_convert_fptoa((Eina_F32p32)(*(Eina_F32p32 *)src), buf);
802 memcpy(d, buf, len + 1);
808 idx = eet_dictionary_string_add(ed, buf);
809 if (idx == -1) return NULL;
811 return eet_data_put_int(ed, &idx, size_ret);
815 eet_data_get_f16p16(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dst)
820 fp = (Eina_F16p16*) dst;
822 if (eet_data_get_f32p32(ed, src, src_end, &tmp) < 0) return -1;
824 *fp = eina_f32p32_to_f16p16(tmp);
829 eet_data_put_f16p16(Eet_Dictionary *ed, const void *src, int *size_ret)
833 tmp = eina_f16p16_to_f32p32((Eina_F16p16)(*(Eina_F16p16 *)src));
834 return eet_data_put_f32p32(ed, &tmp, size_ret);
838 eet_data_get_f8p24(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dst)
843 fp = (Eina_F8p24*) dst;
845 if (eet_data_get_f32p32(ed, src, src_end, &tmp) < 0) return -1;
847 *fp = eina_f32p32_to_f8p24(tmp);
852 eet_data_put_f8p24(Eet_Dictionary *ed, const void *src, int *size_ret)
856 tmp = eina_f8p24_to_f32p32((Eina_F8p24)(*(Eina_F8p24 *)src));
857 return eet_data_put_f32p32(ed, &tmp, size_ret);
861 eet_data_get_type(const Eet_Dictionary *ed, int type, const void *src, const void *src_end, void *dest)
865 ret = eet_basic_codec[type - 1].get(ed, src, src_end, dest);
870 eet_data_put_type(Eet_Dictionary *ed, int type, const void *src, int *size_ret)
874 ret = eet_basic_codec[type - 1].put(ed, src, size_ret);
878 static inline Eina_Bool
879 eet_data_type_match(int type1, int type2)
881 if (type1 == type2) return EINA_TRUE;
883 /* Note: All floating point type are equivalent and could be read
884 without problem by any other floating point getter. */
913 * char[4] = "CHnK"; // untyped data ... or
914 * char[4] = "CHKx"; // typed data - x == type
916 * int = chunk size (including magic string);
917 * char[] = chunk magic/name string (0 byte terminated);
918 * ... sub-chunks (a chunk can contain chuncks recusrively) ...
920 * ... payload data ...
925 eet_data_chunk_get(const Eet_Dictionary *ed, Eet_Data_Chunk *chnk,
926 const void *src, int size)
932 if (size <= 8) return;
938 if ((s[0] != 'C') || (s[1] != 'H') || (s[2] != 'K'))
941 chnk->type = (unsigned char)(s[3]);
942 if (chnk->type >= EET_I_LIMIT)
944 chnk->group_type = ((chnk->type - EET_I_LIMIT) & 0xF) + EET_G_UNKNOWN;
945 switch ((chnk->type - EET_I_LIMIT) & 0xF0)
947 #define EET_UNMATCH_TYPE(Type) \
948 case EET_I_##Type: chnk->type = EET_T_##Type; break;
950 EET_UNMATCH_TYPE(STRING);
951 EET_UNMATCH_TYPE(INLINED_STRING);
952 EET_UNMATCH_TYPE(NULL);
957 else if (chnk->type > EET_T_LAST)
959 chnk->group_type = chnk->type;
960 chnk->type = EET_T_UNKNOW;
963 chnk->group_type = EET_G_UNKNOWN;
964 if ((chnk->type >= EET_T_LAST) ||
965 (chnk->group_type >= EET_G_LAST))
968 chnk->group_type = 0;
973 if ((s[0] != 'C') || (s[1] != 'H') || (s[2] != 'n') || (s[3] != 'K'))
976 ret1 = eet_data_get_type(ed, EET_T_INT, (s + 4), (s + size), &(chnk->size));
978 if (ret1 <= 0) return;
979 if ((chnk->size < 0) || ((chnk->size + 8) > size)) return;
980 ret2 = eet_data_get_type(ed, EET_T_STRING, (s + 8), (s + size), &(chnk->name));
982 if (ret2 <= 0) return;
987 chnk->hash = eet_data_get_string_hash(ed, (s + 8), (s + size));
991 chnk->data = (char *)src + 4 + ret1 + sizeof(int);
992 chnk->size -= sizeof(int);
996 chnk->data = (char *)src + 4 + ret1 + chnk->len;
997 chnk->size -= chnk->len;
1003 static inline Eet_Data_Chunk *
1004 eet_data_chunk_new(void *data, int size, const char *name, int type, int group_type)
1006 Eet_Data_Chunk *chnk;
1008 if (!name) return NULL;
1009 chnk = calloc(1, sizeof(Eet_Data_Chunk));
1010 if (!chnk) return NULL;
1012 /* Note: Another security, so older eet library could read file
1013 saved with fixed point value. */
1014 if (type == EET_T_F32P32
1015 || type == EET_T_F16P16
1016 || type == EET_T_F8P24)
1017 type = EET_T_DOUBLE;
1019 chnk->name = strdup(name);
1020 chnk->len = strlen(name) + 1;
1024 chnk->group_type = group_type;
1029 eet_data_chunk_free(Eet_Data_Chunk *chnk)
1031 if (chnk->name) free(chnk->name);
1035 static inline Eet_Data_Stream *
1036 eet_data_stream_new(void)
1038 Eet_Data_Stream *ds;
1040 ds = calloc(1, sizeof(Eet_Data_Stream));
1041 if (!ds) return NULL;
1046 eet_data_stream_free(Eet_Data_Stream *ds)
1048 if (ds->data) free(ds->data);
1053 eet_data_stream_flush(Eet_Data_Stream *ds)
1059 eet_data_stream_write(Eet_Data_Stream *ds, const void *data, int size)
1063 if ((ds->pos + size) > ds->size)
1065 ds->data = realloc(ds->data, ds->size + size + 512);
1072 ds->size = ds->size + size + 512;
1075 memcpy(p + ds->pos, data, size);
1080 eet_data_chunk_put(Eet_Dictionary *ed, Eet_Data_Chunk *chnk, Eet_Data_Stream *ds)
1087 unsigned char buf[4] = "CHK";
1089 /* disable this check - it will allow empty chunks to be written. this is
1090 * right for corner-cases when y have a struct with empty fields (empty
1091 * strings or empty list ptrs etc.) */
1092 /* if (!chnk->data && chnk->type != EET_T_NULL) return; */
1095 /* eet_data_stream_write(ds, "CHnK", 4);*/
1096 if (chnk->type != EET_T_UNKNOW)
1098 if (chnk->group_type != EET_G_UNKNOWN)
1100 int type = EET_I_LIMIT + chnk->group_type - EET_G_UNKNOWN;
1104 /* Only make sense with pointer type. */
1105 #define EET_MATCH_TYPE(Type) \
1106 case EET_T_##Type: type += EET_I_##Type; break;
1108 EET_MATCH_TYPE(STRING);
1109 EET_MATCH_TYPE(INLINED_STRING);
1110 EET_MATCH_TYPE(NULL);
1118 buf[3] = chnk->type;
1120 else buf[3] = chnk->group_type;
1122 string = eet_data_put_string(ed, &chnk->name, &string_ret);
1126 /* size of chunk payload data + name */
1127 s = chnk->size + string_ret;
1128 size = eet_data_put_int(ed, &s, &size_ret);
1130 /* FIXME: If something goes wrong the resulting file will be corrupted. */
1134 eet_data_stream_write(ds, buf, 4);
1136 /* write chunk length */
1137 eet_data_stream_write(ds, size, size_ret);
1139 /* write chunk name */
1140 eet_data_stream_write(ds, string, string_ret);
1144 eet_data_stream_write(ds, chnk->data, chnk->size);
1154 _eet_descriptor_hash_new(Eet_Data_Descriptor *edd)
1158 edd->elements.hash.size = 1 << 6;
1159 edd->elements.hash.buckets = calloc(1, sizeof(Eet_Data_Descriptor_Hash) * edd->elements.hash.size);
1160 for (i = 0; i < edd->elements.num; i++)
1162 Eet_Data_Element *ede;
1165 ede = &(edd->elements.set[i]);
1166 hash = _eet_hash_gen((char *) ede->name, 6);
1167 if (!edd->elements.hash.buckets[hash].element)
1168 edd->elements.hash.buckets[hash].element = ede;
1171 Eet_Data_Descriptor_Hash *bucket;
1173 bucket = calloc(1, sizeof(Eet_Data_Descriptor_Hash));
1174 bucket->element = ede;
1175 bucket->next = edd->elements.hash.buckets[hash].next;
1176 edd->elements.hash.buckets[hash].next = bucket;
1182 _eet_descriptor_hash_free(Eet_Data_Descriptor *edd)
1186 for (i = 0; i < edd->elements.hash.size; i++)
1188 Eet_Data_Descriptor_Hash *bucket, *pbucket;
1190 bucket = edd->elements.hash.buckets[i].next;
1194 bucket = bucket->next;
1198 if (edd->elements.hash.buckets) free(edd->elements.hash.buckets);
1201 static Eet_Data_Element *
1202 _eet_descriptor_hash_find(Eet_Data_Descriptor *edd, char *name, int hash)
1204 Eet_Data_Descriptor_Hash *bucket;
1206 if (hash < 0) hash = _eet_hash_gen(name, 6);
1208 if (!edd->elements.hash.buckets[hash].element) return NULL;
1210 When we use the dictionnary as a source for chunk name, we will always
1211 have the same pointer in name. It's a good idea to just compare pointer
1212 instead of running strcmp on both string.
1214 if (edd->elements.hash.buckets[hash].element->directory_name_ptr == name)
1215 return edd->elements.hash.buckets[hash].element;
1216 if (!strcmp(edd->elements.hash.buckets[hash].element->name, name))
1218 edd->elements.hash.buckets[hash].element->directory_name_ptr = name;
1219 return edd->elements.hash.buckets[hash].element;
1221 bucket = edd->elements.hash.buckets[hash].next;
1224 if (bucket->element->directory_name_ptr == name) return bucket->element;
1225 if (!strcmp(bucket->element->name, name))
1227 bucket->element->directory_name_ptr = name;
1228 return bucket->element;
1230 bucket = bucket->next;
1236 _eet_mem_alloc(size_t size)
1238 return calloc(1, size);
1242 _eet_mem_free(void *mem)
1248 _eet_str_alloc(const char *str)
1254 _eet_str_free(const char *str)
1260 _eet_eina_hash_add_alloc(Eina_Hash *hash, const char *key, void *data)
1262 if (!hash) hash = eina_hash_string_small_new(NULL);
1263 if (!hash) return NULL;
1265 eina_hash_add(hash, key, data);
1270 _eet_eina_hash_direct_add_alloc(Eina_Hash *hash, const char *key, void *data)
1272 if (!hash) hash = eina_hash_string_small_new(NULL);
1273 if (!hash) return NULL;
1275 eina_hash_direct_add(hash, key, data);
1280 _eet_str_direct_alloc(const char *str)
1286 _eet_str_direct_free(const char *str __UNUSED__)
1291 _eet_eina_hash_foreach(void *hash, Eina_Hash_Foreach cb, void *fdata)
1293 if (hash) eina_hash_foreach(hash, cb, fdata);
1297 _eet_eina_hash_free(void *hash)
1299 if (hash) eina_hash_free(hash);
1304 eet_eina_stream_data_descriptor_class_set(Eet_Data_Descriptor_Class *eddc, const char *name, int size)
1306 if (!eddc || !name) return EINA_FALSE;
1312 eddc->func.mem_alloc = _eet_mem_alloc;
1313 eddc->func.mem_free = _eet_mem_free;
1314 eddc->func.str_alloc = (char *(*)(const char *))eina_stringshare_add;
1315 eddc->func.str_free = eina_stringshare_del;
1316 eddc->func.list_next = (void *(*)(void *))eina_list_next;
1317 eddc->func.list_append = (void *(*)(void *, void *))eina_list_append;
1318 eddc->func.list_data = (void *(*)(void *))eina_list_data_get;
1319 eddc->func.list_free = (void *(*)(void *))eina_list_free;
1320 eddc->func.hash_foreach = (void (*)(void *, int (*)(void *, const char *, void *, void *), void *))_eet_eina_hash_foreach;
1321 eddc->func.hash_add = (void* (*)(void *, const char *, void *)) _eet_eina_hash_add_alloc;
1322 eddc->func.hash_free = (void (*)(void *))_eet_eina_hash_free;
1328 eet_eina_file_data_descriptor_class_set(Eet_Data_Descriptor_Class *eddc, const char *name, int size)
1330 if (!eet_eina_stream_data_descriptor_class_set(eddc, name, size))
1335 eddc->func.hash_add = (void* (*)(void *, const char *, void *)) _eet_eina_hash_direct_add_alloc;
1336 eddc->func.str_direct_alloc = _eet_str_direct_alloc;
1337 eddc->func.str_direct_free = _eet_str_direct_free;
1342 static Eet_Data_Descriptor *
1343 _eet_data_descriptor_new(const Eet_Data_Descriptor_Class *eddc, int version)
1345 Eet_Data_Descriptor *edd;
1347 if (!eddc) return NULL;
1349 edd = calloc(1, sizeof (Eet_Data_Descriptor));
1350 if (!edd) return NULL;
1352 edd->name = eddc->name;
1354 edd->size = eddc->size;
1355 edd->func.mem_alloc = _eet_mem_alloc;
1356 edd->func.mem_free = _eet_mem_free;
1357 edd->func.str_alloc = _eet_str_alloc;
1358 edd->func.str_free = _eet_str_free;
1359 if (eddc->func.mem_alloc)
1360 edd->func.mem_alloc = eddc->func.mem_alloc;
1361 if (eddc->func.mem_free)
1362 edd->func.mem_free = eddc->func.mem_free;
1363 if (eddc->func.str_alloc)
1364 edd->func.str_alloc = eddc->func.str_alloc;
1365 if (eddc->func.str_free)
1366 edd->func.str_free = eddc->func.str_free;
1367 edd->func.list_next = eddc->func.list_next;
1368 edd->func.list_append = eddc->func.list_append;
1369 edd->func.list_data = eddc->func.list_data;
1370 edd->func.list_free = eddc->func.list_free;
1371 edd->func.hash_foreach = eddc->func.hash_foreach;
1372 edd->func.hash_add = eddc->func.hash_add;
1373 edd->func.hash_free = eddc->func.hash_free;
1375 if (eddc->version > 1 && version > 1)
1377 edd->func.str_direct_alloc = eddc->func.str_direct_alloc;
1378 edd->func.str_direct_free = eddc->func.str_direct_free;
1380 if (eddc->version > 2)
1382 edd->func.type_get = eddc->func.type_get;
1383 edd->func.type_set = eddc->func.type_set;
1389 EAPI Eet_Data_Descriptor *
1390 eet_data_descriptor_new(const char *name,
1392 void *(*func_list_next) (void *l),
1393 void *(*func_list_append) (void *l, void *d),
1394 void *(*func_list_data) (void *l),
1395 void *(*func_list_free) (void *l),
1396 void (*func_hash_foreach) (void *h, int (*func) (void *h, const char *k, void *dt, void *fdt), void *fdt),
1397 void *(*func_hash_add) (void *h, const char *k, void *d),
1398 void (*func_hash_free) (void *h))
1400 Eet_Data_Descriptor_Class eddc;
1402 if (!name) return NULL;
1404 memset(&eddc, 0, sizeof (Eet_Data_Descriptor_Class));
1410 eddc.func.list_next = func_list_next;
1411 eddc.func.list_append = func_list_append;
1412 eddc.func.list_data = func_list_data;
1413 eddc.func.list_free = func_list_free;
1414 eddc.func.hash_foreach = func_hash_foreach;
1415 eddc.func.hash_add = func_hash_add;
1416 eddc.func.hash_free = func_hash_free;
1418 return _eet_data_descriptor_new(&eddc, 0);
1421 EAPI Eet_Data_Descriptor *
1422 eet_data_descriptor2_new(const Eet_Data_Descriptor_Class *eddc)
1424 return _eet_data_descriptor_new(eddc, 1);
1427 EAPI Eet_Data_Descriptor *
1428 eet_data_descriptor3_new(const Eet_Data_Descriptor_Class *eddc)
1430 return _eet_data_descriptor_new(eddc, 2);
1433 EAPI Eet_Data_Descriptor *
1434 eet_data_descriptor_stream_new(const Eet_Data_Descriptor_Class *eddc)
1436 return _eet_data_descriptor_new(eddc, 1);
1439 EAPI Eet_Data_Descriptor *
1440 eet_data_descriptor_file_new(const Eet_Data_Descriptor_Class *eddc)
1442 return _eet_data_descriptor_new(eddc, 2);
1446 eet_data_descriptor_free(Eet_Data_Descriptor *edd)
1449 _eet_descriptor_hash_free(edd);
1450 if (edd->elements.set) free(edd->elements.set);
1455 eet_data_descriptor_element_add(Eet_Data_Descriptor *edd,
1461 /* int counter_offset, */
1462 const char *counter_name /* FIXME: Useless should go on a major release */,
1463 Eet_Data_Descriptor *subtype)
1465 Eet_Data_Element *ede;
1466 Eet_Data_Element *tmp;
1468 /* UNION, VARIANT type would not work with simple type, we need a way to map the type. */
1469 if ((group_type == EET_G_UNION
1470 || group_type == EET_G_VARIANT)
1472 (type != EET_T_UNKNOW
1474 || subtype->func.type_get == NULL
1475 || subtype->func.type_set == NULL))
1478 /* VARIANT type will only work if the map only contains EET_G_*, but not UNION, VARIANT and ARRAY. */
1479 if (group_type == EET_G_VARIANT)
1483 for (i = 0; i < subtype->elements.num; ++i)
1484 if (subtype->elements.set[i].type != EET_T_UNKNOW
1485 && subtype->elements.set[i].group_type > EET_G_VAR_ARRAY
1486 && subtype->elements.set[i].group_type < EET_G_UNION)
1489 subtype->unified_type = EINA_TRUE;
1492 && subtype->unified_type
1493 && (type != EET_T_UNKNOW
1494 || group_type < EET_G_UNION))
1497 /* Sanity check done, let allocate ! */
1498 edd->elements.num++;
1499 tmp = realloc(edd->elements.set, edd->elements.num * sizeof(Eet_Data_Element));
1501 edd->elements.set = tmp;
1502 ede = &(edd->elements.set[edd->elements.num - 1]);
1504 ede->directory_name_ptr = NULL;
1507 * We do a special case when we do list,hash or whatever group of simple type.
1508 * Instead of handling it in encode/decode/dump/undump, we create an
1509 * implicit structure with only the simple type.
1511 if (group_type > EET_G_UNKNOWN
1512 && group_type < EET_G_LAST
1513 && ((type > EET_T_UNKNOW && type < EET_T_STRING)
1514 || (type > EET_T_NULL && type < EET_T_LAST))
1517 subtype = calloc(1, sizeof (Eet_Data_Descriptor));
1518 if (!subtype) return ;
1519 subtype->name = "implicit";
1520 subtype->size = eet_basic_codec[type - 1].size;
1521 memcpy(&subtype->func, &edd->func, sizeof(subtype->func));
1523 eet_data_descriptor_element_add(subtype, eet_basic_codec[type - 1].name, type,
1524 EET_G_UNKNOWN, 0, 0, /* 0, */NULL, NULL);
1525 type = EET_T_UNKNOW;
1529 ede->group_type = group_type;
1530 ede->offset = offset;
1532 /* FIXME: For the time being, VAR_ARRAY, UNION and VARIANT will put the counter_offset in count. */
1533 ede->counter_offset = count;
1534 /* ede->counter_offset = counter_offset; */
1535 ede->counter_name = counter_name;
1537 ede->subtype = subtype;
1541 eet_data_read_cipher(Eet_File *ef, Eet_Data_Descriptor *edd, const char *name, const char *cipher_key)
1543 const Eet_Dictionary *ed = NULL;
1544 const void *data = NULL;
1546 Eet_Free_Context context;
1547 int required_free = 0;
1550 ed = eet_dictionary_get(ef);
1553 data = eet_read_direct(ef, name, &size);
1557 data = eet_read_cipher(ef, name, &size, cipher_key);
1558 if (!data) return NULL;
1561 memset(&context, 0, sizeof (context));
1562 data_dec = _eet_data_descriptor_decode(&context, ed, edd, data, size);
1570 eet_data_node_read_cipher(Eet_File *ef, const char *name, const char *cipher_key)
1572 const Eet_Dictionary *ed = NULL;
1573 const void *data = NULL;
1575 Eet_Free_Context context;
1576 int required_free = 0;
1579 ed = eet_dictionary_get(ef);
1582 data = eet_read_direct(ef, name, &size);
1586 data = eet_read_cipher(ef, name, &size, cipher_key);
1587 if (!data) return NULL;
1590 memset(&context, 0, sizeof (context));
1591 result = _eet_data_descriptor_decode(&context, ed, NULL, data, size);
1599 eet_data_read(Eet_File *ef, Eet_Data_Descriptor *edd, const char *name)
1601 return eet_data_read_cipher(ef, edd, name, NULL);
1605 eet_data_write_cipher(Eet_File *ef, Eet_Data_Descriptor *edd, const char *name, const char *cipher_key, const void *data, int compress)
1612 ed = eet_dictionary_get(ef);
1614 data_enc = _eet_data_descriptor_encode(ed, edd, data, &size);
1615 if (!data_enc) return 0;
1616 val = eet_write_cipher(ef, name, data_enc, size, compress, cipher_key);
1622 eet_data_write(Eet_File *ef, Eet_Data_Descriptor *edd, const char *name, const void *data, int compress)
1624 return eet_data_write_cipher(ef, edd, name, NULL, data, compress);
1628 _eet_free_hash(void *data)
1631 __int64 ptr = (UINT_PTR)data;
1633 unsigned long ptr = (unsigned long)(data);
1642 #if defined (_WIN64) || ( (! defined (_WIN32)) && (LONG_BIT != 32) )
1653 _eet_free_add(Eet_Free *ef, void *data)
1658 hash = _eet_free_hash(data);
1660 for (i = 0; i < ef->num[hash]; ++i)
1661 if (ef->list[hash][i] == data) return;
1664 if (ef->num[hash] > ef->len[hash])
1668 tmp = realloc(ef->list[hash], (ef->len[hash] + 16) * sizeof(void*));
1671 ef->len[hash] += 16;
1672 ef->list[hash] = tmp;
1674 ef->list[hash][ef->num[hash] - 1] = data;
1677 _eet_free_reset(Eet_Free *ef)
1681 if (ef->ref > 0) return ;
1682 for (i = 0; i < 256; ++i)
1686 if (ef->list[i]) free(ef->list[i]);
1691 _eet_free_ref(Eet_Free *ef)
1696 _eet_free_unref(Eet_Free *ef)
1701 #define _eet_freelist_add(Ctx, Data) _eet_free_add(&Ctx->freelist, Data);
1702 #define _eet_freelist_reset(Ctx) _eet_free_reset(&Ctx->freelist);
1703 #define _eet_freelist_ref(Ctx) _eet_free_ref(&Ctx->freelist);
1704 #define _eet_freelist_unref(Ctx) _eet_free_unref(&Ctx->freelist);
1707 _eet_freelist_free(Eet_Free_Context *context, Eet_Data_Descriptor *edd)
1712 if (context->freelist.ref > 0) return;
1713 for (j = 0; j < 256; ++j)
1714 for (i = 0; i < context->freelist.num[j]; ++i)
1717 edd->func.mem_free(context->freelist.list[j][i]);
1719 free(context->freelist.list[j][i]);
1721 _eet_free_reset(&context->freelist);
1724 #define _eet_freelist_list_add(Ctx, Data) _eet_free_add(&Ctx->freelist_list, Data);
1725 #define _eet_freelist_list_reset(Ctx) _eet_free_reset(&Ctx->freelist_list);
1726 #define _eet_freelist_list_ref(Ctx) _eet_free_ref(&Ctx->freelist_list);
1727 #define _eet_freelist_list_unref(Ctx) _eet_free_unref(&Ctx->freelist_list);
1730 _eet_freelist_list_free(Eet_Free_Context *context, Eet_Data_Descriptor *edd)
1735 if (context->freelist_list.ref > 0) return;
1736 for (j = 0; j < 256; ++j)
1737 for (i = 0; i < context->freelist_list.num[j]; ++i)
1740 edd->func.list_free(*((void**)(context->freelist_list.list[j][i])));
1742 _eet_free_reset(&context->freelist_list);
1745 #define _eet_freelist_str_add(Ctx, Data) _eet_free_add(&Ctx->freelist_str, Data);
1746 #define _eet_freelist_str_reset(Ctx) _eet_free_reset(&Ctx->freelist_str);
1747 #define _eet_freelist_str_ref(Ctx) _eet_free_ref(&Ctx->freelist_str);
1748 #define _eet_freelist_str_unref(Ctx) _eet_free_unref(&Ctx->freelist_str);
1751 _eet_freelist_str_free(Eet_Free_Context *context, Eet_Data_Descriptor *edd)
1756 if (context->freelist_str.ref > 0) return;
1757 for (j = 0; j < 256; ++j)
1758 for (i = 0; i < context->freelist_str.num[j]; ++i)
1761 edd->func.str_free(context->freelist_str.list[j][i]);
1763 free(context->freelist_str.list[j][i]);
1765 _eet_free_reset(&context->freelist_str);
1768 #define _eet_freelist_direct_str_add(Ctx, Data) _eet_free_add(&Ctx->freelist_direct_str, Data);
1769 #define _eet_freelist_direct_str_reset(Ctx) _eet_free_reset(&Ctx->freelist_direct_str);
1770 #define _eet_freelist_direct_str_ref(Ctx) _eet_free_ref(&Ctx->freelist_direct_str);
1771 #define _eet_freelist_direct_str_unref(Ctx) _eet_free_unref(&Ctx->freelist_direct_str);
1774 _eet_freelist_direct_str_free(Eet_Free_Context *context, Eet_Data_Descriptor *edd)
1779 if (context->freelist_direct_str.ref > 0) return;
1780 for (j = 0; j < 256; ++j)
1781 for (i = 0; i < context->freelist_direct_str.num[j]; ++i)
1784 edd->func.str_direct_free(context->freelist_direct_str.list[j][i]);
1786 free(context->freelist_direct_str.list[j][i]);
1788 _eet_free_reset(&context->freelist_direct_str);
1791 #define _eet_freelist_hash_add(Ctx, Data) _eet_free_add(&Ctx->freelist_hash, Data);
1792 #define _eet_freelist_hash_reset(Ctx) _eet_free_reset(&Ctx->freelist_hash);
1793 #define _eet_freelist_hash_ref(Ctx) _eet_free_ref(&Ctx->freelist_hash);
1794 #define _eet_freelist_hash_unref(Ctx) _eet_free_unref(&Ctx->freelist_hash);
1797 _eet_freelist_hash_free(Eet_Free_Context *context, Eet_Data_Descriptor *edd)
1802 if (context->freelist_hash.ref > 0) return;
1803 for (j = 0; j < 256; ++j)
1804 for (i = 0; i < context->freelist_hash.num[j]; ++i)
1807 edd->func.hash_free(context->freelist_hash.list[j][i]);
1809 free(context->freelist_hash.list[j][i]);
1811 _eet_free_reset(&context->freelist_hash);
1815 _eet_freelist_all_ref(Eet_Free_Context *freelist_context)
1817 _eet_freelist_ref(freelist_context);
1818 _eet_freelist_str_ref(freelist_context);
1819 _eet_freelist_list_ref(freelist_context);
1820 _eet_freelist_hash_ref(freelist_context);
1821 _eet_freelist_direct_str_ref(freelist_context);
1825 _eet_freelist_all_unref(Eet_Free_Context *freelist_context)
1827 _eet_freelist_unref(freelist_context);
1828 _eet_freelist_str_unref(freelist_context);
1829 _eet_freelist_list_unref(freelist_context);
1830 _eet_freelist_hash_unref(freelist_context);
1831 _eet_freelist_direct_str_unref(freelist_context);
1835 eet_data_descriptor_encode_hash_cb(void *hash __UNUSED__, const char *cipher_key, void *hdata, void *fdata)
1838 Eet_Data_Encode_Hash_Info *edehi;
1839 Eet_Data_Stream *ds;
1840 Eet_Data_Element *ede;
1841 Eet_Data_Chunk *echnk;
1851 data = eet_data_put_type(ed,
1857 echnk = eet_data_chunk_new(data, size, ede->name, ede->type, ede->group_type);
1858 eet_data_chunk_put(ed, echnk, ds);
1859 eet_data_chunk_free(echnk);
1864 EET_ASSERT(!((ede->type > EET_T_UNKNOW) && (ede->type < EET_T_STRING)), return );
1867 if (ede->type >= EET_T_STRING)
1868 eet_data_put_unknown(ed, NULL, ede, ds, &hdata);
1872 data = _eet_data_descriptor_encode(ed,
1878 echnk = eet_data_chunk_new(data, size, ede->name, ede->type, ede->group_type);
1879 eet_data_chunk_put(ed, echnk, ds);
1880 eet_data_chunk_free(echnk);
1890 _eet_data_dump_token_get(const char *src, int *len)
1896 int tlen = 0, tsize = 0;
1898 #define TOK_ADD(x) \
1901 if (tlen >= tsize) \
1904 tok = realloc(tok, tsize); \
1906 tok[tlen - 1] = x; \
1909 for (p = src; *len > 0; p++, (*len)--)
1915 if ((p[0] == '\"') && (p > src) && (p[-1] != '\\'))
1919 else if ((p[0] == '\\') && (*len > 1) && (p[1] == '\"'))
1923 else if ((p[0] == '\\') && (p > src) && (p[-1] == '\\'))
1927 else if ((p[0] == '\\') && (*len > 1) && (p[1] == 'n'))
1931 else if ((p[0] == 'n') && (p > src) && (p[-1] == '\\'))
1940 if (p[0] == '\"') in_quote = 1;
1943 if ((isspace(p[0])) || (p[0] == ';')) /* token ends here */
1956 if (!((isspace(p[0])) || (p[0] == ';')))
1974 eet_data_encode(Eet_Dictionary *ed, Eet_Data_Stream *ds, void *data, const char *name, int size, int type, int group_type)
1976 Eet_Data_Chunk *echnk;
1978 if (!data) type = EET_T_NULL;
1980 if (group_type != EET_G_UNKNOWN)
1981 if (type >= EET_T_LAST)
1982 type = EET_T_UNKNOW;
1984 echnk = eet_data_chunk_new(data, size, name, type, group_type);
1985 eet_data_chunk_put(ed, echnk, ds);
1986 eet_data_chunk_free(echnk);
1991 _eet_data_dump_encode(int parent_type,
1996 Eet_Data_Chunk *chnk = NULL;
1997 Eet_Data_Stream *ds;
2004 if (_eet_data_words_bigendian == -1)
2006 unsigned long int v;
2008 v = htonl(0x12345678);
2009 if (v == 0x12345678) _eet_data_words_bigendian = 1;
2010 else _eet_data_words_bigendian = 0;
2013 if (node == NULL) return NULL;
2015 ds = eet_data_stream_new();
2016 if (!ds) return NULL;
2021 for (n = node->values; n; n = n->next)
2023 data = _eet_data_dump_encode(node->type, ed, n, &size);
2026 eet_data_stream_write(ds, data, size);
2032 case EET_G_VAR_ARRAY:
2033 for (child_type = EET_T_NULL, n = node->values; n; n = n->next)
2035 if (n->type != EET_T_NULL)
2037 child_type = n->type;
2042 data = eet_data_put_type(ed,
2046 eet_data_encode(ed, ds, data, node->name, size, child_type, node->type);
2048 count = node->count;
2050 for (n = node->values; n; n = n->next)
2057 case EET_T_INLINED_STRING:
2058 data = eet_data_put_type(ed, n->type, &(n->data.value.str), &size);
2059 if (data) eet_data_encode(ed, ds, data, node->name, size, n->type, node->type);
2064 data = _eet_data_dump_encode(n->type, ed, n, &size);
2065 eet_data_encode(ed, ds, data, node->name, size, n->type, node->type);
2068 if (ds->pos != pos) count--;
2071 for (; count; count--)
2073 eet_data_encode(ed, ds, NULL, node->name, 0, EET_T_NULL, node->type);
2076 /* Array is somekind of special case, so we should embed it inside another chunk. */
2077 *size_ret = ds->pos;
2082 eet_data_stream_free(ds);
2087 for (n = node->values; n; n = n->next)
2092 case EET_T_INLINED_STRING:
2093 data = eet_data_put_type(ed, n->type, &(n->data.value.str), &size);
2094 if (data) eet_data_encode(ed, ds, data, node->name, size, n->type, node->type);
2099 data = _eet_data_dump_encode(node->type, ed, n, &size);
2100 eet_data_encode(ed, ds, data, node->name, size, n->type, node->type);
2104 /* List is another somekind of special case, every chunk is embed inside a list chunk. */
2105 *size_ret = ds->pos;
2110 eet_data_stream_free(ds);
2117 data = eet_data_put_type(ed,
2121 eet_data_encode(ed, ds, data, node->name, size, node->type, node->type);
2124 /* A Hash without key will not decode correctly. */
2127 for (n = node->values; n; n = n->next)
2132 case EET_T_INLINED_STRING:
2133 data = eet_data_put_type(ed, n->type, &(n->data.value.str), &size);
2134 if (data) eet_data_encode(ed, ds, data, node->name, size, n->type, node->type);
2139 data = _eet_data_dump_encode(node->type, ed, n, &size);
2140 eet_data_encode(ed, ds, data, node->name, size, n->type, node->type);
2144 /* Hash is somekind of special case, so we should embed it inside another chunk. */
2145 *size_ret = ds->pos;
2148 eet_data_stream_flush(ds);
2154 #define EET_DATA_NODE_ENCODE(Eet_Type, Type) \
2156 data = eet_data_put_type(ed, node->type, &(node->data.value.Type), &size); \
2159 eet_data_encode(ed, ds, data, node->name, size, node->type, parent_type); \
2161 *size_ret = ds->pos; \
2162 eet_data_stream_flush(ds); \
2167 EET_DATA_NODE_ENCODE(EET_T_CHAR, c);
2168 EET_DATA_NODE_ENCODE(EET_T_SHORT, s);
2169 EET_DATA_NODE_ENCODE(EET_T_INT, i);
2170 EET_DATA_NODE_ENCODE(EET_T_LONG_LONG, l);
2171 EET_DATA_NODE_ENCODE(EET_T_FLOAT, f);
2172 EET_DATA_NODE_ENCODE(EET_T_DOUBLE, d);
2173 EET_DATA_NODE_ENCODE(EET_T_UCHAR, uc);
2174 EET_DATA_NODE_ENCODE(EET_T_USHORT, us);
2175 EET_DATA_NODE_ENCODE(EET_T_UINT, ui);
2176 EET_DATA_NODE_ENCODE(EET_T_ULONG_LONG, ul);
2177 EET_DATA_NODE_ENCODE(EET_T_INLINED_STRING, str);
2178 EET_DATA_NODE_ENCODE(EET_T_STRING, str);
2183 if ((node->type >= EET_G_UNKNOWN) && (node->type < EET_G_LAST))
2184 chnk = eet_data_chunk_new(ds->data, ds->pos, node->name, EET_T_UNKNOW, node->type);
2186 chnk = eet_data_chunk_new(ds->data, ds->pos, node->name, node->type, EET_G_UNKNOWN);
2187 eet_data_stream_flush(ds);
2189 ds = eet_data_stream_new();
2190 eet_data_chunk_put(ed, chnk, ds);
2194 eet_data_stream_flush(ds);
2198 eet_data_chunk_free(chnk);
2204 _eet_data_dump_parse(Eet_Dictionary *ed,
2210 const char *p = NULL;
2215 Eet_Node *node_base = NULL;
2216 Eet_Node *node = NULL;
2217 Eet_Node *n = NULL, *nn = NULL;
2219 /* FIXME; handle parse errors */
2220 #define TOK_GET(t) \
2221 jump = left; t = _eet_data_dump_token_get(p, &left); p += jump - left;
2223 for (p = src; p < (src + size);)
2225 char *tok1, *tok2, *tok3, *tok4;
2230 if (!strcmp(tok1, "group"))
2241 if (!strcmp(tok4, "{"))
2243 /* we have 'group NAM TYP {' */
2259 for (nn = node->values; nn; nn = nn->next)
2269 n->name = eina_stringshare_add(tok2);
2270 if (!strcmp(tok3, "struct")) n->type = EET_G_UNKNOWN;
2271 else if (!strcmp(tok3, "array")) n->type = EET_G_ARRAY;
2272 else if (!strcmp(tok3, "var_array")) n->type = EET_G_VAR_ARRAY;
2273 else if (!strcmp(tok3, "list")) n->type = EET_G_LIST;
2274 else if (!strcmp(tok3, "hash")) n->type = EET_G_HASH;
2277 ERR("ERROR: group type '%s' invalid.", tok3);
2289 else if (!strcmp(tok1, "value"))
2300 /* we have 'value NAME TYP XXX' */
2312 for (nn = node->values; nn; nn = nn->next)
2321 n->name = eina_stringshare_add(tok2);
2322 if (!strcmp(tok3, "char:"))
2324 n->type = EET_T_CHAR;
2325 sscanf(tok4, "%hhi", &(n->data.value.c));
2327 else if (!strcmp(tok3, "short:"))
2329 n->type = EET_T_SHORT;
2330 sscanf(tok4, "%hi", &(n->data.value.s));
2332 else if (!strcmp(tok3, "int:"))
2334 n->type = EET_T_INT;
2335 sscanf(tok4, "%i", &(n->data.value.i));
2337 else if (!strcmp(tok3, "long_long:"))
2339 n->type = EET_T_LONG_LONG;
2340 sscanf(tok4, "%lli", &(n->data.value.l));
2342 else if (!strcmp(tok3, "float:"))
2344 n->type = EET_T_FLOAT;
2345 sscanf(tok4, "%f", &(n->data.value.f));
2347 else if (!strcmp(tok3, "double:"))
2349 n->type = EET_T_DOUBLE;
2350 sscanf(tok4, "%lf", &(n->data.value.d));
2352 else if (!strcmp(tok3, "uchar:"))
2354 n->type = EET_T_UCHAR;
2355 sscanf(tok4, "%hhu", &(n->data.value.uc));
2357 else if (!strcmp(tok3, "ushort:"))
2359 n->type = EET_T_USHORT;
2360 sscanf(tok4, "%hu", &(n->data.value.us));
2362 else if (!strcmp(tok3, "uint:"))
2364 n->type = EET_T_UINT;
2365 sscanf(tok4, "%u", &(n->data.value.ui));
2367 else if (!strcmp(tok3, "ulong_long:"))
2369 n->type = EET_T_ULONG_LONG;
2370 sscanf(tok4, "%llu", &(n->data.value.ul));
2372 else if (!strcmp(tok3, "string:"))
2374 n->type = EET_T_STRING;
2375 n->data.value.str = eina_stringshare_add(tok4);
2377 else if (!strcmp(tok3, "inlined:"))
2379 n->type = EET_T_INLINED_STRING;
2380 n->data.value.str = eina_stringshare_add(tok4);
2382 else if (!strcmp(tok3, "null"))
2384 n->type = EET_T_NULL;
2385 n->data.value.str = NULL;
2389 ERR("ERROR: value type '%s' invalid.", tok4);
2400 else if (!strcmp(tok1, "key"))
2405 /* we have 'key NAME' */
2408 node->key = eina_stringshare_add(tok2);
2413 else if (!strcmp(tok1, "count"))
2418 /* we have a 'count COUNT' */
2421 sscanf(tok2, "%i", &(node->count));
2426 else if (!strcmp(tok1, "}"))
2428 /* we have an end of the group */
2429 if (node) node = node->parent;
2437 cdata = _eet_data_dump_encode(EET_G_UNKNOWN, ed, node_base, size_ret);
2438 eet_node_del(node_base);
2443 #define NEXT_CHUNK(P, Size, Echnk, Ed) \
2446 tmp = Ed ? (int) (sizeof(int) * 2) : Echnk.len + 4;\
2447 P += (4 + Echnk.size + tmp); \
2448 Size -= (4 + Echnk.size + tmp); \
2452 _eet_data_descriptor_decode(Eet_Free_Context *context,
2453 const Eet_Dictionary *ed,
2454 Eet_Data_Descriptor *edd,
2455 const void *data_in,
2458 Eet_Node *result = NULL;
2462 Eet_Data_Chunk chnk;
2464 if (_eet_data_words_bigendian == -1)
2466 unsigned long int v;
2468 v = htonl(0x12345678);
2469 if (v == 0x12345678) _eet_data_words_bigendian = 1;
2470 else _eet_data_words_bigendian = 0;
2475 data = edd->func.mem_alloc(edd->size);
2476 if (!data) return NULL;
2479 for (i = 0; i < edd->elements.num; i++)
2480 edd->elements.set[i].directory_name_ptr = NULL;
2484 _eet_freelist_all_ref(context);
2485 if (data) _eet_freelist_add(context, data);
2486 memset(&chnk, 0, sizeof(Eet_Data_Chunk));
2487 eet_data_chunk_get(ed, &chnk, data_in, size_in);
2488 if (!chnk.name) goto error;
2491 if (strcmp(chnk.name, edd->name)) goto error;
2495 size = size_in - (4 + sizeof(int) * 2);
2497 size = size_in - (4 + 4 + chnk.len);
2500 if (!edd->elements.hash.buckets) _eet_descriptor_hash_new(edd);
2504 switch (chnk.group_type)
2510 return eet_node_string_new(chnk.name, chnk.data);
2511 case EET_T_INLINED_STRING:
2512 return eet_node_inlined_string_new(chnk.name, chnk.data);
2514 return eet_node_null_new(chnk.name);
2516 result = eet_node_struct_new(chnk.name, NULL);
2519 case EET_G_VAR_ARRAY:
2520 return eet_node_var_array_new(chnk.name, NULL);
2532 Eet_Data_Chunk echnk;
2533 Eet_Data_Element *ede = NULL;
2534 Eet_Node *child = NULL;
2535 int group_type = EET_G_UNKNOWN, type = EET_T_UNKNOW;
2538 /* get next data chunk */
2539 memset(&echnk, 0, sizeof(Eet_Data_Chunk));
2540 eet_data_chunk_get(ed, &echnk, p, size);
2541 if (!echnk.name) goto error;
2542 /* FIXME: don't REPLY on edd - work without */
2545 ede = _eet_descriptor_hash_find(edd, echnk.name, echnk.hash);
2548 group_type = ede->group_type;
2550 if ((echnk.type == 0) && (echnk.group_type == 0))
2553 group_type = ede->group_type;
2557 if (IS_SIMPLE_TYPE(echnk.type) &&
2558 eet_data_type_match(echnk.type, ede->type))
2559 /* Needed when converting on the fly from FP to Float */
2561 else if ((echnk.group_type > EET_G_UNKNOWN) &&
2562 (echnk.group_type < EET_G_LAST) &&
2563 (echnk.group_type == ede->group_type))
2564 group_type = echnk.group_type;
2568 /*...... dump to node */
2572 group_type = echnk.group_type;
2575 if (!edd && group_type == EET_G_UNKNOWN && IS_SIMPLE_TYPE(type))
2577 unsigned char dd[128];
2579 ret = eet_data_get_type(ed,
2582 ((char *)echnk.data) + echnk.size,
2584 if (ret <= 0) goto error;
2586 child = eet_data_node_simple_type(type, echnk.name, dd);
2588 eet_node_struct_append(result, echnk.name, child);
2592 ret = eet_group_codec[group_type - 100].get(context,
2593 ed, edd, ede, &echnk,
2594 type, group_type, ede ? (void*) (((char *)data) + ede->offset) : (void**) &result,
2597 if (ret <= 0) goto error;
2600 /* advance to next chunk */
2601 NEXT_CHUNK(p, size, echnk, ed);
2604 _eet_freelist_all_unref(context);
2607 _eet_freelist_str_free(context, edd);
2608 _eet_freelist_direct_str_free(context, edd);
2609 _eet_freelist_list_free(context, edd);
2610 _eet_freelist_hash_free(context, edd);
2611 _eet_freelist_free(context, edd);
2615 _eet_freelist_reset(context);
2616 _eet_freelist_str_reset(context);
2617 _eet_freelist_list_reset(context);
2618 _eet_freelist_hash_reset(context);
2619 _eet_freelist_direct_str_reset(context);
2628 eet_node_del(result);
2630 _eet_freelist_all_unref(context);
2631 _eet_freelist_str_free(context, edd);
2632 _eet_freelist_direct_str_free(context, edd);
2633 _eet_freelist_list_free(context, edd);
2634 _eet_freelist_hash_free(context, edd);
2635 _eet_freelist_free(context, edd);
2637 /* FIXME: Warn that something goes wrong here. */
2642 eet_data_get_list(Eet_Free_Context *context, const Eet_Dictionary *ed, Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Chunk *echnk,
2643 int type, int group_type __UNUSED__, void *data,
2644 char **p, int *size)
2646 Eet_Data_Descriptor *subtype = NULL;
2651 EET_ASSERT(!((type > EET_T_UNKNOW) && (type < EET_T_STRING)), return 0);
2655 subtype = ede->subtype;
2657 if (type != ede->type)
2661 ptr = (void **)data;
2665 if (IS_POINTER_TYPE(type))
2667 POINTER_TYPE_DECODE(context, ed, edd, ede, echnk, type, &data_ret, p, size, on_error);
2671 STRUCT_TYPE_DECODE(data_ret, context, ed, subtype, echnk->data, echnk->size, on_error);
2676 list = edd->func.list_append(list, data_ret);
2678 _eet_freelist_list_add(context, ptr);
2682 eet_node_list_append(*((Eet_Node**) data), echnk->name, data_ret);
2692 eet_data_get_hash(Eet_Free_Context *context, const Eet_Dictionary *ed, Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Chunk *echnk,
2693 int type, int group_type __UNUSED__, void *data,
2694 char **p, int *size)
2699 void *data_ret = NULL;
2702 EET_ASSERT(!((type > EET_T_UNKNOW) && (type < EET_T_STRING)), return 0);
2704 ptr = (void **)data;
2708 ret = eet_data_get_type(ed,
2711 ((char *)echnk->data) + echnk->size,
2713 if (ret <= 0) goto on_error;
2715 /* Advance to next chunk */
2716 NEXT_CHUNK((*p), (*size), (*echnk), ed);
2717 memset(echnk, 0, sizeof(Eet_Data_Chunk));
2720 eet_data_chunk_get(ed, echnk, *p, *size);
2721 if (!echnk->name) goto on_error;
2723 if (IS_POINTER_TYPE(echnk->type))
2725 POINTER_TYPE_DECODE(context, ed, edd, ede, echnk, echnk->type, &data_ret, p, size, on_error);
2729 STRUCT_TYPE_DECODE(data_ret, context, ed, ede ? ede->subtype : NULL, echnk->data, echnk->size, on_error);
2734 hash = edd->func.hash_add(hash, key, data_ret);
2736 _eet_freelist_hash_add(context, hash);
2740 eet_node_hash_add(*((Eet_Node **) data), echnk->name, key, data_ret);
2749 /* var arrays and fixed arrays have to
2750 * get all chunks at once. for fixed arrays
2751 * we can get each chunk and increment a
2752 * counter stored on the element itself but
2753 * it wont be thread safe. for var arrays
2754 * we still need a way to get the number of
2755 * elements from the data, so storing the
2756 * number of elements and the element data on
2757 * each chunk is pointless.
2760 eet_data_get_array(Eet_Free_Context *context, const Eet_Dictionary *ed, Eet_Data_Descriptor *edd,
2761 Eet_Data_Element *ede, Eet_Data_Chunk *echnk,
2762 int type, int group_type, void *data,
2763 char **p, int *size)
2765 Eina_List *childs = NULL;
2774 EET_ASSERT(!((type > EET_T_UNKNOW) && (type < EET_T_STRING)), return 0);
2777 /* read the number of elements */
2778 ret = eet_data_get_type(ed,
2781 ((char *)echnk->data) + echnk->size,
2783 if (ret <= 0) return ret;
2789 if (IS_POINTER_TYPE(type))
2790 subsize = eet_basic_codec[ede->type].size;
2792 subsize = ede->subtype->size;
2794 if (group_type == EET_G_VAR_ARRAY)
2796 /* store the number of elements
2797 * on the counter offset */
2798 *(int *)(((char *)data) + ede->count - ede->offset) = count;
2799 /* allocate space for the array of elements */
2800 *(void **)ptr = edd->func.mem_alloc(count * subsize);
2802 if (!*(void **)ptr) return 0;
2804 memset(*(void **)ptr, 0, count * subsize);
2806 _eet_freelist_add(context, *(void **)ptr);
2810 /* get all array elements */
2811 for (i = 0; i < count; i++)
2814 void *data_ret = NULL;
2816 /* Advance to next chunk */
2817 NEXT_CHUNK((*p), (*size), (*echnk), ed);
2818 memset(echnk, 0, sizeof(Eet_Data_Chunk));
2820 eet_data_chunk_get(ed, echnk, *p, *size);
2821 if (!echnk->name || strcmp(echnk->name, name) != 0) goto on_error;
2824 if (echnk->group_type != group_type
2825 || (echnk->type != type && echnk->type != EET_T_NULL))
2829 if (ede->group_type != echnk->group_type
2830 || (echnk->type != ede->type && echnk->type != EET_T_NULL))
2833 /* get the destination pointer */
2836 if (group_type == EET_G_ARRAY)
2837 dst = (char *)ptr + (subsize * i);
2839 dst = *(char **)ptr + (subsize * i);
2842 if (IS_POINTER_TYPE(echnk->type))
2844 POINTER_TYPE_DECODE(context, ed, edd, ede, echnk, echnk->type, &data_ret, p, size, on_error);
2845 if (dst) memcpy(dst, &data_ret, subsize);
2846 if (!edd) childs = eina_list_append(childs, data_ret);
2850 STRUCT_TYPE_DECODE(data_ret, context, ed, ede ? ede->subtype : NULL, echnk->data, echnk->size, on_error);
2853 memcpy(dst, data_ret, subsize);
2854 _eet_freelist_add(context, data_ret);
2856 if (!edd) childs = eina_list_append(childs, data_ret);
2862 Eet_Node *parent = *((Eet_Node **) data);
2865 if (group_type == EET_G_ARRAY)
2866 array = eet_node_array_new(name, count, childs);
2868 array = eet_node_var_array_new(name, childs);
2870 if (!array) goto on_error;
2872 eet_node_struct_append(parent, name, array);
2878 EINA_LIST_FREE(childs, tmp)
2885 eet_data_put_union(Eet_Dictionary *ed,
2886 Eet_Data_Descriptor *edd __UNUSED__,
2887 Eet_Data_Element *ede, Eet_Data_Stream *ds, void *data_in)
2889 const char *union_type;
2892 EET_ASSERT(!((ede->type != EET_T_UNKNOW) || (!ede->subtype)), return );
2894 union_type = ede->subtype->func.type_get(((char*) data_in) + ede->count - ede->offset,
2897 if (!union_type) return ;
2899 /* Search the structure of the union to encode. */
2900 for (i = 0; i < ede->subtype->elements.num; ++i)
2901 if (strcmp(ede->subtype->elements.set[i].name, union_type) == 0)
2903 Eet_Data_Element *sede;
2907 /* Yeah we found it ! */
2908 data = eet_data_put_type(ed, EET_T_STRING, &union_type, &size);
2909 if (data) eet_data_encode(ed, ds, data, ede->name, size, ede->type, ede->group_type);
2911 sede = &(ede->subtype->elements.set[i]);
2912 data = _eet_data_descriptor_encode(ed,
2916 if (data) eet_data_encode(ed, ds, data, ede->name, size, ede->type, ede->group_type);
2922 eet_data_get_union(Eet_Free_Context *context, const Eet_Dictionary *ed,
2923 Eet_Data_Descriptor *edd __UNUSED__,
2924 Eet_Data_Element *ede, Eet_Data_Chunk *echnk,
2925 int type, int group_type, void *data,
2926 char **p, int *size)
2928 const char *union_type;
2929 void *data_ret = NULL;
2934 ret = eet_data_get_type(ed,
2937 ((char *)echnk->data) + echnk->size,
2939 if (ret <= 0) goto on_error;
2941 /* Advance to next chunk */
2942 NEXT_CHUNK((*p), (*size), (*echnk), ed);
2943 memset(echnk, 0, sizeof(Eet_Data_Chunk));
2946 eet_data_chunk_get(ed, echnk, *p, *size);
2947 if (!echnk->name) goto on_error;
2951 EET_ASSERT(!(ede->group_type != group_type || ede->type != type), goto on_error);
2953 /* Search the structure of the union to decode */
2954 for (i = 0; i < ede->subtype->elements.num; ++i)
2955 if (strcmp(ede->subtype->elements.set[i].name, union_type) == 0)
2957 Eet_Data_Element *sede;
2960 /* Yeah we found it ! */
2961 sede = &(ede->subtype->elements.set[i]);
2962 EET_ASSERT(sede->subtype, goto on_error);
2964 data_ret = _eet_data_descriptor_decode(context,
2969 if (!data_ret) goto on_error;
2971 /* Memcopy the structure content to remove pointer indirection. */
2972 memcpy(data, data_ret, sede->subtype->size);
2974 /* data_ret is now useless. */
2975 sede->subtype->func.mem_free(data_ret);
2977 /* Set union type. */
2978 if ((!ed) || (!ede->subtype->func.str_direct_alloc))
2980 ut = ede->subtype->func.str_alloc(union_type);
2981 _eet_freelist_str_add(context, ut);
2985 ut = ede->subtype->func.str_direct_alloc(union_type);
2986 _eet_freelist_direct_str_add(context, ut);
2989 ede->subtype->func.type_set(ut,
2990 ((char*) data) + ede->count - ede->offset,
2998 /* FIXME: generate node structure. */
2999 data_ret = _eet_data_descriptor_decode(context,
3001 echnk->data, echnk->size);
3012 eet_data_put_variant(Eet_Dictionary *ed,
3013 Eet_Data_Descriptor *edd __UNUSED__,
3014 Eet_Data_Element *ede, Eet_Data_Stream *ds, void *data_in)
3016 const char *union_type;
3018 Eina_Bool unknow = EINA_FALSE;
3022 EET_ASSERT(!((ede->type != EET_T_UNKNOW) || (!ede->subtype)), return );
3024 union_type = ede->subtype->func.type_get(((char*) data_in) + ede->count - ede->offset,
3027 if (!union_type && unknow == EINA_FALSE) return ;
3031 /* Handle opaque internal representation */
3032 Eet_Variant_Unknow *evu;
3034 data = eet_data_put_type(ed, EET_T_STRING, &union_type, &size);
3035 if (data) eet_data_encode(ed, ds, data, ede->name, size, ede->type, ede->group_type);
3037 evu = (Eet_Variant_Unknow*) data_in;
3038 if (evu && EINA_MAGIC_CHECK(evu, EET_MAGIC_VARIANT))
3039 eet_data_encode(ed, ds, evu->data, ede->name, evu->size, ede->type, ede->group_type);
3043 /* Search the structure of the union to encode. */
3044 for (i = 0; i < ede->subtype->elements.num; ++i)
3045 if (strcmp(ede->subtype->elements.set[i].name, union_type) == 0)
3047 Eet_Data_Element *sede;
3049 /* Yeah we found it ! */
3050 data = eet_data_put_type(ed, EET_T_STRING, &union_type, &size);
3051 if (data) eet_data_encode(ed, ds, data, ede->name, size, ede->type, ede->group_type);
3053 sede = &(ede->subtype->elements.set[i]);
3055 if (sede->group_type != EET_G_UNKNOWN)
3057 Eet_Data_Stream *lds;
3059 lds = eet_data_stream_new();
3060 eet_group_codec[sede->group_type - 100].put(ed,
3067 eet_data_encode(ed, ds, lds->data, ede->name, lds->pos,
3068 ede->type, ede->group_type);
3075 eet_data_encode(ed, ds, NULL, ede->name, 0,
3076 EET_T_NULL, ede->group_type);
3079 eet_data_stream_free(lds);
3083 data = _eet_data_descriptor_encode(ed,
3087 if (data) eet_data_encode(ed, ds, data, ede->name, size, ede->type, ede->group_type);
3096 eet_data_get_variant(Eet_Free_Context *context, const Eet_Dictionary *ed,
3097 Eet_Data_Descriptor *edd __UNUSED__,
3098 Eet_Data_Element *ede, Eet_Data_Chunk *echnk,
3099 int type __UNUSED__, int group_type __UNUSED__, void *data,
3100 char **p, int *size)
3102 const char *union_type;
3103 void *data_ret = NULL;
3108 ret = eet_data_get_type(ed,
3111 ((char *)echnk->data) + echnk->size,
3113 if (ret <= 0) goto on_error;
3115 /* Advance to next chunk */
3116 NEXT_CHUNK((*p), (*size), (*echnk), ed);
3117 memset(echnk, 0, sizeof(Eet_Data_Chunk));
3120 eet_data_chunk_get(ed, echnk, *p, *size);
3121 if (!echnk->name) goto on_error;
3127 EET_ASSERT(ede->subtype, goto on_error);
3129 if ((!ed) || (!ede->subtype->func.str_direct_alloc))
3131 ut = ede->subtype->func.str_alloc(union_type);
3132 _eet_freelist_str_add(context, ut);
3136 ut = ede->subtype->func.str_direct_alloc(union_type);
3137 _eet_freelist_direct_str_add(context, ut);
3140 /* Search the structure of the union to decode */
3141 for (i = 0; i < ede->subtype->elements.num; ++i)
3142 if (strcmp(ede->subtype->elements.set[i].name, union_type) == 0)
3144 Eet_Data_Element *sede;
3146 /* Yeah we found it ! */
3147 sede = &(ede->subtype->elements.set[i]);
3149 if (sede->group_type != EET_G_UNKNOWN)
3151 Eet_Data_Chunk chnk;
3157 size2 = echnk->size;
3159 /* Didn't find a proper way to provide this
3160 without duplicating code */
3163 memset(&chnk, 0, sizeof(Eet_Data_Chunk));
3164 eet_data_chunk_get(ed, &chnk, p2, size2);
3166 if (!chnk.name) goto on_error;
3168 ret = eet_group_codec[sede->group_type - 100].get(context,
3171 sede->type, sede->group_type,
3174 if (ret <= 0) goto on_error;
3176 /* advance to next chunk */
3177 NEXT_CHUNK(p2, size2, chnk, ed);
3180 /* Put garbage so that we will not put eet_variant_unknow in it */
3181 data_ret = (void*) data;
3183 /* Set variant type. */
3184 ede->subtype->func.type_set(ut,
3185 ((char*) data) + ede->count - ede->offset,
3190 data_ret = _eet_data_descriptor_decode(context,
3195 if (!data_ret) break;
3197 /* And point to the variant data. */
3198 *(void**) data = data_ret;
3200 /* Set variant type. */
3201 ede->subtype->func.type_set(ut,
3202 ((char*) data) + ede->count - ede->offset,
3209 Eet_Variant_Unknow *evu;
3211 evu = calloc(1, sizeof (Eet_Variant_Unknow) + echnk->size - 1);
3212 if (!evu) goto on_error;
3214 evu->size = echnk->size;
3215 memcpy(evu->data, echnk->data, evu->size);
3216 EINA_MAGIC_SET(evu, EET_MAGIC_VARIANT);
3218 /* And point to the opaque internal data scructure */
3219 *(void**) data = evu;
3221 /* Set variant type. */
3222 ede->subtype->func.type_set(ut,
3223 ((char*) data) + ede->count - ede->offset,
3229 /* FIXME: dump node structure. */
3230 data_ret = _eet_data_descriptor_decode(context,
3232 echnk->data, echnk->size);
3243 eet_data_node_simple_type(int type, const char *name, void *dd)
3249 #define EET_T_TYPE(Eet_Type, Eet_Node_Type, Type) \
3251 return eet_node_##Eet_Node_Type##_new(name, *((Type *) dd)); \
3255 EET_T_TYPE(EET_T_CHAR, char, char);
3256 EET_T_TYPE(EET_T_SHORT, short, short);
3257 EET_T_TYPE(EET_T_INT, int, int);
3258 EET_T_TYPE(EET_T_LONG_LONG, long_long, long long);
3259 EET_T_TYPE(EET_T_FLOAT, float, float);
3260 EET_T_TYPE(EET_T_DOUBLE, double, double);
3261 EET_T_TYPE(EET_T_UCHAR, unsigned_char, unsigned char);
3262 EET_T_TYPE(EET_T_USHORT, unsigned_short, unsigned short);
3263 EET_T_TYPE(EET_T_UINT, unsigned_int, unsigned int);
3264 EET_T_TYPE(EET_T_ULONG_LONG, unsigned_long_long, unsigned long long);
3265 EET_T_TYPE(EET_T_STRING, string, char*);
3266 EET_T_TYPE(EET_T_INLINED_STRING, inlined_string, char*);
3268 return eet_node_null_new(name);
3270 ERR("Unknow type passed to eet_data_node_simple_type");
3276 eet_data_get_unknown(Eet_Free_Context *context, const Eet_Dictionary *ed, Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Chunk *echnk,
3277 int type, int group_type __UNUSED__, void *data,
3278 char **p __UNUSED__, int *size __UNUSED__)
3283 if (IS_SIMPLE_TYPE(type))
3285 unsigned char dd[128];
3287 ret = eet_data_get_type(ed, type, echnk->data, ((char *)echnk->data) + echnk->size, edd ? (char*) data : (char*) dd);
3288 if (ret <= 0) return ret;
3292 Eet_Node **parent = data;
3295 node = eet_data_node_simple_type(type, echnk->name, dd);
3297 if (*parent) eet_node_struct_append(*parent, echnk->name, node);
3298 else *parent = node;
3302 if (type == EET_T_STRING)
3306 str = (char **)(((char *)data));
3309 if ((ed == NULL) || (edd->func.str_direct_alloc == NULL))
3311 *str = edd->func.str_alloc(*str);
3312 _eet_freelist_str_add(context, *str);
3316 *str = edd->func.str_direct_alloc(*str);
3317 _eet_freelist_direct_str_add(context, *str);
3321 else if (edd && type == EET_T_INLINED_STRING)
3325 str = (char **)(((char *)data));
3328 *str = edd->func.str_alloc(*str);
3329 _eet_freelist_str_add(context, *str);
3336 Eet_Data_Descriptor *subtype;
3338 subtype = ede ? ede->subtype : NULL;
3340 if (subtype || !edd)
3342 Eet_Node **parent = data;
3345 data_ret = _eet_data_descriptor_decode(context, ed, subtype, echnk->data, echnk->size);
3346 if (!data_ret) return 0;
3350 ptr = (void **)(((char *)data));
3351 *ptr = (void *)data_ret;
3355 Eet_Node *node = data_ret;
3359 node = eet_node_struct_child_new(echnk->name, node);
3360 eet_node_struct_append(*parent, echnk->name, node);
3362 else *parent = node;
3371 eet_data_put_array(Eet_Dictionary *ed, Eet_Data_Descriptor *edd __UNUSED__, Eet_Data_Element *ede, Eet_Data_Stream *ds, void *data_in)
3380 EET_ASSERT(!((ede->type > EET_T_UNKNOW) && (ede->type < EET_T_STRING)), return );
3382 if (ede->group_type == EET_G_ARRAY)
3383 count = ede->counter_offset;
3385 count = *(int *)(((char *)data_in) + ede->count - ede->offset);
3387 if (count <= 0) return;
3388 /* Store number of elements */
3389 data = eet_data_put_type(ed, EET_T_INT, &count, &size);
3390 if (data) eet_data_encode(ed, ds, data, ede->name, size, ede->type, ede->group_type);
3392 if (IS_POINTER_TYPE(ede->type))
3393 subsize = eet_basic_codec[ede->type].size;
3395 subsize = ede->subtype->size;
3397 for (j = 0; j < count; j++)
3402 if (ede->group_type == EET_G_ARRAY)
3403 d = (void *)(((char *)data_in) + offset);
3405 d = *(((char **)data_in)) + offset;
3407 if (IS_POINTER_TYPE(ede->type))
3410 eet_data_put_unknown(ed, NULL, ede, ds, d);
3414 data = _eet_data_descriptor_encode(ed, ede->subtype, d, &size);
3415 if (data) eet_data_encode(ed, ds, data, ede->name, size, ede->type, ede->group_type);
3420 /* Add a NULL element just to have the correct array layout. */
3421 eet_data_encode(ed, ds, NULL, ede->name, 0, EET_T_NULL, ede->group_type);
3429 eet_data_put_unknown(Eet_Dictionary *ed, Eet_Data_Descriptor *edd __UNUSED__, Eet_Data_Element *ede, Eet_Data_Stream *ds, void *data_in)
3434 if (IS_SIMPLE_TYPE(ede->type))
3435 data = eet_data_put_type(ed, ede->type, data_in, &size);
3436 else if (ede->subtype)
3438 if (*((char **)data_in))
3439 data = _eet_data_descriptor_encode(ed,
3441 *((char **)((char *)(data_in))),
3444 if (data) eet_data_encode(ed, ds, data, ede->name, size, ede->type, ede->group_type);
3448 eet_data_put_list(Eet_Dictionary *ed, Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Stream *ds, void *data_in)
3454 EET_ASSERT(!(((ede->type > EET_T_UNKNOW) && (ede->type < EET_T_STRING))
3455 || ((ede->type > EET_T_NULL) && (ede->type < EET_T_LAST))),
3458 l = *((void **)(((char *)data_in)));
3459 for (; l; l = edd->func.list_next(l))
3461 if (IS_POINTER_TYPE(ede->type))
3463 const void *str = edd->func.list_data(l);
3464 eet_data_put_unknown(ed, NULL, ede, ds, &str);
3468 data = _eet_data_descriptor_encode(ed,
3470 edd->func.list_data(l),
3472 if (data) eet_data_encode(ed, ds, data, ede->name, size, ede->type, ede->group_type);
3478 eet_data_put_hash(Eet_Dictionary *ed, Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Stream *ds, void *data_in)
3480 Eet_Data_Encode_Hash_Info fdata;
3483 l = *((void **)(((char *)data_in)));
3487 edd->func.hash_foreach(l, eet_data_descriptor_encode_hash_cb, &fdata);
3491 eet_data_dump_cipher(Eet_File *ef,
3492 const char *name, const char *cipher_key,
3493 void (*dumpfunc) (void *data, const char *str),
3496 const Eet_Dictionary *ed = NULL;
3497 const void *data = NULL;
3499 Eet_Free_Context context;
3500 int required_free = 0;
3503 ed = eet_dictionary_get(ef);
3506 data = eet_read_direct(ef, name, &size);
3510 data = eet_read_cipher(ef, name, &size, cipher_key);
3511 if (!data) return 0;
3514 memset(&context, 0, sizeof (context));
3515 result = _eet_data_descriptor_decode(&context, ed, NULL, data, size);
3517 eet_node_dump(result, 0, dumpfunc, dumpdata);
3519 eet_node_del(result);
3524 return result ? 1 : 0;
3528 eet_data_dump(Eet_File *ef,
3530 void (*dumpfunc) (void *data, const char *str),
3533 return eet_data_dump_cipher(ef, name, NULL, dumpfunc, dumpdata);
3538 eet_data_text_dump_cipher(const void *data_in,
3539 const char *cipher_key, int size_in,
3540 void (*dumpfunc) (void *data, const char *str),
3545 Eet_Free_Context context;
3546 unsigned int ret_len = 0;
3548 if (!data_in) return 0;
3552 if (eet_decipher(data_in, size_in, cipher_key,
3553 strlen(cipher_key), &ret, &ret_len))
3561 ret = (void*) data_in;
3565 memset(&context, 0, sizeof (context));
3566 result = _eet_data_descriptor_decode(&context, NULL, NULL, ret, ret_len);
3568 eet_node_dump(result, 0, dumpfunc, dumpdata);
3570 eet_node_del(result);
3571 if (cipher_key) free(ret);
3573 return result ? 1 : 0;
3577 eet_data_text_dump(const void *data_in,
3579 void (*dumpfunc) (void *data, const char *str),
3582 return eet_data_text_dump_cipher(data_in, NULL, size_in, dumpfunc, dumpdata);
3586 eet_data_text_undump_cipher(const char *text,
3587 const char *cipher_key,
3593 ret = _eet_data_dump_parse(NULL, size_ret, text, textlen);
3594 if (ret && cipher_key)
3596 void *ciphered = NULL;
3597 unsigned int ciphered_len;
3599 if (eet_cipher(ret, *size_ret, cipher_key,
3600 strlen(cipher_key), &ciphered, &ciphered_len))
3602 if (ciphered) free(ciphered);
3608 *size_ret = ciphered_len;
3615 eet_data_text_undump(const char *text,
3619 return eet_data_text_undump_cipher(text, NULL, textlen, size_ret);
3623 eet_data_undump_cipher(Eet_File *ef,
3625 const char *cipher_key,
3635 ed = eet_dictionary_get(ef);
3637 data_enc = _eet_data_dump_parse(ed, &size, text, textlen);
3638 if (!data_enc) return 0;
3639 val = eet_write_cipher(ef, name, data_enc, size, compress, cipher_key);
3645 eet_data_undump(Eet_File *ef,
3651 return eet_data_undump_cipher(ef, name, NULL, text, textlen, compress);
3655 eet_data_descriptor_decode_cipher(Eet_Data_Descriptor *edd,
3656 const void *data_in,
3657 const char *cipher_key,
3660 void *deciphered = (void*) data_in;
3662 Eet_Free_Context context;
3663 unsigned int deciphered_len = size_in;
3665 if (cipher_key && data_in)
3667 if (eet_decipher(data_in, size_in, cipher_key,
3668 strlen(cipher_key), &deciphered, &deciphered_len))
3670 if (deciphered) free(deciphered);
3675 memset(&context, 0, sizeof (context));
3676 ret = _eet_data_descriptor_decode(&context, NULL, edd, deciphered, deciphered_len);
3678 if (data_in != deciphered) free(deciphered);
3684 eet_data_descriptor_decode(Eet_Data_Descriptor *edd,
3685 const void *data_in,
3688 return eet_data_descriptor_decode_cipher(edd, data_in, NULL, size_in);
3692 eet_data_node_decode_cipher(const void *data_in, const char *cipher_key, int size_in)
3694 void *deciphered = (void*) data_in;
3696 Eet_Free_Context context;
3697 unsigned int deciphered_len = size_in;
3699 if (cipher_key && data_in)
3701 if (eet_decipher(data_in, size_in, cipher_key,
3702 strlen(cipher_key), &deciphered, &deciphered_len))
3704 if (deciphered) free(deciphered);
3709 memset(&context, 0, sizeof (context));
3710 ret = _eet_data_descriptor_decode(&context, NULL, NULL, deciphered, deciphered_len);
3712 if (data_in != deciphered) free(deciphered);
3718 _eet_data_descriptor_encode(Eet_Dictionary *ed,
3719 Eet_Data_Descriptor *edd,
3720 const void *data_in,
3723 Eet_Data_Stream *ds;
3724 Eet_Data_Chunk *chnk;
3729 if (_eet_data_words_bigendian == -1)
3731 unsigned long int v;
3733 v = htonl(0x12345678);
3734 if (v == 0x12345678) _eet_data_words_bigendian = 1;
3735 else _eet_data_words_bigendian = 0;
3738 ds = eet_data_stream_new();
3739 for (i = 0; i < edd->elements.num; i++)
3741 Eet_Data_Element *ede;
3743 ede = &(edd->elements.set[i]);
3744 eet_group_codec[ede->group_type - 100].put(ed, edd, ede, ds, ((char *)data_in) + ede->offset);
3746 chnk = eet_data_chunk_new(ds->data, ds->pos, edd->name, EET_T_UNKNOW, EET_G_UNKNOWN);
3749 eet_data_stream_free(ds);
3751 ds = eet_data_stream_new();
3752 eet_data_chunk_put(ed, chnk, ds);
3758 eet_data_stream_free(ds);
3762 eet_data_chunk_free(chnk);
3768 eet_data_node_write_cipher(Eet_File *ef, const char *name, const char *cipher_key, Eet_Node *node, int compress)
3775 ed = eet_dictionary_get(ef);
3777 data_enc = _eet_data_dump_encode(EET_G_UNKNOWN, ed, node, &size);
3778 if (!data_enc) return 0;
3779 val = eet_write_cipher(ef, name, data_enc, size, compress, cipher_key);
3785 eet_data_node_encode_cipher(Eet_Node *node,
3786 const char *cipher_key,
3790 void *ciphered = NULL;
3791 unsigned int ciphered_len = 0;
3794 ret = _eet_data_dump_encode(EET_G_UNKNOWN, NULL, node, &size);
3795 if (cipher_key && ret)
3797 if (eet_cipher(ret, size, cipher_key,
3798 strlen(cipher_key), &ciphered, &ciphered_len))
3800 if (ciphered) free(ciphered);
3801 if (size_ret) *size_ret = 0;
3806 size = (int) ciphered_len;
3810 if (size_ret) *size_ret = size;
3815 eet_data_descriptor_encode_cipher(Eet_Data_Descriptor *edd,
3816 const void *data_in,
3817 const char *cipher_key,
3821 void *ciphered = NULL;
3822 unsigned int ciphered_len = 0;
3825 ret = _eet_data_descriptor_encode(NULL, edd, data_in, &size);
3826 if (cipher_key && ret)
3828 if (eet_cipher(ret, size, cipher_key,
3829 strlen(cipher_key), &ciphered, &ciphered_len))
3831 if (ciphered) free(ciphered);
3832 if (size_ret) *size_ret = 0;
3837 size = ciphered_len;
3841 if (size_ret) *size_ret = size;
3846 eet_data_descriptor_encode(Eet_Data_Descriptor *edd,
3847 const void *data_in,
3850 return eet_data_descriptor_encode_cipher(edd, data_in, NULL, size_ret);