Nyx Node
Loading...
Searching...
No Matches
json_list.c
1/* NyxNode
2 * Author: Jérôme ODIER <jerome.odier@lpsc.in2p3.fr>
3 * SPDX-License-Identifier: GPL-2.0-only (Mongoose backend) or GPL-3.0+
4 */
5
6/*--------------------------------------------------------------------------------------------------------------------*/
7
8#include "../nyx_node_internal.h"
9
10/*--------------------------------------------------------------------------------------------------------------------*/
11
12typedef struct nyx_list_node_s
13{
14 nyx_object_t *value;
15
16 struct nyx_list_node_s *next;
17
18} node_t;
19
20/*--------------------------------------------------------------------------------------------------------------------*/
21
22static void internal_list_clear(
23 nyx_list_t *object
24);
25
26/*--------------------------------------------------------------------------------------------------------------------*/
27
28nyx_list_t *nyx_list_new(void)
29{
30 /*----------------------------------------------------------------------------------------------------------------*/
31
32 nyx_list_t *object = nyx_memory_alloc(sizeof(nyx_list_t));
33
34 /*----------------------------------------------------------------------------------------------------------------*/
35
36 object->base = NYX_OBJECT(NYX_TYPE_LIST);
37
38 /*----------------------------------------------------------------------------------------------------------------*/
39
40 object->head = NULL;
41 object->tail = NULL;
42
43 /*----------------------------------------------------------------------------------------------------------------*/
44
45 return object;
46}
47
48/*--------------------------------------------------------------------------------------------------------------------*/
49
50void nyx_list_free(nyx_list_t *object)
51{
52 internal_list_clear(object);
53
54 nyx_memory_free(object);
55}
56
57/*--------------------------------------------------------------------------------------------------------------------*/
58
59static void internal_list_clear(nyx_list_t *object)
60{
61 /*----------------------------------------------------------------------------------------------------------------*/
62
63 for(node_t *node = object->head; node != NULL;)
64 {
65 /*------------------------------------------------------------------------------------------------------------*/
66
67 node_t *temp = node;
68
69 node = node->next;
70
71 /*------------------------------------------------------------------------------------------------------------*/
72
73 nyx_object_free(temp->value);
74
75 nyx_memory_free(temp);
76
77 /*------------------------------------------------------------------------------------------------------------*/
78 }
79
80 /*----------------------------------------------------------------------------------------------------------------*/
81
82 object->head = NULL;
83 object->tail = NULL;
84
85 /*----------------------------------------------------------------------------------------------------------------*/
86}
87
88/*--------------------------------------------------------------------------------------------------------------------*/
89
90void nyx_list_clear(nyx_list_t *object)
91{
92 internal_list_clear(object);
93}
94
95/*--------------------------------------------------------------------------------------------------------------------*/
96
97void nyx_list_del(nyx_list_t *object, size_t idx)
98{
99 /*----------------------------------------------------------------------------------------------------------------*/
100
101 for(node_t *prev_node = NULL, *curr_node = object->head; curr_node != NULL; prev_node = curr_node, curr_node = curr_node->next, idx--)
102 {
103 if(idx == 0)
104 {
105 /*--------------------------------------------------------------------------------------------------------*/
106
107 if(prev_node == NULL)
108 {
109 object->head = curr_node->next;
110 }
111 else
112 {
113 prev_node->next = curr_node->next;
114 }
115
116 /*--------------------------------------------------------------------------------------------------------*/
117
118 nyx_object_free(curr_node->value);
119
120 nyx_memory_free(curr_node);
121
122 /*--------------------------------------------------------------------------------------------------------*/
123
124 break;
125 }
126 }
127
128 /*----------------------------------------------------------------------------------------------------------------*/
129}
130
131/*--------------------------------------------------------------------------------------------------------------------*/
132
133bool nyx_list_iterate(nyx_list_iter_t *iter, size_t *idx, nyx_object_t **object)
134{
135 if(iter->head != NULL)
136 {
137 if(idx != NULL) {
138 *idx = iter->idx;
139 }
140
141 if(object != NULL) {
142 *object = iter->head->value;
143 }
144
145 iter->idx += 0x0000000000001;
146 iter->head = iter->head->next;
147
148 return true;
149 }
150
151 return false;
152}
153
154/*--------------------------------------------------------------------------------------------------------------------*/
155
156nyx_object_t *nyx_list_get(const nyx_list_t *object, size_t idx)
157{
158 /*----------------------------------------------------------------------------------------------------------------*/
159
160 for(node_t *curr_node = object->head; curr_node != NULL; curr_node = curr_node->next, idx--)
161 {
162 if(idx == 0)
163 {
164 return curr_node->value;
165 }
166 }
167
168 /*----------------------------------------------------------------------------------------------------------------*/
169
170 return NULL;
171}
172
173/*--------------------------------------------------------------------------------------------------------------------*/
174
175bool nyx_list_set(nyx_list_t *object, size_t idx, void *value)
176{
177 /*----------------------------------------------------------------------------------------------------------------*/
178
179 if(((nyx_object_t *) value)->magic != NYX_OBJECT_MAGIC)
180 {
181 NYX_LOG_FATAL("Invalid object");
182 }
183
184 /*----------------------------------------------------------------------------------------------------------------*/
185
186 ((nyx_object_t *) value)->parent = (nyx_object_t *) object;
187
188 /*----------------------------------------------------------------------------------------------------------------*/
189
190 bool modified = true;
191
192 for(node_t *curr_node = object->head; curr_node != NULL; curr_node = curr_node->next, idx--)
193 {
194 if(idx == 0)
195 {
196 modified = !nyx_object_equal(curr_node->value, value);
197
198 nyx_object_free(curr_node->value);
199
200 curr_node->value = value;
201
202 goto _ok;
203 }
204 }
205
206 /*----------------------------------------------------------------------------------------------------------------*/
207
208 node_t *node = nyx_memory_alloc(sizeof(node_t));
209
210 node->value = value;
211 node->next = NULL;
212
213 /*----------------------------------------------------------------------------------------------------------------*/
214
215 if(object->head == NULL)
216 {
217 object->head = node;
218 object->tail = node;
219 }
220 else
221 {
222 object->tail->next = node;
223 object->tail /*-*/ = node;
224 }
225
226 /*----------------------------------------------------------------------------------------------------------------*/
227_ok:
228 return modified;
229}
230
231/*--------------------------------------------------------------------------------------------------------------------*/
232
233size_t nyx_list_size(const nyx_list_t *object)
234{
235 size_t result = 0;
236
237 /*----------------------------------------------------------------------------------------------------------------*/
238
239 for(node_t *node = object->head; node != NULL; node = node->next, result++) { /* NOSONAR */ };
240
241 /*----------------------------------------------------------------------------------------------------------------*/
242
243 return result;
244}
245
246/*--------------------------------------------------------------------------------------------------------------------*/
247
248str_t nyx_list_to_string(const nyx_list_t *object)
249{
250 nyx_string_builder_t *sb = nyx_string_builder_new();
251
252 nyx_string_builder_append(sb, NYX_SB_NO_ESCAPE, "[");
253
254 for(node_t *curr_node = object->head; curr_node != NULL; curr_node = curr_node->next)
255 {
256 /*----------------------------------------------------------------------------------------------------*/
257
258 str_t curr_node_val = nyx_object_to_string(curr_node->value);
259
260 nyx_string_builder_append(sb, NYX_SB_NO_ESCAPE, curr_node_val);
261
262 nyx_memory_free(curr_node_val);
263
264 /*----------------------------------------------------------------------------------------------------*/
265
266 if(curr_node->next != NULL)
267 {
268 nyx_string_builder_append(sb, NYX_SB_NO_ESCAPE, ",");
269 }
270 /*----------------------------------------------------------------------------------------------------*/
271 }
272
273 nyx_string_builder_append(sb, NYX_SB_NO_ESCAPE, "]");
274
275 str_t result = nyx_string_builder_to_string(sb);
276
277 nyx_string_builder_free(sb);
278
279 return result;
280}
281
282/*--------------------------------------------------------------------------------------------------------------------*/
#define NYX_LOG_FATAL(fmt,...)
Logs a fatal message.
Definition nyx_node.h:207
__NYX_NULLABLE__ buff_t nyx_memory_alloc(__NYX_ZEROABLE__ size_t size)
Similar to libc malloc except that a memory overflow causes the node to stop.
__NYX_ZEROABLE__ size_t nyx_memory_free(__NYX_NULLABLE__ buff_t buff)
Similar to libc free except that it returns the amount of memory freed.
#define str_t
Alias for char *.
Definition nyx_node.h:70
#define NYX_OBJECT_MAGIC
Magic number for identifying JSON objects.
Definition nyx_node.h:401
@ NYX_TYPE_LIST
List object.
Definition nyx_node.h:427
Struct describing a JSON list iterator.
Definition nyx_node.h:1402
struct nyx_list_node_s * head
Next JSON object to visit.
Definition nyx_node.h:1405
size_t idx
Current zero-based iteration index.
Definition nyx_node.h:1403
Struct describing a JSON list object.
Struct describing a JSON object.