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, 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 Eet_Node *eet_data_node_simple_type(int type, const char *name, void *dd);
229 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);
230 static void eet_data_put_unknown(Eet_Dictionary *ed, Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Stream *ds, void *data_in);
231 static void eet_data_put_array(Eet_Dictionary *ed, Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Stream *ds, void *data_in);
232 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);
233 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);
234 static void eet_data_put_list(Eet_Dictionary *ed, Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Stream *ds, void *data_in);
235 static void eet_data_put_hash(Eet_Dictionary *ed, Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Stream *ds, void *data_in);
236 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);
238 static void eet_data_chunk_get(const Eet_Dictionary *ed, Eet_Data_Chunk *chnk, const void *src, int size);
239 static Eet_Data_Chunk *eet_data_chunk_new(void *data, int size, const char *name, int type, int group_type);
240 static void eet_data_chunk_free(Eet_Data_Chunk *chnk);
242 static Eet_Data_Stream *eet_data_stream_new(void);
243 static void eet_data_stream_write(Eet_Data_Stream *ds, const void *data, int size);
244 static void eet_data_stream_free(Eet_Data_Stream *ds);
246 static void eet_data_chunk_put(Eet_Dictionary *ed, Eet_Data_Chunk *chnk, Eet_Data_Stream *ds);
248 static int eet_data_descriptor_encode_hash_cb(void *hash, const char *key, void *hdata, void *fdata);
249 static void *_eet_data_descriptor_encode(Eet_Dictionary *ed, Eet_Data_Descriptor *edd, const void *data_in, int *size_ret);
250 static void *_eet_data_descriptor_decode(Eet_Free_Context *context,
251 const Eet_Dictionary *ed,
252 Eet_Data_Descriptor *edd,
258 static const Eet_Data_Basic_Type_Codec eet_basic_codec[] =
260 {sizeof(char), "char", eet_data_get_char, eet_data_put_char },
261 {sizeof(short), "short", eet_data_get_short, eet_data_put_short },
262 {sizeof(int), "int", eet_data_get_int, eet_data_put_int },
263 {sizeof(long long), "long_long", eet_data_get_long_long, eet_data_put_long_long},
264 {sizeof(float), "float", eet_data_get_float, eet_data_put_float },
265 {sizeof(double), "double", eet_data_get_double, eet_data_put_double },
266 {sizeof(char), "uchar", eet_data_get_char, eet_data_put_char },
267 {sizeof(short), "ushort", eet_data_get_short, eet_data_put_short },
268 {sizeof(int), "uint", eet_data_get_int, eet_data_put_int },
269 {sizeof(long long), "ulong_long", eet_data_get_long_long, eet_data_put_long_long},
270 {sizeof(char *), "string", eet_data_get_string, eet_data_put_string },
271 {sizeof(char *), "inlined", eet_data_get_istring, eet_data_put_istring },
272 {sizeof(void *), "NULL", eet_data_get_null, eet_data_put_null },
273 {sizeof(Eina_F32p32),"f32p32", eet_data_get_f32p32, eet_data_put_f32p32 },
274 {sizeof(Eina_F16p16),"f16p16", eet_data_get_f16p16, eet_data_put_f16p16 },
275 {sizeof(Eina_F8p24),"f8p24", eet_data_get_f8p24, eet_data_put_f8p24 }
278 static const Eet_Data_Group_Type_Codec eet_group_codec[] =
280 { eet_data_get_unknown, eet_data_put_unknown },
281 { eet_data_get_array, eet_data_put_array },
282 { eet_data_get_array, eet_data_put_array },
283 { eet_data_get_list, eet_data_put_list },
284 { eet_data_get_hash, eet_data_put_hash }
287 static int _eet_data_words_bigendian = -1;
291 #define SWAP64(x) (x) = \
292 ((((unsigned long long)(x) & 0x00000000000000ffULL ) << 56) |\
293 (((unsigned long long)(x) & 0x000000000000ff00ULL ) << 40) |\
294 (((unsigned long long)(x) & 0x0000000000ff0000ULL ) << 24) |\
295 (((unsigned long long)(x) & 0x00000000ff000000ULL ) << 8) |\
296 (((unsigned long long)(x) & 0x000000ff00000000ULL ) >> 8) |\
297 (((unsigned long long)(x) & 0x0000ff0000000000ULL ) >> 24) |\
298 (((unsigned long long)(x) & 0x00ff000000000000ULL ) >> 40) |\
299 (((unsigned long long)(x) & 0xff00000000000000ULL ) >> 56))
300 #define SWAP32(x) (x) = \
301 ((((int)(x) & 0x000000ff ) << 24) |\
302 (((int)(x) & 0x0000ff00 ) << 8) |\
303 (((int)(x) & 0x00ff0000 ) >> 8) |\
304 (((int)(x) & 0xff000000 ) >> 24))
305 #define SWAP16(x) (x) = \
306 ((((short)(x) & 0x00ff ) << 8) |\
307 (((short)(x) & 0xff00 ) >> 8))
323 #define CONV16(x) {if (_eet_data_words_bigendian) SWAP16(x);}
324 #define CONV32(x) {if (_eet_data_words_bigendian) SWAP32(x);}
325 #define CONV64(x) {if (_eet_data_words_bigendian) SWAP64(x);}
327 #define IS_SIMPLE_TYPE(Type) (Type > EET_T_UNKNOW && Type < EET_T_LAST)
328 #define IS_POINTER_TYPE(Type) (Type >= EET_T_STRING && Type <= EET_T_NULL)
330 #define EET_I_STRING 1 << 4
331 #define EET_I_INLINED_STRING 2 << 4
332 #define EET_I_NULL 3 << 4
338 eet_data_get_char(const Eet_Dictionary *ed __UNUSED__, const void *src, const void *src_end, void *dst)
342 if (((char *)src + sizeof(char)) > (char *)src_end) return -1;
351 eet_data_put_char(Eet_Dictionary *ed __UNUSED__, const void *src, int *size_ret)
355 d = (char *)malloc(sizeof(char));
360 *size_ret = sizeof(char);
366 eet_data_get_short(const Eet_Dictionary *ed __UNUSED__, const void *src, const void *src_end, void *dst)
370 if (((char *)src + sizeof(short)) > (char *)src_end) return -1;
371 memcpy(dst, src, sizeof(short));
374 return sizeof(short);
378 eet_data_put_short(Eet_Dictionary *ed __UNUSED__, const void *src, int *size_ret)
382 d = (short *)malloc(sizeof(short));
387 *size_ret = sizeof(short);
393 eet_data_get_int(const Eet_Dictionary *ed __UNUSED__, const void *src, const void *src_end, void *dst)
397 if (((char *)src + sizeof(int)) > (char *)src_end) return -1;
398 memcpy(dst, src, sizeof(int));
405 eet_data_put_int(Eet_Dictionary *ed __UNUSED__, const void *src, int *size_ret)
409 d = (int *)malloc(sizeof(int));
414 *size_ret = sizeof(int);
420 eet_data_get_long_long(const Eet_Dictionary *ed __UNUSED__, const void *src, const void *src_end, void *dst)
422 unsigned long long *d;
424 if (((char *)src + sizeof(unsigned long long)) > (char *)src_end) return -1;
425 memcpy(dst, src, sizeof(unsigned long long));
426 d = (unsigned long long *)dst;
428 return sizeof(unsigned long long);
432 eet_data_put_long_long(Eet_Dictionary *ed __UNUSED__, const void *src, int *size_ret)
434 unsigned long long *s, *d;
436 d = (unsigned long long *)malloc(sizeof(unsigned long long));
438 s = (unsigned long long *)src;
441 *size_ret = sizeof(unsigned long long);
447 eet_data_get_string_hash(const Eet_Dictionary *ed, const void *src, const void *src_end)
453 if (eet_data_get_int(ed, src, src_end, &idx) < 0) return -1;
455 return eet_dictionary_string_get_hash(ed, idx);
462 eet_data_get_string(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dst)
473 if (eet_data_get_int(ed, src, src_end, &idx) < 0) return -1;
475 str = eet_dictionary_string_get_char(ed, idx);
480 return eet_dictionary_string_get_size(ed, idx);
491 return strlen(s) + 1;
495 eet_data_put_string(Eet_Dictionary *ed, const void *src, int *size_ret)
505 str = *((const char **) src);
506 if (!str) return NULL;
508 idx = eet_dictionary_string_add(ed, str);
509 if (idx == -1) return NULL;
511 return eet_data_put_int(ed, &idx, size_ret);
514 s = (char *)(*((char **)src));
519 memcpy(d, s, len + 1);
524 /* ALWAYS INLINED STRING TYPE */
526 eet_data_get_istring(const Eet_Dictionary *ed __UNUSED__, const void *src, const void *src_end, void *dst)
528 return eet_data_get_string(NULL, src, src_end, dst);
532 eet_data_put_istring(Eet_Dictionary *ed __UNUSED__, const void *src, int *size_ret)
534 return eet_data_put_string(NULL, src, size_ret);
537 /* ALWAYS NULL TYPE */
539 eet_data_get_null(const Eet_Dictionary *ed __UNUSED__, const void *src __UNUSED__, const void *src_end __UNUSED__, void *dst)
550 eet_data_put_null(Eet_Dictionary *ed __UNUSED__, const void *src __UNUSED__, int *size_ret)
557 * Fast lookups of simple doubles/floats.
559 * These aren't properly a cache because they don't store pre-calculated
560 * values, but have a so simple math that is almost as fast.
563 _eet_data_float_cache_get(const char *s, int len, float *d)
565 /* fast handle of simple case 0xMp+E*/
566 if ((len == 6) && (s[0] == '0') && (s[1] == 'x') && (s[3] == 'p'))
568 int mantisse = (s[2] >= 'a') ? (s[2] - 'a' + 10) : (s[2] - '0');
569 int exponent = (s[5] - '0');
571 if (s[4] == '+') *d = (float)(mantisse << exponent);
572 else *d = (float)mantisse / (float)(1 << exponent);
580 _eet_data_double_cache_get(const char *s, int len, double *d)
582 /* fast handle of simple case 0xMp+E*/
583 if ((len == 6) && (s[0] == '0') && (s[1] == 'x') && (s[3] == 'p'))
585 int mantisse = (s[2] >= 'a') ? (s[2] - 'a' + 10) : (s[2] - '0');
586 int exponent = (s[5] - '0');
588 if (s[4] == '+') *d = (double)(mantisse << exponent);
589 else *d = (double)mantisse / (double)(1 << exponent);
598 eet_data_get_float(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dst)
611 s = (const char *)src;
614 while ((p < (const char *)src_end) && (*p != 0)) {len++; p++;}
616 if (_eet_data_float_cache_get(s, len, d) != 0) return len + 1;
618 if (eina_convert_atod(s, len, &mantisse, &exponent) == EINA_FALSE) return -1;
619 *d = (float)ldexp((double)mantisse, exponent);
624 if (eet_data_get_int(ed, src, src_end, &idx) < 0) return -1;
626 if (!eet_dictionary_string_get_float(ed, idx, d))
632 eet_data_put_float(Eet_Dictionary *ed, const void *src, int *size_ret)
637 eina_convert_dtoa((double)(*(float *)src), buf);
647 memcpy(d, buf, len + 1);
652 idx = eet_dictionary_string_add(ed, buf);
653 if (idx == -1) return NULL;
655 return eet_data_put_int(ed, &idx, size_ret);
660 eet_data_get_double(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dst)
670 long long mantisse = 0;
674 s = (const char *) src;
677 while ((p < (const char *)src_end) && (*p != 0)) {len++; p++;}
679 if (_eet_data_double_cache_get(s, len, d) != 0) return len + 1;
681 if (eina_convert_atod(s, len, &mantisse, &exponent) == EINA_FALSE) return -1;
682 *d = ldexp((double) mantisse, exponent);
687 if (eet_data_get_int(ed, src, src_end, &idx) < 0) return -1;
689 if (!eet_dictionary_string_get_double(ed, idx, d))
695 eet_data_put_double(Eet_Dictionary *ed, const void *src, int *size_ret)
700 eina_convert_dtoa((double)(*(double *)src), buf);
710 memcpy(d, buf, len + 1);
716 idx = eet_dictionary_string_add(ed, buf);
717 if (idx == -1) return NULL;
719 return eet_data_put_int(ed, &idx, size_ret);
723 eet_data_get_f32p32(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dst)
728 fp = (Eina_F32p32*) dst;
732 if (eet_data_get_int(ed, src, src_end, &idx) < 0) return -1;
734 if (!eet_dictionary_string_get_fp(ed, idx, fp))
740 eet_data_put_f32p32(Eet_Dictionary *ed, const void *src, int *size_ret)
745 if (!ed) return NULL;
747 eina_convert_fptoa((Eina_F32p32)(*(Eina_F32p32 *)src), buf);
749 idx = eet_dictionary_string_add(ed, buf);
750 if (idx == -1) return NULL;
752 return eet_data_put_int(ed, &idx, size_ret);
756 eet_data_get_f16p16(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dst)
761 fp = (Eina_F16p16*) dst;
763 if (eet_data_get_f32p32(ed, src, src_end, &tmp) < 0) return -1;
765 *fp = eina_f32p32_to_f16p16(tmp);
770 eet_data_put_f16p16(Eet_Dictionary *ed, const void *src, int *size_ret)
774 tmp = eina_f16p16_to_f32p32((Eina_F16p16)(*(Eina_F16p16 *)src));
775 return eet_data_put_f32p32(ed, &tmp, size_ret);
779 eet_data_get_f8p24(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dst)
784 fp = (Eina_F8p24*) dst;
786 if (eet_data_get_f32p32(ed, src, src_end, &tmp) < 0) return -1;
788 *fp = eina_f32p32_to_f8p24(tmp);
793 eet_data_put_f8p24(Eet_Dictionary *ed, const void *src, int *size_ret)
797 tmp = eina_f8p24_to_f32p32((Eina_F8p24)(*(Eina_F8p24 *)src));
798 return eet_data_put_f32p32(ed, &tmp, size_ret);
802 eet_data_get_type(const Eet_Dictionary *ed, int type, const void *src, const void *src_end, void *dest)
806 ret = eet_basic_codec[type - 1].get(ed, src, src_end, dest);
811 eet_data_put_type(Eet_Dictionary *ed, int type, const void *src, int *size_ret)
815 ret = eet_basic_codec[type - 1].put(ed, src, size_ret);
819 static inline Eina_Bool
820 eet_data_type_match(int type1, int type2)
822 if (type1 == type2) return EINA_TRUE;
824 /* Note: All floating point type are equivalent and could be read
825 without problem by any other floating point getter. */
854 * char[4] = "CHnK"; // untyped data ... or
855 * char[4] = "CHKx"; // typed data - x == type
857 * int = chunk size (including magic string);
858 * char[] = chunk magic/name string (0 byte terminated);
859 * ... sub-chunks (a chunk can contain chuncks recusrively) ...
861 * ... payload data ...
866 eet_data_chunk_get(const Eet_Dictionary *ed, Eet_Data_Chunk *chnk,
867 const void *src, int size)
873 if (size <= 8) return;
879 if ((s[0] != 'C') || (s[1] != 'H') || (s[2] != 'K'))
882 chnk->type = (unsigned char)(s[3]);
883 if (chnk->type >= EET_I_LIMIT)
885 chnk->group_type = ((chnk->type - EET_I_LIMIT) & 0xF) + EET_G_UNKNOWN;
886 switch ((chnk->type - EET_I_LIMIT) & 0xF0)
888 #define EET_UNMATCH_TYPE(Type) \
889 case EET_I_##Type: chnk->type = EET_T_##Type; break;
891 EET_UNMATCH_TYPE(STRING);
892 EET_UNMATCH_TYPE(INLINED_STRING);
893 EET_UNMATCH_TYPE(NULL);
898 else if (chnk->type > EET_T_LAST)
900 chnk->group_type = chnk->type;
901 chnk->type = EET_T_UNKNOW;
904 chnk->group_type = EET_G_UNKNOWN;
905 if ((chnk->type >= EET_T_LAST) ||
906 (chnk->group_type >= EET_G_LAST))
909 chnk->group_type = 0;
914 if ((s[0] != 'C') || (s[1] != 'H') || (s[2] != 'n') || (s[3] != 'K'))
917 ret1 = eet_data_get_type(ed, EET_T_INT, (s + 4), (s + size), &(chnk->size));
919 if (ret1 <= 0) return;
920 if ((chnk->size < 0) || ((chnk->size + 8) > size)) return;
921 ret2 = eet_data_get_type(ed, EET_T_STRING, (s + 8), (s + size), &(chnk->name));
923 if (ret2 <= 0) return;
928 chnk->hash = eet_data_get_string_hash(ed, (s + 8), (s + size));
932 chnk->data = (char *)src + 4 + ret1 + sizeof(int);
933 chnk->size -= sizeof(int);
937 chnk->data = (char *)src + 4 + ret1 + chnk->len;
938 chnk->size -= chnk->len;
944 static inline Eet_Data_Chunk *
945 eet_data_chunk_new(void *data, int size, const char *name, int type, int group_type)
947 Eet_Data_Chunk *chnk;
949 if (!name) return NULL;
950 chnk = calloc(1, sizeof(Eet_Data_Chunk));
951 if (!chnk) return NULL;
953 /* Note: Another security, so older eet library could read file
954 saved with fixed point value. */
955 if (type == EET_T_F32P32
956 || type == EET_T_F16P16
957 || type == EET_T_F8P24)
960 chnk->name = strdup(name);
961 chnk->len = strlen(name) + 1;
965 chnk->group_type = group_type;
970 eet_data_chunk_free(Eet_Data_Chunk *chnk)
972 if (chnk->name) free(chnk->name);
976 static inline Eet_Data_Stream *
977 eet_data_stream_new(void)
981 ds = calloc(1, sizeof(Eet_Data_Stream));
982 if (!ds) return NULL;
987 eet_data_stream_free(Eet_Data_Stream *ds)
989 if (ds->data) free(ds->data);
994 eet_data_stream_flush(Eet_Data_Stream *ds)
1000 eet_data_stream_write(Eet_Data_Stream *ds, const void *data, int size)
1004 if ((ds->pos + size) > ds->size)
1006 ds->data = realloc(ds->data, ds->size + size + 512);
1013 ds->size = ds->size + size + 512;
1016 memcpy(p + ds->pos, data, size);
1021 eet_data_chunk_put(Eet_Dictionary *ed, Eet_Data_Chunk *chnk, Eet_Data_Stream *ds)
1028 unsigned char buf[4] = "CHK";
1030 /* disable this check - it will allow empty chunks to be written. this is
1031 * right for corner-cases when y have a struct with empty fields (empty
1032 * strings or empty list ptrs etc.) */
1033 /* if (!chnk->data && chnk->type != EET_T_NULL) return; */
1036 /* eet_data_stream_write(ds, "CHnK", 4);*/
1037 if (chnk->type != EET_T_UNKNOW)
1039 if (chnk->group_type != EET_G_UNKNOWN)
1041 int type = EET_I_LIMIT + chnk->group_type - EET_G_UNKNOWN;
1045 /* Only make sense with pointer type. */
1046 #define EET_MATCH_TYPE(Type) \
1047 case EET_T_##Type: type += EET_I_##Type; break;
1049 EET_MATCH_TYPE(STRING);
1050 EET_MATCH_TYPE(INLINED_STRING);
1051 EET_MATCH_TYPE(NULL);
1059 buf[3] = chnk->type;
1061 else buf[3] = chnk->group_type;
1063 string = eet_data_put_string(ed, &chnk->name, &string_ret);
1067 /* size of chunk payload data + name */
1068 s = chnk->size + string_ret;
1069 size = eet_data_put_int(ed, &s, &size_ret);
1071 /* FIXME: If something goes wrong the resulting file will be corrupted. */
1075 eet_data_stream_write(ds, buf, 4);
1077 /* write chunk length */
1078 eet_data_stream_write(ds, size, size_ret);
1080 /* write chunk name */
1081 eet_data_stream_write(ds, string, string_ret);
1085 eet_data_stream_write(ds, chnk->data, chnk->size);
1095 _eet_descriptor_hash_new(Eet_Data_Descriptor *edd)
1099 edd->elements.hash.size = 1 << 6;
1100 edd->elements.hash.buckets = calloc(1, sizeof(Eet_Data_Descriptor_Hash) * edd->elements.hash.size);
1101 for (i = 0; i < edd->elements.num; i++)
1103 Eet_Data_Element *ede;
1106 ede = &(edd->elements.set[i]);
1107 hash = _eet_hash_gen((char *) ede->name, 6);
1108 if (!edd->elements.hash.buckets[hash].element)
1109 edd->elements.hash.buckets[hash].element = ede;
1112 Eet_Data_Descriptor_Hash *bucket;
1114 bucket = calloc(1, sizeof(Eet_Data_Descriptor_Hash));
1115 bucket->element = ede;
1116 bucket->next = edd->elements.hash.buckets[hash].next;
1117 edd->elements.hash.buckets[hash].next = bucket;
1123 _eet_descriptor_hash_free(Eet_Data_Descriptor *edd)
1127 for (i = 0; i < edd->elements.hash.size; i++)
1129 Eet_Data_Descriptor_Hash *bucket, *pbucket;
1131 bucket = edd->elements.hash.buckets[i].next;
1135 bucket = bucket->next;
1139 if (edd->elements.hash.buckets) free(edd->elements.hash.buckets);
1142 static Eet_Data_Element *
1143 _eet_descriptor_hash_find(Eet_Data_Descriptor *edd, char *name, int hash)
1145 Eet_Data_Descriptor_Hash *bucket;
1147 if (hash < 0) hash = _eet_hash_gen(name, 6);
1149 if (!edd->elements.hash.buckets[hash].element) return NULL;
1151 When we use the dictionnary as a source for chunk name, we will always
1152 have the same pointer in name. It's a good idea to just compare pointer
1153 instead of running strcmp on both string.
1155 if (edd->elements.hash.buckets[hash].element->directory_name_ptr == name)
1156 return edd->elements.hash.buckets[hash].element;
1157 if (!strcmp(edd->elements.hash.buckets[hash].element->name, name))
1159 edd->elements.hash.buckets[hash].element->directory_name_ptr = name;
1160 return edd->elements.hash.buckets[hash].element;
1162 bucket = edd->elements.hash.buckets[hash].next;
1165 if (bucket->element->directory_name_ptr == name) return bucket->element;
1166 if (!strcmp(bucket->element->name, name))
1168 bucket->element->directory_name_ptr = name;
1169 return bucket->element;
1171 bucket = bucket->next;
1177 _eet_mem_alloc(size_t size)
1179 return calloc(1, size);
1183 _eet_mem_free(void *mem)
1189 _eet_str_alloc(const char *str)
1195 _eet_str_free(const char *str)
1201 _eet_eina_hash_add_alloc(Eina_Hash *hash, const char *key, void *data)
1203 if (!hash) hash = eina_hash_string_small_new(NULL);
1204 if (!hash) return NULL;
1206 eina_hash_add(hash, key, data);
1211 _eet_str_direct_alloc(const char *str)
1217 _eet_str_direct_free(const char *str)
1222 _eet_eina_hash_foreach(void *hash, Eina_Hash_Foreach cb, void *fdata)
1224 if (hash) eina_hash_foreach(hash, cb, fdata);
1228 _eet_eina_hash_free(void *hash)
1230 if (hash) eina_hash_free(hash);
1235 eet_eina_stream_data_descriptor_class_set(Eet_Data_Descriptor_Class *eddc, const char *name, int size)
1237 if (!eddc || !name) return EINA_FALSE;
1243 eddc->func.mem_alloc = _eet_mem_alloc;
1244 eddc->func.mem_free = _eet_mem_free;
1245 eddc->func.str_alloc = (char *(*)(const char *))eina_stringshare_add;
1246 eddc->func.str_free = eina_stringshare_del;
1247 eddc->func.list_next = (void *(*)(void *))eina_list_next;
1248 eddc->func.list_append = (void *(*)(void *, void *))eina_list_append;
1249 eddc->func.list_data = (void *(*)(void *))eina_list_data_get;
1250 eddc->func.list_free = (void *(*)(void *))eina_list_free;
1251 eddc->func.hash_foreach = (void (*)(void *, int (*)(void *, const char *, void *, void *), void *))_eet_eina_hash_foreach;
1252 eddc->func.hash_add = (void* (*)(void *, const char *, void *)) _eet_eina_hash_add_alloc;
1253 eddc->func.hash_free = (void (*)(void *))_eet_eina_hash_free;
1259 eet_eina_file_data_descriptor_class_set(Eet_Data_Descriptor_Class *eddc, const char *name, int size)
1261 if (!eet_eina_stream_data_descriptor_class_set(eddc, name, size))
1266 eddc->func.str_direct_alloc = _eet_str_direct_alloc;
1267 eddc->func.str_direct_free = _eet_str_direct_free;
1272 static Eet_Data_Descriptor *
1273 _eet_data_descriptor_new(const Eet_Data_Descriptor_Class *eddc, int version)
1275 Eet_Data_Descriptor *edd;
1277 if (!eddc) return NULL;
1278 if (eddc->version < version) return NULL;
1280 edd = calloc(1, sizeof (Eet_Data_Descriptor));
1281 if (!edd) return NULL;
1283 edd->name = eddc->name;
1285 edd->size = eddc->size;
1286 edd->func.mem_alloc = _eet_mem_alloc;
1287 edd->func.mem_free = _eet_mem_free;
1288 edd->func.str_alloc = _eet_str_alloc;
1289 edd->func.str_free = _eet_str_free;
1290 if (eddc->func.mem_alloc)
1291 edd->func.mem_alloc = eddc->func.mem_alloc;
1292 if (eddc->func.mem_free)
1293 edd->func.mem_free = eddc->func.mem_free;
1294 if (eddc->func.str_alloc)
1295 edd->func.str_alloc = eddc->func.str_alloc;
1296 if (eddc->func.str_free)
1297 edd->func.str_free = eddc->func.str_free;
1298 edd->func.list_next = eddc->func.list_next;
1299 edd->func.list_append = eddc->func.list_append;
1300 edd->func.list_data = eddc->func.list_data;
1301 edd->func.list_free = eddc->func.list_free;
1302 edd->func.hash_foreach = eddc->func.hash_foreach;
1303 edd->func.hash_add = eddc->func.hash_add;
1304 edd->func.hash_free = eddc->func.hash_free;
1308 edd->func.str_direct_alloc = eddc->func.str_direct_alloc;
1309 edd->func.str_direct_free = eddc->func.str_direct_free;
1315 EAPI Eet_Data_Descriptor *
1316 eet_data_descriptor_new(const char *name,
1318 void *(*func_list_next) (void *l),
1319 void *(*func_list_append) (void *l, void *d),
1320 void *(*func_list_data) (void *l),
1321 void *(*func_list_free) (void *l),
1322 void (*func_hash_foreach) (void *h, int (*func) (void *h, const char *k, void *dt, void *fdt), void *fdt),
1323 void *(*func_hash_add) (void *h, const char *k, void *d),
1324 void (*func_hash_free) (void *h))
1326 Eet_Data_Descriptor_Class eddc;
1328 if (!name) return NULL;
1330 memset(&eddc, 0, sizeof (Eet_Data_Descriptor_Class));
1336 eddc.func.list_next = func_list_next;
1337 eddc.func.list_append = func_list_append;
1338 eddc.func.list_data = func_list_data;
1339 eddc.func.list_free = func_list_free;
1340 eddc.func.hash_foreach = func_hash_foreach;
1341 eddc.func.hash_add = func_hash_add;
1342 eddc.func.hash_free = func_hash_free;
1344 return _eet_data_descriptor_new(&eddc, 0);
1347 EAPI Eet_Data_Descriptor *
1348 eet_data_descriptor2_new(const Eet_Data_Descriptor_Class *eddc)
1350 return _eet_data_descriptor_new(eddc, 1);
1353 EAPI Eet_Data_Descriptor *
1354 eet_data_descriptor3_new(const Eet_Data_Descriptor_Class *eddc)
1356 return _eet_data_descriptor_new(eddc, 2);
1359 EAPI Eet_Data_Descriptor *
1360 eet_data_descriptor_stream_new(const Eet_Data_Descriptor_Class *eddc)
1362 return _eet_data_descriptor_new(eddc, 1);
1365 EAPI Eet_Data_Descriptor *
1366 eet_data_descriptor_file_new(const Eet_Data_Descriptor_Class *eddc)
1368 return _eet_data_descriptor_new(eddc, 2);
1372 eet_data_descriptor_free(Eet_Data_Descriptor *edd)
1375 _eet_descriptor_hash_free(edd);
1376 if (edd->elements.set) free(edd->elements.set);
1381 eet_data_descriptor_element_add(Eet_Data_Descriptor *edd,
1387 /* int counter_offset, */
1388 const char *counter_name /* FIXME: Useless should go on a major release */,
1389 Eet_Data_Descriptor *subtype)
1391 Eet_Data_Element *ede;
1392 Eet_Data_Element *tmp;
1394 edd->elements.num++;
1395 tmp = realloc(edd->elements.set, edd->elements.num * sizeof(Eet_Data_Element));
1397 edd->elements.set = tmp;
1398 ede = &(edd->elements.set[edd->elements.num - 1]);
1400 ede->directory_name_ptr = NULL;
1403 * We do a special case when we do list,hash or whatever group of simple type.
1404 * Instead of handling it in encode/decode/dump/undump, we create an
1405 * implicit structure with only the simple type.
1407 if (group_type > EET_G_UNKNOWN
1408 && group_type < EET_G_LAST
1409 && ((type > EET_T_UNKNOW && type < EET_T_STRING)
1410 || (type > EET_T_NULL && type < EET_T_LAST))
1413 subtype = calloc(1, sizeof (Eet_Data_Descriptor));
1414 if (!subtype) return ;
1415 subtype->name = "implicit";
1416 subtype->size = eet_basic_codec[type - 1].size;
1417 memcpy(&subtype->func, &edd->func, sizeof(subtype->func));
1419 eet_data_descriptor_element_add(subtype, eet_basic_codec[type - 1].name, type,
1420 EET_G_UNKNOWN, 0, 0, /* 0, */NULL, NULL);
1421 type = EET_T_UNKNOW;
1425 ede->group_type = group_type;
1426 ede->offset = offset;
1428 /* FIXME: For the time being, EET_G_VAR_ARRAY will put the counter_offset in count. */
1429 ede->counter_offset = count;
1430 /* ede->counter_offset = counter_offset; */
1431 ede->counter_name = counter_name;
1433 ede->subtype = subtype;
1437 eet_data_read_cipher(Eet_File *ef, Eet_Data_Descriptor *edd, const char *name, const char *key)
1439 const Eet_Dictionary *ed = NULL;
1440 const void *data = NULL;
1442 Eet_Free_Context context;
1443 int required_free = 0;
1446 ed = eet_dictionary_get(ef);
1449 data = eet_read_direct(ef, name, &size);
1453 data = eet_read_cipher(ef, name, &size, key);
1454 if (!data) return NULL;
1457 memset(&context, 0, sizeof (context));
1458 data_dec = _eet_data_descriptor_decode(&context, ed, edd, data, size);
1466 eet_data_node_read_cipher(Eet_File *ef, const char *name, const char *key)
1468 const Eet_Dictionary *ed = NULL;
1469 const void *data = NULL;
1471 Eet_Free_Context context;
1472 int required_free = 0;
1475 ed = eet_dictionary_get(ef);
1478 data = eet_read_direct(ef, name, &size);
1482 data = eet_read_cipher(ef, name, &size, key);
1483 if (!data) return NULL;
1486 memset(&context, 0, sizeof (context));
1487 result = _eet_data_descriptor_decode(&context, ed, NULL, data, size);
1495 eet_data_read(Eet_File *ef, Eet_Data_Descriptor *edd, const char *name)
1497 return eet_data_read_cipher(ef, edd, name, NULL);
1501 eet_data_write_cipher(Eet_File *ef, Eet_Data_Descriptor *edd, const char *name, const char *key, const void *data, int compress)
1508 ed = eet_dictionary_get(ef);
1510 data_enc = _eet_data_descriptor_encode(ed, edd, data, &size);
1511 if (!data_enc) return 0;
1512 val = eet_write_cipher(ef, name, data_enc, size, compress, key);
1518 eet_data_write(Eet_File *ef, Eet_Data_Descriptor *edd, const char *name, const void *data, int compress)
1520 return eet_data_write_cipher(ef, edd, name, NULL, data, compress);
1524 _eet_free_hash(void *data)
1526 unsigned long ptr = (unsigned long)(data);
1545 _eet_free_add(Eet_Free *ef, void *data)
1550 hash = _eet_free_hash(data);
1552 for (i = 0; i < ef->num[hash]; ++i)
1553 if (ef->list[hash][i] == data) return;
1556 if (ef->num[hash] > ef->len[hash])
1560 tmp = realloc(ef->list[hash], (ef->len[hash] + 16) * sizeof(void*));
1563 ef->len[hash] += 16;
1564 ef->list[hash] = tmp;
1566 ef->list[hash][ef->num[hash] - 1] = data;
1569 _eet_free_reset(Eet_Free *ef)
1573 if (ef->ref > 0) return ;
1574 for (i = 0; i < 256; ++i)
1578 if (ef->list[i]) free(ef->list[i]);
1583 _eet_free_ref(Eet_Free *ef)
1588 _eet_free_unref(Eet_Free *ef)
1593 #define _eet_freelist_add(Ctx, Data) _eet_free_add(&Ctx->freelist, Data);
1594 #define _eet_freelist_reset(Ctx) _eet_free_reset(&Ctx->freelist);
1595 #define _eet_freelist_ref(Ctx) _eet_free_ref(&Ctx->freelist);
1596 #define _eet_freelist_unref(Ctx) _eet_free_unref(&Ctx->freelist);
1599 _eet_freelist_free(Eet_Free_Context *context, Eet_Data_Descriptor *edd)
1604 if (context->freelist.ref > 0) return;
1605 for (j = 0; j < 256; ++j)
1606 for (i = 0; i < context->freelist.num[j]; ++i)
1609 edd->func.mem_free(context->freelist.list[j][i]);
1611 free(context->freelist.list[j][i]);
1613 _eet_free_reset(&context->freelist);
1616 #define _eet_freelist_list_add(Ctx, Data) _eet_free_add(&Ctx->freelist_list, Data);
1617 #define _eet_freelist_list_reset(Ctx) _eet_free_reset(&Ctx->freelist_list);
1618 #define _eet_freelist_list_ref(Ctx) _eet_free_ref(&Ctx->freelist_list);
1619 #define _eet_freelist_list_unref(Ctx) _eet_free_unref(&Ctx->freelist_list);
1622 _eet_freelist_list_free(Eet_Free_Context *context, Eet_Data_Descriptor *edd)
1627 if (context->freelist_list.ref > 0) return;
1628 for (j = 0; j < 256; ++j)
1629 for (i = 0; i < context->freelist_list.num[j]; ++i)
1632 edd->func.list_free(*((void**)(context->freelist_list.list[j][i])));
1634 _eet_free_reset(&context->freelist_list);
1637 #define _eet_freelist_str_add(Ctx, Data) _eet_free_add(&Ctx->freelist_str, Data);
1638 #define _eet_freelist_str_reset(Ctx) _eet_free_reset(&Ctx->freelist_str);
1639 #define _eet_freelist_str_ref(Ctx) _eet_free_ref(&Ctx->freelist_str);
1640 #define _eet_freelist_str_unref(Ctx) _eet_free_unref(&Ctx->freelist_str);
1643 _eet_freelist_str_free(Eet_Free_Context *context, Eet_Data_Descriptor *edd)
1648 if (context->freelist_str.ref > 0) return;
1649 for (j = 0; j < 256; ++j)
1650 for (i = 0; i < context->freelist_str.num[j]; ++i)
1653 edd->func.str_free(context->freelist_str.list[j][i]);
1655 free(context->freelist_str.list[j][i]);
1657 _eet_free_reset(&context->freelist_str);
1660 #define _eet_freelist_direct_str_add(Ctx, Data) _eet_free_add(&Ctx->freelist_direct_str, Data);
1661 #define _eet_freelist_direct_str_reset(Ctx) _eet_free_reset(&Ctx->freelist_direct_str);
1662 #define _eet_freelist_direct_str_ref(Ctx) _eet_free_ref(&Ctx->freelist_direct_str);
1663 #define _eet_freelist_direct_str_unref(Ctx) _eet_free_unref(&Ctx->freelist_direct_str);
1666 _eet_freelist_direct_str_free(Eet_Free_Context *context, Eet_Data_Descriptor *edd)
1671 if (context->freelist_direct_str.ref > 0) return;
1672 for (j = 0; j < 256; ++j)
1673 for (i = 0; i < context->freelist_direct_str.num[j]; ++i)
1676 edd->func.str_direct_free(context->freelist_direct_str.list[j][i]);
1678 free(context->freelist_direct_str.list[j][i]);
1680 _eet_free_reset(&context->freelist_direct_str);
1683 #define _eet_freelist_hash_add(Ctx, Data) _eet_free_add(&Ctx->freelist_hash, Data);
1684 #define _eet_freelist_hash_reset(Ctx) _eet_free_reset(&Ctx->freelist_hash);
1685 #define _eet_freelist_hash_ref(Ctx) _eet_free_ref(&Ctx->freelist_hash);
1686 #define _eet_freelist_hash_unref(Ctx) _eet_free_unref(&Ctx->freelist_hash);
1689 _eet_freelist_hash_free(Eet_Free_Context *context, Eet_Data_Descriptor *edd)
1694 if (context->freelist_hash.ref > 0) return;
1695 for (j = 0; j < 256; ++j)
1696 for (i = 0; i < context->freelist_hash.num[j]; ++i)
1699 edd->func.hash_free(context->freelist_hash.list[j][i]);
1701 free(context->freelist_hash.list[j][i]);
1703 _eet_free_reset(&context->freelist_hash);
1707 _eet_freelist_all_ref(Eet_Free_Context *freelist_context)
1709 _eet_freelist_ref(freelist_context);
1710 _eet_freelist_str_ref(freelist_context);
1711 _eet_freelist_list_ref(freelist_context);
1712 _eet_freelist_hash_ref(freelist_context);
1713 _eet_freelist_direct_str_ref(freelist_context);
1717 _eet_freelist_all_unref(Eet_Free_Context *freelist_context)
1719 _eet_freelist_unref(freelist_context);
1720 _eet_freelist_str_unref(freelist_context);
1721 _eet_freelist_list_unref(freelist_context);
1722 _eet_freelist_hash_unref(freelist_context);
1723 _eet_freelist_direct_str_unref(freelist_context);
1727 eet_data_descriptor_encode_hash_cb(void *hash __UNUSED__, const char *key, void *hdata, void *fdata)
1730 Eet_Data_Encode_Hash_Info *edehi;
1731 Eet_Data_Stream *ds;
1732 Eet_Data_Element *ede;
1733 Eet_Data_Chunk *echnk;
1743 data = eet_data_put_type(ed,
1749 echnk = eet_data_chunk_new(data, size, ede->name, ede->type, ede->group_type);
1750 eet_data_chunk_put(ed, echnk, ds);
1751 eet_data_chunk_free(echnk);
1756 EET_ASSERT(!((ede->type > EET_T_UNKNOW) && (ede->type < EET_T_STRING)), return );
1759 if (ede->type >= EET_T_STRING)
1760 eet_data_put_unknown(ed, NULL, ede, ds, &hdata);
1764 data = _eet_data_descriptor_encode(ed,
1770 echnk = eet_data_chunk_new(data, size, ede->name, ede->type, ede->group_type);
1771 eet_data_chunk_put(ed, echnk, ds);
1772 eet_data_chunk_free(echnk);
1782 _eet_data_dump_token_get(const char *src, int *len)
1788 int tlen = 0, tsize = 0;
1790 #define TOK_ADD(x) \
1793 if (tlen >= tsize) \
1796 tok = realloc(tok, tsize); \
1798 tok[tlen - 1] = x; \
1801 for (p = src; *len > 0; p++, (*len)--)
1807 if ((p[0] == '\"') && (p > src) && (p[-1] != '\\'))
1811 else if ((p[0] == '\\') && (*len > 1) && (p[1] == '\"'))
1815 else if ((p[0] == '\\') && (p > src) && (p[-1] == '\\'))
1819 else if ((p[0] == '\\') && (*len > 1) && (p[1] == 'n'))
1823 else if ((p[0] == 'n') && (p > src) && (p[-1] == '\\'))
1832 if (p[0] == '\"') in_quote = 1;
1835 if ((isspace(p[0])) || (p[0] == ';')) /* token ends here */
1848 if (!((isspace(p[0])) || (p[0] == ';')))
1866 eet_data_encode(Eet_Dictionary *ed, Eet_Data_Stream *ds, void *data, const char *name, int size, int type, int group_type)
1868 Eet_Data_Chunk *echnk;
1870 if (!data) type = EET_T_NULL;
1872 if (group_type != EET_G_UNKNOWN)
1873 if (type >= EET_T_LAST)
1874 type = EET_T_UNKNOW;
1876 echnk = eet_data_chunk_new(data, size, name, type, group_type);
1877 eet_data_chunk_put(ed, echnk, ds);
1878 eet_data_chunk_free(echnk);
1883 _eet_data_dump_encode(int parent_type,
1888 Eet_Data_Chunk *chnk = NULL;
1889 Eet_Data_Stream *ds;
1896 if (_eet_data_words_bigendian == -1)
1898 unsigned long int v;
1900 v = htonl(0x12345678);
1901 if (v == 0x12345678) _eet_data_words_bigendian = 1;
1902 else _eet_data_words_bigendian = 0;
1905 if (node == NULL) return NULL;
1907 ds = eet_data_stream_new();
1908 if (!ds) return NULL;
1913 for (n = node->values; n; n = n->next)
1915 data = _eet_data_dump_encode(node->type, ed, n, &size);
1918 eet_data_stream_write(ds, data, size);
1924 case EET_G_VAR_ARRAY:
1925 for (child_type = EET_T_NULL, n = node->values; n; n = n->next)
1927 if (n->type != EET_T_NULL)
1929 child_type = n->type;
1934 data = eet_data_put_type(ed,
1938 eet_data_encode(ed, ds, data, node->name, size, child_type, node->type);
1940 count = node->count;
1942 for (n = node->values; n; n = n->next)
1949 case EET_T_INLINED_STRING:
1950 data = eet_data_put_type(ed, n->type, &(n->data.value.str), &size);
1951 if (data) eet_data_encode(ed, ds, data, node->name, size, n->type, node->type);
1956 data = _eet_data_dump_encode(n->type, ed, n, &size);
1957 eet_data_encode(ed, ds, data, node->name, size, n->type, node->type);
1960 if (ds->pos != pos) count--;
1963 for (; count; count--)
1965 eet_data_encode(ed, ds, NULL, node->name, 0, EET_T_NULL, node->type);
1968 /* Array is somekind of special case, so we should embed it inside another chunk. */
1969 *size_ret = ds->pos;
1974 eet_data_stream_free(ds);
1979 for (n = node->values; n; n = n->next)
1984 case EET_T_INLINED_STRING:
1985 data = eet_data_put_type(ed, n->type, &(n->data.value.str), &size);
1986 if (data) eet_data_encode(ed, ds, data, node->name, size, n->type, node->type);
1991 data = _eet_data_dump_encode(node->type, ed, n, &size);
1992 eet_data_encode(ed, ds, data, node->name, size, n->type, node->type);
1996 /* List is another somekind of special case, every chunk is embed inside a list chunk. */
1997 *size_ret = ds->pos;
2002 eet_data_stream_free(ds);
2009 data = eet_data_put_type(ed,
2013 eet_data_encode(ed, ds, data, node->name, size, node->type, node->type);
2016 /* A Hash without key will not decode correctly. */
2019 for (n = node->values; n; n = n->next)
2024 case EET_T_INLINED_STRING:
2025 data = eet_data_put_type(ed, n->type, &(n->data.value.str), &size);
2026 if (data) eet_data_encode(ed, ds, data, node->name, size, n->type, node->type);
2031 data = _eet_data_dump_encode(node->type, ed, n, &size);
2032 eet_data_encode(ed, ds, data, node->name, size, n->type, node->type);
2036 /* Hash is somekind of special case, so we should embed it inside another chunk. */
2037 *size_ret = ds->pos;
2040 eet_data_stream_flush(ds);
2046 #define EET_DATA_NODE_ENCODE(Eet_Type, Type) \
2048 data = eet_data_put_type(ed, node->type, &(node->data.value.Type), &size); \
2051 eet_data_encode(ed, ds, data, node->name, size, node->type, parent_type); \
2053 *size_ret = ds->pos; \
2054 eet_data_stream_flush(ds); \
2059 EET_DATA_NODE_ENCODE(EET_T_CHAR, c);
2060 EET_DATA_NODE_ENCODE(EET_T_SHORT, s);
2061 EET_DATA_NODE_ENCODE(EET_T_INT, i);
2062 EET_DATA_NODE_ENCODE(EET_T_LONG_LONG, l);
2063 EET_DATA_NODE_ENCODE(EET_T_FLOAT, f);
2064 EET_DATA_NODE_ENCODE(EET_T_DOUBLE, d);
2065 EET_DATA_NODE_ENCODE(EET_T_UCHAR, uc);
2066 EET_DATA_NODE_ENCODE(EET_T_USHORT, us);
2067 EET_DATA_NODE_ENCODE(EET_T_UINT, ui);
2068 EET_DATA_NODE_ENCODE(EET_T_ULONG_LONG, ul);
2069 EET_DATA_NODE_ENCODE(EET_T_INLINED_STRING, str);
2070 EET_DATA_NODE_ENCODE(EET_T_STRING, str);
2075 if ((node->type >= EET_G_UNKNOWN) && (node->type < EET_G_LAST))
2076 chnk = eet_data_chunk_new(ds->data, ds->pos, node->name, EET_T_UNKNOW, node->type);
2078 chnk = eet_data_chunk_new(ds->data, ds->pos, node->name, node->type, EET_G_UNKNOWN);
2079 eet_data_stream_flush(ds);
2081 ds = eet_data_stream_new();
2082 eet_data_chunk_put(ed, chnk, ds);
2086 eet_data_stream_flush(ds);
2090 eet_data_chunk_free(chnk);
2096 _eet_data_dump_parse(Eet_Dictionary *ed,
2102 const char *p = NULL;
2107 Eet_Node *node_base = NULL;
2108 Eet_Node *node = NULL;
2109 Eet_Node *n = NULL, *nn = NULL;
2111 /* FIXME; handle parse errors */
2112 #define TOK_GET(t) \
2113 jump = left; t = _eet_data_dump_token_get(p, &left); p += jump - left;
2115 for (p = src; p < (src + size);)
2117 char *tok1, *tok2, *tok3, *tok4;
2122 if (!strcmp(tok1, "group"))
2133 if (!strcmp(tok4, "{"))
2135 /* we have 'group NAM TYP {' */
2151 for (nn = node->values; nn; nn = nn->next)
2161 n->name = eina_stringshare_add(tok2);
2162 if (!strcmp(tok3, "struct")) n->type = EET_G_UNKNOWN;
2163 else if (!strcmp(tok3, "array")) n->type = EET_G_ARRAY;
2164 else if (!strcmp(tok3, "var_array")) n->type = EET_G_VAR_ARRAY;
2165 else if (!strcmp(tok3, "list")) n->type = EET_G_LIST;
2166 else if (!strcmp(tok3, "hash")) n->type = EET_G_HASH;
2169 ERR("ERROR: group type '%s' invalid.", tok3);
2181 else if (!strcmp(tok1, "value"))
2192 /* we have 'value NAME TYP XXX' */
2204 for (nn = node->values; nn; nn = nn->next)
2213 n->name = eina_stringshare_add(tok2);
2214 if (!strcmp(tok3, "char:"))
2216 n->type = EET_T_CHAR;
2217 sscanf(tok4, "%hhi", &(n->data.value.c));
2219 else if (!strcmp(tok3, "short:"))
2221 n->type = EET_T_SHORT;
2222 sscanf(tok4, "%hi", &(n->data.value.s));
2224 else if (!strcmp(tok3, "int:"))
2226 n->type = EET_T_INT;
2227 sscanf(tok4, "%i", &(n->data.value.i));
2229 else if (!strcmp(tok3, "long_long:"))
2231 n->type = EET_T_LONG_LONG;
2232 sscanf(tok4, "%lli", &(n->data.value.l));
2234 else if (!strcmp(tok3, "float:"))
2236 n->type = EET_T_FLOAT;
2237 sscanf(tok4, "%f", &(n->data.value.f));
2239 else if (!strcmp(tok3, "double:"))
2241 n->type = EET_T_DOUBLE;
2242 sscanf(tok4, "%lf", &(n->data.value.d));
2244 else if (!strcmp(tok3, "uchar:"))
2246 n->type = EET_T_UCHAR;
2247 sscanf(tok4, "%hhu", &(n->data.value.uc));
2249 else if (!strcmp(tok3, "ushort:"))
2251 n->type = EET_T_USHORT;
2252 sscanf(tok4, "%hu", &(n->data.value.us));
2254 else if (!strcmp(tok3, "uint:"))
2256 n->type = EET_T_UINT;
2257 sscanf(tok4, "%u", &(n->data.value.ui));
2259 else if (!strcmp(tok3, "ulong_long:"))
2261 n->type = EET_T_ULONG_LONG;
2262 sscanf(tok4, "%llu", &(n->data.value.ul));
2264 else if (!strcmp(tok3, "string:"))
2266 n->type = EET_T_STRING;
2267 n->data.value.str = eina_stringshare_add(tok4);
2269 else if (!strcmp(tok3, "inlined:"))
2271 n->type = EET_T_INLINED_STRING;
2272 n->data.value.str = eina_stringshare_add(tok4);
2274 else if (!strcmp(tok3, "null"))
2276 n->type = EET_T_NULL;
2277 n->data.value.str = NULL;
2281 ERR("ERROR: value type '%s' invalid.", tok4);
2292 else if (!strcmp(tok1, "key"))
2297 /* we have 'key NAME' */
2300 node->key = eina_stringshare_add(tok2);
2305 else if (!strcmp(tok1, "count"))
2310 /* we have a 'count COUNT' */
2313 sscanf(tok2, "%i", &(node->count));
2318 else if (!strcmp(tok1, "}"))
2320 /* we have an end of the group */
2321 if (node) node = node->parent;
2329 cdata = _eet_data_dump_encode(EET_G_UNKNOWN, ed, node_base, size_ret);
2330 eet_node_del(node_base);
2335 #define NEXT_CHUNK(P, Size, Echnk, Ed) \
2338 tmp = Ed ? (int) (sizeof(int) * 2) : Echnk.len + 4;\
2339 P += (4 + Echnk.size + tmp); \
2340 Size -= (4 + Echnk.size + tmp); \
2344 _eet_data_descriptor_decode(Eet_Free_Context *context,
2345 const Eet_Dictionary *ed,
2346 Eet_Data_Descriptor *edd,
2347 const void *data_in,
2350 Eet_Node *result = NULL;
2354 Eet_Data_Chunk chnk;
2356 if (_eet_data_words_bigendian == -1)
2358 unsigned long int v;
2360 v = htonl(0x12345678);
2361 if (v == 0x12345678) _eet_data_words_bigendian = 1;
2362 else _eet_data_words_bigendian = 0;
2367 data = edd->func.mem_alloc(edd->size);
2368 if (!data) return NULL;
2371 for (i = 0; i < edd->elements.num; i++)
2372 edd->elements.set[i].directory_name_ptr = NULL;
2376 _eet_freelist_all_ref(context);
2377 if (data) _eet_freelist_add(context, data);
2378 memset(&chnk, 0, sizeof(Eet_Data_Chunk));
2379 eet_data_chunk_get(ed, &chnk, data_in, size_in);
2380 if (!chnk.name) goto error;
2383 if (strcmp(chnk.name, edd->name)) goto error;
2387 size = size_in - (4 + sizeof(int) * 2);
2389 size = size_in - (4 + 4 + chnk.len);
2392 if (!edd->elements.hash.buckets) _eet_descriptor_hash_new(edd);
2396 switch (chnk.group_type)
2402 return eet_node_string_new(chnk.name, chnk.data);
2403 case EET_T_INLINED_STRING:
2404 return eet_node_inlined_string_new(chnk.name, chnk.data);
2406 return eet_node_null_new(chnk.name);
2408 result = eet_node_struct_new(chnk.name, NULL);
2411 case EET_G_VAR_ARRAY:
2412 return eet_node_var_array_new(chnk.name, NULL);
2425 Eet_Data_Chunk echnk;
2426 Eet_Data_Element *ede = NULL;
2427 Eet_Node *child = NULL;
2428 int group_type = EET_G_UNKNOWN, type = EET_T_UNKNOW;
2431 /* get next data chunk */
2432 memset(&echnk, 0, sizeof(Eet_Data_Chunk));
2433 eet_data_chunk_get(ed, &echnk, p, size);
2434 if (!echnk.name) goto error;
2435 /* FIXME: don't REPLY on edd - work without */
2438 ede = _eet_descriptor_hash_find(edd, echnk.name, echnk.hash);
2441 group_type = ede->group_type;
2443 if ((echnk.type == 0) && (echnk.group_type == 0))
2446 group_type = ede->group_type;
2450 if (IS_SIMPLE_TYPE(echnk.type) &&
2451 eet_data_type_match(echnk.type, ede->type))
2452 /* Needed when converting on the fly from FP to Float */
2454 else if ((echnk.group_type > EET_G_UNKNOWN) &&
2455 (echnk.group_type < EET_G_LAST) &&
2456 (echnk.group_type == ede->group_type))
2457 group_type = echnk.group_type;
2461 /*...... dump to node */
2465 group_type = echnk.group_type;
2468 if (!edd && group_type == EET_G_UNKNOWN && IS_SIMPLE_TYPE(type))
2470 unsigned char dd[128];
2472 ret = eet_data_get_type(ed,
2475 ((char *)echnk.data) + echnk.size,
2477 if (ret <= 0) goto error;
2479 child = eet_data_node_simple_type(type, echnk.name, dd);
2481 eet_node_struct_append(result, echnk.name, child);
2485 ret = eet_group_codec[group_type - 100].get(context,
2486 ed, edd, ede, &echnk,
2487 type, group_type, ede ? (void*) (((char *)data) + ede->offset) : (void**) &result,
2490 if (ret <= 0) goto error;
2493 /* advance to next chunk */
2494 NEXT_CHUNK(p, size, echnk, ed);
2497 _eet_freelist_all_unref(context);
2500 _eet_freelist_str_free(context, edd);
2501 _eet_freelist_direct_str_free(context, edd);
2502 _eet_freelist_list_free(context, edd);
2503 _eet_freelist_hash_free(context, edd);
2504 _eet_freelist_free(context, edd);
2508 _eet_freelist_reset(context);
2509 _eet_freelist_str_reset(context);
2510 _eet_freelist_list_reset(context);
2511 _eet_freelist_hash_reset(context);
2512 _eet_freelist_direct_str_reset(context);
2521 eet_node_del(result);
2523 _eet_freelist_all_unref(context);
2524 _eet_freelist_str_free(context, edd);
2525 _eet_freelist_direct_str_free(context, edd);
2526 _eet_freelist_list_free(context, edd);
2527 _eet_freelist_hash_free(context, edd);
2528 _eet_freelist_free(context, edd);
2530 /* FIXME: Warn that something goes wrong here. */
2535 eet_data_get_list(Eet_Free_Context *context, const Eet_Dictionary *ed, Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Chunk *echnk,
2536 int type, int group_type __UNUSED__, void *data,
2537 char **p, int *size)
2539 Eet_Data_Descriptor *subtype = NULL;
2544 EET_ASSERT(!((type > EET_T_UNKNOW) && (type < EET_T_STRING)), return 0);
2548 subtype = ede->subtype;
2550 if (type != ede->type)
2554 ptr = (void **)data;
2558 if (IS_POINTER_TYPE(type))
2562 ret = eet_data_get_unknown(context, ed, edd, ede, echnk, type, EET_G_UNKNOWN,
2563 &data_ret, p, size);
2568 data_ret = _eet_data_descriptor_decode(context, ed, subtype,
2569 echnk->data, echnk->size);
2570 if (!data_ret) return 0;
2575 list = edd->func.list_append(list, data_ret);
2577 _eet_freelist_list_add(context, ptr);
2581 eet_node_list_append(*((Eet_Node**) data), echnk->name, data_ret);
2588 eet_data_get_hash(Eet_Free_Context *context, const Eet_Dictionary *ed, Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Chunk *echnk,
2589 int type, int group_type __UNUSED__, void *data,
2590 char **p, int *size)
2595 void *data_ret = NULL;
2598 EET_ASSERT(!((type > EET_T_UNKNOW) && (type < EET_T_STRING)), return 0);
2600 ptr = (void **)data;
2604 ret = eet_data_get_type(ed,
2607 ((char *)echnk->data) + echnk->size,
2609 if (ret <= 0) goto on_error;
2611 /* Advance to next chunk */
2612 NEXT_CHUNK((*p), (*size), (*echnk), ed);
2613 memset(echnk, 0, sizeof(Eet_Data_Chunk));
2616 eet_data_chunk_get(ed, echnk, *p, *size);
2617 if (!echnk->name) goto on_error;
2619 if (IS_POINTER_TYPE(echnk->type))
2621 ret = eet_data_get_unknown(context, ed, edd, ede, echnk, echnk->type, EET_G_UNKNOWN,
2622 &data_ret, p, size);
2623 if (!ret) goto on_error;
2627 data_ret = _eet_data_descriptor_decode(context,
2629 ede ? ede->subtype : NULL,
2632 if (!data_ret) goto on_error;
2637 hash = edd->func.hash_add(hash, key, data_ret);
2639 _eet_freelist_hash_add(context, hash);
2643 eet_node_hash_add(*((Eet_Node **) data), echnk->name, key, data_ret);
2652 /* var arrays and fixed arrays have to
2653 * get all chunks at once. for fixed arrays
2654 * we can get each chunk and increment a
2655 * counter stored on the element itself but
2656 * it wont be thread safe. for var arrays
2657 * we still need a way to get the number of
2658 * elements from the data, so storing the
2659 * number of elements and the element data on
2660 * each chunk is pointless.
2663 eet_data_get_array(Eet_Free_Context *context, const Eet_Dictionary *ed, Eet_Data_Descriptor *edd,
2664 Eet_Data_Element *ede, Eet_Data_Chunk *echnk,
2665 int type, int group_type, void *data,
2666 char **p, int *size)
2668 Eina_List *childs = NULL;
2677 EET_ASSERT(!((type > EET_T_UNKNOW) && (type < EET_T_STRING)), return 0);
2680 /* read the number of elements */
2681 ret = eet_data_get_type(ed,
2684 ((char *)echnk->data) + echnk->size,
2686 if (ret <= 0) return ret;
2692 if (IS_POINTER_TYPE(type))
2693 subsize = eet_basic_codec[ede->type].size;
2695 subsize = ede->subtype->size;
2697 if (group_type == EET_G_VAR_ARRAY)
2699 /* store the number of elements
2700 * on the counter offset */
2701 *(int *)(((char *)data) + ede->count - ede->offset) = count;
2702 /* allocate space for the array of elements */
2703 *(void **)ptr = edd->func.mem_alloc(count * subsize);
2705 if (!*(void **)ptr) return 0;
2707 memset(*(void **)ptr, 0, count * subsize);
2709 _eet_freelist_add(context, *(void **)ptr);
2713 /* get all array elements */
2714 for (i = 0; i < count; i++)
2717 void *data_ret = NULL;
2719 /* Advance to next chunk */
2720 NEXT_CHUNK((*p), (*size), (*echnk), ed);
2721 memset(echnk, 0, sizeof(Eet_Data_Chunk));
2723 eet_data_chunk_get(ed, echnk, *p, *size);
2724 if (!echnk->name || strcmp(echnk->name, name) != 0) goto on_error;
2727 if (echnk->group_type != group_type
2728 || (echnk->type != type && echnk->type != EET_T_NULL))
2732 if (ede->group_type != echnk->group_type
2733 || (echnk->type != ede->type && echnk->type != EET_T_NULL))
2736 /* get the destination pointer */
2739 if (group_type == EET_G_ARRAY)
2740 dst = (char *)ptr + (subsize * i);
2742 dst = *(char **)ptr + (subsize * i);
2745 if (IS_POINTER_TYPE(echnk->type))
2747 ret = eet_data_get_unknown(context, ed, edd, ede, echnk, echnk->type, EET_G_UNKNOWN,
2748 &data_ret, p, size);
2749 if (!ret) goto on_error;
2750 if (dst) memcpy(dst, &data_ret, subsize);
2751 if (!edd) childs = eina_list_append(childs, data_ret);
2755 data_ret = _eet_data_descriptor_decode(context, ed, ede ? ede->subtype : NULL,
2756 echnk->data, echnk->size);
2757 if (!data_ret) goto on_error;
2760 memcpy(dst, data_ret, subsize);
2761 _eet_freelist_add(context, data_ret);
2763 if (!edd) childs = eina_list_append(childs, data_ret);
2769 Eet_Node *parent = *((Eet_Node **) data);
2772 if (group_type == EET_G_ARRAY)
2773 array = eet_node_array_new(name, count, childs);
2775 array = eet_node_var_array_new(name, childs);
2777 if (!array) goto on_error;
2779 eet_node_struct_append(parent, name, array);
2785 EINA_LIST_FREE(childs, tmp)
2792 eet_data_node_simple_type(int type, const char *name, void *dd)
2798 #define EET_T_TYPE(Eet_Type, Eet_Node_Type, Type) \
2800 return eet_node_##Eet_Node_Type##_new(name, *((Type *) dd)); \
2804 EET_T_TYPE(EET_T_CHAR, char, char);
2805 EET_T_TYPE(EET_T_SHORT, short, short);
2806 EET_T_TYPE(EET_T_INT, int, int);
2807 EET_T_TYPE(EET_T_LONG_LONG, long_long, long long);
2808 EET_T_TYPE(EET_T_FLOAT, float, float);
2809 EET_T_TYPE(EET_T_DOUBLE, double, double);
2810 EET_T_TYPE(EET_T_UCHAR, unsigned_char, unsigned char);
2811 EET_T_TYPE(EET_T_USHORT, unsigned_short, unsigned short);
2812 EET_T_TYPE(EET_T_UINT, unsigned_int, unsigned int);
2813 EET_T_TYPE(EET_T_ULONG_LONG, unsigned_long_long, unsigned long long);
2814 EET_T_TYPE(EET_T_STRING, string, char*);
2815 EET_T_TYPE(EET_T_INLINED_STRING, inlined_string, char*);
2817 return eet_node_null_new(name);
2819 ERR("Unknow type passed to eet_data_node_simple_type");
2825 eet_data_get_unknown(Eet_Free_Context *context, const Eet_Dictionary *ed, Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Chunk *echnk,
2826 int type, int group_type __UNUSED__, void *data,
2827 char **p __UNUSED__, int *size __UNUSED__)
2832 if (IS_SIMPLE_TYPE(type))
2834 unsigned char dd[128];
2836 ret = eet_data_get_type(ed, type, echnk->data, ((char *)echnk->data) + echnk->size, edd ? (char*) data : (char*) dd);
2837 if (ret <= 0) return ret;
2841 Eet_Node **parent = data;
2844 node = eet_data_node_simple_type(type, echnk->name, dd);
2846 if (*parent) eet_node_struct_append(*parent, echnk->name, node);
2847 else *parent = node;
2851 if (type == EET_T_STRING)
2855 str = (char **)(((char *)data));
2858 if ((ed == NULL) || (edd->func.str_direct_alloc == NULL))
2860 *str = edd->func.str_alloc(*str);
2861 _eet_freelist_str_add(context, *str);
2865 *str = edd->func.str_direct_alloc(*str);
2866 _eet_freelist_direct_str_add(context, *str);
2870 else if (edd && type == EET_T_INLINED_STRING)
2874 str = (char **)(((char *)data));
2877 *str = edd->func.str_alloc(*str);
2878 _eet_freelist_str_add(context, *str);
2885 Eet_Data_Descriptor *subtype;
2887 subtype = ede ? ede->subtype : NULL;
2889 if (subtype || !edd)
2891 Eet_Node **parent = data;
2894 data_ret = _eet_data_descriptor_decode(context, ed, subtype, echnk->data, echnk->size);
2895 if (!data_ret) return 0;
2899 ptr = (void **)(((char *)data));
2900 *ptr = (void *)data_ret;
2904 Eet_Node *node = data_ret;
2908 node = eet_node_struct_child_new(echnk->name, node);
2909 eet_node_struct_append(*parent, echnk->name, node);
2911 else *parent = node;
2920 eet_data_put_array(Eet_Dictionary *ed, Eet_Data_Descriptor *edd __UNUSED__, Eet_Data_Element *ede, Eet_Data_Stream *ds, void *data_in)
2929 EET_ASSERT(!((ede->type > EET_T_UNKNOW) && (ede->type < EET_T_STRING)), return );
2931 if (ede->group_type == EET_G_ARRAY)
2932 count = ede->counter_offset;
2934 count = *(int *)(((char *)data_in) + ede->count - ede->offset);
2936 if (count <= 0) return;
2937 /* Store number of elements */
2938 data = eet_data_put_type(ed, EET_T_INT, &count, &size);
2939 if (data) eet_data_encode(ed, ds, data, ede->name, size, ede->type, ede->group_type);
2941 if (IS_POINTER_TYPE(ede->type))
2942 subsize = eet_basic_codec[ede->type].size;
2944 subsize = ede->subtype->size;
2946 for (j = 0; j < count; j++)
2951 if (ede->group_type == EET_G_ARRAY)
2952 d = (void *)(((char *)data_in) + offset);
2954 d = *(((char **)data_in)) + offset;
2956 if (IS_POINTER_TYPE(ede->type))
2959 eet_data_put_unknown(ed, NULL, ede, ds, d);
2963 data = _eet_data_descriptor_encode(ed, ede->subtype, d, &size);
2964 if (data) eet_data_encode(ed, ds, data, ede->name, size, ede->type, ede->group_type);
2969 /* Add a NULL element just to have the correct array layout. */
2970 eet_data_encode(ed, ds, NULL, ede->name, 0, EET_T_NULL, ede->group_type);
2978 eet_data_put_unknown(Eet_Dictionary *ed, Eet_Data_Descriptor *edd __UNUSED__, Eet_Data_Element *ede, Eet_Data_Stream *ds, void *data_in)
2983 if (IS_SIMPLE_TYPE(ede->type))
2984 data = eet_data_put_type(ed, ede->type, data_in, &size);
2985 else if (ede->subtype)
2987 if (*((char **)data_in))
2988 data = _eet_data_descriptor_encode(ed,
2990 *((char **)((char *)(data_in))),
2993 if (data) eet_data_encode(ed, ds, data, ede->name, size, ede->type, ede->group_type);
2997 eet_data_put_list(Eet_Dictionary *ed, Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Stream *ds, void *data_in)
3003 EET_ASSERT(!(((ede->type > EET_T_UNKNOW) && (ede->type < EET_T_STRING))
3004 || ((ede->type > EET_T_NULL) && (ede->type < EET_T_LAST))),
3007 l = *((void **)(((char *)data_in)));
3008 for (; l; l = edd->func.list_next(l))
3010 if (IS_POINTER_TYPE(ede->type))
3012 const void *str = edd->func.list_data(l);
3013 eet_data_put_unknown(ed, NULL, ede, ds, &str);
3017 data = _eet_data_descriptor_encode(ed,
3019 edd->func.list_data(l),
3021 if (data) eet_data_encode(ed, ds, data, ede->name, size, ede->type, ede->group_type);
3027 eet_data_put_hash(Eet_Dictionary *ed, Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Stream *ds, void *data_in)
3029 Eet_Data_Encode_Hash_Info fdata;
3032 l = *((void **)(((char *)data_in)));
3036 edd->func.hash_foreach(l, eet_data_descriptor_encode_hash_cb, &fdata);
3040 eet_data_dump_cipher(Eet_File *ef,
3041 const char *name, const char *key,
3042 void (*dumpfunc) (void *data, const char *str),
3045 const Eet_Dictionary *ed = NULL;
3046 const void *data = NULL;
3048 Eet_Free_Context context;
3049 int required_free = 0;
3052 ed = eet_dictionary_get(ef);
3055 data = eet_read_direct(ef, name, &size);
3059 data = eet_read_cipher(ef, name, &size, key);
3060 if (!data) return 0;
3063 memset(&context, 0, sizeof (context));
3064 result = _eet_data_descriptor_decode(&context, ed, NULL, data, size);
3066 eet_node_dump(result, 0, dumpfunc, dumpdata);
3068 eet_node_del(result);
3073 return result ? 1 : 0;
3077 eet_data_dump(Eet_File *ef,
3079 void (*dumpfunc) (void *data, const char *str),
3082 return eet_data_dump_cipher(ef, name, NULL, dumpfunc, dumpdata);
3087 eet_data_text_dump_cipher(const void *data_in,
3088 const char *key, int size_in,
3089 void (*dumpfunc) (void *data, const char *str),
3094 Eet_Free_Context context;
3095 unsigned int ret_len = 0;
3097 if (!data_in) return 0;
3101 if (eet_decipher(data_in, size_in, key, strlen(key), &ret, &ret_len))
3109 ret = (void*) data_in;
3113 memset(&context, 0, sizeof (context));
3114 result = _eet_data_descriptor_decode(&context, NULL, NULL, ret, ret_len);
3116 eet_node_dump(result, 0, dumpfunc, dumpdata);
3118 eet_node_del(result);
3121 return result ? 1 : 0;
3125 eet_data_text_dump(const void *data_in,
3127 void (*dumpfunc) (void *data, const char *str),
3130 return eet_data_text_dump_cipher(data_in, NULL, size_in, dumpfunc, dumpdata);
3134 eet_data_text_undump_cipher(const char *text,
3141 ret = _eet_data_dump_parse(NULL, size_ret, text, textlen);
3144 void *ciphered = NULL;
3145 unsigned int ciphered_len;
3147 if (eet_cipher(ret, *size_ret, key, strlen(key), &ciphered, &ciphered_len))
3149 if (ciphered) free(ciphered);
3155 *size_ret = ciphered_len;
3162 eet_data_text_undump(const char *text,
3166 return eet_data_text_undump_cipher(text, NULL, textlen, size_ret);
3170 eet_data_undump_cipher(Eet_File *ef,
3182 ed = eet_dictionary_get(ef);
3184 data_enc = _eet_data_dump_parse(ed, &size, text, textlen);
3185 if (!data_enc) return 0;
3186 val = eet_write_cipher(ef, name, data_enc, size, compress, key);
3192 eet_data_undump(Eet_File *ef,
3198 return eet_data_undump_cipher(ef, name, NULL, text, textlen, compress);
3202 eet_data_descriptor_decode_cipher(Eet_Data_Descriptor *edd,
3203 const void *data_in,
3207 void *deciphered = (void*) data_in;
3209 Eet_Free_Context context;
3210 unsigned int deciphered_len = size_in;
3214 if (eet_decipher(data_in, size_in, key, strlen(key), &deciphered, &deciphered_len))
3216 if (deciphered) free(deciphered);
3221 memset(&context, 0, sizeof (context));
3222 ret = _eet_data_descriptor_decode(&context, NULL, edd, deciphered, deciphered_len);
3224 if (data_in != deciphered) free(deciphered);
3230 eet_data_descriptor_decode(Eet_Data_Descriptor *edd,
3231 const void *data_in,
3234 return eet_data_descriptor_decode_cipher(edd, data_in, NULL, size_in);
3238 eet_data_node_decode_cipher(const void *data_in, const char *key, int size_in)
3240 void *deciphered = (void*) data_in;
3242 Eet_Free_Context context;
3243 unsigned int deciphered_len = size_in;
3247 if (eet_decipher(data_in, size_in, key, strlen(key), &deciphered, &deciphered_len))
3249 if (deciphered) free(deciphered);
3254 memset(&context, 0, sizeof (context));
3255 ret = _eet_data_descriptor_decode(&context, NULL, NULL, deciphered, deciphered_len);
3257 if (data_in != deciphered) free(deciphered);
3263 _eet_data_descriptor_encode(Eet_Dictionary *ed,
3264 Eet_Data_Descriptor *edd,
3265 const void *data_in,
3268 Eet_Data_Stream *ds;
3269 Eet_Data_Chunk *chnk;
3274 if (_eet_data_words_bigendian == -1)
3276 unsigned long int v;
3278 v = htonl(0x12345678);
3279 if (v == 0x12345678) _eet_data_words_bigendian = 1;
3280 else _eet_data_words_bigendian = 0;
3283 ds = eet_data_stream_new();
3284 for (i = 0; i < edd->elements.num; i++)
3286 Eet_Data_Element *ede;
3288 ede = &(edd->elements.set[i]);
3289 eet_group_codec[ede->group_type - 100].put(ed, edd, ede, ds, ((char *)data_in) + ede->offset);
3291 chnk = eet_data_chunk_new(ds->data, ds->pos, edd->name, EET_T_UNKNOW, EET_G_UNKNOWN);
3294 eet_data_stream_free(ds);
3296 ds = eet_data_stream_new();
3297 eet_data_chunk_put(ed, chnk, ds);
3303 eet_data_stream_free(ds);
3307 eet_data_chunk_free(chnk);
3313 eet_data_node_write_cipher(Eet_File *ef, const char *name, const char *key, Eet_Node *node, int compress)
3320 ed = eet_dictionary_get(ef);
3322 data_enc = _eet_data_dump_encode(EET_G_UNKNOWN, ed, node, &size);
3323 if (!data_enc) return 0;
3324 val = eet_write_cipher(ef, name, data_enc, size, compress, key);
3330 eet_data_node_encode_cipher(Eet_Node *node,
3335 void *ciphered = NULL;
3336 unsigned int ciphered_len = 0;
3339 ret = _eet_data_dump_encode(EET_G_UNKNOWN, NULL, node, &size);
3342 if (eet_cipher(ret, size, key, strlen(key), &ciphered, &ciphered_len))
3344 if (ciphered) free(ciphered);
3345 if (size_ret) *size_ret = 0;
3350 size = (int) ciphered_len;
3354 if (size_ret) *size_ret = size;
3359 eet_data_descriptor_encode_cipher(Eet_Data_Descriptor *edd,
3360 const void *data_in,
3365 void *ciphered = NULL;
3366 unsigned int ciphered_len = 0;
3369 ret = _eet_data_descriptor_encode(NULL, edd, data_in, &size);
3372 if (eet_cipher(ret, size, key, strlen(key), &ciphered, &ciphered_len))
3374 if (ciphered) free(ciphered);
3375 if (size_ret) *size_ret = 0;
3380 size = ciphered_len;
3384 if (size_ret) *size_ret = size;
3389 eet_data_descriptor_encode(Eet_Data_Descriptor *edd,
3390 const void *data_in,
3393 return eet_data_descriptor_encode_cipher(edd, data_in, NULL, size_ret);