mcu_hi3321_watch/tjd/system/sys_dlist.c
2025-05-26 20:15:20 +08:00

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
*/