]> git.lizzy.rs Git - nothing.git/blob - src/system/lt.c
(#477) Replace all instances of malloc with nth_alloc
[nothing.git] / src / system / lt.c
1 #include <assert.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4
5 #include "lt.h"
6 #include "lt/lt_slot.h"
7 #include "system/error.h"
8 #include "system/nth_alloc.h"
9
10 #define INITIAL_FRAME_BUFFER_SIZE 16
11
12 struct Lt
13 {
14     Lt_slot **frames;
15     size_t capacity;
16     size_t size;
17 };
18
19 Lt *create_lt()
20 {
21     Lt *lt = nth_alloc(sizeof(Lt));
22     if(lt == NULL) {
23         throw_error(ERROR_TYPE_LIBC);
24         goto nth_alloc_lt_fail;
25     }
26
27     lt->frames = nth_alloc(sizeof(Lt_slot*) * INITIAL_FRAME_BUFFER_SIZE);
28     if (lt->frames == NULL) {
29         throw_error(ERROR_TYPE_LIBC);
30         goto nth_alloc_lt_slots_fail;
31     }
32
33     lt->capacity = INITIAL_FRAME_BUFFER_SIZE;
34     lt->size = 0;
35
36     return lt;
37
38 nth_alloc_lt_slots_fail:
39     free(lt);
40 nth_alloc_lt_fail:
41     return NULL;
42 }
43
44 void destroy_lt(Lt *lt)
45 {
46     assert(lt);
47
48     while (lt->size-- > 0) {
49         if (lt->frames[lt->size]) {
50             destroy_lt_slot(lt->frames[lt->size]);
51         }
52     }
53
54     free(lt->frames);
55     free(lt);
56 }
57
58 void *lt_push(Lt *lt, void *resource, Lt_destroy resource_destroy)
59 {
60     assert(lt);
61     assert(resource_destroy);
62     assert(lt != resource);
63
64     if (resource == NULL) {
65         return NULL;
66     }
67
68     if (lt->size >= lt->capacity) {
69         lt->capacity *= 2;
70         if ((lt->frames = realloc(lt->frames, sizeof(Lt_slot*) * lt->capacity)) == NULL) {
71             throw_error(ERROR_TYPE_LIBC);
72             return NULL;
73         }
74     }
75
76     if ((lt->frames[lt->size++] = create_lt_slot(resource, resource_destroy)) == NULL) {
77         return NULL;
78     }
79
80     return resource;
81 }
82
83 void* lt_reset(Lt *lt, void *old_resource, void *new_resource)
84 {
85     assert(lt);
86     assert(old_resource);
87     assert(new_resource);
88     assert(old_resource != new_resource);
89
90     for (size_t i = 0; i < lt->size; ++i) {
91         if (lt->frames[i] && lt_slot_contains_resource(lt->frames[i], old_resource)) {
92             lt_slot_reset_resource(lt->frames[i], new_resource);
93             return new_resource;
94         }
95     }
96
97     return old_resource;
98 }
99
100 void *lt_release(Lt *lt, void *resource)
101 {
102     assert(lt);
103     assert(resource);
104
105     for (size_t i = 0; i < lt->size; ++i) {
106         if (lt->frames[i] && lt_slot_contains_resource(lt->frames[i], resource)) {
107             release_lt_slot(lt->frames[i]);
108             lt->frames[i] = NULL;
109             return resource;
110         }
111     }
112
113     return resource;
114 }
115
116 void *lt_replace(Lt *lt, void *old_resource, void *new_resource)
117 {
118     assert(lt);
119     assert(old_resource);
120     assert(new_resource);
121
122     for (size_t i = 0; i < lt->size; ++i) {
123         if (lt->frames[i] && lt_slot_contains_resource(lt->frames[i], old_resource)) {
124             lt_slot_replace_resource(lt->frames[i], new_resource);
125             return new_resource;
126         }
127     }
128
129     return old_resource;
130 }