297 lines
5.9 KiB
C
297 lines
5.9 KiB
C
/*
|
||
* 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
|