#include <math.h>
-#include "Eet_private.h"
#include "Eet.h"
+#include "Eet_private.h"
/*
* routines for doing data -> struct and struct -> data conversion
struct _Eet_Data_Basic_Type_Decoder
{
int size;
- int (*get) (const void *src, const void *src_end, void *dest);
- void *(*put) (const void *src, int *size_ret);
+ 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_Chunk
{
char *name;
+ int len;
int size;
void *data;
unsigned char type;
struct _Eet_Data_Descriptor
{
- const char *name;
- int size;
+ const char *name;
+ 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 (*hash_free) (void *h);
} func;
struct {
- int num;
- Eet_Data_Element *set;
+ int num;
+ Eet_Data_Element *set;
struct {
- int size;
- Eet_Data_Descriptor_Hash *buckets;
+ int size;
+ Eet_Data_Descriptor_Hash *buckets;
} hash;
} elements;
// char *strings;
struct _Eet_Data_Encode_Hash_Info
{
- Eet_Data_Stream *ds;
- Eet_Data_Element *ede;
+ Eet_Data_Stream *ds;
+ Eet_Data_Element *ede;
+ Eet_Dictionary *ed;
};
/*---*/
-static int eet_data_get_char(const void *src, const void *src_end, void *dest);
-static void *eet_data_put_char(const void *src, int *size_ret);
-static int eet_data_get_short(const void *src, const void *src_end, void *dest);
-static void *eet_data_put_short(const void *src, int *size_ret);
-static int eet_data_get_int(const void *src, const void *src_end, void *dest);
-static void *eet_data_put_int(const void *src, int *size_ret);
-static int eet_data_get_long_long(const void *src, const void *src_end, void *dest);
-static void *eet_data_put_long_long(const void *src, int *size_ret);
-static int eet_data_get_float(const void *src, const void *src_end, void *dest);
-static void *eet_data_put_float(const void *src, int *size_ret);
-static int eet_data_get_double(const void *src, const void *src_end, void *dest);
-static void *eet_data_put_double(const void *src, int *size_ret);
-static int eet_data_get_string(const void *src, const void *src_end, void *dest);
-static void *eet_data_put_string(const void *src, int *size_ret);
-
-static int eet_data_get_type(int type, const void *src, const void *src_end, void *dest);
-static void *eet_data_put_type(int type, const void *src, int *size_ret);
-
-static void eet_data_chunk_get(Eet_Data_Chunk *chnk, const void *src, int size);
+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 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_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_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 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 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_Data_Chunk *chnk, 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 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(const Eet_Dictionary *ed,
+ Eet_Data_Descriptor *edd,
+ const void *data_in,
+ int size_in,
+ int level,
+ void (*dumpfunc) (void *data, const char *str),
+ void *dumpdata);
/*---*/
{sizeof(short), eet_data_get_short, eet_data_put_short },
{sizeof(int), eet_data_get_int, eet_data_put_int },
{sizeof(long long), eet_data_get_long_long, eet_data_put_long_long},
- {sizeof(char *), eet_data_get_string, eet_data_put_string }
+ {sizeof(char *), eet_data_get_string, eet_data_put_string },
+ {sizeof(char *), eet_data_get_istring, eet_data_put_istring }
};
static int words_bigendian = -1;
#define CONV32(x) {if (words_bigendian) SWAP32(x);}
#define CONV64(x) {if (words_bigendian) SWAP64(x);}
+#define IS_SIMPLE_TYPE(Type) (Type > EET_T_UNKNOW && Type < EET_T_LAST)
+
/*---*/
/* CHAR TYPE */
static int
-eet_data_get_char(const void *src, const void *src_end, void *dst)
+eet_data_get_char(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dst)
{
char *s, *d;
}
static void *
-eet_data_put_char(const void *src, int *size_ret)
+eet_data_put_char(Eet_Dictionary *ed, const void *src, int *size_ret)
{
char *s, *d;
/* SHORT TYPE */
static int
-eet_data_get_short(const void *src, const void *src_end, void *dst)
+eet_data_get_short(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dst)
{
short *d;
}
static void *
-eet_data_put_short(const void *src, int *size_ret)
+eet_data_put_short(Eet_Dictionary *ed, const void *src, int *size_ret)
{
short *s, *d;
/* INT TYPE */
static int
-eet_data_get_int(const void *src, const void *src_end, void *dst)
+eet_data_get_int(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dst)
{
int *d;
}
static void *
-eet_data_put_int(const void *src, int *size_ret)
+eet_data_put_int(Eet_Dictionary *ed, const void *src, int *size_ret)
{
int *s, *d;
/* LONG LONG TYPE */
static int
-eet_data_get_long_long(const void *src, const void *src_end, void *dst)
+eet_data_get_long_long(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dst)
{
unsigned long long *d;
}
static void *
-eet_data_put_long_long(const void *src, int *size_ret)
+eet_data_put_long_long(Eet_Dictionary *ed, const void *src, int *size_ret)
{
unsigned long long *s, *d;
/* STRING TYPE */
static int
-eet_data_get_string(const void *src, const void *src_end, void *dst)
+eet_data_get_string(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dst)
{
- char *s, **d, *p;
- int len;
+ char *s, **d;
- s = (char *)src;
d = (char **)dst;
- p = s;
- len = 0;
- while ((p < (char *)src_end) && (*p != 0)) {len++; p++;}
- if (len == 0)
+
+ if (ed)
+ {
+ const char *str;
+ int index;
+
+ if (eet_data_get_int(ed, src, src_end, &index) < 0) return -1;
+
+ str = eet_dictionary_string_get_char(ed, index);
+ if (str == NULL)
+ return -1;
+
+ *d = (char *) str;
+ return eet_dictionary_string_get_size(ed, index);
+ }
+
+ s = (char *)src;
+ if (s == NULL)
{
- *d = NULL;
- return 0;
+ *d = NULL;
+ return 0;
}
- *d = malloc(len + 1);
- if (!(*d)) return -1;
- memcpy(*d, s, len);
- (*d)[len] = 0;
- return len + 1;
+
+ *d = s;
+ return strlen(s) + 1;
}
static void *
-eet_data_put_string(const void *src, int *size_ret)
+eet_data_put_string(Eet_Dictionary *ed, const void *src, int *size_ret)
{
char *s, *d;
int len;
- /* const char *empty_s = ""; */
+
+ if (ed)
+ {
+ const char *str;
+ int index;
+
+ str = *((const char **) src);
+ if (!str) return NULL;
+
+ index = eet_dictionary_string_add(ed, str);
+ if (index == -1) return NULL;
+
+ return eet_data_put_int(ed, &index, size_ret);
+ }
s = (char *)(*((char **)src));
if (!s) return NULL;
return d;
}
+/* ALWAYS INLINED STRING TYPE */
+static int
+eet_data_get_istring(const Eet_Dictionary *ed, 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, const void *src, int *size_ret)
+{
+ return eet_data_put_string(NULL, src, size_ret);
+}
+
/**
* Fast lookups of simple doubles/floats.
*
* values, but have a so simple math that is almost as fast.
*/
static inline int
-_eet_data_float_cache_get(char *s, int len, float *d)
+_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'))
}
static inline int
-_eet_data_double_cache_get(char *s, int len, double *d)
+_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'))
/* FLOAT TYPE */
static int
-eet_data_get_float(const void *src, const void *src_end, void *dst)
+eet_data_get_float(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dst)
{
- float *d;
- long long mantisse;
- long exponent;
- char *s, *str, *p;
- int len;
+ float *d;
+ int index;
- s = (char *)src;
- d = (float *)dst;
- p = s;
- len = 0;
- while ((p < (char *)src_end) && (*p != 0)) {len++; p++;}
+ d = (float *) dst;
+ if (!ed)
+ {
+ const char *s, *p;
+ long long mantisse;
+ long exponent;
+ int len;
- if (_eet_data_float_cache_get(s, len, d) != 0) return len + 1;
+ s = (const char *)src;
+ p = s;
+ len = 0;
+ while ((p < (const char *)src_end) && (*p != 0)) {len++; p++;}
- str = alloca(len + 1);
- memcpy(str, s, len);
- str[len] = '\0';
+ if (_eet_data_float_cache_get(s, len, d) != 0) return len + 1;
- _eet_string_to_double_convert(str, &mantisse, &exponent);
- *d = (float)ldexp((double)mantisse, exponent);
-
- return len + 1;
+ _eet_string_to_double_convert(s, &mantisse, &exponent);
+ *d = (float)ldexp((double)mantisse, exponent);
+
+ return len + 1;
+ }
+
+ if (eet_data_get_int(ed, src, src_end, &index) < 0) return -1;
+
+ if (!eet_dictionary_string_get_float(ed, index, d))
+ return -1;
+ return 1;
}
static void *
-eet_data_put_float(const void *src, int *size_ret)
+eet_data_put_float(Eet_Dictionary *ed, const void *src, int *size_ret)
{
- char buf[64];
- char *d;
- int len;
+ char buf[64];
+ int index;
_eet_double_to_string_convert(buf, (double)(*(float *)src));
- len = strlen(buf);
- d = malloc(len + 1);
- if (!d) return NULL;
- strcpy(d, buf);
- *size_ret = len + 1;
- return d;
+ if (!ed)
+ {
+ char *d;
+ int len;
+
+ len = strlen(buf);
+ d = malloc(len + 1);
+ if (!d) return NULL;
+ strcpy(d, buf);
+ *size_ret = len + 1;
+ return d;
+ }
+
+ index = eet_dictionary_string_add(ed, buf);
+ if (index == -1) return NULL;
+
+ return eet_data_put_int(ed, &index, size_ret);
}
/* DOUBLE TYPE */
static int
-eet_data_get_double(const void *src, const void *src_end, void *dst)
+eet_data_get_double(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dst)
{
- double *d;
- long long mantisse = 0;
- long exponent = 0;
- char *s, *str, *p;
- int len;
+ double *d;
+ int index;
- s = (char *)src;
- d = (double *)dst;
- p = s;
- len = 0;
- while ((p < (char *)src_end) && (*p != 0)) {len++; p++;}
+ d = (double *) dst;
- if (_eet_data_double_cache_get(s, len, d) != 0) return len + 1;
+ 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;
- str = alloca(len + 1);
- memcpy(str, s, len);
- str[len] = '\0';
+ _eet_string_to_double_convert(s, &mantisse, &exponent);
+ *d = ldexp((double) mantisse, exponent);
- _eet_string_to_double_convert(str, &mantisse, &exponent);
- *d = ldexp((double)mantisse, exponent);
+ return len + 1;
+ }
+
+ if (eet_data_get_int(ed, src, src_end, &index) < 0) return -1;
- return len + 1;
+ if (!eet_dictionary_string_get_double(ed, index, d))
+ return -1;
+ return 1;
}
static void *
-eet_data_put_double(const void *src, int *size_ret)
+eet_data_put_double(Eet_Dictionary *ed, const void *src, int *size_ret)
{
- char buf[128];
- char *d;
- int len;
+ char buf[128];
+ int index;
_eet_double_to_string_convert(buf, (double)(*(double *)src));
- len = strlen(buf);
- d = malloc(len + 1);
- if (!d) return NULL;
- strcpy(d, buf);
- *size_ret = len + 1;
- return d;
+ if (!ed)
+ {
+ char *d;
+ int len;
+
+ len = strlen(buf);
+ d = malloc(len + 1);
+ if (!d) return NULL;
+ strcpy(d, buf);
+ *size_ret = len + 1;
+
+ return d;
+ }
+
+ index = eet_dictionary_string_add(ed, buf);
+ if (index == -1) return NULL;
+
+ return eet_data_put_int(ed, &index, size_ret);
}
static int
-eet_data_get_type(int type, const void *src, const void *src_end, void *dest)
+eet_data_get_type(const Eet_Dictionary *ed, int type, const void *src, const void *src_end, void *dest)
{
int ret;
- ret = eet_coder[type - 1].get(src, src_end, dest);
+ ret = eet_coder[type - 1].get(ed, src, src_end, dest);
return ret;
}
static void *
-eet_data_put_type(int type, const void *src, int *size_ret)
+eet_data_put_type(Eet_Dictionary *ed, int type, const void *src, int *size_ret)
{
void *ret;
- ret = eet_coder[type - 1].put(src, size_ret);
+ ret = eet_coder[type - 1].put(ed, src, size_ret);
return ret;
}
*/
static void
-eet_data_chunk_get(Eet_Data_Chunk *chnk, const void *src, int size)
+eet_data_chunk_get(const Eet_Dictionary *ed, Eet_Data_Chunk *chnk, const void *src, int size)
{
const char *s;
int ret1, ret2;
return;
}
}
- ret1 = eet_data_get_type(EET_T_INT, (s + 4), (s + size), &(chnk->size));
+ ret1 = eet_data_get_type(ed, EET_T_INT, (s + 4), (s + size), &(chnk->size));
if (ret1 <= 0)
{
return;
{
return;
}
- ret2 = eet_data_get_type(EET_T_STRING, (s + 8), (s + size), &(chnk->name));
+ ret2 = eet_data_get_type(ed, EET_T_STRING, (s + 8), (s + size), &(chnk->name));
if (ret2 <= 0)
{
return;
}
- chnk->data = (char *)src + 4 + ret1 + ret2;
- chnk->size -= ret2;
+
+ chnk->len = ret2;
+ 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;
}
if (!chnk) return NULL;
chnk->name = strdup(name);
+ chnk->len = strlen(name) + 1;
chnk->size = size;
chnk->data = data;
chnk->type = type;
}
static void
-eet_data_chunk_put(Eet_Data_Chunk *chnk, Eet_Data_Stream *ds)
+eet_data_chunk_put(Eet_Dictionary *ed, Eet_Data_Chunk *chnk, Eet_Data_Stream *ds)
{
- int *size;
- int s;
- int size_ret = 0;
+ int *size;
+ void *string;
+ int s;
+ int size_ret = 0;
+ int string_ret = 0;
unsigned char buf[4] = "CHK";
-
+
if (!chnk->data) return;
/* chunk head */
-
+
/* eet_data_stream_write(ds, "CHnK", 4);*/
if (chnk->type != EET_T_UNKNOW) buf[3] = chnk->type;
else buf[3] = chnk->group_type;
- eet_data_stream_write(ds, buf, 4);
+
+ string = eet_data_put_string(ed, &chnk->name, &string_ret);
+ if (!string)
+ return ;
+
/* size of chunk payload data + name */
- s = strlen(chnk->name) + 1 + chnk->size;
- size = eet_data_put_int(&s, &size_ret);
- if (size)
- {
- eet_data_stream_write(ds, size, size_ret);
- free(size);
- }
+ 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, chnk->name, strlen(chnk->name) + 1);
+ eet_data_stream_write(ds, string, string_ret);
+
/* write payload */
eet_data_stream_write(ds, chnk->data, chnk->size);
+
+ free(string);
+ on_error:
+ free(size);
}
/*---*/
Eet_Data_Descriptor *edd;
if (!name) return NULL;
-/*
- edd = calloc(1, sizeof(Eet_Data_Descriptor) + strlen(name) + 1);
- edd->name = ((char *)edd) + sizeof(Eet_Data_Descriptor);
- strcpy(edd->name, name);
- */
edd = calloc(1, sizeof(Eet_Data_Descriptor));
+ if (!edd) return NULL;
+
edd->name = name;
edd->size = 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_direct_alloc = NULL;
+ edd->func.str_direct_free = NULL;
edd->func.str_free = _eet_str_free;
edd->func.list_next = func_list_next;
edd->func.list_append = func_list_append;
Eet_Data_Descriptor *edd;
if (!eddc) return NULL;
+ if (eddc->version < 1) return NULL;
+ edd = calloc(1, sizeof(Eet_Data_Descriptor));
+ if (!edd) return NULL;
+
+ edd->name = eddc->name;
+ 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;
+
+ return edd;
+}
+
+EAPI Eet_Data_Descriptor *
+eet_data_descriptor3_new(Eet_Data_Descriptor_Class *eddc)
+{
+ Eet_Data_Descriptor *edd;
+
+ if (!eddc) return NULL;
+ if (eddc->version < 2) return NULL;
edd = calloc(1, sizeof(Eet_Data_Descriptor));
- if (eddc->version < 1) return edd;
+ if (!edd) return NULL;
+
edd->name = eddc->name;
edd->size = eddc->size;
edd->func.mem_alloc = _eet_mem_alloc;
edd->func.str_alloc = eddc->func.str_alloc;
if (eddc->func.str_free)
edd->func.str_free = eddc->func.str_free;
+ if (eddc->func.str_direct_alloc)
+ edd->func.str_direct_alloc = eddc->func.str_direct_alloc;
+ if (eddc->func.str_direct_free)
+ edd->func.str_direct_free = eddc->func.str_direct_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.hash_foreach = eddc->func.hash_foreach;
edd->func.hash_add = eddc->func.hash_add;
edd->func.hash_free = eddc->func.hash_free;
+
return edd;
}
eet_data_descriptor_free(Eet_Data_Descriptor *edd)
{
_eet_descriptor_hash_free(edd);
-// if (edd->strings) free(edd->strings);
if (edd->elements.set) free(edd->elements.set);
free(edd);
}
edd->elements.set = realloc(edd->elements.set, edd->elements.num * sizeof(Eet_Data_Element));
if (!edd->elements.set) return;
ede = &(edd->elements.set[edd->elements.num - 1]);
-/*
- l1 = strlen(name);
- p1 = edd->strings_len;
- if (counter_name)
- {
- l2 = strlen(counter_name);
- p2 = p1 + l1 + 1;
- }
- else l2 = -1;
- ps = edd->strings;
- edd->strings_len += l1 + 1 + l2 + 1;
- edd->strings = realloc(edd->strings, edd->strings_len);
- if (!edd->strings)
- {
- edd->strings = ps;
- return;
- }
- for (i = 0; i < edd->elements.num; i++)
- {
- edd->elements.set[i].name =
- edd->strings + (edd->elements.set[i].name - ps);
- if (edd->elements.set[i].counter_name)
- edd->elements.set[i].counter_name =
- edd->strings + (edd->elements.set[i].counter_name - ps);
- }
- ede->name = edd->strings + p1;
- strcpy(ede->name, name);
- */
ede->name = name;
-
+
ede->type = type;
ede->group_type = group_type;
ede->offset = offset;
ede->count = count;
-/*
- if (counter_name)
- {
- ede->counter_name = edd->strings + p2;
- strcpy(ede->counter_name, counter_name);
- }
- else ede->counter_name = NULL;
- */
ede->counter_name = counter_name;
-
+
ede->subtype = subtype;
}
EAPI void *
eet_data_read(Eet_File *ef, Eet_Data_Descriptor *edd, const char *name)
{
- void *data_dec;
- void *data;
- int size;
- int required_free = 0;
+ const Eet_Dictionary *ed = NULL;
+ const void *data;
+ void *data_dec;
+ int size;
+ int required_free = 0;
+
+ ed = eet_dictionary_get(ef);
- data = (void *)eet_read_direct(ef, name, &size);
+ data = eet_read_direct(ef, name, &size);
if (!data)
{
required_free = 1;
data = eet_read(ef, name, &size);
if (!data) return NULL;
}
- data_dec = eet_data_descriptor_decode(edd, data, size);
+
+ data_dec = _eet_data_descriptor_decode(ed, edd, data, size, 0, NULL, NULL);
if (required_free)
- free(data);
+ free((void*)data);
return data_dec;
}
EAPI int
eet_data_write(Eet_File *ef, Eet_Data_Descriptor *edd, const char *name, const void *data, int compress)
{
- void *data_enc;
- int size;
- int val;
+ Eet_Dictionary *ed;
+ void *data_enc;
+ int size;
+ int val;
- data_enc = eet_data_descriptor_encode(edd, data, &size);
+ ed = eet_dictionary_get(ef);
+
+ data_enc = _eet_data_descriptor_encode(ed, edd, data, &size);
if (!data_enc) return 0;
val = eet_write(ef, name, data_enc, size, compress);
free(data_enc);
return val;
}
-static int freelist_ref = 0;
-static int freelist_len = 0;
-static int freelist_num = 0;
-static void **freelist = NULL;
+typedef struct _Eet_Free Eet_Free;
+struct _Eet_Free
+{
+ int ref;
+ int len;
+ int num;
+ void **list;
+};
static void
-_eet_freelist_add(void *data)
+_eet_free_add(Eet_Free *ef, void *data)
{
- freelist_num++;
- if (freelist_num > freelist_len)
+ int i;
+
+ for (i = 0; i < ef->num; ++i)
+ if (ef->list[i] == data) return;
+
+ ef->num++;
+ if (ef->num > ef->len)
{
- freelist_len += 16;
- freelist = realloc(freelist, freelist_len * sizeof(void *));
+ void **tmp;
+
+ tmp = realloc(ef->list, (ef->len + 16) * sizeof(void*));
+ if (!tmp) return ;
+
+ ef->len += 16;
+ ef->list = tmp;
}
- freelist[freelist_num - 1] = data;
+ ef->list[ef->num - 1] = data;
}
-
static void
-_eet_freelist_reset(void)
+_eet_free_reset(Eet_Free *ef)
{
- if (freelist_ref > 0) return;
- freelist_len = 0;
- freelist_num = 0;
- if (freelist) free(freelist);
- freelist = NULL;
+ if (ef->ref > 0) return ;
+ ef->len = 0;
+ ef->num = 0;
+ if (ef->list) free(ef->list);
+ ef->list = NULL;
}
-
static void
-_eet_freelist_free(Eet_Data_Descriptor *edd)
+_eet_free_ref(Eet_Free *ef)
{
- int i;
-
- if (freelist_ref > 0) return;
- for (i = 0; i < freelist_num; i++)
- {
- if (edd)
- edd->func.mem_free(freelist[i]);
- else
- free(freelist[i]);
- }
- _eet_freelist_reset();
+ ef->ref++;
}
-
static void
-_eet_freelist_ref(void)
+_eet_free_unref(Eet_Free *ef)
{
- freelist_ref++;
+ ef->ref--;
}
-static void
-_eet_freelist_unref(void)
-{
- freelist_ref--;
-}
+static Eet_Free freelist = { 0, 0, 0, NULL };
-static int freelist_list_ref = 0;
-static int freelist_list_len = 0;
-static int freelist_list_num = 0;
-static void ***freelist_list = NULL;
+#define _eet_freelist_add(Data) _eet_free_add(&freelist, Data);
+#define _eet_freelist_reset() _eet_free_reset(&freelist);
+#define _eet_freelist_ref() _eet_free_ref(&freelist);
+#define _eet_freelist_unref() _eet_free_unref(&freelist);
static void
-_eet_freelist_list_add(void **data)
+_eet_freelist_free(Eet_Data_Descriptor *edd)
{
int i;
- for (i = 0; i < freelist_list_num; i++)
- {
- if (freelist_list[i] == data) return;
- }
- freelist_list_num++;
- if (freelist_list_num > freelist_list_len)
+ if (freelist.ref > 0) return;
+ for (i = 0; i < freelist.num; i++)
{
- freelist_list_len += 16;
- freelist_list = realloc(freelist_list, freelist_list_len * sizeof(void *));
+ if (edd)
+ edd->func.mem_free(freelist.list[i]);
+ else
+ free(freelist.list[i]);
}
- freelist_list[freelist_list_num - 1] = data;
+ _eet_free_reset(&freelist);
}
-static void
-_eet_freelist_list_reset(void)
-{
- if (freelist_list_ref > 0) return;
- freelist_list_len = 0;
- freelist_list_num = 0;
- if (freelist_list) free(freelist_list);
- freelist_list = NULL;
-}
+static Eet_Free freelist_list = { 0, 0, 0, NULL };
+
+#define _eet_freelist_list_add(Data) _eet_free_add(&freelist_list, Data);
+#define _eet_freelist_list_reset() _eet_free_reset(&freelist_list);
+#define _eet_freelist_list_ref() _eet_free_ref(&freelist_list);
+#define _eet_freelist_list_unref() _eet_free_unref(&freelist_list);
static void
_eet_freelist_list_free(Eet_Data_Descriptor *edd)
{
int i;
- if (freelist_list_ref > 0) return;
- for (i = 0; i < freelist_list_num; i++)
+ if (freelist_list.ref > 0) return;
+ for (i = 0; i < freelist_list.num; i++)
{
if (edd)
- edd->func.list_free(*(freelist_list[i]));
+ edd->func.list_free(*((void**)(freelist_list.list[i])));
}
- _eet_freelist_list_reset();
+ _eet_free_reset(&freelist_list);
}
-static void
-_eet_freelist_list_ref(void)
-{
- freelist_list_ref++;
-}
+static Eet_Free freelist_str = { 0, 0, 0, NULL };
-static void
-_eet_freelist_list_unref(void)
-{
- freelist_list_ref--;
-}
-
-static int freelist_str_ref = 0;
-static int freelist_str_len = 0;
-static int freelist_str_num = 0;
-static void **freelist_str = NULL;
+#define _eet_freelist_str_add(Data) _eet_free_add(&freelist_str, Data);
+#define _eet_freelist_str_reset() _eet_free_reset(&freelist_str);
+#define _eet_freelist_str_ref() _eet_free_ref(&freelist_str);
+#define _eet_freelist_str_unref() _eet_free_unref(&freelist_str);
static void
-_eet_freelist_str_add(void *data)
+_eet_freelist_str_free(Eet_Data_Descriptor *edd)
{
- freelist_str_num++;
- if (freelist_str_num > freelist_str_len)
+ int i;
+
+ if (freelist_str.ref > 0) return;
+ for (i = 0; i < freelist_str.num; i++)
{
- freelist_str_len += 16;
- freelist_str = realloc(freelist_str, freelist_str_len * sizeof(void *));
+ if (edd)
+ edd->func.str_free(freelist_str.list[i]);
+ else
+ free(freelist_str.list[i]);
}
- freelist_str[freelist_str_num - 1] = data;
+ _eet_free_reset(&freelist_str);
}
-static void
-_eet_freelist_str_reset(void)
-{
- if (freelist_str_ref > 0) return;
- freelist_str_len = 0;
- freelist_str_num = 0;
- if (freelist_str) free(freelist_str);
- freelist_str = NULL;
-}
+static Eet_Free freelist_direct_str = { 0, 0, 0, NULL };
+
+#define _eet_freelist_direct_str_add(Data) _eet_free_add(&freelist_direct_str, Data);
+#define _eet_freelist_direct_str_reset() _eet_free_reset(&freelist_direct_str);
+#define _eet_freelist_direct_str_ref() _eet_free_ref(&freelist_direct_str);
+#define _eet_freelist_direct_str_unref() _eet_free_unref(&freelist_direct_str);
static void
-_eet_freelist_str_free(Eet_Data_Descriptor *edd)
+_eet_freelist_direct_str_free(Eet_Data_Descriptor *edd)
{
int i;
- if (freelist_str_ref > 0) return;
- for (i = 0; i < freelist_str_num; i++)
+ if (freelist_str.ref > 0) return;
+ for (i = 0; i < freelist_str.num; i++)
{
if (edd)
- edd->func.str_free(freelist_str[i]);
+ edd->func.str_direct_free(freelist_str.list[i]);
else
- free(freelist_str[i]);
+ free(freelist_str.list[i]);
}
- _eet_freelist_str_reset();
-}
-
-static void
-_eet_freelist_str_ref(void)
-{
- freelist_str_ref++;
-}
-
-static void
-_eet_freelist_str_unref(void)
-{
- freelist_str_ref--;
+ _eet_free_reset(&freelist_str);
}
static int
eet_data_descriptor_encode_hash_cb(void *hash, const char *key, void *hdata, void *fdata)
{
- Eet_Data_Encode_Hash_Info *edehi;
- Eet_Data_Stream *ds;
- Eet_Data_Element *ede;
- Eet_Data_Chunk *echnk;
- void *data = NULL;
- int size;
+ 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(EET_T_STRING,
+ data = eet_data_put_type(ed,
+ EET_T_STRING,
&key,
&size);
if (data)
{
echnk = eet_data_chunk_new(data, size, ede->name, ede->type, ede->group_type);
- eet_data_chunk_put(echnk, ds);
+ eet_data_chunk_put(ed, echnk, ds);
eet_data_chunk_free(echnk);
free(data);
data = NULL;
}
/* Store data */
- if ((ede->type >= EET_T_CHAR) &&
- (ede->type <= EET_T_STRING))
- data = eet_data_put_type(ede->type,
+ if (IS_SIMPLE_TYPE(ede->type))
+ data = eet_data_put_type(ed,
+ ede->type,
hdata,
&size);
else if (ede->subtype)
- data = eet_data_descriptor_encode(ede->subtype,
- hdata,
- &size);
+ 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(echnk, ds);
+ eet_data_chunk_put(ed, echnk, ds);
eet_data_chunk_free(echnk);
free(data);
data = NULL;
}
static void *
-_eet_data_dump_encode(Node *node,
+_eet_data_dump_encode(Eet_Dictionary *ed,
+ Node *node,
int *size_ret)
{
Eet_Data_Chunk *chnk = NULL, *echnk = NULL;
if (v == 0x12345678) words_bigendian = 1;
else words_bigendian = 0;
}
-
+
ds = eet_data_stream_new();
if (!ds) return NULL;
case EET_G_UNKNOWN:
for (n = node->values; n; n = n->next)
{
- data = _eet_data_dump_encode(n, &size);
+ data = _eet_data_dump_encode(ed, n, &size);
if (data)
{
eet_data_stream_write(ds, data, size);
case EET_G_ARRAY:
for (n = node->values; n; n = n->next)
{
- data = _eet_data_dump_encode(n, &size);
+ data = _eet_data_dump_encode(ed, n, &size);
if (data)
{
eet_data_stream_write(ds, data, size);
case EET_G_VAR_ARRAY:
for (n = node->values; n; n = n->next)
{
- data = _eet_data_dump_encode(n, &size);
+ data = _eet_data_dump_encode(ed, n, &size);
if (data)
{
eet_data_stream_write(ds, data, size);
case EET_G_LIST:
for (n = node->values; n; n = n->next)
{
- data = _eet_data_dump_encode(n, &size);
+ data = _eet_data_dump_encode(ed, n, &size);
if (data)
{
eet_data_stream_write(ds, data, size);
case EET_G_HASH:
if (node->key)
{
- data = eet_data_put_type(EET_T_STRING,
+ data = eet_data_put_type(ed,
+ EET_T_STRING,
&node->key,
&size);
if (data)
{
echnk = eet_data_chunk_new(data, size, node->name, node->type, node->type);
- eet_data_chunk_put(echnk, ds);
+ eet_data_chunk_put(ed, echnk, ds);
eet_data_chunk_free(echnk);
free(data);
}
}
for (n = node->values; n; n = n->next)
{
- data = _eet_data_dump_encode(n, &size);
+ data = _eet_data_dump_encode(ed, n, &size);
if (data)
{
eet_data_stream_write(ds, data, size);
}
break;
case EET_T_CHAR:
- data = eet_data_put_type(node->type, &(node->data.c), &size);
+ data = eet_data_put_type(ed, node->type, &(node->data.c), &size);
if (data)
{
eet_data_stream_write(ds, data, size);
}
break;
case EET_T_SHORT:
- data = eet_data_put_type(node->type, &(node->data.s), &size);
+ data = eet_data_put_type(ed, node->type, &(node->data.s), &size);
if (data)
{
eet_data_stream_write(ds, data, size);
}
break;
case EET_T_INT:
- data = eet_data_put_type(node->type, &(node->data.i), &size);
+ data = eet_data_put_type(ed, node->type, &(node->data.i), &size);
if (data)
{
eet_data_stream_write(ds, data, size);
}
break;
case EET_T_LONG_LONG:
- data = eet_data_put_type(node->type, &(node->data.l), &size);
+ data = eet_data_put_type(ed, node->type, &(node->data.l), &size);
if (data)
{
eet_data_stream_write(ds, data, size);
}
break;
case EET_T_FLOAT:
- data = eet_data_put_type(node->type, &(node->data.f), &size);
+ data = eet_data_put_type(ed, node->type, &(node->data.f), &size);
if (data)
{
eet_data_stream_write(ds, data, size);
}
break;
case EET_T_DOUBLE:
- data = eet_data_put_type(node->type, &(node->data.d), &size);
+ data = eet_data_put_type(ed, node->type, &(node->data.d), &size);
if (data)
{
eet_data_stream_write(ds, data, size);
}
break;
case EET_T_UCHAR:
- data = eet_data_put_type(node->type, &(node->data.uc), &size);
+ data = eet_data_put_type(ed, node->type, &(node->data.uc), &size);
if (data)
{
eet_data_stream_write(ds, data, size);
}
break;
case EET_T_USHORT:
- data = eet_data_put_type(node->type, &(node->data.us), &size);
+ data = eet_data_put_type(ed, node->type, &(node->data.us), &size);
if (data)
{
eet_data_stream_write(ds, data, size);
}
break;
case EET_T_UINT:
- data = eet_data_put_type(node->type, &(node->data.ui), &size);
+ data = eet_data_put_type(ed, node->type, &(node->data.ui), &size);
if (data)
{
eet_data_stream_write(ds, data, size);
}
break;
case EET_T_ULONG_LONG:
- data = eet_data_put_type(node->type, &(node->data.ul), &size);
+ data = eet_data_put_type(ed, node->type, &(node->data.ul), &size);
if (data)
{
eet_data_stream_write(ds, data, size);
}
break;
case EET_T_STRING:
- data = eet_data_put_type(node->type, &(node->data.str), &size);
+ data = eet_data_put_type(ed, node->type, &(node->data.str), &size);
if (data)
{
eet_data_stream_write(ds, data, size);
eet_data_stream_free(ds);
ds = eet_data_stream_new();
- eet_data_chunk_put(chnk, ds);
+ eet_data_chunk_put(ed, chnk, ds);
cdata = ds->data;
csize = ds->pos;
}
static void *
-_eet_data_dump_parse(int *size_ret,
+_eet_data_dump_parse(Eet_Dictionary *ed,
+ int *size_ret,
const char *src,
int size)
{
if (node_base)
{
- cdata = _eet_data_dump_encode(node_base, size_ret);
+ cdata = _eet_data_dump_encode(ed, node_base, size_ret);
_eet_data_dump_free(node_base);
}
return cdata;
}
+#define NEXT_CHUNK(P, Size, Echnk, Ed) \
+ { \
+ int tmp; \
+ tmp = Ed ? sizeof (int) * 2 : Echnk.len + 4; \
+ P += (4 + Echnk.size + tmp); \
+ Size -= (4 + Echnk.size + tmp); \
+ }
+
static void *
-_eet_data_descriptor_decode(Eet_Data_Descriptor *edd,
+_eet_data_descriptor_decode(const Eet_Dictionary *ed,
+ Eet_Data_Descriptor *edd,
const void *data_in,
int size_in,
int level,
if (data) _eet_freelist_add(data);
dump = 0;
memset(&chnk, 0, sizeof(Eet_Data_Chunk));
- eet_data_chunk_get(&chnk, data_in, size_in);
+ 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;
- size = size_in - (4 + 4 + strlen(chnk.name) + 1);
+ 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);
/* get next data chunk */
memset(&echnk, 0, sizeof(Eet_Data_Chunk));
- eet_data_chunk_get(&echnk, p, size);
+ eet_data_chunk_get(ed, &echnk, p, size);
if (!echnk.name) goto error;
/* FIXME: don't REPLY on edd - work without */
if ((edd) && (!dumpfunc))
int ret;
void *data_ret;
- if ((type >= EET_T_CHAR) &&
- (type <= EET_T_STRING))
+ if (IS_SIMPLE_TYPE(type))
{
- ret = eet_data_get_type(type,
+ ret = eet_data_get_type(ed,
+ type,
echnk.data,
((char *)echnk.data) + echnk.size,
((char *)data) + ede->offset);
if (type == EET_T_STRING)
{
- char **str, *str2;
+ char **str;
str = (char **)(((char *)data) + ede->offset);
if (*str)
{
- str2 = edd->func.str_alloc(*str);
- free(*str);
- *str = str2;
- _eet_freelist_str_add(str2);
+ if (ed == NULL
+ || edd->func.str_direct_alloc == NULL)
+ {
+ *str = edd->func.str_alloc(*str);
+ _eet_freelist_str_add(*str);
+ }
+ else
+ {
+ *str = edd->func.str_direct_alloc(*str);
+ _eet_freelist_direct_str_add(*str);
+ }
}
}
}
{
void **ptr;
- data_ret = _eet_data_descriptor_decode(ede->subtype,
+ data_ret = _eet_data_descriptor_decode(ed,
+ ede->subtype,
echnk.data,
echnk.size,
level + 1,
ptr = (void **)(((char *)data) + ede->offset);
list = *ptr;
data_ret = NULL;
- if ((type >= EET_T_CHAR) &&
- (type <= EET_T_STRING))
+ if (IS_SIMPLE_TYPE(type))
{
data_ret = calloc(1, eet_coder[type].size);
if (data_ret)
{
_eet_freelist_add(data_ret);
- ret = eet_data_get_type(type,
+ ret = eet_data_get_type(ed,
+ type,
echnk.data,
((char *)echnk.data) + echnk.size,
data_ret);
goto error;
}
else if (ede->subtype)
- data_ret = _eet_data_descriptor_decode(ede->subtype,
+ data_ret = _eet_data_descriptor_decode(ed,
+ ede->subtype,
echnk.data,
echnk.size,
level + 2,
hash = *ptr;
/* Read key */
- ret = eet_data_get_type(EET_T_STRING,
+ ret = eet_data_get_type(ed,
+ EET_T_STRING,
echnk.data,
((char *)echnk.data) + echnk.size,
&key);
if (ret <= 0) goto error;
/* Advance to next chunk */
- p += (4 + 4 + strlen(echnk.name) + 1 + echnk.size);
- size -= (4 + 4 + strlen(echnk.name) + 1 + echnk.size);
- free(echnk.name);
+ NEXT_CHUNK(p, size, echnk, ed);
memset(&echnk, 0, sizeof(Eet_Data_Chunk));
/* Read value */
- eet_data_chunk_get(&echnk, p, size);
+ eet_data_chunk_get(ed, &echnk, p, size);
if (!echnk.name) goto error;
- if ((type >= EET_T_CHAR) &&
- (type <= EET_T_STRING))
+ if (IS_SIMPLE_TYPE(type))
{
data_ret = calloc(1, eet_coder[type].size);
if (data_ret)
{
_eet_freelist_add(data_ret);
- ret = eet_data_get_type(type,
+ ret = eet_data_get_type(ed,
+ type,
echnk.data,
((char *)echnk.data) + echnk.size,
data_ret);
}
else if (ede->subtype)
{
- data_ret = _eet_data_descriptor_decode(ede->subtype,
+ data_ret = _eet_data_descriptor_decode(ed,
+ ede->subtype,
echnk.data,
echnk.size,
level + 2,
{
hash = edd->func.hash_add(hash, key, data_ret);
*ptr = hash;
- free(key);
_eet_freelist_list_add(ptr);
}
else
{
- free(key);
goto error;
}
}
int ret;
void *data_ret;
- if ((type >= EET_T_CHAR) &&
- (type <= EET_T_STRING))
+ if (IS_SIMPLE_TYPE(type))
{
- ret = eet_data_get_type(type,
+ ret = eet_data_get_type(ed,
+ type,
echnk.data,
((char *)echnk.data) + echnk.size,
dd);
dumpfunc(dumpdata, "string: \"");
_eet_data_dump_string_escape(dumpdata, dumpfunc, s);
dumpfunc(dumpdata, "\"");
- free(s);
}
}
break;
}
else
{
- data_ret = _eet_data_descriptor_decode(NULL,
+ data_ret = _eet_data_descriptor_decode(ed,
+ NULL,
echnk.data,
echnk.size,
level + 1,
void *data_ret;
data_ret = NULL;
- if ((type >= EET_T_CHAR) &&
- (type <= EET_T_STRING))
+ if (IS_SIMPLE_TYPE(type))
{
data_ret = (void *)1;
- ret = eet_data_get_type(type,
+ ret = eet_data_get_type(ed,
+ type,
echnk.data,
((char *)echnk.data) + echnk.size,
dd);
if (ret <= 0) goto error;
}
else
- data_ret = _eet_data_descriptor_decode(NULL,
+ data_ret = _eet_data_descriptor_decode(ed,
+ NULL,
echnk.data,
echnk.size,
level + 2,
void *data_ret = NULL;
/* Read key */
- ret = eet_data_get_type(EET_T_STRING,
+ ret = eet_data_get_type(ed,
+ EET_T_STRING,
echnk.data,
((char *)echnk.data) + echnk.size,
&key);
if (ret <= 0) goto error;
/* Advance to next chunk */
- p += (4 + 4 + strlen(echnk.name) + 1 + echnk.size);
- size -= (4 + 4 + strlen(echnk.name) + 1 + echnk.size);
- free(echnk.name);
+ NEXT_CHUNK(p, size, echnk, ed);
memset(&echnk, 0, sizeof(Eet_Data_Chunk));
/* Read value */
- eet_data_chunk_get(&echnk, p, size);
+ eet_data_chunk_get(ed, &echnk, p, size);
if (!echnk.name) goto error;
- if ((type >= EET_T_CHAR) &&
- (type <= EET_T_STRING))
+ if (IS_SIMPLE_TYPE(type))
{
data_ret = (void *)1;
- ret = eet_data_get_type(type,
+ ret = eet_data_get_type(ed,
+ type,
echnk.data,
((char *)echnk.data) + echnk.size,
dd);
_eet_data_dump_string_escape(dumpdata, dumpfunc, s);
dumpfunc(dumpdata, "\";\n");
}
- data_ret = _eet_data_descriptor_decode(NULL,
+ data_ret = _eet_data_descriptor_decode(ed,
+ NULL,
echnk.data,
echnk.size,
level + 2,
dumpfunc,
dumpdata);
}
- if (data_ret)
- free(key);
- else
+ if (!data_ret)
{
- free(key);
goto error;
}
}
}
}
/* advance to next chunk */
- p += (4 + 4 + strlen(echnk.name) + 1 + echnk.size);
- size -= (4 + 4 + strlen(echnk.name) + 1 + echnk.size);
- free(echnk.name);
+ NEXT_CHUNK(p, size, echnk, ed);
}
- free(chnk.name);
_eet_freelist_unref();
_eet_freelist_str_unref();
_eet_freelist_list_unref();
if (dumpfunc)
{
_eet_freelist_str_free(edd);
+ _eet_freelist_direct_str_free(edd);
_eet_freelist_list_free(edd);
_eet_freelist_free(edd);
}
return data;
error:
- if (chnk.name) free(chnk.name);
_eet_freelist_unref();
_eet_freelist_str_unref();
_eet_freelist_list_unref();
_eet_freelist_str_free(edd);
+ _eet_freelist_direct_str_free(edd);
_eet_freelist_list_free(edd);
_eet_freelist_free(edd);
if (dumpfunc)
void (*dumpfunc) (void *data, const char *str),
void *dumpdata)
{
- if (_eet_data_descriptor_decode(NULL, data_in, size_in, 0,
+ if (_eet_data_descriptor_decode(NULL, NULL, data_in, size_in, 0,
dumpfunc, dumpdata))
return 1;
return 0;
int textlen,
int *size_ret)
{
- return _eet_data_dump_parse(size_ret, text, textlen);
+ return _eet_data_dump_parse(NULL, size_ret, text, textlen);
}
EAPI void *
const void *data_in,
int size_in)
{
- return _eet_data_descriptor_decode(edd, data_in, size_in, 0, NULL, NULL);
+ return _eet_data_descriptor_decode(NULL, edd, data_in, size_in, 0,
+ NULL, NULL);
}
-EAPI void *
-eet_data_descriptor_encode(Eet_Data_Descriptor *edd,
- const void *data_in,
- int *size_ret)
+static void *
+_eet_data_descriptor_encode(Eet_Dictionary *ed,
+ Eet_Data_Descriptor *edd,
+ const void *data_in,
+ int *size_ret)
{
- Eet_Data_Chunk *chnk;
- Eet_Data_Stream *ds;
- int i;
- void *cdata;
- int csize;
+ Eet_Data_Stream *ds;
+ Eet_Data_Chunk *chnk;
+ void *cdata;
+ int csize;
+ int i;
if (words_bigendian == -1)
{
data = NULL;
if (ede->group_type == EET_G_UNKNOWN)
{
- if ((ede->type >= EET_T_CHAR) &&
- (ede->type <= EET_T_STRING))
- data = eet_data_put_type(ede->type,
+ if (IS_SIMPLE_TYPE(ede->type))
+ data = eet_data_put_type(ed,
+ ede->type,
((char *)data_in) + ede->offset,
&size);
else if (ede->subtype)
{
if (*((char **)(((char *)data_in) + ede->offset)))
- data = eet_data_descriptor_encode(ede->subtype,
- *((char **)(((char *)data_in) + ede->offset)),
- &size);
+ data = _eet_data_descriptor_encode(ed,
+ ede->subtype,
+ *((char **)(((char *)data_in) + ede->offset)),
+ &size);
}
if (data)
{
echnk = eet_data_chunk_new(data, size, ede->name, ede->type, ede->group_type);
- eet_data_chunk_put(echnk, ds);
+ eet_data_chunk_put(ed, echnk, ds);
eet_data_chunk_free(echnk);
free(data);
data = NULL;
l = *((void **)(((char *)data_in) + ede->offset));
for (; l; l = edd->func.list_next(l))
{
- if ((ede->type >= EET_T_CHAR) &&
- (ede->type <= EET_T_STRING))
- data = eet_data_put_type(ede->type,
+ if (IS_SIMPLE_TYPE(ede->type))
+ data = eet_data_put_type(ed,
+ ede->type,
edd->func.list_data(l),
&size);
else if (ede->subtype)
- data = eet_data_descriptor_encode(ede->subtype,
- edd->func.list_data(l),
- &size);
+ data = _eet_data_descriptor_encode(ed,
+ ede->subtype,
+ edd->func.list_data(l),
+ &size);
if (data)
{
echnk = eet_data_chunk_new(data, size, ede->name, ede->type, ede->group_type);
- eet_data_chunk_put(echnk, ds);
+ eet_data_chunk_put(ed, echnk, ds);
eet_data_chunk_free(echnk);
free(data);
data = NULL;
l = *((void **)(((char *)data_in) + ede->offset));
fdata.ds = ds;
fdata.ede = ede;
+ fdata.ed = ed;
edd->func.hash_foreach(l, eet_data_descriptor_encode_hash_cb, &fdata);
}
break;
eet_data_stream_free(ds);
ds = eet_data_stream_new();
- eet_data_chunk_put(chnk, ds);
+ eet_data_chunk_put(ed, chnk, ds);
cdata = ds->data;
csize = ds->pos;
return cdata;
}
+
+EAPI void *
+eet_data_descriptor_encode(Eet_Data_Descriptor *edd,
+ const void *data_in,
+ int *size_ret)
+{
+ return _eet_data_descriptor_encode(NULL, edd, data_in, size_ret);
+}
* vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
*/
-#include "Eet_private.h"
#include "Eet.h"
+#include "Eet_private.h"
#include <sys/types.h>
#ifdef HAVE_SYS_MMAN_H
#define EET_MAGIC_FILE 0x1ee7ff00
#define EET_MAGIC_FILE_HEADER 0x1ee7ff01
+#define EET_MAGIC_FILE2 0x1ee70f42
+
typedef struct _Eet_File_Header Eet_File_Header;
typedef struct _Eet_File_Node Eet_File_Node;
typedef struct _Eet_File_Directory Eet_File_Directory;
FILE *fp;
Eet_File_Header *header;
const unsigned char *data;
+ Eet_Dictionary *ed;
int magic;
int references;
struct _Eet_File_Node
{
- char *name;
- void *data;
- Eet_File_Node *next; /* FIXME: make buckets linked lists */
+ char *name;
+ void *data;
+ Eet_File_Node *next; /* FIXME: make buckets linked lists */
- int offset;
- int size;
- int data_size;
+ int offset;
+ int dictionary_offset;
+ int name_offset;
- unsigned char free_name : 1;
- unsigned char compression : 1;
+ int name_size;
+ int size;
+ int data_size;
+
+ unsigned char free_name : 1;
+ unsigned char compression : 1;
};
#if 0
+/* Version 2 */
/* NB: all int's are stored in network byte order on disk */
/* file format: */
int magic; /* magic number ie 0x1ee7ff00 */
int size; /* size of the data chunk */
int data_size; /* size of the (uncompressed) data chunk */
int name_size; /* length in bytes of the name field */
- char name[name_size]; /* name string (variable length) */
+ char name[name_size]; /* name string (variable length) and \0 terminated */
} directory[num_directory_entries];
/* and now startes the data stream... */
#endif
+#if 0
+/* Version 3 */
+/* NB: all int's are stored in network byte order on disk */
+/* file format: */
+int magic; /* magic number ie 0x1ee70f42 */
+int num_directory_entries; /* number of directory entries to follow */
+int num_dictionary_entries; /* number of dictionary entries to follow */
+struct
+{
+ int data_offset; /* bytes offset into file for data chunk */
+ int size; /* size of the data chunk */
+ int data_size; /* size of the (uncompressed) data chunk */
+ int name_offset; /* bytes offset into file for name string */
+ int name_size; /* length in bytes of the name field */
+ int flags; /* flags - for now 0 = uncompressed, 1 = compressed */
+} directory[num_directory_entries];
+struct
+{
+ int hash;
+ int offset;
+ int size;
+ int prev;
+ int next;
+} dictionary[num_dictionary_entries];
+/* now start the string stream. */
+/* and right after them the data stream. */
+#endif
+
+#define EET_FILE2_HEADER_COUNT 3
+#define EET_FILE2_DIRECTORY_ENTRY_COUNT 6
+#define EET_FILE2_DICTIONARY_ENTRY_COUNT 5
+
+#define EET_FILE2_HEADER_SIZE (sizeof(int) * EET_FILE2_HEADER_COUNT)
+#define EET_FILE2_DIRECTORY_ENTRY_SIZE (sizeof(int) * EET_FILE2_DIRECTORY_ENTRY_COUNT)
+#define EET_FILE2_DICTIONARY_ENTRY_SIZE (sizeof(int) * EET_FILE2_DICTIONARY_ENTRY_COUNT)
+
/* prototypes of internal calls */
static Eet_File *eet_cache_find(const char *path, Eet_File **cache, int cache_num);
static void eet_cache_add(Eet_File *ef, Eet_File ***cache, int *cache_num, int *cache_alloc);
static void eet_cache_del(Eet_File *ef, Eet_File ***cache, int *cache_num, int *cache_alloc);
static int eet_string_match(const char *s1, const char *s2);
static Eet_Error eet_flush(Eet_File *ef);
+static Eet_Error eet_flush2(Eet_File *ef);
static Eet_File_Node *find_node_by_name(Eet_File *ef, const char *name);
static int read_data_from_disk(Eet_File *ef, Eet_File_Node *efn, void *buf, int len);
return (!strcmp(s1, s2));
}
+/* flush out writes to a v2 eet file */
+static Eet_Error
+eet_flush2(Eet_File *ef)
+{
+ Eet_File_Node *efn;
+ Eet_Error error = EET_ERROR_NONE;
+ int head[EET_FILE2_HEADER_COUNT];
+ int num_directory_entries = 0;
+ int num_dictionary_entries = 0;
+ int bytes_directory_entries = 0;
+ int bytes_dictionary_entries = 0;
+ int bytes_strings = 0;
+ int data_offset = 0;
+ int strings_offset = 0;
+ int num;
+ int i;
+ int j;
+
+ if (eet_check_pointer(ef))
+ return EET_ERROR_BAD_OBJECT;
+ if (eet_check_header(ef))
+ return EET_ERROR_EMPTY;
+ if ((ef->mode != EET_FILE_MODE_WRITE) && (ef->mode != EET_FILE_MODE_READ_WRITE))
+ return EET_ERROR_NOT_WRITABLE;
+ if (!ef->writes_pending)
+ return EET_ERROR_NONE;
+
+ /* calculate string base offset and data base offset */
+ num = (1 << ef->header->directory->size);
+ for (i = 0; i < num; ++i)
+ {
+ for (efn = ef->header->directory->nodes[i]; efn; efn = efn->next)
+ {
+ num_directory_entries++;
+ bytes_strings += strlen(efn->name) + 1;
+ }
+ }
+ if (ef->ed)
+ {
+ num_dictionary_entries = ef->ed->count;
+
+ for (i = 0; i < num_dictionary_entries; ++i)
+ bytes_strings += ef->ed->all[i].len;
+ }
+
+ /* calculate section bytes size */
+ bytes_directory_entries = EET_FILE2_DIRECTORY_ENTRY_SIZE * num_directory_entries + EET_FILE2_HEADER_SIZE;
+ bytes_dictionary_entries = EET_FILE2_DICTIONARY_ENTRY_SIZE * num_dictionary_entries;
+
+ /* calculate per entry offset */
+ strings_offset = bytes_directory_entries + bytes_dictionary_entries;
+ data_offset = bytes_directory_entries + bytes_dictionary_entries + bytes_strings;
+
+ for (i = 0; i < num; ++i)
+ {
+ for (efn = ef->header->directory->nodes[i]; efn; efn = efn->next)
+ {
+ efn->offset = data_offset;
+ data_offset += efn->size;
+
+ efn->name_offset = strings_offset;
+ strings_offset += efn->name_size;
+ }
+ }
+
+ /* calculate dictionary strings offset */
+ if (ef->ed)
+ ef->ed->offset = strings_offset;
+
+ /* go thru and write the header */
+ head[0] = (int) htonl ((unsigned int) EET_MAGIC_FILE2);
+ head[1] = (int) htonl ((unsigned int) num_directory_entries);
+ head[2] = (int) htonl ((unsigned int) num_dictionary_entries);
+
+ fseek(ef->fp, 0, SEEK_SET);
+ if (fwrite(head, sizeof (head), 1, ef->fp) != 1)
+ goto write_error;
+
+ /* write directories entry */
+ j = 0;
+ for (i = 0; i < num; i++)
+ {
+ for (efn = ef->header->directory->nodes[i]; efn; efn = efn->next)
+ {
+ int ibuf[EET_FILE2_DIRECTORY_ENTRY_COUNT];
+
+ ibuf[0] = (int) htonl ((unsigned int) efn->offset);
+ ibuf[1] = (int) htonl ((unsigned int) efn->size);
+ ibuf[2] = (int) htonl ((unsigned int) efn->data_size);
+ ibuf[3] = (int) htonl ((unsigned int) efn->name_offset);
+ ibuf[4] = (int) htonl ((unsigned int) efn->name_size);
+ ibuf[5] = (int) htonl ((unsigned int) efn->compression);
+
+ if (fwrite(ibuf, sizeof(ibuf), 1, ef->fp) != 1)
+ goto write_error;
+ }
+ }
+
+ /* write dictionnary */
+ if (ef->ed)
+ {
+ int offset = strings_offset;
+
+ for (j = 0; j < ef->ed->count; ++j)
+ {
+ int sbuf[EET_FILE2_DICTIONARY_ENTRY_COUNT];
+
+ sbuf[0] = (int) htonl ((unsigned int) ef->ed->all[j].hash);
+ sbuf[1] = (int) htonl ((unsigned int) offset);
+ sbuf[2] = (int) htonl ((unsigned int) ef->ed->all[j].len);
+ sbuf[3] = (int) htonl ((unsigned int) ef->ed->all[j].prev);
+ sbuf[4] = (int) htonl ((unsigned int) ef->ed->all[j].next);
+
+ offset += ef->ed->all[j].len;
+
+ if (fwrite(sbuf, sizeof (sbuf), 1, ef->fp) != 1)
+ goto write_error;
+ }
+ }
+
+ /* write directories name */
+ for (i = 0; i < num; i++)
+ {
+ for (efn = ef->header->directory->nodes[i]; efn; efn = efn->next)
+ {
+ if (fwrite(efn->name, efn->name_size, 1, ef->fp) != 1)
+ goto write_error;
+ }
+ }
+
+ /* write strings */
+ if (ef->ed)
+ for (j = 0; j < ef->ed->count; ++j)
+ if (ef->ed->all[j].str)
+ {
+ if (fwrite(ef->ed->all[j].str, ef->ed->all[j].len, 1, ef->fp) != 1)
+ goto write_error;
+ }
+ else
+ {
+ if (fwrite(ef->ed->all[j].mmap, ef->ed->all[j].len, 1, ef->fp) != 1)
+ goto write_error;
+ }
+
+ /* write data */
+ for (i = 0; i < num; i++)
+ {
+ for (efn = ef->header->directory->nodes[i]; efn; efn = efn->next)
+ {
+ if (fwrite(efn->data, efn->size, 1, ef->fp) != 1)
+ goto write_error;
+ }
+ }
+
+ /* no more writes pending */
+ ef->writes_pending = 0;
+
+ return EET_ERROR_NONE;
+
+ write_error:
+ switch (ferror(ef->fp))
+ {
+ case EFBIG: error = EET_ERROR_WRITE_ERROR_FILE_TOO_BIG; break;
+ case EIO: error = EET_ERROR_WRITE_ERROR_IO_ERROR; break;
+ case ENOSPC: error = EET_ERROR_WRITE_ERROR_OUT_OF_SPACE; break;
+ case EPIPE: error = EET_ERROR_WRITE_ERROR_FILE_CLOSED; break;
+ default: error = EET_ERROR_WRITE_ERROR; break;
+ }
+ fclose(ef->fp);
+ ef->fp = NULL;
+ return error;
+}
+
/* flush out writes to an eet file */
static Eet_Error
eet_flush(Eet_File *ef)
}
}
+/* FIXME: MMAP race condition in READ_WRITE_MODE */
static Eet_File*
-eet_internal_read(Eet_File *ef)
+eet_internal_read2(Eet_File *ef)
{
- const unsigned char *dyn_buf = NULL;
- const unsigned char *p = NULL;
- int index = 0;
- int num_entries;
- int byte_entries;
- int i;
+ const int *data = (const int*) ef->data;
+ const char *start = (const char*) ef->data;
+ int index = 0;
+ int num_directory_entries;
+ int bytes_directory_entries;
+ int num_dictionary_entries;
+ int bytes_dictionary_entries;
+ int i;
- if (eet_test_close((ef->data == (void *)-1) || (ef->data == NULL), ef))
+ index += sizeof(int);
+ if (eet_test_close((int) ntohl(*data) != EET_MAGIC_FILE2, ef))
return NULL;
+ data++;
- if (eet_test_close(ef->data_size < sizeof(int) * 3, ef))
+#define GET_INT(Value, Pointer, Index) \
+ { \
+ Value = ntohl(*Pointer); \
+ Pointer++; \
+ Index += sizeof(int); \
+ }
+
+ /* get entries count and byte count */
+ GET_INT(num_directory_entries, data, index);
+ /* get dictionary count and byte count */
+ GET_INT(num_dictionary_entries, data, index);
+
+ bytes_directory_entries = EET_FILE2_DIRECTORY_ENTRY_SIZE * num_directory_entries + EET_FILE2_HEADER_SIZE;
+ bytes_dictionary_entries = EET_FILE2_DICTIONARY_ENTRY_SIZE * num_dictionary_entries;
+
+ /* we cant have <= 0 values here - invalid */
+ if (eet_test_close((num_directory_entries <= 0), ef))
+ return NULL;
+
+ /* we cant have more bytes directory and bytes in dictionaries than the size of the file */
+ if (eet_test_close((bytes_directory_entries + bytes_dictionary_entries) > ef->data_size, ef))
+ return NULL;
+
+ /* allocate header */
+ ef->header = calloc(1, sizeof(Eet_File_Header));
+ if (eet_test_close(!ef->header, ef))
return NULL;
+ ef->header->magic = EET_MAGIC_FILE_HEADER;
+
+ /* allocate directory block in ram */
+ ef->header->directory = calloc(1, sizeof(Eet_File_Directory));
+ if (eet_test_close(!ef->header->directory, ef))
+ return NULL;
+
+ /* 8 bit hash table (256 buckets) */
+ ef->header->directory->size = 8;
+ /* allocate base hash table */
+ ef->header->directory->nodes = calloc(1, sizeof(Eet_File_Node *) * (1 << ef->header->directory->size));
+ if (eet_test_close(!ef->header->directory->nodes, ef))
+ return NULL;
+
+ /* actually read the directory block - all of it, into ram */
+ for (i = 0; i < num_directory_entries; ++i)
+ {
+ const char *name;
+ Eet_File_Node *efn;
+ int name_offset;
+ int name_size;
+ int hash;
+
+ /* out directory block is inconsistent - we have oveerun our */
+ /* dynamic block buffer before we finished scanning dir entries */
+ efn = malloc (sizeof(Eet_File_Node));
+ if (eet_test_close(!efn, ef))
+ return NULL;
+
+ /* get entrie header */
+ GET_INT(efn->offset, data, index);
+ GET_INT(efn->size, data, index);
+ GET_INT(efn->data_size, data, index);
+ GET_INT(name_offset, data, index);
+ GET_INT(name_size, data, index);
+ GET_INT(efn->compression, data, index);
+
+#define EFN_TEST(Test, Ef, Efn) \
+ if (eet_test_close(Test, Ef)) \
+ { \
+ free(Efn); \
+ return NULL; \
+ }
+
+ /* check data pointer position */
+ EFN_TEST(!((efn->size > 0)
+ && (efn->offset + efn->size <= ef->data_size)
+ && (efn->offset > bytes_dictionary_entries + bytes_directory_entries)), ef, efn);
+
+ /* check name position */
+ EFN_TEST(!((name_size > 0)
+ && (name_offset + name_size < ef->data_size)
+ && (name_offset >= bytes_dictionary_entries + bytes_directory_entries)), ef, efn);
+
+ name = start + name_offset;
+
+ /* check '\0' at the end of name string */
+ EFN_TEST(name[name_size - 1] != '\0', ef, efn);
+
+ efn->free_name = 0;
+ efn->name = (char*) name;
+ efn->name_size = name_size;
+
+ hash = _eet_hash_gen(efn->name, ef->header->directory->size);
+ efn->next = ef->header->directory->nodes[hash];
+ ef->header->directory->nodes[hash] = efn;
+
+ /* read-only mode, so currently we have no data loaded */
+ if (ef->mode == EET_FILE_MODE_READ)
+ efn->data = NULL;
+ /* read-write mode - read everything into ram */
+ else
+ {
+ efn->data = malloc(efn->size);
+ if (efn->data)
+ memcpy(efn->data, ef->data + efn->offset, efn->size);
+ }
+ }
+
+ ef->ed = NULL;
+
+ if (num_dictionary_entries)
+ {
+ const int *dico = (const int*) ef->data + EET_FILE2_DIRECTORY_ENTRY_COUNT * num_directory_entries + EET_FILE2_HEADER_COUNT;
+ int j;
+
+ if (eet_test_close((num_directory_entries * EET_FILE2_DICTIONARY_ENTRY_SIZE + index) > (bytes_dictionary_entries + bytes_directory_entries), ef))
+ return NULL;
+
+ ef->ed = calloc(1, sizeof (Eet_Dictionary));
+ if (eet_test_close(!ef->ed, ef)) return NULL;
+
+ ef->ed->all = calloc(num_dictionary_entries, sizeof (Eet_String));
+ if (eet_test_close(!ef->ed->all, ef)) return NULL;
+
+ ef->ed->count = num_dictionary_entries;
+
+ for (j = 0; j < ef->ed->count; ++j)
+ {
+ int hash;
+ int offset;
+
+ GET_INT(hash, dico, index);
+ GET_INT(offset, dico, index);
+ GET_INT(ef->ed->all[j].len, dico, index);
+ GET_INT(ef->ed->all[j].prev, dico, index);
+ GET_INT(ef->ed->all[j].next, dico, index);
+
+ /* Hash value could be stored on 8bits data, but this will break alignment of all the others data.
+ So stick to int and check the value. */
+ if (eet_test_close(hash & 0xFFFFFF00, ef)) return NULL;
+
+ /* Check string position */
+ if (eet_test_close(!((ef->ed->all[j].len > 0)
+ && (offset > (bytes_dictionary_entries + bytes_directory_entries))
+ && (offset + ef->ed->all[j].len < ef->data_size)), ef))
+ return NULL;
+
+ ef->ed->all[j].mmap = start + offset;
+ ef->ed->all[j].str = NULL;
+
+ /* Check '\0' at the end of the string */
+ if (eet_test_close(ef->ed->all[j].mmap[ef->ed->all[j].len - 1] != '\0', ef)) return NULL;
+
+ if (ef->ed->all[j].prev == -1)
+ ef->ed->hash[hash] = j;
+ }
+ }
+
+ return ef;
+}
+
+static Eet_File*
+eet_internal_read1(Eet_File *ef)
+{
+ const unsigned char *dyn_buf = NULL;
+ const unsigned char *p = NULL;
+ int index = 0;
+ int num_entries;
+ int byte_entries;
+ int i;
+
/* build header table if read mode */
/* geat header */
index += sizeof(int);
if (eet_test_close((num_entries * 20) > byte_entries, ef))
return NULL;
+ /* check we will not outrun the file limit */
+ if (eet_test_close(((byte_entries + sizeof(int) * 3) > ef->data_size), ef))
+ return NULL;
+
/* allocate header */
ef->header = calloc(1, sizeof(Eet_File_Header));
if (eet_test_close(!ef->header, ef))
if (eet_test_close(!efn, ef))
return NULL;
- /* get entrie header */
+ /* get entrie header */
EXTRACT_INT(efn->offset, p, indexn);
EXTRACT_INT(efn->compression, p, indexn);
EXTRACT_INT(efn->size, p, indexn);
EXTRACT_INT(efn->data_size, p, indexn);
EXTRACT_INT(name_size, p, indexn);
+ efn->name_size = name_size;
+
/* invalid size */
if (eet_test_close(efn->size <= 0, ef))
{
return ef;
}
+static Eet_File*
+eet_internal_read(Eet_File *ef)
+{
+ const int *data = (const int*) ef->data;
+
+ if (eet_test_close((ef->data == (void *)-1) || (ef->data == NULL), ef))
+ return NULL;
+
+ if (eet_test_close(ef->data_size < sizeof(int) * 3, ef))
+ return NULL;
+
+ switch (ntohl(*data))
+ {
+ case EET_MAGIC_FILE:
+ return eet_internal_read1(ef);
+ case EET_MAGIC_FILE2:
+ return eet_internal_read2(ef);
+ default:
+ ef->delete_me_now = 1;
+ eet_close(ef);
+ break;
+ }
+
+ return NULL;
+}
+
EAPI Eet_File *
eet_memopen_read(const void *data, size_t size)
{
if (!ef)
return NULL;
+ ef->ed = NULL;
ef->path = NULL;
ef->magic = EET_MAGIC_FILE;
ef->references = 1;
ef = eet_cache_find((char *)file, eet_writers, eet_writers_num);
if (ef)
{
- eet_flush(ef);
+ eet_flush2(ef);
ef->delete_me_now = 1;
eet_close(ef);
}
ef->data = NULL;
ef->data_size = 0;
+ /* FIXME: Add new ed on EET_FILE_MODE_WRITE */
+ ef->ed = mode == EET_FILE_MODE_WRITE ? eet_dictionary_add() : NULL;
+
/* if we can't open - bail out */
if (eet_test_close(!ef->fp, ef))
return NULL;
}
}
}
+
+ if (ef->ed)
+ {
+ for (i = 0; i < ef->ed->count; ++i)
+ if (ef->ed->all[i].mmap)
+ {
+ ef->ed->all[i].str = strdup(ef->ed->all[i].mmap);
+ ef->ed->all[i].mmap = NULL;
+ }
+ }
+
fclose(ef->fp);
unlink(ef->path);
ef->fp = fopen(ef->path, "wb");
/* if its still referenced - dont go any further */
if (ef->references > 0) return EET_ERROR_NONE;
/* flush any writes */
- err = eet_flush(ef);
+ err = eet_flush2(ef);
/* if not urgent to delete it - dont free it - leave it in cache */
if ((!ef->delete_me_now) && (ef->mode == EET_FILE_MODE_READ))
free(ef->header);
}
+ eet_dictionary_free(ef->ed);
+
#ifndef _WIN32
if (ef->data) munmap((void*)ef->data, ef->data_size);
#else
return 0;
}
efn->name = strdup(name);
- efn->free_name = 1;
+ efn->name_size = strlen(efn->name) + 1;
+ efn->free_name = 1;
+
efn->next = ef->header->directory->nodes[hash];
ef->header->directory->nodes[hash] = efn;
efn->offset = 0;
ef->header->directory->nodes[hash] = efn->next;
else
pefn->next = efn->next;
+
+ if (efn->free_name) free(efn->name);
free(efn);
exists_already = 1;
break;
return exists_already;
}
+EAPI Eet_Dictionary*
+eet_dictionary_get(Eet_File *ef)
+{
+ if (eet_check_pointer(ef)) return NULL;
+
+ return ef->ed;
+}
+
+
EAPI char **
eet_list(Eet_File *ef, const char *glob, int *count_ret)
{