Generic Value

The Eina_Value object provides storage of and access to generic data, allowing you to store whatever you want in a single Eina_Value type. It is meant for simple data types, providing uniform access and release functions for the exchange of data while preserving their types. Eina_Value supports a number of predefined types, can be extended with additional user-provided types and can convert between differing data types including strings.

Examples of Eina_Value usage can be found in the EFL examples git repository in the file reference/c/eina/src/eina_value.c.

Value Types

Eina_Value can handle the following common simple types:

  • EINA_VALUE_TYPE_UCHAR - Unsigned char
  • EINA_VALUE_TYPE_USHORT - Unsigned short
  • EINA_VALUE_TYPE_UINT - Unsigned int
  • EINA_VALUE_TYPE_ULONG - Unsigned long
  • EINA_VALUE_TYPE_TIMESTAMP An unsigned long variant used for timestamps
  • EINA_VALUE_TYPE_UINT64 - Unsigned 64-bit integer
  • EINA_VALUE_TYPE_CHAR - Char
  • EINA_VALUE_TYPE_SHORT - Short
  • EINA_VALUE_TYPE_INT - Int
  • EINA_VALUE_TYPE_LONG - Long
  • EINA_VALUE_TYPE_INT64 - 64-bit integer
  • EINA_VALUE_TYPE_FLOAT - Float
  • EINA_VALUE_TYPE_DOUBLE - Double
  • EINA_VALUE_TYPE_STRINGSHARE - Stringshared string
  • EINA_VALUE_TYPE_STRING - String
  • EINA_VALUE_TYPE_TIMEVAL - 'Struct timeval'

In addition Eina_Value has a number of specializations to handle the following aggregate types:

  • EINA_VALUE_TYPE_ARRAY - Manages arrays of elements through the Eina_Value_Array object
  • EINA_VALUE_TYPE_LIST - Manages lists of elements through the Eina_Value_List object
  • EINA_VALUE_TYPE_HASH - Manages hash tables through the Eina_Value_Hash object
  • EINA_VALUE_TYPE_BLOB - Manages blobs of bytes (memory buffers) through the Eina_Value_Blob object
  • EINA_VALUE_TYPE_STRUCT: Manages user-defined compound types (structures) through the Eina_Value_Struct object

Simple Values

Creating and Destroying Simple Values

New values can be allocated with the eina_value_new() function and disposed of with the eina_value_free() function.

Eina_Value *v = eina_value_new (type);
eina_value_free (v);

The type parameter must be one of the EINA_VALUE_TYPE_* macros listed above.

Note that eina_value_free() will free the memory allocated for the Eina_Value itself and all its contents, if necessary.

Managing the Content of Simple Values

If you allocate the Eina_Value structure yourself you can configure its contents with eina_value_setup() and free it with eina_value_flush().

Eina_Value v;
eina_value_setup(&v, type);
eina_value_flush(&v);

Note that eina_value_flush() will free the content of the Eina_Value but not the Eina_Value structure itself.

Accessing the Content of Simple Values

The contents of a simple Eina_Value can be set with eina_value_set() and retrieved with eina_value_get(). Note that the value of the second type parameter must match the type used when creating the Eina_Value.

For instance, for integers:

Eina_Value *v = eina_value_new (EINA_VALUE_TYPE_INT);
eina_value_set(v, 123);
 
int i;
eina_value_get(v, &i);
 
eina_value_free(v);

Strings are also easily handled:

Eina_Value *v = eina_value_new (EINA_VALUE_TYPE_STRING);
eina_value_set(v, "My string");
 
const char *str;
eina_value_get(v, &str);
 
eina_value_free(v);

Copying the Content of a Value

You may copy the contents of an Eina_Value over another one using the eina_value_copy() function. Note that the destination Eina_Value must exist - i.e. it will not be allocated for you - and that its contents will be replaced with a copy of the source Eina_Value.

