/src/fwupd/libfwupd/fwupd-json-array.c
Line | Count | Source |
1 | | /* |
2 | | * Copyright 2025 Richard Hughes <richard@hughsie.com> |
3 | | * |
4 | | * SPDX-License-Identifier: LGPL-2.1-or-later |
5 | | */ |
6 | | |
7 | | #include "config.h" |
8 | | |
9 | | #include "fwupd-error.h" |
10 | | #include "fwupd-json-array-private.h" |
11 | | #include "fwupd-json-common-private.h" |
12 | | #include "fwupd-json-node-private.h" |
13 | | #include "fwupd-json-object-private.h" |
14 | | |
15 | | /** |
16 | | * FwupdJsonArray: |
17 | | * |
18 | | * A JSON array. |
19 | | * |
20 | | * See also: [struct@FwupdJsonObject] [struct@FwupdJsonNode] |
21 | | */ |
22 | | |
23 | | struct FwupdJsonArray { |
24 | | grefcount refcount; |
25 | | GPtrArray *nodes; /* of FwupdJsonNode */ |
26 | | }; |
27 | | |
28 | | /** |
29 | | * fwupd_json_array_new: (skip): |
30 | | * |
31 | | * Creates a new JSON array. |
32 | | * |
33 | | * Returns: (transfer full): a #FwupdJsonArray |
34 | | * |
35 | | * Since: 2.1.1 |
36 | | **/ |
37 | | FwupdJsonArray * |
38 | | fwupd_json_array_new(void) |
39 | 10.9k | { |
40 | 10.9k | FwupdJsonArray *self = g_new0(FwupdJsonArray, 1); |
41 | 10.9k | g_ref_count_init(&self->refcount); |
42 | 10.9k | self->nodes = g_ptr_array_new_with_free_func((GDestroyNotify)fwupd_json_node_unref); |
43 | 10.9k | return self; |
44 | 10.9k | } |
45 | | |
46 | | /** |
47 | | * fwupd_json_array_ref: (skip): |
48 | | * @self: a #FwupdJsonArray |
49 | | * |
50 | | * Increases the reference count of a JSON array. |
51 | | * |
52 | | * Returns: (transfer full): a #FwupdJsonArray |
53 | | * |
54 | | * Since: 2.1.1 |
55 | | **/ |
56 | | FwupdJsonArray * |
57 | | fwupd_json_array_ref(FwupdJsonArray *self) |
58 | 15.1k | { |
59 | 15.1k | g_return_val_if_fail(self != NULL, NULL); |
60 | 15.1k | g_ref_count_inc(&self->refcount); |
61 | 15.1k | return self; |
62 | 15.1k | } |
63 | | |
64 | | /** |
65 | | * fwupd_json_array_unref: (skip): |
66 | | * @self: a #FwupdJsonArray |
67 | | * |
68 | | * Decreases the reference count of a JSON array. |
69 | | * |
70 | | * Returns: (transfer none): a #FwupdJsonArray, or %NULL |
71 | | * |
72 | | * Since: 2.1.1 |
73 | | **/ |
74 | | FwupdJsonArray * |
75 | | fwupd_json_array_unref(FwupdJsonArray *self) |
76 | 26.1k | { |
77 | 26.1k | g_return_val_if_fail(self != NULL, NULL); |
78 | 26.1k | if (!g_ref_count_dec(&self->refcount)) |
79 | 15.1k | return self; |
80 | 10.9k | g_ptr_array_unref(self->nodes); |
81 | 10.9k | g_free(self); |
82 | 10.9k | return NULL; |
83 | 26.1k | } |
84 | | |
85 | | /** |
86 | | * fwupd_json_array_get_size: |
87 | | * @self: a #FwupdJsonArray |
88 | | * |
89 | | * Gets the size of the JSON array. |
90 | | * |
91 | | * Returns: number of elements added |
92 | | * |
93 | | * Since: 2.1.1 |
94 | | **/ |
95 | | guint |
96 | | fwupd_json_array_get_size(FwupdJsonArray *self) |
97 | 20.7k | { |
98 | 20.7k | g_return_val_if_fail(self != NULL, G_MAXUINT); |
99 | 20.7k | return self->nodes->len; |
100 | 20.7k | } |
101 | | |
102 | | /** |
103 | | * fwupd_json_array_get_node: (skip): |
104 | | * @self: a #FwupdJsonArray |
105 | | * @idx: index into the array |
106 | | * @error: (nullable): optional return location for an error |
107 | | * |
108 | | * Gets a node from a JSON array. |
109 | | * |
110 | | * Returns: (transfer full): a #FwupdJsonObject, or %NULL for error |
111 | | * |
112 | | * Since: 2.1.1 |
113 | | **/ |
114 | | FwupdJsonNode * |
115 | | fwupd_json_array_get_node(FwupdJsonArray *self, guint idx, GError **error) |
116 | 0 | { |
117 | 0 | g_return_val_if_fail(self != NULL, NULL); |
118 | 0 | g_return_val_if_fail(error == NULL || *error == NULL, NULL); |
119 | | |
120 | | /* sanity check */ |
121 | 0 | if (idx >= self->nodes->len) { |
122 | 0 | g_set_error(error, |
123 | 0 | FWUPD_ERROR, |
124 | 0 | FWUPD_ERROR_NOT_FOUND, |
125 | 0 | "index %u is larger than array size", |
126 | 0 | idx); |
127 | 0 | return NULL; |
128 | 0 | } |
129 | 0 | return fwupd_json_node_ref(g_ptr_array_index(self->nodes, idx)); |
130 | 0 | } |
131 | | |
132 | | /** |
133 | | * fwupd_json_array_get_raw: (skip): |
134 | | * @self: a #FwupdJsonArray |
135 | | * @idx: index into the array |
136 | | * @error: (nullable): optional return location for an error |
137 | | * |
138 | | * Gets a raw value from a JSON array. |
139 | | * |
140 | | * Returns: a string, or %NULL for error |
141 | | * |
142 | | * Since: 2.1.1 |
143 | | **/ |
144 | | GRefString * |
145 | | fwupd_json_array_get_raw(FwupdJsonArray *self, guint idx, GError **error) |
146 | 0 | { |
147 | 0 | g_autoptr(FwupdJsonNode) json_node = NULL; |
148 | |
|
149 | 0 | g_return_val_if_fail(self != NULL, NULL); |
150 | 0 | g_return_val_if_fail(error == NULL || *error == NULL, NULL); |
151 | | |
152 | 0 | json_node = fwupd_json_array_get_node(self, idx, error); |
153 | 0 | if (json_node == NULL) |
154 | 0 | return NULL; |
155 | 0 | return fwupd_json_node_get_raw(json_node, error); |
156 | 0 | } |
157 | | |
158 | | /** |
159 | | * fwupd_json_array_get_string: (skip): |
160 | | * @self: a #FwupdJsonArray |
161 | | * @idx: index into the array |
162 | | * @error: (nullable): optional return location for an error |
163 | | * |
164 | | * Gets a string from a JSON array. |
165 | | * |
166 | | * Returns: a string, or %NULL for error |
167 | | * |
168 | | * Since: 2.1.1 |
169 | | **/ |
170 | | GRefString * |
171 | | fwupd_json_array_get_string(FwupdJsonArray *self, guint idx, GError **error) |
172 | 0 | { |
173 | 0 | g_autoptr(FwupdJsonNode) json_node = NULL; |
174 | |
|
175 | 0 | g_return_val_if_fail(self != NULL, NULL); |
176 | 0 | g_return_val_if_fail(error == NULL || *error == NULL, NULL); |
177 | | |
178 | 0 | json_node = fwupd_json_array_get_node(self, idx, error); |
179 | 0 | if (json_node == NULL) |
180 | 0 | return NULL; |
181 | 0 | return fwupd_json_node_get_string(json_node, error); |
182 | 0 | } |
183 | | |
184 | | /** |
185 | | * fwupd_json_array_get_object: (skip): |
186 | | * @self: a #FwupdJsonArray |
187 | | * @idx: index into the array |
188 | | * @error: (nullable): optional return location for an error |
189 | | * |
190 | | * Gets an object from a JSON array. |
191 | | * |
192 | | * Returns: (transfer full): a #FwupdJsonObject, or %NULL for error |
193 | | * |
194 | | * Since: 2.1.1 |
195 | | **/ |
196 | | FwupdJsonObject * |
197 | | fwupd_json_array_get_object(FwupdJsonArray *self, guint idx, GError **error) |
198 | 0 | { |
199 | 0 | g_autoptr(FwupdJsonNode) json_node = NULL; |
200 | |
|
201 | 0 | g_return_val_if_fail(self != NULL, NULL); |
202 | 0 | g_return_val_if_fail(error == NULL || *error == NULL, NULL); |
203 | | |
204 | 0 | json_node = fwupd_json_array_get_node(self, idx, error); |
205 | 0 | if (json_node == NULL) |
206 | 0 | return NULL; |
207 | 0 | return fwupd_json_node_get_object(json_node, error); |
208 | 0 | } |
209 | | |
210 | | /** |
211 | | * fwupd_json_array_get_array: (skip): |
212 | | * @self: a #FwupdJsonArray |
213 | | * @idx: index into the array |
214 | | * @error: (nullable): optional return location for an error |
215 | | * |
216 | | * Gets another array from a JSON array. |
217 | | * |
218 | | * Returns: (transfer full): a #FwupdJsonArray, or %NULL for error |
219 | | * |
220 | | * Since: 2.1.1 |
221 | | **/ |
222 | | FwupdJsonArray * |
223 | | fwupd_json_array_get_array(FwupdJsonArray *self, guint idx, GError **error) |
224 | 0 | { |
225 | 0 | g_autoptr(FwupdJsonNode) json_node = NULL; |
226 | |
|
227 | 0 | g_return_val_if_fail(self != NULL, NULL); |
228 | 0 | g_return_val_if_fail(error == NULL || *error == NULL, NULL); |
229 | | |
230 | 0 | json_node = fwupd_json_array_get_node(self, idx, error); |
231 | 0 | if (json_node == NULL) |
232 | 0 | return NULL; |
233 | 0 | return fwupd_json_node_get_array(json_node, error); |
234 | 0 | } |
235 | | |
236 | | void |
237 | | fwupd_json_array_add_string_internal(FwupdJsonArray *self, GRefString *value) |
238 | 3.10k | { |
239 | 3.10k | g_ptr_array_add(self->nodes, fwupd_json_node_new_string_internal(value)); |
240 | 3.10k | } |
241 | | |
242 | | /** |
243 | | * fwupd_json_array_add_node: |
244 | | * @self: a #FwupdJsonArray |
245 | | * @json_node: (not nullable): string value |
246 | | * |
247 | | * Adds a node to a JSON array. |
248 | | * |
249 | | * Since: 2.1.1 |
250 | | **/ |
251 | | void |
252 | | fwupd_json_array_add_node(FwupdJsonArray *self, FwupdJsonNode *json_node) |
253 | 0 | { |
254 | 0 | g_return_if_fail(self != NULL); |
255 | 0 | g_return_if_fail(json_node != NULL); |
256 | 0 | g_ptr_array_add(self->nodes, fwupd_json_node_ref(json_node)); |
257 | 0 | } |
258 | | |
259 | | /** |
260 | | * fwupd_json_array_add_string: |
261 | | * @self: a #FwupdJsonArray |
262 | | * @value: (not nullable): string value |
263 | | * |
264 | | * Adds a string to a JSON array. |
265 | | * |
266 | | * Since: 2.1.1 |
267 | | **/ |
268 | | void |
269 | | fwupd_json_array_add_string(FwupdJsonArray *self, const gchar *value) |
270 | 0 | { |
271 | 0 | g_return_if_fail(self != NULL); |
272 | 0 | g_return_if_fail(value != NULL); |
273 | 0 | g_ptr_array_add(self->nodes, fwupd_json_node_new_string(value)); |
274 | 0 | } |
275 | | |
276 | | void |
277 | | fwupd_json_array_add_raw_internal(FwupdJsonArray *self, GRefString *value) |
278 | 5.84k | { |
279 | 5.84k | g_ptr_array_add(self->nodes, fwupd_json_node_new_raw_internal(value)); |
280 | 5.84k | } |
281 | | |
282 | | /** |
283 | | * fwupd_json_array_add_raw: |
284 | | * @self: a #FwupdJsonArray |
285 | | * @value: (not nullable): string value |
286 | | * |
287 | | * Adds a raw value to a JSON array. |
288 | | * |
289 | | * Since: 2.1.1 |
290 | | **/ |
291 | | void |
292 | | fwupd_json_array_add_raw(FwupdJsonArray *self, const gchar *value) |
293 | 0 | { |
294 | 0 | g_return_if_fail(self != NULL); |
295 | 0 | g_return_if_fail(value != NULL); |
296 | 0 | g_ptr_array_add(self->nodes, fwupd_json_node_new_raw(value)); |
297 | 0 | } |
298 | | |
299 | | /** |
300 | | * fwupd_json_array_add_object: |
301 | | * @self: a #FwupdJsonArray |
302 | | * @json_obj: a #FwupdJsonObject |
303 | | * |
304 | | * Adds an object to a JSON array. |
305 | | * |
306 | | * Since: 2.1.1 |
307 | | **/ |
308 | | void |
309 | | fwupd_json_array_add_object(FwupdJsonArray *self, FwupdJsonObject *json_obj) |
310 | 3.97k | { |
311 | 3.97k | g_return_if_fail(self != NULL); |
312 | 3.97k | g_return_if_fail(json_obj != NULL); |
313 | 3.97k | g_ptr_array_add(self->nodes, fwupd_json_node_new_object(json_obj)); |
314 | 3.97k | } |
315 | | |
316 | | /** |
317 | | * fwupd_json_array_add_array: |
318 | | * @self: a #FwupdJsonArray |
319 | | * @json_arr: a #FwupdJsonArray |
320 | | * |
321 | | * Adds a different array to a JSON array. |
322 | | * |
323 | | * Since: 2.1.1 |
324 | | **/ |
325 | | void |
326 | | fwupd_json_array_add_array(FwupdJsonArray *self, FwupdJsonArray *json_arr) |
327 | 7.86k | { |
328 | 7.86k | g_return_if_fail(self != NULL); |
329 | 7.86k | g_return_if_fail(json_arr != NULL); |
330 | 7.86k | g_return_if_fail(self != json_arr); |
331 | 7.86k | g_ptr_array_add(self->nodes, fwupd_json_node_new_array(json_arr)); |
332 | 7.86k | } |
333 | | |
334 | | /** |
335 | | * fwupd_json_array_add_bytes: |
336 | | * @self: a #FwupdJsonArray |
337 | | * @value: (not nullable): string value |
338 | | * |
339 | | * Adds bytes to a JSON array. They will be base64 encoded as a string. |
340 | | * |
341 | | * Since: 2.1.1 |
342 | | **/ |
343 | | void |
344 | | fwupd_json_array_add_bytes(FwupdJsonArray *self, GBytes *value) |
345 | 0 | { |
346 | 0 | g_autofree gchar *b64data = NULL; |
347 | 0 | const guint8 *buf; |
348 | 0 | gsize bufsz = 0; |
349 | |
|
350 | 0 | g_return_if_fail(self != NULL); |
351 | 0 | g_return_if_fail(value != NULL); |
352 | | |
353 | 0 | buf = g_bytes_get_data(value, &bufsz); |
354 | 0 | if (buf == NULL) { |
355 | 0 | g_ptr_array_add(self->nodes, fwupd_json_node_new_string("")); |
356 | 0 | return; |
357 | 0 | } |
358 | | /* nocheck:blocked */ |
359 | 0 | b64data = g_base64_encode(buf, bufsz); |
360 | |
|
361 | 0 | g_ptr_array_add(self->nodes, fwupd_json_node_new_string(b64data)); |
362 | 0 | } |
363 | | |
364 | | /** |
365 | | * fwupd_json_array_append_string: |
366 | | * @self: a #FwupdJsonArray |
367 | | * @str: a #GString |
368 | | * @depth: current depth, where 0 is the root json_node |
369 | | * @flags: some #FwupdJsonExportFlags e.g. #FWUPD_JSON_EXPORT_FLAG_INDENT |
370 | | * |
371 | | * Appends the JSON array to existing string. |
372 | | * |
373 | | * Since: 2.1.1 |
374 | | **/ |
375 | | void |
376 | | fwupd_json_array_append_string(FwupdJsonArray *self, |
377 | | GString *str, |
378 | | guint depth, |
379 | | FwupdJsonExportFlags flags) |
380 | 4.76k | { |
381 | 4.76k | g_return_if_fail(self != NULL); |
382 | 4.76k | g_return_if_fail(str != NULL); |
383 | | |
384 | | /* start */ |
385 | 4.76k | g_string_append_c(str, '['); |
386 | 4.76k | if (flags & FWUPD_JSON_EXPORT_FLAG_INDENT) |
387 | 0 | g_string_append_c(str, '\n'); |
388 | | |
389 | 16.6k | for (guint i = 0; i < self->nodes->len; i++) { |
390 | 11.8k | FwupdJsonNode *json_node = g_ptr_array_index(self->nodes, i); |
391 | 11.8k | if (flags & FWUPD_JSON_EXPORT_FLAG_INDENT) |
392 | 0 | fwupd_json_indent(str, depth + 1); |
393 | 11.8k | fwupd_json_node_append_string(json_node, str, depth + 1, flags); |
394 | 11.8k | if (flags & FWUPD_JSON_EXPORT_FLAG_INDENT) { |
395 | 0 | if (i != self->nodes->len - 1) |
396 | 0 | g_string_append_c(str, ','); |
397 | 0 | g_string_append_c(str, '\n'); |
398 | 11.8k | } else { |
399 | 11.8k | if (i != self->nodes->len - 1) |
400 | 8.79k | g_string_append(str, ", "); |
401 | 11.8k | } |
402 | 11.8k | } |
403 | | |
404 | | /* end */ |
405 | 4.76k | if (flags & FWUPD_JSON_EXPORT_FLAG_INDENT) |
406 | 0 | fwupd_json_indent(str, depth); |
407 | 4.76k | g_string_append_c(str, ']'); |
408 | 4.76k | } |
409 | | |
410 | | /** |
411 | | * fwupd_json_array_to_string: |
412 | | * @self: a #FwupdJsonArray |
413 | | * @flags: some #FwupdJsonExportFlags e.g. #FWUPD_JSON_EXPORT_FLAG_INDENT |
414 | | * |
415 | | * Converts the JSON array to a string representation. |
416 | | * |
417 | | * Returns: (transfer full): a #GString |
418 | | * |
419 | | * Since: 2.1.1 |
420 | | **/ |
421 | | GString * |
422 | | fwupd_json_array_to_string(FwupdJsonArray *self, FwupdJsonExportFlags flags) |
423 | 0 | { |
424 | | GString *str = g_string_new(NULL); |
425 | 0 | fwupd_json_array_append_string(self, str, 0, flags); |
426 | 0 | return str; |
427 | 0 | } |