#include #include #include "c_Alignment.h" #include "c_Macros.h" c_err_t c_LinkQueue_Init(c_LinkQueue_t* self, int obj_size) { if (!self || obj_size == 0) return C_ERR_PARAM; self->head = NULL; self->tail = NULL; self->obj_size = (int)obj_size; self->size = 0; return C_ERR_OK; } void c_LinkQueue_Destroy(c_LinkQueue_t* self) { if (!self) return; c_LinkQueueNode_t* current = self->head; while (current != NULL) { c_LinkQueueNode_t* next = current->next; C_FREE(current); current = next; } self->head = NULL; self->tail = NULL; self->size = 0; } c_err_t c_LinkQueue_Push(c_LinkQueue_t* self, void* obj) { if (!self || !obj) return C_ERR_PARAM; // 1. 配置新節點與資料空間 int size = (int)sizeof(c_LinkQueueNode_t) + self->obj_size; size = C_ALIGN_UPB(size, C_ALIGN_SIZE); c_LinkQueueNode_t* new_node = (c_LinkQueueNode_t*)C_ALLOC(size); if (!new_node) return C_ERR_NOMEM; new_node->data = new_node+1; // 深複製資料內容 memcpy(new_node->data, obj, self->obj_size); new_node->next = NULL; // 2. 將新節點追加到串列尾端 if (self->tail == NULL) { // 佇列原本為空 self->head = new_node; self->tail = new_node; } else { // 佇列不為空,讓原本尾端的 next 指向新節點,並更新 tail self->tail->next = new_node; self->tail = new_node; } self->size++; return C_ERR_OK; } c_err_t c_LinkQueue_Pop(c_LinkQueue_t* self, void* obj) { if (!self ) return C_ERR_PARAM; if (self->size == 0 || !self->head) return C_ERR_EMPTY; c_LinkQueueNode_t* to_delete = self->head; // 1. 複製資料到使用者緩衝區 if (obj) { memcpy(obj, to_delete->data, self->obj_size); } // 2. 將 head 移至下一個節點 self->head = to_delete->next; if (self->head == NULL) { self->tail = NULL; } // 3. 釋放斷開的節點資源 C_FREE(to_delete); self->size--; return C_ERR_OK; } c_err_t c_LinkQueue_Peek(c_LinkQueue_t* self, void* obj) { if (!self ) return C_ERR_PARAM; if (self->size == 0 || !self->head) return C_ERR_EMPTY; // 複製最前端的資料內容 if (obj) { memcpy(obj, self->head->data, self->obj_size); } return C_ERR_OK; } void c_LinkQueueIter_Remove(c_LinkQueueIter_t* self) { if (!self || !self->queue || !self->node || !*(self->node)) return; c_LinkQueueNode_t* to_delete = *(self->node); c_LinkQueue_t* q = self->queue; // 檢查目前要刪除的是否為尾端節點 const c_bool_t is_tail = (to_delete == q->tail); // 讓上一個節點的 next(或 head)直接指向下一個節點,將 to_delete 從串列中斷開 *(self->node) = to_delete->next; // 如果刪除的是尾端節點,必須更新 tail 指標 if (is_tail) { if (q->head == NULL) { // 情況 A:刪除後佇列完全空了 q->tail = NULL; } else { // 情況 B:刪除的是尾巴,但前方還有元素。 // 沿著 head 重新走訪一遍,找出現在最尾端的節點(即 next 為 NULL 的節點) c_LinkQueueNode_t* curr = q->head; while (curr->next != NULL) { curr = curr->next; } q->tail = curr; // 更新新的尾端 } } // 釋放記憶體資源 C_FREE(to_delete); // 同步遞減佇列大小 q->size--; // 此時 self->node 已自動留在原本的下一個節點上,呼叫端可直接繼續 Get() 或 Next() }