245 lines
6.0 KiB
C
245 lines
6.0 KiB
C
/*----------------------------------------------------------------------------
|
|
* Copyright (c) TJD Technologies Co., Ltd. 2020. All rights reserved.
|
|
*
|
|
* Description: sys_dlist.h
|
|
*
|
|
* Author: saimen
|
|
*
|
|
* Create: 2024-4-24
|
|
*--------------------------------------------------------------------------*/
|
|
//lib
|
|
#include <stddef.h>
|
|
//user
|
|
#include "sys_dlist.h"
|
|
|
|
/**********************************************************************************************************************
|
|
* LOCAL FUNCTIONS
|
|
*/
|
|
static inline void dlist_init(tjd_sys_dlist_t *list)
|
|
{
|
|
list->prev = list;
|
|
list->next = list;
|
|
}
|
|
|
|
static inline void dlist_add(tjd_sys_dlist_item_t *item, tjd_sys_dlist_item_t *prev, tjd_sys_dlist_item_t *next)
|
|
{
|
|
item->next = next;
|
|
item->prev = prev;
|
|
next->prev = item;
|
|
prev->next = item;
|
|
}
|
|
|
|
static inline void dlist_del(tjd_sys_dlist_item_t *item)
|
|
{
|
|
item->prev->next = item->next;
|
|
item->next->prev = item->prev;
|
|
item->prev = item;
|
|
item->next = item;
|
|
}
|
|
|
|
/**********************************************************************************************************************
|
|
* PUBLIC FUNCTIONS
|
|
*/
|
|
void tjd_sys_dlist_create(tjd_sys_dlist_t *list)
|
|
{
|
|
list->next = list;
|
|
list->prev = list;
|
|
}
|
|
|
|
void tjd_sys_dlist_destroy(tjd_sys_dlist_t *list, dlist_free_handle_t free_handle, void *cntx)
|
|
{
|
|
tjd_sys_dlist_item_t *curr_item = NULL;
|
|
tjd_sys_dlist_item_t *next_item = NULL;
|
|
|
|
if (list == NULL) {
|
|
return;
|
|
}
|
|
|
|
TJD_SYS_DLIST_FOR_EACH(curr_item, next_item, list) {
|
|
dlist_del(curr_item);
|
|
if (free_handle) {
|
|
(*free_handle)(curr_item, cntx);
|
|
}
|
|
}
|
|
}
|
|
|
|
void tjd_sys_dlist_append(tjd_sys_dlist_t *list, tjd_sys_dlist_item_t *item)
|
|
{
|
|
dlist_add(item, list->prev, list);
|
|
}
|
|
|
|
void tjd_sys_dlist_prepend(tjd_sys_dlist_t *list, tjd_sys_dlist_item_t *item)
|
|
{
|
|
dlist_add(item, list, list->next);
|
|
}
|
|
|
|
void tjd_sys_dlist_remove(tjd_sys_dlist_item_t *item)
|
|
{
|
|
dlist_del(item);
|
|
}
|
|
|
|
void *tjd_sys_dlist_first(tjd_sys_dlist_t *list)
|
|
{
|
|
if (list == NULL || list->next == list) {
|
|
return NULL;
|
|
}
|
|
|
|
return list->next;
|
|
}
|
|
|
|
void *tjd_sys_dlist_last(tjd_sys_dlist_t *list)
|
|
{
|
|
if (list == NULL || list->prev == list) {
|
|
return NULL;
|
|
}
|
|
|
|
return list->prev;
|
|
}
|
|
|
|
uint32_t tjd_sys_dlist_size(tjd_sys_dlist_t *list)
|
|
{
|
|
uint32_t ret = 0;
|
|
tjd_sys_dlist_item_t *curr_item = NULL;
|
|
tjd_sys_dlist_item_t *next_item = NULL;
|
|
|
|
if (list == NULL) {
|
|
return 0;
|
|
}
|
|
|
|
TJD_SYS_DLIST_FOR_EACH(curr_item, next_item, list) {
|
|
ret += 1;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
void tjd_sys_dlist_insert(tjd_sys_dlist_t *list, tjd_sys_dlist_item_t *item, uint32_t ascend, dlist_cmpr_handle_t cmpr_handle)
|
|
{
|
|
tjd_sys_dlist_item_t *curr_item = NULL;
|
|
tjd_sys_dlist_item_t *next_item = NULL;
|
|
|
|
if (list == NULL || item == NULL || cmpr_handle == NULL) {
|
|
return;
|
|
}
|
|
|
|
dlist_init(item);
|
|
TJD_SYS_DLIST_FOR_EACH(curr_item, next_item, list) {
|
|
if (ascend) {
|
|
if ((*cmpr_handle)(curr_item, item) < 0) {
|
|
dlist_add(item, curr_item->prev, curr_item);
|
|
break;
|
|
}
|
|
} else {
|
|
if ((*cmpr_handle)(curr_item, item) > 0) {
|
|
dlist_add(item, curr_item->prev, curr_item);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void *tjd_sys_dlist_find(tjd_sys_dlist_t *list, tjd_sys_dlist_item_t *item, dlist_cmpr_handle_t cmpr_handle)
|
|
{
|
|
tjd_sys_dlist_item_t *curr_item = NULL;
|
|
tjd_sys_dlist_item_t *next_item = NULL;
|
|
|
|
if (list == NULL || item == NULL || cmpr_handle == NULL) {
|
|
return NULL;
|
|
}
|
|
|
|
TJD_SYS_DLIST_FOR_EACH(curr_item, next_item, list) {
|
|
if ((*cmpr_handle)(curr_item, item) == 0) {
|
|
return curr_item;
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
void tjd_sys_dlist_remove_first(tjd_sys_dlist_t *list, dlist_free_handle_t free_handle, void *cntx)
|
|
{
|
|
tjd_sys_dlist_item_t *curr_item = NULL;
|
|
|
|
if (list == NULL) {
|
|
return;
|
|
}
|
|
|
|
curr_item = list->next;
|
|
if (curr_item != list) {
|
|
dlist_del(curr_item);
|
|
if (free_handle) {
|
|
|
|
(*free_handle)(curr_item, cntx);
|
|
}
|
|
}
|
|
}
|
|
|
|
void tjd_sys_dlist_remove_last(tjd_sys_dlist_t *list, dlist_free_handle_t free_handle, void *cntx)
|
|
{
|
|
tjd_sys_dlist_item_t *curr_item = NULL;
|
|
|
|
if (list == NULL) {
|
|
return;
|
|
}
|
|
|
|
curr_item = list->prev;
|
|
if (curr_item != list) {
|
|
dlist_del(curr_item);
|
|
if (free_handle) {
|
|
|
|
(*free_handle)(curr_item, cntx);
|
|
}
|
|
}
|
|
}
|
|
|
|
void tjd_sys_dlist_remove_items(tjd_sys_dlist_t *list, tjd_sys_dlist_item_t *item,
|
|
dlist_cmpr_handle_t cmpr_handle, dlist_free_handle_t free_handle, void *cntx)
|
|
{
|
|
tjd_sys_dlist_item_t *curr_item = NULL;
|
|
tjd_sys_dlist_item_t *next_item = NULL;
|
|
|
|
if (item == NULL) {
|
|
return;
|
|
}
|
|
|
|
if (cmpr_handle == NULL) {
|
|
dlist_del(item);
|
|
if (free_handle) {
|
|
(*free_handle)(item, cntx);
|
|
}
|
|
} else {
|
|
|
|
if (list == NULL) {
|
|
return;
|
|
}
|
|
|
|
TJD_SYS_DLIST_FOR_EACH(curr_item, next_item, list) {
|
|
if ((*cmpr_handle)(curr_item, item) == 0) {
|
|
dlist_del(curr_item);
|
|
if (free_handle) {
|
|
(*free_handle)(curr_item, cntx);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void tjd_sys_dlist_traverse(tjd_sys_dlist_t *list, dlist_trvs_handle_t trvs_handle, void *cntx)
|
|
{
|
|
tjd_sys_dlist_item_t *curr_item = NULL;
|
|
tjd_sys_dlist_item_t *next_item = NULL;
|
|
|
|
if (list == NULL || trvs_handle == NULL) {
|
|
return;
|
|
}
|
|
|
|
TJD_SYS_DLIST_FOR_EACH(curr_item, next_item, list) {
|
|
(*trvs_handle)(curr_item, cntx);
|
|
}
|
|
}
|
|
|
|
/**********************************************************************************************************************
|
|
* EOF
|
|
*/
|
|
|