Eina_Value src, dst;
eina_value_setup(&src, EINA_VALUE_TYPE_INT);
eina_value_set(&src, 123);
eina_value_copy(&src, &dst);
eina_value_flush(&src);
eina_value_flush(&dst);

Comparing Two Values

Two Eina_Values of the same type can be compared with the eina_value_compare(a, b) function. The exact meaning of the comparison depends on the value type, but generally speaking the method returns a negative int if a<b, a positive int if a>b and 0 if both values are equal.

Eina_Value *v1 = eina_value_new(EINA_VALUE_TYPE_FLOAT);
Eina_Value *v2 = eina_value_new(EINA_VALUE_TYPE_FLOAT);
eina_value_set(v1, 7.0f);
eina_value_set(v2, 7.5f);
int comparison = eina_value_compare(v1, v2);
eina_value_free(v1);
eina_value_free(v2);

Converting Between Values

Most Eina_Values allow conversion from one type to another using the eina_value_convert() function. The result of the conversion depends on the types in use. This function returns EINA_TRUE if the conversion is successful. The conversion is typically very strict, meaning that conversion of negative values into unsigned types will fail and values which will not fit in the target type - i.e. conversions that would result in an overflow - will also fail.

Eina_Value *v_int = eina_value_new(EINA_VALUE_TYPE_INT);
Eina_Value *v_str = eina_value_new(EINA_VALUE_TYPE_STRING);
 
eina_value_set(v_int, 123);
eina_value_convert(v_int, v_str);
 
eina_value_set(v_str, "456");
eina_value_convert(v_str, v_int);
 
eina_value_free(v_int);
eina_value_free(v_str);

Converting to Strings

All Eina_Values allow for conversion into a string, and, for convenience, there is a dedicated conversion method: eina_value_to_string(). This function allocates a new string, which you will need to free after use.

Eina_Value v;
eina_value_setup(&v, EINA_VALUE_TYPE_DOUBLE);
eina_value_set(&v, 74.5);
char *str = eina_value_to_string(&v);
free(str);
eina_value_flush(&v);

Aggregate Values

Eina_Value supports handling collections of simple values through the common aggregate types Eina_Value_Array, Eina_Value_List, Eina_Value_Hash and Eina_Value_Struct.

All aggregate types allow the operations for simple types described above - including eina_value_free() and eina_value_flush() - as well as some specific methods, typically involving construction and access to particular elements within the collection.

Arrays

An array is a contiguous block of memory which holds a collection of elements of the same type. Accessing and appending new elements at the end is typically very fast, but removing elements from the middle is not.

Create a new Eina_Value_Array with eina_value_array_new(subtype, step), or configure an existing one with eina_value_array_setup(subtype, step). The subtype parameter is the type of the Eina_Values that will be stored in the array. The step parameter indicates how many elements are added to the end of the array every time it needs to be expanded, since it is typically more efficient to enlarge the array by chunks rather than element by element.

Dispose of the array or of its contents with eina_value_free() and eina_value_flush() respectively.

Retrieve the number of elements in an array with eina_value_array_count().

Remove an element with eina_value_array_remove(position), where the position parameter is the zero-based index of the element to remove.

Append an element at the end of the array with eina_value_array_append().

Insert an element at a given position with eina_value_array_insert(position).

Retrieve the contents of the value at a given position with eina_value_array_get(position).

Set the contents of the value at a given position with eina_value_array_set(position).

Eina_Value *array = eina_value_array_new(EINA_VALUE_TYPE_INT, 0);
int x;
 
eina_value_array_append(array, 1234);
eina_value_array_get(array, 0, &x);
eina_value_free(array);

Iterate over all elements of the array with the EINA_VALUE_ARRAY_FOREACH(array, length, it, val) macro. The array parameter is the Eina_Value_Array to iterate over. The length parameter is an int variable that will receive the length of the array. The it parameter is an int variable that will receive the position in the current iteration. The val parameter is an Eina_Value * that will receive the value in the array for the current iteration.

Eina_Value array;
unsigned int i, len;
Eina_Value v = EINA_VALUE_EMPTY;
 
