155 lines
3.5 KiB
C
Executable File
155 lines
3.5 KiB
C
Executable File
/*
|
|
* node_list.c
|
|
*
|
|
* Created on: Mar 8, 2011
|
|
* Author: posixninja
|
|
*
|
|
* Copyright (c) 2011 Joshua Hill. All Rights Reserved.
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include "list.h"
|
|
#include "node.h"
|
|
#include "node_list.h"
|
|
|
|
void node_list_destroy(node_list_t* list) {
|
|
if(list != NULL) {
|
|
list_destroy((list_t*) list);
|
|
}
|
|
}
|
|
|
|
node_list_t* node_list_create() {
|
|
node_list_t* list = (node_list_t*) malloc(sizeof(node_list_t));
|
|
if(list == NULL) {
|
|
return NULL;
|
|
}
|
|
memset(list, '\0', sizeof(node_list_t));
|
|
|
|
// Initialize structure
|
|
list_init((list_t*) list);
|
|
list->count = 0;
|
|
return list;
|
|
}
|
|
|
|
int node_list_add(node_list_t* list, node_t* node) {
|
|
if (!list || !node) return -1;
|
|
|
|
// Find the last element in the list
|
|
node_t* last = list->end;
|
|
|
|
// Setup our new node as the new last element
|
|
node->next = NULL;
|
|
node->prev = last;
|
|
|
|
// Set the next element of our old "last" element
|
|
if (last) {
|
|
// but only if the node list is not empty
|
|
last->next = node;
|
|
}
|
|
|
|
// Set the lists prev to the new last element
|
|
list->end = node;
|
|
|
|
// Increment our node count for this list
|
|
list->count++;
|
|
return 0;
|
|
}
|
|
|
|
int node_list_insert(node_list_t* list, unsigned int node_index, node_t* node) {
|
|
if (!list || !node) return -1;
|
|
if (node_index >= list->count) {
|
|
return node_list_add(list, node);
|
|
}
|
|
|
|
// Get the first element in the list
|
|
node_t* cur = list->begin;
|
|
|
|
unsigned int pos = 0;
|
|
node_t* prev = NULL;
|
|
|
|
if (node_index > 0) {
|
|
while (pos < node_index) {
|
|
prev = cur;
|
|
cur = cur->next;
|
|
pos++;
|
|
}
|
|
}
|
|
|
|
if (prev) {
|
|
// Set previous node
|
|
node->prev = prev;
|
|
// Set next node of our new node to next node of the previous node
|
|
node->next = prev->next;
|
|
// Set next node of previous node to our new node
|
|
prev->next = node;
|
|
} else {
|
|
node->prev = NULL;
|
|
// get old first element in list
|
|
node->next = list->begin;
|
|
// set new node as first element in list
|
|
list->begin = node;
|
|
}
|
|
|
|
if (node->next == NULL) {
|
|
// Set the lists prev to the new last element
|
|
list->end = node;
|
|
} else {
|
|
// set prev of the new next element to our node
|
|
node->next->prev = node;
|
|
}
|
|
|
|
// Increment our node count for this list
|
|
list->count++;
|
|
return 0;
|
|
}
|
|
|
|
int node_list_remove(node_list_t* list, node_t* node) {
|
|
if (!list || !node) return -1;
|
|
if (list->count == 0) return -1;
|
|
|
|
int node_index = 0;
|
|
node_t* n;
|
|
for (n = list->begin; n; n = n->next) {
|
|
if (node == n) {
|
|
node_t* newnode = node->next;
|
|
if (node->prev) {
|
|
node->prev->next = newnode;
|
|
if (newnode) {
|
|
newnode->prev = node->prev;
|
|
} else {
|
|
// last element in the list
|
|
list->end = node->prev;
|
|
}
|
|
} else {
|
|
// we just removed the first element
|
|
if (newnode) {
|
|
newnode->prev = NULL;
|
|
}
|
|
list->begin = newnode;
|
|
}
|
|
list->count--;
|
|
return node_index;
|
|
}
|
|
node_index++;
|
|
}
|
|
return -1;
|
|
}
|
|
|