2 * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
10 # define __UNUSED__ __attribute__((unused))
21 #ifdef HAVE_NETINET_IN_H
22 # include <netinet/in.h>
25 #if defined(_WIN32) && ! defined(__CEGCC__)
26 # include <winsock2.h>
32 #include "Eet_private.h"
35 * routines for doing data -> struct and struct -> data conversion
55 * multiple entries ordered as...
57 * fixed size array [ of basic types ]
58 * variable size array [ of basic types ]
59 * linked list [ of basic types ]
60 * hash table [ of basic types ]
62 * need to provide builder/accessor funcs for:
74 typedef struct _Eet_Data_Element Eet_Data_Element;
75 typedef struct _Eet_Data_Basic_Type_Codec Eet_Data_Basic_Type_Codec;
76 typedef struct _Eet_Data_Group_Type_Codec Eet_Data_Group_Type_Codec;
77 typedef struct _Eet_Data_Chunk Eet_Data_Chunk;
78 typedef struct _Eet_Data_Stream Eet_Data_Stream;
79 typedef struct _Eet_Data_Descriptor_Hash Eet_Data_Descriptor_Hash;
80 typedef struct _Eet_Data_Encode_Hash_Info Eet_Data_Encode_Hash_Info;
81 typedef struct _Eet_Free Eet_Free;
82 typedef struct _Eet_Free_Context Eet_Free_Context;
87 * Eet_Data_Basic_Type_Codec (Coder, Decoder)
88 * Eet_Data_Group_Type_Codec (Coder, Decoder)
90 struct _Eet_Data_Basic_Type_Codec
94 int (*get) (const Eet_Dictionary *ed, const void *src, const void *src_end, void *dest);
95 void *(*put) (Eet_Dictionary *ed, const void *src, int *size_ret);
98 struct _Eet_Data_Group_Type_Codec
100 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, int level, void (*dumpfunc) (void *data, const char *str), void *dumpdata, char **p, int *size);
101 void (*put) (Eet_Dictionary *ed, Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Stream *ds, void *data_in);
104 struct _Eet_Data_Chunk
112 unsigned char group_type;
115 struct _Eet_Data_Stream
122 struct _Eet_Data_Descriptor_Hash
124 Eet_Data_Element *element;
125 Eet_Data_Descriptor_Hash *next;
128 struct _Eet_Data_Descriptor
131 const Eet_Dictionary *ed;
134 void *(*mem_alloc) (size_t size);
135 void (*mem_free) (void *mem);
136 char *(*str_alloc) (const char *str);
137 char *(*str_direct_alloc) (const char *str);
138 void (*str_free) (const char *str);
139 void (*str_direct_free) (const char *str);
140 void *(*list_next) (void *l);
141 void *(*list_append) (void *l, void *d);
142 void *(*list_data) (void *l);
143 void *(*list_free) (void *l);
144 void (*hash_foreach) (void *h, int (*func) (void *h, const char *k, void *dt, void *fdt), void *fdt);
145 void *(*hash_add) (void *h, const char *k, void *d);
146 void (*hash_free) (void *h);
150 Eet_Data_Element *set;
153 Eet_Data_Descriptor_Hash *buckets;
160 struct _Eet_Data_Element
163 const char *counter_name;
164 const char *directory_name_ptr;
165 Eet_Data_Descriptor *subtype;
166 int offset; /* offset in bytes from the base element */
167 int count; /* number of elements for a fixed array */
168 int counter_offset; /* for a variable array we need the offset of the count variable */
169 unsigned char type; /* EET_T_XXX */
170 unsigned char group_type; /* EET_G_XXX */
173 struct _Eet_Data_Encode_Hash_Info
176 Eet_Data_Element *ede;
188 struct _Eet_Free_Context
191 Eet_Free freelist_list;
192 Eet_Free freelist_hash;
193 Eet_Free freelist_str;
194 Eet_Free freelist_direct_str;
199 static int eet_data_get_char(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dest);
200 static void *eet_data_put_char(Eet_Dictionary *ed, const void *src, int *size_ret);
201 static int eet_data_get_short(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dest);
202 static void *eet_data_put_short(Eet_Dictionary *ed, const void *src, int *size_ret);
203 static inline int eet_data_get_int(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dest);
204 static void *eet_data_put_int(Eet_Dictionary *ed, const void *src, int *size_ret);
205 static int eet_data_get_long_long(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dest);
206 static void *eet_data_put_long_long(Eet_Dictionary *ed, const void *src, int *size_ret);
207 static int eet_data_get_float(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dest);
208 static void *eet_data_put_float(Eet_Dictionary *ed, const void *src, int *size_ret);
209 static int eet_data_get_double(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dest);
210 static void *eet_data_put_double(Eet_Dictionary *ed, const void *src, int *size_ret);
211 static int eet_data_get_f32p32(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dest);
212 static void *eet_data_put_f32p32(Eet_Dictionary *ed, const void *src, int *size_ret);
213 static int eet_data_get_f16p16(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dest);
214 static void *eet_data_put_f16p16(Eet_Dictionary *ed, const void *src, int *size_ret);
215 static int eet_data_get_f8p24(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dest);
216 static void *eet_data_put_f8p24(Eet_Dictionary *ed, const void *src, int *size_ret);
217 static inline int eet_data_get_string(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dest);
218 static void *eet_data_put_string(Eet_Dictionary *ed, const void *src, int *size_ret);
219 static int eet_data_get_istring(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dest);
220 static void *eet_data_put_istring(Eet_Dictionary *ed, const void *src, int *size_ret);
221 static int eet_data_get_null(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dest);
222 static void *eet_data_put_null(Eet_Dictionary *ed, const void *src, int *size_ret);
224 static int eet_data_get_type(const Eet_Dictionary *ed, int type, const void *src, const void *src_end, void *dest);
225 static void *eet_data_put_type(Eet_Dictionary *ed, int type, const void *src, int *size_ret);
227 static void eet_data_dump_group_start(int level, void (*dumpfunc) (void *data, const char *str), void *dumpdata, int group_type, const char *name);
228 static void eet_data_dump_group_end(int level, void (*dumpfunc) (void *data, const char *str), void *dumpdata);
229 static void eet_data_dump_level(int level, void (*dumpfunc) (void *data, const char *str), void *dumpdata);
230 static void eet_data_dump_simple_type(int type, const char *name, void *dd,
231 int level, void (*dumpfunc) (void *data, const char *str), void *dumpdata);
234 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, int level, void (*dumpfunc) (void *data, const char *str), void *dumpdata, char **p, int *size);
235 static void eet_data_put_unknown(Eet_Dictionary *ed, Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Stream *ds, void *data_in);
236 static void eet_data_put_array(Eet_Dictionary *ed, Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Stream *ds, void *data_in);
237 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, int level, void (*dumpfunc) (void *data, const char *str), void *dumpdata, char **p, int *size);
238 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, int level, void (*dumpfunc) (void *data, const char *str), void *dumpdata, char **p, int *size);
239 static void eet_data_put_list(Eet_Dictionary *ed, Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Stream *ds, void *data_in);
240 static void eet_data_put_hash(Eet_Dictionary *ed, Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Stream *ds, void *data_in);
241 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, int level, void (*dumpfunc) (void *data, const char *str), void *dumpdata, char **p, int *size);
243 static void eet_data_chunk_get(const Eet_Dictionary *ed, Eet_Data_Chunk *chnk, const void *src, int size);
244 static Eet_Data_Chunk *eet_data_chunk_new(void *data, int size, const char *name, int type, int group_type);
245 static void eet_data_chunk_free(Eet_Data_Chunk *chnk);
247 static Eet_Data_Stream *eet_data_stream_new(void);
248 static void eet_data_stream_write(Eet_Data_Stream *ds, const void *data, int size);
249 static void eet_data_stream_free(Eet_Data_Stream *ds);
251 static void eet_data_chunk_put(Eet_Dictionary *ed, Eet_Data_Chunk *chnk, Eet_Data_Stream *ds);
253 static int eet_data_descriptor_encode_hash_cb(void *hash, const char *key, void *hdata, void *fdata);
254 static void *_eet_data_descriptor_encode(Eet_Dictionary *ed, Eet_Data_Descriptor *edd, const void *data_in, int *size_ret);
255 static void *_eet_data_descriptor_decode(Eet_Free_Context *context,
256 const Eet_Dictionary *ed,
257 Eet_Data_Descriptor *edd,
261 void (*dumpfunc) (void *data, const char *str),
266 static const Eet_Data_Basic_Type_Codec eet_basic_codec[] =
268 {sizeof(char), "char", eet_data_get_char, eet_data_put_char },
269 {sizeof(short), "short", eet_data_get_short, eet_data_put_short },
270 {sizeof(int), "int", eet_data_get_int, eet_data_put_int },
271 {sizeof(long long), "long_long", eet_data_get_long_long, eet_data_put_long_long},
272 {sizeof(float), "float", eet_data_get_float, eet_data_put_float },
273 {sizeof(double), "double", eet_data_get_double, eet_data_put_double },
274 {sizeof(char), "uchar", eet_data_get_char, eet_data_put_char },
275 {sizeof(short), "ushort", eet_data_get_short, eet_data_put_short },
276 {sizeof(int), "uint", eet_data_get_int, eet_data_put_int },
277 {sizeof(long long), "ulong_long", eet_data_get_long_long, eet_data_put_long_long},
278 {sizeof(char *), "string", eet_data_get_string, eet_data_put_string },
279 {sizeof(char *), "inlined", eet_data_get_istring, eet_data_put_istring },
280 {sizeof(void *), "NULL", eet_data_get_null, eet_data_put_null },
281 {sizeof(Eina_F32p32),"f32p32", eet_data_get_f32p32, eet_data_put_f32p32 },
282 {sizeof(Eina_F16p16),"f16p16", eet_data_get_f16p16, eet_data_put_f16p16 },
283 {sizeof(Eina_F8p24),"f8p24", eet_data_get_f8p24, eet_data_put_f8p24 }
286 static const Eet_Data_Group_Type_Codec eet_group_codec[] =
288 { eet_data_get_unknown, eet_data_put_unknown },
289 { eet_data_get_array, eet_data_put_array },
290 { eet_data_get_array, eet_data_put_array },
291 { eet_data_get_list, eet_data_put_list },
292 { eet_data_get_hash, eet_data_put_hash }
295 static int _eet_data_words_bigendian = -1;
299 #define SWAP64(x) (x) = \
300 ((((unsigned long long)(x) & 0x00000000000000ffULL ) << 56) |\
301 (((unsigned long long)(x) & 0x000000000000ff00ULL ) << 40) |\
302 (((unsigned long long)(x) & 0x0000000000ff0000ULL ) << 24) |\
303 (((unsigned long long)(x) & 0x00000000ff000000ULL ) << 8) |\
304 (((unsigned long long)(x) & 0x000000ff00000000ULL ) >> 8) |\
305 (((unsigned long long)(x) & 0x0000ff0000000000ULL ) >> 24) |\
306 (((unsigned long long)(x) & 0x00ff000000000000ULL ) >> 40) |\
307 (((unsigned long long)(x) & 0xff00000000000000ULL ) >> 56))
308 #define SWAP32(x) (x) = \
309 ((((int)(x) & 0x000000ff ) << 24) |\
310 (((int)(x) & 0x0000ff00 ) << 8) |\
311 (((int)(x) & 0x00ff0000 ) >> 8) |\
312 (((int)(x) & 0xff000000 ) >> 24))
313 #define SWAP16(x) (x) = \
314 ((((short)(x) & 0x00ff ) << 8) |\
315 (((short)(x) & 0xff00 ) >> 8))
331 #define CONV16(x) {if (_eet_data_words_bigendian) SWAP16(x);}
332 #define CONV32(x) {if (_eet_data_words_bigendian) SWAP32(x);}
333 #define CONV64(x) {if (_eet_data_words_bigendian) SWAP64(x);}
335 #define IS_SIMPLE_TYPE(Type) (Type > EET_T_UNKNOW && Type < EET_T_LAST)
341 eet_data_get_char(const Eet_Dictionary *ed __UNUSED__, const void *src, const void *src_end, void *dst)
345 if (((char *)src + sizeof(char)) > (char *)src_end) return -1;
354 eet_data_put_char(Eet_Dictionary *ed __UNUSED__, const void *src, int *size_ret)
358 d = (char *)malloc(sizeof(char));
363 *size_ret = sizeof(char);
369 eet_data_get_short(const Eet_Dictionary *ed __UNUSED__, const void *src, const void *src_end, void *dst)
373 if (((char *)src + sizeof(short)) > (char *)src_end) return -1;
374 memcpy(dst, src, sizeof(short));
377 return sizeof(short);
381 eet_data_put_short(Eet_Dictionary *ed __UNUSED__, const void *src, int *size_ret)
385 d = (short *)malloc(sizeof(short));
390 *size_ret = sizeof(short);
396 eet_data_get_int(const Eet_Dictionary *ed __UNUSED__, const void *src, const void *src_end, void *dst)
400 if (((char *)src + sizeof(int)) > (char *)src_end) return -1;
401 memcpy(dst, src, sizeof(int));
408 eet_data_put_int(Eet_Dictionary *ed __UNUSED__, const void *src, int *size_ret)
412 d = (int *)malloc(sizeof(int));
417 *size_ret = sizeof(int);
423 eet_data_get_long_long(const Eet_Dictionary *ed __UNUSED__, const void *src, const void *src_end, void *dst)
425 unsigned long long *d;
427 if (((char *)src + sizeof(unsigned long long)) > (char *)src_end) return -1;
428 memcpy(dst, src, sizeof(unsigned long long));
429 d = (unsigned long long *)dst;
431 return sizeof(unsigned long long);
435 eet_data_put_long_long(Eet_Dictionary *ed __UNUSED__, const void *src, int *size_ret)
437 unsigned long long *s, *d;
439 d = (unsigned long long *)malloc(sizeof(unsigned long long));
441 s = (unsigned long long *)src;
444 *size_ret = sizeof(unsigned long long);
450 eet_data_get_string_hash(const Eet_Dictionary *ed, const void *src, const void *src_end)
456 if (eet_data_get_int(ed, src, src_end, &index) < 0) return -1;
458 return eet_dictionary_string_get_hash(ed, index);
465 eet_data_get_string(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dst)
476 if (eet_data_get_int(ed, src, src_end, &index) < 0) return -1;
478 str = eet_dictionary_string_get_char(ed, index);
483 return eet_dictionary_string_get_size(ed, index);
494 return strlen(s) + 1;
498 eet_data_put_string(Eet_Dictionary *ed, const void *src, int *size_ret)
508 str = *((const char **) src);
509 if (!str) return NULL;
511 index = eet_dictionary_string_add(ed, str);
512 if (index == -1) return NULL;
514 return eet_data_put_int(ed, &index, size_ret);
517 s = (char *)(*((char **)src));
522 memcpy(d, s, len + 1);
527 /* ALWAYS INLINED STRING TYPE */
529 eet_data_get_istring(const Eet_Dictionary *ed __UNUSED__, const void *src, const void *src_end, void *dst)
531 return eet_data_get_string(NULL, src, src_end, dst);
535 eet_data_put_istring(Eet_Dictionary *ed __UNUSED__, const void *src, int *size_ret)
537 return eet_data_put_string(NULL, src, size_ret);
540 /* ALWAYS NULL TYPE */
542 eet_data_get_null(const Eet_Dictionary *ed __UNUSED__, const void *src __UNUSED__, const void *src_end __UNUSED__, void *dst)
553 eet_data_put_null(Eet_Dictionary *ed __UNUSED__, const void *src __UNUSED__, int *size_ret)
560 * Fast lookups of simple doubles/floats.
562 * These aren't properly a cache because they don't store pre-calculated
563 * values, but have a so simple math that is almost as fast.
566 _eet_data_float_cache_get(const char *s, int len, float *d)
568 /* fast handle of simple case 0xMp+E*/
569 if ((len == 6) && (s[0] == '0') && (s[1] == 'x') && (s[3] == 'p'))
571 int mantisse = (s[2] >= 'a') ? (s[2] - 'a' + 10) : (s[2] - '0');
572 int exponent = (s[5] - '0');
574 if (s[4] == '+') *d = (float)(mantisse << exponent);
575 else *d = (float)mantisse / (float)(1 << exponent);
583 _eet_data_double_cache_get(const char *s, int len, double *d)
585 /* fast handle of simple case 0xMp+E*/
586 if ((len == 6) && (s[0] == '0') && (s[1] == 'x') && (s[3] == 'p'))
588 int mantisse = (s[2] >= 'a') ? (s[2] - 'a' + 10) : (s[2] - '0');
589 int exponent = (s[5] - '0');
591 if (s[4] == '+') *d = (double)(mantisse << exponent);
592 else *d = (double)mantisse / (double)(1 << exponent);
601 eet_data_get_float(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dst)
614 s = (const char *)src;
617 while ((p < (const char *)src_end) && (*p != 0)) {len++; p++;}
619 if (_eet_data_float_cache_get(s, len, d) != 0) return len + 1;
621 if (eina_convert_atod(s, len, &mantisse, &exponent) == EINA_FALSE) return -1;
622 *d = (float)ldexp((double)mantisse, exponent);
627 if (eet_data_get_int(ed, src, src_end, &index) < 0) return -1;
629 if (!eet_dictionary_string_get_float(ed, index, d))
635 eet_data_put_float(Eet_Dictionary *ed, const void *src, int *size_ret)
640 eina_convert_dtoa((double)(*(float *)src), buf);
650 memcpy(d, buf, len + 1);
655 index = eet_dictionary_string_add(ed, buf);
656 if (index == -1) return NULL;
658 return eet_data_put_int(ed, &index, size_ret);
663 eet_data_get_double(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dst)
673 long long mantisse = 0;
677 s = (const char *) src;
680 while ((p < (const char *)src_end) && (*p != 0)) {len++; p++;}
682 if (_eet_data_double_cache_get(s, len, d) != 0) return len + 1;
684 if (eina_convert_atod(s, len, &mantisse, &exponent) == EINA_FALSE) return -1;
685 *d = ldexp((double) mantisse, exponent);
690 if (eet_data_get_int(ed, src, src_end, &index) < 0) return -1;
692 if (!eet_dictionary_string_get_double(ed, index, d))
698 eet_data_put_double(Eet_Dictionary *ed, const void *src, int *size_ret)
703 eina_convert_dtoa((double)(*(double *)src), buf);
713 memcpy(d, buf, len + 1);
719 index = eet_dictionary_string_add(ed, buf);
720 if (index == -1) return NULL;
722 return eet_data_put_int(ed, &index, size_ret);
726 eet_data_get_f32p32(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dst)
731 fp = (Eina_F32p32*) dst;
735 if (eet_data_get_int(ed, src, src_end, &index) < 0) return -1;
737 if (!eet_dictionary_string_get_fp(ed, index, fp))
743 eet_data_put_f32p32(Eet_Dictionary *ed, const void *src, int *size_ret)
748 if (!ed) return NULL;
750 eina_convert_fptoa((Eina_F32p32)(*(Eina_F32p32 *)src), buf);
752 index = eet_dictionary_string_add(ed, buf);
753 if (index == -1) return NULL;
755 return eet_data_put_int(ed, &index, size_ret);
759 eet_data_get_f16p16(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dst)
764 fp = (Eina_F16p16*) dst;
766 if (eet_data_get_f32p32(ed, src, src_end, &tmp) < 0) return -1;
768 *fp = eina_f32p32_to_f16p16(tmp);
773 eet_data_put_f16p16(Eet_Dictionary *ed, const void *src, int *size_ret)
777 tmp = eina_f16p16_to_f32p32((Eina_F16p16)(*(Eina_F16p16 *)src));
778 return eet_data_put_f32p32(ed, &tmp, size_ret);
782 eet_data_get_f8p24(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dst)
787 fp = (Eina_F8p24*) dst;
789 if (eet_data_get_f32p32(ed, src, src_end, &tmp) < 0) return -1;
791 *fp = eina_f32p32_to_f8p24(tmp);
796 eet_data_put_f8p24(Eet_Dictionary *ed, const void *src, int *size_ret)
800 tmp = eina_f8p24_to_f32p32((Eina_F8p24)(*(Eina_F8p24 *)src));
801 return eet_data_put_f32p32(ed, &tmp, size_ret);
805 eet_data_get_type(const Eet_Dictionary *ed, int type, const void *src, const void *src_end, void *dest)
809 ret = eet_basic_codec[type - 1].get(ed, src, src_end, dest);
814 eet_data_put_type(Eet_Dictionary *ed, int type, const void *src, int *size_ret)
818 ret = eet_basic_codec[type - 1].put(ed, src, size_ret);
822 static inline Eina_Bool
823 eet_data_type_match(int type1, int type2)
825 if (type1 == type2) return EINA_TRUE;
827 /* Note: All floating point type are equivalent and could be read
828 without problem by any other floating point getter. */
857 * char[4] = "CHnK"; // untyped data ... or
858 * char[4] = "CHKx"; // typed data - x == type
860 * int = chunk size (including magic string);
861 * char[] = chunk magic/name string (0 byte terminated);
862 * ... sub-chunks (a chunk can contain chuncks recusrively) ...
864 * ... payload data ...
869 eet_data_chunk_get(const Eet_Dictionary *ed, Eet_Data_Chunk *chnk,
870 const void *src, int size)
876 if (size <= 8) return;
883 if ((s[0] != 'C') || (s[1] != 'H') || (s[2] != 'K'))
886 chnk->type = (unsigned char)(s[3]);
887 if (chnk->type > EET_T_LAST)
889 chnk->group_type = chnk->type;
890 chnk->type = EET_T_UNKNOW;
893 chnk->group_type = EET_G_UNKNOWN;
894 if ((chnk->type >= EET_T_LAST) ||
895 (chnk->group_type >= EET_G_LAST))
898 chnk->group_type = 0;
903 if ((s[0] != 'C') || (s[1] != 'H') || (s[2] != 'n') || (s[3] != 'K'))
906 ret1 = eet_data_get_type(ed, EET_T_INT, (s + 4), (s + size), &(chnk->size));
907 if (ret1 <= 0) return;
908 if ((chnk->size < 0) || ((chnk->size + 8) > size)) return;
909 ret2 = eet_data_get_type(ed, EET_T_STRING, (s + 8), (s + size), &(chnk->name));
910 if (ret2 <= 0) return;
915 chnk->hash = eet_data_get_string_hash(ed, (s + 8), (s + size));
919 chnk->data = (char *)src + 4 + ret1 + sizeof(int);
920 chnk->size -= sizeof(int);
924 chnk->data = (char *)src + 4 + ret1 + chnk->len;
925 chnk->size -= chnk->len;
931 static inline Eet_Data_Chunk *
932 eet_data_chunk_new(void *data, int size, const char *name, int type, int group_type)
934 Eet_Data_Chunk *chnk;
936 if (!name) return NULL;
937 chnk = calloc(1, sizeof(Eet_Data_Chunk));
938 if (!chnk) return NULL;
940 /* Note: Another security, so older eet library could read file
941 saved with fixed point value. */
942 if (type == EET_T_F32P32
943 || type == EET_T_F16P16
944 || type == EET_T_F8P24)
947 chnk->name = strdup(name);
948 chnk->len = strlen(name) + 1;
952 chnk->group_type = group_type;
957 eet_data_chunk_free(Eet_Data_Chunk *chnk)
959 if (chnk->name) free(chnk->name);
963 static inline Eet_Data_Stream *
964 eet_data_stream_new(void)
968 ds = calloc(1, sizeof(Eet_Data_Stream));
969 if (!ds) return NULL;
974 eet_data_stream_free(Eet_Data_Stream *ds)
976 if (ds->data) free(ds->data);
981 eet_data_stream_write(Eet_Data_Stream *ds, const void *data, int size)
985 if ((ds->pos + size) > ds->size)
987 ds->data = realloc(ds->data, ds->size + size + 512);
994 ds->size = ds->size + size + 512;
997 memcpy(p + ds->pos, data, size);
1002 eet_data_chunk_put(Eet_Dictionary *ed, Eet_Data_Chunk *chnk, Eet_Data_Stream *ds)
1009 unsigned char buf[4] = "CHK";
1011 /* disable this check - it will allow empty chunks to be written. this is
1012 * right for corner-cases when y have a struct with empty fields (empty
1013 * strings or empty list ptrs etc.) */
1014 /* if (!chnk->data && chnk->type != EET_T_NULL) return; */
1017 /* eet_data_stream_write(ds, "CHnK", 4);*/
1018 if (chnk->type != EET_T_UNKNOW) buf[3] = chnk->type;
1019 else buf[3] = chnk->group_type;
1021 string = eet_data_put_string(ed, &chnk->name, &string_ret);
1025 /* size of chunk payload data + name */
1026 s = chnk->size + string_ret;
1027 size = eet_data_put_int(ed, &s, &size_ret);
1029 /* FIXME: If something goes wrong the resulting file will be corrupted. */
1033 eet_data_stream_write(ds, buf, 4);
1035 /* write chunk length */
1036 eet_data_stream_write(ds, size, size_ret);
1038 /* write chunk name */
1039 eet_data_stream_write(ds, string, string_ret);
1043 eet_data_stream_write(ds, chnk->data, chnk->size);
1053 _eet_descriptor_hash_new(Eet_Data_Descriptor *edd)
1057 edd->elements.hash.size = 1 << 6;
1058 edd->elements.hash.buckets = calloc(1, sizeof(Eet_Data_Descriptor_Hash) * edd->elements.hash.size);
1059 for (i = 0; i < edd->elements.num; i++)
1061 Eet_Data_Element *ede;
1064 ede = &(edd->elements.set[i]);
1065 hash = _eet_hash_gen((char *) ede->name, 6);
1066 if (!edd->elements.hash.buckets[hash].element)
1067 edd->elements.hash.buckets[hash].element = ede;
1070 Eet_Data_Descriptor_Hash *bucket;
1072 bucket = calloc(1, sizeof(Eet_Data_Descriptor_Hash));
1073 bucket->element = ede;
1074 bucket->next = edd->elements.hash.buckets[hash].next;
1075 edd->elements.hash.buckets[hash].next = bucket;
1081 _eet_descriptor_hash_free(Eet_Data_Descriptor *edd)
1085 for (i = 0; i < edd->elements.hash.size; i++)
1087 Eet_Data_Descriptor_Hash *bucket, *pbucket;
1089 bucket = edd->elements.hash.buckets[i].next;
1093 bucket = bucket->next;
1097 if (edd->elements.hash.buckets) free(edd->elements.hash.buckets);
1100 static Eet_Data_Element *
1101 _eet_descriptor_hash_find(Eet_Data_Descriptor *edd, char *name, int hash)
1103 Eet_Data_Descriptor_Hash *bucket;
1105 if (hash < 0) hash = _eet_hash_gen(name, 6);
1107 if (!edd->elements.hash.buckets[hash].element) return NULL;
1109 When we use the dictionnary as a source for chunk name, we will always
1110 have the same pointer in name. It's a good idea to just compare pointer
1111 instead of running strcmp on both string.
1113 if (edd->elements.hash.buckets[hash].element->directory_name_ptr == name)
1114 return edd->elements.hash.buckets[hash].element;
1115 if (!strcmp(edd->elements.hash.buckets[hash].element->name, name))
1117 edd->elements.hash.buckets[hash].element->directory_name_ptr = name;
1118 return edd->elements.hash.buckets[hash].element;
1120 bucket = edd->elements.hash.buckets[hash].next;
1123 if (bucket->element->directory_name_ptr == name) return bucket->element;
1124 if (!strcmp(bucket->element->name, name))
1126 bucket->element->directory_name_ptr = name;
1127 return bucket->element;
1129 bucket = bucket->next;
1135 _eet_mem_alloc(size_t size)
1137 return calloc(1, size);
1141 _eet_mem_free(void *mem)
1147 _eet_str_alloc(const char *str)
1153 _eet_str_free(const char *str)
1159 _eet_eina_hash_add_alloc(Eina_Hash *hash, const char *key, void *data)
1161 if (!hash) hash = eina_hash_string_small_new(NULL);
1162 if (!hash) return NULL;
1164 eina_hash_add(hash, key, data);
1169 _eet_str_direct_alloc(const char *str)
1175 _eet_str_direct_free(const char *str)
1181 eet_eina_stream_data_descriptor_class_set(Eet_Data_Descriptor_Class *eddc, const char *name, int size)
1183 if (!eddc || !name) return EINA_FALSE;
1189 eddc->func.mem_alloc = _eet_mem_alloc;
1190 eddc->func.mem_free = _eet_mem_free;
1191 eddc->func.str_alloc = (char *(*)(const char *))eina_stringshare_add;
1192 eddc->func.str_free = eina_stringshare_del;
1193 eddc->func.list_next = (void *(*)(void *))eina_list_next;
1194 eddc->func.list_append = (void *(*)(void *, void *))eina_list_append;
1195 eddc->func.list_data = (void *(*)(void *))eina_list_data_get;
1196 eddc->func.list_free = (void *(*)(void *))eina_list_free;
1197 eddc->func.hash_foreach = (void (*)(void *, int (*)(void *, const char *, void *, void *), void *))eina_hash_foreach;
1198 eddc->func.hash_add = (void* (*)(void *, const char *, void *)) _eet_eina_hash_add_alloc;
1199 eddc->func.hash_free = (void (*)(void *))eina_hash_free;
1205 eet_eina_file_data_descriptor_class_set(Eet_Data_Descriptor_Class *eddc, const char *name, int size)
1207 if (!eet_eina_stream_data_descriptor_class_set(eddc, name, size))
1212 eddc->func.str_direct_alloc = _eet_str_direct_alloc;
1213 eddc->func.str_direct_free = _eet_str_direct_free;
1218 static Eet_Data_Descriptor *
1219 _eet_data_descriptor_new(const Eet_Data_Descriptor_Class *eddc, int version)
1221 Eet_Data_Descriptor *edd;
1223 if (!eddc) return NULL;
1224 if (eddc->version < version) return NULL;
1226 edd = calloc(1, sizeof (Eet_Data_Descriptor));
1227 if (!edd) return NULL;
1229 edd->name = eddc->name;
1231 edd->size = eddc->size;
1232 edd->func.mem_alloc = _eet_mem_alloc;
1233 edd->func.mem_free = _eet_mem_free;
1234 edd->func.str_alloc = _eet_str_alloc;
1235 edd->func.str_free = _eet_str_free;
1236 if (eddc->func.mem_alloc)
1237 edd->func.mem_alloc = eddc->func.mem_alloc;
1238 if (eddc->func.mem_free)
1239 edd->func.mem_free = eddc->func.mem_free;
1240 if (eddc->func.str_alloc)
1241 edd->func.str_alloc = eddc->func.str_alloc;
1242 if (eddc->func.str_free)
1243 edd->func.str_free = eddc->func.str_free;
1244 edd->func.list_next = eddc->func.list_next;
1245 edd->func.list_append = eddc->func.list_append;
1246 edd->func.list_data = eddc->func.list_data;
1247 edd->func.list_free = eddc->func.list_free;
1248 edd->func.hash_foreach = eddc->func.hash_foreach;
1249 edd->func.hash_add = eddc->func.hash_add;
1250 edd->func.hash_free = eddc->func.hash_free;
1254 edd->func.str_direct_alloc = eddc->func.str_direct_alloc;
1255 edd->func.str_direct_free = eddc->func.str_direct_free;
1261 EAPI Eet_Data_Descriptor *
1262 eet_data_descriptor_new(const char *name,
1264 void *(*func_list_next) (void *l),
1265 void *(*func_list_append) (void *l, void *d),
1266 void *(*func_list_data) (void *l),
1267 void *(*func_list_free) (void *l),
1268 void (*func_hash_foreach) (void *h, int (*func) (void *h, const char *k, void *dt, void *fdt), void *fdt),
1269 void *(*func_hash_add) (void *h, const char *k, void *d),
1270 void (*func_hash_free) (void *h))
1272 Eet_Data_Descriptor_Class eddc;
1274 if (!name) return NULL;
1276 memset(&eddc, 0, sizeof (Eet_Data_Descriptor_Class));
1282 eddc.func.list_next = func_list_next;
1283 eddc.func.list_append = func_list_append;
1284 eddc.func.list_data = func_list_data;
1285 eddc.func.list_free = func_list_free;
1286 eddc.func.hash_foreach = func_hash_foreach;
1287 eddc.func.hash_add = func_hash_add;
1288 eddc.func.hash_free = func_hash_free;
1290 return _eet_data_descriptor_new(&eddc, 0);
1293 EAPI Eet_Data_Descriptor *
1294 eet_data_descriptor2_new(const Eet_Data_Descriptor_Class *eddc)
1296 return _eet_data_descriptor_new(eddc, 1);
1299 EAPI Eet_Data_Descriptor *
1300 eet_data_descriptor3_new(const Eet_Data_Descriptor_Class *eddc)
1302 return _eet_data_descriptor_new(eddc, 2);
1305 EAPI Eet_Data_Descriptor *
1306 eet_data_descriptor_stream_new(const Eet_Data_Descriptor_Class *eddc)
1308 return _eet_data_descriptor_new(eddc, 1);
1311 EAPI Eet_Data_Descriptor *
1312 eet_data_descriptor_file_new(const Eet_Data_Descriptor_Class *eddc)
1314 return _eet_data_descriptor_new(eddc, 2);
1318 eet_data_descriptor_free(Eet_Data_Descriptor *edd)
1320 _eet_descriptor_hash_free(edd);
1321 if (edd->elements.set) free(edd->elements.set);
1326 eet_data_descriptor_element_add(Eet_Data_Descriptor *edd,
1332 /* int counter_offset, */
1333 const char *counter_name /* Useless should go on a major release */,
1334 Eet_Data_Descriptor *subtype)
1336 Eet_Data_Element *ede;
1337 /* int l1, l2, p1, p2, i;
1340 /* FIXME: Fail safely when realloc fail. */
1341 edd->elements.num++;
1342 edd->elements.set = realloc(edd->elements.set, edd->elements.num * sizeof(Eet_Data_Element));
1343 if (!edd->elements.set) return;
1344 ede = &(edd->elements.set[edd->elements.num - 1]);
1346 ede->directory_name_ptr = NULL;
1349 * We do a special case when we do list,hash or whatever group of simple type.
1350 * Instead of handling it in encode/decode/dump/undump, we create an
1351 * implicit structure with only the simple type.
1353 if (group_type > EET_G_UNKNOWN
1354 && group_type < EET_G_LAST
1355 && type > EET_T_UNKNOW && type < EET_T_STRING
1358 subtype = calloc(1, sizeof (Eet_Data_Descriptor));
1359 if (!subtype) return ;
1360 subtype->name = "implicit";
1361 subtype->size = eet_basic_codec[type - 1].size;
1362 memcpy(&subtype->func, &edd->func, sizeof(subtype->func));
1364 eet_data_descriptor_element_add(subtype, eet_basic_codec[type - 1].name, type,
1365 EET_G_UNKNOWN, 0, 0, /* 0, */NULL, NULL);
1366 type = EET_T_UNKNOW;
1370 ede->group_type = group_type;
1371 ede->offset = offset;
1373 /* FIXME: For the time being, EET_G_VAR_ARRAY will put the counter_offset in count. */
1374 ede->counter_offset = count;
1375 /* ede->counter_offset = counter_offset; */
1376 ede->counter_name = counter_name;
1378 ede->subtype = subtype;
1382 eet_data_read_cipher(Eet_File *ef, Eet_Data_Descriptor *edd, const char *name, const char *key)
1384 const Eet_Dictionary *ed = NULL;
1385 const void *data = NULL;
1387 Eet_Free_Context context;
1388 int required_free = 0;
1391 ed = eet_dictionary_get(ef);
1394 data = eet_read_direct(ef, name, &size);
1398 data = eet_read_cipher(ef, name, &size, key);
1399 if (!data) return NULL;
1402 memset(&context, 0, sizeof (context));
1403 data_dec = _eet_data_descriptor_decode(&context, ed, edd, data, size, 0, NULL, NULL);
1411 eet_data_read(Eet_File *ef, Eet_Data_Descriptor *edd, const char *name)
1413 return eet_data_read_cipher(ef, edd, name, NULL);
1417 eet_data_write_cipher(Eet_File *ef, Eet_Data_Descriptor *edd, const char *name, const char *key, const void *data, int compress)
1424 ed = eet_dictionary_get(ef);
1426 data_enc = _eet_data_descriptor_encode(ed, edd, data, &size);
1427 if (!data_enc) return 0;
1428 val = eet_write_cipher(ef, name, data_enc, size, compress, key);
1434 eet_data_write(Eet_File *ef, Eet_Data_Descriptor *edd, const char *name, const void *data, int compress)
1436 return eet_data_write_cipher(ef, edd, name, NULL, data, compress);
1440 _eet_free_hash(void *data)
1442 unsigned long ptr = (unsigned long)(data);
1461 _eet_free_add(Eet_Free *ef, void *data)
1466 hash = _eet_free_hash(data);
1468 for (i = 0; i < ef->num[hash]; ++i)
1469 if (ef->list[hash][i] == data) return;
1472 if (ef->num[hash] > ef->len[hash])
1476 tmp = realloc(ef->list[hash], (ef->len[hash] + 16) * sizeof(void*));
1479 ef->len[hash] += 16;
1480 ef->list[hash] = tmp;
1482 ef->list[hash][ef->num[hash] - 1] = data;
1485 _eet_free_reset(Eet_Free *ef)
1489 if (ef->ref > 0) return ;
1490 for (i = 0; i < 256; ++i)
1494 if (ef->list[i]) free(ef->list[i]);
1499 _eet_free_ref(Eet_Free *ef)
1504 _eet_free_unref(Eet_Free *ef)
1509 #define _eet_freelist_add(Ctx, Data) _eet_free_add(&Ctx->freelist, Data);
1510 #define _eet_freelist_reset(Ctx) _eet_free_reset(&Ctx->freelist);
1511 #define _eet_freelist_ref(Ctx) _eet_free_ref(&Ctx->freelist);
1512 #define _eet_freelist_unref(Ctx) _eet_free_unref(&Ctx->freelist);
1515 _eet_freelist_free(Eet_Free_Context *context, Eet_Data_Descriptor *edd)
1520 if (context->freelist.ref > 0) return;
1521 for (j = 0; j < 256; ++j)
1522 for (i = 0; i < context->freelist.num[j]; ++i)
1525 edd->func.mem_free(context->freelist.list[j][i]);
1527 free(context->freelist.list[j][i]);
1529 _eet_free_reset(&context->freelist);
1532 #define _eet_freelist_list_add(Ctx, Data) _eet_free_add(&Ctx->freelist_list, Data);
1533 #define _eet_freelist_list_reset(Ctx) _eet_free_reset(&Ctx->freelist_list);
1534 #define _eet_freelist_list_ref(Ctx) _eet_free_ref(&Ctx->freelist_list);
1535 #define _eet_freelist_list_unref(Ctx) _eet_free_unref(&Ctx->freelist_list);
1538 _eet_freelist_list_free(Eet_Free_Context *context, Eet_Data_Descriptor *edd)
1543 if (context->freelist_list.ref > 0) return;
1544 for (j = 0; j < 256; ++j)
1545 for (i = 0; i < context->freelist_list.num[j]; ++i)
1548 edd->func.list_free(*((void**)(context->freelist_list.list[j][i])));
1550 _eet_free_reset(&context->freelist_list);
1553 #define _eet_freelist_str_add(Ctx, Data) _eet_free_add(&Ctx->freelist_str, Data);
1554 #define _eet_freelist_str_reset(Ctx) _eet_free_reset(&Ctx->freelist_str);
1555 #define _eet_freelist_str_ref(Ctx) _eet_free_ref(&Ctx->freelist_str);
1556 #define _eet_freelist_str_unref(Ctx) _eet_free_unref(&Ctx->freelist_str);
1559 _eet_freelist_str_free(Eet_Free_Context *context, Eet_Data_Descriptor *edd)
1564 if (context->freelist_str.ref > 0) return;
1565 for (j = 0; j < 256; ++j)
1566 for (i = 0; i < context->freelist_str.num[j]; ++i)
1569 edd->func.str_free(context->freelist_str.list[j][i]);
1571 free(context->freelist_str.list[j][i]);
1573 _eet_free_reset(&context->freelist_str);
1576 #define _eet_freelist_direct_str_add(Ctx, Data) _eet_free_add(&Ctx->freelist_direct_str, Data);
1577 #define _eet_freelist_direct_str_reset(Ctx) _eet_free_reset(&Ctx->freelist_direct_str);
1578 #define _eet_freelist_direct_str_ref(Ctx) _eet_free_ref(&Ctx->freelist_direct_str);
1579 #define _eet_freelist_direct_str_unref(Ctx) _eet_free_unref(&Ctx->freelist_direct_str);
1582 _eet_freelist_direct_str_free(Eet_Free_Context *context, Eet_Data_Descriptor *edd)
1587 if (context->freelist_direct_str.ref > 0) return;
1588 for (j = 0; j < 256; ++j)
1589 for (i = 0; i < context->freelist_direct_str.num[j]; ++i)
1592 edd->func.str_direct_free(context->freelist_direct_str.list[j][i]);
1594 free(context->freelist_direct_str.list[j][i]);
1596 _eet_free_reset(&context->freelist_direct_str);
1599 #define _eet_freelist_hash_add(Ctx, Data) _eet_free_add(&Ctx->freelist_hash, Data);
1600 #define _eet_freelist_hash_reset(Ctx) _eet_free_reset(&Ctx->freelist_hash);
1601 #define _eet_freelist_hash_ref(Ctx) _eet_free_ref(&Ctx->freelist_hash);
1602 #define _eet_freelist_hash_unref(Ctx) _eet_free_unref(&Ctx->freelist_hash);
1605 _eet_freelist_hash_free(Eet_Free_Context *context, Eet_Data_Descriptor *edd)
1610 if (context->freelist_hash.ref > 0) return;
1611 for (j = 0; j < 256; ++j)
1612 for (i = 0; i < context->freelist_hash.num[j]; ++i)
1615 edd->func.hash_free(context->freelist_hash.list[j][i]);
1617 free(context->freelist_hash.list[j][i]);
1619 _eet_free_reset(&context->freelist_hash);
1623 _eet_freelist_all_ref(Eet_Free_Context *freelist_context)
1625 _eet_freelist_ref(freelist_context);
1626 _eet_freelist_str_ref(freelist_context);
1627 _eet_freelist_list_ref(freelist_context);
1628 _eet_freelist_hash_ref(freelist_context);
1629 _eet_freelist_direct_str_ref(freelist_context);
1633 _eet_freelist_all_unref(Eet_Free_Context *freelist_context)
1635 _eet_freelist_unref(freelist_context);
1636 _eet_freelist_str_unref(freelist_context);
1637 _eet_freelist_list_unref(freelist_context);
1638 _eet_freelist_hash_unref(freelist_context);
1639 _eet_freelist_direct_str_unref(freelist_context);
1643 eet_data_descriptor_encode_hash_cb(void *hash __UNUSED__, const char *key, void *hdata, void *fdata)
1646 Eet_Data_Encode_Hash_Info *edehi;
1647 Eet_Data_Stream *ds;
1648 Eet_Data_Element *ede;
1649 Eet_Data_Chunk *echnk;
1659 data = eet_data_put_type(ed,
1665 echnk = eet_data_chunk_new(data, size, ede->name, ede->type, ede->group_type);
1666 eet_data_chunk_put(ed, echnk, ds);
1667 eet_data_chunk_free(echnk);
1672 EET_ASSERT(!((ede->type > EET_T_UNKNOW) && (ede->type < EET_T_STRING)), return );
1675 if (ede->type >= EET_T_STRING)
1676 eet_data_put_unknown(ed, NULL, ede, ds, &hdata);
1680 data = _eet_data_descriptor_encode(ed,
1686 echnk = eet_data_chunk_new(data, size, ede->name, ede->type, ede->group_type);
1687 eet_data_chunk_put(ed, echnk, ds);
1688 eet_data_chunk_free(echnk);
1698 _eet_data_string_escape(const char *str)
1704 for (strp = str; *strp; strp++)
1706 if (*strp == '\"') sz += 2;
1707 else if (*strp == '\\') sz += 2;
1711 if (!s) return NULL;
1712 for (strp = str, sp = s; *strp; strp++, sp++)
1719 else if (*strp == '\\')
1731 _eet_data_dump_string_escape(void *dumpdata, void dumpfunc(void *data, const char *str), const char *str)
1735 s = _eet_data_string_escape(str);
1738 dumpfunc(dumpdata, s);
1744 _eet_data_dump_token_get(const char *src, int *len)
1750 int tlen = 0, tsize = 0;
1752 #define TOK_ADD(x) \
1755 if (tlen >= tsize) \
1758 tok = realloc(tok, tsize); \
1760 tok[tlen - 1] = x; \
1763 for (p = src; *len > 0; p++, (*len)--)
1769 if ((p[0] == '\"') && (p > src) && (p[-1] != '\\'))
1773 else if ((p[0] == '\\') && (*len > 1) && (p[1] == '\"'))
1777 else if ((p[0] == '\\') && (p > src) && (p[-1] == '\\'))
1786 if (p[0] == '\"') in_quote = 1;
1789 if ((isspace(p[0])) || (p[0] == ';')) /* token ends here */
1802 if (!((isspace(p[0])) || (p[0] == ';')))
1820 _eet_data_dump_encode(Eet_Dictionary *ed,
1824 Eet_Data_Chunk *chnk = NULL, *echnk = NULL;
1825 Eet_Data_Stream *ds;
1830 if (_eet_data_words_bigendian == -1)
1832 unsigned long int v;
1834 v = htonl(0x12345678);
1835 if (v == 0x12345678) _eet_data_words_bigendian = 1;
1836 else _eet_data_words_bigendian = 0;
1839 if (node == NULL) return NULL;
1841 ds = eet_data_stream_new();
1842 if (!ds) return NULL;
1847 for (n = node->values; n; n = n->next)
1849 data = _eet_data_dump_encode(ed, n, &size);
1852 eet_data_stream_write(ds, data, size);
1858 case EET_G_VAR_ARRAY:
1859 data = eet_data_put_type(ed,
1865 echnk = eet_data_chunk_new(data, size, node->name, node->type, node->type);
1866 eet_data_chunk_put(ed, echnk, ds);
1867 eet_data_chunk_free(echnk);
1870 for (n = node->values; n; n = n->next)
1872 data = _eet_data_dump_encode(ed, n, &size);
1875 echnk = eet_data_chunk_new(data, size, node->name, node->type, node->type);
1876 eet_data_chunk_put(ed, echnk, ds);
1877 eet_data_chunk_free(echnk);
1882 /* Array is somekind of special case, so we should embed it inside another chunk. */
1883 *size_ret = ds->pos;
1888 eet_data_stream_free(ds);
1892 for (n = node->values; n; n = n->next)
1894 data = _eet_data_dump_encode(ed, n, &size);
1897 eet_data_stream_write(ds, data, size);
1905 data = eet_data_put_type(ed,
1911 echnk = eet_data_chunk_new(data, size, node->name, node->type, node->type);
1912 eet_data_chunk_put(ed, echnk, ds);
1913 eet_data_chunk_free(echnk);
1917 for (n = node->values; n; n = n->next)
1919 data = _eet_data_dump_encode(ed, n, &size);
1922 echnk = eet_data_chunk_new(data, size, node->name, node->type, node->type);
1923 eet_data_chunk_put(ed, echnk, ds);
1924 eet_data_chunk_free(echnk);
1929 /* Hash is somekind of special case, so we should embed it inside another chunk. */
1930 *size_ret = ds->pos;
1935 eet_data_stream_free(ds);
1941 data = eet_data_put_type(ed, node->type, &(node->data.c), &size);
1944 eet_data_stream_write(ds, data, size);
1949 data = eet_data_put_type(ed, node->type, &(node->data.s), &size);
1952 eet_data_stream_write(ds, data, size);
1957 data = eet_data_put_type(ed, node->type, &(node->data.i), &size);
1960 eet_data_stream_write(ds, data, size);
1964 case EET_T_LONG_LONG:
1965 data = eet_data_put_type(ed, node->type, &(node->data.l), &size);
1968 eet_data_stream_write(ds, data, size);
1973 data = eet_data_put_type(ed, node->type, &(node->data.f), &size);
1976 eet_data_stream_write(ds, data, size);
1981 data = eet_data_put_type(ed, node->type, &(node->data.d), &size);
1984 eet_data_stream_write(ds, data, size);
1989 data = eet_data_put_type(ed, node->type, &(node->data.uc), &size);
1992 eet_data_stream_write(ds, data, size);
1997 data = eet_data_put_type(ed, node->type, &(node->data.us), &size);
2000 eet_data_stream_write(ds, data, size);
2005 data = eet_data_put_type(ed, node->type, &(node->data.ui), &size);
2008 eet_data_stream_write(ds, data, size);
2012 case EET_T_ULONG_LONG:
2013 data = eet_data_put_type(ed, node->type, &(node->data.ul), &size);
2016 eet_data_stream_write(ds, data, size);
2020 case EET_T_INLINED_STRING:
2021 data = eet_data_put_type(ed, node->type, &(node->data.str), &size);
2024 eet_data_stream_write(ds, data, size);
2029 data = eet_data_put_type(ed, node->type, &(node->data.str), &size);
2032 eet_data_stream_write(ds, data, size);
2040 if ((node->type >= EET_G_UNKNOWN) && (node->type < EET_G_LAST))
2041 chnk = eet_data_chunk_new(ds->data, ds->pos, node->name, EET_T_UNKNOW, node->type);
2043 chnk = eet_data_chunk_new(ds->data, ds->pos, node->name, node->type, EET_G_UNKNOWN);
2046 eet_data_stream_free(ds);
2048 ds = eet_data_stream_new();
2049 eet_data_chunk_put(ed, chnk, ds);
2055 eet_data_stream_free(ds);
2059 eet_data_chunk_free(chnk);
2065 _eet_data_dump_parse(Eet_Dictionary *ed,
2076 Eet_Node *node_base = NULL;
2077 Eet_Node *node = NULL;
2080 /* FIXME; handle parse errors */
2081 #define TOK_GET(t) \
2082 jump = left; t = _eet_data_dump_token_get(p, &left); p += jump - left;
2084 for (p = src; p < (src + size);)
2086 char *tok1, *tok2, *tok3, *tok4;
2091 if (!strcmp(tok1, "group"))
2102 if (!strcmp(tok4, "{"))
2104 /* we have 'group NAM TYP {' */
2105 n = calloc(1, sizeof(Eet_Node));
2120 for (nn = node->values; nn; nn = nn->next)
2130 n->name = eina_stringshare_add(tok2);
2131 if (!strcmp(tok3, "struct")) n->type = EET_G_UNKNOWN;
2132 else if (!strcmp(tok3, "array")) n->type = EET_G_ARRAY;
2133 else if (!strcmp(tok3, "var_array")) n->type = EET_G_VAR_ARRAY;
2134 else if (!strcmp(tok3, "list")) n->type = EET_G_LIST;
2135 else if (!strcmp(tok3, "hash")) n->type = EET_G_HASH;
2138 ERR("ERROR: group type '%s' invalid.", tok3);
2150 else if (!strcmp(tok1, "value"))
2161 /* we have 'value NAME TYP XXX' */
2164 n = calloc(1, sizeof(Eet_Node));
2173 for (nn = node->values; nn; nn = nn->next)
2182 n->name = eina_stringshare_add(tok2);
2183 if (!strcmp(tok3, "char:"))
2185 n->type = EET_T_CHAR;
2186 sscanf(tok4, "%hhi", &(n->data.c));
2188 else if (!strcmp(tok3, "short:"))
2190 n->type = EET_T_SHORT;
2191 sscanf(tok4, "%hi", &(n->data.s));
2193 else if (!strcmp(tok3, "int:"))
2195 n->type = EET_T_INT;
2196 sscanf(tok4, "%i", &(n->data.i));
2198 else if (!strcmp(tok3, "long_long:"))
2200 n->type = EET_T_LONG_LONG;
2201 sscanf(tok4, "%lli", &(n->data.l));
2203 else if (!strcmp(tok3, "float:"))
2205 n->type = EET_T_FLOAT;
2206 sscanf(tok4, "%f", &(n->data.f));
2208 else if (!strcmp(tok3, "double:"))
2210 n->type = EET_T_DOUBLE;
2211 sscanf(tok4, "%lf", &(n->data.d));
2213 else if (!strcmp(tok3, "uchar:"))
2215 n->type = EET_T_UCHAR;
2216 sscanf(tok4, "%hhu", &(n->data.uc));
2218 else if (!strcmp(tok3, "ushort:"))
2220 n->type = EET_T_USHORT;
2221 sscanf(tok4, "%hu", &(n->data.us));
2223 else if (!strcmp(tok3, "uint:"))
2225 n->type = EET_T_UINT;
2226 sscanf(tok4, "%u", &(n->data.ui));
2228 else if (!strcmp(tok3, "ulong_long:"))
2230 n->type = EET_T_ULONG_LONG;
2231 sscanf(tok4, "%llu", &(n->data.ul));
2233 else if (!strcmp(tok3, "string:"))
2235 n->type = EET_T_STRING;
2236 n->data.str = eina_stringshare_add(tok4);
2238 else if (!strcmp(tok3, "inlined:"))
2240 n->type = EET_T_INLINED_STRING;
2241 n->data.str = eina_stringshare_add(tok4);
2243 else if (!strcmp(tok3, "null"))
2245 n->type = EET_T_NULL;
2250 ERR("ERROR: value type '%s' invalid.", tok4);
2261 else if (!strcmp(tok1, "key"))
2266 /* we have 'key NAME' */
2269 node->key = eina_stringshare_add(tok2);
2274 else if (!strcmp(tok1, "count"))
2279 /* we have a 'count COUNT' */
2282 sscanf(tok2, "%i", &(node->count));
2287 else if (!strcmp(tok1, "}"))
2289 /* we have an end of the group */
2290 if (node) node = node->parent;
2298 cdata = _eet_data_dump_encode(ed, node_base, size_ret);
2299 eet_node_del(node_base);
2304 #define NEXT_CHUNK(P, Size, Echnk, Ed) \
2307 tmp = Ed ? (int) (sizeof(int) * 2) : Echnk.len + 4;\
2308 P += (4 + Echnk.size + tmp); \
2309 Size -= (4 + Echnk.size + tmp); \
2312 static const char *_dump_g_name[6] = {
2321 static const char *_dump_t_name[14][2] = {
2323 { "char: ", "%hhi" },
2324 { "short: ", "%hi" },
2326 { "long_long: ", "%lli" },
2327 { "float: ", "%1.25f" },
2328 { "double: ", "%1.25f" },
2329 { "uchar: ", "%hhu" },
2330 { "ushort: ", "%i" },
2332 { "ulong_long: ", "%llu" },
2337 _eet_data_descriptor_decode(Eet_Free_Context *context,
2338 const Eet_Dictionary *ed,
2339 Eet_Data_Descriptor *edd,
2340 const void *data_in,
2343 void (*dumpfunc) (void *data, const char *str),
2349 Eet_Data_Chunk chnk;
2351 if (_eet_data_words_bigendian == -1)
2353 unsigned long int v;
2355 v = htonl(0x12345678);
2356 if (v == 0x12345678) _eet_data_words_bigendian = 1;
2357 else _eet_data_words_bigendian = 0;
2362 data = edd->func.mem_alloc(edd->size);
2363 if (!data) return NULL;
2366 for (i = 0; i < edd->elements.num; i++)
2367 edd->elements.set[i].directory_name_ptr = NULL;
2371 _eet_freelist_all_ref(context);
2372 if (data) _eet_freelist_add(context, data);
2374 memset(&chnk, 0, sizeof(Eet_Data_Chunk));
2375 eet_data_chunk_get(ed, &chnk, data_in, size_in);
2376 if (!chnk.name) goto error;
2379 if (strcmp(chnk.name, edd->name)) goto error;
2383 size = size_in - (4 + sizeof(int) * 2);
2385 size = size_in - (4 + 4 + chnk.len);
2388 if (!edd->elements.hash.buckets) _eet_descriptor_hash_new(edd);
2393 if (chnk.type == EET_T_UNKNOW)
2394 eet_data_dump_group_start(level, dumpfunc, dumpdata, chnk.group_type, chnk.name);
2398 Eet_Data_Chunk echnk;
2399 Eet_Data_Element *ede = NULL;
2400 unsigned char dd[128];
2401 int group_type = EET_G_UNKNOWN, type = EET_T_UNKNOW;
2404 /* get next data chunk */
2405 memset(&echnk, 0, sizeof(Eet_Data_Chunk));
2406 eet_data_chunk_get(ed, &echnk, p, size);
2407 if (!echnk.name) goto error;
2408 /* FIXME: don't REPLY on edd - work without */
2409 if ((edd) && (!dumpfunc))
2411 ede = _eet_descriptor_hash_find(edd, echnk.name, echnk.hash);
2414 group_type = ede->group_type;
2416 if ((echnk.type == 0) && (echnk.group_type == 0))
2419 group_type = ede->group_type;
2423 if (IS_SIMPLE_TYPE(echnk.type) &&
2424 eet_data_type_match(echnk.type, ede->type))
2426 else if ((echnk.group_type > EET_G_UNKNOWN) &&
2427 (echnk.group_type < EET_G_LAST) &&
2428 (echnk.group_type == ede->group_type))
2429 group_type = echnk.group_type;
2433 /*...... dump func */
2436 if ((echnk.type > EET_T_UNKNOW) &&
2437 (echnk.type < EET_T_LAST))
2439 else if ((echnk.group_type > EET_G_UNKNOWN) &&
2440 (echnk.group_type < EET_G_LAST))
2441 group_type = echnk.group_type;
2444 if (dumpfunc && group_type == EET_G_UNKNOWN && IS_SIMPLE_TYPE(type))
2446 ret = eet_data_get_type(ed,
2449 ((char *)echnk.data) + echnk.size,
2451 if (ret <= 0) goto error;
2453 eet_data_dump_simple_type(type, echnk.name, dd, level, dumpfunc, dumpdata);
2457 ret = eet_group_codec[group_type - 100].get(context,
2458 ed, edd, ede, &echnk,
2459 type, group_type, ede ? (void*) (((char *)data) + ede->offset) : dd,
2460 level, dumpfunc, dumpdata,
2462 if (ret <= 0) goto error;
2464 /* advance to next chunk */
2465 NEXT_CHUNK(p, size, echnk, ed);
2468 _eet_freelist_all_unref(context);
2471 _eet_freelist_str_free(context, edd);
2472 _eet_freelist_direct_str_free(context, edd);
2473 _eet_freelist_list_free(context, edd);
2474 _eet_freelist_hash_free(context, edd);
2475 _eet_freelist_free(context, edd);
2479 _eet_freelist_reset(context);
2480 _eet_freelist_str_reset(context);
2481 _eet_freelist_list_reset(context);
2482 _eet_freelist_hash_reset(context);
2483 _eet_freelist_direct_str_reset(context);
2489 if (chnk.type == EET_T_UNKNOW)
2491 for (i = 0; i < level; i++) dumpfunc(dumpdata, " ");
2492 dumpfunc(dumpdata, "}\n");
2500 _eet_freelist_all_unref(context);
2501 _eet_freelist_str_free(context, edd);
2502 _eet_freelist_direct_str_free(context, edd);
2503 _eet_freelist_list_free(context, edd);
2504 _eet_freelist_hash_free(context, edd);
2505 _eet_freelist_free(context, edd);
2510 if (chnk.type == EET_T_UNKNOW)
2512 for (i = 0; i < level; i++) dumpfunc(dumpdata, " ");
2513 dumpfunc(dumpdata, "}\n");
2521 eet_data_dump_level(int level, void (*dumpfunc) (void *data, const char *str), void *dumpdata)
2525 for (i = 0; i < level; i++) dumpfunc(dumpdata, " ");
2529 eet_data_dump_group_start(int level, void (*dumpfunc) (void *data, const char *str), void *dumpdata,
2530 int group_type, const char *name)
2534 chnk_type = (group_type >= EET_G_UNKNOWN && group_type <= EET_G_HASH) ?
2535 group_type : EET_G_LAST;
2537 eet_data_dump_level(level, dumpfunc, dumpdata);
2538 dumpfunc(dumpdata, "group \"");
2539 _eet_data_dump_string_escape(dumpdata, dumpfunc, name);
2540 dumpfunc(dumpdata, "\" ");
2542 dumpfunc(dumpdata, _dump_g_name[chnk_type - EET_G_UNKNOWN]);
2543 dumpfunc(dumpdata, " {\n");
2547 eet_data_dump_group_end(int level, void (*dumpfunc) (void *data, const char *str), void *dumpdata)
2549 eet_data_dump_level(level, dumpfunc, dumpdata);
2550 dumpfunc(dumpdata, " }\n");
2554 eet_data_get_list(Eet_Free_Context *context, const Eet_Dictionary *ed, Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Chunk *echnk,
2555 int type, int group_type __UNUSED__, void *data,
2556 int level, void (*dumpfunc) (void *data, const char *str), void *dumpdata,
2557 char **p, int *size)
2559 Eet_Data_Descriptor *subtype = NULL;
2563 int et = EET_T_UNKNOW;
2565 EET_ASSERT(!((type > EET_T_UNKNOW) && (type < EET_T_STRING)), return 0);
2569 subtype = ede->subtype;
2574 eet_data_dump_group_start(level + 1, dumpfunc, dumpdata, echnk->group_type, echnk->name);
2577 ptr = (void **)data;
2581 if (et >= EET_T_STRING)
2585 ret = eet_data_get_unknown(context, ed, edd, ede, echnk, et, EET_G_UNKNOWN,
2586 &data_ret, level, dumpfunc, dumpdata, p, size);
2591 data_ret = _eet_data_descriptor_decode(context, ed, subtype,
2592 echnk->data, echnk->size,
2593 level + 2, dumpfunc, dumpdata);
2594 if (!data_ret) return 0;
2599 list = edd->func.list_append(list, data_ret);
2601 _eet_freelist_list_add(context, ptr);
2604 eet_data_dump_group_end(level, dumpfunc, dumpdata);
2610 eet_data_get_hash(Eet_Free_Context *context, const Eet_Dictionary *ed, Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Chunk *echnk,
2611 int type, int group_type __UNUSED__, void *data,
2612 int level, void (*dumpfunc) (void *data, const char *str), void *dumpdata,
2613 char **p, int *size)
2618 void *data_ret = NULL;
2621 EET_ASSERT(!((type > EET_T_UNKNOW) && (type < EET_T_STRING)), return 0);
2623 ptr = (void **)data;
2627 ret = eet_data_get_type(ed,
2630 ((char *)echnk->data) + echnk->size,
2632 if (ret <= 0) goto on_error;
2634 /* Advance to next chunk */
2635 NEXT_CHUNK((*p), (*size), (*echnk), ed);
2636 memset(echnk, 0, sizeof(Eet_Data_Chunk));
2639 eet_data_chunk_get(ed, echnk, *p, *size);
2640 if (!echnk->name) goto on_error;
2642 if (dumpfunc && key)
2644 eet_data_dump_group_start(level + 1, dumpfunc, dumpdata, echnk->group_type, echnk->name);
2646 eet_data_dump_level(level, dumpfunc, dumpdata);
2647 dumpfunc(dumpdata, " key \"");
2648 _eet_data_dump_string_escape(dumpdata, dumpfunc, key);
2649 dumpfunc(dumpdata, "\";\n");
2652 if (type >= EET_T_STRING)
2656 ret = eet_data_get_unknown(context, ed, edd, ede, echnk, ede ? ede->type : type, EET_G_UNKNOWN,
2657 &data_ret, level, dumpfunc, dumpdata, p, size);
2662 data_ret = _eet_data_descriptor_decode(context,
2664 ede ? ede->subtype : NULL,
2670 if (!data_ret) goto on_error;
2675 hash = edd->func.hash_add(hash, key, data_ret);
2677 _eet_freelist_hash_add(context, ptr);
2680 eet_data_dump_group_end(level, dumpfunc, dumpdata);
2688 /* var arrays and fixed arrays have to
2689 * get all chunks at once. for fixed arrays
2690 * we can get each chunk and increment a
2691 * counter stored on the element itself but
2692 * it wont be thread safe. for var arrays
2693 * we still need a way to get the number of
2694 * elements from the data, so storing the
2695 * number of elements and the element data on
2696 * each chunk is pointless.
2699 eet_data_get_array(Eet_Free_Context *context, const Eet_Dictionary *ed, Eet_Data_Descriptor *edd __UNUSED__,
2700 Eet_Data_Element *ede, Eet_Data_Chunk *echnk,
2701 int type, int group_type, void *data,
2702 int level, void (*dumpfunc) (void *data, const char *str), void *dumpdata,
2703 char **p, int *size)
2712 EET_ASSERT(!((type > EET_T_UNKNOW) && (type < EET_T_STRING)), return 0);
2715 /* read the number of elements */
2716 ret = eet_data_get_type(ed,
2719 ((char *)echnk->data) + echnk->size,
2721 if (ret <= 0) return ret;
2727 if (type >= EET_T_STRING)
2728 subsize = eet_basic_codec[ede->type].size;
2730 subsize = ede->subtype->size;
2732 if (group_type == EET_G_VAR_ARRAY)
2734 /* store the number of elements
2735 * on the counter offset */
2736 *(int *)(((char *)data) + ede->count - ede->offset) = count;
2737 /* allocate space for the array of elements */
2738 *(void **)ptr = edd->func.mem_alloc(count * subsize);
2740 if (!*(void **)ptr) return 0;
2742 memset(*(void **)ptr, 0, count * subsize);
2744 _eet_freelist_add(context, *(void **)ptr);
2751 eet_data_dump_group_start(level + 1, dumpfunc, dumpdata, echnk->group_type, echnk->name);
2753 eet_data_dump_level(level, dumpfunc, dumpdata);
2754 dumpfunc(dumpdata, " count ");
2755 eina_convert_itoa(count, tbuf);
2756 dumpfunc(dumpdata, tbuf);
2757 dumpfunc(dumpdata, ";\n");
2760 /* get all array elements */
2761 for (i = 0; i < count; i++)
2764 void *data_ret = NULL;
2766 /* Advance to next chunk */
2767 NEXT_CHUNK((*p), (*size), (*echnk), ed);
2768 memset(echnk, 0, sizeof(Eet_Data_Chunk));
2770 eet_data_chunk_get(ed, echnk, *p, *size);
2771 if (!echnk->name || strcmp(echnk->name, name) != 0) return 0;
2774 /* get the destination pointer */
2777 if (group_type == EET_G_ARRAY)
2778 dst = (char *)ptr + (subsize * i);
2780 dst = *(char **)ptr + (subsize * i);
2783 if (type >= EET_T_STRING)
2787 ret = eet_data_get_unknown(context, ed, edd, ede, echnk, ede ? ede->type : type, EET_G_UNKNOWN,
2788 &data_ret, level, dumpfunc, dumpdata, p, size);
2790 if (dst) memcpy(dst, &data_ret, subsize);
2794 data_ret = _eet_data_descriptor_decode(context, ed, ede ? ede->subtype : NULL,
2795 echnk->data, echnk->size,
2796 level + 2, dumpfunc, dumpdata);
2797 if (!data_ret) return 0;
2800 memcpy(dst, data_ret, subsize);
2801 _eet_freelist_add(context, data_ret);
2807 eet_data_dump_group_end(level, dumpfunc, dumpdata);
2813 eet_data_dump_simple_type(int type, const char *name, void *dd,
2814 int level, void (*dumpfunc) (void *data, const char *str), void *dumpdata)
2816 const char *type_name = NULL;
2819 eet_data_dump_level(level, dumpfunc, dumpdata);
2820 dumpfunc(dumpdata, " value \"");
2821 _eet_data_dump_string_escape(dumpdata, dumpfunc, name);
2822 dumpfunc(dumpdata, "\" ");
2828 #define EET_T_TYPE(Eet_Type, Type) \
2831 dumpfunc(dumpdata, _dump_t_name[Eet_Type][0]); \
2832 snprintf(tbuf, sizeof (tbuf), _dump_t_name[Eet_Type][1], *((Type *)dd)); \
2833 dumpfunc(dumpdata, tbuf); \
2839 EET_T_TYPE(EET_T_CHAR, char);
2840 EET_T_TYPE(EET_T_SHORT, short);
2841 EET_T_TYPE(EET_T_INT, int);
2842 EET_T_TYPE(EET_T_LONG_LONG, long long);
2843 EET_T_TYPE(EET_T_FLOAT, float);
2844 EET_T_TYPE(EET_T_DOUBLE, double);
2845 EET_T_TYPE(EET_T_UCHAR, unsigned char);
2846 EET_T_TYPE(EET_T_USHORT, unsigned short);
2847 EET_T_TYPE(EET_T_UINT, unsigned int);
2848 EET_T_TYPE(EET_T_ULONG_LONG, unsigned long long);
2849 case EET_T_INLINED_STRING:
2850 type_name = "inlined: \"";
2852 if (!type_name) type_name = "string: \"";
2860 dumpfunc(dumpdata, type_name);
2861 _eet_data_dump_string_escape(dumpdata, dumpfunc, s);
2862 dumpfunc(dumpdata, "\"");
2867 dumpfunc(dumpdata, "null");
2870 dumpfunc(dumpdata, "???: ???");
2873 dumpfunc(dumpdata, ";\n");
2877 eet_data_get_unknown(Eet_Free_Context *context, const Eet_Dictionary *ed, Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Chunk *echnk,
2878 int type, int group_type __UNUSED__, void *data,
2879 int level, void (*dumpfunc) (void *data, const char *str), void *dumpdata,
2880 char **p __UNUSED__, int *size __UNUSED__)
2885 if (IS_SIMPLE_TYPE(type))
2887 ret = eet_data_get_type(ed, type, echnk->data, ((char *)echnk->data) + echnk->size, ((char *)data));
2888 if (ret <= 0) return ret;
2890 if (!edd && dumpfunc)
2892 eet_data_dump_simple_type(type, echnk->name, data, level, dumpfunc, dumpdata);
2894 else if (edd && type == EET_T_STRING)
2898 str = (char **)(((char *)data));
2901 if ((ed == NULL) || (edd->func.str_direct_alloc == NULL))
2903 *str = edd->func.str_alloc(*str);
2904 _eet_freelist_str_add(context, *str);
2908 *str = edd->func.str_direct_alloc(*str);
2909 _eet_freelist_direct_str_add(context, *str);
2913 else if (edd && type == EET_T_INLINED_STRING)
2917 str = (char **)(((char *)data));
2920 *str = edd->func.str_alloc(*str);
2921 _eet_freelist_str_add(context, *str);
2927 Eet_Data_Descriptor *subtype;
2929 subtype = ede ? ede->subtype : NULL;
2931 if (subtype || dumpfunc)
2935 data_ret = _eet_data_descriptor_decode(context, ed, subtype, echnk->data, echnk->size, level + 1, dumpfunc, dumpdata);
2936 if (!data_ret) return 0;
2938 ptr = (void **)(((char *)data));
2939 *ptr = (void *)data_ret;
2947 eet_data_encode(Eet_Dictionary *ed, Eet_Data_Stream *ds, void *data, const char *name, int size, int type, int group_type)
2949 Eet_Data_Chunk *echnk;
2951 echnk = eet_data_chunk_new(data, size, name, type, group_type);
2952 eet_data_chunk_put(ed, echnk, ds);
2953 eet_data_chunk_free(echnk);
2954 if (data) free(data);
2958 eet_data_put_array(Eet_Dictionary *ed, Eet_Data_Descriptor *edd __UNUSED__, Eet_Data_Element *ede, Eet_Data_Stream *ds, void *data_in)
2967 EET_ASSERT(!((ede->type > EET_T_UNKNOW) && (ede->type < EET_T_STRING)), return );
2969 if (ede->group_type == EET_G_ARRAY)
2970 count = ede->counter_offset;
2972 count = *(int *)(((char *)data_in) + ede->count - ede->offset);
2974 if (count <= 0) return;
2975 /* Store number of elements */
2976 data = eet_data_put_type(ed, EET_T_INT, &count, &size);
2977 if (data) eet_data_encode(ed, ds, data, ede->name, size, ede->type, ede->group_type);
2979 if (ede->type >= EET_T_STRING)
2980 subsize = eet_basic_codec[ede->type].size;
2982 subsize = ede->subtype->size;
2984 for (j = 0; j < count; j++)
2989 if (ede->group_type == EET_G_ARRAY)
2990 d = (void *)(((char *)data_in) + offset);
2992 d = *(((char **)data_in)) + offset;
2994 if (ede->type >= EET_T_STRING)
2995 eet_data_put_unknown(ed, NULL, ede, ds, d);
2998 data = _eet_data_descriptor_encode(ed, ede->subtype, d, &size);
2999 if (data) eet_data_encode(ed, ds, data, ede->name, size, ede->type, ede->group_type);
3004 /* Add a NULL element just to have the correct array layout. */
3005 eet_data_encode(ed, ds, NULL, ede->name, 0, EET_T_NULL, ede->group_type);
3013 eet_data_put_unknown(Eet_Dictionary *ed, Eet_Data_Descriptor *edd __UNUSED__, Eet_Data_Element *ede, Eet_Data_Stream *ds, void *data_in)
3018 if (IS_SIMPLE_TYPE(ede->type))
3019 data = eet_data_put_type(ed, ede->type, data_in, &size);
3020 else if (ede->subtype)
3022 if (*((char **)data_in))
3023 data = _eet_data_descriptor_encode(ed,
3025 *((char **)((char *)(data_in))),
3028 if (data) eet_data_encode(ed, ds, data, ede->name, size, ede->type, ede->group_type);
3032 eet_data_put_list(Eet_Dictionary *ed, Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Stream *ds, void *data_in)
3038 EET_ASSERT(!((ede->type > EET_T_UNKNOW) && (ede->type < EET_T_STRING)), return );
3040 l = *((void **)(((char *)data_in)));
3041 for (; l; l = edd->func.list_next(l))
3043 if (ede->type >= EET_T_STRING)
3045 const char *str = edd->func.list_data(l);
3046 eet_data_put_unknown(ed, NULL, ede, ds, &str);
3050 data = _eet_data_descriptor_encode(ed,
3052 edd->func.list_data(l),
3054 if (data) eet_data_encode(ed, ds, data, ede->name, size, ede->type, ede->group_type);
3060 eet_data_put_hash(Eet_Dictionary *ed, Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Stream *ds, void *data_in)
3062 Eet_Data_Encode_Hash_Info fdata;
3065 l = *((void **)(((char *)data_in)));
3069 edd->func.hash_foreach(l, eet_data_descriptor_encode_hash_cb, &fdata);
3073 eet_data_dump_cipher(Eet_File *ef,
3074 const char *name, const char *key,
3075 void (*dumpfunc) (void *data, const char *str),
3078 const Eet_Dictionary *ed = NULL;
3079 const void *data = NULL;
3080 Eet_Free_Context context;
3082 int required_free = 0;
3085 ed = eet_dictionary_get(ef);
3088 data = eet_read_direct(ef, name, &size);
3092 data = eet_read_cipher(ef, name, &size, key);
3093 if (!data) return 0;
3096 memset(&context, 0, sizeof (context));
3097 if (_eet_data_descriptor_decode(&context, ed, NULL, data, size, 0,
3098 dumpfunc, dumpdata))
3108 eet_data_dump(Eet_File *ef,
3110 void (*dumpfunc) (void *data, const char *str),
3113 return eet_data_dump_cipher(ef, name, NULL, dumpfunc, dumpdata);
3118 eet_data_text_dump_cipher(const void *data_in,
3119 const char *key, int size_in,
3120 void (*dumpfunc) (void *data, const char *str),
3124 Eet_Free_Context context;
3125 unsigned int ret_len = 0;
3129 if (eet_decipher(data_in, size_in, key, strlen(key), &ret, &ret_len))
3134 memset(&context, 0, sizeof (context));
3135 if (_eet_data_descriptor_decode(&context, NULL, NULL, ret, ret_len, 0,
3136 dumpfunc, dumpdata))
3144 memset(&context, 0, sizeof (context));
3145 if (_eet_data_descriptor_decode(&context, NULL, NULL, data_in, size_in, 0,
3146 dumpfunc, dumpdata))
3152 eet_data_text_dump(const void *data_in,
3154 void (*dumpfunc) (void *data, const char *str),
3157 return eet_data_text_dump_cipher(data_in, NULL, size_in, dumpfunc, dumpdata);
3161 eet_data_text_undump_cipher(const char *text,
3168 ret = _eet_data_dump_parse(NULL, size_ret, text, textlen);
3171 void *ciphered = NULL;
3172 unsigned int ciphered_len;
3174 if (eet_cipher(ret, *size_ret, key, strlen(key), &ciphered, &ciphered_len))
3176 if (ciphered) free(ciphered);
3182 *size_ret = ciphered_len;
3189 eet_data_text_undump(const char *text,
3193 return eet_data_text_undump_cipher(text, NULL, textlen, size_ret);
3197 eet_data_undump_cipher(Eet_File *ef,
3209 ed = eet_dictionary_get(ef);
3211 data_enc = _eet_data_dump_parse(ed, &size, text, textlen);
3212 if (!data_enc) return 0;
3213 val = eet_write_cipher(ef, name, data_enc, size, compress, key);
3219 eet_data_undump(Eet_File *ef,
3225 return eet_data_undump_cipher(ef, name, NULL, text, textlen, compress);
3229 eet_data_descriptor_decode_cipher(Eet_Data_Descriptor *edd,
3230 const void *data_in,
3234 void *deciphered = NULL;
3236 Eet_Free_Context context;
3237 unsigned int deciphered_len = 0;
3241 if (eet_decipher(data_in, size_in, key, strlen(key), &deciphered, &deciphered_len))
3243 if (deciphered) free(deciphered);
3246 memset(&context, 0, sizeof (context));
3247 ret = _eet_data_descriptor_decode(&context, NULL, edd, deciphered, deciphered_len, 0,
3252 memset(&context, 0, sizeof (context));
3253 return _eet_data_descriptor_decode(&context, NULL, edd, data_in, size_in, 0,
3258 eet_data_descriptor_decode(Eet_Data_Descriptor *edd,
3259 const void *data_in,
3262 return eet_data_descriptor_decode_cipher(edd, data_in, NULL, size_in);
3266 _eet_data_descriptor_encode(Eet_Dictionary *ed,
3267 Eet_Data_Descriptor *edd,
3268 const void *data_in,
3271 Eet_Data_Stream *ds;
3272 Eet_Data_Chunk *chnk;
3277 if (_eet_data_words_bigendian == -1)
3279 unsigned long int v;
3281 v = htonl(0x12345678);
3282 if (v == 0x12345678) _eet_data_words_bigendian = 1;
3283 else _eet_data_words_bigendian = 0;
3286 ds = eet_data_stream_new();
3287 for (i = 0; i < edd->elements.num; i++)
3289 Eet_Data_Element *ede;
3291 ede = &(edd->elements.set[i]);
3292 eet_group_codec[ede->group_type - 100].put(ed, edd, ede, ds, ((char *)data_in) + ede->offset);
3294 chnk = eet_data_chunk_new(ds->data, ds->pos, edd->name, EET_T_UNKNOW, EET_G_UNKNOWN);
3297 eet_data_stream_free(ds);
3299 ds = eet_data_stream_new();
3300 eet_data_chunk_put(ed, chnk, ds);
3306 eet_data_stream_free(ds);
3310 eet_data_chunk_free(chnk);
3316 eet_data_node_write_cipher(Eet_File *ef, const char *name, const char *key, Eet_Node *node, int compress)
3323 ed = eet_dictionary_get(ef);
3325 data_enc = _eet_data_dump_encode(ed, node, &size);
3326 if (!data_enc) return 0;
3327 val = eet_write_cipher(ef, name, data_enc, size, compress, key);
3333 eet_data_node_encode_cipher(Eet_Node *node,
3338 void *ciphered = NULL;
3339 unsigned int ciphered_len = 0;
3342 ret = _eet_data_dump_encode(NULL, node, &size);
3345 if (eet_cipher(ret, size, key, strlen(key), &ciphered, &ciphered_len))
3347 if (ciphered) free(ciphered);
3348 if (size_ret) *size_ret = 0;
3353 size = (int) ciphered_len;
3357 if (size_ret) *size_ret = size;
3362 eet_data_descriptor_encode_cipher(Eet_Data_Descriptor *edd,
3363 const void *data_in,
3368 void *ciphered = NULL;
3369 unsigned int ciphered_len = 0;
3372 ret = _eet_data_descriptor_encode(NULL, edd, data_in, &size);
3375 if (eet_cipher(ret, size, key, strlen(key), &ciphered, &ciphered_len))
3377 if (ciphered) free(ciphered);
3378 if (size_ret) *size_ret = 0;
3383 size = ciphered_len;
3387 if (size_ret) *size_ret = size;
3392 eet_data_descriptor_encode(Eet_Data_Descriptor *edd,
3393 const void *data_in,
3396 return eet_data_descriptor_encode_cipher(edd, data_in, NULL, size_ret);