aboutsummaryrefslogtreecommitdiff
path: root/array.c
blob: b0db3f5819b7b4c95a6156d29da5c6ee50a75c55 (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
#include "bowl.h"
#include "array.h"
#include "utils.h"

#include <malloc.h>


err_t array_malloc(struct bowl *self, size_t size)
{
    CHECK(self, INVALID_STATE)
    CHECK((size > 0), INVALID_PARAMS)

    struct bowl_arr *arr = malloc(sizeof(struct bowl_arr));
    CHECK(arr, MALLOC_FAILED)
    arr->size = 2;
    arr->used = 0;

    struct bowl **ptr = calloc(sizeof(struct bowl *), arr->size);
    CHECK(ptr, MALLOC_FAILED)
    arr->ptr = ptr;

    self->_pl.array = arr;
    return OK;
}

err_t array_insert(struct bowl *self, struct bowl *new)
{
    CHECK(self, INVALID_PARAMS)
    CHECK(new, INVALID_PARAMS)

    struct bowl_arr *arr = self->_pl.array;
    CHECK(arr, INVALID_STATE)

    err_t e = _array_rescale((void ***) &arr->ptr, &arr->size, arr->used);
    if(e) return e;

    arr->ptr[arr->used++] = new;
    return OK;
}

err_t array_insert_key(struct bowl *self, size_t idx, struct bowl *new)
{
    CHECK(self, INVALID_PARAMS)
    CHECK(new, INVALID_PARAMS)

    struct bowl_arr *arr = self->_pl.array;
    CHECK(arr, INVALID_STATE)
    CHECK((idx < arr->used), INVALID_PARAMS)

    err_t e = _array_rescale((void ***) &arr->ptr, &arr->size, arr->used);
    if(e) return e;

    for(int i = idx + 1; idx < arr->used; i++)
        arr->ptr[i] = arr->ptr[i - 1];

    arr->ptr[idx] = new;
    arr->used++;

    return OK;
}

err_t array_swap_key(struct bowl *self, size_t idx, struct bowl *new, struct bowl **old)
{
    CHECK(self, INVALID_PARAMS)
    CHECK(new, INVALID_PARAMS)

    struct bowl_arr *arr = self->_pl.array;
    CHECK(arr, INVALID_STATE)

    (*old) = NULL; // Explicitly set to NULL if no such key
    CHECK((idx < arr->used), INVALID_PARAMS)

    (*old) = arr->ptr[idx];
    arr->ptr[idx] = new;

    return OK;
}

err_t array_remove(struct bowl *self, struct bowl *to_remove)
{
    CHECK(self, INVALID_PARAMS)
    CHECK(to_remove, INVALID_PARAMS)

    struct bowl_arr *arr = self->_pl.array;
    CHECK(arr, INVALID_STATE)

    size_t idx;
    err_t e = _array_search((void **) arr->ptr, arr->size, &idx, to_remove);
    if(e) return e;

    e = _array_remove((void **) arr->ptr, idx, arr->size, NULL);
    return e;
}

err_t array_remove_key(struct bowl *self, size_t idx, struct bowl **out)
{
    CHECK(self, INVALID_PARAMS);
    struct bowl_arr *arr = self->_pl.array;
    CHECK(arr, INVALID_STATE)
    CHECK((idx < arr->used), INVALID_PARAMS)

    err_t e = _array_remove((void **) arr->ptr, idx, arr->size, (void **) out);
    return e;
}

err_t array_free(struct bowl *self)
{
    CHECK(self, INVALID_PARAMS)
    struct bowl_arr *arr = self->_pl.array;
    CHECK(arr, INVALID_STATE)

    for(int i = 0; i < arr->used; i++) {
        err_t e = bowl_free(arr->ptr[i]);
        if(e) break;
    }

    free(arr->ptr);
    free(arr);
    return OK;
}