3 #endif /* ifdef HAVE_CONFIG_H */
11 #ifdef HAVE_NETINET_IN_H
12 # include <netinet/in.h>
16 # include <winsock2.h>
17 #endif /* ifdef _WIN32 */
22 #include "Eet_private.h"
25 * routines for doing data -> struct and struct -> data conversion
45 * multiple entries ordered as...
47 * fixed size array [ of basic types ]
48 * variable size array [ of basic types ]
49 * linked list [ of basic types ]
50 * hash table [ of basic types ]
52 * need to provide builder/accessor funcs for:
64 typedef struct _Eet_Data_Element Eet_Data_Element;
65 typedef struct _Eet_Data_Basic_Type_Codec Eet_Data_Basic_Type_Codec;
66 typedef struct _Eet_Data_Group_Type_Codec Eet_Data_Group_Type_Codec;
67 typedef struct _Eet_Data_Chunk Eet_Data_Chunk;
68 typedef struct _Eet_Data_Stream Eet_Data_Stream;
69 typedef struct _Eet_Data_Descriptor_Hash Eet_Data_Descriptor_Hash;
70 typedef struct _Eet_Data_Encode_Hash_Info Eet_Data_Encode_Hash_Info;
71 typedef struct _Eet_Free Eet_Free;
72 typedef struct _Eet_Free_Context Eet_Free_Context;
73 typedef struct _Eet_Variant_Unknow Eet_Variant_Unknow;
78 * Eet_Data_Basic_Type_Codec (Coder, Decoder)
79 * Eet_Data_Group_Type_Codec (Coder, Decoder)
81 struct _Eet_Data_Basic_Type_Codec
85 int (*get)(const Eet_Dictionary *ed,
89 void * (*put)(Eet_Dictionary *ed, const void *src, int *size_ret);
92 struct _Eet_Data_Group_Type_Codec
94 int (*get)(Eet_Free_Context *context,
95 const Eet_Dictionary *ed,
96 Eet_Data_Descriptor *edd,
97 Eet_Data_Element *ede,
98 Eet_Data_Chunk *echnk,
104 void (*put)(Eet_Dictionary *ed,
105 Eet_Data_Descriptor *edd,
106 Eet_Data_Element *ede,
111 struct _Eet_Data_Chunk
119 unsigned char group_type;
122 struct _Eet_Data_Stream
129 struct _Eet_Data_Descriptor_Hash
131 Eet_Data_Element *element;
132 Eet_Data_Descriptor_Hash *next;
135 struct _Eet_Data_Descriptor
138 const Eet_Dictionary *ed;
142 void * (*mem_alloc)(size_t size);
143 void (*mem_free)(void *mem);
144 char * (*str_alloc)(const char *str);
145 char * (*str_direct_alloc)(const char *str);
146 void (*str_free)(const char *str);
147 void (*str_direct_free)(const char *str);
148 void * (*list_next)(void *l);
149 void * (*list_append)(void *l, void *d);
150 void * (*list_data)(void *l);
151 void * (*list_free)(void *l);
152 void (*hash_foreach)(void *h,
158 void * (*hash_add)(void *h, const char *k, void *d);
159 void (*hash_free)(void *h);
160 const char *(*type_get)(const void *data, Eina_Bool *unknow);
161 Eina_Bool (*type_set)(const char *type,
164 void * (*array_alloc)(size_t size);
165 void (*array_free)(void *mem);
170 Eet_Data_Element *set;
174 Eet_Data_Descriptor_Hash *buckets;
178 Eina_Bool unified_type : 1;
183 struct _Eet_Data_Element
186 const char *counter_name;
187 const char *directory_name_ptr;
188 Eet_Data_Descriptor *subtype;
189 int offset; /* offset in bytes from the base element */
190 int count; /* number of elements for a fixed array */
191 int counter_offset; /* for a variable array we need the offset of the count variable */
192 unsigned char type; /* EET_T_XXX */
193 unsigned char group_type; /* EET_G_XXX */
196 struct _Eet_Data_Encode_Hash_Info
199 Eet_Data_Element *ede;
203 #define EET_FREE_COUNT 256
207 Eina_Array list[EET_FREE_COUNT];
210 struct _Eet_Free_Context
213 Eet_Free freelist_array;
214 Eet_Free freelist_list;
215 Eet_Free freelist_hash;
216 Eet_Free freelist_str;
217 Eet_Free freelist_direct_str;
220 struct _Eet_Variant_Unknow
231 eet_free_context_init(Eet_Free_Context *context);
233 eet_free_context_shutdown(Eet_Free_Context *context);
236 eet_data_get_char(const Eet_Dictionary *ed,
241 eet_data_put_char(Eet_Dictionary *ed,
245 eet_data_get_short(const Eet_Dictionary *ed,
250 eet_data_put_short(Eet_Dictionary *ed,
254 eet_data_get_int(const Eet_Dictionary *ed,
259 eet_data_put_int(Eet_Dictionary *ed,
263 eet_data_get_long_long(const Eet_Dictionary *ed,
268 eet_data_put_long_long(Eet_Dictionary *ed,
272 eet_data_get_float(const Eet_Dictionary *ed,
277 eet_data_put_float(Eet_Dictionary *ed,
281 eet_data_get_double(const Eet_Dictionary *ed,
286 eet_data_put_double(Eet_Dictionary *ed,
290 eet_data_get_f32p32(const Eet_Dictionary *ed,
295 eet_data_put_f32p32(Eet_Dictionary *ed,
299 eet_data_get_f16p16(const Eet_Dictionary *ed,
304 eet_data_put_f16p16(Eet_Dictionary *ed,
308 eet_data_get_f8p24(const Eet_Dictionary *ed,
313 eet_data_put_f8p24(Eet_Dictionary *ed,
317 eet_data_get_string(const Eet_Dictionary *ed,
322 eet_data_put_string(Eet_Dictionary *ed,
326 eet_data_get_istring(const Eet_Dictionary *ed,
331 eet_data_put_istring(Eet_Dictionary *ed,
335 eet_data_get_null(const Eet_Dictionary *ed,
340 eet_data_put_null(Eet_Dictionary *ed,
345 eet_data_get_value(const Eet_Dictionary *ed,
351 eet_data_put_value(Eet_Dictionary *ed,
356 eet_data_get_type(const Eet_Dictionary *ed,
362 eet_data_put_type(Eet_Dictionary *ed,
368 eet_data_node_simple_type(int type,
373 eet_data_get_unknown(Eet_Free_Context *context,
374 const Eet_Dictionary *ed,
375 Eet_Data_Descriptor *edd,
376 Eet_Data_Element *ede,
377 Eet_Data_Chunk *echnk,
384 eet_data_put_unknown(Eet_Dictionary *ed,
385 Eet_Data_Descriptor *edd,
386 Eet_Data_Element *ede,
390 eet_data_put_array(Eet_Dictionary *ed,
391 Eet_Data_Descriptor *edd,
392 Eet_Data_Element *ede,
396 eet_data_get_array(Eet_Free_Context *context,
397 const Eet_Dictionary *ed,
398 Eet_Data_Descriptor *edd,
399 Eet_Data_Element *ede,
400 Eet_Data_Chunk *echnk,
407 eet_data_get_list(Eet_Free_Context *context,
408 const Eet_Dictionary *ed,
409 Eet_Data_Descriptor *edd,
410 Eet_Data_Element *ede,
411 Eet_Data_Chunk *echnk,
418 eet_data_put_list(Eet_Dictionary *ed,
419 Eet_Data_Descriptor *edd,
420 Eet_Data_Element *ede,
424 eet_data_put_hash(Eet_Dictionary *ed,
425 Eet_Data_Descriptor *edd,
426 Eet_Data_Element *ede,
430 eet_data_get_hash(Eet_Free_Context *context,
431 const Eet_Dictionary *ed,
432 Eet_Data_Descriptor *edd,
433 Eet_Data_Element *ede,
434 Eet_Data_Chunk *echnk,
441 eet_data_put_union(Eet_Dictionary *ed,
442 Eet_Data_Descriptor *edd,
443 Eet_Data_Element *ede,
447 eet_data_get_union(Eet_Free_Context *context,
448 const Eet_Dictionary *ed,
449 Eet_Data_Descriptor *edd,
450 Eet_Data_Element *ede,
451 Eet_Data_Chunk *echnk,
458 eet_data_put_variant(Eet_Dictionary *ed,
459 Eet_Data_Descriptor *edd,
460 Eet_Data_Element *ede,
464 eet_data_get_variant(Eet_Free_Context *context,
465 const Eet_Dictionary *ed,
466 Eet_Data_Descriptor *edd,
467 Eet_Data_Element *ede,
468 Eet_Data_Chunk *echnk,
476 eet_data_chunk_get(const Eet_Dictionary *ed,
477 Eet_Data_Chunk *chnk,
480 static Eet_Data_Chunk *
481 eet_data_chunk_new(void *data,
487 eet_data_chunk_free(Eet_Data_Chunk *chnk);
489 static Eet_Data_Stream *
490 eet_data_stream_new(void);
492 eet_data_stream_write(Eet_Data_Stream *ds,
496 eet_data_stream_free(Eet_Data_Stream *ds);
499 eet_data_chunk_put(Eet_Dictionary *ed,
500 Eet_Data_Chunk *chnk,
501 Eet_Data_Stream *ds);
504 eet_data_descriptor_encode_hash_cb(void *hash,
508 static void *_eet_data_descriptor_encode(Eet_Dictionary *ed,
509 Eet_Data_Descriptor *edd,
512 static void *_eet_data_descriptor_decode(Eet_Free_Context *context,
513 const Eet_Dictionary *ed,
514 Eet_Data_Descriptor *edd,
522 static const Eet_Data_Basic_Type_Codec eet_basic_codec[] =
524 {sizeof(char), "char", eet_data_get_char, eet_data_put_char },
525 {sizeof(short), "short", eet_data_get_short, eet_data_put_short },
526 {sizeof(int), "int", eet_data_get_int, eet_data_put_int },
527 {sizeof(long long), "long_long", eet_data_get_long_long, eet_data_put_long_long},
528 {sizeof(float), "float", eet_data_get_float, eet_data_put_float },
529 {sizeof(double), "double", eet_data_get_double, eet_data_put_double },
530 {sizeof(char), "uchar", eet_data_get_char, eet_data_put_char },
531 {sizeof(short), "ushort", eet_data_get_short, eet_data_put_short },
532 {sizeof(int), "uint", eet_data_get_int, eet_data_put_int },
533 {sizeof(long long), "ulong_long", eet_data_get_long_long, eet_data_put_long_long},
534 {sizeof(char *), "string", eet_data_get_string, eet_data_put_string },
535 {sizeof(char *), "inlined", eet_data_get_istring, eet_data_put_istring },
536 {sizeof(void *), "NULL", eet_data_get_null, eet_data_put_null },
537 {sizeof(Eina_F32p32), "f32p32", eet_data_get_f32p32, eet_data_put_f32p32 },
538 {sizeof(Eina_F16p16), "f16p16", eet_data_get_f16p16, eet_data_put_f16p16 },
539 {sizeof(Eina_F8p24), "f8p24", eet_data_get_f8p24, eet_data_put_f8p24 },
540 {sizeof(Eina_Value*), "eina_value*", eet_data_get_value, eet_data_put_value }
543 static const Eet_Data_Group_Type_Codec eet_group_codec[] =
545 { eet_data_get_unknown, eet_data_put_unknown },
546 { eet_data_get_array, eet_data_put_array },
547 { eet_data_get_array, eet_data_put_array },
548 { eet_data_get_list, eet_data_put_list },
549 { eet_data_get_hash, eet_data_put_hash },
550 { eet_data_get_union, eet_data_put_union },
551 { eet_data_get_variant, eet_data_put_variant },
552 { eet_data_get_unknown, eet_data_put_unknown }
555 static int _eet_data_words_bigendian = -1;
559 #define SWAP64(x) (x) = \
560 ((((unsigned long long)(x) & 0x00000000000000ffULL) << 56) | \
561 (((unsigned long long)(x) & 0x000000000000ff00ULL) << 40) | \
562 (((unsigned long long)(x) & 0x0000000000ff0000ULL) << 24) | \
563 (((unsigned long long)(x) & 0x00000000ff000000ULL) << 8) | \
564 (((unsigned long long)(x) & 0x000000ff00000000ULL) >> 8) | \
565 (((unsigned long long)(x) & 0x0000ff0000000000ULL) >> 24) | \
566 (((unsigned long long)(x) & 0x00ff000000000000ULL) >> 40) | \
567 (((unsigned long long)(x) & 0xff00000000000000ULL) >> 56))
568 #define SWAP32(x) (x) = \
569 ((((int)(x) & 0x000000ff) << 24) | \
570 (((int)(x) & 0x0000ff00) << 8) | \
571 (((int)(x) & 0x00ff0000) >> 8) | \
572 (((int)(x) & 0xff000000) >> 24))
573 #define SWAP16(x) (x) = \
574 ((((short)(x) & 0x00ff) << 8) | \
575 (((short)(x) & 0xff00) >> 8))
579 #endif /* ifdef CONV8 */
582 #endif /* ifdef CONV16 */
585 #endif /* ifdef CONV32 */
588 #endif /* ifdef CONV64 */
591 #define CONV16(x) {if (_eet_data_words_bigendian) {SWAP16(x); }}
592 #define CONV32(x) {if (_eet_data_words_bigendian) {SWAP32(x); }}
593 #define CONV64(x) {if (_eet_data_words_bigendian) {SWAP64(x); }}
595 #define IS_SIMPLE_TYPE(Type) (Type > EET_T_UNKNOW && Type < EET_T_LAST)
596 #define IS_POINTER_TYPE(Type) ((Type >= EET_T_STRING && Type <= EET_T_NULL) || Type == EET_T_VALUE)
598 #define POINTER_TYPE_DECODE(Context, \
610 ___r = eet_data_get_unknown(Context, \
614 Type, EET_G_UNKNOWN, \
616 if (!___r) { goto Label; } \
619 #define STRUCT_TYPE_DECODE(Data_Ret, Context, Ed, Ede, Data, Size, SubSize, Label) \
621 Data_Ret = _eet_data_descriptor_decode(Context, \
626 SubSize > 0 ? Data_Ret : NULL, \
628 if (!Data_Ret) { goto Label; } \
631 #define EET_I_STRING 1 << 4
632 #define EET_I_INLINED_STRING 2 << 4
633 #define EET_I_NULL 3 << 4
635 #define EET_MAGIC_VARIANT 0xF1234BC
640 eet_data_get_char(const Eet_Dictionary *ed EINA_UNUSED,
647 if (((char *)src + sizeof(char)) > (char *)src_end)
658 eet_data_put_char(Eet_Dictionary *ed EINA_UNUSED,
664 d = (char *)malloc(sizeof(char));
671 *size_ret = sizeof(char);
677 eet_data_get_short(const Eet_Dictionary *ed EINA_UNUSED,
684 if (((char *)src + sizeof(short)) > (char *)src_end)
687 memcpy(dst, src, sizeof(short));
690 return sizeof(short);
694 eet_data_put_short(Eet_Dictionary *ed EINA_UNUSED,
700 d = (short *)malloc(sizeof(short));
707 *size_ret = sizeof(short);
713 eet_data_get_int(const Eet_Dictionary *ed EINA_UNUSED,
720 if (((char *)src + sizeof(int)) > (char *)src_end)
723 memcpy(dst, src, sizeof(int));
730 eet_data_put_int(Eet_Dictionary *ed EINA_UNUSED,
736 d = (int *)malloc(sizeof(int));
743 *size_ret = sizeof(int);
749 eet_data_get_long_long(const Eet_Dictionary *ed EINA_UNUSED,
754 unsigned long long *d;
756 if (((char *)src + sizeof(unsigned long long)) > (char *)src_end)
759 memcpy(dst, src, sizeof(unsigned long long));
760 d = (unsigned long long *)dst;
762 return sizeof(unsigned long long);
766 eet_data_put_long_long(Eet_Dictionary *ed EINA_UNUSED,
770 unsigned long long *s, *d;
772 d = (unsigned long long *)malloc(sizeof(unsigned long long));
776 s = (unsigned long long *)src;
779 *size_ret = sizeof(unsigned long long);
785 eet_data_get_string_hash(const Eet_Dictionary *ed,
793 if (eet_data_get_int(ed, src, src_end, &idx) < 0)
796 return eet_dictionary_string_get_hash(ed, idx);
803 eet_data_get_string(const Eet_Dictionary *ed,
817 if (eet_data_get_int(ed, src, src_end, &idx) < 0)
820 str = eet_dictionary_string_get_char(ed, idx);
825 return eet_dictionary_string_get_size(ed, idx);
836 return strlen(s) + 1;
840 eet_data_put_string(Eet_Dictionary *ed,
852 str = *((const char **)src);
856 idx = eet_dictionary_string_add(ed, str);
860 return eet_data_put_int(ed, &idx, size_ret);
863 s = (char *)(*((char **)src));
872 memcpy(d, s, len + 1);
877 /* ALWAYS INLINED STRING TYPE */
879 eet_data_get_istring(const Eet_Dictionary *ed EINA_UNUSED,
884 return eet_data_get_string(NULL, src, src_end, dst);
888 eet_data_put_istring(Eet_Dictionary *ed EINA_UNUSED,
892 return eet_data_put_string(NULL, src, size_ret);
895 /* ALWAYS NULL TYPE */
897 eet_data_get_null(const Eet_Dictionary *ed EINA_UNUSED,
898 const void *src EINA_UNUSED,
899 const void *src_end EINA_UNUSED,
911 eet_data_put_null(Eet_Dictionary *ed EINA_UNUSED,
912 const void *src EINA_UNUSED,
920 * Fast lookups of simple doubles/floats.
922 * These aren't properly a cache because they don't store pre-calculated
923 * values, but have a so simple math that is almost as fast.
926 _eet_data_float_cache_get(const char *s,
930 /* fast handle of simple case 0xMp+E*/
931 if ((len == 6) && (s[0] == '0') && (s[1] == 'x') && (s[3] == 'p'))
933 int mantisse = (s[2] >= 'a') ? (s[2] - 'a' + 10) : (s[2] - '0');
934 int exponent = (s[5] - '0');
937 *d = (float)(mantisse << exponent);
939 *d = (float)mantisse / (float)(1 << exponent);
948 _eet_data_double_cache_get(const char *s,
952 /* fast handle of simple case 0xMp+E*/
953 if ((len == 6) && (s[0] == '0') && (s[1] == 'x') && (s[3] == 'p'))
955 int mantisse = (s[2] >= 'a') ? (s[2] - 'a' + 10) : (s[2] - '0');
956 int exponent = (s[5] - '0');
959 *d = (double)(mantisse << exponent);
961 *d = (double)mantisse / (double)(1 << exponent);
971 eet_data_get_float(const Eet_Dictionary *ed,
987 s = (const char *)src;
990 while ((p < (const char *)src_end) && (*p != 0)) {len++; p++; }
992 if (_eet_data_float_cache_get(s, len, d) != 0)
995 if (eina_convert_atod(s, len, &mantisse, &exponent) == EINA_FALSE)
998 *d = (float)ldexp((double)mantisse, exponent);
1003 if (eet_data_get_int(ed, src, src_end, &idx) < 0)
1006 if (!eet_dictionary_string_get_float(ed, idx, d))
1013 eet_data_put_float(Eet_Dictionary *ed,
1020 eina_convert_dtoa((double)(*(float *)src), buf);
1028 d = malloc(len + 1);
1032 memcpy(d, buf, len + 1);
1033 *size_ret = len + 1;
1037 idx = eet_dictionary_string_add(ed, buf);
1041 return eet_data_put_int(ed, &idx, size_ret);
1046 eet_data_get_double(const Eet_Dictionary *ed,
1048 const void *src_end,
1059 long long mantisse = 0;
1063 s = (const char *)src;
1066 while ((p < (const char *)src_end) && (*p != 0)) {len++; p++; }
1068 if (_eet_data_double_cache_get(s, len, d) != 0)
1071 if (eina_convert_atod(s, len, &mantisse, &exponent) == EINA_FALSE)
1074 *d = ldexp((double)mantisse, exponent);
1079 if (eet_data_get_int(ed, src, src_end, &idx) < 0)
1082 if (!eet_dictionary_string_get_double(ed, idx, d))
1089 eet_data_put_double(Eet_Dictionary *ed,
1096 eina_convert_dtoa((double)(*(double *)src), buf);
1104 d = malloc(len + 1);
1108 memcpy(d, buf, len + 1);
1109 *size_ret = len + 1;
1114 idx = eet_dictionary_string_add(ed, buf);
1118 return eet_data_put_int(ed, &idx, size_ret);
1122 eet_data_get_f32p32(const Eet_Dictionary *ed,
1124 const void *src_end,
1130 fp = (Eina_F32p32 *)dst;
1137 s = (const char *)src;
1140 while ((p < (const char *)src_end) && (*p != 0)) { len++; p++; }
1142 if (!(eina_convert_atofp(s, len, fp)))
1148 if (eet_data_get_int(ed, src, src_end, &idx) < 0)
1151 if (!eet_dictionary_string_get_fp(ed, idx, fp))
1158 eet_data_put_f32p32(Eet_Dictionary *ed,
1165 eina_convert_fptoa((Eina_F32p32)(*(Eina_F32p32 *)src), buf);
1173 d = malloc(len + 1);
1177 memcpy(d, buf, len + 1);
1178 *size_ret = len + 1;
1183 idx = eet_dictionary_string_add(ed, buf);
1187 return eet_data_put_int(ed, &idx, size_ret);
1191 eet_data_get_f16p16(const Eet_Dictionary *ed,
1193 const void *src_end,
1199 fp = (Eina_F16p16 *)dst;
1201 if (eet_data_get_f32p32(ed, src, src_end, &tmp) < 0)
1204 *fp = eina_f32p32_to_f16p16(tmp);
1209 eet_data_put_f16p16(Eet_Dictionary *ed,
1215 tmp = eina_f16p16_to_f32p32((Eina_F16p16)(*(Eina_F16p16 *)src));
1216 return eet_data_put_f32p32(ed, &tmp, size_ret);
1220 eet_data_get_f8p24(const Eet_Dictionary *ed,
1222 const void *src_end,
1228 fp = (Eina_F8p24 *)dst;
1230 if (eet_data_get_f32p32(ed, src, src_end, &tmp) < 0)
1233 *fp = eina_f32p32_to_f8p24(tmp);
1238 eet_data_put_f8p24(Eet_Dictionary *ed,
1244 tmp = eina_f8p24_to_f32p32((Eina_F8p24)(*(Eina_F8p24 *)src));
1245 return eet_data_put_f32p32(ed, &tmp, size_ret);
1248 static const Eina_Value_Type *
1249 _eet_type_to_eina_value_get(int eet_type)
1253 case EET_T_UCHAR: return EINA_VALUE_TYPE_UCHAR;
1254 case EET_T_USHORT: return EINA_VALUE_TYPE_USHORT;
1255 case EET_T_UINT: return EINA_VALUE_TYPE_UINT;
1256 #if SIZEOF_LONG == SIZEOF_INT
1257 /* case EET_T_UINT: return EINA_VALUE_TYPE_ULONG; */
1258 /* case EET_T_UINT: return EINA_VALUE_TYPE_TIMESTAMP; */
1260 /* case EET_T_ULONG_LONG: return EINA_VALUE_TYPE_ULONG; */
1261 /* case EET_T_ULONG_LONG: return EINA_VALUE_TYPE_TIMESTAMP; */
1263 case EET_T_ULONG_LONG: return EINA_VALUE_TYPE_UINT64;
1264 case EET_T_CHAR: return EINA_VALUE_TYPE_CHAR;
1265 case EET_T_SHORT: return EINA_VALUE_TYPE_SHORT;
1266 case EET_T_INT: return EINA_VALUE_TYPE_INT;
1267 #if SIZEOF_LONG == SIZEOF_INT
1268 /* case EET_T_INT: return EINA_VALUE_TYPE_LONG; */
1270 /* case EET_T_LONG_LONG: return EINA_VALUE_TYPE_LONG; */
1272 case EET_T_LONG_LONG: return EINA_VALUE_TYPE_INT64;
1273 case EET_T_FLOAT: return EINA_VALUE_TYPE_FLOAT;
1274 case EET_T_DOUBLE: return EINA_VALUE_TYPE_DOUBLE;
1275 case EET_T_STRING: return EINA_VALUE_TYPE_STRING;
1276 /* case EET_T_STRING: return EINA_VALUE_TYPE_STRINGSHARE; */
1283 _eina_value_to_eet_type_get(const Eina_Value_Type *eina_type)
1285 if (eina_type == EINA_VALUE_TYPE_UCHAR) return EET_T_UCHAR;
1286 else if (eina_type == EINA_VALUE_TYPE_USHORT) return EET_T_USHORT;
1287 else if (eina_type == EINA_VALUE_TYPE_UINT) return EET_T_UINT;
1288 #if SIZEOF_LONG == SIZEOF_INT
1289 else if (eina_type == EINA_VALUE_TYPE_ULONG) return EET_T_UINT;
1290 else if (eina_type == EINA_VALUE_TYPE_TIMESTAMP) return EET_T_UINT;
1292 else if (eina_type == EINA_VALUE_TYPE_ULONG) return EET_T_ULONG_LONG;
1293 else if (eina_type == EINA_VALUE_TYPE_TIMESTAMP) return EET_T_ULONG_LONG;
1295 else if (eina_type == EINA_VALUE_TYPE_UINT64) return EET_T_ULONG_LONG;
1296 else if (eina_type == EINA_VALUE_TYPE_CHAR) return EET_T_CHAR;
1297 else if (eina_type == EINA_VALUE_TYPE_SHORT) return EET_T_SHORT;
1298 else if (eina_type == EINA_VALUE_TYPE_INT) return EET_T_INT;
1299 #if SIZEOF_LONG == SIZEOF_INT
1300 else if (eina_type == EINA_VALUE_TYPE_LONG) return EET_T_INT;
1302 else if (eina_type == EINA_VALUE_TYPE_LONG) return EET_T_LONG_LONG;
1304 else if (eina_type == EINA_VALUE_TYPE_INT64) return EET_T_LONG_LONG;
1305 else if (eina_type == EINA_VALUE_TYPE_FLOAT) return EET_T_FLOAT;
1306 else if (eina_type == EINA_VALUE_TYPE_DOUBLE) return EET_T_DOUBLE;
1307 else if (eina_type == EINA_VALUE_TYPE_STRING) return EET_T_STRING;
1308 else if (eina_type == EINA_VALUE_TYPE_STRINGSHARE) return EET_T_STRING;
1309 // always fallback to try a conversion to string if possible
1310 return EET_T_STRING;
1314 eet_data_get_value(const Eet_Dictionary *ed,
1316 const void *src_end,
1319 const Eina_Value_Type *eina_type;
1322 int eet_size, type_size;
1324 eet_size = eet_data_get_int(ed, src, src_end, &eet_type);
1326 eet_type <= EET_T_UNKNOW ||
1327 eet_type >= EET_T_VALUE)
1330 tmp = alloca(eet_basic_codec[eet_type - 1].size);
1331 type_size = eet_basic_codec[eet_type - 1].get(ed, (char*) src + eet_size, src_end, tmp);
1333 if (eet_type == EET_T_NULL)
1335 Eina_Value **value = dst;
1339 return eet_size + type_size;
1342 eina_type = _eet_type_to_eina_value_get(eet_type);
1345 Eina_Value **value = dst;
1347 *value = eina_value_new(eina_type);
1348 eina_value_pset(*value, tmp);
1350 return eet_size + type_size;
1357 eet_data_put_value(Eet_Dictionary *ed,
1361 const Eina_Value *value = *(void**)src;
1362 const Eina_Value_Type *value_type;
1365 int int_size, type_size;
1368 Eina_Bool v2s = EINA_FALSE;
1370 // map empty Eina_Value to EET_T_NULL;
1373 eet_type = EET_T_NULL;
1377 value_type = eina_value_type_get(value);
1378 eet_type = _eina_value_to_eet_type_get(value_type);
1381 tmp = alloca(eet_basic_codec[eet_type - 1].size);
1382 if (value) eina_value_get(value, tmp);
1383 else *(void**) tmp = NULL;
1385 // handle non simple case by forcing them to convert to string
1386 if ((eet_type == EET_T_STRING) &&
1387 (*(char**)tmp == NULL))
1389 *(char**)tmp = eina_value_to_string(value);
1393 int_data = eet_data_put_int(ed, &eet_type, &int_size);
1394 type_data = eet_basic_codec[eet_type - 1].put(ed, tmp, &type_size);
1396 // free temporary string as it is not needed anymore
1397 if (v2s) free(*(char**)tmp);
1399 // pack data with type first, then the data
1400 *size_ret = int_size + type_size;
1401 tmp = malloc(*size_ret);
1402 memcpy(tmp, int_data, int_size);
1403 memcpy(((char*)tmp) + int_size, type_data, type_size);
1412 eet_data_get_type(const Eet_Dictionary *ed,
1415 const void *src_end,
1420 ret = eet_basic_codec[type - 1].get(ed, src, src_end, dest);
1424 static inline void *
1425 eet_data_put_type(Eet_Dictionary *ed,
1432 ret = eet_basic_codec[type - 1].put(ed, src, size_ret);
1436 static inline Eina_Bool
1437 eet_data_type_match(int type1,
1443 /* Note: All floating point type are equivalent and could be read
1444 without problem by any other floating point getter. */
1475 * char[4] = "CHnK"; // untyped data ... or
1476 * char[4] = "CHKx"; // typed data - x == type
1478 * int = chunk size (including magic string);
1479 * char[] = chunk magic/name string (0 byte terminated);
1480 * ... sub-chunks (a chunk can contain chuncks recusrively) ...
1482 * ... payload data ...
1487 eet_data_chunk_get(const Eet_Dictionary *ed,
1488 Eet_Data_Chunk *chnk,
1507 if ((s[0] != 'C') || (s[1] != 'H') || (s[2] != 'K'))
1510 chnk->type = (unsigned char)(s[3]);
1511 if (chnk->type >= EET_I_LIMIT)
1514 ((chnk->type - EET_I_LIMIT) & 0xF) + EET_G_UNKNOWN;
1515 switch ((chnk->type - EET_I_LIMIT) & 0xF0)
1517 #define EET_UNMATCH_TYPE(Type) \
1518 case EET_I_ ## Type: chnk->type = EET_T_ ## Type; break;
1520 EET_UNMATCH_TYPE(STRING);
1521 EET_UNMATCH_TYPE(INLINED_STRING);
1522 EET_UNMATCH_TYPE(NULL);
1528 else if (chnk->type > EET_T_LAST)
1530 chnk->group_type = chnk->type;
1531 chnk->type = EET_T_UNKNOW;
1534 chnk->group_type = EET_G_UNKNOWN;
1535 if ((chnk->type >= EET_T_LAST) ||
1536 (chnk->group_type >=
1540 chnk->group_type = 0;
1543 else if ((s[0] != 'C') || (s[1] != 'H') || (s[2] != 'n') || (s[3] != 'K'))
1546 ret1 = eet_data_get_type(ed, EET_T_INT, (s + 4), (s + size), &(chnk->size));
1551 if ((chnk->size < 0) || ((chnk->size + 8) > size))
1554 ret2 = eet_data_get_type(ed, EET_T_STRING, (s + 8), (s + size), &(chnk->name));
1562 chnk->hash = eet_data_get_string_hash(ed, (s + 8), (s + size));
1566 chnk->data = (char *)src + 4 + ret1 + sizeof(int);
1567 chnk->size -= sizeof(int);
1571 chnk->data = (char *)src + 4 + ret1 + chnk->len;
1572 chnk->size -= chnk->len;
1578 static inline Eet_Data_Chunk *
1579 eet_data_chunk_new(void *data,
1585 Eet_Data_Chunk *chnk;
1590 chnk = calloc(1, sizeof(Eet_Data_Chunk));
1594 /* Note: Another security, so older eet library could read file
1595 saved with fixed point value. */
1596 if (type == EET_T_F32P32
1597 || type == EET_T_F16P16
1598 || type == EET_T_F8P24)
1599 type = EET_T_DOUBLE;
1602 chnk->len = strlen(name) + 1;
1606 chnk->group_type = group_type;
1611 eet_data_chunk_free(Eet_Data_Chunk *chnk)
1616 static inline Eet_Data_Stream *
1617 eet_data_stream_new(void)
1619 Eet_Data_Stream *ds;
1621 ds = calloc(1, sizeof(Eet_Data_Stream));
1629 eet_data_stream_free(Eet_Data_Stream *ds)
1638 eet_data_stream_flush(Eet_Data_Stream *ds)
1644 eet_data_stream_write(Eet_Data_Stream *ds,
1650 if ((ds->pos + size) > ds->size)
1652 ds->data = realloc(ds->data, ds->size + size + 512);
1660 ds->size = ds->size + size + 512;
1664 memcpy(p + ds->pos, data, size);
1669 eet_data_chunk_put(Eet_Dictionary *ed,
1670 Eet_Data_Chunk *chnk,
1671 Eet_Data_Stream *ds)
1678 unsigned char buf[4] = "CHK";
1680 /* disable this check - it will allow empty chunks to be written. this is
1681 * right for corner-cases when y have a struct with empty fields (empty
1682 * strings or empty list ptrs etc.) */
1683 /* if (!chnk->data && chnk->type != EET_T_NULL) return; */
1686 /* eet_data_stream_write(ds, "CHnK", 4);*/
1687 if (chnk->type != EET_T_UNKNOW)
1689 if (chnk->group_type != EET_G_UNKNOWN)
1691 int type = EET_I_LIMIT + chnk->group_type - EET_G_UNKNOWN;
1695 /* Only make sense with pointer type. */
1696 #define EET_MATCH_TYPE(Type) \
1697 case EET_T_ ## Type: type += EET_I_ ## Type; break;
1699 EET_MATCH_TYPE(STRING);
1700 EET_MATCH_TYPE(INLINED_STRING);
1701 EET_MATCH_TYPE(NULL);
1710 buf[3] = chnk->type;
1713 buf[3] = chnk->group_type;
1715 string = eet_data_put_string(ed, &chnk->name, &string_ret);
1719 /* size of chunk payload data + name */
1720 s = chnk->size + string_ret;
1721 size = eet_data_put_int(ed, &s, &size_ret);
1723 /* FIXME: If something goes wrong the resulting file will be corrupted. */
1727 eet_data_stream_write(ds, buf, 4);
1729 /* write chunk length */
1730 eet_data_stream_write(ds, size, size_ret);
1732 /* write chunk name */
1733 eet_data_stream_write(ds, string, string_ret);
1737 eet_data_stream_write(ds, chnk->data, chnk->size);
1747 _eet_descriptor_hash_new(Eet_Data_Descriptor *edd)
1751 edd->elements.hash.size = 1 << 6;
1752 edd->elements.hash.buckets = calloc(
1754 sizeof(Eet_Data_Descriptor_Hash) *
1755 edd->elements.hash.size);
1756 for (i = 0; i < edd->elements.num; i++)
1758 Eet_Data_Element *ede;
1761 ede = &(edd->elements.set[i]);
1762 hash = _eet_hash_gen((char *)ede->name, 6);
1763 if (!edd->elements.hash.buckets[hash].element)
1764 edd->elements.hash.buckets[hash].element = ede;
1767 Eet_Data_Descriptor_Hash *bucket;
1769 bucket = calloc(1, sizeof(Eet_Data_Descriptor_Hash));
1770 bucket->element = ede;
1771 bucket->next = edd->elements.hash.buckets[hash].next;
1772 edd->elements.hash.buckets[hash].next = bucket;
1778 _eet_descriptor_hash_free(Eet_Data_Descriptor *edd)
1782 for (i = 0; i < edd->elements.hash.size; i++)
1784 Eet_Data_Descriptor_Hash *bucket, *pbucket;
1786 bucket = edd->elements.hash.buckets[i].next;
1790 bucket = bucket->next;
1794 if (edd->elements.hash.buckets)
1795 free(edd->elements.hash.buckets);
1798 static Eet_Data_Element *
1799 _eet_descriptor_hash_find(Eet_Data_Descriptor *edd,
1803 Eet_Data_Descriptor_Hash *bucket;
1806 hash = _eet_hash_gen(name, 6);
1810 if (!edd->elements.hash.buckets[hash].element)
1812 When we use the dictionary as a source for chunk name, we will always
1813 have the same pointer in name. It's a good idea to just compare pointer
1814 instead of running strcmp on both string.
1817 if (edd->elements.hash.buckets[hash].element->directory_name_ptr == name)
1818 return edd->elements.hash.buckets[hash].element;
1820 if (!strcmp(edd->elements.hash.buckets[hash].element->name, name))
1822 edd->elements.hash.buckets[hash].element->directory_name_ptr = name;
1823 return edd->elements.hash.buckets[hash].element;
1826 bucket = edd->elements.hash.buckets[hash].next;
1829 if (bucket->element->directory_name_ptr == name)
1830 return bucket->element;
1832 if (!strcmp(bucket->element->name, name))
1834 bucket->element->directory_name_ptr = name;
1835 return bucket->element;
1838 bucket = bucket->next;
1844 _eet_mem_alloc(size_t size)
1846 return calloc(1, size);
1850 _eet_mem_free(void *mem)
1856 _eet_str_alloc(const char *str)
1862 _eet_str_free(const char *str)
1868 _eet_eina_hash_add_alloc(Eina_Hash *hash,
1873 hash = eina_hash_string_small_new(NULL);
1878 eina_hash_add(hash, key, data);
1883 _eet_eina_hash_direct_add_alloc(Eina_Hash *hash,
1888 hash = eina_hash_string_small_new(NULL);
1893 eina_hash_direct_add(hash, key, data);
1898 _eet_str_direct_alloc(const char *str)
1904 _eet_str_direct_free(const char *str EINA_UNUSED)
1909 _eet_eina_hash_foreach(void *hash,
1910 Eina_Hash_Foreach cb,
1914 eina_hash_foreach(hash, cb, fdata);
1918 _eet_eina_hash_free(void *hash)
1921 eina_hash_free(hash);
1926 eet_eina_stream_data_descriptor_class_set(Eet_Data_Descriptor_Class *eddc,
1927 /* When we change the structure content in the future, we need to handle old structure type too */
1928 unsigned int eddc_size,
1932 if (!eddc || !name || eddc_size != sizeof (Eet_Data_Descriptor_Class))
1937 eddc->version = EET_DATA_DESCRIPTOR_CLASS_VERSION;
1939 eddc->func.mem_alloc = _eet_mem_alloc;
1940 eddc->func.mem_free = _eet_mem_free;
1941 eddc->func.str_alloc = (char *(*)(const char *))eina_stringshare_add;
1942 eddc->func.str_free = eina_stringshare_del;
1943 eddc->func.list_next = (void *(*)(void *))eina_list_next;
1944 eddc->func.list_append = (void *(*)(void *, void *))eina_list_append;
1945 eddc->func.list_data = (void *(*)(void *))eina_list_data_get;
1946 eddc->func.list_free = (void *(*)(void *))eina_list_free;
1947 eddc->func.hash_foreach = (void (*)(void *, int (*)(void *, const char *, void *, void *), void *))_eet_eina_hash_foreach;
1948 eddc->func.hash_add = (void *(*)(void *, const char *, void *))_eet_eina_hash_add_alloc;
1949 eddc->func.hash_free = (void (*)(void *))_eet_eina_hash_free;
1951 /* This will cause an ABI incompatibility */
1952 eddc->func.array_alloc = _eet_mem_alloc;
1953 eddc->func.array_free = _eet_mem_free;
1959 eet_eina_file_data_descriptor_class_set(Eet_Data_Descriptor_Class *eddc,
1960 /* When we change the structure content in the future, we need to handle old structure type too */
1961 unsigned int eddc_size,
1965 if (!eet_eina_stream_data_descriptor_class_set(eddc, eddc_size, name, size))
1968 eddc->version = EET_DATA_DESCRIPTOR_CLASS_VERSION;
1970 eddc->func.hash_add = (void *(*)(void *, const char *, void *))_eet_eina_hash_direct_add_alloc;
1971 eddc->func.str_direct_alloc = _eet_str_direct_alloc;
1972 eddc->func.str_direct_free = _eet_str_direct_free;
1977 static Eet_Data_Descriptor *
1978 _eet_data_descriptor_new(const Eet_Data_Descriptor_Class *eddc,
1981 Eet_Data_Descriptor *edd;
1986 edd = calloc(1, sizeof (Eet_Data_Descriptor));
1990 edd->name = eddc->name;
1992 edd->size = eddc->size;
1993 edd->func.mem_alloc = _eet_mem_alloc;
1994 edd->func.mem_free = _eet_mem_free;
1995 edd->func.str_alloc = _eet_str_alloc;
1996 edd->func.str_free = _eet_str_free;
1997 if (eddc->func.mem_alloc)
1998 edd->func.mem_alloc = eddc->func.mem_alloc;
2000 if (eddc->func.mem_free)
2001 edd->func.mem_free = eddc->func.mem_free;
2003 if (eddc->func.str_alloc)
2004 edd->func.str_alloc = eddc->func.str_alloc;
2006 if (eddc->func.str_free)
2007 edd->func.str_free = eddc->func.str_free;
2009 edd->func.list_next = eddc->func.list_next;
2010 edd->func.list_append = eddc->func.list_append;
2011 edd->func.list_data = eddc->func.list_data;
2012 edd->func.list_free = eddc->func.list_free;
2013 edd->func.hash_foreach = eddc->func.hash_foreach;
2014 edd->func.hash_add = eddc->func.hash_add;
2015 edd->func.hash_free = eddc->func.hash_free;
2017 if (eddc->version > 1 && version > 1)
2019 edd->func.str_direct_alloc = eddc->func.str_direct_alloc;
2020 edd->func.str_direct_free = eddc->func.str_direct_free;
2023 if (eddc->version > 2)
2025 edd->func.type_get = eddc->func.type_get;
2026 edd->func.type_set = eddc->func.type_set;
2029 if (eddc->version > 3)
2031 edd->func.array_alloc = eddc->func.array_alloc;
2032 edd->func.array_free = eddc->func.array_free;
2038 EAPI Eet_Data_Descriptor *
2039 eet_data_descriptor_new(const char *name,
2041 Eet_Descriptor_List_Next_Callback func_list_next,
2042 Eet_Descriptor_List_Append_Callback func_list_append,
2043 Eet_Descriptor_List_Data_Callback func_list_data,
2044 Eet_Descriptor_List_Free_Callback func_list_free,
2045 Eet_Descriptor_Hash_Foreach_Callback func_hash_foreach,
2046 Eet_Descriptor_Hash_Add_Callback func_hash_add,
2047 Eet_Descriptor_Hash_Free_Callback func_hash_free)
2049 Eet_Data_Descriptor_Class eddc;
2054 memset(&eddc, 0, sizeof (Eet_Data_Descriptor_Class));
2060 eddc.func.list_next = func_list_next;
2061 eddc.func.list_append = func_list_append;
2062 eddc.func.list_data = func_list_data;
2063 eddc.func.list_free = func_list_free;
2064 eddc.func.hash_foreach = func_hash_foreach;
2065 eddc.func.hash_add = func_hash_add;
2066 eddc.func.hash_free = func_hash_free;
2068 return _eet_data_descriptor_new(&eddc, 0);
2071 EAPI Eet_Data_Descriptor *
2072 eet_data_descriptor2_new(const Eet_Data_Descriptor_Class *eddc)
2074 return _eet_data_descriptor_new(eddc, 1);
2077 EAPI Eet_Data_Descriptor *
2078 eet_data_descriptor3_new(const Eet_Data_Descriptor_Class *eddc)
2080 return _eet_data_descriptor_new(eddc, 2);
2083 EAPI Eet_Data_Descriptor *
2084 eet_data_descriptor_stream_new(const Eet_Data_Descriptor_Class *eddc)
2086 return _eet_data_descriptor_new(eddc, 1);
2089 EAPI Eet_Data_Descriptor *
2090 eet_data_descriptor_file_new(const Eet_Data_Descriptor_Class *eddc)
2092 return _eet_data_descriptor_new(eddc, 2);
2096 eet_data_descriptor_name_get(const Eet_Data_Descriptor *edd)
2098 EINA_SAFETY_ON_NULL_RETURN_VAL(edd, NULL);
2104 eet_data_descriptor_free(Eet_Data_Descriptor *edd)
2109 _eet_descriptor_hash_free(edd);
2110 if (edd->elements.set)
2111 free(edd->elements.set);
2117 eet_data_descriptor_element_add(Eet_Data_Descriptor *edd,
2123 /* int counter_offset, */
2124 const char *counter_name /* FIXME: Useless should go on a major release */,
2125 Eet_Data_Descriptor *subtype)
2127 Eet_Data_Element *ede;
2128 Eet_Data_Element *tmp;
2130 EINA_SAFETY_ON_NULL_RETURN(edd);
2132 /* Sanity check to avoid crash later at runtime */
2133 if (type < EET_T_UNKNOW ||
2136 CRI("Preventing later bug due to unknow type: %i", type);
2141 CRI("Preventing later buffer underrun : offset = %i", offset);
2144 if (offset > edd->size)
2146 CRI("Preventing later buffer overrun : offset = %i in a structure of %i bytes", offset, edd->size);
2149 if (group_type == EET_G_UNKNOWN && type != EET_T_UNKNOW)
2151 if (offset + eet_basic_codec[type - 1].size > edd->size)
2153 CRI("Preventing later buffer overrun : offset = %i, size = %i in a structure of %i bytes", offset, eet_basic_codec[type - 1].size, edd->size);
2157 else if ((offset + sizeof (void*)) > (unsigned int) edd->size)
2159 CRI("Preventing later buffer overrun : offset = %i, estimated size = %zu in a structure of %i bytes", offset, sizeof (void*), edd->size);
2163 /* UNION, VARIANT type would not work with simple type, we need a way to map the type. */
2164 if ((group_type == EET_G_UNION
2165 || group_type == EET_G_VARIANT)
2167 (type != EET_T_UNKNOW
2169 || !subtype->func.type_get
2170 || !subtype->func.type_set))
2173 /* VARIANT type will only work if the map only contains EET_G_*, but not UNION, VARIANT and ARRAY. */
2174 if (group_type == EET_G_VARIANT)
2178 for (i = 0; i < subtype->elements.num; ++i)
2179 if (subtype->elements.set[i].type != EET_T_UNKNOW
2180 && subtype->elements.set[i].group_type > EET_G_VAR_ARRAY
2181 && subtype->elements.set[i].group_type < EET_G_UNION)
2184 subtype->unified_type = EINA_TRUE;
2188 && subtype->unified_type
2189 && (type != EET_T_UNKNOW
2190 || group_type < EET_G_UNION))
2193 /* Sanity check done, let allocate ! */
2194 edd->elements.num++;
2195 tmp = realloc(edd->elements.set, edd->elements.num * sizeof(Eet_Data_Element));
2199 edd->elements.set = tmp;
2200 ede = &(edd->elements.set[edd->elements.num - 1]);
2202 ede->directory_name_ptr = NULL;
2205 * We do a special case when we do list,hash or whatever group of simple type.
2206 * Instead of handling it in encode/decode/dump/undump, we create an
2207 * implicit structure with only the simple type.
2209 if ((group_type > EET_G_UNKNOWN)
2210 && (group_type < EET_G_LAST)
2211 && (((type > EET_T_UNKNOW) && (type < EET_T_STRING))
2212 || ((type > EET_T_NULL) && (type < EET_T_LAST)))
2215 subtype = calloc(1, sizeof (Eet_Data_Descriptor));
2219 subtype->name = "implicit";
2220 subtype->size = eet_basic_codec[type - 1].size;
2221 memcpy(&subtype->func, &edd->func, sizeof(subtype->func));
2223 eet_data_descriptor_element_add(subtype,
2224 eet_basic_codec[type - 1].name,
2231 type = EET_T_UNKNOW;
2235 ede->group_type = group_type;
2236 ede->offset = offset;
2238 /* FIXME: For the time being, VAR_ARRAY, UNION and VARIANT will put the counter_offset in count. */
2239 ede->counter_offset = count;
2240 /* ede->counter_offset = counter_offset; */
2241 ede->counter_name = counter_name;
2244 INF("Adding '%s' of size %i to '%s' at offset %i.",
2245 subtype->name, subtype->size,
2248 ede->subtype = subtype;
2252 eet_data_read_cipher(Eet_File *ef,
2253 Eet_Data_Descriptor *edd,
2255 const char *cipher_key)
2257 const Eet_Dictionary *ed = NULL;
2258 const void *data = NULL;
2260 Eet_Free_Context context;
2261 int required_free = 0;
2264 ed = eet_dictionary_get(ef);
2267 data = eet_read_direct(ef, name, &size);
2272 data = eet_read_cipher(ef, name, &size, cipher_key);
2277 eet_free_context_init(&context);
2278 data_dec = _eet_data_descriptor_decode(&context, ed, edd, data, size, NULL, 0);
2279 eet_free_context_shutdown(&context);
2288 eet_data_read_cipher_buffer(Eet_File *ef,
2289 Eet_Data_Descriptor *edd,
2291 const char *cipher_key,
2295 const Eet_Dictionary *ed = NULL;
2296 const void *data = NULL;
2298 Eet_Free_Context context;
2299 int required_free = 0;
2302 ed = eet_dictionary_get(ef);
2305 data = eet_read_direct(ef, name, &size);
2310 data = eet_read_cipher(ef, name, &size, cipher_key);
2315 eet_free_context_init(&context);
2316 data_dec = _eet_data_descriptor_decode(&context, ed, edd, data, size, buffer, buffer_size);
2317 eet_free_context_shutdown(&context);
2326 eet_data_node_read_cipher(Eet_File *ef,
2328 const char *cipher_key)
2330 const Eet_Dictionary *ed = NULL;
2331 const void *data = NULL;
2333 Eet_Free_Context context;
2334 int required_free = 0;
2337 ed = eet_dictionary_get(ef);
2340 data = eet_read_direct(ef, name, &size);
2345 data = eet_read_cipher(ef, name, &size, cipher_key);
2350 eet_free_context_init(&context);
2351 result = _eet_data_descriptor_decode(&context, ed, NULL, data, size, NULL, 0);
2352 eet_free_context_shutdown(&context);
2361 eet_data_read(Eet_File *ef,
2362 Eet_Data_Descriptor *edd,
2365 return eet_data_read_cipher(ef, edd, name, NULL);
2369 eet_data_write_cipher(Eet_File *ef,
2370 Eet_Data_Descriptor *edd,
2372 const char *cipher_key,
2381 EINA_SAFETY_ON_NULL_RETURN_VAL(edd, 0);
2383 ed = eet_dictionary_get(ef);
2385 data_enc = _eet_data_descriptor_encode(ed, edd, data, &size);
2389 val = eet_write_cipher(ef, name, data_enc, size, comp, cipher_key);
2395 eet_data_write(Eet_File *ef,
2396 Eet_Data_Descriptor *edd,
2401 return eet_data_write_cipher(ef, edd, name, NULL, data, comp);
2405 eet_free_context_init(Eet_Free_Context *context)
2409 memset(context, 0, sizeof (Eet_Free_Context));
2410 for (i = 0; i < EET_FREE_COUNT; ++i)
2412 eina_array_step_set(&context->freelist.list[i],
2413 sizeof (context->freelist.list[i]),
2415 eina_array_step_set(&context->freelist_array.list[i],
2416 sizeof (context->freelist.list[i]),
2418 eina_array_step_set(&context->freelist_list.list[i],
2419 sizeof (context->freelist.list[i]),
2421 eina_array_step_set(&context->freelist_hash.list[i],
2422 sizeof (context->freelist.list[i]),
2424 eina_array_step_set(&context->freelist_str.list[i],
2425 sizeof (context->freelist.list[i]),
2427 eina_array_step_set(&context->freelist_direct_str.list[i],
2428 sizeof (context->freelist.list[i]),
2434 eet_free_context_shutdown(Eet_Free_Context *context)
2438 for (i = 0; i < EET_FREE_COUNT; ++i)
2440 eina_array_flush(&context->freelist.list[i]);
2441 eina_array_flush(&context->freelist_array.list[i]);
2442 eina_array_flush(&context->freelist_list.list[i]);
2443 eina_array_flush(&context->freelist_hash.list[i]);
2444 eina_array_flush(&context->freelist_str.list[i]);
2445 eina_array_flush(&context->freelist_direct_str.list[i]);
2450 _eet_free_hash(void *data)
2453 __int64 ptr = (UINT_PTR)data;
2454 #else /* ifdef _WIN64 */
2455 unsigned long ptr = (unsigned long)(data);
2456 #endif /* ifdef _WIN64 */
2464 #if defined (_WIN64) || ((!defined (_WIN32)) && (LONG_BIT != 32))
2469 #endif /* if defined (_WIN64) || ((!defined (_WIN32)) && (LONG_BIT != 32)) */
2475 _eet_free_add(Eet_Free *ef,
2479 Eina_Array_Iterator it;
2483 hash = _eet_free_hash(data);
2485 EINA_ARRAY_ITER_NEXT(&ef->list[hash], i, track, it)
2489 eina_array_push(&ef->list[hash], data);
2494 _eet_free_del(Eet_Free *ef,
2498 Eina_Array_Iterator it;
2502 hash = _eet_free_hash(data);
2504 EINA_ARRAY_ITER_NEXT(&ef->list[hash], i, track, it)
2507 eina_array_data_set(&ef->list[hash], i, NULL);
2515 _eet_free_reset(Eet_Free *ef)
2522 for (i = 0; i < EET_FREE_COUNT; ++i)
2523 eina_array_clean(&ef->list[i]);
2527 _eet_free_ref(Eet_Free *ef)
2533 _eet_free_unref(Eet_Free *ef)
2538 #define _eet_freelist_add(Ctx, Data) _eet_free_add(&Ctx->freelist, Data);
2539 #define _eet_freelist_del(Ctx, Data) _eet_free_del(&Ctx->freelist, Data);
2540 #define _eet_freelist_reset(Ctx) _eet_free_reset(&Ctx->freelist);
2541 #define _eet_freelist_ref(Ctx) _eet_free_ref(&Ctx->freelist);
2542 #define _eet_freelist_unref(Ctx) _eet_free_unref(&Ctx->freelist);
2545 _eet_freelist_free(Eet_Free_Context *context,
2546 Eet_Data_Descriptor *edd)
2549 Eina_Array_Iterator it;
2553 if (context->freelist.ref > 0)
2556 for (j = 0; j < EET_FREE_COUNT; ++j)
2557 EINA_ARRAY_ITER_NEXT(&context->freelist.list[j], i, track, it)
2561 edd->func.mem_free(track);
2565 _eet_free_reset(&context->freelist);
2568 #define _eet_freelist_array_add(Ctx, Data) _eet_free_add(&Ctx->freelist_array, Data);
2569 #define _eet_freelist_array_del(Ctx, Data) _eet_free_del(&Ctx->freelist_array, Data);
2570 #define _eet_freelist_array_reset(Ctx) _eet_free_reset(&Ctx->freelist_array);
2571 #define _eet_freelist_array_ref(Ctx) _eet_free_ref(&Ctx->freelist_array);
2572 #define _eet_freelist_array_unref(Ctx) _eet_free_unref(&Ctx->freelist_array);
2575 _eet_freelist_array_free(Eet_Free_Context *context,
2576 Eet_Data_Descriptor *edd)
2579 Eina_Array_Iterator it;
2583 if (context->freelist_array.ref > 0)
2586 for (j = 0; j < EET_FREE_COUNT; ++j)
2587 EINA_ARRAY_ITER_NEXT(&context->freelist_array.list[j], i, track, it)
2592 if (edd->func.array_free)
2593 edd->func.array_free(track);
2595 edd->func.mem_free(track);
2600 _eet_free_reset(&context->freelist_array);
2603 #define _eet_freelist_list_add(Ctx, Data) _eet_free_add(&Ctx->freelist_list, Data);
2604 #define _eet_freelist_list_del(Ctx, Data) _eet_free_del(&Ctx->freelist_list, Data);
2605 #define _eet_freelist_list_reset(Ctx) _eet_free_reset(&Ctx->freelist_list);
2606 #define _eet_freelist_list_ref(Ctx) _eet_free_ref(&Ctx->freelist_list);
2607 #define _eet_freelist_list_unref(Ctx) _eet_free_unref(&Ctx->freelist_list);
2610 _eet_freelist_list_free(Eet_Free_Context *context,
2611 Eet_Data_Descriptor *edd)
2614 Eina_Array_Iterator it;
2618 if (context->freelist_list.ref > 0)
2621 for (j = 0; j < EET_FREE_COUNT; ++j)
2622 EINA_ARRAY_ITER_NEXT(&context->freelist_list.list[j], i, track, it)
2626 edd->func.list_free(*((void **)(track)));
2628 _eet_free_reset(&context->freelist_list);
2631 #define _eet_freelist_str_add(Ctx, Data) _eet_free_add(&Ctx->freelist_str, Data);
2632 #define _eet_freelist_str_del(Ctx, Data) _eet_free_del(&Ctx->freelist_str, Data);
2633 #define _eet_freelist_str_reset(Ctx) _eet_free_reset(&Ctx->freelist_str);
2634 #define _eet_freelist_str_ref(Ctx) _eet_free_ref(&Ctx->freelist_str);
2635 #define _eet_freelist_str_unref(Ctx) _eet_free_unref(&Ctx->freelist_str);
2638 _eet_freelist_str_free(Eet_Free_Context *context,
2639 Eet_Data_Descriptor *edd)
2642 Eina_Array_Iterator it;
2646 if (context->freelist_str.ref > 0)
2649 for (j = 0; j < EET_FREE_COUNT; ++j)
2650 EINA_ARRAY_ITER_NEXT(&context->freelist_str.list[j], i, track, it)
2654 edd->func.str_free(track);
2658 _eet_free_reset(&context->freelist_str);
2661 #define _eet_freelist_direct_str_add(Ctx, Data) _eet_free_add(&Ctx->freelist_direct_str, Data);
2662 #define _eet_freelist_direct_str_del(Ctx, Data) _eet_free_del(&Ctx->freelist_direct_str, Data);
2663 #define _eet_freelist_direct_str_reset(Ctx) _eet_free_reset(&Ctx->freelist_direct_str);
2664 #define _eet_freelist_direct_str_ref(Ctx) _eet_free_ref(&Ctx->freelist_direct_str);
2665 #define _eet_freelist_direct_str_unref(Ctx) _eet_free_unref(&Ctx->freelist_direct_str);
2668 _eet_freelist_direct_str_free(Eet_Free_Context *context,
2669 Eet_Data_Descriptor *edd)
2672 Eina_Array_Iterator it;
2676 if (context->freelist_direct_str.ref > 0)
2679 for (j = 0; j < EET_FREE_COUNT; ++j)
2680 EINA_ARRAY_ITER_NEXT(&context->freelist_str.list[j], i, track, it)
2684 edd->func.str_direct_free(track);
2688 _eet_free_reset(&context->freelist_direct_str);
2691 #define _eet_freelist_hash_add(Ctx, Data) _eet_free_add(&Ctx->freelist_hash, Data);
2692 #define _eet_freelist_hash_del(Ctx, Data) _eet_free_del(&Ctx->freelist_hash, Data);
2693 #define _eet_freelist_hash_reset(Ctx) _eet_free_reset(&Ctx->freelist_hash);
2694 #define _eet_freelist_hash_ref(Ctx) _eet_free_ref(&Ctx->freelist_hash);
2695 #define _eet_freelist_hash_unref(Ctx) _eet_free_unref(&Ctx->freelist_hash);
2698 _eet_freelist_hash_free(Eet_Free_Context *context,
2699 Eet_Data_Descriptor *edd)
2702 Eina_Array_Iterator it;
2706 if (context->freelist_hash.ref > 0)
2709 for (j = 0; j < EET_FREE_COUNT; ++j)
2710 EINA_ARRAY_ITER_NEXT(&context->freelist_hash.list[j], i, track, it)
2714 edd->func.hash_free(track);
2718 _eet_free_reset(&context->freelist_hash);
2722 _eet_freelist_all_ref(Eet_Free_Context *freelist_context)
2724 _eet_freelist_ref(freelist_context);
2725 _eet_freelist_str_ref(freelist_context);
2726 _eet_freelist_list_ref(freelist_context);
2727 _eet_freelist_hash_ref(freelist_context);
2728 _eet_freelist_direct_str_ref(freelist_context);
2732 _eet_freelist_all_unref(Eet_Free_Context *freelist_context)
2734 _eet_freelist_unref(freelist_context);
2735 _eet_freelist_str_unref(freelist_context);
2736 _eet_freelist_list_unref(freelist_context);
2737 _eet_freelist_hash_unref(freelist_context);
2738 _eet_freelist_direct_str_unref(freelist_context);
2742 eet_data_descriptor_encode_hash_cb(void *hash EINA_UNUSED,
2743 const char *cipher_key,
2748 Eet_Data_Encode_Hash_Info *edehi;
2749 Eet_Data_Stream *ds;
2750 Eet_Data_Element *ede;
2751 Eet_Data_Chunk *echnk;
2761 data = eet_data_put_type(ed,
2767 echnk = eet_data_chunk_new(data,
2772 eet_data_chunk_put(ed, echnk, ds);
2773 eet_data_chunk_free(echnk);
2778 EET_ASSERT(!((ede->type > EET_T_UNKNOW) && (ede->type < EET_T_STRING)), return );
2781 if (ede->type >= EET_T_STRING)
2782 eet_data_put_unknown(ed, NULL, ede, ds, &hdata);
2786 data = _eet_data_descriptor_encode(ed,
2793 echnk = eet_data_chunk_new(data,
2798 eet_data_chunk_put(ed, echnk, ds);
2799 eet_data_chunk_free(echnk);
2809 _eet_data_dump_token_get(const char *src,
2817 int tlen = 0, tsize = 0;
2819 #define TOK_ADD(x) \
2822 if (tlen >= tsize) \
2825 tok = realloc(tok, tsize); \
2827 tok[tlen - 1] = x; \
2830 for (p = src; *len > 0; p++, (*len)--)
2846 ERR("Unknow escape character %#x (%c). Append as is",
2852 else if (p[0] == '\\')
2869 if ((isspace(p[0])) || (p[0] == ';')) /* token ends here */
2880 else if (!((isspace(p[0])) || (p[0] == ';')))
2900 eet_data_encode(Eet_Dictionary *ed,
2901 Eet_Data_Stream *ds,
2907 Eina_Bool free_data)
2909 Eet_Data_Chunk *echnk;
2914 if (group_type != EET_G_UNKNOWN)
2915 if (type >= EET_T_LAST)
2916 type = EET_T_UNKNOW;
2918 echnk = eet_data_chunk_new(data, size, name, type, group_type);
2919 eet_data_chunk_put(ed, echnk, ds);
2920 eet_data_chunk_free(echnk);
2921 if (free_data) free(data);
2925 _eet_data_dump_encode(int parent_type,
2930 Eet_Data_Chunk *chnk = NULL;
2931 Eet_Data_Stream *ds;
2938 if (_eet_data_words_bigendian == -1)
2940 unsigned long int v;
2942 v = htonl(0x12345678);
2943 if (v == 0x12345678)
2944 _eet_data_words_bigendian = 1;
2946 _eet_data_words_bigendian = 0;
2952 ds = eet_data_stream_new();
2959 for (n = node->values; n; n = n->next)
2961 data = _eet_data_dump_encode(node->type, ed, n, &size);
2964 eet_data_stream_write(ds, data, size);
2971 case EET_G_VAR_ARRAY:
2972 for (child_type = EET_T_NULL, n = node->values; n; n = n->next)
2974 if (n->type != EET_T_NULL)
2976 child_type = n->type;
2981 data = eet_data_put_type(ed,
2994 count = node->count;
2996 for (n = node->values; n; n = n->next)
3003 case EET_T_INLINED_STRING:
3004 data = eet_data_put_type(ed,
3006 &(n->data.value.str),
3025 data = _eet_data_dump_encode(n->type, ed, n, &size);
3040 for (; count; count--)
3052 /* Array is somekind of special case, so we should embed it inside another chunk. */
3053 *size_ret = ds->pos;
3058 eet_data_stream_free(ds);
3064 for (n = node->values; n; n = n->next)
3069 case EET_T_INLINED_STRING:
3070 data = eet_data_put_type(ed,
3072 &(n->data.value.str),
3091 data = _eet_data_dump_encode(node->type, ed, n, &size);
3103 /* List is another somekind of special case, every chunk is embed inside a list chunk. */
3104 *size_ret = ds->pos;
3109 eet_data_stream_free(ds);
3117 data = eet_data_put_type(ed,
3132 /* A Hash without key will not decode correctly. */
3136 eet_data_stream_free(ds);
3141 for (n = node->values; n; n = n->next)
3146 case EET_T_INLINED_STRING:
3147 data = eet_data_put_type(ed,
3149 &(n->data.value.str),
3168 data = _eet_data_dump_encode(node->type, ed, n, &size);
3180 /* Hash is somekind of special case, so we should embed it inside another chunk. */
3181 *size_ret = ds->pos;
3184 eet_data_stream_flush(ds);
3192 #define EET_DATA_NODE_ENCODE(Eet_Type, Type) \
3194 data = eet_data_put_type(ed, node->type, &(node->data.value.Type), &size); \
3197 eet_data_encode(ed, \
3206 *size_ret = ds->pos; \
3207 eet_data_stream_flush(ds); \
3212 EET_DATA_NODE_ENCODE(EET_T_CHAR, c);
3213 EET_DATA_NODE_ENCODE(EET_T_SHORT, s);
3214 EET_DATA_NODE_ENCODE(EET_T_INT, i);
3215 EET_DATA_NODE_ENCODE(EET_T_LONG_LONG, l);
3216 EET_DATA_NODE_ENCODE(EET_T_FLOAT, f);
3217 EET_DATA_NODE_ENCODE(EET_T_DOUBLE, d);
3218 EET_DATA_NODE_ENCODE(EET_T_UCHAR, uc);
3219 EET_DATA_NODE_ENCODE(EET_T_USHORT, us);
3220 EET_DATA_NODE_ENCODE(EET_T_UINT, ui);
3221 EET_DATA_NODE_ENCODE(EET_T_ULONG_LONG, ul);
3222 EET_DATA_NODE_ENCODE(EET_T_INLINED_STRING, str);
3223 EET_DATA_NODE_ENCODE(EET_T_STRING, str);
3229 if ((node->type >= EET_G_UNKNOWN) && (node->type < EET_G_LAST))
3230 chnk = eet_data_chunk_new(ds->data,
3236 chnk = eet_data_chunk_new(ds->data,
3242 eet_data_stream_flush(ds);
3244 ds = eet_data_stream_new();
3245 eet_data_chunk_put(ed, chnk, ds);
3249 eet_data_stream_flush(ds);
3253 eet_data_chunk_free(chnk);
3259 _eet_data_dump_parse(Eet_Dictionary *ed,
3265 const char *p = NULL;
3270 Eet_Node *node_base = NULL;
3271 Eet_Node *node = NULL;
3272 Eet_Node *n = NULL, *nn = NULL;
3274 /* FIXME; handle parse errors */
3275 #define TOK_GET(t) \
3276 jump = left; t = _eet_data_dump_token_get(p, &left); p += jump - left;
3278 for (p = src; p < (src + size); )
3280 char *tok1, *tok2, *tok3, *tok4;
3285 if (!strcmp(tok1, "group"))
3296 if (!strcmp(tok4, "{"))
3298 /* we have 'group NAM TYP {' */
3312 for (nn = node->values; nn;
3323 n->name = eina_stringshare_add(tok2);
3324 if (!strcmp(tok3, "struct"))
3325 n->type = EET_G_UNKNOWN;
3326 else if (!strcmp(tok3, "array"))
3327 n->type = EET_G_ARRAY;
3328 else if (!strcmp(tok3, "var_array"))
3329 n->type = EET_G_VAR_ARRAY;
3330 else if (!strcmp(tok3, "list"))
3331 n->type = EET_G_LIST;
3332 else if (!strcmp(tok3, "hash"))
3333 n->type = EET_G_HASH;
3336 "ERROR: group type '%s' invalid.",
3352 else if (!strcmp(tok1, "value"))
3363 /* we have 'value NAME TYP XXX' */
3374 for (nn = node->values; nn;
3384 n->name = eina_stringshare_add(tok2);
3385 if (!strcmp(tok3, "char:"))
3387 n->type = EET_T_CHAR;
3388 sscanf(tok4, "%hhi",
3389 &(n->data.value.c));
3391 else if (!strcmp(tok3, "short:"))
3393 n->type = EET_T_SHORT;
3395 &(n->data.value.s));
3397 else if (!strcmp(tok3, "int:"))
3399 n->type = EET_T_INT;
3401 &(n->data.value.i));
3403 else if (!strcmp(tok3, "long_long:"))
3405 n->type = EET_T_LONG_LONG;
3406 sscanf(tok4, "%lli",
3407 &(n->data.value.l));
3409 else if (!strcmp(tok3, "float:"))
3411 n->type = EET_T_FLOAT;
3413 &(n->data.value.f));
3415 else if (!strcmp(tok3, "double:"))
3417 n->type = EET_T_DOUBLE;
3419 &(n->data.value.d));
3421 else if (!strcmp(tok3, "uchar:"))
3423 n->type = EET_T_UCHAR;
3424 sscanf(tok4, "%hhu",
3425 &(n->data.value.uc));
3427 else if (!strcmp(tok3, "ushort:"))
3429 n->type = EET_T_USHORT;
3431 &(n->data.value.us));
3433 else if (!strcmp(tok3, "uint:"))
3435 n->type = EET_T_UINT;
3437 &(n->data.value.ui));
3439 else if (!strcmp(tok3, "ulong_long:"))
3441 n->type = EET_T_ULONG_LONG;
3442 sscanf(tok4, "%llu",
3443 &(n->data.value.ul));
3445 else if (!strcmp(tok3, "string:"))
3447 n->type = EET_T_STRING;
3449 eina_stringshare_add(tok4);
3451 else if (!strcmp(tok3, "inlined:"))
3453 n->type = EET_T_INLINED_STRING;
3455 eina_stringshare_add(tok4);
3457 else if (!strcmp(tok3, "null"))
3459 n->type = EET_T_NULL;
3460 n->data.value.str = NULL;
3464 "ERROR: value type '%s' invalid.",
3478 else if (!strcmp(tok1, "key"))
3483 /* we have 'key NAME' */
3485 node->key = eina_stringshare_add(tok2);
3490 else if (!strcmp(tok1, "count"))
3495 /* we have a 'count COUNT' */
3497 sscanf(tok2, "%i", &(node->count));
3502 else if (!strcmp(tok1, "}"))
3503 /* we have an end of the group */
3505 node = node->parent;
3513 cdata = _eet_data_dump_encode(EET_G_UNKNOWN, ed, node_base, size_ret);
3514 eet_node_del(node_base);
3520 #define NEXT_CHUNK(P, Size, Echnk, Ed) \
3523 __tmp = Ed ? (int)(sizeof(int) * 2) : Echnk.len + 4; \
3524 P += (4 + Echnk.size + __tmp); \
3525 Size -= (4 + Echnk.size + __tmp); \
3529 _eet_data_descriptor_decode(Eet_Free_Context *context,
3530 const Eet_Dictionary *ed,
3531 Eet_Data_Descriptor *edd,
3532 const void *data_in,
3537 Eet_Node *result = NULL;
3541 Eet_Data_Chunk chnk;
3543 if (_eet_data_words_bigendian == -1)
3545 unsigned long int v;
3547 v = htonl(0x12345678);
3548 if (v == 0x12345678)
3549 _eet_data_words_bigendian = 1;
3551 _eet_data_words_bigendian = 0;
3558 if (size_out <= edd->size)
3563 data = edd->func.mem_alloc(edd->size);
3571 for (i = 0; i < edd->elements.num; i++)
3572 edd->elements.set[i].directory_name_ptr = NULL;
3577 _eet_freelist_all_ref(context);
3578 if (data && !data_out)
3579 _eet_freelist_add(context, data);
3581 memset(&chnk, 0, sizeof(Eet_Data_Chunk));
3582 eet_data_chunk_get(ed, &chnk, data_in, size_in);
3587 if (strcmp(chnk.name, edd->name))
3592 size = size_in - (4 + sizeof(int) * 2);
3594 size = size_in - (4 + 4 + chnk.len);
3598 if (!edd->elements.hash.buckets)
3599 _eet_descriptor_hash_new(edd);
3603 switch (chnk.group_type)
3609 return eet_node_string_new(chnk.name, chnk.data);
3611 case EET_T_INLINED_STRING:
3612 return eet_node_inlined_string_new(chnk.name, chnk.data);
3616 return eet_node_null_new(chnk.name);
3619 result = eet_node_struct_new(chnk.name, NULL);
3623 case EET_G_VAR_ARRAY:
3624 return eet_node_var_array_new(chnk.name, NULL);
3638 Eet_Data_Chunk echnk;
3639 Eet_Data_Element *ede = NULL;
3640 Eet_Node *child = NULL;
3641 int group_type = EET_G_UNKNOWN, type = EET_T_UNKNOW;
3644 /* get next data chunk */
3645 memset(&echnk, 0, sizeof(Eet_Data_Chunk));
3646 eet_data_chunk_get(ed, &echnk, p, size);
3648 goto error; /* FIXME: don't REPLY on edd - work without */
3652 ede = _eet_descriptor_hash_find(edd, echnk.name, echnk.hash);
3655 group_type = ede->group_type;
3657 if ((echnk.type == 0) && (echnk.group_type == 0))
3660 group_type = ede->group_type;
3664 if (IS_SIMPLE_TYPE(echnk.type) &&
3665 eet_data_type_match(echnk.type, ede->type))
3666 /* Needed when converting on the fly from FP to Float */
3668 else if (IS_SIMPLE_TYPE(echnk.type) &&
3669 echnk.type == EET_T_NULL &&
3670 ede->type == EET_T_VALUE)
3671 /* EET_T_NULL can become an EET_T_VALUE as EET_T_VALUE are pointer to */
3673 else if ((echnk.group_type > EET_G_UNKNOWN) &&
3674 (echnk.group_type < EET_G_LAST) &&
3675 (echnk.group_type == ede->group_type))
3676 group_type = echnk.group_type;
3680 /*...... dump to node */
3684 group_type = echnk.group_type;
3687 if (!edd && group_type == EET_G_UNKNOWN && IS_SIMPLE_TYPE(type))
3689 unsigned long long dd[128];
3691 ret = eet_data_get_type(ed,
3694 ((char *)echnk.data) + echnk.size,
3699 child = eet_data_node_simple_type(type, echnk.name, dd);
3701 eet_node_struct_append(result, echnk.name, child);
3705 ret = eet_group_codec[group_type - 100].get(
3713 ede ? (void *)(((char *)data) + ede->offset) : (void **)&result,
3721 /* advance to next chunk */
3722 NEXT_CHUNK(p, size, echnk, ed);
3725 _eet_freelist_all_unref(context);
3728 _eet_freelist_str_free(context, edd);
3729 _eet_freelist_direct_str_free(context, edd);
3730 _eet_freelist_list_free(context, edd);
3731 _eet_freelist_hash_free(context, edd);
3732 _eet_freelist_array_free(context, edd);
3733 _eet_freelist_free(context, edd);
3737 _eet_freelist_reset(context);
3738 _eet_freelist_str_reset(context);
3739 _eet_freelist_list_reset(context);
3740 _eet_freelist_hash_reset(context);
3741 _eet_freelist_direct_str_reset(context);
3742 _eet_freelist_array_reset(context);
3751 eet_node_del(result);
3753 _eet_freelist_all_unref(context);
3754 _eet_freelist_str_free(context, edd);
3755 _eet_freelist_direct_str_free(context, edd);
3756 _eet_freelist_list_free(context, edd);
3757 _eet_freelist_hash_free(context, edd);
3758 _eet_freelist_array_free(context, edd);
3759 _eet_freelist_free(context, edd);
3761 /* FIXME: Warn that something goes wrong here. */
3766 eet_data_get_list(Eet_Free_Context *context,
3767 const Eet_Dictionary *ed,
3768 Eet_Data_Descriptor *edd,
3769 Eet_Data_Element *ede,
3770 Eet_Data_Chunk *echnk,
3772 int group_type EINA_UNUSED,
3777 Eet_Data_Descriptor *subtype = NULL;
3782 EET_ASSERT(!((type > EET_T_UNKNOW) && (type < EET_T_STRING)), return 0);
3786 subtype = ede->subtype;
3788 if (type != ede->type)
3792 ptr = (void **)data;
3796 if (IS_POINTER_TYPE(type))
3797 POINTER_TYPE_DECODE(context,
3808 STRUCT_TYPE_DECODE(data_ret,
3819 list = edd->func.list_append(list, data_ret);
3821 _eet_freelist_list_add(context, ptr);
3824 eet_node_list_append(*((Eet_Node **)data), echnk->name, data_ret);
3833 eet_data_get_hash(Eet_Free_Context *context,
3834 const Eet_Dictionary *ed,
3835 Eet_Data_Descriptor *edd,
3836 Eet_Data_Element *ede,
3837 Eet_Data_Chunk *echnk,
3839 int group_type EINA_UNUSED,
3847 void *data_ret = NULL;
3850 EET_ASSERT(!((type > EET_T_UNKNOW) && (type < EET_T_STRING)), return 0);
3852 ptr = (void **)data;
3856 ret = eet_data_get_type(ed,
3859 ((char *)echnk->data) + echnk->size,
3867 /* Advance to next chunk */
3868 NEXT_CHUNK((*p), (*size), (*echnk), ed);
3869 memset(echnk, 0, sizeof(Eet_Data_Chunk));
3872 eet_data_chunk_get(ed, echnk, *p, *size);
3877 if ((ede->group_type != echnk->group_type)
3878 || (ede->type != echnk->type))
3881 if (IS_POINTER_TYPE(echnk->type))
3882 POINTER_TYPE_DECODE(context,
3893 STRUCT_TYPE_DECODE(data_ret,
3896 ede ? ede->subtype : NULL,
3904 hash = edd->func.hash_add(hash, key, data_ret);
3906 _eet_freelist_hash_add(context, hash);
3909 eet_node_hash_add(*((Eet_Node **)data), echnk->name, key, data_ret);
3917 /* var arrays and fixed arrays have to
3918 * get all chunks at once. for fixed arrays
3919 * we can get each chunk and increment a
3920 * counter stored on the element itself but
3921 * it wont be thread safe. for var arrays
3922 * we still need a way to get the number of
3923 * elements from the data, so storing the
3924 * number of elements and the element data on
3925 * each chunk is pointless.
3928 eet_data_get_array(Eet_Free_Context *context,
3929 const Eet_Dictionary *ed,
3930 Eet_Data_Descriptor *edd,
3931 Eet_Data_Element *ede,
3932 Eet_Data_Chunk *echnk,
3939 Eina_List *childs = NULL;
3948 EET_ASSERT(!((type > EET_T_UNKNOW) && (type < EET_T_STRING)), return 0);
3951 /* read the number of elements */
3952 ret = eet_data_get_type(ed,
3955 ((char *)echnk->data) + echnk->size,
3964 if (IS_POINTER_TYPE(type))
3965 subsize = eet_basic_codec[ede->type - 1].size;
3967 subsize = ede->subtype->size;
3969 if (group_type == EET_G_VAR_ARRAY)
3971 /* store the number of elements
3972 * on the counter offset */
3973 *(int *)(((char *)data) + ede->count - ede->offset) = count;
3974 /* allocate space for the array of elements */
3975 if (edd->func.array_alloc)
3976 *(void **)ptr = edd->func.array_alloc(count * subsize);
3978 *(void **)ptr = edd->func.mem_alloc(count * subsize);
3983 memset(*(void **)ptr, 0, count * subsize);
3985 _eet_freelist_array_add(context, *(void **)ptr);
3989 /* get all array elements */
3990 for (i = 0; i < count; i++)
3994 /* Advance to next chunk */
3995 NEXT_CHUNK((*p), (*size), (*echnk), ed);
3996 memset(echnk, 0, sizeof(Eet_Data_Chunk));
3998 eet_data_chunk_get(ed, echnk, *p, *size);
3999 if (!echnk->name || strcmp(echnk->name, name) != 0)
4000 goto on_error; /* get the data */
4002 if ((echnk->group_type != group_type)
4003 || ((echnk->type != type) && (echnk->type != EET_T_NULL)))
4007 if ((ede->group_type != echnk->group_type)
4008 || ((echnk->type != ede->type) && (echnk->type != EET_T_NULL)))
4011 /* get the destination pointer */
4014 if (group_type == EET_G_ARRAY)
4015 dst = (char *)ptr + (subsize * i);
4017 dst = *(char **)ptr + (subsize * i);
4020 if (IS_POINTER_TYPE(echnk->type))
4022 void *data_ret = NULL;
4024 POINTER_TYPE_DECODE(context,
4035 memcpy(dst, &data_ret, subsize);
4038 childs = eina_list_append(childs, data_ret);
4042 STRUCT_TYPE_DECODE(dst,
4045 ede ? ede->subtype : NULL,
4052 childs = eina_list_append(childs, dst);
4058 Eet_Node *parent = *((Eet_Node **)data);
4061 if (group_type == EET_G_ARRAY)
4062 array = eet_node_array_new(name, count, childs);
4064 array = eet_node_var_array_new(name, childs);
4069 eet_node_struct_append(parent, name, array);
4075 EINA_LIST_FREE(childs, tmp)
4082 eet_data_put_union(Eet_Dictionary *ed,
4083 Eet_Data_Descriptor *edd EINA_UNUSED,
4084 Eet_Data_Element *ede,
4085 Eet_Data_Stream *ds,
4088 const char *union_type;
4091 EET_ASSERT(!((ede->type != EET_T_UNKNOW) || (!ede->subtype)), return );
4093 union_type = ede->subtype->func.type_get(
4094 ((char *)data_in) + ede->count - ede->offset,
4100 /* Search the structure of the union to encode. */
4101 for (i = 0; i < ede->subtype->elements.num; ++i)
4102 if (strcmp(ede->subtype->elements.set[i].name, union_type) == 0)
4104 Eet_Data_Element *sede;
4108 /* Yeah we found it ! */
4109 data = eet_data_put_type(ed, EET_T_STRING, &union_type, &size);
4120 sede = &(ede->subtype->elements.set[i]);
4122 if (IS_SIMPLE_TYPE(sede->type))
4123 data = eet_data_put_type(ed, sede->type, data_in, &size);
4125 data = _eet_data_descriptor_encode(ed,
4144 eet_data_get_union(Eet_Free_Context *context,
4145 const Eet_Dictionary *ed,
4146 Eet_Data_Descriptor *edd EINA_UNUSED,
4147 Eet_Data_Element *ede,
4148 Eet_Data_Chunk *echnk,
4155 const char *union_type;
4156 void *data_ret = NULL;
4161 ret = eet_data_get_type(ed,
4164 ((char *)echnk->data) + echnk->size,
4169 /* Advance to next chunk */
4170 NEXT_CHUNK((*p), (*size), (*echnk), ed);
4171 memset(echnk, 0, sizeof(Eet_Data_Chunk));
4174 eet_data_chunk_get(ed, echnk, *p, *size);
4180 EET_ASSERT(!(ede->group_type != group_type || ede->type != type),
4183 /* Search the structure of the union to decode */
4184 for (i = 0; i < ede->subtype->elements.num; ++i)
4185 if (strcmp(ede->subtype->elements.set[i].name, union_type) == 0)
4187 Eet_Data_Element *sede;
4190 /* Yeah we found it ! */
4191 sede = &(ede->subtype->elements.set[i]);
4193 if (IS_SIMPLE_TYPE(sede->type))
4195 ret = eet_data_get_type(ed,
4198 ((char *)echnk->data) + echnk->size,
4206 EET_ASSERT(sede->subtype, goto on_error);
4207 data_ret = _eet_data_descriptor_decode(context,
4213 sede->subtype->size);
4218 /* Set union type. */
4219 if ((!ed) || (!ede->subtype->func.str_direct_alloc))
4221 ut = ede->subtype->func.str_alloc(union_type);
4222 _eet_freelist_str_add(context, ut);
4226 ut = ede->subtype->func.str_direct_alloc(union_type);
4227 _eet_freelist_direct_str_add(context, ut);
4230 ede->subtype->func.type_set(
4232 ((char *)data) + ede->count -
4241 /* FIXME: generate node structure. */
4242 data_ret = _eet_data_descriptor_decode(context,
4244 echnk->data, echnk->size,
4256 eet_data_put_variant(Eet_Dictionary *ed,
4257 Eet_Data_Descriptor *edd EINA_UNUSED,
4258 Eet_Data_Element *ede,
4259 Eet_Data_Stream *ds,
4262 const char *union_type;
4264 Eina_Bool unknow = EINA_FALSE;
4268 EET_ASSERT(!((ede->type != EET_T_UNKNOW) || (!ede->subtype)), return );
4270 union_type = ede->subtype->func.type_get(
4271 ((char *)data_in) + ede->count - ede->offset,
4274 if (!union_type && unknow == EINA_FALSE)
4279 /* Handle opaque internal representation */
4280 Eet_Variant_Unknow *evu;
4282 data = eet_data_put_type(ed, EET_T_STRING, &union_type, &size);
4293 evu = (Eet_Variant_Unknow *)data_in;
4294 if (evu && EINA_MAGIC_CHECK(evu, EET_MAGIC_VARIANT))
4305 /* Search the structure of the union to encode. */
4306 for (i = 0; i < ede->subtype->elements.num; ++i)
4307 if (strcmp(ede->subtype->elements.set[i].name, union_type) == 0)
4309 Eet_Data_Element *sede;
4311 /* Yeah we found it ! */
4312 data = eet_data_put_type(ed, EET_T_STRING, &union_type, &size);
4323 sede = &(ede->subtype->elements.set[i]);
4325 if (sede->group_type != EET_G_UNKNOWN)
4327 Eet_Data_Stream *lds;
4329 lds = eet_data_stream_new();
4330 eet_group_codec[sede->group_type - 100].put(ed,
4337 eet_data_encode(ed, ds, lds->data, ede->name, lds->pos,
4338 ede->type, ede->group_type,
4345 eet_data_encode(ed, ds, NULL, ede->name, 0,
4346 EET_T_NULL, ede->group_type,
4349 eet_data_stream_free(lds);
4353 data = _eet_data_descriptor_encode(ed,
4373 eet_data_get_variant(Eet_Free_Context *context,
4374 const Eet_Dictionary *ed,
4375 Eet_Data_Descriptor *edd EINA_UNUSED,
4376 Eet_Data_Element *ede,
4377 Eet_Data_Chunk *echnk,
4378 int type EINA_UNUSED,
4379 int group_type EINA_UNUSED,
4384 const char *union_type;
4385 void *data_ret = NULL;
4390 ret = eet_data_get_type(ed,
4393 ((char *)echnk->data) + echnk->size,
4398 /* Advance to next chunk */
4399 NEXT_CHUNK((*p), (*size), (*echnk), ed);
4400 memset(echnk, 0, sizeof(Eet_Data_Chunk));
4403 eet_data_chunk_get(ed, echnk, *p, *size);
4411 EET_ASSERT(ede->subtype, goto on_error);
4413 if ((!ed) || (!ede->subtype->func.str_direct_alloc))
4415 ut = ede->subtype->func.str_alloc(union_type);
4416 _eet_freelist_str_add(context, ut);
4420 ut = ede->subtype->func.str_direct_alloc(union_type);
4421 _eet_freelist_direct_str_add(context, ut);
4424 /* Search the structure of the union to decode */
4425 for (i = 0; i < ede->subtype->elements.num; ++i)
4426 if (strcmp(ede->subtype->elements.set[i].name, union_type) == 0)
4428 Eet_Data_Element *sede;
4430 /* Yeah we found it ! */
4431 sede = &(ede->subtype->elements.set[i]);
4433 if (sede->group_type != EET_G_UNKNOWN)
4435 Eet_Data_Chunk chnk;
4440 size2 = echnk->size;
4442 /* Didn't find a proper way to provide this
4443 without duplicating code */
4446 memset(&chnk, 0, sizeof(Eet_Data_Chunk));
4447 eet_data_chunk_get(ed, &chnk, p2, size2);
4452 ret = eet_group_codec[sede->group_type - 100].get
4453 (context, ed, sede->subtype, sede, &chnk, sede->type,
4454 sede->group_type, data, &p2, &size2);
4459 /* advance to next chunk */
4460 NEXT_CHUNK(p2, size2, chnk, ed);
4463 /* Put garbage so that we will not put eet_variant_unknow in it */
4464 data_ret = (void *)data;
4466 /* Set variant type. */
4467 ede->subtype->func.type_set
4468 (ut, ((char *)data) + ede->count - ede->offset,
4473 data_ret = _eet_data_descriptor_decode(context,
4482 /* And point to the variant data. */
4483 *(void **)data = data_ret;
4485 /* Set variant type. */
4486 ede->subtype->func.type_set
4487 (ut, ((char *)data) + ede->count - ede->offset, EINA_FALSE);
4493 Eet_Variant_Unknow *evu;
4495 evu = calloc(1, sizeof (Eet_Variant_Unknow) + echnk->size - 1);
4499 evu->size = echnk->size;
4500 memcpy(evu->data, echnk->data, evu->size);
4501 EINA_MAGIC_SET(evu, EET_MAGIC_VARIANT);
4503 /* And point to the opaque internal data scructure */
4504 *(void **)data = evu;
4506 /* Set variant type. */
4507 ede->subtype->func.type_set
4508 (ut, ((char *)data) + ede->count - ede->offset, EINA_TRUE);
4513 /* FIXME: dump node structure. */
4514 data_ret = _eet_data_descriptor_decode(context,
4516 echnk->data, echnk->size,
4528 eet_data_node_simple_type(int type,
4534 #endif /* ifdef EET_T_TYPE */
4536 #define EET_T_TYPE(Eet_Type, Eet_Node_Type, Type) \
4538 return eet_node_ ## Eet_Node_Type ## _new(name, *((Type *)dd)); \
4542 EET_T_TYPE(EET_T_CHAR, char, char);
4543 EET_T_TYPE(EET_T_SHORT, short, short);
4544 EET_T_TYPE(EET_T_INT, int, int);
4545 EET_T_TYPE(EET_T_LONG_LONG, long_long, long long);
4546 EET_T_TYPE(EET_T_FLOAT, float, float);
4547 EET_T_TYPE(EET_T_DOUBLE, double, double);
4548 EET_T_TYPE(EET_T_UCHAR, unsigned_char, unsigned char);
4549 EET_T_TYPE(EET_T_USHORT, unsigned_short, unsigned short);
4550 EET_T_TYPE(EET_T_UINT, unsigned_int, unsigned int);
4551 EET_T_TYPE(EET_T_ULONG_LONG, unsigned_long_long, unsigned long long);
4552 EET_T_TYPE(EET_T_STRING, string, char *);
4553 EET_T_TYPE(EET_T_INLINED_STRING, inlined_string, char *);
4556 return eet_node_null_new(name);
4559 return eet_node_null_new(name);
4562 ERR("Unknow type passed to eet_data_node_simple_type");
4568 eet_data_get_unknown(Eet_Free_Context *context,
4569 const Eet_Dictionary *ed,
4570 Eet_Data_Descriptor *edd,
4571 Eet_Data_Element *ede,
4572 Eet_Data_Chunk *echnk,
4574 int group_type EINA_UNUSED,
4576 char **p EINA_UNUSED,
4577 int *size EINA_UNUSED)
4582 if (IS_SIMPLE_TYPE(type))
4584 unsigned long long dd[128];
4586 ret = eet_data_get_type(ed,
4589 ((char *)echnk->data) + echnk->size,
4590 edd ? (char *)data : (char *)dd);
4596 Eet_Node **parent = data;
4599 node = eet_data_node_simple_type(type, echnk->name, dd);
4602 eet_node_struct_append(*parent, echnk->name, node);
4608 if (type == EET_T_STRING)
4612 str = (char **)(((char *)data));
4615 if ((!ed) || (!edd->func.str_direct_alloc))
4617 *str = edd->func.str_alloc(*str);
4618 _eet_freelist_str_add(context, *str);
4622 *str = edd->func.str_direct_alloc(*str);
4623 _eet_freelist_direct_str_add(context, *str);
4627 else if (edd && type == EET_T_INLINED_STRING)
4631 str = (char **)(((char *)data));
4634 *str = edd->func.str_alloc(*str);
4635 _eet_freelist_str_add(context, *str);
4642 Eet_Data_Descriptor *subtype;
4644 subtype = ede ? ede->subtype : NULL;
4646 if (subtype || !edd)
4648 Eet_Node **parent = data;
4651 data_ret = _eet_data_descriptor_decode(context,
4662 if (subtype && ede->group_type == EET_G_UNKNOWN_NESTED)
4664 memcpy(data, data_ret, subtype->size);
4669 ptr = (void **)(((char *)data));
4670 *ptr = (void *)data_ret;
4675 Eet_Node *node = data_ret;
4679 node = eet_node_struct_child_new(echnk->name, node);
4680 eet_node_struct_append(*parent, echnk->name, node);
4692 eet_data_put_array(Eet_Dictionary *ed,
4693 Eet_Data_Descriptor *edd EINA_UNUSED,
4694 Eet_Data_Element *ede,
4695 Eet_Data_Stream *ds,
4705 EET_ASSERT(!((ede->type > EET_T_UNKNOW) && (ede->type < EET_T_STRING)),
4708 if (ede->group_type == EET_G_ARRAY)
4709 count = ede->counter_offset;
4711 count = *(int *)(((char *)data_in) + ede->count - ede->offset);
4714 return; /* Store number of elements */
4716 data = eet_data_put_type(ed, EET_T_INT, &count, &size);
4718 eet_data_encode(ed, ds, data, ede->name, size, ede->type, ede->group_type, EINA_TRUE);
4720 if (IS_POINTER_TYPE(ede->type))
4721 subsize = eet_basic_codec[ede->type - 1].size;
4723 subsize = ede->subtype->size;
4725 for (j = 0; j < count; j++)
4730 if (ede->group_type == EET_G_ARRAY)
4731 d = (void *)(((char *)data_in) + offset);
4733 d = *(((char **)data_in)) + offset;
4735 if (IS_POINTER_TYPE(ede->type))
4738 eet_data_put_unknown(ed, NULL, ede, ds, d);
4742 data = _eet_data_descriptor_encode(ed, ede->subtype, d, &size);
4755 /* Add a NULL element just to have the correct array layout. */
4770 eet_data_put_unknown(Eet_Dictionary *ed,
4771 Eet_Data_Descriptor *edd EINA_UNUSED,
4772 Eet_Data_Element *ede,
4773 Eet_Data_Stream *ds,
4779 if (IS_SIMPLE_TYPE(ede->type))
4780 data = eet_data_put_type(ed, ede->type, data_in, &size);
4781 else if (ede->subtype)
4783 if (ede->group_type == EET_G_UNKNOWN_NESTED)
4784 data = _eet_data_descriptor_encode(ed,
4788 else if (*((char **)data_in))
4789 data = _eet_data_descriptor_encode(ed,
4791 *((char **)((char *)(data_in))),
4807 eet_data_put_list(Eet_Dictionary *ed,
4808 Eet_Data_Descriptor *edd,
4809 Eet_Data_Element *ede,
4810 Eet_Data_Stream *ds,
4817 EET_ASSERT(!(((ede->type > EET_T_UNKNOW) && (ede->type < EET_T_STRING))
4818 || ((ede->type > EET_T_NULL) && (ede->type < EET_T_LAST))),
4821 l = *((void **)(((char *)data_in)));
4822 for (; l; l = edd->func.list_next(l))
4824 if (IS_POINTER_TYPE(ede->type))
4826 const void *str = edd->func.list_data(l);
4827 eet_data_put_unknown(ed, NULL, ede, ds, &str);
4831 data = _eet_data_descriptor_encode(ed,
4833 edd->func.list_data(l),
4849 eet_data_put_hash(Eet_Dictionary *ed,
4850 Eet_Data_Descriptor *edd,
4851 Eet_Data_Element *ede,
4852 Eet_Data_Stream *ds,
4855 Eet_Data_Encode_Hash_Info fdata;
4858 l = *((void **)(((char *)data_in)));
4862 edd->func.hash_foreach(l, eet_data_descriptor_encode_hash_cb, &fdata);
4866 eet_data_dump_cipher(Eet_File *ef,
4868 const char *cipher_key,
4869 Eet_Dump_Callback dumpfunc,
4872 const Eet_Dictionary *ed = NULL;
4873 const void *data = NULL;
4875 Eet_Free_Context context;
4876 int required_free = 0;
4879 ed = eet_dictionary_get(ef);
4882 data = eet_read_direct(ef, name, &size);
4887 data = eet_read_cipher(ef, name, &size, cipher_key);
4892 eet_free_context_init(&context);
4893 result = _eet_data_descriptor_decode(&context, ed, NULL, data, size, NULL, 0);
4894 eet_free_context_shutdown(&context);
4896 eet_node_dump(result, 0, dumpfunc, dumpdata);
4898 eet_node_del(result);
4903 return result ? 1 : 0;
4907 eet_data_dump(Eet_File *ef,
4909 Eet_Dump_Callback dumpfunc,
4912 return eet_data_dump_cipher(ef, name, NULL, dumpfunc, dumpdata);
4916 eet_data_text_dump_cipher(const void *data_in,
4917 const char *cipher_key,
4919 Eet_Dump_Callback dumpfunc,
4924 Eet_Free_Context context;
4925 unsigned int ret_len = 0;
4932 if (eet_decipher(data_in, size_in, cipher_key,
4933 strlen(cipher_key), &ret, &ret_len))
4943 ret = (void *)data_in;
4947 eet_free_context_init(&context);
4948 result = _eet_data_descriptor_decode(&context, NULL, NULL, ret, ret_len, NULL, 0);
4949 eet_free_context_shutdown(&context);
4951 eet_node_dump(result, 0, dumpfunc, dumpdata);
4953 eet_node_del(result);
4957 return result ? 1 : 0;
4961 eet_data_text_dump(const void *data_in,
4963 Eet_Dump_Callback dumpfunc,
4966 return eet_data_text_dump_cipher(data_in, NULL, size_in, dumpfunc, dumpdata);
4970 eet_data_text_undump_cipher(const char *text,
4971 const char *cipher_key,
4977 ret = _eet_data_dump_parse(NULL, size_ret, text, textlen);
4978 if (ret && cipher_key)
4980 void *ciphered = NULL;
4981 unsigned int ciphered_len;
4983 if (eet_cipher(ret, *size_ret, cipher_key,
4984 strlen(cipher_key), &ciphered, &ciphered_len))
4995 *size_ret = ciphered_len;
5003 eet_data_text_undump(const char *text,
5007 return eet_data_text_undump_cipher(text, NULL, textlen, size_ret);
5011 eet_data_undump_cipher(Eet_File *ef,
5013 const char *cipher_key,
5023 ed = eet_dictionary_get(ef);
5025 data_enc = _eet_data_dump_parse(ed, &size, text, textlen);
5029 val = eet_write_cipher(ef, name, data_enc, size, comp, cipher_key);
5035 eet_data_undump(Eet_File *ef,
5041 return eet_data_undump_cipher(ef, name, NULL, text, textlen, comp);
5045 eet_data_descriptor_decode_cipher(Eet_Data_Descriptor *edd,
5046 const void *data_in,
5047 const char *cipher_key,
5050 void *deciphered = (void *)data_in;
5052 Eet_Free_Context context;
5053 unsigned int deciphered_len = size_in;
5055 EINA_SAFETY_ON_NULL_RETURN_VAL(edd, NULL);
5057 if (cipher_key && data_in)
5058 if (eet_decipher(data_in, size_in, cipher_key,
5059 strlen(cipher_key), &deciphered, &deciphered_len))
5067 eet_free_context_init(&context);
5068 ret = _eet_data_descriptor_decode(&context,
5074 eet_free_context_shutdown(&context);
5076 if (data_in != deciphered)
5083 eet_data_descriptor_decode(Eet_Data_Descriptor *edd,
5084 const void *data_in,
5087 return eet_data_descriptor_decode_cipher(edd, data_in, NULL, size_in);
5091 eet_data_node_decode_cipher(const void *data_in,
5092 const char *cipher_key,
5095 void *deciphered = (void *)data_in;
5097 Eet_Free_Context context;
5098 unsigned int deciphered_len = size_in;
5100 if (cipher_key && data_in)
5101 if (eet_decipher(data_in, size_in, cipher_key,
5102 strlen(cipher_key), &deciphered, &deciphered_len))
5110 eet_free_context_init(&context);
5111 ret = _eet_data_descriptor_decode(&context,
5117 eet_free_context_shutdown(&context);
5119 if (data_in != deciphered)
5126 _eet_data_descriptor_encode(Eet_Dictionary *ed,
5127 Eet_Data_Descriptor *edd,
5128 const void *data_in,
5131 Eet_Data_Stream *ds;
5132 Eet_Data_Chunk *chnk;
5137 if (_eet_data_words_bigendian == -1)
5139 unsigned long int v;
5141 v = htonl(0x12345678);
5142 if (v == 0x12345678)
5143 _eet_data_words_bigendian = 1;
5145 _eet_data_words_bigendian = 0;
5148 ds = eet_data_stream_new();
5149 for (i = 0; i < edd->elements.num; i++)
5151 Eet_Data_Element *ede;
5153 ede = &(edd->elements.set[i]);
5154 eet_group_codec[ede->group_type - 100].put(
5162 chnk = eet_data_chunk_new(ds->data,
5169 eet_data_stream_free(ds);
5171 ds = eet_data_stream_new();
5172 eet_data_chunk_put(ed, chnk, ds);
5178 eet_data_stream_free(ds);
5182 eet_data_chunk_free(chnk);
5188 eet_data_node_write_cipher(Eet_File *ef,
5190 const char *cipher_key,
5199 ed = eet_dictionary_get(ef);
5201 data_enc = _eet_data_dump_encode(EET_G_UNKNOWN, ed, node, &size);
5205 val = eet_write_cipher(ef, name, data_enc, size, comp, cipher_key);
5211 eet_data_node_encode_cipher(Eet_Node *node,
5212 const char *cipher_key,
5216 void *ciphered = NULL;
5217 unsigned int ciphered_len = 0;
5220 ret = _eet_data_dump_encode(EET_G_UNKNOWN, NULL, node, &size);
5221 if (cipher_key && ret)
5223 if (eet_cipher(ret, size, cipher_key,
5224 strlen(cipher_key), &ciphered, &ciphered_len))
5237 size = (int)ciphered_len;
5248 eet_data_descriptor_encode_cipher(Eet_Data_Descriptor *edd,
5249 const void *data_in,
5250 const char *cipher_key,
5254 void *ciphered = NULL;
5255 unsigned int ciphered_len = 0;
5258 EINA_SAFETY_ON_NULL_RETURN_VAL(edd, NULL);
5260 ret = _eet_data_descriptor_encode(NULL, edd, data_in, &size);
5261 if (cipher_key && ret)
5263 if (eet_cipher(ret, size, cipher_key,
5264 strlen(cipher_key), &ciphered, &ciphered_len))
5277 size = ciphered_len;
5288 eet_data_descriptor_encode(Eet_Data_Descriptor *edd,
5289 const void *data_in,
5292 return eet_data_descriptor_encode_cipher(edd, data_in, NULL, size_ret);
5296 eet_data_xattr_cipher_get(const char *filename,
5297 const char *attribute,
5298 Eet_Data_Descriptor *edd,
5299 const char *cipher_key)
5305 EINA_SAFETY_ON_NULL_RETURN_VAL(edd, NULL);
5307 blob = eina_xattr_get(filename, attribute, &size);
5308 if (!blob) return NULL;
5310 ret = eet_data_descriptor_decode_cipher(edd, blob, cipher_key, size);
5317 eet_data_xattr_cipher_set(const char *filename,
5318 const char *attribute,
5319 Eet_Data_Descriptor *edd,
5320 const char *cipher_key,
5322 Eina_Xattr_Flags flags)
5328 EINA_SAFETY_ON_NULL_RETURN_VAL(edd, EINA_FALSE);
5330 blob = eet_data_descriptor_encode_cipher(edd, data, cipher_key, &size);
5331 if (!blob) return EINA_FALSE;
5333 ret = eina_xattr_set(filename, attribute, blob, size, flags);