You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
172 lines
4.3 KiB
172 lines
4.3 KiB
/**
|
|
* @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;
|
|
}
|
|
|