diff options
Diffstat (limited to 'lib/lvgl/src/misc/lv_array.c')
| -rw-r--r-- | lib/lvgl/src/misc/lv_array.c | 172 |
1 files changed, 172 insertions, 0 deletions
diff --git a/lib/lvgl/src/misc/lv_array.c b/lib/lvgl/src/misc/lv_array.c new file mode 100644 index 00000000..cb962050 --- /dev/null +++ b/lib/lvgl/src/misc/lv_array.c @@ -0,0 +1,172 @@ +/** + * @file lv_array.c + * Array. + * The nodes are dynamically allocated by the 'lv_mem' module, + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_array.h" +#include "../stdlib/lv_mem.h" +#include "../stdlib/lv_string.h" + +#include "lv_assert.h" +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ +void lv_array_init(lv_array_t * array, uint32_t capacity, uint32_t element_size) +{ + array->size = 0; + array->capacity = capacity; + array->element_size = element_size; + + array->data = lv_malloc(capacity * element_size); + LV_ASSERT_MALLOC(array->data); +} + +void lv_array_deinit(lv_array_t * array) +{ + if(array->data) { + lv_free(array->data); + array->data = NULL; + } + + array->size = 0; + array->capacity = 0; +} + +void lv_array_copy(lv_array_t * target, const lv_array_t * source) +{ + if(lv_array_is_empty(source)) { + return; + } + lv_array_deinit(target); + lv_array_init(target, source->capacity, source->element_size); + lv_memcpy(target->data, source->data, source->size * source->element_size); + target->size = source->size; +} + +lv_result_t lv_array_remove(lv_array_t * array, uint32_t index) +{ + if(index >= array->size) { + return LV_RESULT_INVALID; + } + + /*Shortcut*/ + if(index == array->size - 1) { + lv_array_resize(array, array->size - 1); + return LV_RESULT_OK; + } + + uint8_t * start = lv_array_at(array, index); + uint8_t * remaining = start + array->element_size; + uint32_t remaining_size = (array->size - index - 1) * array->element_size; + lv_memmove(start, remaining, remaining_size); + lv_array_resize(array, array->size - 1); + return LV_RESULT_OK; +} + +lv_result_t lv_array_erase(lv_array_t * array, uint32_t start, uint32_t end) +{ + if(end > array->size) { + end = array->size; + } + + if(start >= end) { + return LV_RESULT_INVALID; + } + + /*Shortcut*/ + if(end == array->size) { + lv_array_resize(array, start); + return LV_RESULT_OK; + } + + uint8_t * start_p = lv_array_at(array, start); + uint8_t * remaining = start_p + (end - start) * array->element_size; + uint32_t remaining_size = (array->size - end) * array->element_size; + lv_memcpy(start_p, remaining, remaining_size); + lv_array_resize(array, array->size - (end - start)); + return LV_RESULT_OK; +} + +void lv_array_resize(lv_array_t * array, uint32_t new_capacity) +{ + uint8_t * data = lv_realloc(array->data, new_capacity * array->element_size); + LV_ASSERT_NULL(data); + array->data = data; + array->capacity = new_capacity; + if(array->size > new_capacity) { + array->size = new_capacity; + } +} + +lv_result_t lv_array_concat(lv_array_t * array, const lv_array_t * other) +{ + LV_ASSERT_NULL(array->data); + uint32_t size = other->size; + if(array->size + size > array->capacity) { + /*array is full*/ + lv_array_resize(array, array->size + size); + } + + uint8_t * data = array->data + array->size * array->element_size; + lv_memcpy(data, other->data, array->element_size * size); + array->size += size; + return LV_RESULT_OK; +} + +lv_result_t lv_array_push_back(lv_array_t * array, const void * element) +{ + LV_ASSERT_NULL(array->data); + + if(array->size == array->capacity) { + /*array is full*/ + lv_array_resize(array, array->capacity + 1); + } + + uint8_t * data = array->data + array->size * array->element_size; + lv_memcpy(data, element, array->element_size); + array->size++; + return LV_RESULT_OK; +} + +void * lv_array_at(const lv_array_t * array, uint32_t index) +{ + if(index >= array->size) { + return NULL; + } + + LV_ASSERT_NULL(array->data); + return array->data + index * array->element_size; +} + +lv_result_t lv_array_assign(lv_array_t * array, uint32_t index, const void * value) +{ + uint8_t * data = lv_array_at(array, index); + if(data == NULL) return LV_RESULT_INVALID; + + lv_memcpy(data, value, array->element_size); + return LV_RESULT_OK; +} |
