From 07274513e984f0b5544586c74508ccd16e7dcafa Mon Sep 17 00:00:00 2001 From: David Walter Seikel Date: Sun, 13 Jan 2013 17:29:19 +1000 Subject: Remove EFL, since it's been released now. --- libraries/eet/src/lib/eet_data.c | 4986 -------------------------------------- 1 file changed, 4986 deletions(-) delete mode 100644 libraries/eet/src/lib/eet_data.c (limited to 'libraries/eet/src/lib/eet_data.c') diff --git a/libraries/eet/src/lib/eet_data.c b/libraries/eet/src/lib/eet_data.c deleted file mode 100644 index d502f44..0000000 --- a/libraries/eet/src/lib/eet_data.c +++ /dev/null @@ -1,4986 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif /* ifdef HAVE_CONFIG_H */ - -#include -#include -#include -#include -#include - -#ifdef HAVE_NETINET_IN_H -# include -#endif /* ifdef HAVE_NETINET_IN_H */ - -#ifdef _WIN32 -# include -#endif /* ifdef _WIN32 */ - -#include - -#include "Eet.h" -#include "Eet_private.h" - -/* - * routines for doing data -> struct and struct -> data conversion - * - * types: - * - * basic types: - * a sequence of... - * - * char - * short - * int - * long long - * float - * double - * unsigned char - * unsigned short - * unsigned int - * unsgined long long - * string - * - * groupings: - * multiple entries ordered as... - * - * fixed size array [ of basic types ] - * variable size array [ of basic types ] - * linked list [ of basic types ] - * hash table [ of basic types ] - * - * need to provide builder/accessor funcs for: - * - * list_next - * list_append - * - * hash_foreach - * hash_add - * - */ - -/*---*/ - -typedef struct _Eet_Data_Element Eet_Data_Element; -typedef struct _Eet_Data_Basic_Type_Codec Eet_Data_Basic_Type_Codec; -typedef struct _Eet_Data_Group_Type_Codec Eet_Data_Group_Type_Codec; -typedef struct _Eet_Data_Chunk Eet_Data_Chunk; -typedef struct _Eet_Data_Stream Eet_Data_Stream; -typedef struct _Eet_Data_Descriptor_Hash Eet_Data_Descriptor_Hash; -typedef struct _Eet_Data_Encode_Hash_Info Eet_Data_Encode_Hash_Info; -typedef struct _Eet_Free Eet_Free; -typedef struct _Eet_Free_Context Eet_Free_Context; -typedef struct _Eet_Variant_Unknow Eet_Variant_Unknow; - -/*---*/ - -/* TODO: - * Eet_Data_Basic_Type_Codec (Coder, Decoder) - * Eet_Data_Group_Type_Codec (Coder, Decoder) - */ -struct _Eet_Data_Basic_Type_Codec -{ - int size; - const char *name; - int (*get)(const Eet_Dictionary *ed, - const void *src, - const void *src_end, - void *dest); - void * (*put)(Eet_Dictionary *ed, const void *src, int *size_ret); -}; - -struct _Eet_Data_Group_Type_Codec -{ - 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); - void (*put)(Eet_Dictionary *ed, - Eet_Data_Descriptor *edd, - Eet_Data_Element *ede, - Eet_Data_Stream *ds, - void *data_in); -}; - -struct _Eet_Data_Chunk -{ - char *name; - int len; - int size; - int hash; - void *data; - unsigned char type; - unsigned char group_type; -}; - -struct _Eet_Data_Stream -{ - void *data; - int size; - int pos; -}; - -struct _Eet_Data_Descriptor_Hash -{ - Eet_Data_Element *element; - Eet_Data_Descriptor_Hash *next; -}; - -struct _Eet_Data_Descriptor -{ - const char *name; - const Eet_Dictionary *ed; - int size; - struct - { - void * (*mem_alloc)(size_t size); - void (*mem_free)(void *mem); - char * (*str_alloc)(const char *str); - char * (*str_direct_alloc)(const char *str); - void (*str_free)(const char *str); - void (*str_direct_free)(const char *str); - void * (*list_next)(void *l); - void * (*list_append)(void *l, void *d); - void * (*list_data)(void *l); - void * (*list_free)(void *l); - void (*hash_foreach)(void *h, - int (*func)(void *h, - const char *k, - void *dt, - void *fdt), - void *fdt); - void * (*hash_add)(void *h, const char *k, void *d); - void (*hash_free)(void *h); - const char *(*type_get)(const void *data, Eina_Bool *unknow); - Eina_Bool (*type_set)(const char *type, - void *data, - Eina_Bool unknow); - void * (*array_alloc)(size_t size); - void (*array_free)(void *mem); - } func; - struct - { - int num; - Eet_Data_Element *set; - struct - { - int size; - Eet_Data_Descriptor_Hash *buckets; - } hash; - } elements; - - Eina_Bool unified_type : 1; -// char *strings; -// int strings_len; -}; - -struct _Eet_Data_Element -{ - const char *name; - const char *counter_name; - const char *directory_name_ptr; - Eet_Data_Descriptor *subtype; - int offset; /* offset in bytes from the base element */ - int count; /* number of elements for a fixed array */ - int counter_offset; /* for a variable array we need the offset of the count variable */ - unsigned char type; /* EET_T_XXX */ - unsigned char group_type; /* EET_G_XXX */ -}; - -struct _Eet_Data_Encode_Hash_Info -{ - Eet_Data_Stream *ds; - Eet_Data_Element *ede; - Eet_Dictionary *ed; -}; - -#define EET_FREE_COUNT 256 -struct _Eet_Free -{ - int ref; - Eina_Array list[EET_FREE_COUNT]; -}; - -struct _Eet_Free_Context -{ - Eet_Free freelist; - Eet_Free freelist_array; - Eet_Free freelist_list; - Eet_Free freelist_hash; - Eet_Free freelist_str; - Eet_Free freelist_direct_str; -}; - -struct _Eet_Variant_Unknow -{ - EINA_MAGIC - - int size; - char data[1]; -}; - -/*---*/ - -static void - eet_free_context_init(Eet_Free_Context *context); -static void - eet_free_context_shutdown(Eet_Free_Context *context); - -static int -eet_data_get_char(const Eet_Dictionary *ed, - const void *src, - const void *src_end, - void *dest); -static void * -eet_data_put_char(Eet_Dictionary *ed, - const void *src, - int *size_ret); -static int -eet_data_get_short(const Eet_Dictionary *ed, - const void *src, - const void *src_end, - void *dest); -static void * -eet_data_put_short(Eet_Dictionary *ed, - const void *src, - int *size_ret); -static inline int -eet_data_get_int(const Eet_Dictionary *ed, - const void *src, - const void *src_end, - void *dest); -static void * -eet_data_put_int(Eet_Dictionary *ed, - const void *src, - int *size_ret); -static int -eet_data_get_long_long(const Eet_Dictionary *ed, - const void *src, - const void *src_end, - void *dest); -static void * -eet_data_put_long_long(Eet_Dictionary *ed, - const void *src, - int *size_ret); -static int -eet_data_get_float(const Eet_Dictionary *ed, - const void *src, - const void *src_end, - void *dest); -static void * -eet_data_put_float(Eet_Dictionary *ed, - const void *src, - int *size_ret); -static int -eet_data_get_double(const Eet_Dictionary *ed, - const void *src, - const void *src_end, - void *dest); -static void * -eet_data_put_double(Eet_Dictionary *ed, - const void *src, - int *size_ret); -static int -eet_data_get_f32p32(const Eet_Dictionary *ed, - const void *src, - const void *src_end, - void *dest); -static void * -eet_data_put_f32p32(Eet_Dictionary *ed, - const void *src, - int *size_ret); -static int -eet_data_get_f16p16(const Eet_Dictionary *ed, - const void *src, - const void *src_end, - void *dest); -static void * -eet_data_put_f16p16(Eet_Dictionary *ed, - const void *src, - int *size_ret); -static int -eet_data_get_f8p24(const Eet_Dictionary *ed, - const void *src, - const void *src_end, - void *dest); -static void * -eet_data_put_f8p24(Eet_Dictionary *ed, - const void *src, - int *size_ret); -static inline int -eet_data_get_string(const Eet_Dictionary *ed, - const void *src, - const void *src_end, - void *dest); -static void * -eet_data_put_string(Eet_Dictionary *ed, - const void *src, - int *size_ret); -static int -eet_data_get_istring(const Eet_Dictionary *ed, - const void *src, - const void *src_end, - void *dest); -static void * -eet_data_put_istring(Eet_Dictionary *ed, - const void *src, - int *size_ret); -static int -eet_data_get_null(const Eet_Dictionary *ed, - const void *src, - const void *src_end, - void *dest); -static void * -eet_data_put_null(Eet_Dictionary *ed, - const void *src, - int *size_ret); - -static int -eet_data_get_type(const Eet_Dictionary *ed, - int type, - const void *src, - const void *src_end, - void *dest); -static void * -eet_data_put_type(Eet_Dictionary *ed, - int type, - const void *src, - int *size_ret); - -static Eet_Node * -eet_data_node_simple_type(int type, - const char *name, - void *dd); - -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); -static void -eet_data_put_unknown(Eet_Dictionary *ed, - Eet_Data_Descriptor *edd, - Eet_Data_Element *ede, - Eet_Data_Stream *ds, - void *data_in); -static void -eet_data_put_array(Eet_Dictionary *ed, - Eet_Data_Descriptor *edd, - Eet_Data_Element *ede, - Eet_Data_Stream *ds, - void *data_in); -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); -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); -static void -eet_data_put_list(Eet_Dictionary *ed, - Eet_Data_Descriptor *edd, - Eet_Data_Element *ede, - Eet_Data_Stream *ds, - void *data_in); -static void -eet_data_put_hash(Eet_Dictionary *ed, - Eet_Data_Descriptor *edd, - Eet_Data_Element *ede, - Eet_Data_Stream *ds, - void *data_in); -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); -static void -eet_data_put_union(Eet_Dictionary *ed, - Eet_Data_Descriptor *edd, - Eet_Data_Element *ede, - Eet_Data_Stream *ds, - void *data_in); -static int -eet_data_get_union(Eet_Free_Context *context, - const Eet_Dictionary *ed, - Eet_Data_Descriptor *edd, - Eet_Data_Element *ede, - Eet_Data_Chunk *echnk, - int type, - int group_type, - void *data, - char **p, - int *size); -static void -eet_data_put_variant(Eet_Dictionary *ed, - Eet_Data_Descriptor *edd, - Eet_Data_Element *ede, - Eet_Data_Stream *ds, - void *data_in); -static int -eet_data_get_variant(Eet_Free_Context *context, - const Eet_Dictionary *ed, - Eet_Data_Descriptor *edd, - Eet_Data_Element *ede, - Eet_Data_Chunk *echnk, - int type, - int group_type, - void *data, - char **p, - int *size); - -static void -eet_data_chunk_get(const Eet_Dictionary *ed, - Eet_Data_Chunk *chnk, - const void *src, - int size); -static Eet_Data_Chunk * -eet_data_chunk_new(void *data, - int size, - const char *name, - int type, - int group_type); -static void -eet_data_chunk_free(Eet_Data_Chunk *chnk); - -static Eet_Data_Stream * - eet_data_stream_new(void); -static void - eet_data_stream_write(Eet_Data_Stream *ds, - const void *data, - int size); -static void -eet_data_stream_free(Eet_Data_Stream *ds); - -static void -eet_data_chunk_put(Eet_Dictionary *ed, - Eet_Data_Chunk *chnk, - Eet_Data_Stream *ds); - -static int -eet_data_descriptor_encode_hash_cb(void *hash, - const char *key, - void *hdata, - void *fdata); -static void *_eet_data_descriptor_encode(Eet_Dictionary *ed, - Eet_Data_Descriptor *edd, - const void *data_in, - int *size_ret); -static void *_eet_data_descriptor_decode(Eet_Free_Context *context, - const Eet_Dictionary *ed, - Eet_Data_Descriptor *edd, - const void *data_in, - int size_in, - void *data_out, - int size_out); - -/*---*/ - -static const Eet_Data_Basic_Type_Codec eet_basic_codec[] = -{ - {sizeof(char), "char", eet_data_get_char, eet_data_put_char }, - {sizeof(short), "short", eet_data_get_short, eet_data_put_short }, - {sizeof(int), "int", eet_data_get_int, eet_data_put_int }, - {sizeof(long long), "long_long", eet_data_get_long_long, eet_data_put_long_long}, - {sizeof(float), "float", eet_data_get_float, eet_data_put_float }, - {sizeof(double), "double", eet_data_get_double, eet_data_put_double }, - {sizeof(char), "uchar", eet_data_get_char, eet_data_put_char }, - {sizeof(short), "ushort", eet_data_get_short, eet_data_put_short }, - {sizeof(int), "uint", eet_data_get_int, eet_data_put_int }, - {sizeof(long long), "ulong_long", eet_data_get_long_long, eet_data_put_long_long}, - {sizeof(char *), "string", eet_data_get_string, eet_data_put_string }, - {sizeof(char *), "inlined", eet_data_get_istring, eet_data_put_istring }, - {sizeof(void *), "NULL", eet_data_get_null, eet_data_put_null }, - {sizeof(Eina_F32p32), "f32p32", eet_data_get_f32p32, eet_data_put_f32p32 }, - {sizeof(Eina_F16p16), "f16p16", eet_data_get_f16p16, eet_data_put_f16p16 }, - {sizeof(Eina_F8p24), "f8p24", eet_data_get_f8p24, eet_data_put_f8p24 } -}; - -static const Eet_Data_Group_Type_Codec eet_group_codec[] = -{ - { eet_data_get_unknown, eet_data_put_unknown }, - { eet_data_get_array, eet_data_put_array }, - { eet_data_get_array, eet_data_put_array }, - { eet_data_get_list, eet_data_put_list }, - { eet_data_get_hash, eet_data_put_hash }, - { eet_data_get_union, eet_data_put_union }, - { eet_data_get_variant, eet_data_put_variant } -}; - -static int _eet_data_words_bigendian = -1; - -/*---*/ - -#define SWAP64(x) (x) = \ - ((((unsigned long long)(x) & 0x00000000000000ffULL) << 56) | \ - (((unsigned long long)(x) & 0x000000000000ff00ULL) << 40) | \ - (((unsigned long long)(x) & 0x0000000000ff0000ULL) << 24) | \ - (((unsigned long long)(x) & 0x00000000ff000000ULL) << 8) | \ - (((unsigned long long)(x) & 0x000000ff00000000ULL) >> 8) | \ - (((unsigned long long)(x) & 0x0000ff0000000000ULL) >> 24) | \ - (((unsigned long long)(x) & 0x00ff000000000000ULL) >> 40) | \ - (((unsigned long long)(x) & 0xff00000000000000ULL) >> 56)) -#define SWAP32(x) (x) = \ - ((((int)(x) & 0x000000ff) << 24) | \ - (((int)(x) & 0x0000ff00) << 8) | \ - (((int)(x) & 0x00ff0000) >> 8) | \ - (((int)(x) & 0xff000000) >> 24)) -#define SWAP16(x) (x) = \ - ((((short)(x) & 0x00ff) << 8) | \ - (((short)(x) & 0xff00) >> 8)) - -#ifdef CONV8 -# undef CONV8 -#endif /* ifdef CONV8 */ -#ifdef CONV16 -# undef CONV16 -#endif /* ifdef CONV16 */ -#ifdef CONV32 -# undef CONV32 -#endif /* ifdef CONV32 */ -#ifdef CONV64 -# undef CONV64 -#endif /* ifdef CONV64 */ - -#define CONV8(x) -#define CONV16(x) {if (_eet_data_words_bigendian) {SWAP16(x); }} -#define CONV32(x) {if (_eet_data_words_bigendian) {SWAP32(x); }} -#define CONV64(x) {if (_eet_data_words_bigendian) {SWAP64(x); }} - -#define IS_SIMPLE_TYPE(Type) (Type > EET_T_UNKNOW && Type < EET_T_LAST) -#define IS_POINTER_TYPE(Type) (Type >= EET_T_STRING && Type <= EET_T_NULL) - -#define POINTER_TYPE_DECODE(Context, \ - Ed, \ - Edd, \ - Ede, \ - Echnk, \ - Type, \ - Data, \ - P, \ - Size, \ - Label) \ - do { \ - int ___r; \ - ___r = eet_data_get_unknown(Context, \ - Ed, \ - Edd, Ede, \ - Echnk, \ - Type, EET_G_UNKNOWN, \ - Data, P, Size); \ - if (!___r) { goto Label; } \ - } while (0) - -#define STRUCT_TYPE_DECODE(Data_Ret, Context, Ed, Ede, Data, Size, SubSize, Label) \ - do { \ - Data_Ret = _eet_data_descriptor_decode(Context, \ - Ed, \ - Ede, \ - Data, \ - Size, \ - SubSize > 0 ? Data_Ret : NULL, \ - SubSize); \ - if (!Data_Ret) { goto Label; } \ - } while (0) - -#define EET_I_STRING 1 << 4 -#define EET_I_INLINED_STRING 2 << 4 -#define EET_I_NULL 3 << 4 - -#define EET_MAGIC_VARIANT 0xF1234BC -/*---*/ - -/* CHAR TYPE */ -static int -eet_data_get_char(const Eet_Dictionary *ed __UNUSED__, - const void *src, - const void *src_end, - void *dst) -{ - char *s, *d; - - if (((char *)src + sizeof(char)) > (char *)src_end) - return -1; - - s = (char *)src; - d = (char *)dst; - *d = *s; - CONV8(*d); - return sizeof(char); -} - -static void * -eet_data_put_char(Eet_Dictionary *ed __UNUSED__, - const void *src, - int *size_ret) -{ - char *s, *d; - - d = (char *)malloc(sizeof(char)); - if (!d) - return NULL; - - s = (char *)src; - *d = *s; - CONV8(*d); - *size_ret = sizeof(char); - return d; -} - -/* SHORT TYPE */ -static int -eet_data_get_short(const Eet_Dictionary *ed __UNUSED__, - const void *src, - const void *src_end, - void *dst) -{ - short *d; - - if (((char *)src + sizeof(short)) > (char *)src_end) - return -1; - - memcpy(dst, src, sizeof(short)); - d = (short *)dst; - CONV16(*d); - return sizeof(short); -} - -static void * -eet_data_put_short(Eet_Dictionary *ed __UNUSED__, - const void *src, - int *size_ret) -{ - short *s, *d; - - d = (short *)malloc(sizeof(short)); - if (!d) - return NULL; - - s = (short *)src; - *d = *s; - CONV16(*d); - *size_ret = sizeof(short); - return d; -} - -/* INT TYPE */ -static inline int -eet_data_get_int(const Eet_Dictionary *ed __UNUSED__, - const void *src, - const void *src_end, - void *dst) -{ - int *d; - - if (((char *)src + sizeof(int)) > (char *)src_end) - return -1; - - memcpy(dst, src, sizeof(int)); - d = (int *)dst; - CONV32(*d); - return sizeof(int); -} - -static void * -eet_data_put_int(Eet_Dictionary *ed __UNUSED__, - const void *src, - int *size_ret) -{ - int *s, *d; - - d = (int *)malloc(sizeof(int)); - if (!d) - return NULL; - - s = (int *)src; - *d = *s; - CONV32(*d); - *size_ret = sizeof(int); - return d; -} - -/* LONG LONG TYPE */ -static int -eet_data_get_long_long(const Eet_Dictionary *ed __UNUSED__, - const void *src, - const void *src_end, - void *dst) -{ - unsigned long long *d; - - if (((char *)src + sizeof(unsigned long long)) > (char *)src_end) - return -1; - - memcpy(dst, src, sizeof(unsigned long long)); - d = (unsigned long long *)dst; - CONV64(*d); - return sizeof(unsigned long long); -} - -static void * -eet_data_put_long_long(Eet_Dictionary *ed __UNUSED__, - const void *src, - int *size_ret) -{ - unsigned long long *s, *d; - - d = (unsigned long long *)malloc(sizeof(unsigned long long)); - if (!d) - return NULL; - - s = (unsigned long long *)src; - *d = *s; - CONV64(*d); - *size_ret = sizeof(unsigned long long); - return d; -} - -/* STRING TYPE */ -static inline int -eet_data_get_string_hash(const Eet_Dictionary *ed, - const void *src, - const void *src_end) -{ - if (ed) - { - int idx; - - if (eet_data_get_int(ed, src, src_end, &idx) < 0) - return -1; - - return eet_dictionary_string_get_hash(ed, idx); - } - - return -1; -} - -static inline int -eet_data_get_string(const Eet_Dictionary *ed, - const void *src, - const void *src_end, - void *dst) -{ - char *s, **d; - - d = (char **)dst; - - if (ed) - { - const char *str; - int idx; - - if (eet_data_get_int(ed, src, src_end, &idx) < 0) - return -1; - - str = eet_dictionary_string_get_char(ed, idx); - if (!str) - return -1; - - *d = (char *)str; - return eet_dictionary_string_get_size(ed, idx); - } - - s = (char *)src; - if (!s) - { - *d = NULL; - return 0; - } - - *d = s; - return strlen(s) + 1; -} - -static void * -eet_data_put_string(Eet_Dictionary *ed, - const void *src, - int *size_ret) -{ - char *s, *d; - int len; - - if (ed) - { - const char *str; - int idx; - - str = *((const char **)src); - if (!str) - return NULL; - - idx = eet_dictionary_string_add(ed, str); - if (idx == -1) - return NULL; - - return eet_data_put_int(ed, &idx, size_ret); - } - - s = (char *)(*((char **)src)); - if (!s) - return NULL; - - len = strlen(s); - d = malloc(len + 1); - if (!d) - return NULL; - - memcpy(d, s, len + 1); - *size_ret = len + 1; - return d; -} - -/* ALWAYS INLINED STRING TYPE */ -static int -eet_data_get_istring(const Eet_Dictionary *ed __UNUSED__, - const void *src, - const void *src_end, - void *dst) -{ - return eet_data_get_string(NULL, src, src_end, dst); -} - -static void * -eet_data_put_istring(Eet_Dictionary *ed __UNUSED__, - const void *src, - int *size_ret) -{ - return eet_data_put_string(NULL, src, size_ret); -} - -/* ALWAYS NULL TYPE */ -static int -eet_data_get_null(const Eet_Dictionary *ed __UNUSED__, - const void *src __UNUSED__, - const void *src_end __UNUSED__, - void *dst) -{ - char **d; - - d = (char **)dst; - - *d = NULL; - return 1; -} - -static void * -eet_data_put_null(Eet_Dictionary *ed __UNUSED__, - const void *src __UNUSED__, - int *size_ret) -{ - *size_ret = 0; - return NULL; -} - -/** - * Fast lookups of simple doubles/floats. - * - * These aren't properly a cache because they don't store pre-calculated - * values, but have a so simple math that is almost as fast. - */ -static inline int -_eet_data_float_cache_get(const char *s, - int len, - float *d) -{ - /* fast handle of simple case 0xMp+E*/ - if ((len == 6) && (s[0] == '0') && (s[1] == 'x') && (s[3] == 'p')) - { - int mantisse = (s[2] >= 'a') ? (s[2] - 'a' + 10) : (s[2] - '0'); - int exponent = (s[5] - '0'); - - if (s[4] == '+') - *d = (float)(mantisse << exponent); - else - *d = (float)mantisse / (float)(1 << exponent); - - return 1; - } - - return 0; -} - -static inline int -_eet_data_double_cache_get(const char *s, - int len, - double *d) -{ - /* fast handle of simple case 0xMp+E*/ - if ((len == 6) && (s[0] == '0') && (s[1] == 'x') && (s[3] == 'p')) - { - int mantisse = (s[2] >= 'a') ? (s[2] - 'a' + 10) : (s[2] - '0'); - int exponent = (s[5] - '0'); - - if (s[4] == '+') - *d = (double)(mantisse << exponent); - else - *d = (double)mantisse / (double)(1 << exponent); - - return 1; - } - - return 0; -} - -/* FLOAT TYPE */ -static int -eet_data_get_float(const Eet_Dictionary *ed, - const void *src, - const void *src_end, - void *dst) -{ - float *d; - int idx; - - d = (float *)dst; - if (!ed) - { - const char *s, *p; - long long mantisse; - long exponent; - int len; - - s = (const char *)src; - p = s; - len = 0; - while ((p < (const char *)src_end) && (*p != 0)) {len++; p++; } - - if (_eet_data_float_cache_get(s, len, d) != 0) - return len + 1; - - if (eina_convert_atod(s, len, &mantisse, &exponent) == EINA_FALSE) - return -1; - - *d = (float)ldexp((double)mantisse, exponent); - - return len + 1; - } - - if (eet_data_get_int(ed, src, src_end, &idx) < 0) - return -1; - - if (!eet_dictionary_string_get_float(ed, idx, d)) - return -1; - - return 1; -} - -static void * -eet_data_put_float(Eet_Dictionary *ed, - const void *src, - int *size_ret) -{ - char buf[128]; - int idx; - - eina_convert_dtoa((double)(*(float *)src), buf); - - if (!ed) - { - char *d; - int len; - - len = strlen(buf); - d = malloc(len + 1); - if (!d) - return NULL; - - memcpy(d, buf, len + 1); - *size_ret = len + 1; - return d; - } - - idx = eet_dictionary_string_add(ed, buf); - if (idx == -1) - return NULL; - - return eet_data_put_int(ed, &idx, size_ret); -} - -/* DOUBLE TYPE */ -static int -eet_data_get_double(const Eet_Dictionary *ed, - const void *src, - const void *src_end, - void *dst) -{ - double *d; - int idx; - - d = (double *)dst; - - if (!ed) - { - const char *s, *p; - long long mantisse = 0; - long exponent = 0; - int len; - - s = (const char *)src; - p = s; - len = 0; - while ((p < (const char *)src_end) && (*p != 0)) {len++; p++; } - - if (_eet_data_double_cache_get(s, len, d) != 0) - return len + 1; - - if (eina_convert_atod(s, len, &mantisse, &exponent) == EINA_FALSE) - return -1; - - *d = ldexp((double)mantisse, exponent); - - return len + 1; - } - - if (eet_data_get_int(ed, src, src_end, &idx) < 0) - return -1; - - if (!eet_dictionary_string_get_double(ed, idx, d)) - return -1; - - return 1; -} - -static void * -eet_data_put_double(Eet_Dictionary *ed, - const void *src, - int *size_ret) -{ - char buf[128]; - int idx; - - eina_convert_dtoa((double)(*(double *)src), buf); - - if (!ed) - { - char *d; - int len; - - len = strlen(buf); - d = malloc(len + 1); - if (!d) - return NULL; - - memcpy(d, buf, len + 1); - *size_ret = len + 1; - - return d; - } - - idx = eet_dictionary_string_add(ed, buf); - if (idx == -1) - return NULL; - - return eet_data_put_int(ed, &idx, size_ret); -} - -static int -eet_data_get_f32p32(const Eet_Dictionary *ed, - const void *src, - const void *src_end, - void *dst) -{ - Eina_F32p32 *fp; - int idx; - - fp = (Eina_F32p32 *)dst; - - if (!ed) - { - const char *s, *p; - int len; - - s = (const char *)src; - p = s; - len = 0; - while ((p < (const char *)src_end) && (*p != 0)) { len++; p++; } - - if (!(eina_convert_atofp(s, len, fp))) - return -1; - - return 1; - } - - if (eet_data_get_int(ed, src, src_end, &idx) < 0) - return -1; - - if (!eet_dictionary_string_get_fp(ed, idx, fp)) - return -1; - - return 1; -} - -static void * -eet_data_put_f32p32(Eet_Dictionary *ed, - const void *src, - int *size_ret) -{ - char buf[128]; - int idx; - - eina_convert_fptoa((Eina_F32p32)(*(Eina_F32p32 *)src), buf); - - if (!ed) - { - char *d; - int len; - - len = strlen(buf); - d = malloc(len + 1); - if (!d) - return NULL; - - memcpy(d, buf, len + 1); - *size_ret = len + 1; - - return d; - } - - idx = eet_dictionary_string_add(ed, buf); - if (idx == -1) - return NULL; - - return eet_data_put_int(ed, &idx, size_ret); -} - -static int -eet_data_get_f16p16(const Eet_Dictionary *ed, - const void *src, - const void *src_end, - void *dst) -{ - Eina_F32p32 tmp; - Eina_F16p16 *fp; - - fp = (Eina_F16p16 *)dst; - - if (eet_data_get_f32p32(ed, src, src_end, &tmp) < 0) - return -1; - - *fp = eina_f32p32_to_f16p16(tmp); - return 1; -} - -static void * -eet_data_put_f16p16(Eet_Dictionary *ed, - const void *src, - int *size_ret) -{ - Eina_F32p32 tmp; - - tmp = eina_f16p16_to_f32p32((Eina_F16p16)(*(Eina_F16p16 *)src)); - return eet_data_put_f32p32(ed, &tmp, size_ret); -} - -static int -eet_data_get_f8p24(const Eet_Dictionary *ed, - const void *src, - const void *src_end, - void *dst) -{ - Eina_F32p32 tmp; - Eina_F8p24 *fp; - - fp = (Eina_F8p24 *)dst; - - if (eet_data_get_f32p32(ed, src, src_end, &tmp) < 0) - return -1; - - *fp = eina_f32p32_to_f8p24(tmp); - return 1; -} - -static void * -eet_data_put_f8p24(Eet_Dictionary *ed, - const void *src, - int *size_ret) -{ - Eina_F32p32 tmp; - - tmp = eina_f8p24_to_f32p32((Eina_F8p24)(*(Eina_F8p24 *)src)); - return eet_data_put_f32p32(ed, &tmp, size_ret); -} - -static inline int -eet_data_get_type(const Eet_Dictionary *ed, - int type, - const void *src, - const void *src_end, - void *dest) -{ - int ret; - - ret = eet_basic_codec[type - 1].get(ed, src, src_end, dest); - return ret; -} - -static inline void * -eet_data_put_type(Eet_Dictionary *ed, - int type, - const void *src, - int *size_ret) -{ - void *ret; - - ret = eet_basic_codec[type - 1].put(ed, src, size_ret); - return ret; -} - -static inline Eina_Bool -eet_data_type_match(int type1, - int type2) -{ - if (type1 == type2) - return EINA_TRUE; - - /* Note: All floating point type are equivalent and could be read - without problem by any other floating point getter. */ - switch (type1) - { - case EET_T_FLOAT: - case EET_T_DOUBLE: - case EET_T_F32P32: - case EET_T_F16P16: - case EET_T_F8P24: - switch (type2) - { - case EET_T_FLOAT: - case EET_T_DOUBLE: - case EET_T_F32P32: - case EET_T_F16P16: - case EET_T_F8P24: - return EINA_TRUE; - - default: - break; - } /* switch */ - break; - - default: - break; - } - - return EINA_FALSE; -} - -/* chunk format... - * - * char[4] = "CHnK"; // untyped data ... or - * char[4] = "CHKx"; // typed data - x == type - * - * int = chunk size (including magic string); - * char[] = chunk magic/name string (0 byte terminated); - * ... sub-chunks (a chunk can contain chuncks recusrively) ... - * or - * ... payload data ... - * - */ - -static inline void -eet_data_chunk_get(const Eet_Dictionary *ed, - Eet_Data_Chunk *chnk, - const void *src, - int size) -{ - const char *s; - int ret1, ret2; - - if (!src) - return; - - if (size <= 8) - return; - - if (!chnk) - return; - - s = src; - if (s[2] == 'K') - { - if ((s[0] != 'C') || (s[1] != 'H') || (s[2] != 'K')) - return; - - chnk->type = (unsigned char)(s[3]); - if (chnk->type >= EET_I_LIMIT) - { - chnk->group_type = - ((chnk->type - EET_I_LIMIT) & 0xF) + EET_G_UNKNOWN; - switch ((chnk->type - EET_I_LIMIT) & 0xF0) - { -#define EET_UNMATCH_TYPE(Type) \ -case EET_I_ ## Type: chnk->type = EET_T_ ## Type; break; - - EET_UNMATCH_TYPE(STRING); - EET_UNMATCH_TYPE(INLINED_STRING); - EET_UNMATCH_TYPE(NULL); - - default: - return; - } - } - else if (chnk->type > EET_T_LAST) - { - chnk->group_type = chnk->type; - chnk->type = EET_T_UNKNOW; - } - else - chnk->group_type = EET_G_UNKNOWN; - if ((chnk->type >= EET_T_LAST) || - (chnk->group_type >= - EET_G_LAST)) - { - chnk->type = 0; - chnk->group_type = 0; - } - } - else if ((s[0] != 'C') || (s[1] != 'H') || (s[2] != 'n') || (s[3] != 'K')) - return; - - ret1 = eet_data_get_type(ed, EET_T_INT, (s + 4), (s + size), &(chnk->size)); - - if (ret1 <= 0) - return; - - if ((chnk->size < 0) || ((chnk->size + 8) > size)) - return; - - ret2 = eet_data_get_type(ed, EET_T_STRING, (s + 8), (s + size), &(chnk->name)); - - if (ret2 <= 0) - return; - - chnk->len = ret2; - - /* Precalc hash */ - chnk->hash = eet_data_get_string_hash(ed, (s + 8), (s + size)); - - if (ed) - { - chnk->data = (char *)src + 4 + ret1 + sizeof(int); - chnk->size -= sizeof(int); - } - else - { - chnk->data = (char *)src + 4 + ret1 + chnk->len; - chnk->size -= chnk->len; - } - - return; -} - -static inline Eet_Data_Chunk * -eet_data_chunk_new(void *data, - int size, - const char *name, - int type, - int group_type) -{ - Eet_Data_Chunk *chnk; - - if (!name) - return NULL; - - chnk = calloc(1, sizeof(Eet_Data_Chunk)); - if (!chnk) - return NULL; - - /* Note: Another security, so older eet library could read file - saved with fixed point value. */ - if (type == EET_T_F32P32 - || type == EET_T_F16P16 - || type == EET_T_F8P24) - type = EET_T_DOUBLE; - - chnk->name = strdup(name); - chnk->len = strlen(name) + 1; - chnk->size = size; - chnk->data = data; - chnk->type = type; - chnk->group_type = group_type; - return chnk; -} - -static inline void -eet_data_chunk_free(Eet_Data_Chunk *chnk) -{ - if (chnk->name) - free(chnk->name); - - free(chnk); -} - -static inline Eet_Data_Stream * -eet_data_stream_new(void) -{ - Eet_Data_Stream *ds; - - ds = calloc(1, sizeof(Eet_Data_Stream)); - if (!ds) - return NULL; - - return ds; -} - -static inline void -eet_data_stream_free(Eet_Data_Stream *ds) -{ - if (ds->data) - free(ds->data); - - free(ds); -} - -static inline void -eet_data_stream_flush(Eet_Data_Stream *ds) -{ - free(ds); -} - -static inline void -eet_data_stream_write(Eet_Data_Stream *ds, - const void *data, - int size) -{ - char *p; - - if ((ds->pos + size) > ds->size) - { - ds->data = realloc(ds->data, ds->size + size + 512); - if (!ds->data) - { - ds->pos = 0; - ds->size = 0; - return; - } - - ds->size = ds->size + size + 512; - } - - p = ds->data; - memcpy(p + ds->pos, data, size); - ds->pos += size; -} - -static void -eet_data_chunk_put(Eet_Dictionary *ed, - Eet_Data_Chunk *chnk, - Eet_Data_Stream *ds) -{ - int *size; - void *string; - int s; - int size_ret = 0; - int string_ret = 0; - unsigned char buf[4] = "CHK"; - - /* disable this check - it will allow empty chunks to be written. this is - * right for corner-cases when y have a struct with empty fields (empty - * strings or empty list ptrs etc.) */ - /* if (!chnk->data && chnk->type != EET_T_NULL) return; */ - /* chunk head */ - -/* eet_data_stream_write(ds, "CHnK", 4);*/ - if (chnk->type != EET_T_UNKNOW) - { - if (chnk->group_type != EET_G_UNKNOWN) - { - int type = EET_I_LIMIT + chnk->group_type - EET_G_UNKNOWN; - - switch (chnk->type) - { - /* Only make sense with pointer type. */ -#define EET_MATCH_TYPE(Type) \ -case EET_T_ ## Type: type += EET_I_ ## Type; break; - - EET_MATCH_TYPE(STRING); - EET_MATCH_TYPE(INLINED_STRING); - EET_MATCH_TYPE(NULL); - - default: - return; - } - - buf[3] = type; - } - else - buf[3] = chnk->type; - } - else - buf[3] = chnk->group_type; - - string = eet_data_put_string(ed, &chnk->name, &string_ret); - if (!string) - return; - - /* size of chunk payload data + name */ - s = chnk->size + string_ret; - size = eet_data_put_int(ed, &s, &size_ret); - - /* FIXME: If something goes wrong the resulting file will be corrupted. */ - if (!size) - goto on_error; - - eet_data_stream_write(ds, buf, 4); - - /* write chunk length */ - eet_data_stream_write(ds, size, size_ret); - - /* write chunk name */ - eet_data_stream_write(ds, string, string_ret); - - /* write payload */ - if (chnk->data) - eet_data_stream_write(ds, chnk->data, chnk->size); - - free(string); -on_error: - free(size); -} - -/*---*/ - -static void -_eet_descriptor_hash_new(Eet_Data_Descriptor *edd) -{ - int i; - - edd->elements.hash.size = 1 << 6; - edd->elements.hash.buckets = calloc( - 1, - sizeof(Eet_Data_Descriptor_Hash) * - edd->elements.hash.size); - for (i = 0; i < edd->elements.num; i++) - { - Eet_Data_Element *ede; - int hash; - - ede = &(edd->elements.set[i]); - hash = _eet_hash_gen((char *)ede->name, 6); - if (!edd->elements.hash.buckets[hash].element) - edd->elements.hash.buckets[hash].element = ede; - else - { - Eet_Data_Descriptor_Hash *bucket; - - bucket = calloc(1, sizeof(Eet_Data_Descriptor_Hash)); - bucket->element = ede; - bucket->next = edd->elements.hash.buckets[hash].next; - edd->elements.hash.buckets[hash].next = bucket; - } - } -} - -static void -_eet_descriptor_hash_free(Eet_Data_Descriptor *edd) -{ - int i; - - for (i = 0; i < edd->elements.hash.size; i++) - { - Eet_Data_Descriptor_Hash *bucket, *pbucket; - - bucket = edd->elements.hash.buckets[i].next; - while (bucket) - { - pbucket = bucket; - bucket = bucket->next; - free(pbucket); - } - } - if (edd->elements.hash.buckets) - free(edd->elements.hash.buckets); -} - -static Eet_Data_Element * -_eet_descriptor_hash_find(Eet_Data_Descriptor *edd, - char *name, - int hash) -{ - Eet_Data_Descriptor_Hash *bucket; - - if (hash < 0) - hash = _eet_hash_gen(name, 6); - else - hash &= 0x3f; - - if (!edd->elements.hash.buckets[hash].element) - return NULL; /* - When we use the dictionary as a source for chunk name, we will always - have the same pointer in name. It's a good idea to just compare pointer - instead of running strcmp on both string. - */ - - if (edd->elements.hash.buckets[hash].element->directory_name_ptr == name) - return edd->elements.hash.buckets[hash].element; - - if (!strcmp(edd->elements.hash.buckets[hash].element->name, name)) - { - edd->elements.hash.buckets[hash].element->directory_name_ptr = name; - return edd->elements.hash.buckets[hash].element; - } - - bucket = edd->elements.hash.buckets[hash].next; - while (bucket) - { - if (bucket->element->directory_name_ptr == name) - return bucket->element; - - if (!strcmp(bucket->element->name, name)) - { - bucket->element->directory_name_ptr = name; - return bucket->element; - } - - bucket = bucket->next; - } - return NULL; -} - -static void * -_eet_mem_alloc(size_t size) -{ - return calloc(1, size); -} - -static void -_eet_mem_free(void *mem) -{ - free(mem); -} - -static char * -_eet_str_alloc(const char *str) -{ - return strdup(str); -} - -static void -_eet_str_free(const char *str) -{ - free((char *)str); -} - -static Eina_Hash * -_eet_eina_hash_add_alloc(Eina_Hash *hash, - const char *key, - void *data) -{ - if (!hash) - hash = eina_hash_string_small_new(NULL); - - if (!hash) - return NULL; - - eina_hash_add(hash, key, data); - return hash; -} - -static Eina_Hash * -_eet_eina_hash_direct_add_alloc(Eina_Hash *hash, - const char *key, - void *data) -{ - if (!hash) - hash = eina_hash_string_small_new(NULL); - - if (!hash) - return NULL; - - eina_hash_direct_add(hash, key, data); - return hash; -} - -static char * -_eet_str_direct_alloc(const char *str) -{ - return (char *)str; -} - -static void -_eet_str_direct_free(const char *str __UNUSED__) -{ -} - -static void -_eet_eina_hash_foreach(void *hash, - Eina_Hash_Foreach cb, - void *fdata) -{ - if (hash) - eina_hash_foreach(hash, cb, fdata); -} - -static void -_eet_eina_hash_free(void *hash) -{ - if (hash) - eina_hash_free(hash); -} - -/*---*/ -EAPI Eina_Bool -eet_eina_stream_data_descriptor_class_set(Eet_Data_Descriptor_Class *eddc, - /* When we change the structure content in the future, we need to handle old structure type too */ - unsigned int eddc_size, - const char *name, - int size) -{ - if (!eddc || !name || eddc_size != sizeof (Eet_Data_Descriptor_Class)) - return EINA_FALSE; - - eddc->name = name; - eddc->size = size; - eddc->version = EET_DATA_DESCRIPTOR_CLASS_VERSION; - - eddc->func.mem_alloc = _eet_mem_alloc; - eddc->func.mem_free = _eet_mem_free; - eddc->func.str_alloc = (char *(*)(const char *))eina_stringshare_add; - eddc->func.str_free = eina_stringshare_del; - eddc->func.list_next = (void *(*)(void *))eina_list_next; - eddc->func.list_append = (void *(*)(void *, void *))eina_list_append; - eddc->func.list_data = (void *(*)(void *))eina_list_data_get; - eddc->func.list_free = (void *(*)(void *))eina_list_free; - eddc->func.hash_foreach = (void (*)(void *, int (*)(void *, const char *, void *, void *), void *))_eet_eina_hash_foreach; - eddc->func.hash_add = (void *(*)(void *, const char *, void *))_eet_eina_hash_add_alloc; - eddc->func.hash_free = (void (*)(void *))_eet_eina_hash_free; - - /* This will cause an ABI incompatibility */ - eddc->func.array_alloc = _eet_mem_alloc; - eddc->func.array_free = _eet_mem_free; - - return EINA_TRUE; -} - -EAPI Eina_Bool -eet_eina_file_data_descriptor_class_set(Eet_Data_Descriptor_Class *eddc, - /* When we change the structure content in the future, we need to handle old structure type too */ - unsigned int eddc_size, - const char *name, - int size) -{ - if (!eet_eina_stream_data_descriptor_class_set(eddc, eddc_size, name, size)) - return EINA_FALSE; - - eddc->version = EET_DATA_DESCRIPTOR_CLASS_VERSION; - - eddc->func.hash_add = (void *(*)(void *, const char *, void *))_eet_eina_hash_direct_add_alloc; - eddc->func.str_direct_alloc = _eet_str_direct_alloc; - eddc->func.str_direct_free = _eet_str_direct_free; - - return EINA_TRUE; -} - -static Eet_Data_Descriptor * -_eet_data_descriptor_new(const Eet_Data_Descriptor_Class *eddc, - int version) -{ - Eet_Data_Descriptor *edd; - - if (!eddc) - return NULL; - - edd = calloc(1, sizeof (Eet_Data_Descriptor)); - if (!edd) - return NULL; - - edd->name = eddc->name; - edd->ed = NULL; - edd->size = eddc->size; - edd->func.mem_alloc = _eet_mem_alloc; - edd->func.mem_free = _eet_mem_free; - edd->func.str_alloc = _eet_str_alloc; - edd->func.str_free = _eet_str_free; - if (eddc->func.mem_alloc) - edd->func.mem_alloc = eddc->func.mem_alloc; - - if (eddc->func.mem_free) - edd->func.mem_free = eddc->func.mem_free; - - if (eddc->func.str_alloc) - edd->func.str_alloc = eddc->func.str_alloc; - - if (eddc->func.str_free) - edd->func.str_free = eddc->func.str_free; - - edd->func.list_next = eddc->func.list_next; - edd->func.list_append = eddc->func.list_append; - edd->func.list_data = eddc->func.list_data; - edd->func.list_free = eddc->func.list_free; - edd->func.hash_foreach = eddc->func.hash_foreach; - edd->func.hash_add = eddc->func.hash_add; - edd->func.hash_free = eddc->func.hash_free; - - if (eddc->version > 1 && version > 1) - { - edd->func.str_direct_alloc = eddc->func.str_direct_alloc; - edd->func.str_direct_free = eddc->func.str_direct_free; - } - - if (eddc->version > 2) - { - edd->func.type_get = eddc->func.type_get; - edd->func.type_set = eddc->func.type_set; - } - - if (eddc->version > 3) - { - edd->func.array_alloc = eddc->func.array_alloc; - edd->func.array_free = eddc->func.array_free; - } - - return edd; -} - -EAPI Eet_Data_Descriptor * -eet_data_descriptor_new(const char *name, - int size, - Eet_Descriptor_List_Next_Callback func_list_next, - Eet_Descriptor_List_Append_Callback func_list_append, - Eet_Descriptor_List_Data_Callback func_list_data, - Eet_Descriptor_List_Free_Callback func_list_free, - Eet_Descriptor_Hash_Foreach_Callback func_hash_foreach, - Eet_Descriptor_Hash_Add_Callback func_hash_add, - Eet_Descriptor_Hash_Free_Callback func_hash_free) -{ - Eet_Data_Descriptor_Class eddc; - - if (!name) - return NULL; - - memset(&eddc, 0, sizeof (Eet_Data_Descriptor_Class)); - - eddc.name = name; - eddc.size = size; - eddc.version = 0; - - eddc.func.list_next = func_list_next; - eddc.func.list_append = func_list_append; - eddc.func.list_data = func_list_data; - eddc.func.list_free = func_list_free; - eddc.func.hash_foreach = func_hash_foreach; - eddc.func.hash_add = func_hash_add; - eddc.func.hash_free = func_hash_free; - - return _eet_data_descriptor_new(&eddc, 0); -} - -EAPI Eet_Data_Descriptor * -eet_data_descriptor2_new(const Eet_Data_Descriptor_Class *eddc) -{ - return _eet_data_descriptor_new(eddc, 1); -} - -EAPI Eet_Data_Descriptor * -eet_data_descriptor3_new(const Eet_Data_Descriptor_Class *eddc) -{ - return _eet_data_descriptor_new(eddc, 2); -} - -EAPI Eet_Data_Descriptor * -eet_data_descriptor_stream_new(const Eet_Data_Descriptor_Class *eddc) -{ - return _eet_data_descriptor_new(eddc, 1); -} - -EAPI Eet_Data_Descriptor * -eet_data_descriptor_file_new(const Eet_Data_Descriptor_Class *eddc) -{ - return _eet_data_descriptor_new(eddc, 2); -} - -EAPI void -eet_data_descriptor_free(Eet_Data_Descriptor *edd) -{ - if (!edd) - return; - - _eet_descriptor_hash_free(edd); - if (edd->elements.set) - free(edd->elements.set); - - free(edd); -} - -EAPI void -eet_data_descriptor_element_add(Eet_Data_Descriptor *edd, - const char *name, - int type, - int group_type, - int offset, - int count, -/* int counter_offset, */ - const char *counter_name /* FIXME: Useless should go on a major release */, - Eet_Data_Descriptor *subtype) -{ - Eet_Data_Element *ede; - Eet_Data_Element *tmp; - - /* UNION, VARIANT type would not work with simple type, we need a way to map the type. */ - if ((group_type == EET_G_UNION - || group_type == EET_G_VARIANT) - && - (type != EET_T_UNKNOW - || !subtype - || !subtype->func.type_get - || !subtype->func.type_set)) - return; - - /* VARIANT type will only work if the map only contains EET_G_*, but not UNION, VARIANT and ARRAY. */ - if (group_type == EET_G_VARIANT) - { - int i; - - for (i = 0; i < subtype->elements.num; ++i) - if (subtype->elements.set[i].type != EET_T_UNKNOW - && subtype->elements.set[i].group_type > EET_G_VAR_ARRAY - && subtype->elements.set[i].group_type < EET_G_UNION) - return; - - subtype->unified_type = EINA_TRUE; - } - - if (subtype - && subtype->unified_type - && (type != EET_T_UNKNOW - || group_type < EET_G_UNION)) - return; - - /* Sanity check done, let allocate ! */ - edd->elements.num++; - tmp = realloc(edd->elements.set, edd->elements.num * sizeof(Eet_Data_Element)); - if (!tmp) - return; - - edd->elements.set = tmp; - ede = &(edd->elements.set[edd->elements.num - 1]); - ede->name = name; - ede->directory_name_ptr = NULL; - - /* - * We do a special case when we do list,hash or whatever group of simple type. - * Instead of handling it in encode/decode/dump/undump, we create an - * implicit structure with only the simple type. - */ - if ((group_type > EET_G_UNKNOWN) - && (group_type < EET_G_LAST) - && (((type > EET_T_UNKNOW) && (type < EET_T_STRING)) - || ((type > EET_T_NULL) && (type < EET_T_LAST))) - && (!subtype)) - { - subtype = calloc(1, sizeof (Eet_Data_Descriptor)); - if (!subtype) - return; - - subtype->name = "implicit"; - subtype->size = eet_basic_codec[type - 1].size; - memcpy(&subtype->func, &edd->func, sizeof(subtype->func)); - - eet_data_descriptor_element_add(subtype, - eet_basic_codec[type - 1].name, - type, - EET_G_UNKNOWN, - 0, - 0, - /* 0, */ NULL, - NULL); - type = EET_T_UNKNOW; - } - - ede->type = type; - ede->group_type = group_type; - ede->offset = offset; - ede->count = count; - /* FIXME: For the time being, VAR_ARRAY, UNION and VARIANT will put the counter_offset in count. */ - ede->counter_offset = count; -/* ede->counter_offset = counter_offset; */ - ede->counter_name = counter_name; - - ede->subtype = subtype; -} - -EAPI void * -eet_data_read_cipher(Eet_File *ef, - Eet_Data_Descriptor *edd, - const char *name, - const char *cipher_key) -{ - const Eet_Dictionary *ed = NULL; - const void *data = NULL; - void *data_dec; - Eet_Free_Context context; - int required_free = 0; - int size; - - ed = eet_dictionary_get(ef); - - if (!cipher_key) - data = eet_read_direct(ef, name, &size); - - if (!data) - { - required_free = 1; - data = eet_read_cipher(ef, name, &size, cipher_key); - if (!data) - return NULL; - } - - eet_free_context_init(&context); - data_dec = _eet_data_descriptor_decode(&context, ed, edd, data, size, NULL, 0); - eet_free_context_shutdown(&context); - - if (required_free) - free((void *)data); - - return data_dec; -} - -EAPI Eet_Node * -eet_data_node_read_cipher(Eet_File *ef, - const char *name, - const char *cipher_key) -{ - const Eet_Dictionary *ed = NULL; - const void *data = NULL; - Eet_Node *result; - Eet_Free_Context context; - int required_free = 0; - int size; - - ed = eet_dictionary_get(ef); - - if (!cipher_key) - data = eet_read_direct(ef, name, &size); - - if (!data) - { - required_free = 1; - data = eet_read_cipher(ef, name, &size, cipher_key); - if (!data) - return NULL; - } - - eet_free_context_init(&context); - result = _eet_data_descriptor_decode(&context, ed, NULL, data, size, NULL, 0); - eet_free_context_shutdown(&context); - - if (required_free) - free((void *)data); - - return result; -} - -EAPI void * -eet_data_read(Eet_File *ef, - Eet_Data_Descriptor *edd, - const char *name) -{ - return eet_data_read_cipher(ef, edd, name, NULL); -} - -EAPI int -eet_data_write_cipher(Eet_File *ef, - Eet_Data_Descriptor *edd, - const char *name, - const char *cipher_key, - const void *data, - int compress) -{ - Eet_Dictionary *ed; - void *data_enc; - int size; - int val; - - ed = eet_dictionary_get(ef); - - data_enc = _eet_data_descriptor_encode(ed, edd, data, &size); - if (!data_enc) - return 0; - - val = eet_write_cipher(ef, name, data_enc, size, compress, cipher_key); - free(data_enc); - return val; -} - -EAPI int -eet_data_write(Eet_File *ef, - Eet_Data_Descriptor *edd, - const char *name, - const void *data, - int compress) -{ - return eet_data_write_cipher(ef, edd, name, NULL, data, compress); -} - -static void -eet_free_context_init(Eet_Free_Context *context) -{ - unsigned int i = 0; - - memset(context, 0, sizeof (Eet_Free_Context)); - for (i = 0; i < EET_FREE_COUNT; ++i) - { - eina_array_step_set(&context->freelist.list[i], - sizeof (context->freelist.list[i]), - 32); - eina_array_step_set(&context->freelist_array.list[i], - sizeof (context->freelist.list[i]), - 32); - eina_array_step_set(&context->freelist_list.list[i], - sizeof (context->freelist.list[i]), - 32); - eina_array_step_set(&context->freelist_hash.list[i], - sizeof (context->freelist.list[i]), - 32); - eina_array_step_set(&context->freelist_str.list[i], - sizeof (context->freelist.list[i]), - 32); - eina_array_step_set(&context->freelist_direct_str.list[i], - sizeof (context->freelist.list[i]), - 32); - } -} - -static void -eet_free_context_shutdown(Eet_Free_Context *context) -{ - unsigned int i = 0; - - for (i = 0; i < EET_FREE_COUNT; ++i) - { - eina_array_flush(&context->freelist.list[i]); - eina_array_flush(&context->freelist_array.list[i]); - eina_array_flush(&context->freelist_list.list[i]); - eina_array_flush(&context->freelist_hash.list[i]); - eina_array_flush(&context->freelist_str.list[i]); - eina_array_flush(&context->freelist_direct_str.list[i]); - } -} - -static int -_eet_free_hash(void *data) -{ -#ifdef _WIN64 - __int64 ptr = (UINT_PTR)data; -#else /* ifdef _WIN64 */ - unsigned long ptr = (unsigned long)(data); -#endif /* ifdef _WIN64 */ - int hash; - - hash = ptr; - hash ^= ptr >> 8; - hash ^= ptr >> 16; - hash ^= ptr >> 24; - -#if defined (_WIN64) || ((!defined (_WIN32)) && (LONG_BIT != 32)) - hash ^= ptr >> 32; - hash ^= ptr >> 40; - hash ^= ptr >> 48; - hash ^= ptr >> 56; -#endif /* if defined (_WIN64) || ((!defined (_WIN32)) && (LONG_BIT != 32)) */ - - return hash & 0xFF; -} - -static void -_eet_free_add(Eet_Free *ef, - void *data) -{ - void *track; - Eina_Array_Iterator it; - unsigned int i; - int hash; - - hash = _eet_free_hash(data); - - EINA_ARRAY_ITER_NEXT(&ef->list[hash], i, track, it) - if (track == data) - return; - - eina_array_push(&ef->list[hash], data); -} - -#if 0 -static void -_eet_free_del(Eet_Free *ef, - void *data) -{ - void *track; - Eina_Array_Iterator it; - unsigned int i; - int hash; - - hash = _eet_free_hash(data); - - EINA_ARRAY_ITER_NEXT(&ef->list[hash], i, track, it) - if (track == data) - { - eina_array_data_set(&ef->list[hash], i, NULL); - return; - } -} - -#endif - -static void -_eet_free_reset(Eet_Free *ef) -{ - unsigned int i; - - if (ef->ref > 0) - return; - - for (i = 0; i < EET_FREE_COUNT; ++i) - eina_array_clean(&ef->list[i]); -} - -static void -_eet_free_ref(Eet_Free *ef) -{ - ef->ref++; -} - -static void -_eet_free_unref(Eet_Free *ef) -{ - ef->ref--; -} - -#define _eet_freelist_add(Ctx, Data) _eet_free_add(&Ctx->freelist, Data); -#define _eet_freelist_del(Ctx, Data) _eet_free_del(&Ctx->freelist, Data); -#define _eet_freelist_reset(Ctx) _eet_free_reset(&Ctx->freelist); -#define _eet_freelist_ref(Ctx) _eet_free_ref(&Ctx->freelist); -#define _eet_freelist_unref(Ctx) _eet_free_unref(&Ctx->freelist); - -static void -_eet_freelist_free(Eet_Free_Context *context, - Eet_Data_Descriptor *edd) -{ - void *track; - Eina_Array_Iterator it; - unsigned int j; - unsigned int i; - - if (context->freelist.ref > 0) - return; - - for (j = 0; j < EET_FREE_COUNT; ++j) - EINA_ARRAY_ITER_NEXT(&context->freelist.list[j], i, track, it) - if (track) - { - if (edd) - edd->func.mem_free(track); - else - free(track); - } - _eet_free_reset(&context->freelist); -} - -#define _eet_freelist_array_add(Ctx, Data) _eet_free_add(&Ctx->freelist_array, Data); -#define _eet_freelist_array_del(Ctx, Data) _eet_free_del(&Ctx->freelist_array, Data); -#define _eet_freelist_array_reset(Ctx) _eet_free_reset(&Ctx->freelist_array); -#define _eet_freelist_array_ref(Ctx) _eet_free_ref(&Ctx->freelist_array); -#define _eet_freelist_array_unref(Ctx) _eet_free_unref(&Ctx->freelist_array); - -static void -_eet_freelist_array_free(Eet_Free_Context *context, - Eet_Data_Descriptor *edd) -{ - void *track; - Eina_Array_Iterator it; - unsigned int j; - unsigned int i; - - if (context->freelist_array.ref > 0) - return; - - for (j = 0; j < EET_FREE_COUNT; ++j) - EINA_ARRAY_ITER_NEXT(&context->freelist_array.list[j], i, track, it) - if (track) - { - if (edd) - { - if (edd->func.array_free) - edd->func.array_free(track); - else - edd->func.mem_free(track); - } - else - free(track); - } - _eet_free_reset(&context->freelist_array); -} - -#define _eet_freelist_list_add(Ctx, Data) _eet_free_add(&Ctx->freelist_list, Data); -#define _eet_freelist_list_del(Ctx, Data) _eet_free_del(&Ctx->freelist_list, Data); -#define _eet_freelist_list_reset(Ctx) _eet_free_reset(&Ctx->freelist_list); -#define _eet_freelist_list_ref(Ctx) _eet_free_ref(&Ctx->freelist_list); -#define _eet_freelist_list_unref(Ctx) _eet_free_unref(&Ctx->freelist_list); - -static void -_eet_freelist_list_free(Eet_Free_Context *context, - Eet_Data_Descriptor *edd) -{ - void *track; - Eina_Array_Iterator it; - unsigned int j; - unsigned int i; - - if (context->freelist_list.ref > 0) - return; - - for (j = 0; j < EET_FREE_COUNT; ++j) - EINA_ARRAY_ITER_NEXT(&context->freelist_list.list[j], i, track, it) - if (track) - { - if (edd) - edd->func.list_free(*((void **)(track))); - } - _eet_free_reset(&context->freelist_list); -} - -#define _eet_freelist_str_add(Ctx, Data) _eet_free_add(&Ctx->freelist_str, Data); -#define _eet_freelist_str_del(Ctx, Data) _eet_free_del(&Ctx->freelist_str, Data); -#define _eet_freelist_str_reset(Ctx) _eet_free_reset(&Ctx->freelist_str); -#define _eet_freelist_str_ref(Ctx) _eet_free_ref(&Ctx->freelist_str); -#define _eet_freelist_str_unref(Ctx) _eet_free_unref(&Ctx->freelist_str); - -static void -_eet_freelist_str_free(Eet_Free_Context *context, - Eet_Data_Descriptor *edd) -{ - void *track; - Eina_Array_Iterator it; - unsigned int j; - unsigned int i; - - if (context->freelist_str.ref > 0) - return; - - for (j = 0; j < EET_FREE_COUNT; ++j) - EINA_ARRAY_ITER_NEXT(&context->freelist_str.list[j], i, track, it) - if (track) - { - if (edd) - edd->func.str_free(track); - else - free(track); - } - _eet_free_reset(&context->freelist_str); -} - -#define _eet_freelist_direct_str_add(Ctx, Data) _eet_free_add(&Ctx->freelist_direct_str, Data); -#define _eet_freelist_direct_str_del(Ctx, Data) _eet_free_del(&Ctx->freelist_direct_str, Data); -#define _eet_freelist_direct_str_reset(Ctx) _eet_free_reset(&Ctx->freelist_direct_str); -#define _eet_freelist_direct_str_ref(Ctx) _eet_free_ref(&Ctx->freelist_direct_str); -#define _eet_freelist_direct_str_unref(Ctx) _eet_free_unref(&Ctx->freelist_direct_str); - -static void -_eet_freelist_direct_str_free(Eet_Free_Context *context, - Eet_Data_Descriptor *edd) -{ - void *track; - Eina_Array_Iterator it; - unsigned int j; - unsigned int i; - - if (context->freelist_direct_str.ref > 0) - return; - - for (j = 0; j < EET_FREE_COUNT; ++j) - EINA_ARRAY_ITER_NEXT(&context->freelist_str.list[j], i, track, it) - if (track) - { - if (edd) - edd->func.str_direct_free(track); - else - free(track); - } - _eet_free_reset(&context->freelist_direct_str); -} - -#define _eet_freelist_hash_add(Ctx, Data) _eet_free_add(&Ctx->freelist_hash, Data); -#define _eet_freelist_hash_del(Ctx, Data) _eet_free_del(&Ctx->freelist_hash, Data); -#define _eet_freelist_hash_reset(Ctx) _eet_free_reset(&Ctx->freelist_hash); -#define _eet_freelist_hash_ref(Ctx) _eet_free_ref(&Ctx->freelist_hash); -#define _eet_freelist_hash_unref(Ctx) _eet_free_unref(&Ctx->freelist_hash); - -static void -_eet_freelist_hash_free(Eet_Free_Context *context, - Eet_Data_Descriptor *edd) -{ - void *track; - Eina_Array_Iterator it; - unsigned int j; - unsigned int i; - - if (context->freelist_hash.ref > 0) - return; - - for (j = 0; j < EET_FREE_COUNT; ++j) - EINA_ARRAY_ITER_NEXT(&context->freelist_hash.list[j], i, track, it) - if (track) - { - if (edd) - edd->func.hash_free(track); - else - free(track); - } - _eet_free_reset(&context->freelist_hash); -} - -static void -_eet_freelist_all_ref(Eet_Free_Context *freelist_context) -{ - _eet_freelist_ref(freelist_context); - _eet_freelist_str_ref(freelist_context); - _eet_freelist_list_ref(freelist_context); - _eet_freelist_hash_ref(freelist_context); - _eet_freelist_direct_str_ref(freelist_context); -} - -static void -_eet_freelist_all_unref(Eet_Free_Context *freelist_context) -{ - _eet_freelist_unref(freelist_context); - _eet_freelist_str_unref(freelist_context); - _eet_freelist_list_unref(freelist_context); - _eet_freelist_hash_unref(freelist_context); - _eet_freelist_direct_str_unref(freelist_context); -} - -static int -eet_data_descriptor_encode_hash_cb(void *hash __UNUSED__, - const char *cipher_key, - void *hdata, - void *fdata) -{ - Eet_Dictionary *ed; - Eet_Data_Encode_Hash_Info *edehi; - Eet_Data_Stream *ds; - Eet_Data_Element *ede; - Eet_Data_Chunk *echnk; - void *data = NULL; - int size; - - edehi = fdata; - ede = edehi->ede; - ds = edehi->ds; - ed = edehi->ed; - - /* Store key */ - data = eet_data_put_type(ed, - EET_T_STRING, - &cipher_key, - &size); - if (data) - { - echnk = eet_data_chunk_new(data, - size, - ede->name, - ede->type, - ede->group_type); - eet_data_chunk_put(ed, echnk, ds); - eet_data_chunk_free(echnk); - free(data); - data = NULL; - } - - EET_ASSERT(!((ede->type > EET_T_UNKNOW) && (ede->type < EET_T_STRING)), return ); - - /* Store data */ - if (ede->type >= EET_T_STRING) - eet_data_put_unknown(ed, NULL, ede, ds, &hdata); - else - { - if (ede->subtype) - data = _eet_data_descriptor_encode(ed, - ede->subtype, - hdata, - &size); - - if (data) - { - echnk = eet_data_chunk_new(data, - size, - ede->name, - ede->type, - ede->group_type); - eet_data_chunk_put(ed, echnk, ds); - eet_data_chunk_free(echnk); - free(data); - data = NULL; - } - } - - return 1; -} - -static char * -_eet_data_dump_token_get(const char *src, - int *len) -{ - const char *p; - char *tok = NULL; - int in_token = 0; - int in_quote = 0; - int tlen = 0, tsize = 0; - -#define TOK_ADD(x) \ - do { \ - tlen++; \ - if (tlen >= tsize) \ - { \ - tsize += 32; \ - tok = realloc(tok, tsize); \ - } \ - tok[tlen - 1] = x; \ - } while (0) - - for (p = src; *len > 0; p++, (*len)--) - { - if (in_token) - { - if (in_quote) - { - if ((p[0] == '\"') && (p > src) && (p[-1] != '\\')) - in_quote = 0; - else if ((p[0] == '\\') && (*len > 1) && - (p[1] == '\"')) - { -/* skip */ - } - else if ((p[0] == '\\') && (p > src) && (p[-1] == '\\')) - { -/* skip */ - } - else if ((p[0] == '\\') && (*len > 1) && (p[1] == 'n')) - { -/* skip */ - } - else if ((p[0] == 'n') && (p > src) && (p[-1] == '\\')) - TOK_ADD('\n'); - else - TOK_ADD(p[0]); - } - else - { - if (p[0] == '\"') - in_quote = 1; - else - { - if ((isspace(p[0])) || (p[0] == ';')) /* token ends here */ - { - TOK_ADD(0); - (*len)--; - return tok; - } - else - TOK_ADD(p[0]); - } - } - } - else if (!((isspace(p[0])) || (p[0] == ';'))) - { - in_token = 1; - (*len)++; - p--; - } - } - if (in_token) - { - TOK_ADD(0); - return tok; - } - - if (tok) - free(tok); - - return NULL; -} - -static void -eet_data_encode(Eet_Dictionary *ed, - Eet_Data_Stream *ds, - void *data, - const char *name, - int size, - int type, - int group_type) -{ - Eet_Data_Chunk *echnk; - - if (!data) - type = EET_T_NULL; - - if (group_type != EET_G_UNKNOWN) - if (type >= EET_T_LAST) - type = EET_T_UNKNOW; - - echnk = eet_data_chunk_new(data, size, name, type, group_type); - eet_data_chunk_put(ed, echnk, ds); - eet_data_chunk_free(echnk); - free(data); -} - -static void * -_eet_data_dump_encode(int parent_type, - Eet_Dictionary *ed, - Eet_Node *node, - int *size_ret) -{ - Eet_Data_Chunk *chnk = NULL; - Eet_Data_Stream *ds; - void *cdata, *data; - int csize, size; - int count; - int child_type; - Eet_Node *n; - - if (_eet_data_words_bigendian == -1) - { - unsigned long int v; - - v = htonl(0x12345678); - if (v == 0x12345678) - _eet_data_words_bigendian = 1; - else - _eet_data_words_bigendian = 0; - } - - if (!node) - return NULL; - - ds = eet_data_stream_new(); - if (!ds) - return NULL; - - switch (node->type) - { - case EET_G_UNKNOWN: - for (n = node->values; n; n = n->next) - { - data = _eet_data_dump_encode(node->type, ed, n, &size); - if (data) - { - eet_data_stream_write(ds, data, size); - free(data); - } - } - break; - - case EET_G_ARRAY: - case EET_G_VAR_ARRAY: - for (child_type = EET_T_NULL, n = node->values; n; n = n->next) - { - if (n->type != EET_T_NULL) - { - child_type = n->type; - break; - } - } - - data = eet_data_put_type(ed, - EET_T_INT, - &node->count, - &size); - eet_data_encode(ed, - ds, - data, - node->name, - size, - child_type, - node->type); - - count = node->count; - - for (n = node->values; n; n = n->next) - { - int pos = ds->pos; - - switch (n->type) - { - case EET_T_STRING: - case EET_T_INLINED_STRING: - data = eet_data_put_type(ed, - n->type, - &(n->data.value.str), - &size); - if (data) - eet_data_encode(ed, - ds, - data, - node->name, - size, - n->type, - node->type); - - break; - - case EET_T_NULL: - continue; - - default: - data = _eet_data_dump_encode(n->type, ed, n, &size); - eet_data_encode(ed, - ds, - data, - node->name, - size, - n->type, - node->type); - break; - } /* switch */ - if (ds->pos != pos) - count--; - } - - for (; count; count--) - { - eet_data_encode(ed, - ds, - NULL, - node->name, - 0, - EET_T_NULL, - node->type); - } - - /* Array is somekind of special case, so we should embed it inside another chunk. */ - *size_ret = ds->pos; - cdata = ds->data; - - ds->data = NULL; - ds->size = 0; - eet_data_stream_free(ds); - - return cdata; - break; - - case EET_G_LIST: - for (n = node->values; n; n = n->next) - { - switch (n->type) - { - case EET_T_STRING: - case EET_T_INLINED_STRING: - data = eet_data_put_type(ed, - n->type, - &(n->data.value.str), - &size); - if (data) - eet_data_encode(ed, - ds, - data, - node->name, - size, - n->type, - node->type); - - break; - - case EET_T_NULL: - continue; - - default: - data = _eet_data_dump_encode(node->type, ed, n, &size); - eet_data_encode(ed, - ds, - data, - node->name, - size, - n->type, - node->type); - } /* switch */ - } - - /* List is another somekind of special case, every chunk is embed inside a list chunk. */ - *size_ret = ds->pos; - cdata = ds->data; - - ds->data = NULL; - ds->size = 0; - eet_data_stream_free(ds); - - return cdata; - break; - - case EET_G_HASH: - if (node->key) - { - data = eet_data_put_type(ed, - EET_T_STRING, - &node->key, - &size); - eet_data_encode(ed, - ds, - data, - node->name, - size, - node->type, - node->type); - } - else - /* A Hash without key will not decode correctly. */ - return NULL; - - for (n = node->values; n; n = n->next) - { - switch (n->type) - { - case EET_T_STRING: - case EET_T_INLINED_STRING: - data = eet_data_put_type(ed, - n->type, - &(n->data.value.str), - &size); - if (data) - eet_data_encode(ed, - ds, - data, - node->name, - size, - n->type, - node->type); - - break; - - case EET_T_NULL: - continue; - - default: - data = _eet_data_dump_encode(node->type, ed, n, &size); - eet_data_encode(ed, - ds, - data, - node->name, - size, - n->type, - node->type); - } /* switch */ - } - - /* Hash is somekind of special case, so we should embed it inside another chunk. */ - *size_ret = ds->pos; - cdata = ds->data; - - eet_data_stream_flush(ds); - - return cdata; - - case EET_T_NULL: - break; - -#define EET_DATA_NODE_ENCODE(Eet_Type, Type) \ -case Eet_Type: \ - data = eet_data_put_type(ed, node->type, &(node->data.value.Type), &size); \ - if (data) \ - { \ - eet_data_encode(ed, \ - ds, \ - data, \ - node->name, \ - size, \ - node->type, \ - parent_type); \ - cdata = ds->data; \ - *size_ret = ds->pos; \ - eet_data_stream_flush(ds); \ - return cdata; \ - } /* switch */ \ - break; - - EET_DATA_NODE_ENCODE(EET_T_CHAR, c); - EET_DATA_NODE_ENCODE(EET_T_SHORT, s); - EET_DATA_NODE_ENCODE(EET_T_INT, i); - EET_DATA_NODE_ENCODE(EET_T_LONG_LONG, l); - EET_DATA_NODE_ENCODE(EET_T_FLOAT, f); - EET_DATA_NODE_ENCODE(EET_T_DOUBLE, d); - EET_DATA_NODE_ENCODE(EET_T_UCHAR, uc); - EET_DATA_NODE_ENCODE(EET_T_USHORT, us); - EET_DATA_NODE_ENCODE(EET_T_UINT, ui); - EET_DATA_NODE_ENCODE(EET_T_ULONG_LONG, ul); - EET_DATA_NODE_ENCODE(EET_T_INLINED_STRING, str); - EET_DATA_NODE_ENCODE(EET_T_STRING, str); - - default: - break; - } - - if ((node->type >= EET_G_UNKNOWN) && (node->type < EET_G_LAST)) - chnk = eet_data_chunk_new(ds->data, - ds->pos, - node->name, - EET_T_UNKNOW, - node->type); - else - chnk = eet_data_chunk_new(ds->data, - ds->pos, - node->name, - node->type, - EET_G_UNKNOWN); - - eet_data_stream_flush(ds); - - ds = eet_data_stream_new(); - eet_data_chunk_put(ed, chnk, ds); - cdata = ds->data; - csize = ds->pos; - - eet_data_stream_flush(ds); - *size_ret = csize; - - free(chnk->data); - eet_data_chunk_free(chnk); - - return cdata; -} - -static void * -_eet_data_dump_parse(Eet_Dictionary *ed, - int *size_ret, - const char *src, - int size) -{ - void *cdata = NULL; - const char *p = NULL; -#define M_NONE 0 -#define M_STRUCT 1 -#define M_ 2 - int left, jump; - Eet_Node *node_base = NULL; - Eet_Node *node = NULL; - Eet_Node *n = NULL, *nn = NULL; - - /* FIXME; handle parse errors */ -#define TOK_GET(t) \ - jump = left; t = _eet_data_dump_token_get(p, &left); p += jump - left; - left = size; - for (p = src; p < (src + size); ) - { - char *tok1, *tok2, *tok3, *tok4; - - TOK_GET(tok1); - if (tok1) - { - if (!strcmp(tok1, "group")) - { - TOK_GET(tok2); - if (tok2) - { - TOK_GET(tok3); - if (tok3) - { - TOK_GET(tok4); - if (tok4) - { - if (!strcmp(tok4, "{")) - { -/* we have 'group NAM TYP {' */ - n = eet_node_new(); - if (n) - { - n->parent = node; - if (!node_base) - node_base = n; - - if (node) - { -/* append node */ - if (!node->values) - node->values = n; - else - for (nn = node->values; nn; - nn = nn->next) - { - if (!nn->next) - { - nn->next = n; - break; - } - } - } - - n->name = eina_stringshare_add(tok2); - if (!strcmp(tok3, "struct")) - n->type = EET_G_UNKNOWN; - else if (!strcmp(tok3, "array")) - n->type = EET_G_ARRAY; - else if (!strcmp(tok3, "var_array")) - n->type = EET_G_VAR_ARRAY; - else if (!strcmp(tok3, "list")) - n->type = EET_G_LIST; - else if (!strcmp(tok3, "hash")) - n->type = EET_G_HASH; - else - ERR( - "ERROR: group type '%s' invalid.", - tok3); - - node = n; - } - } - - free(tok4); - } - - free(tok3); - } - - free(tok2); - } - } - else if (!strcmp(tok1, "value")) - { - TOK_GET(tok2); - if (tok2) - { - TOK_GET(tok3); - if (tok3) - { - TOK_GET(tok4); - if (tok4) - { -/* we have 'value NAME TYP XXX' */ - if (node_base) - { - n = eet_node_new(); - if (n) - { - n->parent = node; -/* append node */ - if (!node->values) - node->values = n; - else - for (nn = node->values; nn; - nn = nn->next) - { - if (!nn->next) - { - nn->next = n; - break; - } - } - - n->name = eina_stringshare_add(tok2); - if (!strcmp(tok3, "char:")) - { - n->type = EET_T_CHAR; - sscanf(tok4, "%hhi", - &(n->data.value.c)); - } - else if (!strcmp(tok3, "short:")) - { - n->type = EET_T_SHORT; - sscanf(tok4, "%hi", - &(n->data.value.s)); - } - else if (!strcmp(tok3, "int:")) - { - n->type = EET_T_INT; - sscanf(tok4, "%i", - &(n->data.value.i)); - } - else if (!strcmp(tok3, "long_long:")) - { - n->type = EET_T_LONG_LONG; - sscanf(tok4, "%lli", - &(n->data.value.l)); - } - else if (!strcmp(tok3, "float:")) - { - n->type = EET_T_FLOAT; - sscanf(tok4, "%f", - &(n->data.value.f)); - } - else if (!strcmp(tok3, "double:")) - { - n->type = EET_T_DOUBLE; - sscanf(tok4, "%lf", - &(n->data.value.d)); - } - else if (!strcmp(tok3, "uchar:")) - { - n->type = EET_T_UCHAR; - sscanf(tok4, "%hhu", - &(n->data.value.uc)); - } - else if (!strcmp(tok3, "ushort:")) - { - n->type = EET_T_USHORT; - sscanf(tok4, "%hu", - &(n->data.value.us)); - } - else if (!strcmp(tok3, "uint:")) - { - n->type = EET_T_UINT; - sscanf(tok4, "%u", - &(n->data.value.ui)); - } - else if (!strcmp(tok3, "ulong_long:")) - { - n->type = EET_T_ULONG_LONG; - sscanf(tok4, "%llu", - &(n->data.value.ul)); - } - else if (!strcmp(tok3, "string:")) - { - n->type = EET_T_STRING; - n->data.value.str = - eina_stringshare_add(tok4); - } - else if (!strcmp(tok3, "inlined:")) - { - n->type = EET_T_INLINED_STRING; - n->data.value.str = - eina_stringshare_add(tok4); - } - else if (!strcmp(tok3, "null")) - { - n->type = EET_T_NULL; - n->data.value.str = NULL; - } - else - ERR( - "ERROR: value type '%s' invalid.", - tok4); - } - } - - free(tok4); - } - - free(tok3); - } - - free(tok2); - } - } - else if (!strcmp(tok1, "key")) - { - TOK_GET(tok2); - if (tok2) - { -/* we have 'key NAME' */ - if (node) - node->key = eina_stringshare_add(tok2); - - free(tok2); - } - } - else if (!strcmp(tok1, "count")) - { - TOK_GET(tok2); - if (tok2) - { -/* we have a 'count COUNT' */ - if (node) - sscanf(tok2, "%i", &(node->count)); - - free(tok2); - } - } - else if (!strcmp(tok1, "}")) - /* we have an end of the group */ - if (node) - node = node->parent; - - free(tok1); - } - } - - if (node_base) - { - cdata = _eet_data_dump_encode(EET_G_UNKNOWN, ed, node_base, size_ret); - eet_node_del(node_base); - } - - return cdata; -} - -#define NEXT_CHUNK(P, Size, Echnk, Ed) \ - { \ - int __tmp; \ - __tmp = Ed ? (int)(sizeof(int) * 2) : Echnk.len + 4; \ - P += (4 + Echnk.size + __tmp); \ - Size -= (4 + Echnk.size + __tmp); \ - } - -static void * -_eet_data_descriptor_decode(Eet_Free_Context *context, - const Eet_Dictionary *ed, - Eet_Data_Descriptor *edd, - const void *data_in, - int size_in, - void *data_out, - int size_out) -{ - Eet_Node *result = NULL; - void *data = NULL; - char *p; - int size, i; - Eet_Data_Chunk chnk; - - if (_eet_data_words_bigendian == -1) - { - unsigned long int v; - - v = htonl(0x12345678); - if (v == 0x12345678) - _eet_data_words_bigendian = 1; - else - _eet_data_words_bigendian = 0; - } - - if (edd) - { - if (data_out) - { - if (size_out <= edd->size) - data = data_out; - } - else - { - data = edd->func.mem_alloc(edd->size); - } - - if (!data) - return NULL; - - if (edd->ed != ed) - { - for (i = 0; i < edd->elements.num; i++) - edd->elements.set[i].directory_name_ptr = NULL; - edd->ed = ed; - } - } - - _eet_freelist_all_ref(context); - if (data && !data_out) - _eet_freelist_add(context, data); - - memset(&chnk, 0, sizeof(Eet_Data_Chunk)); - eet_data_chunk_get(ed, &chnk, data_in, size_in); - if (!chnk.name) - goto error; - - if (edd) - if (strcmp(chnk.name, edd->name)) - goto error; - - p = chnk.data; - if (ed) - size = size_in - (4 + sizeof(int) * 2); - else - size = size_in - (4 + 4 + chnk.len); - - if (edd) - { - if (!edd->elements.hash.buckets) - _eet_descriptor_hash_new(edd); - } - else - { - switch (chnk.group_type) - { - case EET_G_UNKNOWN: - switch (chnk.type) - { - case EET_T_STRING: - return eet_node_string_new(chnk.name, chnk.data); - - case EET_T_INLINED_STRING: - return eet_node_inlined_string_new(chnk.name, chnk.data); - - case EET_T_NULL: - return eet_node_null_new(chnk.name); - - default: - result = eet_node_struct_new(chnk.name, NULL); - } /* switch */ - break; - - case EET_G_VAR_ARRAY: - return eet_node_var_array_new(chnk.name, NULL); - - case EET_G_LIST: - case EET_G_HASH: - case EET_G_ARRAY: - case EET_G_UNION: - case EET_G_VARIANT: - default: - goto error; - } - } - - while (size > 0) - { - Eet_Data_Chunk echnk; - Eet_Data_Element *ede = NULL; - Eet_Node *child = NULL; - int group_type = EET_G_UNKNOWN, type = EET_T_UNKNOW; - int ret = 0; - - /* get next data chunk */ - memset(&echnk, 0, sizeof(Eet_Data_Chunk)); - eet_data_chunk_get(ed, &echnk, p, size); - if (!echnk.name) - goto error; /* FIXME: don't REPLY on edd - work without */ - - if (edd) - { - ede = _eet_descriptor_hash_find(edd, echnk.name, echnk.hash); - if (ede) - { - group_type = ede->group_type; - type = ede->type; - if ((echnk.type == 0) && (echnk.group_type == 0)) - { - type = ede->type; - group_type = ede->group_type; - } - else - { - if (IS_SIMPLE_TYPE(echnk.type) && - eet_data_type_match(echnk.type, ede->type)) -/* Needed when converting on the fly from FP to Float */ - type = ede->type; - else if ((echnk.group_type > EET_G_UNKNOWN) && - (echnk.group_type < EET_G_LAST) && - (echnk.group_type == ede->group_type)) - group_type = echnk.group_type; - } - } - } - /*...... dump to node */ - else - { - type = echnk.type; - group_type = echnk.group_type; - } - - if (!edd && group_type == EET_G_UNKNOWN && IS_SIMPLE_TYPE(type)) - { - unsigned char dd[128]; - - ret = eet_data_get_type(ed, - type, - echnk.data, - ((char *)echnk.data) + echnk.size, - dd); - if (ret <= 0) - goto error; - - child = eet_data_node_simple_type(type, echnk.name, dd); - - eet_node_struct_append(result, echnk.name, child); - } - else - { - ret = eet_group_codec[group_type - 100].get( - context, - ed, - edd, - ede, - &echnk, - type, - group_type, - ede ? (void *)(((char *)data) + ede->offset) : (void **)&result, - &p, - &size); - - if (ret <= 0) - goto error; - } - - /* advance to next chunk */ - NEXT_CHUNK(p, size, echnk, ed); - } - - _eet_freelist_all_unref(context); - if (!edd) - { - _eet_freelist_str_free(context, edd); - _eet_freelist_direct_str_free(context, edd); - _eet_freelist_list_free(context, edd); - _eet_freelist_hash_free(context, edd); - _eet_freelist_array_free(context, edd); - _eet_freelist_free(context, edd); - } - else - { - _eet_freelist_reset(context); - _eet_freelist_str_reset(context); - _eet_freelist_list_reset(context); - _eet_freelist_hash_reset(context); - _eet_freelist_direct_str_reset(context); - _eet_freelist_array_reset(context); - } - - if (!edd) - return result; - - return data; - -error: - eet_node_del(result); - - _eet_freelist_all_unref(context); - _eet_freelist_str_free(context, edd); - _eet_freelist_direct_str_free(context, edd); - _eet_freelist_list_free(context, edd); - _eet_freelist_hash_free(context, edd); - _eet_freelist_array_free(context, edd); - _eet_freelist_free(context, edd); - - /* FIXME: Warn that something goes wrong here. */ - return NULL; -} - -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 __UNUSED__, - void *data, - char **p, - int *size) -{ - Eet_Data_Descriptor *subtype = NULL; - void *list = NULL; - void **ptr; - void *data_ret; - - EET_ASSERT(!((type > EET_T_UNKNOW) && (type < EET_T_STRING)), return 0); - - if (ede) - { - subtype = ede->subtype; - - if (type != ede->type) - return 0; - } - - ptr = (void **)data; - list = *ptr; - data_ret = NULL; - - if (IS_POINTER_TYPE(type)) - POINTER_TYPE_DECODE(context, - ed, - edd, - ede, - echnk, - type, - &data_ret, - p, - size, - on_error); - else - STRUCT_TYPE_DECODE(data_ret, - context, - ed, - subtype, - echnk->data, - echnk->size, - -1, - on_error); - - if (edd) - { - list = edd->func.list_append(list, data_ret); - *ptr = list; - _eet_freelist_list_add(context, ptr); - } - else - eet_node_list_append(*((Eet_Node **)data), echnk->name, data_ret); - - return 1; - -on_error: - return 0; -} - -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 __UNUSED__, - void *data, - char **p, - int *size) -{ - void **ptr; - void *hash = NULL; - char *key = NULL; - void *data_ret = NULL; - int ret = 0; - - EET_ASSERT(!((type > EET_T_UNKNOW) && (type < EET_T_STRING)), return 0); - - ptr = (void **)data; - hash = *ptr; - - /* Read key */ - ret = eet_data_get_type(ed, - EET_T_STRING, - echnk->data, - ((char *)echnk->data) + echnk->size, - &key); - if (ret <= 0) - goto on_error; - - if (!key) - goto on_error; - - /* Advance to next chunk */ - NEXT_CHUNK((*p), (*size), (*echnk), ed); - memset(echnk, 0, sizeof(Eet_Data_Chunk)); - - /* Read value */ - eet_data_chunk_get(ed, echnk, *p, *size); - if (!echnk->name) - goto on_error; - - if (ede) - if ((ede->group_type != echnk->group_type) - || (ede->type != echnk->type)) - goto on_error; - - if (IS_POINTER_TYPE(echnk->type)) - POINTER_TYPE_DECODE(context, - ed, - edd, - ede, - echnk, - echnk->type, - &data_ret, - p, - size, - on_error); - else - STRUCT_TYPE_DECODE(data_ret, - context, - ed, - ede ? ede->subtype : NULL, - echnk->data, - echnk->size, - -1, - on_error); - - if (edd) - { - hash = edd->func.hash_add(hash, key, data_ret); - *ptr = hash; - _eet_freelist_hash_add(context, hash); - } - else - eet_node_hash_add(*((Eet_Node **)data), echnk->name, key, data_ret); - - return 1; - -on_error: - return 0; -} - -/* var arrays and fixed arrays have to - * get all chunks at once. for fixed arrays - * we can get each chunk and increment a - * counter stored on the element itself but - * it wont be thread safe. for var arrays - * we still need a way to get the number of - * elements from the data, so storing the - * number of elements and the element data on - * each chunk is pointless. - */ -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) -{ - Eina_List *childs = NULL; - const char *name; - Eet_Node *tmp; - void *ptr; - int count; - int ret; - int subsize = 0; - int i; - - EET_ASSERT(!((type > EET_T_UNKNOW) && (type < EET_T_STRING)), return 0); - - ptr = data; - /* read the number of elements */ - ret = eet_data_get_type(ed, - EET_T_INT, - echnk->data, - ((char *)echnk->data) + echnk->size, - &count); - if (ret <= 0) - return ret; - - name = echnk->name; - - if (ede) - { - if (IS_POINTER_TYPE(type)) - subsize = eet_basic_codec[ede->type].size; - else - subsize = ede->subtype->size; - - if (group_type == EET_G_VAR_ARRAY) - { - /* store the number of elements - * on the counter offset */ - *(int *)(((char *)data) + ede->count - ede->offset) = count; - /* allocate space for the array of elements */ - if (edd->func.array_alloc) - *(void **)ptr = edd->func.array_alloc(count * subsize); - else - *(void **)ptr = edd->func.mem_alloc(count * subsize); - - if (!*(void **)ptr) - return 0; - - memset(*(void **)ptr, 0, count * subsize); - - _eet_freelist_array_add(context, *(void **)ptr); - } - } - - /* get all array elements */ - for (i = 0; i < count; i++) - { - void *dst = NULL; - - /* Advance to next chunk */ - NEXT_CHUNK((*p), (*size), (*echnk), ed); - memset(echnk, 0, sizeof(Eet_Data_Chunk)); - - eet_data_chunk_get(ed, echnk, *p, *size); - if (!echnk->name || strcmp(echnk->name, name) != 0) - goto on_error; /* get the data */ - - if ((echnk->group_type != group_type) - || ((echnk->type != type) && (echnk->type != EET_T_NULL))) - goto on_error; - - if (ede) - if ((ede->group_type != echnk->group_type) - || ((echnk->type != ede->type) && (echnk->type != EET_T_NULL))) - goto on_error; - - /* get the destination pointer */ - if (ede) - { - if (group_type == EET_G_ARRAY) - dst = (char *)ptr + (subsize * i); - else - dst = *(char **)ptr + (subsize * i); - } - - if (IS_POINTER_TYPE(echnk->type)) - { - void *data_ret = NULL; - - POINTER_TYPE_DECODE(context, - ed, - edd, - ede, - echnk, - echnk->type, - &data_ret, - p, - size, - on_error); - if (dst) - memcpy(dst, &data_ret, subsize); - - if (!edd) - childs = eina_list_append(childs, data_ret); - } - else - { - STRUCT_TYPE_DECODE(dst, - context, - ed, - ede ? ede->subtype : NULL, - echnk->data, - echnk->size, - subsize, - on_error); - - if (!edd) - childs = eina_list_append(childs, dst); - } - } - - if (!edd) - { - Eet_Node *parent = *((Eet_Node **)data); - Eet_Node *array; - - if (group_type == EET_G_ARRAY) - array = eet_node_array_new(name, count, childs); - else - array = eet_node_var_array_new(name, childs); - - if (!array) - goto on_error; - - eet_node_struct_append(parent, name, array); - } - - return 1; - -on_error: - EINA_LIST_FREE(childs, tmp) - eet_node_del(tmp); - - return 0; -} - -static void -eet_data_put_union(Eet_Dictionary *ed, - Eet_Data_Descriptor *edd __UNUSED__, - Eet_Data_Element *ede, - Eet_Data_Stream *ds, - void *data_in) -{ - const char *union_type; - int i; - - EET_ASSERT(!((ede->type != EET_T_UNKNOW) || (!ede->subtype)), return ); - - union_type = ede->subtype->func.type_get( - ((char *)data_in) + ede->count - ede->offset, - NULL); - - if (!union_type) - return; - - /* Search the structure of the union to encode. */ - for (i = 0; i < ede->subtype->elements.num; ++i) - if (strcmp(ede->subtype->elements.set[i].name, union_type) == 0) - { - Eet_Data_Element *sede; - void *data; - int size; - - /* Yeah we found it ! */ - data = eet_data_put_type(ed, EET_T_STRING, &union_type, &size); - if (data) - eet_data_encode(ed, - ds, - data, - ede->name, - size, - ede->type, - ede->group_type); - - sede = &(ede->subtype->elements.set[i]); - data = _eet_data_descriptor_encode(ed, - sede->subtype, - data_in, - &size); - if (data) - eet_data_encode(ed, - ds, - data, - ede->name, - size, - ede->type, - ede->group_type); - - break; - } -} - -static int -eet_data_get_union(Eet_Free_Context *context, - const Eet_Dictionary *ed, - Eet_Data_Descriptor *edd __UNUSED__, - Eet_Data_Element *ede, - Eet_Data_Chunk *echnk, - int type, - int group_type, - void *data, - char **p, - int *size) -{ - const char *union_type; - void *data_ret = NULL; - int ret = 0; - int i; - - /* Read type */ - ret = eet_data_get_type(ed, - EET_T_STRING, - echnk->data, - ((char *)echnk->data) + echnk->size, - &union_type); - if (ret <= 0) - goto on_error; - - /* Advance to next chunk */ - NEXT_CHUNK((*p), (*size), (*echnk), ed); - memset(echnk, 0, sizeof(Eet_Data_Chunk)); - - /* Read value */ - eet_data_chunk_get(ed, echnk, *p, *size); - if (!echnk->name) - goto on_error; - - if (ede) - { - EET_ASSERT(!(ede->group_type != group_type || ede->type != type), - goto on_error); - - /* Search the structure of the union to decode */ - for (i = 0; i < ede->subtype->elements.num; ++i) - if (strcmp(ede->subtype->elements.set[i].name, union_type) == 0) - { - Eet_Data_Element *sede; - char *ut; - - /* Yeah we found it ! */ - sede = &(ede->subtype->elements.set[i]); - EET_ASSERT(sede->subtype, goto on_error); - - data_ret = _eet_data_descriptor_decode(context, - ed, - sede->subtype, - echnk->data, - echnk->size, - data, - sede->subtype->size); - if (!data_ret) - goto on_error; - - /* Set union type. */ - if ((!ed) || (!ede->subtype->func.str_direct_alloc)) - { - ut = ede->subtype->func.str_alloc(union_type); - _eet_freelist_str_add(context, ut); - } - else - { - ut = ede->subtype->func.str_direct_alloc(union_type); - _eet_freelist_direct_str_add(context, ut); - } - - ede->subtype->func.type_set( - ut, - ((char *)data) + ede->count - - ede->offset, - EINA_FALSE); - - break; - } - } - else - { - /* FIXME: generate node structure. */ - data_ret = _eet_data_descriptor_decode(context, - ed, NULL, - echnk->data, echnk->size, - NULL, 0); - goto on_error; - } - - return 1; - -on_error: - return 0; -} - -static void -eet_data_put_variant(Eet_Dictionary *ed, - Eet_Data_Descriptor *edd __UNUSED__, - Eet_Data_Element *ede, - Eet_Data_Stream *ds, - void *data_in) -{ - const char *union_type; - void *data; - Eina_Bool unknow = EINA_FALSE; - int size; - int i; - - EET_ASSERT(!((ede->type != EET_T_UNKNOW) || (!ede->subtype)), return ); - - union_type = ede->subtype->func.type_get( - ((char *)data_in) + ede->count - ede->offset, - &unknow); - - if (!union_type && unknow == EINA_FALSE) - return; - - if (unknow) - { - /* Handle opaque internal representation */ - Eet_Variant_Unknow *evu; - - data = eet_data_put_type(ed, EET_T_STRING, &union_type, &size); - if (data) - eet_data_encode(ed, - ds, - data, - ede->name, - size, - ede->type, - ede->group_type); - - evu = (Eet_Variant_Unknow *)data_in; - if (evu && EINA_MAGIC_CHECK(evu, EET_MAGIC_VARIANT)) - eet_data_encode(ed, - ds, - evu->data, - ede->name, - evu->size, - ede->type, - ede->group_type); - } - else - /* Search the structure of the union to encode. */ - for (i = 0; i < ede->subtype->elements.num; ++i) - if (strcmp(ede->subtype->elements.set[i].name, union_type) == 0) - { - Eet_Data_Element *sede; - - /* Yeah we found it ! */ - data = eet_data_put_type(ed, EET_T_STRING, &union_type, &size); - if (data) - eet_data_encode(ed, - ds, - data, - ede->name, - size, - ede->type, - ede->group_type); - - sede = &(ede->subtype->elements.set[i]); - - if (sede->group_type != EET_G_UNKNOWN) - { - Eet_Data_Stream *lds; - - lds = eet_data_stream_new(); - eet_group_codec[sede->group_type - 100].put(ed, - sede->subtype, - sede, - lds, - data_in); - if (lds->size != 0) - { - eet_data_encode(ed, ds, lds->data, ede->name, lds->pos, - ede->type, ede->group_type); - - lds->data = NULL; - lds->size = 0; - } - else - eet_data_encode(ed, ds, NULL, ede->name, 0, - EET_T_NULL, ede->group_type); - - eet_data_stream_free(lds); - } - else - { - data = _eet_data_descriptor_encode(ed, - sede->subtype, - *(void **)data_in, - &size); - if (data) - eet_data_encode(ed, - ds, - data, - ede->name, - size, - ede->type, - ede->group_type); - } - - break; - } -} - -static int -eet_data_get_variant(Eet_Free_Context *context, - const Eet_Dictionary *ed, - Eet_Data_Descriptor *edd __UNUSED__, - Eet_Data_Element *ede, - Eet_Data_Chunk *echnk, - int type __UNUSED__, - int group_type __UNUSED__, - void *data, - char **p, - int *size) -{ - const char *union_type; - void *data_ret = NULL; - int ret = 0; - int i; - - /* Read type */ - ret = eet_data_get_type(ed, - EET_T_STRING, - echnk->data, - ((char *)echnk->data) + echnk->size, - &union_type); - if (ret <= 0) - goto on_error; - - /* Advance to next chunk */ - NEXT_CHUNK((*p), (*size), (*echnk), ed); - memset(echnk, 0, sizeof(Eet_Data_Chunk)); - - /* Read value */ - eet_data_chunk_get(ed, echnk, *p, *size); - if (!echnk->name) - goto on_error; - - if (ede) - { - char *ut; - - EET_ASSERT(ede->subtype, goto on_error); - - if ((!ed) || (!ede->subtype->func.str_direct_alloc)) - { - ut = ede->subtype->func.str_alloc(union_type); - _eet_freelist_str_add(context, ut); - } - else - { - ut = ede->subtype->func.str_direct_alloc(union_type); - _eet_freelist_direct_str_add(context, ut); - } - - /* Search the structure of the union to decode */ - for (i = 0; i < ede->subtype->elements.num; ++i) - if (strcmp(ede->subtype->elements.set[i].name, union_type) == 0) - { - Eet_Data_Element *sede; - - /* Yeah we found it ! */ - sede = &(ede->subtype->elements.set[i]); - - if (sede->group_type != EET_G_UNKNOWN) - { - Eet_Data_Chunk chnk; - char *p2; - int size2; - - p2 = echnk->data; - size2 = echnk->size; - - /* Didn't find a proper way to provide this - without duplicating code */ - while (size2 > 0) - { - memset(&chnk, 0, sizeof(Eet_Data_Chunk)); - eet_data_chunk_get(ed, &chnk, p2, size2); - - if (!chnk.name) - goto on_error; - - ret = eet_group_codec[sede->group_type - 100].get - (context, ed, sede->subtype, sede, &chnk, sede->type, - sede->group_type, data, &p2, &size2); - - if (ret <= 0) - goto on_error; - -/* advance to next chunk */ - NEXT_CHUNK(p2, size2, chnk, ed); - } - - /* Put garbage so that we will not put eet_variant_unknow in it */ - data_ret = (void *)data; - - /* Set variant type. */ - ede->subtype->func.type_set - (ut, ((char *)data) + ede->count - ede->offset, - EINA_FALSE); - break; - } - - data_ret = _eet_data_descriptor_decode(context, - ed, - sede->subtype, - echnk->data, - echnk->size, - NULL, 0); - if (!data_ret) - break; - - /* And point to the variant data. */ - *(void **)data = data_ret; - - /* Set variant type. */ - ede->subtype->func.type_set - (ut, ((char *)data) + ede->count - ede->offset, EINA_FALSE); - break; - } - - if (!data_ret) - { - Eet_Variant_Unknow *evu; - - evu = calloc(1, sizeof (Eet_Variant_Unknow) + echnk->size - 1); - if (!evu) - goto on_error; - - evu->size = echnk->size; - memcpy(evu->data, echnk->data, evu->size); - EINA_MAGIC_SET(evu, EET_MAGIC_VARIANT); - - /* And point to the opaque internal data scructure */ - *(void **)data = evu; - - /* Set variant type. */ - ede->subtype->func.type_set - (ut, ((char *)data) + ede->count - ede->offset, EINA_TRUE); - } - } - else - { - /* FIXME: dump node structure. */ - data_ret = _eet_data_descriptor_decode(context, - ed, NULL, - echnk->data, echnk->size, - NULL, 0); - goto on_error; - } - - return 1; - -on_error: - return 0; -} - -static Eet_Node * -eet_data_node_simple_type(int type, - const char *name, - void *dd) -{ -#ifdef EET_T_TYPE -# undef EET_T_TYPE -#endif /* ifdef EET_T_TYPE */ - -#define EET_T_TYPE(Eet_Type, Eet_Node_Type, Type) \ -case Eet_Type: \ - return eet_node_ ## Eet_Node_Type ## _new(name, *((Type *)dd)); \ - - switch (type) - { - EET_T_TYPE(EET_T_CHAR, char, char); - EET_T_TYPE(EET_T_SHORT, short, short); - EET_T_TYPE(EET_T_INT, int, int); - EET_T_TYPE(EET_T_LONG_LONG, long_long, long long); - EET_T_TYPE(EET_T_FLOAT, float, float); - EET_T_TYPE(EET_T_DOUBLE, double, double); - EET_T_TYPE(EET_T_UCHAR, unsigned_char, unsigned char); - EET_T_TYPE(EET_T_USHORT, unsigned_short, unsigned short); - EET_T_TYPE(EET_T_UINT, unsigned_int, unsigned int); - EET_T_TYPE(EET_T_ULONG_LONG, unsigned_long_long, unsigned long long); - EET_T_TYPE(EET_T_STRING, string, char *); - EET_T_TYPE(EET_T_INLINED_STRING, inlined_string, char *); - - case EET_T_NULL: - return eet_node_null_new(name); - - default: - ERR("Unknow type passed to eet_data_node_simple_type"); - return NULL; - } -} - -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 __UNUSED__, - void *data, - char **p __UNUSED__, - int *size __UNUSED__) -{ - int ret; - void *data_ret; - - if (IS_SIMPLE_TYPE(type)) - { - unsigned char dd[128]; - - ret = eet_data_get_type(ed, - type, - echnk->data, - ((char *)echnk->data) + echnk->size, - edd ? (char *)data : (char *)dd); - if (ret <= 0) - return ret; - - if (!edd) - { - Eet_Node **parent = data; - Eet_Node *node; - - node = eet_data_node_simple_type(type, echnk->name, dd); - - if (*parent) - eet_node_struct_append(*parent, echnk->name, node); - else - *parent = node; - } - else - { - if (type == EET_T_STRING) - { - char **str; - - str = (char **)(((char *)data)); - if (*str) - { - if ((!ed) || (!edd->func.str_direct_alloc)) - { - *str = edd->func.str_alloc(*str); - _eet_freelist_str_add(context, *str); - } - else - { - *str = edd->func.str_direct_alloc(*str); - _eet_freelist_direct_str_add(context, *str); - } - } - } - else if (edd && type == EET_T_INLINED_STRING) - { - char **str; - - str = (char **)(((char *)data)); - if (*str) - { - *str = edd->func.str_alloc(*str); - _eet_freelist_str_add(context, *str); - } - } - } - } - else - { - Eet_Data_Descriptor *subtype; - - subtype = ede ? ede->subtype : NULL; - - if (subtype || !edd) - { - Eet_Node **parent = data; - void **ptr; - - data_ret = _eet_data_descriptor_decode(context, - ed, - subtype, - echnk->data, - echnk->size, - NULL, 0); - if (!data_ret) - return 0; - - if (edd) - { - ptr = (void **)(((char *)data)); - *ptr = (void *)data_ret; - } - else - { - Eet_Node *node = data_ret; - - if (*parent) - { - node = eet_node_struct_child_new(echnk->name, node); - eet_node_struct_append(*parent, echnk->name, node); - } - else - *parent = node; - } - } - } - - return 1; -} - -static void -eet_data_put_array(Eet_Dictionary *ed, - Eet_Data_Descriptor *edd __UNUSED__, - Eet_Data_Element *ede, - Eet_Data_Stream *ds, - void *data_in) -{ - void *data; - int offset = 0; - int subsize; - int count; - int size; - int j; - - EET_ASSERT(!((ede->type > EET_T_UNKNOW) && (ede->type < EET_T_STRING)), - return ); - - if (ede->group_type == EET_G_ARRAY) - count = ede->counter_offset; - else - count = *(int *)(((char *)data_in) + ede->count - ede->offset); - - if (count <= 0) - return; /* Store number of elements */ - - data = eet_data_put_type(ed, EET_T_INT, &count, &size); - if (data) - eet_data_encode(ed, ds, data, ede->name, size, ede->type, ede->group_type); - - if (IS_POINTER_TYPE(ede->type)) - subsize = eet_basic_codec[ede->type].size; - else - subsize = ede->subtype->size; - - for (j = 0; j < count; j++) - { - void *d; - int pos = ds->pos; - - if (ede->group_type == EET_G_ARRAY) - d = (void *)(((char *)data_in) + offset); - else - d = *(((char **)data_in)) + offset; - - if (IS_POINTER_TYPE(ede->type)) - { - if (*(char **)d) - eet_data_put_unknown(ed, NULL, ede, ds, d); - } - else - { - data = _eet_data_descriptor_encode(ed, ede->subtype, d, &size); - if (data) - eet_data_encode(ed, - ds, - data, - ede->name, - size, - ede->type, - ede->group_type); - } - - if (pos == ds->pos) - /* Add a NULL element just to have the correct array layout. */ - eet_data_encode(ed, - ds, - NULL, - ede->name, - 0, - EET_T_NULL, - ede->group_type); - - offset += subsize; - } -} - -static void -eet_data_put_unknown(Eet_Dictionary *ed, - Eet_Data_Descriptor *edd __UNUSED__, - Eet_Data_Element *ede, - Eet_Data_Stream *ds, - void *data_in) -{ - void *data = NULL; - int size; - - if (IS_SIMPLE_TYPE(ede->type)) - data = eet_data_put_type(ed, ede->type, data_in, &size); - else if (ede->subtype) - if (*((char **)data_in)) - data = _eet_data_descriptor_encode(ed, - ede->subtype, - *((char **)((char *)(data_in))), - &size); - - if (data) - eet_data_encode(ed, - ds, - data, - ede->name, - size, - ede->type, - ede->group_type); -} - -static void -eet_data_put_list(Eet_Dictionary *ed, - Eet_Data_Descriptor *edd, - Eet_Data_Element *ede, - Eet_Data_Stream *ds, - void *data_in) -{ - void *data; - void *l; - int size; - - EET_ASSERT(!(((ede->type > EET_T_UNKNOW) && (ede->type < EET_T_STRING)) - || ((ede->type > EET_T_NULL) && (ede->type < EET_T_LAST))), - return ); - - l = *((void **)(((char *)data_in))); - for (; l; l = edd->func.list_next(l)) - { - if (IS_POINTER_TYPE(ede->type)) - { - const void *str = edd->func.list_data(l); - eet_data_put_unknown(ed, NULL, ede, ds, &str); - } - else - { - data = _eet_data_descriptor_encode(ed, - ede->subtype, - edd->func.list_data(l), - &size); - if (data) - eet_data_encode(ed, - ds, - data, - ede->name, - size, - ede->type, - ede->group_type); - } - } -} - -static void -eet_data_put_hash(Eet_Dictionary *ed, - Eet_Data_Descriptor *edd, - Eet_Data_Element *ede, - Eet_Data_Stream *ds, - void *data_in) -{ - Eet_Data_Encode_Hash_Info fdata; - void *l; - - l = *((void **)(((char *)data_in))); - fdata.ds = ds; - fdata.ede = ede; - fdata.ed = ed; - edd->func.hash_foreach(l, eet_data_descriptor_encode_hash_cb, &fdata); -} - -EAPI int -eet_data_dump_cipher(Eet_File *ef, - const char *name, - const char *cipher_key, - Eet_Dump_Callback dumpfunc, - void *dumpdata) -{ - const Eet_Dictionary *ed = NULL; - const void *data = NULL; - Eet_Node *result; - Eet_Free_Context context; - int required_free = 0; - int size; - - ed = eet_dictionary_get(ef); - - if (!cipher_key) - data = eet_read_direct(ef, name, &size); - - if (!data) - { - required_free = 1; - data = eet_read_cipher(ef, name, &size, cipher_key); - if (!data) - return 0; - } - - eet_free_context_init(&context); - result = _eet_data_descriptor_decode(&context, ed, NULL, data, size, NULL, 0); - eet_free_context_shutdown(&context); - - eet_node_dump(result, 0, dumpfunc, dumpdata); - - eet_node_del(result); - - if (required_free) - free((void *)data); - - return result ? 1 : 0; -} - -EAPI int -eet_data_dump(Eet_File *ef, - const char *name, - Eet_Dump_Callback dumpfunc, - void *dumpdata) -{ - return eet_data_dump_cipher(ef, name, NULL, dumpfunc, dumpdata); -} - -EAPI int -eet_data_text_dump_cipher(const void *data_in, - const char *cipher_key, - int size_in, - Eet_Dump_Callback dumpfunc, - void *dumpdata) -{ - void *ret = NULL; - Eet_Node *result; - Eet_Free_Context context; - unsigned int ret_len = 0; - - if (!data_in) - return 0; - - if (cipher_key) - { - if (eet_decipher(data_in, size_in, cipher_key, - strlen(cipher_key), &ret, &ret_len)) - { - if (ret) - free(ret); - - return 0; - } - } - else - { - ret = (void *)data_in; - ret_len = size_in; - } - - eet_free_context_init(&context); - result = _eet_data_descriptor_decode(&context, NULL, NULL, ret, ret_len, NULL, 0); - eet_free_context_shutdown(&context); - - eet_node_dump(result, 0, dumpfunc, dumpdata); - - eet_node_del(result); - if (cipher_key) - free(ret); - - return result ? 1 : 0; -} - -EAPI int -eet_data_text_dump(const void *data_in, - int size_in, - Eet_Dump_Callback dumpfunc, - void *dumpdata) -{ - return eet_data_text_dump_cipher(data_in, NULL, size_in, dumpfunc, dumpdata); -} - -EAPI void * -eet_data_text_undump_cipher(const char *text, - const char *cipher_key, - int textlen, - int *size_ret) -{ - void *ret = NULL; - - ret = _eet_data_dump_parse(NULL, size_ret, text, textlen); - if (ret && cipher_key) - { - void *ciphered = NULL; - unsigned int ciphered_len; - - if (eet_cipher(ret, *size_ret, cipher_key, - strlen(cipher_key), &ciphered, &ciphered_len)) - { - if (ciphered) - free(ciphered); - - size_ret = 0; - free(ret); - return NULL; - } - - free(ret); - *size_ret = ciphered_len; - ret = ciphered; - } - - return ret; -} - -EAPI void * -eet_data_text_undump(const char *text, - int textlen, - int *size_ret) -{ - return eet_data_text_undump_cipher(text, NULL, textlen, size_ret); -} - -EAPI int -eet_data_undump_cipher(Eet_File *ef, - const char *name, - const char *cipher_key, - const char *text, - int textlen, - int compress) -{ - Eet_Dictionary *ed; - void *data_enc; - int size; - int val; - - ed = eet_dictionary_get(ef); - - data_enc = _eet_data_dump_parse(ed, &size, text, textlen); - if (!data_enc) - return 0; - - val = eet_write_cipher(ef, name, data_enc, size, compress, cipher_key); - free(data_enc); - return val; -} - -EAPI int -eet_data_undump(Eet_File *ef, - const char *name, - const char *text, - int textlen, - int compress) -{ - return eet_data_undump_cipher(ef, name, NULL, text, textlen, compress); -} - -EAPI void * -eet_data_descriptor_decode_cipher(Eet_Data_Descriptor *edd, - const void *data_in, - const char *cipher_key, - int size_in) -{ - void *deciphered = (void *)data_in; - void *ret; - Eet_Free_Context context; - unsigned int deciphered_len = size_in; - - if (cipher_key && data_in) - if (eet_decipher(data_in, size_in, cipher_key, - strlen(cipher_key), &deciphered, &deciphered_len)) - { - if (deciphered) - free(deciphered); - - return NULL; - } - - eet_free_context_init(&context); - ret = _eet_data_descriptor_decode(&context, - NULL, - edd, - deciphered, - deciphered_len, - NULL, 0); - eet_free_context_shutdown(&context); - - if (data_in != deciphered) - free(deciphered); - - return ret; -} - -EAPI void * -eet_data_descriptor_decode(Eet_Data_Descriptor *edd, - const void *data_in, - int size_in) -{ - return eet_data_descriptor_decode_cipher(edd, data_in, NULL, size_in); -} - -EAPI Eet_Node * -eet_data_node_decode_cipher(const void *data_in, - const char *cipher_key, - int size_in) -{ - void *deciphered = (void *)data_in; - Eet_Node *ret; - Eet_Free_Context context; - unsigned int deciphered_len = size_in; - - if (cipher_key && data_in) - if (eet_decipher(data_in, size_in, cipher_key, - strlen(cipher_key), &deciphered, &deciphered_len)) - { - if (deciphered) - free(deciphered); - - return NULL; - } - - eet_free_context_init(&context); - ret = _eet_data_descriptor_decode(&context, - NULL, - NULL, - deciphered, - deciphered_len, - NULL, 0); - eet_free_context_shutdown(&context); - - if (data_in != deciphered) - free(deciphered); - - return ret; -} - -static void * -_eet_data_descriptor_encode(Eet_Dictionary *ed, - Eet_Data_Descriptor *edd, - const void *data_in, - int *size_ret) -{ - Eet_Data_Stream *ds; - Eet_Data_Chunk *chnk; - void *cdata; - int csize; - int i; - - if (_eet_data_words_bigendian == -1) - { - unsigned long int v; - - v = htonl(0x12345678); - if (v == 0x12345678) - _eet_data_words_bigendian = 1; - else - _eet_data_words_bigendian = 0; - } - - ds = eet_data_stream_new(); - for (i = 0; i < edd->elements.num; i++) - { - Eet_Data_Element *ede; - - ede = &(edd->elements.set[i]); - eet_group_codec[ede->group_type - 100].put( - ed, - edd, - ede, - ds, - ((char *)data_in) + - ede->offset); - } - chnk = eet_data_chunk_new(ds->data, - ds->pos, - edd->name, - EET_T_UNKNOW, - EET_G_UNKNOWN); - ds->data = NULL; - ds->size = 0; - eet_data_stream_free(ds); - - ds = eet_data_stream_new(); - eet_data_chunk_put(ed, chnk, ds); - cdata = ds->data; - csize = ds->pos; - - ds->data = NULL; - ds->size = 0; - eet_data_stream_free(ds); - *size_ret = csize; - - free(chnk->data); - eet_data_chunk_free(chnk); - - return cdata; -} - -EAPI int -eet_data_node_write_cipher(Eet_File *ef, - const char *name, - const char *cipher_key, - Eet_Node *node, - int compress) -{ - Eet_Dictionary *ed; - void *data_enc; - int size; - int val; - - ed = eet_dictionary_get(ef); - - data_enc = _eet_data_dump_encode(EET_G_UNKNOWN, ed, node, &size); - if (!data_enc) - return 0; - - val = eet_write_cipher(ef, name, data_enc, size, compress, cipher_key); - free(data_enc); - return val; -} - -EAPI void * -eet_data_node_encode_cipher(Eet_Node *node, - const char *cipher_key, - int *size_ret) -{ - void *ret = NULL; - void *ciphered = NULL; - unsigned int ciphered_len = 0; - int size; - - ret = _eet_data_dump_encode(EET_G_UNKNOWN, NULL, node, &size); - if (cipher_key && ret) - { - if (eet_cipher(ret, size, cipher_key, - strlen(cipher_key), &ciphered, &ciphered_len)) - { - if (ciphered) - free(ciphered); - - if (size_ret) - *size_ret = 0; - - free(ret); - return NULL; - } - - free(ret); - size = (int)ciphered_len; - ret = ciphered; - } - - if (size_ret) - *size_ret = size; - - return ret; -} - -EAPI void * -eet_data_descriptor_encode_cipher(Eet_Data_Descriptor *edd, - const void *data_in, - const char *cipher_key, - int *size_ret) -{ - void *ret = NULL; - void *ciphered = NULL; - unsigned int ciphered_len = 0; - int size; - - ret = _eet_data_descriptor_encode(NULL, edd, data_in, &size); - if (cipher_key && ret) - { - if (eet_cipher(ret, size, cipher_key, - strlen(cipher_key), &ciphered, &ciphered_len)) - { - if (ciphered) - free(ciphered); - - if (size_ret) - *size_ret = 0; - - free(ret); - return NULL; - } - - free(ret); - size = ciphered_len; - ret = ciphered; - } - - if (size_ret) - *size_ret = size; - - return ret; -} - -EAPI void * -eet_data_descriptor_encode(Eet_Data_Descriptor *edd, - const void *data_in, - int *size_ret) -{ - return eet_data_descriptor_encode_cipher(edd, data_in, NULL, size_ret); -} - -EAPI void * -eet_data_xattr_cipher_get(const char *filename, - const char *attribute, - Eet_Data_Descriptor *edd, - const char *cipher_key) -{ - void *blob; - void *ret; - ssize_t size; - - blob = eina_xattr_get(filename, attribute, &size); - if (!blob) return NULL; - - ret = eet_data_descriptor_decode_cipher(edd, blob, cipher_key, size); - free(blob); - - return ret; -} - -EAPI Eina_Bool -eet_data_xattr_cipher_set(const char *filename, - const char *attribute, - Eet_Data_Descriptor *edd, - const char *cipher_key, - const void *data, - Eina_Xattr_Flags flags) -{ - void *blob; - int size; - Eina_Bool ret; - - blob = eet_data_descriptor_encode_cipher(edd, data, cipher_key, &size); - if (!blob) return EINA_FALSE; - - ret = eina_xattr_set(filename, attribute, blob, size, flags); - free(blob); - - return ret; -} -- cgit v1.1