Nyx Node
Loading...
Searching...
No Matches
json_dict.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 <string.h>
9
10#include "../nyx_node_internal.h"
11
12/*--------------------------------------------------------------------------------------------------------------------*/
13
14typedef struct nyx_dict_node_s
15{
16 STR_t key;
17
18 nyx_object_t *value;
19
20 struct nyx_dict_node_s *next;
21
22} node_t;
23
24/*--------------------------------------------------------------------------------------------------------------------*/
25
26static void internal_dict_clear(
27 nyx_dict_t *object
28);
29
30/*--------------------------------------------------------------------------------------------------------------------*/
31
32nyx_dict_t *nyx_dict_new(void)
33{
34 /*----------------------------------------------------------------------------------------------------------------*/
35
36 nyx_dict_t *object = nyx_memory_alloc(sizeof(nyx_dict_t));
37
38 /*----------------------------------------------------------------------------------------------------------------*/
39
40 object->base = NYX_OBJECT(NYX_TYPE_DICT);
41
42 /*----------------------------------------------------------------------------------------------------------------*/
43
44 object->head = NULL;
45 object->tail = NULL;
46
47 /*----------------------------------------------------------------------------------------------------------------*/
48
49 return object;
50}
51
52/*--------------------------------------------------------------------------------------------------------------------*/
53
54void nyx_dict_free(nyx_dict_t *object)
55{
56 internal_dict_clear(object);
57
58 nyx_memory_free(object);
59}
60
61/*--------------------------------------------------------------------------------------------------------------------*/
62
63static void internal_dict_clear(nyx_dict_t *object)
64{
65 /*----------------------------------------------------------------------------------------------------------------*/
66
67 for(node_t *node = object->head; node != NULL;)
68 {
69 /*------------------------------------------------------------------------------------------------------------*/
70
71 node_t *temp = node;
72
73 node = node->next;
74
75 /*------------------------------------------------------------------------------------------------------------*/
76
77 nyx_object_free(temp->value);
78
79 nyx_memory_free(temp);
80
81 /*------------------------------------------------------------------------------------------------------------*/
82 }
83
84 /*----------------------------------------------------------------------------------------------------------------*/
85
86 object->head = NULL;
87 object->tail = NULL;
88
89 /*----------------------------------------------------------------------------------------------------------------*/
90}
91
92/*--------------------------------------------------------------------------------------------------------------------*/
93
94void nyx_dict_clear(nyx_dict_t *object)
95{
96 internal_dict_clear(object);
97}
98
99/*--------------------------------------------------------------------------------------------------------------------*/
100
101void nyx_dict_del(nyx_dict_t *object, STR_t key)
102{
103 /*----------------------------------------------------------------------------------------------------------------*/
104
105 for(node_t *prev_node = NULL, *curr_node = object->head; curr_node != NULL; prev_node = curr_node, curr_node = curr_node->next)
106 {
107 if(strcmp(curr_node->key, key) == 0)
108 {
109 /*--------------------------------------------------------------------------------------------------------*/
110
111 if(prev_node == NULL)
112 {
113 object->head = curr_node->next;
114 }
115 else
116 {
117 prev_node->next = curr_node->next;
118 }
119
120 /*--------------------------------------------------------------------------------------------------------*/
121
122 nyx_object_free(curr_node->value);
123
124 nyx_memory_free(curr_node);
125
126 /*--------------------------------------------------------------------------------------------------------*/
127
128 break;
129 }
130 }
131
132 /*----------------------------------------------------------------------------------------------------------------*/
133}
134
135/*--------------------------------------------------------------------------------------------------------------------*/
136
137bool nyx_dict_iterate(nyx_dict_iter_t *iter, STR_t *key, nyx_object_t **object)
138{
139 if(iter->head != NULL)
140 {
141 if(key != NULL) {
142 *key = iter->head->key;
143 }
144
145 if(object != NULL) {
146 *object = iter->head->value;
147 }
148
149 iter->idx += 0x0000000000001;
150 iter->head = iter->head->next;
151
152 return true;
153 }
154
155 return false;
156}
157
158/*--------------------------------------------------------------------------------------------------------------------*/
159
160nyx_object_t *nyx_dict_get(const nyx_dict_t *object, STR_t key)
161{
162 /*----------------------------------------------------------------------------------------------------------------*/
163
164 for(node_t *curr_node = object->head; curr_node != NULL; curr_node = curr_node->next)
165 {
166 if(strcmp(curr_node->key, key) == 0)
167 {
168 return curr_node->value;
169 }
170 }
171
172 /*----------------------------------------------------------------------------------------------------------------*/
173
174 return NULL;
175}
176
177/*--------------------------------------------------------------------------------------------------------------------*/
178
179bool nyx_dict_set(nyx_dict_t *object, STR_t key, void *value)
180{
181 /*----------------------------------------------------------------------------------------------------------------*/
182
183 if(((nyx_object_t *) value)->magic != NYX_OBJECT_MAGIC)
184 {
185 NYX_LOG_FATAL("Invalid object");
186 }
187
188 /*----------------------------------------------------------------------------------------------------------------*/
189
190 ((nyx_object_t *) value)->parent = (nyx_object_t *) object;
191
192 /*----------------------------------------------------------------------------------------------------------------*/
193
194 bool modified = true;
195
196 for(node_t *curr_node = object->head; curr_node != NULL; curr_node = curr_node->next)
197 {
198 if(strcmp(curr_node->key, key) == 0)
199 {
200 modified = !nyx_object_equal(curr_node->value, value);
201
202 nyx_object_free(curr_node->value);
203
204 curr_node->value = value;
205
206 goto _ok;
207 }
208 }
209
210 /*----------------------------------------------------------------------------------------------------------------*/
211
212 node_t *node = nyx_memory_alloc(sizeof(node_t) + strlen(key) + 1);
213
214 node->key = strcpy((str_t) (node + 1), key);
215
216 node->value = value;
217 node->next = NULL;
218
219 /*----------------------------------------------------------------------------------------------------------------*/
220
221 if(object->head == NULL)
222 {
223 object->head = node;
224 object->tail = node;
225 }
226 else
227 {
228 object->tail->next = node;
229 object->tail /*-*/ = node;
230 }
231
232 /*----------------------------------------------------------------------------------------------------------------*/
233_ok:
234 return modified;
235}
236
237/*--------------------------------------------------------------------------------------------------------------------*/
238
239size_t nyx_dict_size(const nyx_dict_t *object)
240{
241 size_t result = 0;
242
243 /*----------------------------------------------------------------------------------------------------------------*/
244
245 for(node_t *node = object->head; node != NULL; node = node->next, result++) { /* NOSONAR */ }
246
247 /*----------------------------------------------------------------------------------------------------------------*/
248
249 return result;
250}
251
252/*--------------------------------------------------------------------------------------------------------------------*/
253
254str_t nyx_dict_to_string(const nyx_dict_t *object)
255{
256 nyx_string_builder_t *sb = nyx_string_builder_new();
257
258 nyx_string_builder_append(sb, NYX_SB_NO_ESCAPE, "{");
259
260 for(node_t *curr_node = object->head; curr_node != NULL; curr_node = curr_node->next)
261 {
262 /*----------------------------------------------------------------------------------------------------*/
263
264 str_t curr_node_val = nyx_object_to_string(curr_node->value);
265
266 nyx_string_builder_append(sb, NYX_SB_NO_ESCAPE, "\"");
267 nyx_string_builder_append(sb, NYX_SB_ESCAPE_JSON, curr_node->key);
268 nyx_string_builder_append(sb, NYX_SB_NO_ESCAPE, "\"", ":", curr_node_val);
269
270 nyx_memory_free(curr_node_val);
271
272 /*----------------------------------------------------------------------------------------------------*/
273
274 if(curr_node->next != NULL)
275 {
276 nyx_string_builder_append(sb, NYX_SB_NO_ESCAPE, ",");
277 }
278
279 /*----------------------------------------------------------------------------------------------------*/
280 }
281
282 nyx_string_builder_append(sb, NYX_SB_NO_ESCAPE, "}");
283
284 str_t result = nyx_string_builder_to_string(sb);
285
286 nyx_string_builder_free(sb);
287
288 return result;
289}
290
291/*--------------------------------------------------------------------------------------------------------------------*/
#define NYX_LOG_FATAL(fmt,...)
Logs a fatal message.
Definition nyx_node.h:207
#define STR_t
Alias for const char *.
Definition nyx_node.h:71
__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_DICT
Dict object.
Definition nyx_node.h:426
Struct describing a JSON dict iterator.
Definition nyx_node.h:1162
size_t idx
Current zero-based iteration index.
Definition nyx_node.h:1163
struct nyx_dict_node_s * head
Next JSON object to visit.
Definition nyx_node.h:1165
Struct describing a JSON dict object.
Struct describing a JSON object.