%PDF- %PDF-
| Direktori : /home/vacivi36/vittasync.vacivitta.com.br/vittasync/node/deps/cares/src/lib/ |
| Current File : /home/vacivi36/vittasync.vacivitta.com.br/vittasync/node/deps/cares/src/lib/ares__llist.c |
/* MIT License
*
* Copyright (c) 2023 Brad House
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* SPDX-License-Identifier: MIT
*/
#include "ares_setup.h"
#include "ares.h"
#include "ares_private.h"
#include "ares__llist.h"
struct ares__llist {
ares__llist_node_t *head;
ares__llist_node_t *tail;
ares__llist_destructor_t destruct;
size_t cnt;
};
struct ares__llist_node {
void *data;
ares__llist_node_t *prev;
ares__llist_node_t *next;
ares__llist_t *parent;
};
ares__llist_t *ares__llist_create(ares__llist_destructor_t destruct)
{
ares__llist_t *list = ares_malloc_zero(sizeof(*list));
if (list == NULL) {
return NULL;
}
list->destruct = destruct;
return list;
}
void ares__llist_replace_destructor(ares__llist_t *list,
ares__llist_destructor_t destruct)
{
if (list == NULL) {
return;
}
list->destruct = destruct;
}
typedef enum {
ARES__LLIST_INSERT_HEAD,
ARES__LLIST_INSERT_TAIL,
ARES__LLIST_INSERT_BEFORE
} ares__llist_insert_type_t;
static void ares__llist_attach_at(ares__llist_t *list,
ares__llist_insert_type_t type,
ares__llist_node_t *at,
ares__llist_node_t *node)
{
if (list == NULL || node == NULL) {
return;
}
node->parent = list;
if (type == ARES__LLIST_INSERT_BEFORE && (at == list->head || at == NULL)) {
type = ARES__LLIST_INSERT_HEAD;
}
switch (type) {
case ARES__LLIST_INSERT_HEAD:
node->next = list->head;
node->prev = NULL;
if (list->head) {
list->head->prev = node;
}
list->head = node;
break;
case ARES__LLIST_INSERT_TAIL:
node->next = NULL;
node->prev = list->tail;
if (list->tail) {
list->tail->next = node;
}
list->tail = node;
break;
case ARES__LLIST_INSERT_BEFORE:
node->next = at;
node->prev = at->prev;
at->prev = node;
break;
}
if (list->tail == NULL) {
list->tail = node;
}
if (list->head == NULL) {
list->head = node;
}
list->cnt++;
}
static ares__llist_node_t *ares__llist_insert_at(ares__llist_t *list,
ares__llist_insert_type_t type,
ares__llist_node_t *at,
void *val)
{
ares__llist_node_t *node = NULL;
if (list == NULL || val == NULL) {
return NULL;
}
node = ares_malloc_zero(sizeof(*node));
if (node == NULL) {
return NULL;
}
node->data = val;
ares__llist_attach_at(list, type, at, node);
return node;
}
ares__llist_node_t *ares__llist_insert_first(ares__llist_t *list, void *val)
{
return ares__llist_insert_at(list, ARES__LLIST_INSERT_HEAD, NULL, val);
}
ares__llist_node_t *ares__llist_insert_last(ares__llist_t *list, void *val)
{
return ares__llist_insert_at(list, ARES__LLIST_INSERT_TAIL, NULL, val);
}
ares__llist_node_t *ares__llist_insert_before(ares__llist_node_t *node,
void *val)
{
if (node == NULL) {
return NULL;
}
return ares__llist_insert_at(node->parent, ARES__LLIST_INSERT_BEFORE, node,
val);
}
ares__llist_node_t *ares__llist_insert_after(ares__llist_node_t *node,
void *val)
{
if (node == NULL) {
return NULL;
}
if (node->next == NULL) {
return ares__llist_insert_last(node->parent, val);
}
return ares__llist_insert_at(node->parent, ARES__LLIST_INSERT_BEFORE,
node->next, val);
}
ares__llist_node_t *ares__llist_node_first(ares__llist_t *list)
{
if (list == NULL) {
return NULL;
}
return list->head;
}
ares__llist_node_t *ares__llist_node_last(ares__llist_t *list)
{
if (list == NULL) {
return NULL;
}
return list->tail;
}
ares__llist_node_t *ares__llist_node_next(ares__llist_node_t *node)
{
if (node == NULL) {
return NULL;
}
return node->next;
}
ares__llist_node_t *ares__llist_node_prev(ares__llist_node_t *node)
{
if (node == NULL) {
return NULL;
}
return node->prev;
}
void *ares__llist_node_val(ares__llist_node_t *node)
{
if (node == NULL) {
return NULL;
}
return node->data;
}
size_t ares__llist_len(const ares__llist_t *list)
{
if (list == NULL) {
return 0;
}
return list->cnt;
}
ares__llist_t *ares__llist_node_parent(ares__llist_node_t *node)
{
if (node == NULL) {
return NULL;
}
return node->parent;
}
void *ares__llist_first_val(ares__llist_t *list)
{
return ares__llist_node_val(ares__llist_node_first(list));
}
void *ares__llist_last_val(ares__llist_t *list)
{
return ares__llist_node_val(ares__llist_node_last(list));
}
static void ares__llist_node_detach(ares__llist_node_t *node)
{
ares__llist_t *list;
if (node == NULL) {
return;
}
list = node->parent;
if (node->prev) {
node->prev->next = node->next;
}
if (node->next) {
node->next->prev = node->prev;
}
if (node == list->head) {
list->head = node->next;
}
if (node == list->tail) {
list->tail = node->prev;
}
node->parent = NULL;
list->cnt--;
}
void *ares__llist_node_claim(ares__llist_node_t *node)
{
void *val;
if (node == NULL) {
return NULL;
}
val = node->data;
ares__llist_node_detach(node);
ares_free(node);
return val;
}
void ares__llist_node_destroy(ares__llist_node_t *node)
{
ares__llist_destructor_t destruct;
void *val;
if (node == NULL) {
return;
}
destruct = node->parent->destruct;
val = ares__llist_node_claim(node);
if (val != NULL && destruct != NULL) {
destruct(val);
}
}
void ares__llist_node_replace(ares__llist_node_t *node, void *val)
{
ares__llist_destructor_t destruct;
if (node == NULL) {
return;
}
destruct = node->parent->destruct;
if (destruct != NULL) {
destruct(node->data);
}
node->data = val;
}
void ares__llist_destroy(ares__llist_t *list)
{
ares__llist_node_t *node;
if (list == NULL) {
return;
}
while ((node = ares__llist_node_first(list)) != NULL) {
ares__llist_node_destroy(node);
}
ares_free(list);
}
void ares__llist_node_move_parent_last(ares__llist_node_t *node,
ares__llist_t *new_parent)
{
if (node == NULL || new_parent == NULL) {
return;
}
ares__llist_node_detach(node);
ares__llist_attach_at(new_parent, ARES__LLIST_INSERT_TAIL, NULL, node);
}
void ares__llist_node_move_parent_first(ares__llist_node_t *node,
ares__llist_t *new_parent)
{
if (node == NULL || new_parent == NULL) {
return;
}
ares__llist_node_detach(node);
ares__llist_attach_at(new_parent, ARES__LLIST_INSERT_HEAD, NULL, node);
}