Wiki pages eina_pg created: 1 main + 4 data types and 3 eina tools PG + index
Signed-off-by: Clément Bénier <clement.benier@openwide.fr>
This commit is contained in:
parent
2d1d2afcc1
commit
830ec3bfa6
|
@ -64,6 +64,7 @@ Go check the current available version of EFL on each distro/platform:
|
|||
* [[program_guide/edje_pg|Edje PG]]
|
||||
* [[program_guide/multilingual_pg|Multilingual PG]]
|
||||
* [[program_guide/connectivity_pg|Connectivity PG]]
|
||||
* [[program_guide/eina_pg|Eina PG]]
|
||||
|
||||
=== Samples ===
|
||||
|
||||
|
|
|
@ -0,0 +1,745 @@
|
|||
{{page>index}}
|
||||
-------
|
||||
===== Arrays =====
|
||||
|
||||
An array is a data type which describes an ordered collection of values. The
|
||||
values are accessed by their index.
|
||||
|
||||
<code c>
|
||||
INDEX | VALUE
|
||||
--------------
|
||||
0 | value0
|
||||
1 | value1
|
||||
2 | value2
|
||||
3 | value3
|
||||
4 | value4
|
||||
5 | value5
|
||||
6 | value6
|
||||
7 | value7
|
||||
</code>
|
||||
|
||||
Eina provides 2 array types: the classic array and an inline array.
|
||||
|
||||
=== Table of Contents ===
|
||||
|
||||
* [[#Creating_and_Destroying_a_Classic_Array|Creating and Destroying a Classic Array]]
|
||||
* [[#To_create_an_array_to_store_strings|To create an array to store strings]]
|
||||
* [[#Modifying_Classic_Array_Content|Modifying Classic Array Content]]
|
||||
* [[#To_set_the_data_of_an_element|To set the data of an element]]
|
||||
* [[#To_add_elements_to_the_end_of_the_array|To add elements to the end of the array]]
|
||||
* [[#To_remove_the_last_element_of_an_array|To remove the last element of an array]]
|
||||
* [[#To_rebuild_the_array_by_specifying_the_data_to_be_kept|To rebuild the array by specifying the data to be kept]]
|
||||
* [[#To_completely_wipe_an_array_out|To completely wipe an array out]]
|
||||
* [[#To_empty_an_array_quickly|To empty an array quickly]]
|
||||
* [[#Accessing_Classic_Array_Data|Accessing Classic Array Data]]
|
||||
* [[#To_access_the_data_in_the_array|To access the data in the array]]
|
||||
* [[#To_get_the_number_of_elements_in_an_array|To get the number of elements in an array]]
|
||||
* [[#To_iterate_through_an_array|To iterate through an array]]
|
||||
* [[#Creating_and_Destroying_an_Inline_Array|Creating and Destroying an Inline Array]]
|
||||
* [[#Modifying_Inline_Array_Content|Modifying Inline Array Content]]
|
||||
* [[#To_add_data_as_the_last_element_of_the_inline_array|To add data as the last element of the inline array]]
|
||||
* [[#To_insert_data_to_a_given_position_of_the_inline_array|To insert data to a given position of the inline array]]
|
||||
* [[#To_insert_data_with_your_own_position_criteria|To insert data with your own position criteria]]
|
||||
* [[#To_remove_the_last_element_of_the_inline_array|To remove the last element of the inline array]]
|
||||
* [[#To_remove_specific_data_from_an_inline_array|To remove specific data from an inline array]]
|
||||
* [[#To_remove_data_from_a_defined_position_in_an_inline_array|To remove data from a defined position in an inline array]]
|
||||
* [[#To_remove_all_the_elements_of_the_array|To remove all the elements of the array]]
|
||||
* [[#To_replace_values_in_the_inline_array|To replace values in the inline array]]
|
||||
* [[#To_sort_an_inline_array|To sort an inline array]]
|
||||
* [[#Accessing_Inline_Array_Data|Accessing Inline Array Data]]
|
||||
* [[#To_search_a_member_in_an_inline_array|To search a member in an inline array]]
|
||||
* [[#To_get_the_number_of_elements_in_an_inline_array|To get the number of elements in an inline array]]
|
||||
* [[#To_iterate_through_an_inline_array|To iterate through an inline array]]
|
||||
* [[#To_remove_some_elements_based_on_your_own_criteria|To remove some elements based on your own criteria]]
|
||||
|
||||
=== Related Info ===
|
||||
|
||||
* [[https://build.enlightenment.org/job/nightly_efl_gcc_x86_64/lastSuccessfulBuild/artifact/doc/html/group__Eina__Array__Group.html|Array API]]
|
||||
* [[https://build.enlightenment.org/job/nightly_efl_gcc_x86_64/lastSuccessfulBuild/artifact/doc/html/group__Eina__Inline__Array__Group.html|Inline Array API]]
|
||||
|
||||
^ Array |[[https://build.enlightenment.org/job/nightly_efl_gcc_x86_64/lastSuccessfulBuild/artifact/doc/html/eina_array_01_8c-example.html|Array Example 1]]|[[https://build.enlightenment.org/job/nightly_efl_gcc_x86_64/lastSuccessfulBuild/artifact/doc/html/eina_array_02_8c-example.html|Array Example 2]]||
|
||||
^ Inline Array |[[https://build.enlightenment.org/job/nightly_efl_gcc_x86_64/lastSuccessfulBuild/artifact/doc/html/eina_inarray_01_8c-example.html|Inline Array Example 1]]|[[https://build.enlightenment.org/job/nightly_efl_gcc_x86_64/lastSuccessfulBuild/artifact/doc/html/eina_inarray_02_8c-example.html|Inline Array Example 2]]|[[https://build.enlightenment.org/job/nightly_efl_gcc_x86_64/lastSuccessfulBuild/artifact/doc/html/eina_inarray_02_8c-example.html|Inline Array Example 3]]|
|
||||
|
||||
==== Creating and Destroying a Classic Array ====
|
||||
|
||||
The ''eina_array_new()'' function creates a new array. You can store strings or
|
||||
objects in the created array. The function returns a new array, or if memory
|
||||
allocation fails, ''NULL''.
|
||||
|
||||
The first parameter of the ''eina_array_new()'' function defines the size of
|
||||
the array allocation step. For example, if you set it to 4, the function
|
||||
returns an array of 4 elements and the next time you grow the array it grows
|
||||
by 4 elements. Unless you have pushed 4 elements inside, it does not grow. But
|
||||
once you add the 5th element, it grows again and becomes an array of 8
|
||||
elements. The allocation step feature is very useful for optimizing
|
||||
performance, and it also reduces memory fragmentation by having a size that
|
||||
fits the array usage. If you set the step to 0, the function sets a default
|
||||
safe value.
|
||||
|
||||
=== To create an array to store strings ===
|
||||
|
||||
__**1**__. Create the array:
|
||||
|
||||
<code c>
|
||||
// Strings to store in the array
|
||||
const char* strings[] =
|
||||
{
|
||||
"helo", "hera", "starbuck", "kat", "boomer",
|
||||
"hotdog", "longshot", "jammer", "crashdown", "hardball",
|
||||
"duck", "racetrack", "apolo", "husker", "freaker",
|
||||
"skulls", "bulldog", "flat top", "hammerhead", "gonzo"
|
||||
};
|
||||
// Declaring the array (type Eina_Array)
|
||||
Eina_Array *array;
|
||||
unsigned int i;
|
||||
|
||||
// Creating the array
|
||||
array = eina_array_new(20);
|
||||
|
||||
// Inserting elements in the array
|
||||
for (i = 0; i < 20; i++)
|
||||
eina_array_push(array, strdup(strings[i]));
|
||||
</code>
|
||||
|
||||
__**2**__. To change the allocation step, use the ''eina_array_step_set()'' function:
|
||||
* The first parameter is the array you want to change.
|
||||
* The second parameter is the size of that specific array (retrieved with the ''sizeof()'' function).
|
||||
* The last parameter is the new step size.
|
||||
|
||||
In this example, the array step changes from 20 to 30.
|
||||
<code c>
|
||||
eina_array_step_set(array, sizeof(*array), 30);
|
||||
</code>
|
||||
|
||||
__**3**__. When no longer used, use the ''eina_array_free()'' function to free the array. It first calls the ''eina_array_flush()'' function and frees the memory of the pointer. It does not free the memory allocated for the elements of the array. To free them, use a ''while'' statement with the ''eina_array_pop'' function.
|
||||
|
||||
<code c>
|
||||
// Freeing the array elements
|
||||
while (eina_array_count(array))
|
||||
free(eina_array_pop(array));
|
||||
|
||||
// Freeing the array itself
|
||||
eina_array_free(array);
|
||||
</code>
|
||||
|
||||
==== Modifying Classic Array Content ====
|
||||
|
||||
=== To set the data of an element ===
|
||||
Use the ''eina_array_data_set()'' function. The first parameter is the array,
|
||||
the second is the index of the element you want to set, and the last one is
|
||||
the data. You must first get the related pointer if you need to free it, as
|
||||
this function replaces the previously held data. Be careful, as there is no
|
||||
array or index check. If the value is ''NULL'' or invalid, the application can
|
||||
crash.
|
||||
|
||||
<code c>
|
||||
free(eina_array_data_get(array, 0));
|
||||
eina_array_data_set(array, 0, strdup(strings[3]);
|
||||
</code>
|
||||
|
||||
=== To add elements to the end of the array ===
|
||||
Use the ''eina_array_push()'' function. The function returns ''EINA_TRUE'' on
|
||||
success, and ''EINA_FALSE'' on failure. The first parameter is the array to
|
||||
store the element, the second one is the data you want to store. If you store
|
||||
strings, remember to allocate the memory first. The example uses the
|
||||
''strdup'' function to duplicate the string contained in ''strings[]''. This
|
||||
function allocates the memory of the returned string, so you do not have to do
|
||||
it yourself.
|
||||
|
||||
<code c>
|
||||
for (i = 0; i < 20; i++)
|
||||
eina_array_push(array, strdup(strings[i]));
|
||||
</code>
|
||||
|
||||
=== To remove the last element of an array ===
|
||||
Use the ''eina_array_pop()'' function. It takes the array as a parameter, and
|
||||
if the operation is successful, returns a pointer to the data of the removed
|
||||
element.
|
||||
|
||||
<code c>
|
||||
while (eina_array_count(array))
|
||||
free(eina_array_pop(array));
|
||||
</code>
|
||||
|
||||
=== To rebuild the array by specifying the data to be kept ===
|
||||
Use the ''eina_array_remove()'' function:
|
||||
* The first parameter is the array to be changed.
|
||||
* The second parameter is the function which selects the data to keep in the rebuilt array.
|
||||
* The last parameter is the data to pass to the selector function defined as the second parameter.
|
||||
|
||||
The selector function has to return an ''Eina_Bool'', ''EINA_TRUE'' if the
|
||||
element stays, and ''EINA_FALSE'' if it has to be removed.
|
||||
|
||||
The following example shows how to remove all the elements of the array that
|
||||
are longer than 5.
|
||||
|
||||
<code c>
|
||||
// Selector function
|
||||
Eina_Bool keep(void *data, void *gdata)
|
||||
{
|
||||
if (strlen((const char*)data) <= 5)
|
||||
return EINA_TRUE;
|
||||
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
int remove_array()
|
||||
{
|
||||
Eina_Array *array;
|
||||
Eina_Array_Iterator iterator;
|
||||
const char *item;
|
||||
unsigned int i;
|
||||
|
||||
// Creating and populating an array
|
||||
|
||||
// Removing the undesired elements
|
||||
eina_array_remove(array, keep, NULL);
|
||||
|
||||
// Flushing and freeing the array
|
||||
|
||||
return 0;
|
||||
}
|
||||
</code>
|
||||
|
||||
=== To completely wipe an array out ===
|
||||
Use the ''eina_array_flush()'' function. This function sets the count and
|
||||
total members of an array to 0, and frees and sets its data members to
|
||||
''NULL''. For performance reasons, there is no array check. If the value is
|
||||
''NULL'' or invalid, the program can crash. The only parameter of this
|
||||
function is a pointer to the ''Eina_Array'' array you want to flush.
|
||||
|
||||
<code c>
|
||||
eina_array_flush(array);
|
||||
</code>
|
||||
|
||||
=== To empty an array quickly ===
|
||||
Use the ''eina_array_clean()'' function. This function sets the counting of
|
||||
members in the array to 0. It does not free any space so you have to use it
|
||||
carefully. For performance reasons, there is no array check. If the value is
|
||||
''NULL'' or invalid, the program can crash.
|
||||
|
||||
<code c>
|
||||
eina_array_clean(array);
|
||||
</code>
|
||||
|
||||
==== Accessing Classic Array Data ====
|
||||
|
||||
=== To access the data in the array ===
|
||||
Use the ''eina_array_data_get()'' function with the array and the index of the
|
||||
element you want to get. The function returns a pointer to the data.
|
||||
|
||||
<code c>
|
||||
// Getting the data of the first element
|
||||
char *mydata;
|
||||
mydata = eina_array_data_get(array, 0);
|
||||
</code>
|
||||
|
||||
=== To get the number of elements in an array ===
|
||||
Use the ''eina_array_count()'' function. The first parameter is a pointer to
|
||||
the array variable returned by the ''eina_array_new()'' function.
|
||||
|
||||
The function returns the number of elements.
|
||||
|
||||
<code c>
|
||||
unsigned int nb_elm;
|
||||
nb_elm = eina_array_count(array);
|
||||
</code>
|
||||
|
||||
=== To iterate through an array ===
|
||||
|
||||
You can use various methods:
|
||||
* Use the ''Eina_Array'' iterator called ''ITER_NEXT''. \\ \\ You can use the iterator by calling the macro ''EINA_ARRAY_ITER_NEXT()''. It takes the array to iterate as the first parameter, a counter for the current index during the iteration, and a variable of the same type as the item data and an ''Eina_Iterator''. To use it, declare an ''Eina_Iterator'', an ''int'' counter, and, for example, a ''char *'' item if your array contains any strings.
|
||||
|
||||
<code c>
|
||||
Eina_Array_Iterator iterator;
|
||||
const char *item;
|
||||
unsigned int i;
|
||||
|
||||
EINA_ARRAY_ITER_NEXT(array, i, item, iterator)
|
||||
printf("item #%d: %s\n", i, item);
|
||||
</code>
|
||||
|
||||
* Use the ''eina_array_foreach()'' function to iterate over the array. \\ \\ The first parameter is the array to iterate, the second is a callback function which determines whether the iteration can continue,and the last is the data passed to the callback function. \\ \\ To iterate over the array and to print the data of each array element:
|
||||
|
||||
<code c>
|
||||
// Callback function
|
||||
static Eina_Bool
|
||||
elm_print(const void *container, void *data, void *fdata)
|
||||
{
|
||||
printf("%s\n", (char *)data);
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
int iterating_array()
|
||||
{
|
||||
Eina_Array *array;
|
||||
unsigned int i;
|
||||
|
||||
// Creating and populating an array
|
||||
|
||||
// Iterating over the array and calling elm_print on each element
|
||||
eina_array_foreach(array, elm_print, NULL);
|
||||
|
||||
// Freeing the element data and array
|
||||
|
||||
return 0;
|
||||
}
|
||||
</code>
|
||||
* Use the ''eina_array_iterator_new()'' function to create an iterator for the array. \\ \\ The function returns a newly allocated iterator associated with the array. If the array is ''NULL'' or the count of the array members is less than or equal to 0, the function returns ''NULL''. If the memory cannot be allocated, ''NULL'' is returned and ''EINA_ERROR_OUT_OF_MEMORY'' is thrown. Otherwise, a valid iterator is returned. \\ \\ Pass to this function the array for which you want to create a new iterator. The iterator is used to run a sequential walk through the array, just like the ''eina_array_foreach()'' function. \\ \\ To create an iterator and use it to print the data of each array element:
|
||||
|
||||
<code c>
|
||||
static Eina_Bool
|
||||
print_one(const void *container, void *data, void *fdata)
|
||||
{
|
||||
printf("%s\n", (char*)data);
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
int new_iterator()
|
||||
{
|
||||
Eina_Array *array;
|
||||
Eina_Iterator *it;
|
||||
unsigned short int i;
|
||||
void *uninteresting;
|
||||
Eina_Bool rt;
|
||||
|
||||
// Creating and populating an array
|
||||
|
||||
it = eina_array_iterator_new(array);
|
||||
|
||||
it = eina_iterator_next(it, &uninteresting);
|
||||
eina_iterator_foreach(it, print_one, NULL);
|
||||
eina_iterator_free(it);
|
||||
|
||||
return 0;
|
||||
}
|
||||
</code>
|
||||
|
||||
* Use the ''eina_array_accessor_new()'' function to get random access to the array elements. \\ \\ The function returns a newly allocated accessor associated with the array. If the array is ''NULL'' or the counting of array members is less than or equal to 0, this function returns ''NULL''. If the memory cannot be allocated, ''NULL'' is returned and ''EINA_ERROR_OUT_OF_MEMORY'' is thrown. Otherwise, a valid accessor is returned. \\ \\ To use the accessor to retrieve and print the data of every other array element:
|
||||
|
||||
<code c>
|
||||
int random_access()
|
||||
{
|
||||
Eina_Array *array; // Declaration of the array
|
||||
Eina_Accessor *acc; // Declaration of the accessor
|
||||
|
||||
unsigned short int i; // Generic counter
|
||||
|
||||
void *data; // Variable to put the data retrieved from an array element
|
||||
|
||||
// Creating and populating an array
|
||||
|
||||
// Creating the array accessor
|
||||
acc = eina_array_accessor_new(array);
|
||||
|
||||
// Random access to the data of the array elements
|
||||
for(i = 1; i < 10; i += 2)
|
||||
{
|
||||
// Putting the data in the variable 'data'
|
||||
eina_accessor_data_get(acc, i, &data);
|
||||
printf("%s\n", (const char *)data);
|
||||
}
|
||||
|
||||
eina_accessor_free(acc); // Freeing the accessor
|
||||
|
||||
// Freeing the array
|
||||
return 0;
|
||||
}
|
||||
</code>
|
||||
|
||||
==== Creating and Destroying an Inline Array ====
|
||||
|
||||
An inline array is a container that stores the data itself, not the pointers
|
||||
to the data. This means there is no memory fragmentation, and for small data
|
||||
types, such as char, short, and int, it is more memory-efficient. This is
|
||||
because the data is stored in the cache and is faster to access. The bigger
|
||||
the data gets, however, the less likely it is and the less interesting it
|
||||
becomes.
|
||||
|
||||
To create an inline array, use the ''eina_inarray_new()'' function:
|
||||
|
||||
* The first parameter is the size of the value. In this example, only the characters are stored, and because of that, only ''sizeof(char)'' is passed to the function.
|
||||
* The second parameter defines the size of the array allocation step. For example, if you set it to 4, the function returns an inline array of 4 elements, and the next time you grow the inline array, it grows by 4 elements and becomes an array of 8 elements. If you set the step to 0, the function sets a default safe value. \\ \\ The step can be changed later on using the ''eina_inarray_step_set()'' function.
|
||||
|
||||
The ''eina_inarray_new()'' function returns a pointer to the new
|
||||
''Eina_Inarray'' variable.
|
||||
|
||||
<code c>
|
||||
int inline_array()
|
||||
{
|
||||
Eina_Inarray *iarr; // Declare an inline array variable of the type Eina_Inarray
|
||||
|
||||
iarr = eina_inarray_new(sizeof(char), 0); // Create an inline array of "char"
|
||||
|
||||
eina_inarray_free(iarr); // When no longer needed, free the array memory
|
||||
|
||||
return 0;
|
||||
}
|
||||
</code>
|
||||
|
||||
==== Modifying Inline Array Content ====
|
||||
|
||||
=== To add data as the last element of the inline array ===
|
||||
|
||||
Use the ''eina_inarray_push()'' function. The first parameter is a pointer to
|
||||
the array variable returned by the ''eina_inarray_new()'' function. The second
|
||||
parameter is the data you want to push to the inline array.
|
||||
|
||||
If everything runs fine, the function returns the index of the new element. If
|
||||
something goes wrong, it returns ''-1''.
|
||||
|
||||
<code c>
|
||||
ch = 'a';
|
||||
eina_inarray_push(iarr, &ch);
|
||||
</code>
|
||||
|
||||
=== To insert data to a given position of the inline array ===
|
||||
|
||||
Use the ''eina_inarray_insert_at()'' function:
|
||||
* The first parameter is a pointer to the array variable returned by the ''eina_inarray_new()'' function.
|
||||
* The second parameter is the index of the element you want to add to the inline array.
|
||||
* The last parameter is a pointer to the content to be added.
|
||||
|
||||
The content of the pointer is copied to the given position in the inline
|
||||
array. All the members from the position to the end of the array are shifted
|
||||
towards the end. If the position is equal to the end of the array, the member
|
||||
is appended. If the position is bigger than the array length, the function
|
||||
fails.
|
||||
|
||||
<code c>
|
||||
ch = 'a';
|
||||
eina_inarray_push(iarr, &ch);
|
||||
ch = 'b';
|
||||
eina_inarray_push(iarr, &ch);
|
||||
ch = 'd';
|
||||
eina_inarray_push(iarr, &ch);
|
||||
|
||||
// Adding data on position 3
|
||||
ch = 'c';
|
||||
eina_inarray_insert_at(iarr, 2, &ch)
|
||||
</code>
|
||||
|
||||
=== To insert data with your own position criteria ===
|
||||
|
||||
Use the ''eina_inarray_insert()'' or ''eina_inarray_insert_sorted()''
|
||||
function. The only difference between these functions is that the
|
||||
''eina_inarray_insert_sorted()'' function assumes that the array is already
|
||||
sorted and consequently optimizes the insertion position by doing a binary
|
||||
search.
|
||||
|
||||
In both functions:
|
||||
|
||||
* The first parameter is a pointer to the array variable returned by the ''eina_inarray_new()'' function.
|
||||
* The second parameter is the data you want to push to the inline array.
|
||||
* The last parameter is the callback comparison function. \\ \\ The ''Eina_Compare_Cb'' callback function compares data1 and data2. data1 is the value contained in the inline array and data2 is the data you pass to the ''eina_inarray_insert()'' or ''eina_inarray_insert_sorted()'' function as the second parameter. If data1 is less than data2, -1 must be returned, if it is greater, 1 must be returned, and if they are equal, 0 must be returned.
|
||||
|
||||
The following example shows how to insert a value before a greater value:
|
||||
|
||||
<code c>
|
||||
// Defining the comparison function with the position criteria
|
||||
Eina_Compare_Cb cmp(const void *a, const void *b)
|
||||
{
|
||||
return *(int*)a > *(int*)b;
|
||||
}
|
||||
|
||||
int inline_insert()
|
||||
{
|
||||
Eina_Inarray *iarr;
|
||||
char ch, *ch3;
|
||||
int a, *b;
|
||||
|
||||
// Creating an inline array
|
||||
|
||||
// Adding data to the inline array
|
||||
a = 97;
|
||||
eina_inarray_push(iarr, &a);
|
||||
a = 98;
|
||||
eina_inarray_push(iarr, &a);
|
||||
a = 100;
|
||||
eina_inarray_push(iarr, &a);
|
||||
|
||||
// Inserting data with the criteria
|
||||
a = 99;
|
||||
eina_inarray_insert_sorted(iarr, &a, cmp);
|
||||
|
||||
eina_inarray_free(iarr);
|
||||
}
|
||||
</code>
|
||||
|
||||
=== To remove the last element of the inline array ===
|
||||
|
||||
Use the ''eina_inarray_pop()'' function. The only parameter is a pointer to
|
||||
the array variable returned by the ''eina_inarray_new()'' function. This
|
||||
function returns the data removed from the inline array.
|
||||
|
||||
<code c>
|
||||
eina_inarray_pop(iarr);
|
||||
</code>
|
||||
|
||||
=== To remove specific data from an inline array ===
|
||||
|
||||
Use the ''eina_inarray_remove()'' function. The first parameter is a pointer
|
||||
to the array variable returned by the ''eina_inarray_new()'' function. The
|
||||
second parameter is the data you want to remove from the inline array.
|
||||
|
||||
The ''eina_inarray_remove()'' function finds the data and removes the matching
|
||||
members from the array. The data can be an existing member of an inline array
|
||||
for optimized usage. In other cases, the content is matched using the
|
||||
''memcmp()'' function.
|
||||
|
||||
The ''eina_inarray_remove()'' function returns the index of the removed
|
||||
member, or -1 if failed.
|
||||
|
||||
<code c>
|
||||
iarr = eina_inarray_new(sizeof(char), 0);
|
||||
|
||||
ch = 'a';
|
||||
eina_inarray_push(iarr, &ch);
|
||||
|
||||
// Removing data from the array
|
||||
eina_inarray_remove(iarr, &ch);
|
||||
</code>
|
||||
|
||||
=== To remove data from a defined position in an inline array ===
|
||||
|
||||
Use the ''eina_inarray_remove_at()'' function. The first parameter is a
|
||||
pointer to the array variable returned by the ''eina_inarray_new()'' function.
|
||||
The second parameter is the index of the element you want to remove from the
|
||||
inline array.
|
||||
|
||||
The function returns ''EINA_TRUE'' on success and ''EINA_FALSE'' if something
|
||||
goes wrong. The member is removed from the inline array and any members after
|
||||
it are moved towards the array's head.
|
||||
|
||||
<code c>
|
||||
// Removing data from position 2
|
||||
eina_inarray_remove_at(iarr, 2);
|
||||
</code>
|
||||
|
||||
=== To remove all the elements of the array ===
|
||||
|
||||
Use the ''eina_inarray_flush()'' function. The first parameter is a pointer to
|
||||
the array variable returned by the ''eina_inarray_new()'' function. The
|
||||
function removes every member from the array.
|
||||
|
||||
<code c>
|
||||
eina_inarray_flush(iarr);
|
||||
</code>
|
||||
|
||||
=== To replace values in the inline array ===
|
||||
|
||||
Use the ''eina_inarray_replace_at()'' function, which copies the data over the
|
||||
given position:
|
||||
|
||||
* The first parameter is a pointer to the array variable returned by the ''eina_inarray_new()'' function.
|
||||
* The second parameter is the index of the element you want to remove from the inline array.
|
||||
* The last parameter is the data you want to copy in place of the current data.
|
||||
|
||||
The function returns ''EINA_TRUE'' on success, and ''EINA_FALSE'' on failure.
|
||||
The given pointer content is copied to the given position in the array. The
|
||||
pointer is not referenced, instead its contents are copied to the member's
|
||||
array using the previously defined ''member_size''. If the position does not
|
||||
exist, the function fails.
|
||||
|
||||
<code c>
|
||||
// Replacing the member at position 3
|
||||
ch = 'd';
|
||||
eina_inarray_replace_at(iarr, 3, &ch);
|
||||
</code>
|
||||
|
||||
=== To sort an inline array ===
|
||||
|
||||
Use the ''eina_inarray_sort()'' function, which applies a quick sorting algorithm to the inline array:
|
||||
|
||||
* The first parameter is a pointer to the array returned by the ''eina_inarray_new()'' function.
|
||||
* The last parameter is the ''Eina_Compare_Cb'' callback comparison function, which compares data1 and data2. \\ \\ data1 and data2 are values contained in the inline array. If the data matches, the function must return 0, if data1 is less than data2, -1 must be returned and if it is greater, 1 must be returned.
|
||||
|
||||
<code c>
|
||||
static int
|
||||
short_cmp(const void *pa, const void *pb)
|
||||
{
|
||||
const short *a = pa, *b = pb;
|
||||
|
||||
return *a - *b;
|
||||
}
|
||||
|
||||
int sorting_inline_array()
|
||||
{
|
||||
Eina_Inarray *array;
|
||||
int i;
|
||||
|
||||
// Creating and populating the inline array
|
||||
|
||||
eina_inarray_sort(array, short_cmp);
|
||||
eina_inarray_free(array);
|
||||
}
|
||||
</code>
|
||||
|
||||
Be careful, the data given to the compare function is the pointer to the
|
||||
member memory itself. Do not change it.
|
||||
|
||||
==== Accessing Inline Array Data ====
|
||||
|
||||
=== To search a member in an inline array ===
|
||||
|
||||
Use the ''eina_inarray_search()'' function that runs a linear walk looking for
|
||||
the given data:
|
||||
|
||||
* The first parameter is a pointer to the array variable returned by the ''eina_inarray_new()'' function.
|
||||
* The second parameter is the data used by the callback function to run the comparison.
|
||||
* The last parameter is the ''Eina_Compare_Cb'' callback comparison function, which compares data1 and data2. \\ \\ data1 is the value contained in the inline array and data2 is the data you pass to the ''eina_inarray_search()'' function as the second parameter. If the data matches, the function must return 0, if data1 is less than data2, -1 must be returned and if it is greater, 1 must be returned.
|
||||
|
||||
The function returns the member index, or -1 if not found.
|
||||
|
||||
<code c>
|
||||
Eina_Compare_Cb
|
||||
compare(const void *pa, const void *pb)
|
||||
{
|
||||
const short *a = pa, *b = pb;
|
||||
if (*a == *b)
|
||||
return EINA_TRUE;
|
||||
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
int search_inline_array()
|
||||
{
|
||||
Eina_Inarray *array;
|
||||
int i;
|
||||
int elm_index;
|
||||
int to_search = 3;
|
||||
|
||||
// Creating and populating the inline array
|
||||
|
||||
elm_index = eina_inarray_search(array, &to_search, compare);
|
||||
eina_inarray_free(array);
|
||||
}
|
||||
</code>
|
||||
|
||||
Be careful, the data given to the compare function is the pointer to the
|
||||
member memory itself. Do not change it.
|
||||
|
||||
The ''eina_inarray_search_sorted()'' function does exactly the same as
|
||||
''eina_inarray_search()'', but uses a binary search for the given data.
|
||||
|
||||
=== To get the number of elements in an inline array ===
|
||||
|
||||
Use the ''eina_inarray_count()''. The first parameter is a pointer to the
|
||||
array returned by the ''eina_inarray_new()'' function. The function returns an
|
||||
''unsigned int'', the number of elements.
|
||||
|
||||
<code c>
|
||||
printf("Inline array of integers with %d elements:\n", eina_inarray_count(iarr));
|
||||
</code>
|
||||
|
||||
=== To iterate through an inline array ===
|
||||
|
||||
You can use various methods:
|
||||
* You can use the iterator macros for the inline arrays: ''FOREACH'' and ''REVERSE_FOREACH''.
|
||||
* To run a linear walk over an array of elements, use the ''EINA_INARRAY_FOREACH()'' macro. The first parameter is a pointer to the array variable returned by ''eina_inarray_new()'', and the second parameter is the variable into which the current value is put during the walk. The ''EINA_INARRAY_REVERSE_FOREACH()'' macro does the same thing but starts from the last element. \\ \\ The following example illustrates the printing of each element and its pointer:
|
||||
|
||||
<code c>
|
||||
iarr = eina_inarray_new(sizeof(char), 0);
|
||||
int a, *b;
|
||||
|
||||
a = 97;
|
||||
eina_inarray_push(iarr, &a);
|
||||
a = 98;
|
||||
eina_inarray_push(iarr, &a);
|
||||
a = 99;
|
||||
eina_inarray_push(iarr, &a);
|
||||
|
||||
EINA_INARRAY_FOREACH(iarr, b)
|
||||
printf("int: %d(pointer: %p)\n", *b, b);
|
||||
</code>
|
||||
|
||||
* To process the array data, use the ''eina_inarray_foreach()'' function, which invokes the given function on each element of the array with the given data:
|
||||
* The first parameter is a pointer to the array variable returned by ''eina_inarray_new()''.
|
||||
* The second parameter is the function to run on each element. \\ \\ The function must return ''EINA_TRUE'' as long as you want to continue iterating. By returning ''EINA_FALSE'', you stop the iteration and make the ''eina_inarray_foreach()'' function return ''EINA_FALSE''. \\ \\ The data given to the function is the pointer to the member itself.
|
||||
* The last parameter is the data passed to the function called on each element.
|
||||
|
||||
The ''eina_inarray_foreach()'' function returns ''EINA_TRUE'' if it
|
||||
successfully iterates through all items of the array. Call the function for
|
||||
every given data in the array. This is a safe way to iterate over an array.
|
||||
|
||||
<code c>
|
||||
static Eina_Bool
|
||||
array_foreach(const void *array __UNUSED__, void *p, void *user_data __UNUSED__)
|
||||
{
|
||||
short *member = p;
|
||||
int *i = user_data;
|
||||
(*p)++;
|
||||
(*i)++;
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
int inline_array_foreach()
|
||||
{
|
||||
Eina_Inarray *iarr;
|
||||
iarr = eina_inarray_new(sizeof(char), 1);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < numbers_count; i++)
|
||||
{
|
||||
short val = i;
|
||||
eina_inarray_push(iarr, &val);
|
||||
}
|
||||
|
||||
i = 0;
|
||||
eina_inarray_foreach(iarr, array_foreach, &i);
|
||||
|
||||
eina_inarray_free(iarr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
</code>
|
||||
|
||||
=== To remove some elements based on your own criteria ===
|
||||
|
||||
Use the ''eina_inarray_foreach_remove()'' function, which walks through the
|
||||
array and, if the value matches in the callback function, removes the element:
|
||||
|
||||
* The first parameter is a pointer to the array returned by ''eina_inarray_new()'' function.
|
||||
* The second parameter is the callback function to run on each element. \\ \\ The callback function returns ''EINA_TRUE'' if the value matches, or ''EINA_FALSE'' if it does not match.
|
||||
* The last parameter is the data passed to the callback function.
|
||||
|
||||
The function returns the number of removed entries or -1 if something goes wrong.
|
||||
|
||||
<code c>
|
||||
static Eina_Bool
|
||||
array_foreach(const void *array __UNUSED__, void *p, void *user_data __UNUSED__)
|
||||
{
|
||||
short *member = p;
|
||||
int *i = user_data;
|
||||
if (*i == *p)
|
||||
return EINA_TRUE;
|
||||
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
int inline_array_foreach_remove()
|
||||
{
|
||||
Eina_Inarray *iarr;
|
||||
iarr = eina_inarray_new(sizeof(char), 1);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < numbers_count; i++)
|
||||
{
|
||||
short val = i;
|
||||
eina_inarray_push(iarr, &val);
|
||||
}
|
||||
|
||||
i = 6;
|
||||
eina_inarray_foreach_remove(iarr, array_foreach, &i);
|
||||
|
||||
eina_inarray_free(iarr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
</code>
|
||||
|
||||
-------
|
||||
{{page>index}}
|
|
@ -0,0 +1,96 @@
|
|||
{{page>index}}
|
||||
-------
|
||||
===== Generic Value =====
|
||||
|
||||
The ''Eina_Value'' object provides generic data storage and access, allowing
|
||||
you to store what you want in one single type of ''Eina_Value''. It is meant
|
||||
for simple data types, providing uniform access and release functions, useful
|
||||
to exchange data preserving their types. The ''Eina_Value'' comes with
|
||||
predefined types for numbers, array, list, hash, blob, and structs, and it can
|
||||
convert between data types, including string.
|
||||
|
||||
=== Related Info ===
|
||||
|
||||
* [[https://build.enlightenment.org/job/nightly_efl_gcc_x86_64/lastSuccessfulBuild/artifact/doc/html/group__Eina__Value__Group.html|Generic Value API]]
|
||||
|
||||
|[[https://build.enlightenment.org/job/nightly_efl_gcc_x86_64/lastSuccessfulBuild/artifact/doc/html/eina_value_01_8c-example.html|Generic Value Example 1]]|[[https://build.enlightenment.org/job/nightly_efl_gcc_x86_64/lastSuccessfulBuild/artifact/doc/html/eina_value_02_8c-example.html|Generic Value Example 2]]|[[https://build.enlightenment.org/job/nightly_efl_gcc_x86_64/lastSuccessfulBuild/artifact/doc/html/eina_value_03_8c-example.html|Generic Value Example 3]]|
|
||||
|
||||
The ''Eina_Value'' can handle the following 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'': unsigned long used for timestamps
|
||||
* ''EINA_VALUE_TYPE_UINT64'': unsigned integer of 64 bits
|
||||
* ''EINA_VALUE_TYPE_CHAR'': char
|
||||
* ''EINA_VALUE_TYPE_SHORT'': short
|
||||
* ''EINA_VALUE_TYPE_INT'': int
|
||||
* ''EINA_VALUE_TYPE_LONG'': long
|
||||
* ''EINA_VALUE_TYPE_INT64'': integer of 64 bits
|
||||
* ''EINA_VALUE_TYPE_FLOAT'': float
|
||||
* ''EINA_VALUE_TYPE_DOUBLE'': double
|
||||
* ''EINA_VALUE_TYPE_STRINGSHARE'': stringshared string
|
||||
* ''EINA_VALUE_TYPE_STRING'': string
|
||||
* ''EINA_VALUE_TYPE_ARRAY'': array
|
||||
* ''EINA_VALUE_TYPE_LIST'': list
|
||||
* ''EINA_VALUE_TYPE_HASH'': hash
|
||||
* ''EINA_VALUE_TYPE_TIMEVAL'': 'struct timeval'
|
||||
* ''EINA_VALUE_TYPE_BLOB'': blob of bytes
|
||||
* ''EINA_VALUE_TYPE_STRUCT'': struct
|
||||
|
||||
|
||||
To set up a generic value:
|
||||
|
||||
__**1**__. Declare the necessary variables:
|
||||
|
||||
<code c>
|
||||
// The Eina_Value itself
|
||||
Eina_Value v;
|
||||
// An integer
|
||||
int i;
|
||||
// And a char *
|
||||
char *newstr;
|
||||
</code>
|
||||
|
||||
__**2**__. To set up an Eina_Value for an integer, use the
|
||||
''eina_value_setup()'' function. The first argument is the ''Eina_Value'' and
|
||||
the second is the type.
|
||||
|
||||
<code c>
|
||||
eina_value_setup(&v, EINA_VALUE_TYPE_INT);
|
||||
</code>
|
||||
|
||||
To manage the generic value:
|
||||
|
||||
* To set an integer, use the ''eina_value_set()'' function:
|
||||
|
||||
<code c>
|
||||
eina_value_set(&v, 123);
|
||||
</code>
|
||||
|
||||
* To get the value, use the ''eina_value_get()'' function. Pass the ''Eina_Value'' as the first argument, and a pointer to a variable to store the value (the target variable must have the same type as the ''Eina_Value'').
|
||||
|
||||
<code c>
|
||||
eina_value_get(&v, &i);
|
||||
printf("v=%d\n", i);
|
||||
</code>
|
||||
The above example prints "v=123".
|
||||
|
||||
* To store a string, get its value, and print it:
|
||||
|
||||
<code c>
|
||||
const char *s;
|
||||
|
||||
eina_value_setup(&v, EINA_VALUE_TYPE_STRING);
|
||||
eina_value_set(&v, "My string");
|
||||
eina_value_get(&v, &s);
|
||||
|
||||
printf("v=%s (pointer: %p)\n", s, s);
|
||||
</code>
|
||||
|
||||
* To store an ''Eina_List'', use the ''Eina_Value'' that corresponds to the ''EINA_VALUE_TYPE_LIST'' type.
|
||||
* To create an ''Eina_Value_List'', use the ''eina_value_list_setup()'' function. The function initializes a generic value storage of the list type. The first parameter is the "object" value, and the second one is the type (how to manage the stored list members).
|
||||
|
||||
-------
|
||||
{{page>index}}
|
|
@ -0,0 +1,338 @@
|
|||
{{page>index}}
|
||||
-------
|
||||
===== Hash Tables =====
|
||||
|
||||
The ''Eina_Hash'' provides a way to store values in association with a key.
|
||||
For example, if you want to store some tuples into a table, you can do it
|
||||
using the ''Eina_Hash''.
|
||||
|
||||
The ''Eina_Hash'' is implemented using an array of "buckets" where each bucket
|
||||
is a pointer to a structure that is the head of a red-black tree. This
|
||||
implementation makes it very robust against week keys as in the worst case
|
||||
scenario, you can still depend on an efficient binary tree implementation.
|
||||
|
||||
=== Table of Contents ===
|
||||
|
||||
* [[#Creating_a_Hash_Table|Creating a Hash Table]]
|
||||
* [[#Modifying_Hash_Table_Content|Modifying Hash Table Content]]
|
||||
* [[#To_add_some_data_to_a_hash|To add some data to a hash]]
|
||||
* [[#To_modify_an_entry|To modify an entry]]
|
||||
* [[#To_change_the_key_associated_with_the_data_without_freeing_and_creating_a_new_entry|To change the key associated with the data without freeing and creating a new entry]]
|
||||
* [[#To_delete_entries_from_a_hash_table|To delete entries from a hash table]]
|
||||
* [[#Accessing_Hash_Table_Data|Accessing Hash Table Data]]
|
||||
* [[#To_retrieve_an_entry_based_on_its_key|To retrieve an entry based on its key]]
|
||||
* [[#To_get_the_number_of_entries_in_a_hash|To get the number of entries in a hash]]
|
||||
* [[#To_iterate_through_a_hash_table|To iterate through a hash table]]
|
||||
* [[#To_iterate_over_the_keys|To iterate over the keys]]
|
||||
* [[#To_iterate_over_the_hash_data|To iterate over the hash data]]
|
||||
* [[#To_iterate_over_a_tuple_composed_of_keys_and_data|To iterate over a tuple composed of keys and data]]
|
||||
=== Related Info ===
|
||||
|
||||
* [[https://build.enlightenment.org/job/nightly_efl_gcc_x86_64/lastSuccessfulBuild/artifact/doc/html/group__Eina__Hash__Group.html|Hash Table API]]
|
||||
|
||||
|[[https://build.enlightenment.org/job/nightly_efl_gcc_x86_64/lastSuccessfulBuild/artifact/doc/html/eina_hash_01_8c-example.html|Hash Table Example 1]]|[[https://build.enlightenment.org/job/nightly_efl_gcc_x86_64/lastSuccessfulBuild/artifact/doc/html/eina_hash_02_8c-example.html|Hash Table Example 2]]|[[https://build.enlightenment.org/job/nightly_efl_gcc_x86_64/lastSuccessfulBuild/artifact/doc/html/eina_hash_03_8c-example.html|Hash Table Example 3]]|[[https://build.enlightenment.org/job/nightly_efl_gcc_x86_64/lastSuccessfulBuild/artifact/doc/html/eina_hash_04_8c-example.html|Hash Table Example 4]]|
|
||||
|[[https://build.enlightenment.org/job/nightly_efl_gcc_x86_64/lastSuccessfulBuild/artifact/doc/html/eina_hash_05_8c-example.html|Hash Table Example 5]]|[[https://build.enlightenment.org/job/nightly_efl_gcc_x86_64/lastSuccessfulBuild/artifact/doc/html/eina_hash_06_8c-example.html|Hash Table Example 6]]|[[https://build.enlightenment.org/job/nightly_efl_gcc_x86_64/lastSuccessfulBuild/artifact/doc/html/eina_hash_07_8c-example.html|Hash Table Example 7]]|[[https://build.enlightenment.org/job/nightly_efl_gcc_x86_64/lastSuccessfulBuild/artifact/doc/html/eina_hash_08_8c-example.html|Hash Table Example 8]]|
|
||||
|
||||
==== Creating a Hash Table ====
|
||||
|
||||
To create the hash table, use the ''eina_hash_new()'' function:
|
||||
|
||||
* The first parameter is the function called when getting the size of the key.
|
||||
* The second parameter is the function called when comparing the keys.
|
||||
* The third parameter is the function called when getting the values.
|
||||
* The fourth parameter is the function called on each value when the hash table is freed, or when an item is deleted from it. ''NULL'' can be passed as the callback.
|
||||
* The last parameter is the size of the buckets.
|
||||
|
||||
When you create an ''Eina_Hash'' instance, you have to create 4 potentially
|
||||
long callback functions. To make the functions shorter, ''Eina_Hash'' offers
|
||||
some predefined functions to create the following kinds of hash tables:
|
||||
|
||||
* ''eina_hash_string_djb2_new()'' creates a new hash table using the djb2 algorithm for strings.
|
||||
* ''eina_hash_string_superfast_new()'' creates a new hash table for use with strings (better with long strings).
|
||||
* ''eina_hash_string_small_new()'' creates a new hash table for use with strings with a small bucket size.
|
||||
* ''eina_hash_int32_new()'' and ''eina_hash_int64_new()'' create a new hash table for use with 32-bit and 64-bit integers.
|
||||
* ''eina_hash_pointer_new()'' creates a new hash table for use with pointers.
|
||||
* ''eina_hash_stringshared_new()'' creates a new hash table for use with shared strings.
|
||||
|
||||
All these predefined functions require only one parameter, which is the
|
||||
function to free the data you store in the hash table.
|
||||
|
||||
The following example shows how to manage a small phone book using the
|
||||
''eina_hash_string_superfast_new()'' function to create the hash table.
|
||||
|
||||
__**1**__. Create the phone book structure and some static data:
|
||||
|
||||
<code c>
|
||||
struct _Phone_Entry
|
||||
{
|
||||
const char *name; // Full name
|
||||
const char *number; // Phone number
|
||||
};
|
||||
|
||||
typedef struct _Phone_Entry Phone_Entry;
|
||||
|
||||
static Phone_Entry _start_entries[] =
|
||||
{
|
||||
{ "Wolfgang Amadeus Mozart", "+01 23 456-78910" },
|
||||
{ "Ludwig van Beethoven", "+12 34 567-89101" },
|
||||
{ "Richard Georg Strauss", "+23 45 678-91012" },
|
||||
{ "Heitor Villa-Lobos", "+34 56 789-10123" },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
</code>
|
||||
|
||||
__**2**__. Create the callback to free the data:
|
||||
|
||||
<code c>
|
||||
static void
|
||||
_phone_entry_free_cb(void *data)
|
||||
{
|
||||
free(data);
|
||||
}
|
||||
</code>
|
||||
|
||||
The free callback can be changed later using the ''eina_hash_free_cb_set()''
|
||||
function. You need to pass the hash and the new callback function.
|
||||
|
||||
__**3**__. Create and destroy the hash table.
|
||||
|
||||
The ''eina_hash_free_buckets()'' function frees all hash table buckets. It
|
||||
empties the hash but does not destroy it, and you can still use it for another
|
||||
purpose. When ''eina_hash_free()'' is called, the space allocated for the hash
|
||||
is freed.
|
||||
|
||||
<code c>
|
||||
int free_data()
|
||||
{
|
||||
Eina_Hash *phone_book = NULL;
|
||||
phone_book = eina_hash_string_superfast_new(_phone_entry_free_cb);
|
||||
|
||||
// Empty the phone book without destroying it
|
||||
eina_hash_free_buckets(phone_book);
|
||||
eina_hash_free(phone_book);
|
||||
}
|
||||
</code>
|
||||
|
||||
==== Modifying Hash Table Content ====
|
||||
|
||||
=== To add some data to a hash ===
|
||||
|
||||
Use the ''eina_hash_add()'' function. This function takes the hash, the key to
|
||||
access the data, and the data as its parameters. \\ \\ The following example shows how to add the initial data declared earlier to the hash:
|
||||
|
||||
<code c>
|
||||
for (i = 0; _start_entries[i].name != NULL; i++)
|
||||
{
|
||||
eina_hash_add(phone_book, _start_entries[i].name, strdup(_start_entries[i].number));
|
||||
}
|
||||
</code>
|
||||
|
||||
The ''Eina_Hash'' offers various ways to add elements to a hash, such as the
|
||||
''eina_hash_direct_add()'' function, which adds the entry without duplicating
|
||||
the string key. The key is stored in the struct, so this function can be used
|
||||
with ''eina_stringshare'' to avoid key data duplication.
|
||||
|
||||
<code c>
|
||||
for (i = 0; _start_entries[i].name != NULL; i++)
|
||||
{
|
||||
// Allocating memory for the phone entry
|
||||
Phone_Entry *e = malloc(sizeof(Phone_Entry));
|
||||
|
||||
// Creating an eina_stringshare for the name and the phone number
|
||||
e->name = eina_stringshare_add(_start_entries[i].name);
|
||||
e->number = eina_stringshare_add(_start_entries[i].number);
|
||||
|
||||
// Adding the entry to the hash
|
||||
eina_hash_direct_add(phone_book, e->name, e);
|
||||
}
|
||||
</code>
|
||||
|
||||
=== To modify an entry ===
|
||||
|
||||
Use ''eina_hash_modify()'' function passing the hash, the key of the data to
|
||||
change, and the new data. The function returns the old data on success.
|
||||
|
||||
The ''eina_hash_set()'' function does the same work as ''eina_hash_modify()'',
|
||||
but if the entry does not exist, the function creates a new one.
|
||||
|
||||
<code c>
|
||||
char *old_phone = NULL;
|
||||
char *phone = NULL;
|
||||
// Replace the phone number of Richard Strauss
|
||||
old_phone = eina_hash_modify(phone_book, "Richard Georg Strauss", strdup("+23 45 111-11111"));
|
||||
phone = eina_hash_set(phone_book, "Philippe de Magalhães", strdup("+33 6 111-11111"));
|
||||
eina_hash_set(phone_book, "Richard Georg Strauss", strdup("+23 45 111-117711"));
|
||||
</code>
|
||||
|
||||
=== To change the key associated with the data without freeing and creating a new entry ===
|
||||
|
||||
Use the ''eina_hash_move()'' function. You only have to pass the hash, the old
|
||||
key, and the new key. If the operation succeeds, the function returns
|
||||
''EINA_TRUE'', if not, it returns ''EINA_FALSE''.
|
||||
|
||||
<code c>
|
||||
Eina_Bool res;
|
||||
res = eina_hash_move(phone_book, "Philippe de Magalhães", "Filipe de Magalhães");
|
||||
</code>
|
||||
|
||||
=== To delete entries from a hash table ===
|
||||
|
||||
Use the ''eina_hash_del()'' function to remove the entry identified by a key
|
||||
or data from the given hash table:
|
||||
|
||||
<code c>
|
||||
Eina_Bool r;
|
||||
const char *entry_name = "Heitor Villa-Lobos";
|
||||
r = eina_hash_del(phone_book, entry_name, NULL);
|
||||
</code>
|
||||
|
||||
Use the ''eina_hash_del_by_key()'' function to remove an entry based on the
|
||||
key:
|
||||
|
||||
<code c>
|
||||
r = eina_hash_del_by_key(phone_book, "Richard Georg Strauss");
|
||||
</code>
|
||||
|
||||
Use the ''eina_hash_del_by_data()'' function to remove an entry based on the
|
||||
data:
|
||||
|
||||
<code c>
|
||||
r = eina_hash_del_by_data(phone_book, "+12 34 567-89101");
|
||||
</code>
|
||||
|
||||
==== Accessing Hash Table Data ====
|
||||
|
||||
To find hash table elements and get data based on the key name:
|
||||
|
||||
=== To retrieve an entry based on its key ===
|
||||
|
||||
Use the ''eina_hash_find()'' function by passing the hash and the key you are
|
||||
looking for:
|
||||
|
||||
<code c>
|
||||
char *phone = NULL;
|
||||
const char *entry_name = "Heitor Villa-Lobos";
|
||||
|
||||
// Look for a specific entry and get its phone number
|
||||
phone = eina_hash_find(phone_book, entry_name);
|
||||
</code>
|
||||
|
||||
=== To get the number of entries in a hash ===
|
||||
|
||||
Use the ''eina_hash_population()'' function. Pass the hash as the only
|
||||
argument.
|
||||
|
||||
<code c>
|
||||
unsigned int nb_elm;
|
||||
nb_elm = eina_hash_population(phone_book);
|
||||
</code>
|
||||
|
||||
=== To iterate through a hash table ===
|
||||
|
||||
You can use various methods:
|
||||
* to iterate over the hash table, use the ''eina_hash_foreach()'' function:
|
||||
* The first parameter is the hash.
|
||||
* The second parameter is the callback function called on each iteration. \\ \\ The callback function has to return an ''Eina_Bool'', ''EINA_TRUE'' if the iteration has to continue and ''EINA_FALSE'' if the iteration has to stop.
|
||||
* The last parameter one is the data passed to the callback function.
|
||||
|
||||
The following example prints the key and the data of the hash entry (the name and the phone number):
|
||||
|
||||
<code c>
|
||||
static Eina_Bool
|
||||
pb_foreach_cb(const Eina_Hash *phone_book, const void *key, void *data, void *fdata)
|
||||
{
|
||||
const char *name = key;
|
||||
const char *number = data;
|
||||
printf("%s: %s\n", name, number);
|
||||
|
||||
// Return EINA_FALSE to stop this callback from being called
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
printf("List of phones:\n");
|
||||
|
||||
// Running the callback on the hash called phone_book
|
||||
eina_hash_foreach(phone_book, pb_foreach_cb, NULL);
|
||||
printf("\n");
|
||||
</code>
|
||||
|
||||
=== To iterate over the keys ===
|
||||
|
||||
Use the ''eina_hash_iterator_key_new()'' function:
|
||||
|
||||
<code c>
|
||||
// Declaration of the Eina_Iterator
|
||||
Eina_Iterator *it;
|
||||
|
||||
// Variable to handle the current iteration "data"
|
||||
void *data;
|
||||
|
||||
// Iterate over the keys (names)
|
||||
printf("List of names in the phone book:\n");
|
||||
|
||||
it = eina_hash_iterator_key_new(phone_book);
|
||||
|
||||
// Use the generic eina_iterator_next()
|
||||
while (eina_iterator_next(it, &data))
|
||||
{
|
||||
const char *name = data;
|
||||
printf("%s\n", name);
|
||||
}
|
||||
|
||||
// Free the iterator
|
||||
eina_iterator_free(it);
|
||||
</code>
|
||||
|
||||
=== To iterate over the hash data ===
|
||||
|
||||
Use the ''eina_hash_iterator_data_new()'' function the same way as
|
||||
''eina_hash_iterator_key_new()'':
|
||||
|
||||
<code c>
|
||||
// Declaration of the Eina_Iterator
|
||||
Eina_Iterator *it;
|
||||
|
||||
// Variable to handle the current iteration "data"
|
||||
void *data;
|
||||
|
||||
// Iterate over hash data
|
||||
printf("List of numbers in the phone book:\n");
|
||||
|
||||
it = eina_hash_iterator_data_new(phone_book);
|
||||
while (eina_iterator_next(it, &data))
|
||||
{
|
||||
const char *number = data;
|
||||
printf("%s\n", number);
|
||||
}
|
||||
|
||||
// Free the iterator
|
||||
eina_iterator_free(it);
|
||||
</code>
|
||||
|
||||
=== To iterate over a tuple composed of keys and data ===
|
||||
|
||||
Use the ''eina_hash_iterator_tuple_new()'' function:
|
||||
|
||||
<code c>
|
||||
// Declaration of the Eina_Iterator
|
||||
Eina_Iterator *tit;
|
||||
|
||||
// Variable to handle the current iteration "data"
|
||||
void *tuple;
|
||||
|
||||
printf("List of phones:\n");
|
||||
tit = eina_hash_iterator_tuple_new(phone_book);
|
||||
while (eina_iterator_next(tit, &tuple))
|
||||
{
|
||||
Eina_Hash_Tuple *t = tuple;
|
||||
const char *name = t->key;
|
||||
const char *number = t->data;
|
||||
printf("%s: %s\n", name, number);
|
||||
}
|
||||
|
||||
// Always free the iterator after its use
|
||||
eina_iterator_free(tit);
|
||||
</code>
|
||||
|
||||
-------
|
||||
{{page>index}}
|
|
@ -0,0 +1,6 @@
|
|||
++++Eina Menu|
|
||||
^ [[/program_guide/eina_pg|Eina Programming Guide]] ^^^^^^^
|
||||
^ Data Types | [[/program_guide/eina/iterator_functions|Iterator Functions]] | [[/program_guide/eina/strings|Strings]] | [[/program_guide/eina/arrays|Arrays]] | [[/program_guide/eina/hash_tables|Hash Tables]] | [[/program_guide/eina/lists|Lists]] | [[/program_guide/eina/generic_value|Generic Value]] |
|
||||
^ Eina Tools | [[/program_guide/eina/string_tools|String]] || [[/program_guide/eina/memory_pool_tools|Memory Pool]] || [[/program_guide/eina/safety_checks_tools|Safety Checks]] ||
|
||||
++++
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
{{page>index}}
|
||||
-------
|
||||
===== Iterator Functions =====
|
||||
|
||||
=== Related Info ===
|
||||
|
||||
* [[https://build.enlightenment.org/job/nightly_efl_gcc_x86_64/lastSuccessfulBuild/artifact/doc/html/group__Eina__Iterator__Group.html|Iterator Functions API]]
|
||||
* [[https://build.enlightenment.org/job/nightly_efl_gcc_x86_64/lastSuccessfulBuild/artifact/doc/html/eina_iterator_01_8c-example.html|Eina Iterator Example]]
|
||||
|
||||
Eina provides a set of iterator functions to manipulate data types, such as
|
||||
arrays.
|
||||
|
||||
These functions allow access to container elements in a generic way, without
|
||||
knowing which container is used (similar to iterators in the C++ STL).
|
||||
Iterators only allow sequential access (that is, from one element to the next
|
||||
one). For random access, Eina provides accessor functions.
|
||||
|
||||
Getting an iterator to access elements of a given container is done through
|
||||
the functions of that particular container. There is no function to create a
|
||||
generic iterator as iterators absolutely depend on the container. Note that
|
||||
all iterators, regardless of the container type, are always deleted with the
|
||||
same ''eina_iterator_free()'' function.
|
||||
|
||||
To get the data and iterate, use the ''eina_iterator_next()'' function. To
|
||||
call a function on every single element of a container, use the
|
||||
''eina_iterator_foreach()'' function.
|
||||
|
||||
In addition to iterator functions, each data type also owns a set of macros
|
||||
that provide the iterators, such as ''FOREACH'' or ''REVERSE_FOREACH''.
|
||||
|
||||
-------
|
||||
{{page>index}}
|
|
@ -0,0 +1,601 @@
|
|||
{{page>index}}
|
||||
-------
|
||||
===== Lists =====
|
||||
|
||||
The ''Eina_List'' is a double-linked list that can store data of any type as
|
||||
void pointers. It provides a set of functions to create and manipulate the
|
||||
list to avoid the access to the struct's fields, similar to a self-made
|
||||
double-link list.
|
||||
|
||||
In addition to the previous and next node and its data, the ''Eina_List''
|
||||
nodes keep a reference to an accounting structure. The accounting structure is
|
||||
used to improve the performance of some functions. The structure is private
|
||||
and must not be modified.
|
||||
|
||||
In an ''Eina_List'', everything is a "list": the list itself is a list where
|
||||
each node is a list as well.
|
||||
|
||||
Eina provides 2 list types: the classic list (''Eina_List'') and an inline
|
||||
list (''Eina_Inlist'').
|
||||
|
||||
=== Table of Contents ===
|
||||
|
||||
* [[#Creating_and_Destroying_a_List|Creating and Destroying a List]]
|
||||
* [[#Modifying_List_Content|Modifying List Content]]
|
||||
* [[#To_add_data_to_a_list|To add data to a list]]
|
||||
* [[#To_set_data_in_a_list_member|To set data in a list member]]
|
||||
* [[#To_remove_a_node_from_the_list|To remove a node from the list]]
|
||||
* [[#To_move_elements_in_a_list|To move elements in a list]]
|
||||
* [[#To_reverse_all_the_elements_of_a_list|To reverse all the elements of a list]]
|
||||
* [[#To_sort_a_list|To sort a list]]
|
||||
* [[#To_merge_2_list_into_1|To merge 2 list into 1]]
|
||||
* [[#To_split_a_list|To split a list]]
|
||||
* [[#To_copy_a_list|To copy a list]]
|
||||
* [[#Accessing_List_Data|Accessing List Data]]
|
||||
* [[#To_find_some_data_on_your_list|To find some data on your list]]
|
||||
* [[#To_search_for_data_in_a_list|To search for data in a list]]
|
||||
* [[#To_get_data_from_a_list_element|To get data from a list element]]
|
||||
* [[#To_move_in_a_list|To move in a list]]
|
||||
* [[#To_count_the_list_elements|To count the list elements]]
|
||||
* [[#To_iterate_through_an_array|To iterate through an array]]
|
||||
* [[#Using_an_Inline_List|Using an Inline List]]
|
||||
|
||||
=== Related Info ===
|
||||
|
||||
* [[https://build.enlightenment.org/job/nightly_efl_gcc_x86_64/lastSuccessfulBuild/artifact/doc/html/group__Eina__List__Group.html|List API]]
|
||||
|
||||
|[[https://build.enlightenment.org/job/nightly_efl_gcc_x86_64/lastSuccessfulBuild/artifact/doc/html/eina_list_01_8c-example.html|List Example 1]]|[[https://build.enlightenment.org/job/nightly_efl_gcc_x86_64/lastSuccessfulBuild/artifact/doc/html/eina_list_02_8c-example.html|List Example 2]]||[[https://build.enlightenment.org/job/nightly_efl_gcc_x86_64/lastSuccessfulBuild/artifact/doc/html/eina_list_03_8c-example.html|List Example 3]]|[[https://build.enlightenment.org/job/nightly_efl_gcc_x86_64/lastSuccessfulBuild/artifact/doc/html/eina_list_04_8c-example.html|List Example 4]]|
|
||||
|
||||
==== Creating and Destroying a List ====
|
||||
|
||||
To use an ''Eina_List'':
|
||||
|
||||
__**1**__. Declare the list with ''NULL'' as the default value:
|
||||
|
||||
<code c>
|
||||
int list()
|
||||
{
|
||||
// Declaration of the Eina_List with NULL as default value;
|
||||
Eina_List *list = NULL;
|
||||
</code>
|
||||
|
||||
__**2**__. Call the ''eina_list_append()'' function with the list and the data you
|
||||
want to append as parameters.
|
||||
|
||||
The list must be a pointer to the first element of the list (or ''NULL''). The
|
||||
function returns a pointer to the list.
|
||||
|
||||
<code c>
|
||||
// Creating the first element of the list
|
||||
list = eina_list_append(list, "watch");
|
||||
|
||||
// Adding more elements
|
||||
list = eina_list_append(list, "phone");
|
||||
list = eina_list_append(list, "ivi");
|
||||
list = eina_list_append(list, "notebook");
|
||||
</code>
|
||||
|
||||
__**3**__. When you no longer need the list, free it:
|
||||
|
||||
<code c>
|
||||
// Free the Eina_List
|
||||
eina_list_free(list);
|
||||
|
||||
return 0;
|
||||
}
|
||||
</code>
|
||||
|
||||
==== Modifying List Content ====
|
||||
|
||||
=== To add data to a list ===
|
||||
|
||||
* To add data at the end of the list, use the ''eina_list_append()'' function. To add data at the top of the list, use ''eina_list_prepend()''. The functions work in the same way, only adding the data to different places.
|
||||
|
||||
<code c>
|
||||
list = eina_list_prepend(list, "set-top box");
|
||||
</code>
|
||||
|
||||
* To insert data into the list after a specified data, use the ''eina_list_append_relative()'' function. As the last parameter, define the element after which the data is added. \\ \\ For example to append data after the "phone" element:
|
||||
|
||||
<code c>
|
||||
list = eina_list_append_relative(list, "single-board computer", "phone");
|
||||
</code>
|
||||
|
||||
* To add a new entry before a specified data, use the ''eina_list_prepend_relative()'' function. It is similar to the ''eina_list_append_relative()'' function.
|
||||
|
||||
<code c>
|
||||
list = eina_list_prepend_relative(list, "ultrabook", "ivi");
|
||||
</code>
|
||||
|
||||
* To append a list node to a linked list after a specified member, use the ''eina_list_append_relative_list()'' function. To prepend a list node to a linked list before a specified member, use the ''Eina_List * eina_list_prepend_relative_list()'' function.
|
||||
|
||||
=== To set data in a list member ===
|
||||
Use the ''eina_list_data_set()'' function. Pass the
|
||||
"list" (node) as the first argument and the data to set as the second.
|
||||
|
||||
The following example also shows the usage of the ''eina_list_last()''
|
||||
function, which returns the last element of an ''Eina_List''.
|
||||
|
||||
<code c>
|
||||
// Setting new data for the last element
|
||||
eina_list_data_set(eina_list_last(list), eina_stringshare_add("Boris"));
|
||||
</code>
|
||||
|
||||
=== To remove a node from the list ===
|
||||
|
||||
Use the ''eina_list_remove()'' function. This function removes the first
|
||||
instance of the specified data from the given list.
|
||||
|
||||
<code c>
|
||||
list = eina_list_remove(list, "ultrabook");
|
||||
</code>
|
||||
|
||||
You can also remove a "list" (node) from a list using the
|
||||
''eina_list_remove_list()'' function. Pass the list you want to delete an
|
||||
element from and a 'list' (node) you want to delete.
|
||||
|
||||
<code c>
|
||||
Eina_List *app_list = NULL;
|
||||
Eina_List *to_remove = NULL;
|
||||
|
||||
// Adding some elements to the list (using stringshares)
|
||||
app_list = eina_list_append(app_list, eina_stringshare_add("enna"));
|
||||
app_list = eina_list_append(app_list, eina_stringshare_add("ebird"));
|
||||
app_list = eina_list_append(app_list, eina_stringshare_add("calaos"));
|
||||
app_list = eina_list_append(app_list, eina_stringshare_add("rage"));
|
||||
app_list = eina_list_append(app_list, eina_stringshare_add("terminology"));
|
||||
app_list = eina_list_append(app_list, eina_stringshare_add("enlightenment"));
|
||||
app_list = eina_list_append(app_list, eina_stringshare_add("eyelight"));
|
||||
app_list = eina_list_append(app_list, eina_stringshare_add("ephoto"));
|
||||
|
||||
// Finding the "list" to remove
|
||||
to_remove = eina_list_data_find_list(list, eina_string_share_add("enlightenment"));
|
||||
|
||||
list = eina_list_remove_list(list, to_remove);
|
||||
</code>
|
||||
|
||||
=== To move elements in a list ===
|
||||
|
||||
You can use various function, such as ''eina_list_promote_list()'' that
|
||||
promotes an element to the top of the list or ''eina_list_demote_list()'' that
|
||||
puts the specified element at the end of the list. Remember that everything is
|
||||
a list so the second parameter represents the "list" (node) you want to move.
|
||||
Use the functions just like the ''eina_list_remove_list()'' function.
|
||||
|
||||
<code c>
|
||||
list = eina_list_promote_list(list, eina_list_data_find_list(list, "ivi"));
|
||||
</code>
|
||||
|
||||
=== To reverse all the elements of a list ===
|
||||
|
||||
Use the ''eina_list_reverse()'' function. To obtain a reversed copy of the
|
||||
list while keeping the initial list unchanged, use the
|
||||
''eina_list_reverse_clone()'' function.
|
||||
|
||||
<code c>
|
||||
Eina_List *rev_copy;
|
||||
|
||||
app_list = eina_list_reverse(app_list);
|
||||
rev_copy = eina_list_reverse_clone(app_list);
|
||||
</code>
|
||||
|
||||
=== To sort a list ===
|
||||
|
||||
Use the ''eina_list_sort()'' function. This function takes a list which needs
|
||||
to be sorted, the maximum number of elements to be sorted, and a callback
|
||||
function that compares data. To sort all list elements, set the maximum number
|
||||
of elements to 0.
|
||||
|
||||
<code c>
|
||||
int sort_cb(const void *d1, const void *d2)
|
||||
{
|
||||
const char *txt = d1;
|
||||
const char *txt2 = d2;
|
||||
if(!txt) return(1);
|
||||
if(!txt2) return(-1);
|
||||
|
||||
return(strcmp(txt, txt2));
|
||||
}
|
||||
|
||||
extern Eina_List *list;
|
||||
list = eina_list_sort(list, 0, sort_cb);
|
||||
</code>
|
||||
|
||||
=== To merge 2 list into 1 ===
|
||||
|
||||
Use the ''eina_list_merge()'' function. The ''eina_list_sorted_merge()''
|
||||
function merges 2 sorted lists according to the ordering function that you
|
||||
pass as the last argument.
|
||||
|
||||
<code c>
|
||||
int sort_cb(void *d1, void *d2)
|
||||
{
|
||||
const char *txt = NULL;
|
||||
const char *txt2 = NULL;
|
||||
if(!d1) return(1);
|
||||
if(!d2) return(-1);
|
||||
|
||||
return(strcmp((const char*)d1, (const char*)d2));
|
||||
}
|
||||
|
||||
Eina_List *sorted1;
|
||||
Eina_List *sorted2;
|
||||
Eina_List *newlist;
|
||||
|
||||
// Insert some values and sort your lists
|
||||
|
||||
// Simply merge 2 lists without any process
|
||||
newlist = eina_list_merge(sorted1, sorted2);
|
||||
|
||||
newlist = eina_list_sorted_merge(sorted1, sorted2, sort_cb);
|
||||
</code>
|
||||
|
||||
=== To split a list ===
|
||||
|
||||
Use the eina_list_split_list() function:
|
||||
* The first parameter is the list to split.
|
||||
* The second parameter is the "list" (element) after which the list is split.
|
||||
* The last parameter is the head of the second list.
|
||||
|
||||
<code c>
|
||||
// Original list (left list)
|
||||
Eina_List *list = NULL;
|
||||
|
||||
// New list (right list)
|
||||
Eina_List *other_list = NULL;
|
||||
|
||||
// Eina_List (element)
|
||||
Eina_List *l;
|
||||
|
||||
list = eina_list_append(list, "super tux");
|
||||
list = eina_list_append(list, "frozen bubble");
|
||||
list = eina_list_append(list, "lincity-ng");
|
||||
|
||||
// Sorting the list (just for fun)
|
||||
list = eina_list_sort(list, 0, cmp_func);
|
||||
|
||||
// Looking for the 'split' element
|
||||
l = eina_list_search_sorted_list(list, cmp_func, "frozen bubble");
|
||||
|
||||
// Splitting the list
|
||||
list = eina_list_split_list(list, l, &other_list);
|
||||
</code>
|
||||
|
||||
=== To copy a list ===
|
||||
|
||||
Use the ''eina_list_clone()'' function. The function copies all the elements
|
||||
in the list in the exact same order.
|
||||
|
||||
<code c>
|
||||
Eina_List *app_list_copy;
|
||||
|
||||
app_list_copy = eina_list_clone(app_list);
|
||||
</code>
|
||||
|
||||
==== Accessing List Data ====
|
||||
|
||||
=== To find some data on your list ===
|
||||
|
||||
Use the ''eina_list_data_find()'' function. Pass the list containing your data
|
||||
as the first parameter and the data you are looking for as the last one. The
|
||||
function returns the found member data pointer if found, ''NULL'' otherwise.
|
||||
|
||||
The ''eina_list_data_find()'' function searches the list from the beginning to
|
||||
the end for the first member for which the data pointer is data. If it is
|
||||
found, the data is returned, otherwise ''NULL'' is returned. The function only
|
||||
compares pointers, which is why using ''Eina_Stringshare'' is very useful with
|
||||
lists, because it always returns the same pointer for the same string.
|
||||
|
||||
<code c>
|
||||
Eina_List *app_list = NULL;
|
||||
const char *res_str;
|
||||
|
||||
// Adding some elements to the list (using stringshares)
|
||||
app_list = eina_list_append(app_list, eina_stringshare_add("enna"));
|
||||
app_list = eina_list_append(app_list, eina_stringshare_add("ebird"));
|
||||
app_list = eina_list_append(app_list, eina_stringshare_add("calaos"));
|
||||
app_list = eina_list_append(app_list, eina_stringshare_add("rage"));
|
||||
app_list = eina_list_append(app_list, eina_stringshare_add("terminology"));
|
||||
app_list = eina_list_append(app_list, eina_stringshare_add("enlightenment"));
|
||||
app_list = eina_list_append(app_list, eina_stringshare_add("eyelight"));
|
||||
app_list = eina_list_append(app_list, eina_stringshare_add("ephoto"));
|
||||
|
||||
// Finding the data
|
||||
res_str = eina_list_data_find(list, eina_string_share_add("enlightenment"));
|
||||
if (res_str == eina_stringshare_add("enlightenment"))
|
||||
printf("Data is present");
|
||||
else
|
||||
printf("Data not present");
|
||||
</code>
|
||||
|
||||
The above example returns "Data is present".
|
||||
|
||||
The ''eina_list_data_find_list()'' function does the same thing as
|
||||
''eina_list_data_find()'', but returns an ''Eina_List''. For an example, see
|
||||
the ''eina_list_remove_list()'' function.
|
||||
|
||||
You can access the data or a "list" (node) of an ''Eina_List'' using the
|
||||
''eina_list_nth()'' and ''eina_list_nth_list()'' functions. The first one returns a
|
||||
pointer to the data of the "n" element and the second a pointer to the "list".
|
||||
To access the data of the 3rd element of an ''Eina_List'':
|
||||
|
||||
<code c>
|
||||
const char *res;
|
||||
Eina_List *res_lst;
|
||||
|
||||
res = eina_list_nth(app_list, 2);
|
||||
res_lst = eina_list_nth_list(app_list, 2);
|
||||
</code>
|
||||
|
||||
The ''res'' variable contains the pointer to the string "calaos". The
|
||||
''res_lst'' variable is the list containing "calaos".
|
||||
|
||||
=== To search for data in a list ===
|
||||
|
||||
Select your function based on whether the list is sorted or unsorted.
|
||||
* To search in an unsorted list, use the ''eina_list_search_unsorted()'' function:
|
||||
* The first parameter is the list.
|
||||
* The second parameter is a callback function for comparison.
|
||||
* The last parameter is the data you are looking for.
|
||||
|
||||
The ''eina_list_search_unsorted_list()'' function does the same but returns an
|
||||
"Eina_List".
|
||||
|
||||
The following example shows 2 searches using both the
|
||||
''eina_list_search_unsorted()'' and ''eina_list_search_unsorted_list()''
|
||||
functions:
|
||||
|
||||
<code c>
|
||||
int search_list()
|
||||
{
|
||||
// Declaring the list
|
||||
Eina_List *list = NULL;
|
||||
Eina_List *l;
|
||||
// Little trick to use strcmp as Eina_Compare_Cb
|
||||
Eina_Compare_Cb cmp_func = (Eina_Compare_Cb)strcmp;
|
||||
|
||||
void *data;
|
||||
int cmp_result;
|
||||
|
||||
list = eina_list_append(list, "debian");
|
||||
list = eina_list_append(list, "archlinux");
|
||||
list = eina_list_append(list, "centos");
|
||||
|
||||
data = eina_list_search_unsorted(list, cmp_func, "archlinux");
|
||||
l = eina_list_search_unsorted_list(list, cmp_func, "archlinux");
|
||||
if (l->data != data)
|
||||
{
|
||||
eina_list_free(list);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
eina_list_free(list);
|
||||
|
||||
return 0;
|
||||
}
|
||||
</code>
|
||||
* To search in sorted lists, use the ''eina_list_search_sorted_list()'' and ''eina_list_search_sorted()'' functions. They work similarly as the ''eina_list_search_unsorted()'' function.
|
||||
|
||||
=== To get data from a list element ===
|
||||
|
||||
Use the ''eina_list_data_get()'' function. The function returns the data
|
||||
contained in the given list.
|
||||
|
||||
The following example uses the ''eina_list_next()'' function to move through
|
||||
the list in a statement.
|
||||
|
||||
<code c>
|
||||
int list_data_set()
|
||||
{
|
||||
// Declaring the list
|
||||
Eina_List *list = NULL;
|
||||
// Eina_List in which to place the elements or lists
|
||||
Eina_List *l;
|
||||
|
||||
void *list_data;
|
||||
|
||||
list = eina_list_append(list, eina_stringshare_add("Bertrand"));
|
||||
list = eina_list_append(list, eina_stringshare_add("Cedric"));
|
||||
list = eina_list_append(list, eina_stringshare_add("Nicolas"));
|
||||
list = eina_list_append(list, eina_stringshare_add("Vincent"));
|
||||
list = eina_list_append(list, eina_stringshare_add("Raoul"));
|
||||
list = eina_list_append(list, eina_stringshare_add("Fabien"));
|
||||
list = eina_list_append(list, eina_stringshare_add("Philippe"));
|
||||
list = eina_list_append(list, eina_stringshare_add("billiob"));
|
||||
|
||||
for(l = list; l; l = eina_list_next(l))
|
||||
// Printing the data returned by eina_list_data_get
|
||||
printf("%s\n", (char*)eina_list_data_get(l));
|
||||
|
||||
EINA_LIST_FREE(list, list_data)
|
||||
eina_stringshare_del(list_data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
</code>
|
||||
|
||||
=== To move in a list ===
|
||||
|
||||
Use the ''eina_list_last()'', ''eina_list_next()'', or ''eina_list_prev()''
|
||||
functions to move to the last, next, or previous element in the list.
|
||||
|
||||
The following example scrolls backwards starting from the end of the list:
|
||||
|
||||
<code c>
|
||||
|
||||
for(l = eina_list_last(list); l; l = eina_list_prev(l))
|
||||
printf("%s\n", (char*)eina_list_data_get(l));
|
||||
</code>
|
||||
|
||||
=== To count the list elements ===
|
||||
|
||||
Use the ''eina_list_count()'' function. The function returns the number of
|
||||
items in a list.
|
||||
|
||||
<code c>
|
||||
printf("List size: %d\n", eina_list_count(list));
|
||||
</code>
|
||||
|
||||
=== To iterate through an array ===
|
||||
|
||||
You can use various iterators:
|
||||
|
||||
* To iterate over a list from the beginning to the end, use the ''EINA_LIST_FOREACH'' macro:
|
||||
* The first parameter is the list to iterate.
|
||||
* The second parameter is an ''Eina_List *'' to hold the current "List" (node).
|
||||
* The last parameter receives the current data during the run.
|
||||
|
||||
The following example prints the data of each "List" (node) of the list:
|
||||
|
||||
<code c>
|
||||
Eina_List *list = NULL;
|
||||
Eina_List *l;
|
||||
void *list_data;
|
||||
|
||||
list = eina_list_append(list, "ls");
|
||||
list = eina_list_append(list, "top");
|
||||
list = eina_list_append(list, "rmdir");
|
||||
list = eina_list_append(list, "uname");
|
||||
|
||||
EINA_LIST_FOREACH(list, l, list_data)
|
||||
printf("%s\n", (char*)list_data);
|
||||
|
||||
eina_list_free(list);
|
||||
</code>
|
||||
|
||||
* To iterate from the last element to the first, use the ''EINA_LIST_REVERSE_FOREACH'' macro. It works similarly as ''EINA_LIST_FOREACH()''.
|
||||
* To iterate over a list from the beginning to the end, you can also use the
|
||||
''EINA_LIST_FOREACH_SAFE'' macro. It is called safe, because it stores the next "List" (node), so you can safely remove the current "List" (node) and continue the iteration.
|
||||
|
||||
<code c>
|
||||
Eina_List *list;
|
||||
Eina_List *l;
|
||||
Eina_List *l_next;
|
||||
char *data;
|
||||
|
||||
list = eina_list_append(list, "enlightenment");
|
||||
list = eina_list_append(list, "enlightenment");
|
||||
list = eina_list_append(list, "enlightenment");
|
||||
list = eina_list_append(list, "enlightenment");
|
||||
|
||||
// Using EINA_LIST_FOREACH_SAFE to free the elements that match "enlightenment"
|
||||
|
||||
EINA_LIST_FOREACH_SAFE(list, l, l_next, data)
|
||||
if (strcmp(data, "enlightenment") == 0)
|
||||
{
|
||||
free(data);
|
||||
list = eina_list_remove_list(list, l);
|
||||
}
|
||||
</code>
|
||||
|
||||
* To remove each list element while having access to the node's data, use the ''EINA_LIST_FREE'' macro. Pass the list and a pointer to hold the current data.
|
||||
|
||||
<code c>
|
||||
Eina_List *list;
|
||||
char *data;
|
||||
|
||||
// List is filled
|
||||
|
||||
EINA_LIST_FREE(list, data)
|
||||
free(data);
|
||||
</code>
|
||||
|
||||
==== Using an Inline List ====
|
||||
|
||||
The ''Eina_Inlist'' is a special data type drawn to store nodes pointers in
|
||||
the same memory as data. This way the memory is less fragmented, but
|
||||
operations, such as sort and count, are slower. The ''Eina_Inlist'' has its
|
||||
own purpose, but if you do not understand what the purpose is, use the regular
|
||||
''Eina_List'' instead.
|
||||
|
||||
The ''Eina_Inlist'' nodes can be part of a regular ''Eina_List'', simply added
|
||||
with the ''eina_list_append()'' or ''eina_list_prepend()'' functions.
|
||||
|
||||
To use the inline list:
|
||||
|
||||
__**1**__. Define the structure of the data before creating the inline list:
|
||||
|
||||
<code c>
|
||||
struct my_struct
|
||||
{
|
||||
EINA_INLIST;
|
||||
int a, b;
|
||||
};
|
||||
</code>
|
||||
|
||||
The structure is composed of 2 integers, the real data, and the
|
||||
''EINA_INLIST'' type which is composed of 3 pointers defining the inline list
|
||||
structure:
|
||||
* ''Eina_Inlist * next'': next node
|
||||
* ''Eina_Inlist * prev'': previous node
|
||||
* ''Eina_Inlist * last'': last node
|
||||
|
||||
__**2**__. To create the inlist nodes, allocate the memory and use the
|
||||
''eina_inlist_append()'' function:
|
||||
|
||||
* The first parameter is the existing list head or NULL to create a new list. \\ \\ The following example passes NULL to create a new list.
|
||||
* The second parameter is the new list node, and it must not be NULL. \\ \\ You must use the ''EINA_INLIST_GET()'' macro to get the inlist object of the datastruct.
|
||||
|
||||
<code c>
|
||||
struct my_struct *d, *cur;
|
||||
Eina_Inlist *list, *itr, *tmp;
|
||||
|
||||
d = malloc(sizeof(*d));
|
||||
d->a = 1;
|
||||
d->b = 10;
|
||||
|
||||
list = eina_inlist_append(NULL, EINA_INLIST_GET(d));
|
||||
</code>
|
||||
|
||||
Repeat this operation for every new node:
|
||||
|
||||
<code c>
|
||||
d = malloc(sizeof(*d));
|
||||
d->a = 2;
|
||||
d->b = 20;
|
||||
list = eina_inlist_append(list, EINA_INLIST_GET(d));
|
||||
</code>
|
||||
|
||||
__**3**__. To add data to the inline list:
|
||||
|
||||
* Put data at the end of the inline list with the ''eina_inlist_prepend()'' function:
|
||||
|
||||
<code c>
|
||||
d = malloc(sizeof(*d));
|
||||
d->a = 3;
|
||||
d->b = 30;
|
||||
list = eina_inlist_prepend(list, EINA_INLIST_GET(d));
|
||||
</code>
|
||||
|
||||
* Add a node before or after a given node with the ''eina_inlist_prepend_relative()'' and ''eina_inlist_append_relative()'' functions. \\ \\ In both functions, the first parameter is the target list, the second is the element you want to add, and the last is the reference element to place data after (in this case). Similarly as in a regular ''Eina_List'', everything is a list, so the last parameter is an ''Eina_Inlist'' typed variable.
|
||||
|
||||
<code c>
|
||||
d = malloc(sizeof(*d));
|
||||
d->a = 4;
|
||||
d->b = 40;
|
||||
list = eina_inlist_append_relative(list, EINA_INLIST_GET(d), list);
|
||||
</code>
|
||||
|
||||
__**4**__. To sort and iterate an inline list, to find and move list elements, and to perform other inline list operations, see the Inline List API.
|
||||
|
||||
__**5**__. When the inline list is no longer needed, destroy it by looping over the list to free each ''EINA_INLIST'' structure and the data using allocated memory. Use the ''eina_inlist_remove()'' function on each node.
|
||||
|
||||
In the following example, the ''EINA_INLIST_CONTAINER_GET()'' macro returns
|
||||
the container object of an inlist (the ''EINA_INLIST'' of ''my_struct''), and
|
||||
the list element is removed and the allocated memory of the container "object"
|
||||
is freed.
|
||||
|
||||
<code c>
|
||||
while (list)
|
||||
{
|
||||
struct my_struct *aux = EINA_INLIST_CONTAINER_GET(list, struct my_struct);
|
||||
|
||||
// Remove the current list element
|
||||
list = eina_inlist_remove(list, list);
|
||||
free(aux);
|
||||
}
|
||||
</code>
|
||||
|
||||
------
|
||||
{{page>index}}
|
|
@ -0,0 +1,22 @@
|
|||
{{page>index}}
|
||||
--------
|
||||
===== Memory Pool =====
|
||||
|
||||
The ''Eina_Mempool'' tool provides memory pool functionality. With a memory
|
||||
pool, you can preallocate fixed-size memory spaces for easy memory management.
|
||||
|
||||
=== Related Info ===
|
||||
|
||||
* [[https://build.enlightenment.org/job/nightly_efl_gcc_x86_64/lastSuccessfulBuild/artifact/doc/html/group__Eina__Memory__Pool__Group.html|Memory Pool API]]
|
||||
|
||||
The following mempools are available:
|
||||
|
||||
* ''buddy''
|
||||
* ''chained_pool''
|
||||
* ''ememoa_fixed and ememoa_unknown''
|
||||
* ''fixed_bitmap''
|
||||
* ''pass_through''
|
||||
* ''one_big''
|
||||
|
||||
--------
|
||||
{{page>index}}
|
|
@ -0,0 +1,83 @@
|
|||
{{page>index}}
|
||||
--------
|
||||
===== Safety Checks =====
|
||||
|
||||
Eina safety checks are a set of macros that can be used to check for
|
||||
parameters or values that must never occur. The concept is similar to the
|
||||
''assert()'' function, but safety checks log the parameter or value and return
|
||||
instead of aborting your program.
|
||||
|
||||
=== Related Info ===
|
||||
|
||||
* [[https://build.enlightenment.org/job/nightly_efl_gcc_x86_64/lastSuccessfulBuild/artifact/doc/html/group__Eina__Safety__Checks__Group.html|Safety Checks API]]
|
||||
|
||||
The following safety checks are available:
|
||||
|
||||
* ''EINA_SAFETY_ON_NULL_RETURN(exp)''
|
||||
* ''EINA_SAFETY_ON_NULL_RETURN_VAL(exp, val)''
|
||||
* ''EINA_SAFETY_ON_NULL_GOTO(exp, label)''
|
||||
* ''EINA_SAFETY_ON_TRUE_RETURN(exp)''
|
||||
* ''EINA_SAFETY_ON_TRUE_RETURN_VAL(exp, val)''
|
||||
* ''EINA_SAFETY_ON_TRUE_GOTO(exp, label)''
|
||||
* ''EINA_SAFETY_ON_FALSE_RETURN(exp)''
|
||||
* ''EINA_SAFETY_ON_FALSE_RETURN_VAL(exp, val)''
|
||||
* ''EINA_SAFETY_ON_FALSE_GOTO(exp, label)''
|
||||
* ''EINA_ARG_NONNULL(...)''
|
||||
|
||||
To return if a variable is ''NULL'', use the ''EINA_SAFETY_ON_NULL_RETURN()''
|
||||
function. This macro calls return if the given parameter is ''NULL''.
|
||||
|
||||
<code c>
|
||||
Eina_Bool myfunction(char *param)
|
||||
{
|
||||
// If my param is NULL, EINA_SAFETY_ON_NULL_RETURN calls "return"
|
||||
EINA_SAFETY_ON_NULL_RETURN(param);
|
||||
|
||||
printf("My pram is : %s\n", param);
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
</code>
|
||||
|
||||
To return a specific value, use the ''EINA_SAFETY_ON_NULL_RETURN_VAL()''
|
||||
function instead of the ''EINA_SAFETY_ON_NULL_RETURN()'' function. This macro
|
||||
returns the given value.
|
||||
|
||||
<code c>
|
||||
Eina_Bool void myfunction(char *param)
|
||||
{
|
||||
// If the parameter is NULL, return EINA_FALSE;
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(param, EINA_FALSE);
|
||||
printf("My pram is : %s\n", param);
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
</code>
|
||||
|
||||
To call another function if a parameter is ''NULL'', use the
|
||||
''EINA_SAFETY_ON_NULL_GOTO()'' function. This macro works similarly to the
|
||||
''EINA_SAFETY_ON_NULL_RETURN()'' function except that it calls goto with the
|
||||
given function instead of return.
|
||||
|
||||
<code c>
|
||||
static void isnullcb()
|
||||
{
|
||||
printf("The parameter is NULL\n");
|
||||
}
|
||||
Eina_Bool void myfunction(char *param)
|
||||
{
|
||||
// If the parameter is NULL we return EINA_FALSE;
|
||||
EINA_SAFETY_ON_NULL_GOTO(param, isnullcb);
|
||||
printf("My pram is : %s\n", param);
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
</code>
|
||||
|
||||
Eina also provides macros that check whether a given value is ''TRUE'' or
|
||||
''FALSE''. For example, to call return if a given value is ''TRUE'', use the
|
||||
''EINA_SAFETY_ON_TRUE_RETURN()'' function. To call "goto" in a given function
|
||||
if a given value is ''TRUE'', use the ''EINA_SAFETY_ON_NULL_GOTO()'' function.
|
||||
|
||||
--------
|
||||
{{page>index}}
|
|
@ -0,0 +1,115 @@
|
|||
{{page>index}}
|
||||
-------
|
||||
===== String =====
|
||||
|
||||
When creating applications, you always need to manipulate strings. Eina
|
||||
provides a very useful API for manipulating C strings:
|
||||
|
||||
=== Table of Contents ===
|
||||
|
||||
* [[#The_most_common_string_manipulation_is_the_"split"|The most common string manipulation is the "split"]]
|
||||
* [[#To_change_the_string_to_lowercase_or_uppercase|To change the string to lowercase or uppercase]]
|
||||
* [[#If_you_need_to_"join"_2_strings_of_known_length|If you need to "join" 2 strings of known length]]
|
||||
* [[#To_check_whether_a_string_starts_or_ends_with_another_string|To check whether a string starts or ends with another string]]
|
||||
|
||||
=== Related Info ===
|
||||
|
||||
* [[https://build.enlightenment.org/job/nightly_efl_gcc_x86_64/lastSuccessfulBuild/artifact/doc/html/group__Eina__String__Group.html|String Tools API]]
|
||||
* [[https://build.enlightenment.org/job/nightly_efl_gcc_x86_64/lastSuccessfulBuild/artifact/doc/html/tutorial_eina_string.html|Example]]
|
||||
|
||||
=== The most common string manipulation is the "split" ===
|
||||
|
||||
If you have a string, such as
|
||||
"Rasterman:Bluebugs:Tasn:Illogict:billiob:Puppet_Master", and you want to
|
||||
print it in an easily readable format, you can use the ''eina_str_split()''
|
||||
function to split the string using a delimiter. The first parameter is the
|
||||
string to split, the second determines where to split the string, and the
|
||||
final parameter is the maximum number of strings to split the string into. If
|
||||
you set a number less than 1, it splits the string as many times as possible.
|
||||
|
||||
The function returns a newly-allocated ''NULL''-terminated array of strings,
|
||||
or NULL, if it fails to allocate the array. Always remember to free the memory
|
||||
allocated by the ''eina_str_split()'' function.
|
||||
|
||||
<code c>
|
||||
char *nicks = "Rasterman:Bluebugs:Tasn:Illogict:billiob:Puppet_Master";
|
||||
char **result_arr;
|
||||
int i;
|
||||
|
||||
// Splitting the string with ':' delimiter
|
||||
result_arr = eina_str_split(names, ":", 0);
|
||||
// Printing the result
|
||||
for (i = 0; result_arr[i]; i++)
|
||||
printf("Nick : %s\n", result_arr[i]);
|
||||
// Remember to free memory
|
||||
free(arr[0]);
|
||||
free(arr);
|
||||
</code>
|
||||
|
||||
=== To change the string to lowercase or uppercase ===
|
||||
|
||||
Use the ''eina_str_tolower()'' and ''eina_str_toupper()'' functions. They
|
||||
change the case for all characters of the given string. These functions modify
|
||||
the original strings.
|
||||
|
||||
<code c>
|
||||
char *str;
|
||||
// Initialize the string
|
||||
str = malloc(sizeof(char) * 4);
|
||||
strcpy(str, "bsd");
|
||||
// Change the string to uppercase
|
||||
eina_str_toupper((char **)&str);
|
||||
printf("%s\n", str);
|
||||
// Change the string to lowercase
|
||||
eina_str_tolower(&str);
|
||||
printf("%s\n", str);
|
||||
// Free the allocated memory
|
||||
free(str);
|
||||
</code>
|
||||
|
||||
=== If you need to "join" 2 strings of known length ===
|
||||
|
||||
Use the ''eina_str_join()'' function. The fist parameter is the buffer to
|
||||
store the result, the second is the size of the buffer, the third is the
|
||||
separator between the 2 strings, and the 2 final parameters are the stings to
|
||||
be joined.
|
||||
|
||||
<code c>
|
||||
char *part1 = "Elementary powered by";
|
||||
char *part2 = "Enlightenment Foundation Libraries";
|
||||
char *res;
|
||||
size_t size;
|
||||
// Calculate the string size + 1 for the delimiter
|
||||
size = strlen(part1) + strlen(part2) + 1
|
||||
// Allocate memory for the result
|
||||
res = malloc(sizeof(char) * size);
|
||||
// Join the strings
|
||||
eina_str_join(res, size, ' ', part1, part2);
|
||||
printf("%s\n", res);
|
||||
// Free the allocated memory
|
||||
free(res):
|
||||
</code>
|
||||
|
||||
=== To check whether a string starts or ends with another string ===
|
||||
use the
|
||||
''eina_str_has_prefix()'' or ''eina_str_has_suffix()'' function. You can also
|
||||
check whether a string has a particular extension with the
|
||||
''eina_str_has_extension()'' function.
|
||||
|
||||
These functions return ''EINA_TRUE'' if the given string contains the
|
||||
specified prefix, suffix, or extension, and ''EINA_FALSE'' if it does not.
|
||||
|
||||
<code c>
|
||||
char *names = "Carsten;Cedric;Tom;Chidambar;Boris;Philippe"
|
||||
if (eina_str_has_prefix(names, "Carsten"))
|
||||
printf("String starts with 'Carsten'")
|
||||
if (eina_str_has_suffix(names, "Philippe"))
|
||||
printf("String ends with 'Philippe'")
|
||||
if (eina_str_has_extension(names, "philippe"))
|
||||
printf("String has extension 'philippe'")
|
||||
else
|
||||
printf("String does not have extension "philippe)
|
||||
</code>
|
||||
|
||||
-------
|
||||
{{page>index}}
|
|
@ -0,0 +1,153 @@
|
|||
{{page>index}}
|
||||
-------
|
||||
===== Strings =====
|
||||
|
||||
=== Table of Contents ===
|
||||
|
||||
* [[#Stringshare]]
|
||||
* [[String_Buffer|String Buffer]]
|
||||
|
||||
=== Related Info ===
|
||||
|
||||
* [[https://build.enlightenment.org/job/nightly_efl_gcc_x86_64/lastSuccessfulBuild/artifact/doc/html/group__Eina__Stringshare__Group.html|Stringshare API]]
|
||||
* [[https://build.enlightenment.org/job/nightly_efl_gcc_x86_64/lastSuccessfulBuild/artifact/doc/html/group__Eina__String__Buffer__Group.html|String Buffer API]]
|
||||
|
||||
|[[https://build.enlightenment.org/job/nightly_efl_gcc_x86_64/lastSuccessfulBuild/artifact/doc/html/eina_str_01_8c-example.html|String Example]]|[[https://build.enlightenment.org/job/nightly_efl_gcc_x86_64/lastSuccessfulBuild/artifact/doc/html/eina_strbuf_01_8c-example.html|String Buffer Example]]|[[https://build.enlightenment.org/job/nightly_efl_gcc_x86_64/lastSuccessfulBuild/artifact/doc/html/eina_stringshare_01_8c-example.html|Stringshare Example]]|
|
||||
|
||||
==== Stringshare ====
|
||||
|
||||
The ''Eina_Stringshare'' data type functions allow you to store a single copy
|
||||
of a string and use it in multiple places throughout your program. This way
|
||||
you can save a lot of strings with less memory. It improves string creation
|
||||
and destruction speed, reduces memory use, and decreases memory fragmentation.
|
||||
|
||||
With this data type you can reduce the number of duplicated strings kept in
|
||||
memory. It is common for the same strings to be dynamically allocated
|
||||
repeatedly between applications and libraries, especially in circumstances
|
||||
where you can have multiple copies of a structure that allocates the string.
|
||||
Rather than duplicating and freeing these strings, request a read-only pointer
|
||||
to an existing string and only incur the overhead of a hash lookup. This can
|
||||
sound like micro-optimizing, but profiling has shown that this can have a
|
||||
significant impact as the number of copies grows.
|
||||
|
||||
=== To manage stringshares ===
|
||||
|
||||
__**1**__. To create a stringshare, declare a string variable and call the ''eina_stringshare_add()'' function:
|
||||
|
||||
<code c>
|
||||
|
||||
const char *mystr;
|
||||
const char *prologue = "Enlightenment is not just a window manager for Linux/X11 and others"
|
||||
|
||||
mystr = eina_stringshare_add(prologue);
|
||||
</code>
|
||||
|
||||
__**2**__. To retrieve or modify the string data:
|
||||
* Retrieve a string for use in a program from a format string using the ''eina_stringshare_printf()'' function. If you have a "format" string to pass to a function like ''printf'', you can store it as a stringshare as well. \\ The following example produces "1 desktop manager to rule them all".
|
||||
|
||||
<code c>
|
||||
const char *myfmtstr = "%d desktop manager to rule them all";
|
||||
const char *str;
|
||||
|
||||
str = eina_stringshare_printf(myfmtstr, 1);
|
||||
|
||||
print(str)
|
||||
</code>
|
||||
* Replace the value of a stringshare with the ''eina_stringshare_replace()'' function. Pass the pointer address and the new value to the function.
|
||||
<code c>
|
||||
eina_stringshare_replace(&str,"One desktop manager to rule them all");
|
||||
</code>
|
||||
* Retrieve the length of the stringshare value with the ''eina_stringshare_strlen()'' function.
|
||||
<code c>
|
||||
printf("length: %d\n", eina_stringshare_strlen(str));
|
||||
</code>
|
||||
|
||||
__**3**__. When the string is no longer needed, delete it using the
|
||||
''eina_stringshare_del()'' function:
|
||||
|
||||
<code c>
|
||||
eina_stringshare_del(mystr);
|
||||
</code>
|
||||
|
||||
==== String Buffer ====
|
||||
|
||||
The string buffer data type is designed to be a mutable string, allowing you
|
||||
to append, prepend or insert a string to a buffer. It allows easy handling of
|
||||
buffers in your applications.
|
||||
|
||||
=== To manage string buffer ===
|
||||
|
||||
__**1**__. Initialize the ''Eina_Strbuf'' instance and create the buffer:
|
||||
|
||||
<code c>
|
||||
Eina_Strbuf *buf;
|
||||
mybuffer = eina_strbuf_new();
|
||||
</code>
|
||||
|
||||
__**2**__. Manage the buffer content:
|
||||
* To append characters to the buffer:
|
||||
|
||||
//For basic strings, use the ''eina_strbuf_append()'' function//:
|
||||
<code c>
|
||||
eina_strbuf_append(mybuffer, "This is my string.");
|
||||
</code>
|
||||
//To append 1 character to your buffer, use the ''eina_strbuf_append_char()''
|
||||
function. You can also append a sized string to the buffer using the
|
||||
''eina_strbuf_append_length()'' function//:
|
||||
<code c>
|
||||
eina_strbuf_append_length(mybuffer, "Buffe", 5);
|
||||
eina_strbuf_append_char(mybuffer, 'r');
|
||||
</code>
|
||||
//To handle "printf" format strings, use the
|
||||
''eina_strbuf_append_printf()'' function to add formatted strings to the
|
||||
buffer//:
|
||||
|
||||
<code c>
|
||||
eina_strbuf_append_printf(buf, "%s%c", "buffe", 'r');
|
||||
</code>
|
||||
|
||||
* To remove characters from one position to another, use the ''eina_strbuf_remove()'' function. The first parameter is the buffer, the second is the start position of the characters you want to delete, and the last the end position. \\ This example removes the first 19 characters of the buffer:
|
||||
|
||||
<code c>
|
||||
eina_strbuf_remove(buf, 0, 18);
|
||||
</code>
|
||||
|
||||
* To replace characters:
|
||||
* ''eina_strbuf_replace()'' replaces a specific occurrence of a given string in the buffer with another string.
|
||||
* ''eina_strbuf_replace_all()'' replaces all occurrences of a given string in the buffer with another string.
|
||||
|
||||
<code c>
|
||||
eina_strbuf_append(mybuffer, "buffer buffer buffer");
|
||||
|
||||
// Replacing one occurrence of "buffer" by "B-U-F-F-E-R"
|
||||
eina_strbuf_replace(mybuffer, "buffer", "B-U-F-F-E-R", 1);
|
||||
|
||||
// Replacing all the occurrences of "buffer" by "B-U-F-F-E-R"
|
||||
eina_strbuf_replace_all(mybuffer, "buffer", "B-U-F-F-E-R");
|
||||
|
||||
// Replacing all the occurrences of "B-U-F-F-E-R" by "Buffer"
|
||||
eina_strbuf_replace_all(mybuffer, "B-U-F-F-E-R", "Buffer");
|
||||
</code>
|
||||
|
||||
* To insert a string at the specified position, use the ''eina_strbuf_insert()'' function. Use the ''eina_strbuf_insert_printf()'' function with formatted strings.
|
||||
|
||||
<code c>
|
||||
eina_strbuf_insert(mybuffer, "More buffer", 10);
|
||||
|
||||
// Using eina_strbuf_length_get to get the buffer length
|
||||
eina_strbuf_insert_printf(buf, " %s: %d", 6, "length", eina_strbuf_length_get(buf));
|
||||
</code>
|
||||
|
||||
* To get the complete length of the string and the buffer, use the ''eina_strbuf_string_get()'' and ''eina_strbuf_length_get()'' functions:
|
||||
|
||||
<code c>
|
||||
printf("%s : %d\n", eina_strbuf_string_get(mybuffer), eina_strbuf_length_get(buf));
|
||||
</code>
|
||||
|
||||
__**3**__. When no longer needed, free the buffer with the ''eina_strbuf_free()'' function. You can also free the content of ''Eina_Strbuf'' without freeing the buffer itself using the ''eina_strbuf_string_free()'' function.
|
||||
|
||||
<code c>
|
||||
eina_strbuf_free(mybuffer);
|
||||
</code>
|
||||
-------
|
||||
{{page>index}}
|
|
@ -0,0 +1,70 @@
|
|||
~~Title: Eina Programming Guide~~
|
||||
{{page>index}}
|
||||
===== Eina Programming Guide =====
|
||||
|
||||
Eina provides data types and useful tools.
|
||||
|
||||
The Eina library implements an API for data types in an efficient way. It also
|
||||
provides some useful tools, such as opening shared libraries, error
|
||||
management, type conversion, time accounting, and memory pool.
|
||||
|
||||
=== Table of Contents ===
|
||||
|
||||
* Data Types
|
||||
* [[/program_guide/eina/iterator_functions|Iterator Functions]]
|
||||
* [[/program_guide/eina/strings|Strings]]
|
||||
* [[/program_guide/eina/arrays|Arrays]]
|
||||
* [[/program_guide/eina/hash_tables|Hash Tables]]
|
||||
* [[/program_guide/eina/lists|Lists]]
|
||||
* [[/program_guide/eina/generic_value|Generic Value]]
|
||||
* Eina Tools
|
||||
* [[/program_guide/eina/string_tools|String]]
|
||||
* [[/program_guide/eina/memory_pool_tools|Memory Pool]]
|
||||
* [[/program_guide/eina/safety_checks_tools|Safety Checks]]
|
||||
|
||||
=== Related Info ===
|
||||
|
||||
* [[https://build.enlightenment.org/job/nightly_efl_gcc_x86_64/lastSuccessfulBuild/artifact/doc/html/eina_main.html|Eina API]]
|
||||
* [[https://build.enlightenment.org/job/nightly_efl_gcc_x86_64/lastSuccessfulBuild/artifact/doc/html/eina_examples.html|Eina Examples]]
|
||||
|
||||
==== Data Types ====
|
||||
|
||||
The Eina library is a central part of the EFL. It implements an API for
|
||||
data types, and allows you to create and manipulate several data types.
|
||||
|
||||
* [[/program_guide/eina/arrays#Creating_and_Destroying_an_Inline_Array|Inline Array]]: standard array of inlined members
|
||||
* [[/program_guide/eina/arrays|Array]]: standard array of ''void*'' data
|
||||
* [[/program_guide/eina/hash_tables|Hash Table]]: standard hash of void* data
|
||||
* [[/program_guide/eina/lists#Using_an_Inline_List|Inline List]]: list with nodes inlined into the user type
|
||||
* Compact List
|
||||
* [[/program_guide/eina/lists|List]]: standard list of ''void*'' data
|
||||
* [[/program_guide/eina/iterator_functions|Iterator Functions]]
|
||||
* Sparse Matrix: sparse matrix of ''void*'' data
|
||||
* Red-Black tree: red-black tree with nodes inlined into the user type
|
||||
* [[/program_guide/eina/strings#String_Buffer|String Buffer]]: mutable string to prepend, insert, or append strings to a buffer
|
||||
* [[/program_guide/eina/strings#Stringshare|Stringshare]]: shares read-only string references
|
||||
* Tiler split: merges and navigates into 2D tiled regions
|
||||
* Trash: container of unused but allocated data
|
||||
* [[/program_guide/eina/generic_value|Generic Value Storage]]: container for generic value storage and access
|
||||
* Data Model API: container for data with a user-defined hierarchy or structure
|
||||
|
||||
==== Eina Tools ====
|
||||
|
||||
Eina provides a number of tools, such as string manipulation, that make
|
||||
your life easier when coding applications.
|
||||
|
||||
* Convert fast: conversion from, for example, strings to integers and double
|
||||
* Counter: measures the number of calls and their time
|
||||
* Error: error identifiers
|
||||
* File: file list and path split
|
||||
* Lazy allocator: lazy allocator
|
||||
* Log: full-featured logging system
|
||||
* Magic: provides runtime type checking
|
||||
* [[/program_guide/eina/memory_pool_tools|Memory Pool]]: abstraction for various memory allocators
|
||||
* Module lists: loads and shares modules using the ''Eina_Module'' standard
|
||||
* Rectangle: rectangle structure and standard manipulation methods
|
||||
* [[/program_guide/eina/safety_checks_tools|Safety Checks]]: extra checks that report unexpected conditions and can be disabled during compilation
|
||||
* [[/program_guide/eina/string_tools|String]]: set of functions that manage C strings
|
||||
|
||||
----
|
||||
{{page>index}}
|
|
@ -7,4 +7,5 @@
|
|||
* [[program_guide/edje_pg|Edje PG]]
|
||||
* [[program_guide/multilingual_pg|Multilingual PG]]
|
||||
* [[program_guide/connectivity_pg|Connectivity PG]]
|
||||
* [[program_guide/eina_pg|Eina PG]]
|
||||
++++
|
||||
|
|
Loading…
Reference in New Issue