bond/x64/src/kernel/k_linked_list.c

330 lines
6.6 KiB
C
Raw Normal View History

2016-05-24 07:27:26 +00:00
/* Copyright 2016 secXsQuared
* Distributed under GPL license
* See COPYING under root for details
*/
2016-08-27 05:13:54 +00:00
#include "k_linked_list.h"
2016-08-28 00:20:38 +00:00
static void KAPI _init_linked_list_node(k_linked_list_node_t *node)
{
if (node != NULL)
{
node->next = NULL;
node->prev = NULL;
}
return;
}
2016-08-28 00:20:38 +00:00
static void KAPI _append_node(k_linked_list_node_t *target, k_linked_list_node_t *node)
{
if(target == NULL || node == NULL)
return;
2016-08-28 00:20:38 +00:00
k_linked_list_node_t* next = target->next;
// update the next node
if(next != NULL)
{
next->prev = node;
}
// update the target node
target->next = node;
// update the node itself
node->prev = target;
node->next = next;
return;
}
// link target with node, suppose target is in the current list
2016-08-28 00:20:38 +00:00
static void KAPI _prepend_node(k_linked_list_node_t *target, k_linked_list_node_t *node)
{
if(target == NULL || node == NULL)
return;
2016-08-28 00:20:38 +00:00
k_linked_list_node_t* prev = target->prev;
// update the prev node
if(prev != NULL)
{
prev->next = node;
}
// update the target node
target->prev = node;
// update the node itself
node->next = target;
node->prev = prev;
return;
}
2016-08-28 00:20:38 +00:00
static void KAPI _unlink_node(k_linked_list_node_t* node)
{
if(node == NULL)
return;
if(node->prev != NULL)
{
node->prev->next = node->next;
}
if(node->next != NULL)
{
node->next->prev = node->prev;
}
return;
}
2016-08-28 00:20:38 +00:00
void KAPI ke_linked_list_init(k_linked_list_t *list)
{
if (list != NULL)
{
list->head = NULL;
list->tail = NULL;
}
return;
}
2016-08-28 00:20:38 +00:00
int32_t KAPI ke_linked_list_size(k_linked_list_t *list)
{
if (list == NULL)
return -1;
if (list->head == NULL)
return 0;
int32_t size = 1;
2016-08-28 00:20:38 +00:00
k_linked_list_node_t *cur_node = list->head;
k_linked_list_node_t *tail = list->tail;
while ((cur_node != tail) && ((cur_node = cur_node->next) != NULL))
{
size++;
}
return size;
}
2016-08-28 00:20:38 +00:00
void KAPI ke_linked_list_push_front(k_linked_list_t *list, k_linked_list_node_t *node)
{
if (list == NULL || node == NULL)
return;
_init_linked_list_node(node);
2016-08-28 00:20:38 +00:00
ke_linked_list_insert_ref(list, NULL, node);
return;
}
2016-08-28 00:20:38 +00:00
void KAPI ke_linked_list_push_back(k_linked_list_t *list, k_linked_list_node_t *node)
{
if (list == NULL || node == NULL)
return;
_init_linked_list_node(node);
2016-08-28 00:20:38 +00:00
ke_linked_list_insert_ref(list, list->tail, node);
return;
}
2016-08-28 00:20:38 +00:00
k_linked_list_node_t *KAPI ke_linked_list_pop_front(k_linked_list_t *list)
{
if (list == NULL)
return NULL;
2016-08-28 00:20:38 +00:00
return ke_linked_list_remove_ref(list, list->head);
}
2016-08-28 00:20:38 +00:00
k_linked_list_node_t *KAPI ke_linked_list_pop_back(k_linked_list_t *list)
{
if (list == NULL)
return NULL;
2016-08-28 00:20:38 +00:00
return ke_linked_list_remove_ref(list, list->tail);
}
2016-08-28 00:20:38 +00:00
void KAPI ke_linked_list_insert_ref(k_linked_list_t *list, k_linked_list_node_t *prev_node, k_linked_list_node_t *node)
{
if (list == NULL || node == NULL)
return;
_init_linked_list_node(node);
if (prev_node == NULL)
{
// if prev_node is NULL, then we are inserting to the head
// linked node with list->head
_prepend_node(list->head, node);
if (list->tail == NULL)
{
// if the list is empty, we assign list->tail to node too
list->tail = node;
}
list->head = node;
}
else
{
// if prev_node is not NULL, we are inserting to the middle or the end
// linked node with the prev_node
_append_node(prev_node, node);
if (node->next == NULL)
{
// if it's the end
list->tail = node;
}
}
}
2016-08-28 00:20:38 +00:00
void KAPI ke_linked_list_insert(k_linked_list_t *list, int32_t index, k_linked_list_node_t *node)
{
if (list == NULL || index < 0 || node == NULL)
return;
2016-08-28 00:20:38 +00:00
k_linked_list_node_t *prev_node = ke_linked_list_get(list, index - 1);
_init_linked_list_node(node);
if (prev_node == NULL)
{
if (index == 0)
{
2016-08-28 00:20:38 +00:00
ke_linked_list_insert_ref(list, NULL, node);
}
}
else
{
2016-08-28 00:20:38 +00:00
ke_linked_list_insert_ref(list, prev_node, node);
}
return;
}
2016-08-28 00:20:38 +00:00
k_linked_list_node_t *KAPI ke_linked_list_remove(k_linked_list_t *list, int32_t index)
{
if (list == NULL || index < 0)
return NULL;
2016-08-28 00:20:38 +00:00
k_linked_list_node_t *cur_node = ke_linked_list_get(list, index);
if (cur_node == NULL)
return NULL;
2016-08-28 00:20:38 +00:00
return ke_linked_list_remove_ref(list, cur_node);
}
2016-08-28 00:20:38 +00:00
k_linked_list_node_t *KAPI ke_linked_list_remove_ref(k_linked_list_t *list, k_linked_list_node_t *node)
{
if (list == NULL || node == NULL)
return NULL;
_unlink_node(node);
if(node->next == NULL)
{
list->tail = node->prev;
}
if(node->prev == NULL)
{
list->head = node->next;
}
_init_linked_list_node(node);
return node;
}
2016-08-28 00:20:38 +00:00
k_linked_list_node_t *KAPI ke_linked_list_get(k_linked_list_t *list, int32_t index)
{
if (list == NULL || index < 0 || list->head == NULL)
return NULL;
2016-08-28 00:20:38 +00:00
k_linked_list_node_t *cur_node = list->head;
while (index-- && (cur_node = cur_node->next) != NULL);
return cur_node;
}
2016-08-28 00:20:38 +00:00
k_linked_list_node_t *KAPI ke_linked_list_next(k_linked_list_node_t *node)
{
if (node != NULL)
{
node = node->next;
}
return node;
}
2016-08-28 00:20:38 +00:00
k_linked_list_node_t *KAPI ke_linked_list_prev(k_linked_list_node_t *node)
{
if (node != NULL)
{
node = node->prev;
}
return node;
}
2016-08-28 00:20:38 +00:00
k_linked_list_node_t *KAPI ke_linked_list_first(k_linked_list_t *list)
{
2016-08-28 00:20:38 +00:00
k_linked_list_node_t *result = NULL;
if (list != NULL)
{
result = list->head;
}
return result;
}
2016-08-28 00:20:38 +00:00
k_linked_list_node_t *KAPI ke_linked_list_last(k_linked_list_t *list)
{
2016-08-28 00:20:38 +00:00
k_linked_list_node_t *result = NULL;
if (list != NULL)
{
result = list->tail;
}
return result;
}
2016-08-28 00:20:38 +00:00
int32_t KAPI ke_linked_list_search(k_linked_list_t *list, k_linked_list_node_t *target,
k_callback_func_t equals)
{
if(list == NULL || target == NULL)
return -1;
int32_t result = 0;
2016-08-28 00:20:38 +00:00
k_linked_list_node_t* node = ke_linked_list_first(list);
while(node != NULL)
{
if(equals != NULL)
{
if (equals(node, target))
{
return result;
}
}
else
{
if(target->next == node->next && target->prev == node->prev)
{
return result;
}
}
result++;
2016-08-28 00:20:38 +00:00
node = ke_linked_list_next(node);
}
return -1;
}