2009-09-15 Cedric BAIL
* Remove apparently useless eet_freeleak_* from eet_data.
+
+2009-09-29 Cedric BAIL
+
+ * Add Fixed Point support and make it possible to switch from float
+ and double to any fixed point variant supported by eina.
+
+ Note: File saved with fixed point could be read by older version of
+ eet library with EET_T_DOUBLE type.
#define EET_T_STRING 11 /**< Data type: char * */
#define EET_T_INLINED_STRING 12 /**< Data type: char * (but compressed inside the resulting eet) */
#define EET_T_NULL 13 /**< Data type: (void *) (only use it if you know why) */
-#define EET_T_LAST 14 /**< Last data type */
+#define EET_T_F32P32 14 /**< Data type: */
+#define EET_T_F16P16 15 /**< Data type: */
+#define EET_T_F8P24 16 /**< Data type: */
+#define EET_T_LAST 17 /**< Last data type */
#define EET_G_UNKNOWN 100 /**< Unknown group data encoding type */
#define EET_G_ARRAY 101 /**< Fixed size array group type */
#ifndef _EET_PRIVATE_H
#define _EET_PRIVATE_H
+#include <Eina.h>
+
+typedef enum _Eet_Convert_Type Eet_Convert_Type;
+
+enum _Eet_Convert_Type
+{
+ EET_D_NOT_CONVERTED,
+ EET_D_FLOAT,
+ EET_D_DOUBLE,
+ EET_D_FIXED_POINT
+};
+
typedef struct _Eet_String Eet_String;
struct _Eet_String
{
float f;
double d;
+ Eina_F32p32 fp;
} convert;
- struct
- {
- unsigned int converted : 1;
- unsigned int is_float : 1;
- } flags;
+ Eet_Convert_Type type;
};
struct _Eet_Dictionary
{
int eet_dictionary_string_add(Eet_Dictionary *ed, const char *string);
int eet_dictionary_string_get_size(const Eet_Dictionary *ed, int index);
const char *eet_dictionary_string_get_char(const Eet_Dictionary *ed, int index);
-int eet_dictionary_string_get_float(const Eet_Dictionary *ed, int index, float *result);
-int eet_dictionary_string_get_double(const Eet_Dictionary *ed, int index, double *result);
+Eina_Bool eet_dictionary_string_get_float(const Eet_Dictionary *ed, int index, float *result);
+Eina_Bool eet_dictionary_string_get_double(const Eet_Dictionary *ed, int index, double *result);
+Eina_Bool eet_dictionary_string_get_fp(const Eet_Dictionary *ed, int index, Eina_F32p32 *result);
int eet_dictionary_string_get_hash(const Eet_Dictionary *ed, int index);
int _eet_hash_gen(const char *key, int hash_size);
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);
{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(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[] =
return eet_data_put_int(ed, &index, 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 index;
+
+ fp = (Eina_F32p32*) dst;
+
+ if (!ed) return -1;
+
+ if (eet_data_get_int(ed, src, src_end, &index) < 0) return -1;
+
+ if (!eet_dictionary_string_get_fp(ed, index, fp))
+ return -1;
+ return 1;
+}
+
+static void *
+eet_data_put_f32p32(Eet_Dictionary *ed, const void *src, int *size_ret)
+{
+ char buf[128];
+ int index;
+
+ if (!ed) return NULL;
+
+ eina_convert_fptoa((Eina_F32p32)(*(Eina_F32p32 *)src), buf);
+
+ 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_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)
{
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;
+ }
+ break;
+ default:
+ break;
+ }
+
+ return EINA_FALSE;
+}
+
/* chunk format...
*
* char[4] = "CHnK"; // untyped data ... or
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;
else
{
if (IS_SIMPLE_TYPE(echnk.type) &&
- (echnk.type == ede->type))
+ eet_data_type_match(echnk.type, ede->type))
type = echnk.type;
else if ((echnk.group_type > EET_G_UNKNOWN) &&
(echnk.group_type < EET_G_LAST) &&
current = ed->all + ed->count;
- current->flags.converted = 0;
- current->flags.is_float = 0;
+ current->type = EET_D_NOT_CONVERTED;
current->hash = hash;
return NULL;
}
-static inline int
+static inline Eina_Bool
_eet_dictionary_string_get_me_cache(const char *s, int len, int *mantisse, int *exponent)
{
if ((len == 6) && (s[0] == '0') && (s[1] == 'x') && (s[3] == 'p'))
*mantisse = (s[2] >= 'a') ? (s[2] - 'a' + 10) : (s[2] - '0');
*exponent = (s[5] - '0');
- return -1;
+ return EINA_TRUE;
}
- return 0;
+ return EINA_FALSE;
}
-static inline int
+static inline Eina_Bool
_eet_dictionary_string_get_float_cache(const char *s, int len, float *result)
{
int mantisse;
if (s[4] == '+') *result = (float) (mantisse << exponent);
else *result = (float) mantisse / (float) (1 << exponent);
- return -1;
+ return EINA_TRUE;
}
- return 0;
+ return EINA_FALSE;
}
-static inline int
+static inline Eina_Bool
_eet_dictionary_string_get_double_cache(const char *s, int len, double *result)
{
int mantisse;
if (s[4] == '+') *result = (double) (mantisse << exponent);
else *result = (double) mantisse / (float) (1 << exponent);
- return -1;
+ return EINA_TRUE;
}
- return 0;
+ return EINA_FALSE;
}
-int
+static inline Eina_Bool
+_eet_dictionary_test(const Eet_Dictionary *ed, int index, void *result)
+{
+ if (!result) return EINA_FALSE;
+ if (!ed) return EINA_FALSE;
+ if (index < 0) return EINA_FALSE;
+ if (!(index < ed->count)) return EINA_FALSE;
+ return EINA_TRUE;
+}
+
+Eina_Bool
eet_dictionary_string_get_float(const Eet_Dictionary *ed, int index, float *result)
{
- if (!result) return 0;
- if (!ed) return 0;
- if (index < 0) return 0;
- if (index < ed->count)
- {
- if (!(ed->all[index].flags.converted
- && ed->all[index].flags.is_float))
- {
- const char *str;
+ if (!_eet_dictionary_test(ed, index, result)) return EINA_FALSE;
- str = ed->all[index].str ? ed->all[index].str : ed->all[index].mmap;
+ if (ed->all[index].type != EET_D_FLOAT)
+ {
+ const char *str;
- if (!_eet_dictionary_string_get_float_cache(str, ed->all[index].len, &ed->all[index].convert.f))
- {
- long long mantisse = 0;
- long exponent = 0;
+ str = ed->all[index].str ? ed->all[index].str : ed->all[index].mmap;
- if (eina_convert_atod(str, ed->all[index].len, &mantisse, &exponent) == EINA_FALSE)
- return 0;
+ if (!_eet_dictionary_string_get_float_cache(str, ed->all[index].len, &ed->all[index].convert.f))
+ {
+ long long mantisse = 0;
+ long exponent = 0;
- ed->all[index].convert.f = ldexpf((float) mantisse, exponent);
- }
+ if (eina_convert_atod(str, ed->all[index].len, &mantisse, &exponent) == EINA_FALSE)
+ return EINA_FALSE;
- ed->all[index].flags.is_float = 1;
- }
+ ed->all[index].convert.f = ldexpf((float) mantisse, exponent);
+ }
- *result = ed->all[index].convert.f;
- return -1;
+ ed->all[index].type = EET_D_FLOAT;
}
- return 0;
+
+ *result = ed->all[index].convert.f;
+ return EINA_TRUE;
}
-int
+Eina_Bool
eet_dictionary_string_get_double(const Eet_Dictionary *ed, int index, double *result)
{
- if (!result) return 0;
- if (!ed) return 0;
- if (index < 0) return 0;
- if (index < ed->count)
+ if (!_eet_dictionary_test(ed, index, result)) return EINA_FALSE;
+
+ if (ed->all[index].type != EET_D_DOUBLE)
{
- if (!(ed->all[index].flags.converted
- && !ed->all[index].flags.is_float))
- {
- const char *str;
+ const char *str;
- str = ed->all[index].str ? ed->all[index].str : ed->all[index].mmap;
+ str = ed->all[index].str ? ed->all[index].str : ed->all[index].mmap;
- if (!_eet_dictionary_string_get_double_cache(str, ed->all[index].len, &ed->all[index].convert.d))
- {
- long long mantisse = 0;
- long exponent = 0;
+ if (!_eet_dictionary_string_get_double_cache(str, ed->all[index].len, &ed->all[index].convert.d))
+ {
+ long long mantisse = 0;
+ long exponent = 0;
- if (eina_convert_atod(str, ed->all[index].len, &mantisse, &exponent) == EINA_FALSE)
- return 0;
+ if (eina_convert_atod(str, ed->all[index].len, &mantisse, &exponent) == EINA_FALSE)
+ return EINA_FALSE;
- ed->all[index].convert.d = ldexp((double) mantisse, exponent);
- }
+ ed->all[index].convert.d = ldexp((double) mantisse, exponent);
+ }
- ed->all[index].flags.is_float = 0;
- }
+ ed->all[index].type = EET_D_DOUBLE;
+ }
- *result = ed->all[index].convert.d;
- return -1;
+ *result = ed->all[index].convert.d;
+ return EINA_TRUE;
+}
+
+Eina_Bool
+eet_dictionary_string_get_fp(const Eet_Dictionary *ed, int index, Eina_F32p32 *result)
+{
+ if (!_eet_dictionary_test(ed, index, result)) return EINA_FALSE;
+
+ if (ed->all[index].type != EET_D_FIXED_POINT)
+ {
+ const char *str;
+ Eina_F32p32 fp;
+
+ str = ed->all[index].str ? ed->all[index].str : ed->all[index].mmap;
+
+ if (!eina_convert_atofp(str, ed->all[index].len, &fp))
+ return EINA_FALSE;
+
+ ed->all[index].convert.fp = fp;
+ ed->all[index].type = EET_D_FIXED_POINT;
}
- return 0;
+
+ *result = ed->all[index].convert.fp;
+ return EINA_TRUE;
}
EAPI int