1/*
2 * Copyright 2004-2008, François Revol, <revol@free.fr>.
3 * Distributed under the terms of the MIT License.
4 */
5
6#include <OS.h>
7#include "lists2.h"
8
9void *sll_find(long nextoff, void *head, sll_compare_func func, void *id)
10{
11	void *p = head;
12	int count = 5000;
13	if (head == NULL)
14		return NULL;
15	while (p) {
16		if (func(p, id) == 0)
17			return p;
18		p = sll_next(nextoff, p);
19		if (!count--) {
20			dprintf("sll_find: WARNING: 5000 nodes to search ??? looks more of a loop.\n");
21			return NULL;
22		}
23	}
24	return NULL;
25}
26
27status_t sll_insert_head(long nextoff, void **head, void *item)
28{
29	void *next = NULL;
30	if (head == NULL || item == NULL)
31		return EINVAL;
32	if (*head)
33		next = *head;
34	*(void **)(((char *)item)+nextoff) = next;
35	*head = item;
36	return B_OK;
37}
38
39status_t sll_insert_tail(long nextoff, void **head, void *item)
40{
41	void *p, *next = NULL;
42	if (head == NULL || item == NULL)
43		return EINVAL;
44
45	if (*(void **)(((char *)item)+nextoff)) {
46		dprintf("sll_insert_tail: WARNING: %p->next NOT NULL\n", item);
47		*(void **)(((char *)item)+nextoff) = NULL;
48	}
49
50	p = *head;
51	if (!p) {
52		*head = item;
53		return B_OK;
54	}
55	while (sll_next(nextoff, p))
56		p = sll_next(nextoff, p);
57	*(void **)(((char *)p)+nextoff) = item;
58	return B_OK;
59}
60
61void *sll_dequeue_tail(long nextoff, void **head)
62{
63	void **prev = NULL;
64	void *curr = NULL;
65	if (head == NULL || *head == NULL)
66		return NULL;
67	prev = head;
68	curr = *head;
69	while (sll_next(nextoff, curr)) {
70		prev = (void **)(((char *)curr)+nextoff);
71		curr = sll_next(nextoff, curr);
72	}
73	*prev = NULL;
74	return curr;
75}
76
77status_t sll_remove(long nextoff, void **head, void *item)
78{
79	void **prev = NULL;
80	void *curr = NULL;
81	if (head == NULL || *head == NULL || item == NULL)
82		return EINVAL;
83	prev = head;
84	curr = *head;
85	while (prev && curr) {
86		if (curr == item) {
87			*prev = sll_next(nextoff, curr);
88			*(void **)(((char *)item)+nextoff) = NULL;
89			return B_OK;
90		}
91		prev = (void **)(((char *)curr)+nextoff);
92		curr = sll_next(nextoff, curr);
93	}
94	return ENOENT;
95}
96
97void *sll_next(long nextoff, void *item)
98{
99	void *next;
100	if (!item)
101		return NULL;
102	next = *(void **)(((char *)item)+nextoff);
103	return next;
104}
105