EINA_VALUE_ARRAY_FOREACH(&array, len, i, &v)
  {
  }

Lists

A list is linked collection of Eina_Values in which each element contains a pointer to the next element. Insertions and deletions anywhere in the list are typically very fast, but accesses to a given position can be slow since it requires traveling through the list.

Create a new Eina_Value_List with eina_value_list_new(subtype), or configure an existing one with eina_value_list_setup(subtype). The subtype parameter is the type of the Eina_Values that will be stored in the list.

Dispose of the list or of its contents with eina_value_free() and eina_value_flush() respectively.

Retrieve the number of elements in a list with eina_value_list_count().

Remove an element with eina_value_list_remove(position), where the position parameter is the zero-based index of the element to remove.

Append an element at the end of the list with eina_value_list_append().

Insert an element at a given position with eina_value_list_insert(position).

Retrieve the contents of the value at a given position with eina_value_list_get(position).

Set the contents of the value at a given position with eina_value_list_set(position).

Eina_Value *list = eina_value_list_new(EINA_VALUE_TYPE_INT);
int x;
 
eina_value_list_append(list, 1234);
eina_value_list_set(list, 0, 5678);
eina_value_list_get(list, 0, &x);
eina_value_free(list);

Hash Tables

A hash table stores Einva_Values indexed by a string key rather than an index. Insertions, deletions and searches are typically very fast, at the cost of increased memory consumption.

Create a new Eina_Value_Hash with eina_value_hash_new(subtype, bucket_size), or configure an existing one with eina_value_hash_setup(subtype, bucket_size). The subtype parameter is the type of the Eina_Values that will be stored in the hash table. The bucket_size parameter indicates how the table is to be expanded as new elements are added; use 0 and a sane default is chosen automatically.

Dispose of the hash table or of its contents with eina_value_free() and eina_value_flush() respectively.

Retrieve the number of elements in a hash table with eina_value_hash_population().

Remove an element with eina_value_hash_del(key), where the key parameter is the string identifying the element to remove.

Retrieve the contents of the value with a given key using eina_value_hash_get(key).

Set the contents of the value with a given key using eina_value_hash_set(key). This also allows new elements to be added into the hash table.

Eina_Value *hash = eina_value_hash_new(EINA_VALUE_TYPE_INT, 0);
int x;
 
eina_value_hash_set(hash, "abc", 1234);
eina_value_hash_get(hash, "abc", &x);
eina_value_free(hash);

Structures

Any number of Eina_Values can be grouped and handled through a single Eina_Value_Struct, just like regular structures in other languages. Upon creation the contents of the structure has to be described through an Eina_Value_Struct_Desc object.

Create a new Eina_Value_Struct with eina_value_struct_new(description), or configure an existing one with eina_value_struct_setup(description). The description parameter is an object of type Eina_Value_Struct_Desc which lists the members of the structure, among other things. Look at the Generic Value API reference for details, or this example in the EFL repository.

Dispose of the structure or its contents with eina_value_free() and eina_value_flush() respectively.

Retrieve the contents of any of the values in the structure with eina_value_struct_get(name), where the name parameter identifies the member you want to retrieve.

Set the contents of any of the values in the structure with eina_value_struct_set(name), where the name parameter identifies the member you want to set.

Custom Value Types

Beyond the above mentioned simple and aggregated Eina_Value types provided by EFL, you can also define your own types for use anywhere you can use an Eina_Value.

To do this, define an Eina_Value_Type structure and use it in your calls to eina_value_new() and eina_value_setup(). This structure contains mainly function pointers to methods performing operations on your type such as setup, flush, copy, compare and so on.

You can find a usage example in the EFL examples repository in the file reference/c/eina/src/eina_value_custom.c.

Further Reading

Generic Value API
A reference for the Generic Value API.
Eina Value Example
An example use of the Generic Value API.
Eina Value Custom Example
An example of using custom types with the Generic Value API.