Files
cKit/Foundation/c_StringList.c
T

125 lines
3.9 KiB
C
Raw Normal View History

2026-08-29 01:50:50 +08:00
#include <c_StringList.h>
#include <c_Memory.h>
c_err_t c_StringList_Init(c_StringList* list, c_size_t initial_capacity) {
if (!list) return C_ERR_PARAM;
list->size = 0;
list->capacity = initial_capacity;
if (initial_capacity > 0) {
list->strings = (char**)C_ALLOC(initial_capacity * sizeof(char*));
if (!list->strings) {
list->capacity = 0;
return C_ERR_NOMEM;
}
} else {
list->strings = NULL;
}
return C_ERR_OK;
}
void c_StringList_Destroy(c_StringList* list) {
if (!list) return;
if (list->strings) {
for (c_size_t i = 0; i < list->size; i++) {
C_FREE(list->strings[i]);
}
C_FREE(list->strings);
}
list->size = 0;
list->capacity = 0;
}
c_err_t c_StringList_Append(c_StringList* list, const char* str) {
if (!list || !str) return C_ERR_PARAM;
if (list->size >= list->capacity) {
c_size_t new_capacity = (list->capacity == 0) ? 4 : list->capacity * 2;
char** new_array = (char**)C_REALLOC(list->strings, new_capacity * sizeof(char*));
if (!new_array) return C_ERR_NOMEM;
list->strings = new_array;
list->capacity = new_capacity;
}
char* copy = (char*)C_ALLOC(strlen(str) + 1);
if (!copy) return C_ERR_NOMEM;
strcpy(copy, str);
list->strings[list->size++] = copy;
return C_ERR_OK;
}
/**
* Insert a new null-terminated string copy row at the very front of the collection list (Index 0)
*/
c_err_t c_StringList_Prepend(c_StringList* list, const char* str) {
if (!list || !str) {
return C_ERR_PARAM;
}
// 1. Dynamic scale check and array reallocation if capacity bounds are reached
if (list->size >= list->capacity) {
c_size_t new_capacity = (list->capacity == 0) ? 4 : list->capacity * 2;
char** new_array = (char**)C_REALLOC(list->strings, new_capacity * sizeof(char*));
if (!new_array) {
return C_ERR_NOMEM;
}
list->strings = new_array;
list->capacity = new_capacity;
}
// 2. Allocate an isolated deep-copy heap buffer for the incoming string characters
char* str_copy = (char*)C_ALLOC(strlen(str) + 1);
if (!str_copy) {
return C_ERR_NOMEM;
}
strcpy(str_copy, str);
// 3. Shift all existing string pointer entries rightward by 1 to make room at index 0
for (c_size_t i = list->size; i > 0; i--) {
list->strings[i] = list->strings[i - 1];
}
// 4. Place the newly allocated string capsule at the front and increment tracking metrics
list->strings[0] = str_copy;
list->size++;
return C_ERR_OK;
}
/**
* Remove the first occurrence of a string value from the collection.
* Cleans up memory allocations and tightly shifts elements to prevent layout leaks.
*/
c_err_t c_StringList_Remove(c_StringList* list, const char* str) {
if (!list || !list->strings || !str) {
return C_ERR_PARAM;
}
c_size_t target_idx = (c_size_t)-1;
// 1. Linearly scan the string array to locate a matching value match
for (c_size_t i = 0; i < list->size; i++) {
if (list->strings[i] != NULL && strcmp(list->strings[i], str) == 0) {
target_idx = i;
break;
}
}
// If the targeted string value does not exist, return an error code parameter
if (target_idx == (c_size_t)-1) {
return C_ERR_PARAM;
}
// 2. Safely free the individual string characters heap capsule
C_FREE(list->strings[target_idx]); // Safe macro automatically sets index entry to NULL
// 3. Shift subsequent array entries leftward to maintain dense cache prefetching locality
for (c_size_t i = target_idx; i < list->size - 1; i++) {
list->strings[i] = list->strings[i + 1];
}
// 4. Update trailing metadata bounds
list->size--;
list->strings[list->size] = NULL; // Ensure the newly vacant tail slot is nullified safely
return C_ERR_OK;
}