forked from enlightenment/efl
eina_value: add struct timeval.
may be useful for esskyuehl. SVN revision: 67106
This commit is contained in:
parent
3d701ab72f
commit
a125108ebe
|
@ -236,6 +236,13 @@ EAPI extern const Eina_Value_Type *EINA_VALUE_TYPE_LIST;
|
|||
*/
|
||||
EAPI extern const Eina_Value_Type *EINA_VALUE_TYPE_HASH;
|
||||
|
||||
/**
|
||||
* @var EINA_VALUE_TYPE_TIMEVAL
|
||||
* manages 'struct timeval' type
|
||||
* @since 1.2
|
||||
*/
|
||||
EAPI extern const Eina_Value_Type *EINA_VALUE_TYPE_TIMEVAL;
|
||||
|
||||
|
||||
/**
|
||||
* @var EINA_ERROR_VALUE_FAILED
|
||||
|
|
|
@ -47,6 +47,7 @@ void *alloca (size_t);
|
|||
|
||||
#include <stdio.h> /* asprintf() */
|
||||
#include <inttypes.h> /* PRId64 and PRIu64 */
|
||||
#include <sys/time.h> /* struct timeval */
|
||||
|
||||
#include "eina_config.h"
|
||||
#include "eina_private.h"
|
||||
|
@ -3327,6 +3328,207 @@ static const Eina_Value_Type _EINA_VALUE_TYPE_HASH = {
|
|||
_eina_value_type_hash_pget
|
||||
};
|
||||
|
||||
static Eina_Bool
|
||||
_eina_value_type_timeval_setup(const Eina_Value_Type *type __UNUSED__, void *mem)
|
||||
{
|
||||
memset(mem, 0, sizeof(struct timeval));
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_eina_value_type_timeval_flush(const Eina_Value_Type *type __UNUSED__, void *mem __UNUSED__)
|
||||
{
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_eina_value_type_timeval_copy(const Eina_Value_Type *type __UNUSED__, const void *src, void *dst)
|
||||
{
|
||||
const struct timeval *s = src;
|
||||
struct timeval *d = dst;
|
||||
*d = *s;
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
static inline struct timeval _eina_value_type_timeval_fix(const struct timeval *input)
|
||||
{
|
||||
struct timeval ret = *input;
|
||||
if (EINA_UNLIKELY(ret.tv_usec < 0))
|
||||
{
|
||||
ret.tv_sec -= 1;
|
||||
ret.tv_usec += 1e6;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
_eina_value_type_timeval_compare(const Eina_Value_Type *type __UNUSED__, const void *a, const void *b)
|
||||
{
|
||||
struct timeval va = _eina_value_type_timeval_fix(a);
|
||||
struct timeval vb = _eina_value_type_timeval_fix(b);
|
||||
if (timercmp(&va, &vb, <))
|
||||
return -1;
|
||||
else if (timercmp(&va, &vb, >))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_eina_value_type_timeval_convert_to(const Eina_Value_Type *type __UNUSED__, const Eina_Value_Type *convert, const void *type_mem, void *convert_mem)
|
||||
{
|
||||
struct timeval v = _eina_value_type_timeval_fix(type_mem);
|
||||
|
||||
eina_error_set(0);
|
||||
|
||||
if (convert == EINA_VALUE_TYPE_UCHAR)
|
||||
{
|
||||
unsigned char other_mem = v.tv_sec;
|
||||
if (EINA_UNLIKELY(v.tv_sec < 0))
|
||||
return EINA_FALSE;
|
||||
if (EINA_UNLIKELY(v.tv_sec > eina_value_uchar_max))
|
||||
return EINA_FALSE;
|
||||
return eina_value_type_pset(convert, convert_mem, &other_mem);
|
||||
}
|
||||
else if (convert == EINA_VALUE_TYPE_USHORT)
|
||||
{
|
||||
unsigned short other_mem = v.tv_sec;
|
||||
if (EINA_UNLIKELY(v.tv_sec < 0))
|
||||
return EINA_FALSE;
|
||||
if (EINA_UNLIKELY(v.tv_sec > eina_value_ushort_max))
|
||||
return EINA_FALSE;
|
||||
return eina_value_type_pset(convert, convert_mem, &other_mem);
|
||||
}
|
||||
else if (convert == EINA_VALUE_TYPE_UINT)
|
||||
{
|
||||
unsigned int other_mem = v.tv_sec;
|
||||
if (EINA_UNLIKELY(v.tv_sec < 0))
|
||||
return EINA_FALSE;
|
||||
if (EINA_UNLIKELY(v.tv_sec > eina_value_uint_max))
|
||||
return EINA_FALSE;
|
||||
return eina_value_type_pset(convert, convert_mem, &other_mem);
|
||||
}
|
||||
else if (convert == EINA_VALUE_TYPE_ULONG)
|
||||
{
|
||||
unsigned long other_mem = v.tv_sec;
|
||||
if (EINA_UNLIKELY(v.tv_sec < 0))
|
||||
return EINA_FALSE;
|
||||
if (EINA_UNLIKELY((sizeof(other_mem) != sizeof(v)) &&
|
||||
((unsigned long)v.tv_sec > eina_value_ulong_max)))
|
||||
return EINA_FALSE;
|
||||
return eina_value_type_pset(convert, convert_mem, &other_mem);
|
||||
}
|
||||
else if (convert == EINA_VALUE_TYPE_UINT64)
|
||||
{
|
||||
uint64_t other_mem = v.tv_sec;
|
||||
if (EINA_UNLIKELY(v.tv_sec < 0))
|
||||
return EINA_FALSE;
|
||||
return eina_value_type_pset(convert, convert_mem, &other_mem);
|
||||
}
|
||||
else if (convert == EINA_VALUE_TYPE_CHAR)
|
||||
{
|
||||
char other_mem = v.tv_sec;
|
||||
if (EINA_UNLIKELY(v.tv_sec < eina_value_char_min))
|
||||
return EINA_FALSE;
|
||||
if (EINA_UNLIKELY(v.tv_sec > eina_value_char_max))
|
||||
return EINA_FALSE;
|
||||
return eina_value_type_pset(convert, convert_mem, &other_mem);
|
||||
}
|
||||
else if (convert == EINA_VALUE_TYPE_SHORT)
|
||||
{
|
||||
short other_mem = v.tv_sec;
|
||||
if (EINA_UNLIKELY(v.tv_sec < eina_value_short_min))
|
||||
return EINA_FALSE;
|
||||
if (EINA_UNLIKELY(v.tv_sec > eina_value_short_max))
|
||||
return EINA_FALSE;
|
||||
return eina_value_type_pset(convert, convert_mem, &other_mem);
|
||||
}
|
||||
else if (convert == EINA_VALUE_TYPE_INT)
|
||||
{
|
||||
int other_mem = v.tv_sec;
|
||||
if (EINA_UNLIKELY(v.tv_sec < eina_value_int_min))
|
||||
return EINA_FALSE;
|
||||
if (EINA_UNLIKELY(v.tv_sec > eina_value_int_max))
|
||||
return EINA_FALSE;
|
||||
return eina_value_type_pset(convert, convert_mem, &other_mem);
|
||||
}
|
||||
else if (convert == EINA_VALUE_TYPE_LONG)
|
||||
{
|
||||
long other_mem = v.tv_sec;
|
||||
if (EINA_UNLIKELY(v.tv_sec < eina_value_long_min))
|
||||
return EINA_FALSE;
|
||||
if (EINA_UNLIKELY(v.tv_sec > eina_value_long_max))
|
||||
return EINA_FALSE;
|
||||
return eina_value_type_pset(convert, convert_mem, &other_mem);
|
||||
}
|
||||
else if (convert == EINA_VALUE_TYPE_INT64)
|
||||
{
|
||||
int64_t other_mem = v.tv_sec;
|
||||
return eina_value_type_pset(convert, convert_mem, &other_mem);
|
||||
}
|
||||
else if (convert == EINA_VALUE_TYPE_FLOAT)
|
||||
{
|
||||
float other_mem = (float)v.tv_sec + (float)v.tv_usec / 1.0e6;
|
||||
return eina_value_type_pset(convert, convert_mem, &other_mem);
|
||||
}
|
||||
else if (convert == EINA_VALUE_TYPE_DOUBLE)
|
||||
{
|
||||
double other_mem = (double)v.tv_sec + (double)v.tv_usec / 1.0e6;
|
||||
return eina_value_type_pset(convert, convert_mem, &other_mem);
|
||||
}
|
||||
else if (convert == EINA_VALUE_TYPE_STRINGSHARE ||
|
||||
convert == EINA_VALUE_TYPE_STRING)
|
||||
{
|
||||
const char *other_mem;
|
||||
char buf[64];
|
||||
snprintf(buf, sizeof(buf), "%ld.%06ld", v.tv_sec, v.tv_usec);
|
||||
other_mem = buf; /* required due &buf == buf */
|
||||
return eina_value_type_pset(convert, convert_mem, &other_mem);
|
||||
}
|
||||
else
|
||||
{
|
||||
eina_error_set(EINA_ERROR_VALUE_FAILED);
|
||||
return EINA_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_eina_value_type_timeval_pset(const Eina_Value_Type *type __UNUSED__, void *mem, const void *ptr)
|
||||
{
|
||||
struct timeval *tmem = mem;
|
||||
*tmem = _eina_value_type_timeval_fix(ptr);
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_eina_value_type_timeval_vset(const Eina_Value_Type *type, void *mem, va_list args)
|
||||
{
|
||||
const struct timeval desc = va_arg(args, struct timeval);
|
||||
_eina_value_type_timeval_pset(type, mem, &desc);
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_eina_value_type_timeval_pget(const Eina_Value_Type *type __UNUSED__, const void *mem, void *ptr)
|
||||
{
|
||||
memcpy(ptr, mem, sizeof(struct timeval));
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
static const Eina_Value_Type _EINA_VALUE_TYPE_TIMEVAL = {
|
||||
EINA_VALUE_TYPE_VERSION,
|
||||
sizeof(struct timeval),
|
||||
"struct timeval",
|
||||
_eina_value_type_timeval_setup,
|
||||
_eina_value_type_timeval_flush,
|
||||
_eina_value_type_timeval_copy,
|
||||
_eina_value_type_timeval_compare,
|
||||
_eina_value_type_timeval_convert_to,
|
||||
NULL, /* no convert from */
|
||||
_eina_value_type_timeval_vset,
|
||||
_eina_value_type_timeval_pset,
|
||||
_eina_value_type_timeval_pget
|
||||
};
|
||||
|
||||
/* keep all basic types inlined in an array so we can compare if it's
|
||||
* a basic type using pointer arithmetic.
|
||||
*
|
||||
|
@ -3587,6 +3789,7 @@ eina_value_init(void)
|
|||
EINA_VALUE_TYPE_ARRAY = &_EINA_VALUE_TYPE_ARRAY;
|
||||
EINA_VALUE_TYPE_LIST = &_EINA_VALUE_TYPE_LIST;
|
||||
EINA_VALUE_TYPE_HASH = &_EINA_VALUE_TYPE_HASH;
|
||||
EINA_VALUE_TYPE_TIMEVAL = &_EINA_VALUE_TYPE_TIMEVAL;
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
@ -3638,6 +3841,7 @@ EAPI const Eina_Value_Type *EINA_VALUE_TYPE_STRING = NULL;
|
|||
EAPI const Eina_Value_Type *EINA_VALUE_TYPE_ARRAY = NULL;
|
||||
EAPI const Eina_Value_Type *EINA_VALUE_TYPE_LIST = NULL;
|
||||
EAPI const Eina_Value_Type *EINA_VALUE_TYPE_HASH = NULL;
|
||||
EAPI const Eina_Value_Type *EINA_VALUE_TYPE_TIMEVAL = NULL;
|
||||
|
||||
EAPI Eina_Error EINA_ERROR_VALUE_FAILED = 0;
|
||||
|
||||
|
|
|
@ -1307,6 +1307,84 @@ START_TEST(eina_value_test_hash)
|
|||
}
|
||||
END_TEST
|
||||
|
||||
|
||||
START_TEST(eina_value_test_timeval)
|
||||
{
|
||||
Eina_Value *value, other;
|
||||
struct timeval itv, otv;
|
||||
char c;
|
||||
char *str;
|
||||
|
||||
eina_init();
|
||||
|
||||
value = eina_value_new(EINA_VALUE_TYPE_TIMEVAL);
|
||||
fail_unless(value != NULL);
|
||||
|
||||
itv.tv_sec = 1;
|
||||
itv.tv_usec = 123;
|
||||
fail_unless(eina_value_set(value, itv));
|
||||
fail_unless(eina_value_get(value, &otv));
|
||||
fail_unless(memcmp(&itv, &otv, sizeof(struct timeval)) == 0);
|
||||
|
||||
itv.tv_sec = 3;
|
||||
itv.tv_usec = -1;
|
||||
fail_unless(eina_value_set(value, itv));
|
||||
fail_unless(eina_value_get(value, &otv));
|
||||
itv.tv_sec = 2;
|
||||
itv.tv_usec = 999999;
|
||||
fail_unless(memcmp(&itv, &otv, sizeof(struct timeval)) == 0);
|
||||
|
||||
fail_unless(eina_value_setup(&other, EINA_VALUE_TYPE_CHAR));
|
||||
fail_unless(eina_value_convert(value, &other));
|
||||
fail_unless(eina_value_get(&other, &c));
|
||||
fail_unless(c == 2);
|
||||
eina_value_flush(&other);
|
||||
|
||||
itv.tv_sec = 12345;
|
||||
itv.tv_usec = 6789;
|
||||
fail_unless(eina_value_set(value, itv));
|
||||
str = eina_value_to_string(value);
|
||||
fail_unless(str != NULL);
|
||||
fail_unless(strcmp(str, "12345.006789") == 0);
|
||||
free(str);
|
||||
|
||||
fail_unless(eina_value_setup(&other, EINA_VALUE_TYPE_TIMEVAL));
|
||||
fail_unless(eina_value_set(&other, itv));
|
||||
fail_unless(eina_value_compare(value, &other) == 0);
|
||||
|
||||
itv.tv_sec++;
|
||||
fail_unless(eina_value_set(&other, itv));
|
||||
fail_unless(eina_value_compare(value, &other) < 0);
|
||||
|
||||
itv.tv_sec -= 2;
|
||||
fail_unless(eina_value_set(&other, itv));
|
||||
fail_unless(eina_value_compare(value, &other) > 0);
|
||||
|
||||
itv.tv_sec++;
|
||||
fail_unless(eina_value_set(&other, itv));
|
||||
fail_unless(eina_value_compare(value, &other) == 0);
|
||||
|
||||
itv.tv_usec++;
|
||||
fail_unless(eina_value_set(&other, itv));
|
||||
fail_unless(eina_value_compare(value, &other) < 0);
|
||||
|
||||
itv.tv_usec -= 2;
|
||||
fail_unless(eina_value_set(&other, itv));
|
||||
fail_unless(eina_value_compare(value, &other) > 0);
|
||||
|
||||
itv.tv_usec++;
|
||||
fail_unless(eina_value_set(&other, itv));
|
||||
fail_unless(eina_value_compare(value, &other) == 0);
|
||||
|
||||
|
||||
eina_value_flush(&other);
|
||||
|
||||
|
||||
eina_value_free(value);
|
||||
eina_shutdown();
|
||||
}
|
||||
END_TEST
|
||||
|
||||
void
|
||||
eina_test_value(TCase *tc)
|
||||
{
|
||||
|
@ -1321,4 +1399,5 @@ eina_test_value(TCase *tc)
|
|||
tcase_add_test(tc, eina_value_test_array);
|
||||
tcase_add_test(tc, eina_value_test_list);
|
||||
tcase_add_test(tc, eina_value_test_hash);
|
||||
tcase_add_test(tc, eina_value_test_timeval);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue