ucloud-iot-rtthread-package/uiot/utils/utils_list.c

297 lines
5.9 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* Copyright (C) 2012-2019 UCloud. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* or in the "license" file accompanying this file. This file is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/
#ifdef __cplusplus
extern "C" {
#endif
#include "utils_list.h"
#include "uiot_import.h"
/*
* 创建List. 失败则返回NULL.
*/
List *list_new(void)
{
List *self;
self = (List *)HAL_Malloc(sizeof(List));
if (!self) {
return NULL;
}
self->head = NULL;
self->tail = NULL;
self->free = NULL;
self->match = NULL;
self->len = 0;
return self;
}
/*
* 失败List的内存.
*/
void list_destroy(List *self)
{
unsigned int len = self->len;
ListNode *next;
ListNode *curr = self->head;
while (len--) {
next = curr->next;
if (self->free) {
self->free(curr->val);
}
HAL_Free(curr);
curr = next;
}
HAL_Free(self);
}
/*
* 将给定节点附加到列表并返回该节点在失败时返回NULL.
*/
ListNode *list_rpush(List *self, ListNode *node)
{
if (!node) {
return NULL;
}
if (self->len) {
node->prev = self->tail;
node->next = NULL;
self->tail->next = node;
self->tail = node;
} else {
self->head = self->tail = node;
node->prev = node->next = NULL;
}
++self->len;
return node;
}
/*
* 弹出列表中的最后一个节点, 失败返回NULL.
*/
ListNode *list_rpop(List *self)
{
ListNode *node = NULL;
if (!self->len) {
return NULL;
}
node = self->tail;
if (--self->len) {
(self->tail = node->prev)->next = NULL;
} else {
self->tail = self->head = NULL;
}
node->next = node->prev = NULL;
return node;
}
/*
* 弹出列表中的首个节点, 失败返回NULL.
*/
ListNode *list_lpop(List *self)
{
ListNode *node = NULL;
if (!self->len) {
return NULL;
}
node = self->head;
if (--self->len) {
(self->head = node->next)->prev = NULL;
} else {
self->head = self->tail = NULL;
}
node->next = node->prev = NULL;
return node;
}
/*
* 预先将给定的节点添加到列表中并返回该节点在失败时返回NULL.
*/
ListNode *list_lpush(List *self, ListNode *node)
{
if (!node) {
return NULL;
}
if (self->len) {
node->next = self->head;
node->prev = NULL;
self->head->prev = node;
self->head = node;
} else {
self->head = self->tail = node;
node->prev = node->next = NULL;
}
++self->len;
return node;
}
/*
* 根据val返回对应的节点没有则返回NULL.
*/
ListNode *list_find(List *self, void *val)
{
ListIterator *it;
ListNode *node;
if (NULL == (it = list_iterator_new(self, LIST_HEAD))) {
return NULL;
}
node = list_iterator_next(it);
while (node) {
if (self->match) {
if (self->match(val, node->val)) {
list_iterator_destroy(it);
return node;
}
} else {
if (val == node->val) {
list_iterator_destroy(it);
return node;
}
}
node = list_iterator_next(it);
}
list_iterator_destroy(it);
return NULL;
}
/*
* 根据index返回对应的节点没有则返回NULL.
*/
ListNode *list_at(List *self, int index)
{
ListDirection direction = LIST_HEAD;
if (index < 0) {
direction = LIST_TAIL;
index = ~index;
}
if ((unsigned) index < self->len) {
ListIterator *it;
ListNode *node;
if (NULL == (it = list_iterator_new(self, direction))) {
return NULL;
}
node = list_iterator_next(it);
while (index--) {
node = list_iterator_next(it);
}
list_iterator_destroy(it);
return node;
}
return NULL;
}
/*
* 从列表中删除给定的节点,释放它和它的值.
*/
void list_remove(List *self, ListNode *node)
{
node->prev ? (node->prev->next = node->next) : (self->head = node->next);
node->next ? (node->next->prev = node->prev) : (self->tail = node->prev);
if (self->free) {
self->free(node->val);
}
HAL_Free(node);
--self->len;
}
/*
* 创建一个新的ListIterator失败返回NULL, 并且设置其ListDirection.
*/
ListIterator *list_iterator_new(List *list, ListDirection direction)
{
ListNode *node = direction == LIST_HEAD ? list->head : list->tail;
return list_iterator_new_from_node(node, direction);
}
/*
* 创建一个新的ListIterator, 并设置初始节点. 失败则返回NULL.
*/
ListIterator *list_iterator_new_from_node(ListNode *node, ListDirection direction)
{
ListIterator *self;
self = HAL_Malloc(sizeof(ListIterator));
if (!self) {
return NULL;
}
self->next = node;
self->direction = direction;
return self;
}
/*
* 返回下一个节点, 如果没有更多的节点则返回NULL.
*/
ListNode *list_iterator_next(ListIterator *self)
{
ListNode *curr = self->next;
if (curr) {
self->next = self->direction == LIST_HEAD ? curr->next : curr->prev;
}
return curr;
}
/*
* 释放列表迭代器.
*/
void list_iterator_destroy(ListIterator *self)
{
HAL_Free(self);
self = NULL;
}
/*
* 根据预设值来创建新节点, 失败则返回NULL.
*/
ListNode *list_node_new(void *val)
{
ListNode *self;
self = HAL_Malloc(sizeof(ListNode));
if (!self) {
return NULL;
}
self->prev = NULL;
self->next = NULL;
self->val = val;
return self;
}
#ifdef __cplusplus
}
#endif