Coverage Report

Created: 2025-08-26 06:51

/src/tinysparql/subprojects/json-glib-1.10.6/json-glib/json-builder.c
Line
Count
Source (jump to first uncovered line)
1
/* json-generator.c - JSON tree builder
2
 *
3
 * This file is part of JSON-GLib
4
 *
5
 * SPDX-FileCopyrightText: 2010  Luca Bruno <lethalman88@gmail.com>
6
 * SPDX-FileCopyrightText: 2015  Collabora Ltd.
7
 * SPDX-License-Identifier: LGPL-2.1-or-later
8
 *
9
 * This library is free software; you can redistribute it and/or
10
 * modify it under the terms of the GNU Lesser General Public
11
 * License as published by the Free Software Foundation; either
12
 * version 2.1 of the License, or (at your option) any later version.
13
 *
14
 * This library is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17
 * Lesser General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU Lesser General Public
20
 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
21
 *
22
 * Author:
23
 *   Luca Bruno  <lethalman88@gmail.com>
24
 *   Philip Withnall  <philip.withnall@collabora.co.uk>
25
 */
26
27
/**
28
 * JsonBuilder:
29
 *
30
 * `JsonBuilder` provides an object for generating a JSON tree.
31
 *
32
 * The root of the JSON tree can be either a [struct@Json.Object] or a [struct@Json.Array].
33
 * Thus the first call must necessarily be either
34
 * [method@Json.Builder.begin_object] or [method@Json.Builder.begin_array].
35
 *
36
 * For convenience to language bindings, most `JsonBuilder` method return the
37
 * instance, making it easy to chain function calls.
38
 *
39
 * ## Using `JsonBuilder`
40
 *
41
 * ```c
42
 * g_autoptr(JsonBuilder) builder = json_builder_new ();
43
 *
44
 * json_builder_begin_object (builder);
45
 *
46
 * json_builder_set_member_name (builder, "url");
47
 * json_builder_add_string_value (builder, "http://www.gnome.org/img/flash/two-thirty.png");
48
 *
49
 * json_builder_set_member_name (builder, "size");
50
 * json_builder_begin_array (builder);
51
 * json_builder_add_int_value (builder, 652);
52
 * json_builder_add_int_value (builder, 242);
53
 * json_builder_end_array (builder);
54
 *
55
 * json_builder_end_object (builder);
56
 *
57
 * g_autoptr(JsonNode) root = json_builder_get_root (builder);
58
 *
59
 * g_autoptr(JsonGenerator) gen = json_generator_new ();
60
 * json_generator_set_root (gen, root);
61
 * g_autofree char *str = json_generator_to_data (gen, NULL);
62
 *
63
 * // str now contains the following JSON data
64
 * // { "url" : "http://www.gnome.org/img/flash/two-thirty.png", "size" : [ 652, 242 ] }
65
 * ```
66
 */
