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
12static void internal_list_clear(
13 nyx_list_t *object
14);
15
16/*--------------------------------------------------------------------------------------------------------------------*/
17
19{
20 /*----------------------------------------------------------------------------------------------------------------*/
21
22 nyx_list_t *object = nyx_memory_alloc(sizeof(nyx_list_t));
23
24 /*----------------------------------------------------------------------------------------------------------------*/
25
26 object->base = NYX_OBJECT(NYX_TYPE_LIST);
27
28 /*----------------------------------------------------------------------------------------------------------------*/
29
30 object->head = NULL;
31 object->tail = NULL;
32
33 /*----------------------------------------------------------------------------------------------------------------*/
34
35 return object;
36}
37
38/*--------------------------------------------------------------------------------------------------------------------*/
39
40void nyx_list_free(nyx_list_t *object)
41{
42 internal_list_clear(object);
43
44 nyx_memory_free(object);
45}
46
47/*--------------------------------------------------------------------------------------------------------------------*/
48
49static void internal_list_clear(nyx_list_t *object)
50{
51 /*----------------------------------------------------------------------------------------------------------------*/
52
53 for(nyx_list_node_t *node = object->head; node != NULL;)
54 {
55 /*------------------------------------------------------------------------------------------------------------*/
56
57 nyx_list_node_t *temp = node;
58
59 node = node->next;
60
61 /*------------------------------------------------------------------------------------------------------------*/
62
63 temp->value->parent = NULL;
64
65 nyx_object_unref(temp->value);
66
67 nyx_memory_free(temp);
68
69 /*------------------------------------------------------------------------------------------------------------*/
70 }
71
72 /*----------------------------------------------------------------------------------------------------------------*/
73
74 object->head = NULL;
75 object->tail = NULL;
76
77 /*----------------------------------------------------------------------------------------------------------------*/
78}
79
80/*--------------------------------------------------------------------------------------------------------------------*/
81
83{
84 internal_list_clear(object);
85}
86
87/*--------------------------------------------------------------------------------------------------------------------*/
88
89void nyx_list_del(nyx_list_t *object, size_t idx)
90{
91 /*----------------------------------------------------------------------------------------------------------------*/
92
93 for(nyx_list_node_t *prev_node = NULL, *curr_node = object->head; curr_node != NULL; prev_node = curr_node, curr_node = curr_node->next, idx--)
94 {
95 if(idx == 0)
96 {
97 /*--------------------------------------------------------------------------------------------------------*/
98
99 if(prev_node == NULL)
100 {
101 object->head = curr_node->next;
102 }
103 else
104 {
105 prev_node->next = curr_node->next;
106 }
107
108 /*--------------------------------------------------------------------------------------------------------*/
109
110 if(curr_node == object->tail)
111 {
112 object->tail = prev_node;
113 }
114
115 /*--------------------------------------------------------------------------------------------------------*/
116
117 curr_node->value->parent = NULL;
118
119 nyx_object_unref(curr_node->value);
120
121 nyx_memory_free(curr_node);
122
123 /*--------------------------------------------------------------------------------------------------------*/
124
125 break;
126 }
127 }
128
129 /*----------------------------------------------------------------------------------------------------------------*/
130}
131
132/*--------------------------------------------------------------------------------------------------------------------*/
133
134bool nyx_list_iterate(nyx_list_iter_t *iter, size_t *idx, nyx_object_t **object)
135{
136 if(iter->head != NULL)
137 {
138 if(idx != NULL) {
139 *idx = iter->idx;
140 }
141
142 if(object != NULL) {
143 *object = iter->head->value;
144 }
145
146 iter->idx += 0x0000000000001;
147 iter->head = iter->head->next;
148
149 return true;
150 }
151
152 return false;
153}
154
155/*--------------------------------------------------------------------------------------------------------------------*/
156
157nyx_object_t *nyx_list_get(const nyx_list_t *object, size_t idx)
158{
159 /*----------------------------------------------------------------------------------------------------------------*/
160
161 for(nyx_list_node_t *curr_node = object->head; curr_node != NULL; curr_node = curr_node->next, idx--)
162 {
163 if(idx == 0)
164 {
165 return curr_node->value;
166 }
167 }
168
169 /*----------------------------------------------------------------------------------------------------------------*/
170
171 return NULL;
172}
173
174/*--------------------------------------------------------------------------------------------------------------------*/
175
176bool nyx_list_set(nyx_list_t *object, size_t idx, void *value)
177{
178 /*----------------------------------------------------------------------------------------------------------------*/
179
180 if(!NYX_OBJECT_CHECK_MAGIC(value))
181 {
182 NYX_LOG_FATAL("Invalid object");
183 }
184
185 /*----------------------------------------------------------------------------------------------------------------*/
186
187 if(((nyx_object_t *) value)->parent != NULL)
188 {
189 NYX_LOG_ERROR("Object already has a parent");
190
191 return false;
192 }
193
194 for(nyx_object_t *parent = (nyx_object_t *) object; parent != NULL; parent = parent->parent)
195 {
196 if(parent == (nyx_object_t *) value)
197 {
198 NYX_LOG_ERROR("An object cannot be its own parent");
199
200 return false;
201 }
202 }
203
204 /*----------------------------------------------------------------------------------------------------------------*/
205
206 bool modified = true;
207
208 for(nyx_list_node_t *curr_node = /* NOSONAR */ object->head; curr_node != NULL; curr_node = curr_node->next, idx--)
209 {
210 if(idx == 0)
211 {
212 modified = !nyx_object_equal(curr_node->value, value);
213
214 curr_node->value->parent = NULL;
215
216 nyx_object_ref(/*-*/ value /*-*/);
217 nyx_object_unref(curr_node->value);
218
219 curr_node->value = value;
220
221 goto _ok;
222 }
223 }
224
225 /*----------------------------------------------------------------------------------------------------------------*/
226
227 nyx_list_node_t *node = nyx_memory_alloc(sizeof(nyx_list_node_t));
228
229 nyx_object_ref(value);
230
231 node->value = value;
232 node->next = NULL;
233
234 /*----------------------------------------------------------------------------------------------------------------*/
235
236 if(object->head == NULL)
237 {
238 object->head = node;
239 object->tail = node;
240 }
241 else
242 {
243 object->tail->next = node;
244 object->tail /*-*/ = node;
245 }
246
247 /*----------------------------------------------------------------------------------------------------------------*/
248_ok:
249 ((nyx_object_t *) value)->parent = (nyx_object_t *) object;
250
251 return modified;
252}
253
254/*--------------------------------------------------------------------------------------------------------------------*/
255
256size_t nyx_list_size(const nyx_list_t *object)
257{
258 size_t result = 0;
259
260 /*----------------------------------------------------------------------------------------------------------------*/
261
262 for(nyx_list_node_t *node = object->head; node != NULL; node = node->next, result++) { /* NOSONAR */ };
263
264 /*----------------------------------------------------------------------------------------------------------------*/
265
266 return result;
267}
268
269/*--------------------------------------------------------------------------------------------------------------------*/
270
272{
273 nyx_string_builder_t *sb = nyx_string_builder_new();
274
275 /**/ nyx_string_builder_append(sb, NYX_SB_NO_ESCAPE, "[");
276 /**/
277 /**/ for(nyx_list_node_t *curr_node = object->head; curr_node != NULL; curr_node = curr_node->next)
278 /**/ {
279 /**/ /*----------------------------------------------------------------------------------------------------*/
280 /**/
281 /**/ str_t curr_node_val = nyx_object_to_string(curr_node->value);
282 /**/
283 /**/ nyx_string_builder_append(sb, NYX_SB_NO_ESCAPE, curr_node_val);
284 /**/
285 /**/ nyx_memory_free(curr_node_val);
286 /**/
287 /**/ /*----------------------------------------------------------------------------------------------------*/
288 /**/
289 /**/ if(curr_node->next != NULL)
290 /**/ {
291 /**/ nyx_string_builder_append(sb, NYX_SB_NO_ESCAPE, ",");
292 /**/ }
293 /**/ /*----------------------------------------------------------------------------------------------------*/
294 /**/ }
295 /**/
296 /**/ nyx_string_builder_append(sb, NYX_SB_NO_ESCAPE, "]");
297
298 str_t result = nyx_string_builder_to_string(sb);
299
300 nyx_string_builder_free(sb);
301
302 return result;
303}
304
305/*--------------------------------------------------------------------------------------------------------------------*/
struct nyx_list_node_s * head
Next JSON object to visit.
Definition nyx_node.h:1446
size_t idx
Current zero-based iteration index.
Definition nyx_node.h:1444
str_t nyx_list_to_string(const nyx_list_t *object)
Returns a string representing the provided JSON list object.
Definition json_list.c:271
void nyx_list_del(nyx_list_t *object, size_t idx)
Deletes the entry at the provided index.
Definition json_list.c:89
bool nyx_list_iterate(nyx_list_iter_t *iter, size_t *idx, nyx_object_t **object)
Iterates over a JSON list object.
Definition json_list.c:134
nyx_list_t * nyx_list_new(void)
Allocates a new JSON list.
Definition json_list.c:18
nyx_object_t * nyx_list_get(const nyx_list_t *object, size_t idx)
Gets the JSON object at the provided index.
Definition json_list.c:157
size_t nyx_list_size(const nyx_list_t *object)
Gets the number of items in the provided JSON list object.
Definition json_list.c:256
void nyx_list_clear(nyx_list_t *object)
Clears the content of the provided JSON list object.
Definition json_list.c:82
Struct describing a JSON list iterator.
Definition nyx_node.h:1443
Struct describing a JSON list object.
#define NYX_LOG_FATAL(fmt,...)
Logs a fatal message.
Definition nyx_node.h:208
#define NYX_LOG_ERROR(fmt,...)
Logs an error message.
Definition nyx_node.h:219
__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
@ NYX_TYPE_LIST
List object.
Definition nyx_node.h:439
Struct describing a JSON object.