summaryrefslogtreecommitdiff
path: root/arm9/lib/libnns/src/NNS_FND_list.c
blob: fdab818878a21e5dc204b7786eb56169898e6a0b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#include "nitro.h"
#include "NNS_FND_list.h"

#define OBJ_TO_LINK(list, obj) ((NNSFndLink*)((void*)(obj) + (list)->offset))

ARM_FUNC void NNS_FndInitList(NNSFndList* list, s32 alignment)
{
    list->headObject = NULL;
    list->tailObject = NULL;
    list->numObjects = 0;
    list->offset = (u16)alignment;
}

ARM_FUNC static void SetFirstObject(NNSFndList* list, void* object)
{
    NNSFndLink* tail = OBJ_TO_LINK(list, object);
    tail->nextObject = NULL;
    tail->prevObject = NULL;
    list->headObject = object;
    list->tailObject = object;
    list->numObjects++;
}

ARM_FUNC void NNS_FndAppendListObject(NNSFndList* list, void* object)
{
    if (list->headObject == NULL)
    {
        SetFirstObject(list, object);
    }
    else
    {
        NNSFndLink *tail = OBJ_TO_LINK(list, object);
        tail->prevObject = list->tailObject;
        tail->nextObject = NULL;
        OBJ_TO_LINK(list, list->tailObject)->nextObject = object;
        list->tailObject = object;
        list->numObjects++;
    }
}

ARM_FUNC void NNS_FndPrependListObject(NNSFndList* list, void* object)
{
    if (list->headObject == NULL)
    {
        SetFirstObject(list, object);
    }
    else
    {
        NNSFndLink *tail = OBJ_TO_LINK(list, object);
        tail->prevObject = NULL;
        tail->nextObject = list->headObject;
        OBJ_TO_LINK(list, list->headObject)->prevObject = object;
        list->headObject = object;
        list->numObjects++;
    }
}

ARM_FUNC void NNS_FndInsertListObject(NNSFndList* list, void* where, void* object)
{
    if (where == NULL)
    {
        NNS_FndAppendListObject(list, object);
    }

    else if (where == list->headObject)
    {
        NNS_FndPrependListObject(list, object);
    }
    else
    {
        NNSFndLink* tail = OBJ_TO_LINK(list, object);
        void* prevObject = OBJ_TO_LINK(list, where)->prevObject;
        NNSFndLink* head = OBJ_TO_LINK(list, prevObject);
        tail->prevObject = prevObject;
        tail->nextObject = where;
        head->nextObject = object;
        OBJ_TO_LINK(list, where)->prevObject = object;
        list->numObjects++;
    }
}

ARM_FUNC void NNS_FndRemoveListObject(NNSFndList* list, void* object)
{
    NNSFndLink* node = OBJ_TO_LINK(list, object);
    if (node->prevObject == NULL)
    {
        list->headObject = node->nextObject;
    }
    else
    {
        OBJ_TO_LINK(list, node->prevObject)->nextObject = node->nextObject;
    }
    if (node->nextObject == NULL)
    {
        list->tailObject = node->prevObject;
    }
    else
    {
        OBJ_TO_LINK(list, node->nextObject)->prevObject = node->prevObject;
    }
    node->prevObject = NULL;
    node->nextObject = NULL;
    list->numObjects--;
}

ARM_FUNC void * NNS_FndGetNextListObject(NNSFndList* list, void* object)
{
    if (object == NULL)
    {
        return list->headObject;
    }
    else
    {
        return OBJ_TO_LINK(list, object)->nextObject;
    }
}

ARM_FUNC void * NNS_FndGetPrevListObject(NNSFndList* list, void* object)
{
    if (object == NULL)
    {
        return list->tailObject;
    }
    else
    {
        return OBJ_TO_LINK(list, object)->prevObject;
    }
}