67
68
#include "config.h"
69
70
#include <stdlib.h>
71
#include <string.h>
72
73
#include "json-types-private.h"
74
75
#include "json-builder.h"
76
77
struct _JsonBuilderPrivate
78
{
79
  GQueue *stack;
80
  JsonNode *root;
81
  gboolean immutable;
82
};
83
84
enum
85
{
86
  PROP_IMMUTABLE = 1,
87
  PROP_LAST
88
};
89
90
static GParamSpec *builder_props[PROP_LAST] = { NULL, };
91
92
typedef enum
93
{
94
  JSON_BUILDER_MODE_OBJECT,
95
  JSON_BUILDER_MODE_ARRAY,
96
  JSON_BUILDER_MODE_MEMBER
97
} JsonBuilderMode;
98
99
typedef struct
100
{
101
  JsonBuilderMode mode;
102
103
  union
104
  {
105
    JsonObject *object;
106
    JsonArray *array;
107
  } data;
108
  gchar *member_name;
109
} JsonBuilderState;
110
111
static void
112
json_builder_state_free (JsonBuilderState *state)
113
0
{
114
0
  if (G_LIKELY (state))
115
0
    {
116
0
      switch (state->mode)
117
0
        {
118
0
        case JSON_BUILDER_MODE_OBJECT:
119
0
        case JSON_BUILDER_MODE_MEMBER:
120
0
          json_object_unref (state->data.object);
121
0
          g_free (state->member_name);
122
0
          state->data.object = NULL;
123
0
          state->member_name = NULL;
124
0
          break;
125
126
0
        case JSON_BUILDER_MODE_ARRAY:
127
0
          json_array_unref (state->data.array);
128
0
          state->data.array = NULL;
129
0
          break;
130
131
0
        default:
132
0
          g_assert_not_reached ();
133
0
        }
134
135
0
      g_free (state);
136
0
    }
137
0
}
138
139
G_DEFINE_TYPE_WITH_PRIVATE (JsonBuilder, json_builder, G_TYPE_OBJECT)
140
141
static void
142
json_builder_free_all_state (JsonBuilder *builder)
143
0
{
144
0
  JsonBuilderState *state;
145
146
0
  while (!g_queue_is_empty (builder->priv->stack))
147
0
    {
148
0
      state = g_queue_pop_head (builder->priv->stack);
149
0
      json_builder_state_free (state);
150
0
    }
151
152
0
  if (builder->priv->root)
153
0
    {
154
0
      json_node_unref (builder->priv->root);
155
0
      builder->priv->root = NULL;
156
0
    }
157
0
}
158
159
static void
160
json_builder_finalize (GObject *gobject)
161
0
{
162
0
  JsonBuilderPrivate *priv = json_builder_get_instance_private ((JsonBuilder *) gobject);
163
164
0
  json_builder_free_all_state (JSON_BUILDER (gobject));
165
166
0
  g_queue_free (priv->stack);
167
0
  priv->stack = NULL;
168
169
0
  G_OBJECT_CLASS (json_builder_parent_class)->finalize (gobject);
170
0
}
171
172
static void
173
json_builder_set_property (GObject      *gobject,
174
                           guint         prop_id,
175
                           const GValue *value,
176
                           GParamSpec   *pspec)
177
0
{
178
0
  JsonBuilderPrivate *priv = JSON_BUILDER (gobject)->priv;
179
180
0
  switch (prop_id)
181
0
    {
182
0
    case PROP_IMMUTABLE:
183
      /* Construct-only. */
184
0
      priv->immutable = g_value_get_boolean (value);
185
0
      break;
186
0
    default:
187
0
      G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
188
0
      break;
189
0
    }
190
0
}
191
192
static void
193
json_builder_get_property (GObject    *gobject,
194
                           guint       prop_id,
195
                           GValue     *value,
196
                           GParamSpec *pspec)
