83 lines
2.1 KiB
C
83 lines
2.1 KiB
C
#include <c_LinkList.h>
|
|||
|
|
#include <c_Memory.h>
|
||
|
|
#include <c_Alignment.h>
|
||
|
|
#include "c_Macros.h"
|
||
|
|
|
||
|
|
c_err_t c_LinkList_Init(c_LinkList_t* self, c_size_t obj_size) {
|
||
|
|
if (!self || obj_size == 0) return C_ERR_PARAM;
|
||
|
|
self->head = NULL;
|
||
|
|
self->obj_size = (int)obj_size;
|
||
|
|
self->size = 0;
|
||
|
|
return C_ERR_OK;
|
||
|
|
}
|
||
|
|
|
||
|
|
void c_LinkList_Destroy(c_LinkList_t* self) {
|
||
|
|
if (!self) return;
|
||
|
|
|
||
|
|
c_LinkListNode_t* current = self->head;
|
||
|
|
while (current != NULL) {
|
||
|
|
c_LinkListNode_t* next = current->next;
|
||
|
|
// 由於 Add 時 data 與 node 是分開或合開,此處依據一體化配置釋放
|
||
|
|
C_FREE(current);
|
||
|
|
current = next;
|
||
|
|
}
|
||
|
|
self->head = NULL;
|
||
|
|
self->size = 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
c_err_t c_LinkList_Add(c_LinkList_t* self, void* obj) {
|
||
|
|
if (!self || !obj) return C_ERR_PARAM;
|
||
|
|
|
||
|
|
int size = (int)sizeof(c_LinkListNode_t) + self->obj_size;
|
||
|
|
size = C_ALIGN_UPB(size, C_ALIGN_SIZE);
|
||
|
|
c_LinkListNode_t* new_node = (c_LinkListNode_t*)C_ALLOC(size);
|
||
|
|
if (!new_node) return C_ERR_NOMEM;
|
||
|
|
new_node->data = new_node+1;
|
||
|
|
|
||
|
|
// 值複製 (Value Copy)
|
||
|
|
memcpy(new_node->data, obj, self->obj_size);
|
||
|
|
|
||
|
|
// 頭插法鏈結
|
||
|
|
new_node->next = self->head;
|
||
|
|
self->head = new_node;
|
||
|
|
self->size++;
|
||
|
|
|
||
|
|
return C_ERR_OK;
|
||
|
|
}
|
||
|
|
|
||
|
|
c_err_t c_LinkList_Remove(c_LinkList_t* self, void* obj) {
|
||
|
|
if (!self || !obj) return C_ERR_PARAM;
|
||
|
|
|
||
|
|
c_LinkListNode_t** curr = &self->head;
|
||
|
|
while (*curr != NULL) {
|
||
|
|
// 使用 memcmp 進行二進位值比對
|
||
|
|
if (memcmp((*curr)->data, obj, self->obj_size) == 0) {
|
||
|
|
c_LinkListNode_t* to_delete = *curr;
|
||
|
|
*curr = to_delete->next;
|
||
|
|
|
||
|
|
C_FREE(to_delete);
|
||
|
|
self->size--;
|
||
|
|
return C_ERR_OK;
|
||
|
|
}
|
||
|
|
curr = &(*curr)->next;
|
||
|
|
}
|
||
|
|
|
||
|
|
return C_ERR_FAIL;
|
||
|
|
}
|
||
|
|
|
||
|
|
void c_LinkListIter_Remove(c_LinkListIter_t* self) {
|
||
|
|
if (!self || !self->list || !self->node || !*(self->node)) return;
|
||
|
|
|
||
|
|
c_LinkListNode_t* to_delete = *(self->node);
|
||
|
|
|
||
|
|
// 讓上一個節點的 next 指向下一個節點,移除鏈結
|
||
|
|
*(self->node) = to_delete->next;
|
||
|
|
|
||
|
|
// 釋放該節點的值與結構
|
||
|
|
C_FREE(to_delete);
|
||
|
|
|
||
|
|
self->list->size--;
|
||
|
|
}
|
||
|
|
|
||
|
|
|