dmi_vector_initialize
Synopsis
#include <opendmi/utils/vector.h>
typedef bool dmi_vector_match_fn(uintptr_t entry, uintptr_t key);
typedef struct dmi_vector {
uintptr_t *data;
size_t capacity;
size_t length;
dmi_vector_match_fn *matcher;
dmi_context_t *context;
} dmi_vector_t;
bool dmi_vector_initialize(dmi_vector_t *vector, dmi_context_t *context, dmi_vector_match_fn *matcher);
bool dmi_vector_clear(dmi_vector_t *vector);
bool dmi_vector_push(dmi_vector_t *vector, uintptr_t value);
bool dmi_vector_pop(dmi_vector_t *vector, uintptr_t *value);
bool dmi_vector_get(const dmi_vector_t *vector, size_t index, uintptr_t *value);
bool dmi_vector_find(const dmi_vector_t *vector, uintptr_t key, uintptr_t *value);
bool dmi_vector_exists(const dmi_vector_t *vector, uintptr_t key);
size_t dmi_vector_length(const dmi_vector_t *vector);
bool dmi_vector_is_empty(const dmi_vector_t *vector);
Description
A vector, dmi_vector_t, is an array of uintptr_t values, typically
pointers cast to uintptr_t, which grows as values are appended to it. The
vector is a variable of the caller, usually a member of a structure; it owns
the memory of the array, but not whatever the values point to.
The data member points to the array, length is the number of values the
array holds, and capacity the number it can hold before it is grown. The
members are read, but are changed only by the functions.
The dmi_vector_initialize function sets the vector up empty, with no memory
allocated, with context as the context its errors are raised against, and
with matcher as the function dmi_vector_find and dmi_vector_exists
compare the values with keys by. The dmi_vector_clear function removes all
values and frees the array, and leaves the vector empty, as
dmi_vector_initialize does, with the context and the matcher kept. A vector is cleared once it
is no longer needed.
The dmi_vector_push function appends value to the vector, growing the
array by 16 values when it is full. The dmi_vector_pop function removes the
last value and stores it in the variable value points to; the array is
freed once the last value is removed.
The dmi_vector_get function stores the value at index, counted from zero,
in the variable value points to.
The dmi_vector_find function calls the matcher with each value, in order,
and key, and stores the first value it returns true for in the variable
value points to. The dmi_vector_exists function tells whether there is
such a value.
The dmi_vector_length function returns the number of values in the vector,
and the dmi_vector_is_empty function tells whether there are none. Both
take a nullptr vector as an empty one.
Parameters
vector-
Vector to work on.
context-
Context to raise the errors of the vector against, or
nullptrif there is none, in which case the errors are not recorded. matcher-
Function to compare the values with keys by, or
nullptrif the vector is not searched. value-
For
dmi_vector_push, value to append. Fordmi_vector_get, variable to store the value in. Fordmi_vector_popanddmi_vector_find, variable to store the value in, ornullptrif the value is not needed. index-
Index of the value, counted from zero.
key-
Key to pass to the matcher.
entry-
Value of the vector the matcher compares with
key.
Return value
The dmi_vector_initialize, dmi_vector_clear, dmi_vector_push and
dmi_vector_get functions return true on success, and false on failure.
If dmi_vector_push fails, the vector is left as it was.
The dmi_vector_pop function returns true if a value has been removed, and
false if the vector is empty, which is not an error, so that a vector can
be emptied by popping its values until there is none, or on failure.
The dmi_vector_find and dmi_vector_exists functions return true if a
value matches key, and false if none does, which is not an error either,
or on failure.
Errors
DMI_ERROR_ARGUMENT_NULL-
Raised if
vectorisnullptr, or, fordmi_vector_get, ifvalueisnullptr. DMI_ERROR_ARGUMENT_INVALID-
Raised by
dmi_vector_getifindexis out of range. DMI_ERROR_STATE_INVALID-
Raised by
dmi_vector_findanddmi_vector_existsif the vector has no matcher. DMI_ERROR_OUT_OF_MEMORY-
Raised by
dmi_vector_pushif the array cannot be grown.
The errors are raised against the context of the vector, and reach no error
queue if the vector has none, or if vector itself is nullptr. The one of
dmi_vector_initialize is raised against context.
Example
static bool match_name(uintptr_t entry, uintptr_t key)
{
return strcmp((const char *)entry, (const char *)key) == 0;
}
dmi_vector_t names;
dmi_vector_initialize(&names, context, match_name);
if (!dmi_vector_push(&names, (uintptr_t)"cpu") ||
!dmi_vector_push(&names, (uintptr_t)"memory")) {
dmi_vector_clear(&names);
return false;
}
if (dmi_vector_exists(&names, (uintptr_t)"memory"))
puts("found");
for (size_t i = 0; i < dmi_vector_length(&names); i++) {
uintptr_t value;
if (dmi_vector_get(&names, i, &value))
puts((const char *)value);
}
dmi_vector_clear(&names);