197
0
{
198
0
  JsonBuilderPrivate *priv = JSON_BUILDER (gobject)->priv;
199
200
0
  switch (prop_id)
201
0
    {
202
0
    case PROP_IMMUTABLE:
203
0
      g_value_set_boolean (value, priv->immutable);
204
0
      break;
205
0
    default:
206
0
      G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
207
0
      break;
208
0
    }
209
0
}
210
211
static void
212
json_builder_class_init (JsonBuilderClass *klass)
213
0
{
214
0
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
215
216
  /**
217
   * JsonBuilder:immutable:
218
   *
219
   * Whether the tree should be immutable when created.
220
   *
221
   * Making the output immutable on creation avoids the expense
222
   * of traversing it to make it immutable later.
223
   *
224
   * Since: 1.2
225
   */
226
0
  builder_props[PROP_IMMUTABLE] =
227
0
    g_param_spec_boolean ("immutable",
228
0
                          "Immutable Output",
229
0
                          "Whether the builder output is immutable.",
230
0
                          FALSE,
231
0
                          G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
232
233
0
  gobject_class->set_property = json_builder_set_property;
234
0
  gobject_class->get_property = json_builder_get_property;
235
0
  gobject_class->finalize = json_builder_finalize;
236
237
0
  g_object_class_install_properties (gobject_class, PROP_LAST, builder_props);
238
0
}
239
240
static void
241
json_builder_init (JsonBuilder *builder)
242
0
{
243
0
  JsonBuilderPrivate *priv = json_builder_get_instance_private (builder);
244
245
0
  builder->priv = priv;
246
247
0
  priv->stack = g_queue_new ();
248
0
  priv->root = NULL;
249
0
}
250
251
static inline JsonBuilderMode
252
json_builder_current_mode (JsonBuilder *builder)
253
0
{
254
0
  JsonBuilderState *state = g_queue_peek_head (builder->priv->stack);
255
0
  return state->mode;
256
0
}
257
258
static inline gboolean
259
json_builder_is_valid_add_mode (JsonBuilder *builder)
260
0
{
261
0
  JsonBuilderMode mode = json_builder_current_mode (builder);
262
0
  return mode == JSON_BUILDER_MODE_MEMBER || mode == JSON_BUILDER_MODE_ARRAY;
263
0
}
264
265
/**
266
 * json_builder_new:
267
 *
268
 * Creates a new `JsonBuilder`.
269
 *
270
 * You can use this object to generate a JSON tree and obtain the root node.
271
 *
272
 * Return value: the newly created builder instance
273
 */
274
JsonBuilder *
275
json_builder_new (void)
276
0
{
277
0
  return g_object_new (JSON_TYPE_BUILDER, NULL);
278
0
}
279
280
/**
281
 * json_builder_new_immutable: (constructor)
282
 *
283
 * Creates a new, immutable `JsonBuilder` instance.
284
 *
285
 * It is equivalent to setting the [property@Json.Builder:immutable] property
286
 * set to `TRUE` at construction time.
287
 *
288
 * Since: 1.2
289
 * Returns: (transfer full): the newly create builder instance
290
 */
291
JsonBuilder *
292
json_builder_new_immutable (void)
293
0
{
294
0
  return g_object_new (JSON_TYPE_BUILDER, "immutable", TRUE, NULL);
295
0
}
296
297
/**
298
 * json_builder_get_root:
299
 * @builder: a builder
300
 *
301
 * Returns the root of the currently constructed tree.
302
 *
303
 * if the build is incomplete (ie: if there are any opened objects, or any
304
 * open object members and array elements) then this function will return
305
 * `NULL`.
306
 *
307
 * Return value: (nullable) (transfer full): the root node
308
 */
309
JsonNode *
310
json_builder_get_root (JsonBuilder *builder)
311
0
{
312
0
  JsonNode *root = NULL;
313
314
0
  g_return_val_if_fail (JSON_IS_BUILDER (builder), NULL);
315
316
0
  if (builder->priv->root)
317
0
    root = json_node_copy (builder->priv->root);
318
319
  /* Sanity check. */
320
0
  g_assert (!builder->priv->immutable ||
321
0
            root == NULL ||
322
0
            json_node_is_immutable (root));
323
324
0
  return root;
325
0
}
326
327
/**
328
 * json_builder_reset:
329
 * @builder: a builder
330
 *
331
 * Resets the state of the builder back to its initial state.
332
 */
333
void
334
json_builder_reset (JsonBuilder *builder)
335
0
{
336
0
  g_return_if_fail (JSON_IS_BUILDER (builder));
337
338
0
  json_builder_free_all_state (builder);
339
0
}
340
341
/**
342
 * json_builder_begin_object:
343
 * @builder: a builder
344
 *
345
 * Opens an object inside the given builder.
346
 *
347
 * You can add a new member to the object by using [method@Json.Builder.set_member_name],
348
 * followed by [method@Json.Builder.add_value].
349
 *
350
 * Once you added all members to the object, you must call [method@Json.Builder.end_object]
351
 * to close the object.
352
 *
353
 * If the builder is in an inconsistent state, this function will return `NULL`.
354
 *
355
 * Return value: (nullable) (transfer none): the builder instance
356
 */
357
JsonBuilder *
358
json_builder_begin_object (JsonBuilder *builder)
359
0
{
360
0
  JsonObject *object;
361
0
  JsonBuilderState *state;
362
0
  JsonBuilderState *cur_state;
363
364
0
  g_return_val_if_fail (JSON_IS_BUILDER (builder), NULL);
365
0
  g_return_val_if_fail (builder->priv->root == NULL, NULL);
366
0
  g_return_val_if_fail (g_queue_is_empty (builder->priv->stack) || json_builder_is_valid_add_mode (builder), NULL);
367
368
0
  object = json_object_new ();
369
0
  cur_state = g_queue_peek_head (builder->priv->stack);
370
0
  if (cur_state)
371
0
    {
372
0
      switch (cur_state->mode)
373
0
        {
374
0
        case JSON_BUILDER_MODE_ARRAY:
375
0
          json_array_add_object_element (cur_state->data.array, json_object_ref (object));
376
0
          break;
377
378
0
        case JSON_BUILDER_MODE_MEMBER:
379
0
          json_object_set_object_member (cur_state->data.object, cur_state->member_name, json_object_ref (object));
380
0
          g_free (cur_state->member_name);
381
0
          cur_state->member_name = NULL;
382
0
          cur_state->mode = JSON_BUILDER_MODE_OBJECT;
383
0
          break;
384
385
0
        default:
386
0
          g_assert_not_reached ();
387
0
        }
388
0
    }
389
390
0
  state = g_new (JsonBuilderState, 1);
391
0
  state->data.object = object;
392
0
  state->member_name = NULL;
393
0
  state->mode = JSON_BUILDER_MODE_OBJECT;
394
0
  g_queue_push_head (builder->priv->stack, state);
395
396
0
  return builder;
397
0
}
398
399
/**
400
 * json_builder_end_object:
401
 * @builder: a builder
402
 *
403
 * Closes the object inside the given builder that was opened by the most
404
 * recent call to [method@Json.Builder.begin_object].
405
 *
406
 * This function cannot be called after [method@Json.Builder.set_member_name].
407
 *
408
 * Return value: (nullable) (transfer none): the builder instance
409
 */
410
JsonBuilder *
411
json_builder_end_object (JsonBuilder *builder)
412
0
{
413
0
  JsonBuilderState *state;
414
415
0
  g_return_val_if_fail (JSON_IS_BUILDER (builder), NULL);
416
0
  g_return_val_if_fail (!g_queue_is_empty (builder->priv->stack), NULL);
417
0
  g_return_val_if_fail (json_builder_current_mode (builder) == JSON_BUILDER_MODE_OBJECT, NULL);
418
419
0
  state = g_queue_pop_head (builder->priv->stack);
420
421
0
  if (builder->priv->immutable)
422
0
    json_object_seal (state->data.object);
423
424
0
  if (g_queue_is_empty (builder->priv->stack))
425
0
    {
426
0
      builder->priv->root = json_node_new (JSON_NODE_OBJECT);
427
0
      json_node_take_object (builder->priv->root, json_object_ref (state->data.object));
428
429
0
      if (builder->priv->immutable)
430
0
        json_node_seal (builder->priv->root);
431
0
    }
432
433
0
  json_builder_state_free (state);
434
435
0
  return builder;
436
0
}
437
438
/**
439
 * json_builder_begin_array:
440
 * @builder: a builder
441
 *
442
 * Opens an array inside the given builder.
443
 *
444
 * You can add a new element to the array by using [method@Json.Builder.add_value].
445
 *
446
 * Once you added all elements to the array, you must call
447
 * [method@Json.Builder.end_array] to close the array.
448
 *
449
 * Return value: (nullable) (transfer none): the builder instance
450
 */
451
JsonBuilder *
452
json_builder_begin_array (JsonBuilder *builder)
453
0
{
454
0
  JsonArray *array;
455
0
  JsonBuilderState *state;
456
0
  JsonBuilderState *cur_state;
457
458
0
  g_return_val_if_fail (JSON_IS_BUILDER (builder), NULL);
459
0
  g_return_val_if_fail (builder->priv->root == NULL, NULL);
460
0
  g_return_val_if_fail (g_queue_is_empty (builder->priv->stack) || json_builder_is_valid_add_mode (builder), NULL);
461
462
0
  array = json_array_new ();
463
0
  cur_state = g_queue_peek_head (builder->priv->stack);
464
0
  if (cur_state)
465
0
    {
466
0
      switch (cur_state->mode)
467
0
        {
468
0
        case JSON_BUILDER_MODE_ARRAY:
469
0
          json_array_add_array_element (cur_state->data.array, json_array_ref (array));
470
0
          break;
471
472
0
        case JSON_BUILDER_MODE_MEMBER:
473
0
          json_object_set_array_member (cur_state->data.object, cur_state->member_name, json_array_ref (array));
474
0
          g_free (cur_state->member_name);
475
0
          cur_state->member_name = NULL;
476
0
          cur_state->mode = JSON_BUILDER_MODE_OBJECT;
477
0
          break;
478
479
0
        default:
480
0
          g_assert_not_reached ();
481
0
        }
482
0
    }
483
484
0
  state = g_new (JsonBuilderState, 1);
485
0
  state->data.array = array;
486
0
  state->mode = JSON_BUILDER_MODE_ARRAY;
487
0
  g_queue_push_head (builder->priv->stack, state);
488
489
0
  return builder;
490
0
}
491
492
/**
493
 * json_builder_end_array:
494
 * @builder: a builder
495
 *
496
 * Closes the array inside the given builder that was opened by the most
497
 * recent call to [method@Json.Builder.begin_array].
498
 *
499
 * This function cannot be called after [method@Json.Builder.set_member_name].
500
 *
501
 * Return value: (nullable) (transfer none): the builder instance
502
 */
503
JsonBuilder *
504
json_builder_end_array (JsonBuilder *builder)
505
0
{
506
0
  JsonBuilderState *state;
507
508
0
  g_return_val_if_fail (JSON_IS_BUILDER (builder), NULL);
509
0
  g_return_val_if_fail (!g_queue_is_empty (builder->priv->stack), NULL);
510
0
  g_return_val_if_fail (json_builder_current_mode (builder) == JSON_BUILDER_MODE_ARRAY, NULL);
511
512
0
  state = g_queue_pop_head (builder->priv->stack);
513
514
0
  if (builder->priv->immutable)
515
0
    json_array_seal (state->data.array);
516
517
0
  if (g_queue_is_empty (builder->priv->stack))
518
0
    {
519
0
      builder->priv->root = json_node_new (JSON_NODE_ARRAY);
520
0
      json_node_take_array (builder->priv->root, json_array_ref (state->data.array));
521
522
0
      if (builder->priv->immutable)
523
0
        json_node_seal (builder->priv->root);
524
0
    }
525
526
0
  json_builder_state_free (state);
527
528
0
  return builder;
529
0
}
530
531
/**
532
 * json_builder_set_member_name:
533
 * @builder: a builder
534
 * @member_name: the name of the member
535
 *
536
 * Sets the name of the member in an object.
537
 *
538
 * This function must be followed by of these functions:
539
 *
540
 *  - [method@Json.Builder.add_value], to add a scalar value to the member
541
 *  - [method@Json.Builder.begin_object], to add an object to the member
542
 *  - [method@Json.Builder.begin_array], to add an array to the member
543
 *
544
 * This function can only be called within an open object.
545
 *
546
 * Return value: (nullable) (transfer none): the builder instance
547
 */
548
JsonBuilder *
549
json_builder_set_member_name (JsonBuilder *builder,
550
                              const gchar *member_name)
551
0
{
552
0
  JsonBuilderState *state;
553
554
0
  g_return_val_if_fail (JSON_IS_BUILDER (builder), NULL);
555
0
  g_return_val_if_fail (member_name != NULL, NULL);
556
0
  g_return_val_if_fail (!g_queue_is_empty (builder->priv->stack), NULL);
557
0
  g_return_val_if_fail (json_builder_current_mode (builder) == JSON_BUILDER_MODE_OBJECT, NULL);
558
559
0
  state = g_queue_peek_head (builder->priv->stack);
560
0
  state->member_name = g_strdup (member_name);
561
0
  state->mode = JSON_BUILDER_MODE_MEMBER;
562
563
0
  return builder;
564
0
}
565
566
/**
567
 * json_builder_add_value:
568
 * @builder: a builder
569
 * @node: (transfer full): the value of the member or element
570
 *
571
 * Adds a value to the currently open object member or array.
572
 *
573
 * If called after [method@Json.Builder.set_member_name], sets the given node
574
 * as the value of the current member in the open object; otherwise, the node
575
 * is appended to the elements of the open array.
576
 *
577
 * The builder will take ownership of the node.
578
 *
579
 * Return value: (nullable) (transfer none): the builder instance
580
 */
581
JsonBuilder *
582
json_builder_add_value (JsonBuilder *builder,
583
                        JsonNode    *node)
584
0
{
585
0
  JsonBuilderState *state;
586
587
0
  g_return_val_if_fail (JSON_IS_BUILDER (builder), NULL);
588
0
  g_return_val_if_fail (node != NULL, NULL);
589
0
  g_return_val_if_fail (!g_queue_is_empty (builder->priv->stack), NULL);
590
0
  g_return_val_if_fail (json_builder_is_valid_add_mode (builder), NULL);
591
592
0
  state = g_queue_peek_head (builder->priv->stack);
593
594
0
  if (builder->priv->immutable)
595
0
    json_node_seal (node);
596
597
0
  switch (state->mode)
598
0
    {
599
0
    case JSON_BUILDER_MODE_MEMBER:
600
0
      json_object_set_member (state->data.object, state->member_name, node);
601
0
      g_free (state->member_name);
602
0
      state->member_name = NULL;
603
0
      state->mode = JSON_BUILDER_MODE_OBJECT;
604
0
      break;
605
606
0
    case JSON_BUILDER_MODE_ARRAY:
607
0
      json_array_add_element (state->data.array, node);
608
0
      break;
609
610
0
    default:
611
0
      g_assert_not_reached ();
612
0
    }
613
614
0
  return builder;
615
0
}
616
617
/**
618
 * json_builder_add_int_value:
619
 * @builder: a builder
620
 * @value: the value of the member or element
621
 *
622
 * Adds an integer value to the currently open object member or array.
623
 *
624
 * If called after [method@Json.Builder.set_member_name], sets the given value
625
 * as the value of the current member in the open object; otherwise, the value
626
 * is appended to the elements of the open array.
627
 *
628
 * See also: [method@Json.Builder.add_value]
629
 *
630
 * Return value: (nullable) (transfer none): the builder instance
631
 */
632
JsonBuilder *
633
json_builder_add_int_value (JsonBuilder *builder,
634
                            gint64       value)
635
0
{
636
0
  JsonBuilderState *state;
637
638
0
  g_return_val_if_fail (JSON_IS_BUILDER (builder), NULL);
639
0
  g_return_val_if_fail (!g_queue_is_empty (builder->priv->stack), NULL);
640
0
  g_return_val_if_fail (json_builder_is_valid_add_mode (builder), NULL);
641
642
0
  state = g_queue_peek_head (builder->priv->stack);
643
0
  switch (state->mode)
644
0
    {
645
0
    case JSON_BUILDER_MODE_MEMBER:
646
0
      json_object_set_int_member (state->data.object, state->member_name, value);
647
0
      g_free (state->member_name);
648
0
      state->member_name = NULL;
649
0
      state->mode = JSON_BUILDER_MODE_OBJECT;
650
0
      break;
651
652
0
    case JSON_BUILDER_MODE_ARRAY:
653
0
      json_array_add_int_element (state->data.array, value);
654
0
      break;
655
656
0
    default:
657
0
      g_assert_not_reached ();
658
0
    }
659
660
0
  return builder;
661
0
}
662
663
/**
664
 * json_builder_add_double_value:
665
 * @builder: a builder
666
 * @value: the value of the member or element
667
 *
668
 * Adds a floating point value to the currently open object member or array.
669
 *
670
 * If called after [method@Json.Builder.set_member_name], sets the given value
671
 * as the value of the current member in the open object; otherwise, the value
672
 * is appended to the elements of the open array.
673
 *
674
 * See also: [method@Json.Builder.add_value]
675
 *
676
 * Return value: (nullable) (transfer none): the builder instance
677
 */
678
JsonBuilder *
679
json_builder_add_double_value (JsonBuilder *builder,
680
                               gdouble      value)
681
0
{
682
0
  JsonBuilderState *state;
683
684
0
  g_return_val_if_fail (JSON_IS_BUILDER (builder), NULL);
685
0
  g_return_val_if_fail (!g_queue_is_empty (builder->priv->stack), NULL);
686
0
  g_return_val_if_fail (json_builder_is_valid_add_mode (builder), NULL);
687
688
0
  state = g_queue_peek_head (builder->priv->stack);
689
690
0
  switch (state->mode)
691
0
    {
692
0
    case JSON_BUILDER_MODE_MEMBER:
693
0
      json_object_set_double_member (state->data.object, state->member_name, value);
694
0
      g_free (state->member_name);
695
0
      state->member_name = NULL;
696
0
      state->mode = JSON_BUILDER_MODE_OBJECT;
697
0
      break;
698
699
0
    case JSON_BUILDER_MODE_ARRAY:
700
0
      json_array_add_double_element (state->data.array, value);
701
0
      break;
702
703
0
    default:
704
0
      g_assert_not_reached ();
705
0
    }
706
707
0
  return builder;
708
0
}
709
710
/**
711
 * json_builder_add_boolean_value:
712
 * @builder: a builder
713
 * @value: the value of the member or element
714
 *
715
 * Adds a boolean value to the currently open object member or array.
716
 *
717
 * If called after [method@Json.Builder.set_member_name], sets the given value
718
 * as the value of the current member in the open object; otherwise, the value
719
 * is appended to the elements of the open array.
720
 *
721
 * See also: [method@Json.Builder.add_value]
722
 *
723
 * Return value: (nullable) (transfer none): the builder instance
724
 */
725
JsonBuilder *
726
json_builder_add_boolean_value (JsonBuilder *builder,
727
                                gboolean     value)
728
0
{
729
0
  JsonBuilderState *state;
730
731
0
  g_return_val_if_fail (JSON_IS_BUILDER (builder), NULL);
732
0
  g_return_val_if_fail (!g_queue_is_empty (builder->priv->stack), NULL);
733
0
  g_return_val_if_fail (json_builder_is_valid_add_mode (builder), NULL);
734
735
0
  state = g_queue_peek_head (builder->priv->stack);
736
737
0
  switch (state->mode)
738
0
    {
739
0
    case JSON_BUILDER_MODE_MEMBER:
740
0
      json_object_set_boolean_member (state->data.object, state->member_name, value);
741
0
      g_free (state->member_name);
742
0
      state->member_name = NULL;
743
0
      state->mode = JSON_BUILDER_MODE_OBJECT;
744
0
      break;
745
746
0
    case JSON_BUILDER_MODE_ARRAY:
747
0
      json_array_add_boolean_element (state->data.array, value);
748
0
      break;
749
750
0
    default:
751
0
      g_assert_not_reached ();
752
0
    }
753
754
0
  return builder;
755
0
}
756
757
/**
758
 * json_builder_add_string_value:
759
 * @builder: a builder
760
 * @value: the value of the member or element
761
 *
762
 * Adds a string value to the currently open object member or array.
763
 *
764
 * If called after [method@Json.Builder.set_member_name], sets the given value
765
 * as the value of the current member in the open object; otherwise, the value
766
 * is appended to the elements of the open array.
767
 *
768
 * See also: [method@Json.Builder.add_value]
769
 *
770
 * Return value: (nullable) (transfer none): the builder instance
771
 */
772
JsonBuilder *
773
json_builder_add_string_value (JsonBuilder *builder,
774
                               const gchar *value)
775
0
{
776
0
  JsonBuilderState *state;
777
778
0
  g_return_val_if_fail (JSON_IS_BUILDER (builder), NULL);
779
0
  g_return_val_if_fail (!g_queue_is_empty (builder->priv->stack), NULL);
780
0
  g_return_val_if_fail (json_builder_is_valid_add_mode (builder), NULL);
781
782
0
  state = g_queue_peek_head (builder->priv->stack);
783
784
0
  switch (state->mode)
785
0
    {
786
0
    case JSON_BUILDER_MODE_MEMBER:
787
0
      json_object_set_string_member (state->data.object, state->member_name, value);
788
0
      g_free (state->member_name);
789
0
      state->member_name = NULL;
790
0
      state->mode = JSON_BUILDER_MODE_OBJECT;
791
0
      break;
792
793
0
    case JSON_BUILDER_MODE_ARRAY:
794
0
      json_array_add_string_element (state->data.array, value);
795
0
      break;
796
797
0
    default:
798
0
      g_assert_not_reached ();
799
0
    }
800
801
0
  return builder;
802
0
}
803
804
/**
805
 * json_builder_add_null_value:
806
 * @builder: a builder
807
 *
808
 * Adds a null value to the currently open object member or array.
809
 *
810
 * If called after [method@Json.Builder.set_member_name], sets the given value
811
 * as the value of the current member in the open object; otherwise, the value
812
 * is appended to the elements of the open array.
813
 *
814
 * See also: [method@Json.Builder.add_value]
815
 *
816
 * Return value: (nullable) (transfer none): the builder instance
817
 */
818
JsonBuilder *
819
json_builder_add_null_value (JsonBuilder *builder)
820
0
{
821
0
  JsonBuilderState *state;
822
823
0
  g_return_val_if_fail (JSON_IS_BUILDER (builder), NULL);
824
0
  g_return_val_if_fail (!g_queue_is_empty (builder->priv->stack), NULL);
825
0
  g_return_val_if_fail (json_builder_is_valid_add_mode (builder), NULL);
826
827
0
  state = g_queue_peek_head (builder->priv->stack);
828
829
0
  switch (state->mode)
830
0
    {
831
0
    case JSON_BUILDER_MODE_MEMBER:
832
0
      json_object_set_null_member (state->data.object, state->member_name);
833
0
      g_free (state->member_name);
834
0
      state->member_name = NULL;
835
0
      state->mode = JSON_BUILDER_MODE_OBJECT;
836
0
      break;
837
838
0
    case JSON_BUILDER_MODE_ARRAY:
839
0
      json_array_add_null_element (state->data.array);
840
0
      break;
841
842
0
    default:
843
0
      g_assert_not_reached ();
844
0
    }
845
846
0
  return builder;
847
0
}