/src/fwupd/libfwupd/fwupd-json-object.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 | | * FwupdJsonObject: |
17 | | * |
18 | | * A JSON object. |
19 | | * |
20 | | * See also: [struct@FwupdJsonArray] [struct@FwupdJsonNode] |
21 | | */ |
22 | | |
23 | | typedef struct { |
24 | | GRefString *key; |
25 | | FwupdJsonNode *json_node; |
26 | | } FwupdJsonObjectEntry; |
27 | | |
28 | | struct FwupdJsonObject { |
29 | | grefcount refcount; |
30 | | GPtrArray *items; /* element-type FwupdJsonObjectEntry */ |
31 | | }; |
32 | | |
33 | | static void |
34 | | fwupd_json_object_entry_free(FwupdJsonObjectEntry *entry) |
35 | 10.1k | { |
36 | 10.1k | g_ref_string_release(entry->key); |
37 | 10.1k | fwupd_json_node_unref(entry->json_node); |
38 | 10.1k | g_free(entry); |
39 | 10.1k | } |
40 | | |
41 | | /** |
42 | | * fwupd_json_object_new: (skip): |
43 | | * |
44 | | * Creates a new JSON object. |
45 | | * |
46 | | * Returns: (transfer full): a #FwupdJsonObject |
47 | | * |
48 | | * Since: 2.1.1 |
49 | | **/ |
50 | | FwupdJsonObject * |
51 | | fwupd_json_object_new(void) |
52 | 8.55k | { |
53 | 8.55k | FwupdJsonObject *self = g_new0(FwupdJsonObject, 1); |
54 | 8.55k | g_ref_count_init(&self->refcount); |
55 | 8.55k | self->items = g_ptr_array_new_with_free_func((GDestroyNotify)fwupd_json_object_entry_free); |
56 | 8.55k | return self; |
57 | 8.55k | } |
58 | | |
59 | | /** |
60 | | * fwupd_json_object_ref: (skip): |
61 | | * @self: a #FwupdJsonObject |
62 | | * |
63 | | * Increases the reference count of a JSON object. |
64 | | * |
65 | | * Returns: (transfer full): a #FwupdJsonObject |
66 | | * |
67 | | * Since: 2.1.1 |
68 | | **/ |
69 | | FwupdJsonObject * |
70 | | fwupd_json_object_ref(FwupdJsonObject *self) |
71 | 11.4k | { |
72 | 11.4k | g_return_val_if_fail(self != NULL, NULL); |
73 | 11.4k | g_ref_count_inc(&self->refcount); |
74 | 11.4k | return self; |
75 | 11.4k | } |
76 | | |
77 | | /** |
78 | | * fwupd_json_object_unref: (skip): |
79 | | * @self: a #FwupdJsonObject |
80 | | * |
81 | | * Decreases the reference count of a JSON object. |
82 | | * |
83 | | * Returns: (transfer none): a #FwupdJsonObject, or %NULL |
84 | | * |
85 | | * Since: 2.1.1 |
86 | | **/ |
87 | | FwupdJsonObject * |
88 | | fwupd_json_object_unref(FwupdJsonObject *self) |
89 | 19.9k | { |
90 | 19.9k | g_return_val_if_fail(self != NULL, NULL); |
91 | 19.9k | if (!g_ref_count_dec(&self->refcount)) |
92 | 11.4k | return self; |
93 | 8.55k | g_ptr_array_unref(self->items); |
94 | 8.55k | g_free(self); |
95 | 8.55k | return NULL; |
96 | 19.9k | } |
97 | | |
98 | | /** |
99 | | * fwupd_json_object_clear: |
100 | | * @self: a #FwupdJsonObject |
101 | | * |
102 | | * Clears the member data for the JSON object, but does not affect the refcount. |
103 | | * |
104 | | * Since: 2.1.1 |
105 | | **/ |
106 | | void |
107 | | fwupd_json_object_clear(FwupdJsonObject *self) |
108 | 0 | { |
109 | 0 | g_return_if_fail(self != NULL); |
110 | 0 | g_ptr_array_set_size(self->items, 0); |
111 | 0 | } |
112 | | |
113 | | /** |
114 | | * fwupd_json_object_get_size: |
115 | | * @self: a #FwupdJsonObject |
116 | | * |
117 | | * Gets the size of the JSON object. |
118 | | * |
119 | | * Returns: number of key-values added |
120 | | * |
121 | | * Since: 2.1.1 |
122 | | **/ |
123 | | guint |
124 | | fwupd_json_object_get_size(FwupdJsonObject *self) |
125 | 13.5k | { |
126 | 13.5k | g_return_val_if_fail(self != NULL, G_MAXUINT); |
127 | 13.5k | return self->items->len; |
128 | 13.5k | } |
129 | | |
130 | | /** |
131 | | * fwupd_json_object_get_key_for_index: (skip): |
132 | | * @self: a #FwupdJsonObject |
133 | | * @idx: index |
134 | | * @error: (nullable): optional return location for an error |
135 | | * |
136 | | * Gets the key for a given index position. |
137 | | * |
138 | | * Returns: a #GRefString, or %NULL on error |
139 | | * |
140 | | * Since: 2.1.1 |
141 | | **/ |
142 | | GRefString * |
143 | | fwupd_json_object_get_key_for_index(FwupdJsonObject *self, guint idx, GError **error) |
144 | 0 | { |
145 | 0 | FwupdJsonObjectEntry *entry; |
146 | |
|
147 | 0 | g_return_val_if_fail(self != NULL, NULL); |
148 | 0 | g_return_val_if_fail(error == NULL || *error == NULL, NULL); |
149 | | |
150 | | /* sanity check */ |
151 | 0 | if (idx >= self->items->len) { |
152 | 0 | g_set_error(error, |
153 | 0 | FWUPD_ERROR, |
154 | 0 | FWUPD_ERROR_NOT_FOUND, |
155 | 0 | "index %u is larger than object size", |
156 | 0 | idx); |
157 | 0 | return NULL; |
158 | 0 | } |
159 | | |
160 | | /* success */ |
161 | 0 | entry = g_ptr_array_index(self->items, idx); |
162 | 0 | return entry->key; |
163 | 0 | } |
164 | | |
165 | | /** |
166 | | * fwupd_json_object_get_node_for_index: (skip): |
167 | | * @self: a #FwupdJsonObject |
168 | | * @idx: index |
169 | | * @error: (nullable): optional return location for an error |
170 | | * |
171 | | * Gets the node for a given index position. |
172 | | * |
173 | | * Returns: (transfer full): a #FwupdJsonNode, or %NULL on error |
174 | | * |
175 | | * Since: 2.1.1 |
176 | | **/ |
177 | | FwupdJsonNode * |
178 | | fwupd_json_object_get_node_for_index(FwupdJsonObject *self, guint idx, GError **error) |
179 | 0 | { |
180 | 0 | FwupdJsonObjectEntry *entry; |
181 | |
|
182 | 0 | g_return_val_if_fail(self != NULL, NULL); |
183 | 0 | g_return_val_if_fail(error == NULL || *error == NULL, NULL); |
184 | | |
185 | | /* sanity check */ |
186 | 0 | if (idx >= self->items->len) { |
187 | 0 | g_set_error(error, |
188 | 0 | FWUPD_ERROR, |
189 | 0 | FWUPD_ERROR_NOT_FOUND, |
190 | 0 | "index %u is larger than object size", |
191 | 0 | idx); |
192 | 0 | return NULL; |
193 | 0 | } |
194 | | |
195 | | /* success */ |
196 | 0 | entry = g_ptr_array_index(self->items, idx); |
197 | 0 | return fwupd_json_node_ref(entry->json_node); |
198 | 0 | } |
199 | | |
200 | | static FwupdJsonObjectEntry * |
201 | | fwupd_json_object_get_entry(FwupdJsonObject *self, const gchar *key, GError **error) |
202 | 13.5k | { |
203 | 33.7k | for (guint i = 0; i < self->items->len; i++) { |
204 | 23.6k | FwupdJsonObjectEntry *entry = g_ptr_array_index(self->items, i); |
205 | 23.6k | if (g_strcmp0(key, entry->key) == 0) |
206 | 3.39k | return entry; |
207 | 23.6k | } |
208 | 10.1k | g_set_error(error, FWUPD_ERROR, FWUPD_ERROR_NOT_FOUND, "no json_node for key %s", key); |
209 | 10.1k | return NULL; |
210 | 13.5k | } |
211 | | |
212 | | /** |
213 | | * fwupd_json_object_get_string: (skip): |
214 | | * @self: a #FwupdJsonObject |
215 | | * @key: (not nullable): dictionary key |
216 | | * @error: (nullable): optional return location for an error |
217 | | * |
218 | | * Gets a string from a JSON object. An error is returned if @key is not the correct type. |
219 | | * |
220 | | * Returns: a #GRefString, or %NULL on error |
221 | | * |
222 | | * Since: 2.1.1 |
223 | | **/ |
224 | | GRefString * |
225 | | fwupd_json_object_get_string(FwupdJsonObject *self, const gchar *key, GError **error) |
226 | 0 | { |
227 | 0 | FwupdJsonObjectEntry *entry; |
228 | |
|
229 | 0 | g_return_val_if_fail(self != NULL, NULL); |
230 | 0 | g_return_val_if_fail(key != NULL, NULL); |
231 | 0 | g_return_val_if_fail(error == NULL || *error == NULL, NULL); |
232 | | |
233 | 0 | entry = fwupd_json_object_get_entry(self, key, error); |
234 | 0 | if (entry == NULL) |
235 | 0 | return NULL; |
236 | 0 | return fwupd_json_node_get_string(entry->json_node, error); |
237 | 0 | } |
238 | | |
239 | | /** |
240 | | * fwupd_json_object_get_string_with_default: |
241 | | * @self: a #FwupdJsonObject |
242 | | * @key: (not nullable): dictionary key |
243 | | * @value_default: (not nullable): value to return if @key is not found |
244 | | * @error: (nullable): optional return location for an error |
245 | | * |
246 | | * Gets a string from a JSON object. An error is returned if @key is not the correct type. |
247 | | * |
248 | | * Returns: a string, or %NULL on error |
249 | | * |
250 | | * Since: 2.1.1 |
251 | | **/ |
252 | | const gchar * |
253 | | fwupd_json_object_get_string_with_default(FwupdJsonObject *self, |
254 | | const gchar *key, |
255 | | const gchar *value_default, |
256 | | GError **error) |
257 | 0 | { |
258 | 0 | FwupdJsonObjectEntry *entry; |
259 | |
|
260 | 0 | g_return_val_if_fail(self != NULL, NULL); |
261 | 0 | g_return_val_if_fail(key != NULL, NULL); |
262 | 0 | g_return_val_if_fail(value_default != NULL, NULL); |
263 | 0 | g_return_val_if_fail(error == NULL || *error == NULL, NULL); |
264 | | |
265 | 0 | entry = fwupd_json_object_get_entry(self, key, NULL); |
266 | 0 | if (entry == NULL) |
267 | 0 | return value_default; |
268 | 0 | return fwupd_json_node_get_string(entry->json_node, error); |
269 | 0 | } |
270 | | |
271 | | /** |
272 | | * fwupd_json_object_get_integer: |
273 | | * @self: a #FwupdJsonObject |
274 | | * @key: (not nullable): dictionary key |
275 | | * @value: (out) (nullable): integer value |
276 | | * @error: (nullable): optional return location for an error |
277 | | * |
278 | | * Gets an integer from a JSON object. An error is returned if @key is not the correct type. |
279 | | * |
280 | | * Returns: %TRUE if @value was parsed as an integer |
281 | | * |
282 | | * Since: 2.1.1 |
283 | | **/ |
284 | | gboolean |
285 | | fwupd_json_object_get_integer(FwupdJsonObject *self, |
286 | | const gchar *key, |
287 | | gint64 *value, |
288 | | GError **error) |
289 | 0 | { |
290 | 0 | FwupdJsonObjectEntry *entry; |
291 | 0 | const gchar *str; |
292 | 0 | gchar *endptr = NULL; |
293 | 0 | gint64 value_tmp; |
294 | |
|
295 | 0 | g_return_val_if_fail(self != NULL, FALSE); |
296 | 0 | g_return_val_if_fail(key != NULL, FALSE); |
297 | 0 | g_return_val_if_fail(error == NULL || *error == NULL, FALSE); |
298 | | |
299 | 0 | entry = fwupd_json_object_get_entry(self, key, error); |
300 | 0 | if (entry == NULL) |
301 | 0 | return FALSE; |
302 | 0 | str = fwupd_json_node_get_raw(entry->json_node, error); |
303 | 0 | if (str == NULL) |
304 | 0 | return FALSE; |
305 | | |
306 | | /* convert */ |
307 | 0 | value_tmp = g_ascii_strtoll(str, &endptr, 10); /* nocheck:blocked */ |
308 | 0 | if ((gsize)(endptr - str) != strlen(str)) { |
309 | 0 | g_set_error(error, FWUPD_ERROR, FWUPD_ERROR_INVALID_DATA, "cannot parse %s", str); |
310 | 0 | return FALSE; |
311 | 0 | } |
312 | | |
313 | | /* overflow check */ |
314 | 0 | if (value_tmp == G_MAXINT64) { |
315 | 0 | g_set_error(error, |
316 | 0 | FWUPD_ERROR, |
317 | 0 | FWUPD_ERROR_INVALID_DATA, |
318 | 0 | "cannot parse %s due to overflow", |
319 | 0 | str); |
320 | 0 | return FALSE; |
321 | 0 | } |
322 | | |
323 | | /* success */ |
324 | 0 | if (value != NULL) |
325 | 0 | *value = value_tmp; |
326 | 0 | return TRUE; |
327 | 0 | } |
328 | | |
329 | | /** |
330 | | * fwupd_json_object_get_integer_with_default: |
331 | | * @self: a #FwupdJsonObject |
332 | | * @key: (not nullable): dictionary key |
333 | | * @value: (out) (nullable): integer value |
334 | | * @value_default: value to return if @key is not found, typically 0 or %G_MAXINT64 |
335 | | * @error: (nullable): optional return location for an error |
336 | | * |
337 | | * Gets an integer from a JSON object. An error is returned if @key is not the correct type. |
338 | | * |
339 | | * Returns: %TRUE if @value was parsed as an integer |
340 | | * |
341 | | * Since: 2.1.1 |
342 | | **/ |
343 | | gboolean |
344 | | fwupd_json_object_get_integer_with_default(FwupdJsonObject *self, |
345 | | const gchar *key, |
346 | | gint64 *value, |
347 | | gint64 value_default, |
348 | | GError **error) |
349 | 0 | { |
350 | 0 | FwupdJsonObjectEntry *entry; |
351 | 0 | const gchar *str; |
352 | 0 | gchar *endptr = NULL; |
353 | 0 | gint64 value_tmp; |
354 | |
|
355 | 0 | g_return_val_if_fail(self != NULL, FALSE); |
356 | 0 | g_return_val_if_fail(key != NULL, FALSE); |
357 | 0 | g_return_val_if_fail(error == NULL || *error == NULL, FALSE); |
358 | | |
359 | 0 | entry = fwupd_json_object_get_entry(self, key, NULL); |
360 | 0 | if (entry == NULL || |
361 | 0 | fwupd_json_node_get_kind(entry->json_node) == FWUPD_JSON_NODE_KIND_NULL) { |
362 | 0 | if (value != NULL) |
363 | 0 | *value = value_default; |
364 | 0 | return TRUE; |
365 | 0 | } |
366 | 0 | str = fwupd_json_node_get_raw(entry->json_node, error); |
367 | 0 | if (str == NULL) |
368 | 0 | return FALSE; |
369 | | |
370 | | /* convert */ |
371 | 0 | value_tmp = g_ascii_strtoll(str, &endptr, 10); /* nocheck:blocked */ |
372 | 0 | if ((gsize)(endptr - str) != strlen(str)) { |
373 | 0 | g_set_error(error, FWUPD_ERROR, FWUPD_ERROR_INVALID_DATA, "cannot parse %s", str); |
374 | 0 | return FALSE; |
375 | 0 | } |
376 | | |
377 | | /* overflow check */ |
378 | 0 | if (value_tmp == G_MAXINT64) { |
379 | 0 | g_set_error(error, |
380 | 0 | FWUPD_ERROR, |
381 | 0 | FWUPD_ERROR_INVALID_DATA, |
382 | 0 | "cannot parse %s due to overflow", |
383 | 0 | str); |
384 | 0 | return FALSE; |
385 | 0 | } |
386 | | |
387 | | /* success */ |
388 | 0 | if (value != NULL) |
389 | 0 | *value = value_tmp; |
390 | 0 | return TRUE; |
391 | 0 | } |
392 | | |
393 | | /** |
394 | | * fwupd_json_object_get_boolean: |
395 | | * @self: a #FwupdJsonObject |
396 | | * @key: (not nullable): dictionary key |
397 | | * @value: (out) (nullable): boolean value |
398 | | * @error: (nullable): optional return location for an error |
399 | | * |
400 | | * Gets a boolean from a JSON object. An error is returned if @key is not the correct type. |
401 | | * |
402 | | * Returns: %TRUE if @value was parsed as an integer |
403 | | * |
404 | | * Since: 2.1.1 |
405 | | **/ |
406 | | gboolean |
407 | | fwupd_json_object_get_boolean(FwupdJsonObject *self, |
408 | | const gchar *key, |
409 | | gboolean *value, |
410 | | GError **error) |
411 | 0 | { |
412 | 0 | FwupdJsonObjectEntry *entry; |
413 | 0 | const gchar *str; |
414 | |
|
415 | 0 | g_return_val_if_fail(self != NULL, FALSE); |
416 | 0 | g_return_val_if_fail(key != NULL, FALSE); |
417 | 0 | g_return_val_if_fail(error == NULL || *error == NULL, FALSE); |
418 | | |
419 | 0 | entry = fwupd_json_object_get_entry(self, key, error); |
420 | 0 | if (entry == NULL) |
421 | 0 | return FALSE; |
422 | 0 | str = fwupd_json_node_get_raw(entry->json_node, error); |
423 | 0 | if (str == NULL) |
424 | 0 | return FALSE; |
425 | | |
426 | | /* convert */ |
427 | 0 | if (g_ascii_strcasecmp(str, "false") == 0) { |
428 | 0 | if (value != NULL) |
429 | 0 | *value = FALSE; |
430 | 0 | return TRUE; |
431 | 0 | } |
432 | 0 | if (g_ascii_strcasecmp(str, "true") == 0) { |
433 | 0 | if (value != NULL) |
434 | 0 | *value = TRUE; |
435 | 0 | return TRUE; |
436 | 0 | } |
437 | | |
438 | | /* failed */ |
439 | 0 | g_set_error(error, FWUPD_ERROR, FWUPD_ERROR_INVALID_DATA, "cannot parse %s", str); |
440 | 0 | return FALSE; |
441 | 0 | } |
442 | | |
443 | | /** |
444 | | * fwupd_json_object_get_boolean_with_default: |
445 | | * @self: a #FwupdJsonObject |
446 | | * @key: (not nullable): dictionary key |
447 | | * @value: (out) (nullable): boolean value |
448 | | * @value_default: value to return if @key is not found, typically %FALSE |
449 | | * @error: (nullable): optional return location for an error |
450 | | * |
451 | | * Gets a boolean from a JSON object. An error is returned if @key is not the correct type. |
452 | | * |
453 | | * Returns: %TRUE if @value was parsed as an integer |
454 | | * |
455 | | * Since: 2.1.1 |
456 | | **/ |
457 | | gboolean |
458 | | fwupd_json_object_get_boolean_with_default(FwupdJsonObject *self, |
459 | | const gchar *key, |
460 | | gboolean *value, |
461 | | gboolean value_default, |
462 | | GError **error) |
463 | 0 | { |
464 | 0 | FwupdJsonObjectEntry *entry; |
465 | 0 | const gchar *str; |
466 | |
|
467 | 0 | g_return_val_if_fail(self != NULL, FALSE); |
468 | 0 | g_return_val_if_fail(key != NULL, FALSE); |
469 | 0 | g_return_val_if_fail(error == NULL || *error == NULL, FALSE); |
470 | | |
471 | 0 | entry = fwupd_json_object_get_entry(self, key, NULL); |
472 | 0 | if (entry == NULL || |
473 | 0 | fwupd_json_node_get_kind(entry->json_node) == FWUPD_JSON_NODE_KIND_NULL) { |
474 | 0 | if (value != NULL) |
475 | 0 | *value = value_default; |
476 | 0 | return TRUE; |
477 | 0 | } |
478 | 0 | str = fwupd_json_node_get_raw(entry->json_node, error); |
479 | 0 | if (str == NULL) |
480 | 0 | return FALSE; |
481 | | |
482 | | /* convert */ |
483 | 0 | if (g_ascii_strcasecmp(str, "false") == 0) { |
484 | 0 | if (value != NULL) |
485 | 0 | *value = FALSE; |
486 | 0 | return TRUE; |
487 | 0 | } |
488 | 0 | if (g_ascii_strcasecmp(str, "true") == 0) { |
489 | 0 | if (value != NULL) |
490 | 0 | *value = TRUE; |
491 | 0 | return TRUE; |
492 | 0 | } |
493 | | |
494 | | /* failed */ |
495 | 0 | g_set_error(error, FWUPD_ERROR, FWUPD_ERROR_INVALID_DATA, "cannot parse %s", str); |
496 | 0 | return FALSE; |
497 | 0 | } |
498 | | |
499 | | /** |
500 | | * fwupd_json_object_has_node: (skip): |
501 | | * @self: a #FwupdJsonObject |
502 | | * @key: (not nullable): dictionary key |
503 | | * |
504 | | * Finds if a node exists in a JSON object. |
505 | | * |
506 | | * In general, it's nearly always better to call the type-specific method directly e.g. |
507 | | * fwupd_json_object_get_string() and handle the error. |
508 | | * |
509 | | * Returns: %TRUE if a node exists with the key. |
510 | | * |
511 | | * Since: 2.1.1 |
512 | | **/ |
513 | | gboolean |
514 | | fwupd_json_object_has_node(FwupdJsonObject *self, const gchar *key) |
515 | 0 | { |
516 | 0 | g_return_val_if_fail(self != NULL, FALSE); |
517 | 0 | g_return_val_if_fail(key != NULL, FALSE); |
518 | 0 | return fwupd_json_object_get_entry(self, key, NULL) != NULL; |
519 | 0 | } |
520 | | |
521 | | /** |
522 | | * fwupd_json_object_get_node: (skip): |
523 | | * @self: a #FwupdJsonObject |
524 | | * @key: (not nullable): dictionary key |
525 | | * @error: (nullable): optional return location for an error |
526 | | * |
527 | | * Gets a node from a JSON object. |
528 | | * |
529 | | * Returns: (transfer full): a #FwupdJsonObject, or %NULL on error |
530 | | * |
531 | | * Since: 2.1.1 |
532 | | **/ |
533 | | FwupdJsonNode * |
534 | | fwupd_json_object_get_node(FwupdJsonObject *self, const gchar *key, GError **error) |
535 | 0 | { |
536 | 0 | FwupdJsonObjectEntry *entry; |
537 | |
|
538 | 0 | g_return_val_if_fail(self != NULL, NULL); |
539 | 0 | g_return_val_if_fail(key != NULL, NULL); |
540 | 0 | g_return_val_if_fail(error == NULL || *error == NULL, NULL); |
541 | | |
542 | 0 | entry = fwupd_json_object_get_entry(self, key, error); |
543 | 0 | if (entry == NULL) |
544 | 0 | return NULL; |
545 | 0 | return fwupd_json_node_ref(entry->json_node); |
546 | 0 | } |
547 | | |
548 | | /** |
549 | | * fwupd_json_object_get_nodes: (skip): |
550 | | * @self: a #FwupdJsonObject |
551 | | * |
552 | | * Gets all the nodes from a JSON object. |
553 | | * |
554 | | * Returns: (transfer container) (element-type FwupdJsonNode): an array of nodes |
555 | | * |
556 | | * Since: 2.1.1 |
557 | | **/ |
558 | | GPtrArray * |
559 | | fwupd_json_object_get_nodes(FwupdJsonObject *self) |
560 | 0 | { |
561 | 0 | g_autoptr(GPtrArray) json_nodes = |
562 | 0 | g_ptr_array_new_with_free_func((GDestroyNotify)fwupd_json_node_unref); |
563 | |
|
564 | 0 | g_return_val_if_fail(self != NULL, NULL); |
565 | | |
566 | 0 | for (guint i = 0; i < self->items->len; i++) { |
567 | 0 | FwupdJsonObjectEntry *entry = g_ptr_array_index(self->items, i); |
568 | 0 | g_ptr_array_add(json_nodes, fwupd_json_node_ref(entry->json_node)); |
569 | 0 | } |
570 | 0 | return g_steal_pointer(&json_nodes); |
571 | 0 | } |
572 | | |
573 | | /** |
574 | | * fwupd_json_object_get_keys: (skip): |
575 | | * @self: a #FwupdJsonObject |
576 | | * |
577 | | * Gets all the keys from a JSON object. |
578 | | * |
579 | | * Returns: (transfer container) (element-type GRefString): an array of keys |
580 | | * |
581 | | * Since: 2.1.1 |
582 | | **/ |
583 | | GPtrArray * |
584 | | fwupd_json_object_get_keys(FwupdJsonObject *self) |
585 | 0 | { |
586 | 0 | g_autoptr(GPtrArray) json_keys = |
587 | 0 | g_ptr_array_new_with_free_func((GDestroyNotify)g_ref_string_release); |
588 | |
|
589 | 0 | g_return_val_if_fail(self != NULL, NULL); |
590 | | |
591 | 0 | for (guint i = 0; i < self->items->len; i++) { |
592 | 0 | FwupdJsonObjectEntry *entry = g_ptr_array_index(self->items, i); |
593 | 0 | g_ptr_array_add(json_keys, g_ref_string_acquire(entry->key)); |
594 | 0 | } |
595 | 0 | return g_steal_pointer(&json_keys); |
596 | 0 | } |
597 | | |
598 | | /** |
599 | | * fwupd_json_object_get_object: (skip): |
600 | | * @self: a #FwupdJsonObject |
601 | | * @key: (not nullable): dictionary key |
602 | | * @error: (nullable): optional return location for an error |
603 | | * |
604 | | * Gets a different object from a JSON object. An error is returned if @key is not the correct type. |
605 | | * |
606 | | * Returns: (transfer full): a #FwupdJsonObject, or %NULL on error |
607 | | * |
608 | | * Since: 2.1.1 |
609 | | **/ |
610 | | FwupdJsonObject * |
611 | | fwupd_json_object_get_object(FwupdJsonObject *self, const gchar *key, GError **error) |
612 | 0 | { |
613 | 0 | FwupdJsonObjectEntry *entry; |
614 | |
|
615 | 0 | g_return_val_if_fail(self != NULL, NULL); |
616 | 0 | g_return_val_if_fail(key != NULL, NULL); |
617 | 0 | g_return_val_if_fail(error == NULL || *error == NULL, NULL); |
618 | | |
619 | 0 | entry = fwupd_json_object_get_entry(self, key, error); |
620 | 0 | if (entry == NULL) |
621 | 0 | return NULL; |
622 | 0 | return fwupd_json_node_get_object(entry->json_node, error); |
623 | 0 | } |
624 | | |
625 | | /** |
626 | | * fwupd_json_object_get_array: (skip): |
627 | | * @self: a #FwupdJsonObject |
628 | | * @key: (not nullable): dictionary key |
629 | | * @error: (nullable): optional return location for an error |
630 | | * |
631 | | * Gets an array from a JSON object. An error is returned if @key is not the correct type. |
632 | | * |
633 | | * Returns: (transfer full): a #FwupdJsonArray, or %NULL on error |
634 | | * |
635 | | * Since: 2.1.1 |
636 | | **/ |
637 | | FwupdJsonArray * |
638 | | fwupd_json_object_get_array(FwupdJsonObject *self, const gchar *key, GError **error) |
639 | 0 | { |
640 | 0 | FwupdJsonObjectEntry *entry; |
641 | |
|
642 | 0 | g_return_val_if_fail(self != NULL, NULL); |
643 | 0 | g_return_val_if_fail(key != NULL, NULL); |
644 | 0 | g_return_val_if_fail(error == NULL || *error == NULL, NULL); |
645 | | |
646 | 0 | entry = fwupd_json_object_get_entry(self, key, error); |
647 | 0 | if (entry == NULL) |
648 | 0 | return NULL; |
649 | 0 | return fwupd_json_node_get_array(entry->json_node, error); |
650 | 0 | } |
651 | | |
652 | | void |
653 | | fwupd_json_object_add_raw_internal(FwupdJsonObject *self, |
654 | | GRefString *key, |
655 | | GRefString *value, |
656 | | FwupdJsonLoadFlags flags) |
657 | 2.80k | { |
658 | 2.80k | FwupdJsonObjectEntry *entry = NULL; |
659 | | |
660 | 2.80k | if ((flags & FWUPD_JSON_LOAD_FLAG_TRUSTED) == 0) |
661 | 2.80k | entry = fwupd_json_object_get_entry(self, key, NULL); |
662 | 2.80k | if (entry != NULL) { |
663 | 369 | fwupd_json_node_unref(entry->json_node); |
664 | 2.44k | } else { |
665 | 2.44k | entry = g_new0(FwupdJsonObjectEntry, 1); |
666 | 2.44k | entry->key = (flags & FWUPD_JSON_LOAD_FLAG_STATIC_KEYS) > 0 |
667 | 2.44k | ? g_ref_string_new_intern(key) |
668 | 2.44k | : g_ref_string_acquire(key); |
669 | 2.44k | g_ptr_array_add(self->items, entry); |
670 | 2.44k | } |
671 | 2.80k | entry->json_node = fwupd_json_node_new_raw_internal(value); |
672 | 2.80k | } |
673 | | |
674 | | void |
675 | | fwupd_json_object_add_null_internal(FwupdJsonObject *self, |
676 | | GRefString *key, |
677 | | FwupdJsonLoadFlags flags) |
678 | 2.17k | { |
679 | 2.17k | FwupdJsonObjectEntry *entry = NULL; |
680 | | |
681 | 2.17k | if ((flags & FWUPD_JSON_LOAD_FLAG_TRUSTED) == 0) |
682 | 2.17k | entry = fwupd_json_object_get_entry(self, key, NULL); |
683 | 2.17k | if (entry != NULL) { |
684 | 830 | fwupd_json_node_unref(entry->json_node); |
685 | 1.34k | } else { |
686 | 1.34k | entry = g_new0(FwupdJsonObjectEntry, 1); |
687 | 1.34k | entry->key = (flags & FWUPD_JSON_LOAD_FLAG_STATIC_KEYS) > 0 |
688 | 1.34k | ? g_ref_string_new_intern(key) |
689 | 1.34k | : g_ref_string_acquire(key); |
690 | 1.34k | g_ptr_array_add(self->items, entry); |
691 | 1.34k | } |
692 | 2.17k | entry->json_node = fwupd_json_node_new_null_internal(); |
693 | 2.17k | } |
694 | | |
695 | | /** |
696 | | * fwupd_json_object_add_node: |
697 | | * @self: a #FwupdJsonObject |
698 | | * @key: (not nullable): dictionary key |
699 | | * @json_node: (not nullable): a #FwupdJsonNode |
700 | | * |
701 | | * Adds a node to the JSON object. If the node already exists the old one is replaced. |
702 | | * |
703 | | * Since: 2.1.1 |
704 | | **/ |
705 | | void |
706 | | fwupd_json_object_add_node(FwupdJsonObject *self, const gchar *key, FwupdJsonNode *json_node) |
707 | 0 | { |
708 | 0 | FwupdJsonObjectEntry *entry; |
709 | |
|
710 | 0 | g_return_if_fail(self != NULL); |
711 | 0 | g_return_if_fail(key != NULL); |
712 | 0 | g_return_if_fail(json_node != NULL); |
713 | | |
714 | 0 | entry = fwupd_json_object_get_entry(self, key, NULL); |
715 | 0 | if (entry != NULL) { |
716 | 0 | fwupd_json_node_unref(entry->json_node); |
717 | 0 | } else { |
718 | 0 | entry = g_new0(FwupdJsonObjectEntry, 1); |
719 | 0 | entry->key = g_ref_string_new(key); |
720 | 0 | g_ptr_array_add(self->items, entry); |
721 | 0 | } |
722 | 0 | entry->json_node = fwupd_json_node_ref(json_node); |
723 | 0 | } |
724 | | |
725 | | /** |
726 | | * fwupd_json_object_add_raw: |
727 | | * @self: a #FwupdJsonObject |
728 | | * @key: (not nullable): dictionary key |
729 | | * @value: (not nullable): value |
730 | | * |
731 | | * Adds a raw value to the JSON object. If the node already exists the old one is replaced. |
732 | | * |
733 | | * Since: 2.1.1 |
734 | | **/ |
735 | | void |
736 | | fwupd_json_object_add_raw(FwupdJsonObject *self, const gchar *key, const gchar *value) |
737 | 0 | { |
738 | 0 | g_autoptr(FwupdJsonNode) json_node = NULL; |
739 | |
|
740 | 0 | g_return_if_fail(self != NULL); |
741 | 0 | g_return_if_fail(key != NULL); |
742 | 0 | g_return_if_fail(value != NULL); |
743 | | |
744 | 0 | json_node = fwupd_json_node_new_raw(value); |
745 | 0 | fwupd_json_object_add_node(self, key, json_node); |
746 | 0 | } |
747 | | |
748 | | void |
749 | | fwupd_json_object_add_string_internal(FwupdJsonObject *self, |
750 | | GRefString *key, |
751 | | GRefString *value, |
752 | | FwupdJsonLoadFlags flags) |
753 | 2.34k | { |
754 | 2.34k | FwupdJsonObjectEntry *entry = NULL; |
755 | | |
756 | 2.34k | if ((flags & FWUPD_JSON_LOAD_FLAG_TRUSTED) == 0) |
757 | 2.34k | entry = fwupd_json_object_get_entry(self, key, NULL); |
758 | 2.34k | if (entry != NULL) { |
759 | 317 | fwupd_json_node_unref(entry->json_node); |
760 | 2.03k | } else { |
761 | 2.03k | entry = g_new0(FwupdJsonObjectEntry, 1); |
762 | 2.03k | entry->key = (flags & FWUPD_JSON_LOAD_FLAG_STATIC_KEYS) > 0 |
763 | 2.03k | ? g_ref_string_new_intern(key) |
764 | 2.03k | : g_ref_string_acquire(key); |
765 | 2.03k | g_ptr_array_add(self->items, entry); |
766 | 2.03k | } |
767 | 2.34k | entry->json_node = fwupd_json_node_new_string_internal(value); |
768 | 2.34k | } |
769 | | |
770 | | /** |
771 | | * fwupd_json_object_add_string: |
772 | | * @self: a #FwupdJsonObject |
773 | | * @key: (not nullable): dictionary key |
774 | | * @value: (nullable): value, or %NULL |
775 | | * |
776 | | * Adds a string value to the JSON object. If the node already exists the old one is replaced. |
777 | | * |
778 | | * Since: 2.1.1 |
779 | | **/ |
780 | | void |
781 | | fwupd_json_object_add_string(FwupdJsonObject *self, const gchar *key, const gchar *value) |
782 | 0 | { |
783 | 0 | g_autoptr(FwupdJsonNode) json_node = NULL; |
784 | |
|
785 | 0 | g_return_if_fail(self != NULL); |
786 | 0 | g_return_if_fail(key != NULL); |
787 | | |
788 | 0 | json_node = fwupd_json_node_new_string(value); |
789 | 0 | fwupd_json_object_add_node(self, key, json_node); |
790 | 0 | } |
791 | | |
792 | | /** |
793 | | * fwupd_json_object_add_bytes: |
794 | | * @self: a #FwupdJsonObject |
795 | | * @key: (not nullable): dictionary key |
796 | | * @value: (not nullable): value |
797 | | * |
798 | | * Adds bytes to the JSON object. They will be base64 encoded as a string. |
799 | | * If the node already exists the old one is replaced. |
800 | | * |
801 | | * Since: 2.1.1 |
802 | | **/ |
803 | | void |
804 | | fwupd_json_object_add_bytes(FwupdJsonObject *self, const gchar *key, GBytes *value) |
805 | 0 | { |
806 | 0 | g_autoptr(FwupdJsonNode) json_node = NULL; |
807 | 0 | g_autofree gchar *b64data = NULL; |
808 | 0 | const guint8 *buf; |
809 | 0 | gsize bufsz = 0; |
810 | |
|
811 | 0 | g_return_if_fail(self != NULL); |
812 | 0 | g_return_if_fail(key != NULL); |
813 | 0 | g_return_if_fail(value != NULL); |
814 | | |
815 | 0 | buf = g_bytes_get_data(value, &bufsz); |
816 | 0 | b64data = g_base64_encode(buf, bufsz); |
817 | |
|
818 | 0 | json_node = fwupd_json_node_new_string(b64data); |
819 | 0 | fwupd_json_object_add_node(self, key, json_node); |
820 | 0 | } |
821 | | |
822 | | /** |
823 | | * fwupd_json_object_add_array_strv: |
824 | | * @self: a #FwupdJsonObject |
825 | | * @key: (not nullable): dictionary key |
826 | | * @value: (not nullable): value |
827 | | * |
828 | | * Adds a string array to the JSON object. If the node already exists the old one is replaced. |
829 | | * |
830 | | * Since: 2.1.1 |
831 | | **/ |
832 | | void |
833 | | fwupd_json_object_add_array_strv(FwupdJsonObject *self, const gchar *key, gchar **value) |
834 | 0 | { |
835 | 0 | g_autoptr(FwupdJsonArray) json_arr = fwupd_json_array_new(); |
836 | |
|
837 | 0 | g_return_if_fail(self != NULL); |
838 | 0 | g_return_if_fail(key != NULL); |
839 | 0 | g_return_if_fail(value != NULL); |
840 | | |
841 | 0 | for (guint i = 0; value[i] != NULL; i++) |
842 | 0 | fwupd_json_array_add_string(json_arr, value[i]); |
843 | 0 | fwupd_json_object_add_array(self, key, json_arr); |
844 | 0 | } |
845 | | |
846 | | /** |
847 | | * fwupd_json_object_add_integer: |
848 | | * @self: a #FwupdJsonObject |
849 | | * @key: (not nullable): dictionary key |
850 | | * @value: integer |
851 | | * |
852 | | * Adds an integer value to the JSON object. |
853 | | * |
854 | | * Since: 2.1.1 |
855 | | **/ |
856 | | void |
857 | | fwupd_json_object_add_integer(FwupdJsonObject *self, const gchar *key, gint64 value) |
858 | 0 | { |
859 | 0 | g_autoptr(FwupdJsonNode) json_node = NULL; |
860 | 0 | g_autofree gchar *str = NULL; |
861 | |
|
862 | 0 | g_return_if_fail(self != NULL); |
863 | 0 | g_return_if_fail(key != NULL); |
864 | 0 | g_return_if_fail(value != G_MAXINT64); |
865 | | |
866 | 0 | str = g_strdup_printf("%" G_GINT64_FORMAT, value); |
867 | 0 | json_node = fwupd_json_node_new_raw(str); |
868 | 0 | fwupd_json_object_add_node(self, key, json_node); |
869 | 0 | } |
870 | | |
871 | | /** |
872 | | * fwupd_json_object_add_boolean: |
873 | | * @self: a #FwupdJsonObject |
874 | | * @key: (not nullable): dictionary key |
875 | | * @value: boolean |
876 | | * |
877 | | * Adds a boolean value to the JSON object. |
878 | | * |
879 | | * Since: 2.1.1 |
880 | | **/ |
881 | | void |
882 | | fwupd_json_object_add_boolean(FwupdJsonObject *self, const gchar *key, gboolean value) |
883 | 0 | { |
884 | 0 | g_autoptr(FwupdJsonNode) json_node = NULL; |
885 | |
|
886 | 0 | g_return_if_fail(self != NULL); |
887 | 0 | g_return_if_fail(key != NULL); |
888 | | |
889 | 0 | json_node = fwupd_json_node_new_raw(value ? "true" : "false"); |
890 | 0 | fwupd_json_object_add_node(self, key, json_node); |
891 | 0 | } |
892 | | |
893 | | void |
894 | | fwupd_json_object_add_object_internal(FwupdJsonObject *self, |
895 | | GRefString *key, |
896 | | FwupdJsonObject *json_obj) |
897 | 3.13k | { |
898 | 3.13k | FwupdJsonObjectEntry *entry = fwupd_json_object_get_entry(self, key, NULL); |
899 | 3.13k | if (entry != NULL) { |
900 | 1.39k | fwupd_json_node_unref(entry->json_node); |
901 | 1.74k | } else { |
902 | 1.74k | entry = g_new0(FwupdJsonObjectEntry, 1); |
903 | 1.74k | entry->key = g_ref_string_acquire(key); |
904 | 1.74k | g_ptr_array_add(self->items, entry); |
905 | 1.74k | } |
906 | 3.13k | entry->json_node = fwupd_json_node_new_object(json_obj); |
907 | 3.13k | } |
908 | | |
909 | | /** |
910 | | * fwupd_json_object_add_object: |
911 | | * @self: a #FwupdJsonObject |
912 | | * @key: (not nullable): dictionary key |
913 | | * @json_obj: a #FwupdJsonObject |
914 | | * |
915 | | * Adds a different object to the JSON object. |
916 | | * |
917 | | * Since: 2.1.1 |
918 | | **/ |
919 | | void |
920 | | fwupd_json_object_add_object(FwupdJsonObject *self, const gchar *key, FwupdJsonObject *json_obj) |
921 | 0 | { |
922 | 0 | g_autoptr(FwupdJsonNode) json_node = NULL; |
923 | |
|
924 | 0 | g_return_if_fail(self != NULL); |
925 | 0 | g_return_if_fail(key != NULL); |
926 | 0 | g_return_if_fail(json_obj != NULL); |
927 | 0 | g_return_if_fail(self != json_obj); |
928 | | |
929 | 0 | json_node = fwupd_json_node_new_object(json_obj); |
930 | 0 | fwupd_json_object_add_node(self, key, json_node); |
931 | 0 | } |
932 | | |
933 | | /** |
934 | | * fwupd_json_object_add_object_map: |
935 | | * @self: a #FwupdJsonObject |
936 | | * @key: (not nullable): dictionary key |
937 | | * @value: (element-type utf8 utf8): a hash table |
938 | | * |
939 | | * Adds a object to the JSON object. |
940 | | * |
941 | | * Since: 2.1.1 |
942 | | **/ |
943 | | void |
944 | | fwupd_json_object_add_object_map(FwupdJsonObject *self, const gchar *key, GHashTable *value) |
945 | 0 | { |
946 | 0 | GHashTableIter iter; |
947 | 0 | gpointer hash_key, hash_value; |
948 | 0 | g_autoptr(FwupdJsonObject) json_obj = fwupd_json_object_new(); |
949 | |
|
950 | 0 | g_return_if_fail(self != NULL); |
951 | 0 | g_return_if_fail(key != NULL); |
952 | 0 | g_return_if_fail(value != NULL); |
953 | | |
954 | 0 | g_hash_table_iter_init(&iter, value); |
955 | 0 | while (g_hash_table_iter_next(&iter, &hash_key, &hash_value)) { |
956 | 0 | fwupd_json_object_add_string(json_obj, |
957 | 0 | (const gchar *)hash_key, |
958 | 0 | (const gchar *)hash_value); |
959 | 0 | } |
960 | 0 | fwupd_json_object_add_object(self, key, json_obj); |
961 | 0 | } |
962 | | |
963 | | void |
964 | | fwupd_json_object_add_array_internal(FwupdJsonObject *self, |
965 | | GRefString *key, |
966 | | FwupdJsonArray *json_arr) |
967 | 3.03k | { |
968 | 3.03k | FwupdJsonObjectEntry *entry = fwupd_json_object_get_entry(self, key, NULL); |
969 | 3.03k | if (entry != NULL) { |
970 | 477 | fwupd_json_node_unref(entry->json_node); |
971 | 2.55k | } else { |
972 | 2.55k | entry = g_new0(FwupdJsonObjectEntry, 1); |
973 | 2.55k | entry->key = g_ref_string_acquire(key); |
974 | 2.55k | g_ptr_array_add(self->items, entry); |
975 | 2.55k | } |
976 | 3.03k | entry->json_node = fwupd_json_node_new_array(json_arr); |
977 | 3.03k | } |
978 | | |
979 | | /** |
980 | | * fwupd_json_object_add_array: |
981 | | * @self: a #FwupdJsonObject |
982 | | * @key: (not nullable): dictionary key |
983 | | * @json_arr: a #FwupdJsonArray |
984 | | * |
985 | | * Adds an array to the JSON object. |
986 | | * |
987 | | * Since: 2.1.1 |
988 | | **/ |
989 | | void |
990 | | fwupd_json_object_add_array(FwupdJsonObject *self, const gchar *key, FwupdJsonArray *json_arr) |
991 | 0 | { |
992 | 0 | g_autoptr(FwupdJsonNode) json_node = NULL; |
993 | |
|
994 | 0 | g_return_if_fail(self != NULL); |
995 | 0 | g_return_if_fail(key != NULL); |
996 | 0 | g_return_if_fail(json_arr != NULL); |
997 | | |
998 | 0 | json_node = fwupd_json_node_new_array(json_arr); |
999 | 0 | fwupd_json_object_add_node(self, key, json_node); |
1000 | 0 | } |
1001 | | |
1002 | | /** |
1003 | | * fwupd_json_object_append_string: |
1004 | | * @self: a #FwupdJsonObject |
1005 | | * @str: a #GString |
1006 | | * @depth: depth, where 0 is the root node |
1007 | | * @flags: some #FwupdJsonExportFlags e.g. #FWUPD_JSON_EXPORT_FLAG_INDENT |
1008 | | * |
1009 | | * Appends the JSON object to existing string. |
1010 | | * |
1011 | | * Since: 2.1.1 |
1012 | | **/ |
1013 | | void |
1014 | | fwupd_json_object_append_string(FwupdJsonObject *self, |
1015 | | GString *str, |
1016 | | guint depth, |
1017 | | FwupdJsonExportFlags flags) |
1018 | 3.94k | { |
1019 | 3.94k | g_return_if_fail(self != NULL); |
1020 | 3.94k | g_return_if_fail(str != NULL); |
1021 | | |
1022 | | /* start */ |
1023 | 3.94k | g_string_append_c(str, '{'); |
1024 | 3.94k | if (flags & FWUPD_JSON_EXPORT_FLAG_INDENT) |
1025 | 0 | g_string_append_c(str, '\n'); |
1026 | | |
1027 | 8.35k | for (guint i = 0; i < self->items->len; i++) { |
1028 | 4.40k | FwupdJsonObjectEntry *entry = g_ptr_array_index(self->items, i); |
1029 | | |
1030 | 4.40k | if (flags & FWUPD_JSON_EXPORT_FLAG_INDENT) |
1031 | 0 | fwupd_json_indent(str, depth + 1); |
1032 | 4.40k | g_string_append_printf(str, "\"%s\": ", entry->key); |
1033 | 4.40k | fwupd_json_node_append_string(entry->json_node, str, depth + 1, flags); |
1034 | 4.40k | if (flags & FWUPD_JSON_EXPORT_FLAG_INDENT) { |
1035 | 0 | if (i != self->items->len - 1) |
1036 | 0 | g_string_append_c(str, ','); |
1037 | 0 | g_string_append_c(str, '\n'); |
1038 | 4.40k | } else { |
1039 | 4.40k | if (i != self->items->len - 1) |
1040 | 2.84k | g_string_append(str, ", "); |
1041 | 4.40k | } |
1042 | 4.40k | } |
1043 | | |
1044 | | /* end */ |
1045 | 3.94k | if (flags & FWUPD_JSON_EXPORT_FLAG_INDENT) |
1046 | 0 | fwupd_json_indent(str, depth); |
1047 | 3.94k | g_string_append_c(str, '}'); |
1048 | 3.94k | } |
1049 | | |
1050 | | /** |
1051 | | * fwupd_json_object_to_string: |
1052 | | * @self: a #FwupdJsonObject |
1053 | | * @flags: some #FwupdJsonExportFlags e.g. #FWUPD_JSON_EXPORT_FLAG_INDENT |
1054 | | * |
1055 | | * Converts the JSON object to a string representation. |
1056 | | * |
1057 | | * Returns: (transfer full): a #GString |
1058 | | * |
1059 | | * Since: 2.1.1 |
1060 | | **/ |
1061 | | GString * |
1062 | | fwupd_json_object_to_string(FwupdJsonObject *self, FwupdJsonExportFlags flags) |
1063 | 0 | { |
1064 | 0 | GString *str = g_string_new(NULL); |
1065 | 0 | fwupd_json_object_append_string(self, str, 0, flags); |
1066 | 0 | if (flags & FWUPD_JSON_EXPORT_FLAG_TRAILING_NEWLINE) |
1067 | 0 | g_string_append_c(str, '\n'); |
1068 | 0 | return str; |
1069 | 0 | } |
1070 | | |
1071 | | /** |
1072 | | * fwupd_json_object_to_bytes: |
1073 | | * @self: a #FwupdJsonObject |
1074 | | * @flags: some #FwupdJsonExportFlags e.g. #FWUPD_JSON_EXPORT_FLAG_INDENT |
1075 | | * |
1076 | | * Converts the JSON object to UTF-8 bytes. |
1077 | | * |
1078 | | * Returns: (transfer full): a #GBytes |
1079 | | * |
1080 | | * Since: 2.1.1 |
1081 | | **/ |
1082 | | GBytes * |
1083 | | fwupd_json_object_to_bytes(FwupdJsonObject *self, FwupdJsonExportFlags flags) |
1084 | 0 | { |
1085 | 0 | GString *str = g_string_new(NULL); |
1086 | 0 | fwupd_json_object_append_string(self, str, 0, flags); |
1087 | 0 | if (flags & FWUPD_JSON_EXPORT_FLAG_TRAILING_NEWLINE) |
1088 | 0 | g_string_append_c(str, '\n'); |
1089 | 0 | return g_string_free_to_bytes(str); |
1090 | 0 | } |