eina_value: add EINA_VALUE_TYPE_MODEL

SVN revision: 67637
This commit is contained in:
Gustavo Sverzut Barbieri 2012-01-31 16:45:59 +00:00
parent 088ab8dd2b
commit 948ce4b9ec
3 changed files with 183 additions and 0 deletions

View File

@ -323,6 +323,21 @@ EAPI extern const Eina_Value_Type *EINA_VALUE_TYPE_BLOB;
*/
EAPI extern const Eina_Value_Type *EINA_VALUE_TYPE_STRUCT;
/**
* @var EINA_VALUE_TYPE_MODEL
*
* manages Eina_Model type. Use the value get/set to change the model
* in use, it will increase the reference while in use by the value.
*
* eina_value_set() takes a pointer to #Eina_Model, increasing the
* reference.
*
* eina_value_get() takes a pointer to pointer to #Eina_Model, it's an
* exact copy of the current model, no copies are done, no references
* are increased.
*/
EAPI extern const Eina_Value_Type *EINA_VALUE_TYPE_MODEL;
/**
* @var EINA_ERROR_VALUE_FAILED
* Error identifier corresponding to value check failure.

View File

@ -60,6 +60,7 @@ void *alloca (size_t);
/* undefs EINA_ARG_NONULL() so NULL checks are not compiled out! */
#include "eina_safety_checks.h"
#include "eina_value.h"
#include "eina_model.h" /* uses eina_value.h */
/*============================================================================*
* Local *
@ -4305,6 +4306,127 @@ static const Eina_Value_Type _EINA_VALUE_TYPE_STRUCT = {
_eina_value_type_struct_pget
};
static Eina_Bool
_eina_value_type_model_setup(const Eina_Value_Type *type __UNUSED__, void *mem)
{
Eina_Model **tmem = mem;
*tmem = NULL;
return EINA_TRUE;
}
static Eina_Bool
_eina_value_type_model_flush(const Eina_Value_Type *type __UNUSED__, void *mem)
{
Eina_Model **tmem = mem;
if (*tmem)
{
eina_model_unref(*tmem);
*tmem = NULL;
}
return EINA_TRUE;
}
static Eina_Bool
_eina_value_type_model_copy(const Eina_Value_Type *type __UNUSED__, const void *src, void *dst)
{
const Eina_Model * const *s = src;
Eina_Model **d = dst;
if (*s)
*d = eina_model_copy(*s); /* is it better to deep-copy? */
else
*d = NULL;
return EINA_TRUE;
}
static int
_eina_value_type_model_compare(const Eina_Value_Type *type __UNUSED__, const void *a, const void *b)
{
const Eina_Model * const *ta = a;
const Eina_Model * const *tb = b;
if ((!*ta) && (!*tb)) return 0;
else if (!*ta) return 1;
else if (!*tb) return -1;
else return eina_model_compare(*ta, *tb);
}
static Eina_Bool
_eina_value_type_model_convert_to(const Eina_Value_Type *type __UNUSED__, const Eina_Value_Type *convert, const void *type_mem, void *convert_mem)
{
const Eina_Model *v = *(const Eina_Model **)type_mem;
eina_error_set(0);
if (convert == EINA_VALUE_TYPE_STRINGSHARE ||
convert == EINA_VALUE_TYPE_STRING)
{
char *other_mem = v ? eina_model_to_string(v) : NULL;
Eina_Bool ret = eina_value_type_pset(convert, convert_mem, &other_mem);
free(other_mem);
return ret;
}
else
{
eina_error_set(EINA_ERROR_VALUE_FAILED);
return EINA_FALSE;
}
return EINA_TRUE;
}
static Eina_Bool
_eina_value_type_model_vset(const Eina_Value_Type *type __UNUSED__, void *mem, va_list args)
{
Eina_Model **tmem = mem, *tmp;
tmp = va_arg(args, Eina_Model *);
if (tmp) eina_model_ref(tmp);
if (*tmem) eina_model_unref(*tmem);
*tmem = tmp;
return EINA_TRUE;
}
static Eina_Bool
_eina_value_type_model_pset(const Eina_Value_Type *type __UNUSED__, void *mem, const void *ptr)
{
Eina_Model **tmem = mem;
Eina_Model **p = (Eina_Model **)ptr;
if (*p) eina_model_ref(*p);
if (*tmem) eina_model_unref(*tmem);
*tmem = *p;
return EINA_TRUE;
}
static Eina_Bool
_eina_value_type_model_pget(const Eina_Value_Type *type __UNUSED__, const void *mem, void *ptr)
{
Eina_Model **tmem = (Eina_Model **)mem;
Eina_Model **p = ptr;
*p = *tmem;
return EINA_TRUE;
}
static const Eina_Value_Type _EINA_VALUE_TYPE_MODEL = {
EINA_VALUE_TYPE_VERSION,
sizeof(Eina_Model *),
"Eina_Model",
_eina_value_type_model_setup,
_eina_value_type_model_flush,
_eina_value_type_model_copy,
_eina_value_type_model_compare,
_eina_value_type_model_convert_to,
NULL, /* no convert from */
_eina_value_type_model_vset,
_eina_value_type_model_pset,
_eina_value_type_model_pget
};
/* keep all basic types inlined in an array so we can compare if it's
* a basic type using pointer arithmetic.
*
@ -4736,6 +4858,7 @@ eina_value_init(void)
EINA_VALUE_TYPE_TIMEVAL = &_EINA_VALUE_TYPE_TIMEVAL;
EINA_VALUE_TYPE_BLOB = &_EINA_VALUE_TYPE_BLOB;
EINA_VALUE_TYPE_STRUCT = &_EINA_VALUE_TYPE_STRUCT;
EINA_VALUE_TYPE_MODEL = &_EINA_VALUE_TYPE_MODEL;
EINA_VALUE_BLOB_OPERATIONS_MALLOC = &_EINA_VALUE_BLOB_OPERATIONS_MALLOC;
@ -4817,6 +4940,7 @@ EAPI const Eina_Value_Type *EINA_VALUE_TYPE_HASH = NULL;
EAPI const Eina_Value_Type *EINA_VALUE_TYPE_TIMEVAL = NULL;
EAPI const Eina_Value_Type *EINA_VALUE_TYPE_BLOB = NULL;
EAPI const Eina_Value_Type *EINA_VALUE_TYPE_STRUCT = NULL;
EAPI const Eina_Value_Type *EINA_VALUE_TYPE_MODEL = NULL;
EAPI const Eina_Value_Blob_Operations *EINA_VALUE_BLOB_OPERATIONS_MALLOC = NULL;

View File

@ -1792,6 +1792,49 @@ START_TEST(eina_value_test_array_of_struct)
}
END_TEST
START_TEST(eina_value_test_model)
{
Eina_Value *value, inv;
Eina_Model *model, *m;
char *str;
eina_init();
value = eina_value_new(EINA_VALUE_TYPE_MODEL);
fail_unless(value != NULL);
model = eina_model_new(EINA_MODEL_TYPE_GENERIC);
fail_unless(model != NULL);
fail_unless(eina_value_setup(&inv, EINA_VALUE_TYPE_INT));
fail_unless(eina_value_set(&inv, 1234));
fail_unless(eina_model_property_set(model, "i", &inv));
eina_value_flush(&inv);
fail_unless(eina_value_set(value, model));
fail_unless(eina_model_refcount(model) == 2);
fail_unless(eina_value_get(value, &m));
fail_unless(m == model);
fail_unless(eina_model_refcount(m) == 2);
fail_unless(eina_value_pset(value, &model));
fail_unless(eina_model_refcount(model) == 2);
str = eina_value_to_string(value);
fail_unless(str != NULL);
fail_unless(strcmp(str, "Eina_Model_Type_Generic({i: 1234}, [])") == 0);
eina_value_free(value);
fail_unless(eina_model_refcount(model) == 1);
eina_model_unref(model);
eina_shutdown();
}
END_TEST
void
eina_test_value(TCase *tc)
{
@ -1810,4 +1853,5 @@ eina_test_value(TCase *tc)
tcase_add_test(tc, eina_value_test_blob);
tcase_add_test(tc, eina_value_test_struct);
tcase_add_test(tc, eina_value_test_array_of_struct);
tcase_add_test(tc, eina_value_test_model);
}