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:
Clément Bénier 2015-09-04 13:47:47 +02:00 committed by Cedric BAIL
parent 2d1d2afcc1
commit 830ec3bfa6
13 changed files with 2263 additions and 0 deletions

View File

@ -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 ===

View File

@ -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}}

View File

@ -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}}

View File

@ -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}}

View File

@ -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]] ||
++++

View File

@ -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}}

View File

@ -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}}

View File

@ -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}}

View File

@ -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}}

View File

@ -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}}

View File

@ -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}}

View File

@ -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}}

View File

@ -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]]
++++