Coverage Report

Created: 2026-04-12 06:29

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/tinysparql/subprojects/json-glib-1.10.6/json-glib/json-generator.c
Line
Count
Source
1
/* json-generator.c - JSON streams generator
2
 *
3
 * This file is part of JSON-GLib
4
 *
5
 * SPDX-FileCopyrightText: 2007  OpenedHand Ltd.
6
 * SPDX-FileCopyrightText: 2009  Intel Corp.
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
 *   Emmanuele Bassi  <ebassi@linux.intel.com>
24
 */
25
26
/**
27
 * JsonGenerator: 
28
 *
29
 * `JsonGenerator` provides an object for generating a JSON data stream
30
 * from a tree of [struct@Json.Node] instances, and put it into a buffer
31
 * or a file.
32
 */
33
34
#include "config.h"
35
36
#include <stdlib.h>
37
#include <string.h>
38
39
#include "json-types-private.h"
40
41
#include "json-generator.h"
42
43
struct _JsonGeneratorPrivate
44
{
45
  JsonNode *root;
46
47
  guint indent;
48
  gunichar indent_char;
49
50
  guint pretty : 1;
51
};
52
53
enum
54
{
55
  PROP_0,
56
57
  PROP_PRETTY,
58
  PROP_INDENT,
59
  PROP_ROOT,
60
  PROP_INDENT_CHAR,
61
62
  PROP_LAST
63
};
64
65
static void   dump_value  (GString       *buffer,
66
                           JsonNode      *node);
67
static void   dump_array  (JsonGenerator *generator,
68
                           GString       *buffer,
69
                           gint           level,
70
                           JsonArray     *array);
71
static void   dump_object (JsonGenerator *generator,
72
                           GString       *buffer,
73
                           gint           level,
74
                           JsonObject    *object);
75
76
static GParamSpec *generator_props[PROP_LAST] = { NULL, };
77
78
0
G_DEFINE_TYPE_WITH_PRIVATE (JsonGenerator, json_generator, G_TYPE_OBJECT)
79
0
80
0
static void
81
0
json_strescape (GString     *output,
82
0
                const gchar *str)
83
0
{
84
0
  const gchar *p;
85
0
  const gchar *end;
86
0
  gsize len;
87
88
0
  len = strlen (str);
89
0
  end = str + len;
90
91
0
  for (p = str; p < end; p++)
92
0
    {
93
0
      if (*p == '\\' || *p == '"')
94
0
        {
95
0
          g_string_append_c (output, '\\');
96
0
          g_string_append_c (output, *p);
97
0
        }
98
0
      else if ((*p > 0 && *p < 0x1f) || *p == 0x7f)
99
0
        {
100
0
          switch (*p)
101
0
            {
102
0
            case '\b':
103
0
              g_string_append (output, "\\b");
104
0
              break;
105
0
            case '\f':
106
0
              g_string_append (output, "\\f");
107
0
              break;
108
0
            case '\n':
109
0
              g_string_append (output, "\\n");
110
0
              break;
111
0
            case '\r':
112
0
              g_string_append (output, "\\r");
113
0
              break;
114
0
            case '\t':
115
0
              g_string_append (output, "\\t");
116
0
              break;
117
0
            default:
118
0
              g_string_append_printf (output, "\\u00%02x", (guint)*p);
119
0
              break;
120
0
            }
121
0
        }
122
0
      else
123
0
        {
124
0
          g_string_append_c (output, *p);
125
0
        }
126
0
    }
127
0
}
128
129
static void
130
json_generator_finalize (GObject *gobject)
131
0
{
132
0
  JsonGeneratorPrivate *priv;
133
134
0
  priv = json_generator_get_instance_private ((JsonGenerator *) gobject);
135
0
  if (priv->root != NULL)
136
0
    json_node_unref (priv->root);
137
138
0
  G_OBJECT_CLASS (json_generator_parent_class)->finalize (gobject);
139
0
}
140
141
static void
142
json_generator_set_property (GObject      *gobject,
143
                             guint         prop_id,
144
                             const GValue *value,
145
                             GParamSpec   *pspec)
146
0
{
147
0
  JsonGenerator *generator = JSON_GENERATOR (gobject);
148
149
0
  switch (prop_id)
150
0
    {
151
0
    case PROP_PRETTY:
152
0
      json_generator_set_pretty (generator, g_value_get_boolean (value));
153
0
      break;
154
155
0
    case PROP_INDENT:
156
0
      json_generator_set_indent (generator, g_value_get_uint (value));
157
0
      break;
158
159
0
    case PROP_INDENT_CHAR:
160
0
      json_generator_set_indent_char (generator, g_value_get_uint (value));
161
0
      break;
162
163
0
    case PROP_ROOT:
164
0
      json_generator_set_root (generator, g_value_get_boxed (value));
165
0
      break;
166
167
0
    default:
168
0
      G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
169
0
      break;
170
0
    }
171
0
}
172
173
static void
174
json_generator_get_property (GObject    *gobject,
175
                             guint       prop_id,
176
                             GValue     *value,
177
                             GParamSpec *pspec)
178
0
{
179
0
  JsonGeneratorPrivate *priv = JSON_GENERATOR (gobject)->priv;
180
181
0
  switch (prop_id)
182
0
    {
183
0
    case PROP_PRETTY:
184
0
      g_value_set_boolean (value, priv->pretty);
185
0
      break;
186
0
    case PROP_INDENT:
187
0
      g_value_set_uint (value, priv->indent);
188
0
      break;
189
0
    case PROP_INDENT_CHAR:
190
0
      g_value_set_uint (value, priv->indent_char);
191
0
      break;
192
0
    case PROP_ROOT:
193
0
      g_value_set_boxed (value, priv->root);
194
0
      break;
195
0
    default:
196
0
      G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
197
0
      break;
198
0
    }
199
0
}
200
201
static void
202
json_generator_class_init (JsonGeneratorClass *klass)
203
0
{
204
0
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
205
206
  /**
207
   * JsonGenerator:pretty: (attributes org.gtk.Property.get=json_generator_get_pretty org.gtk.Property.set=json_generator_set_pretty)
208
   *
209
   * Whether the output should be "pretty-printed", with indentation and
210
   * newlines.
211
   *
212
   * The indentation level can be controlled by using the
213
   * [property@Json.Generator:indent] property.
214
   */
215
0
  generator_props[PROP_PRETTY] =
216
0
    g_param_spec_boolean ("pretty",
217
0
                          "Pretty",
218
0
                          "Pretty-print the output",
219
0
                          FALSE,
220
0
                          G_PARAM_READWRITE);
221
222
  /**
223
   * JsonGenerator:indent: (attributes org.gtk.Property.get=json_generator_get_indent org.gtk.Property.set=json_generator_set_indent)
224
   *
225
   * Number of spaces to be used to indent when pretty printing.
226
   */
227
0
  generator_props[PROP_INDENT] =
228
0
    g_param_spec_uint ("indent",
229
0
                       "Indent",
230
0
                       "Number of indentation spaces",
231
0
                       0, G_MAXUINT,
232
0
                       2,
233
0
                       G_PARAM_READWRITE);
234
235
  /**
236
   * JsonGenerator:root: (attributes org.gtk.Property.get=json_generator_get_root org.gtk.Property.set=json_generator_set_root)
237
   *
238
   * The root node to be used when constructing a JSON data
239
   * stream.
240
   *
241
   * Since: 0.4
242
   */
243
0
  generator_props[PROP_ROOT] =
244
0
    g_param_spec_boxed ("root",
245
0
                        "Root",
246
0
                        "Root of the JSON data tree",
247
0
                        JSON_TYPE_NODE,
248
0
                        G_PARAM_READWRITE);
249
250
  /**
251
   * JsonGenerator:indent-char: (attributes org.gtk.Property.get=json_generator_get_indent_char org.gtk.Property.set=json_generator_set_indent_char)
252
   *
253
   * The character that should be used when indenting in pretty print.
254
   *
255
   * Since: 0.6
256
   */
257
0
  generator_props[PROP_INDENT_CHAR] =
258
0
    g_param_spec_unichar ("indent-char",
259
0
                          "Indent Char",
260
0
                          "Character that should be used when indenting",
261
0
                          ' ',
262
0
                          G_PARAM_READWRITE);
263
264
0
  gobject_class->set_property = json_generator_set_property;
265
0
  gobject_class->get_property = json_generator_get_property;
266
0
  gobject_class->finalize = json_generator_finalize;
267
0
  g_object_class_install_properties (gobject_class, PROP_LAST, generator_props);
268
0
}
269
270
static void
271
json_generator_init (JsonGenerator *generator)
272
0
{
273
0
  JsonGeneratorPrivate *priv = json_generator_get_instance_private (generator);
274
275
0
  generator->priv = priv;
276
277
0
  priv->pretty = FALSE;
278
0
  priv->indent = 2;
279
0
  priv->indent_char = ' ';
280
0
}
281
282
static void
283
dump_node (JsonGenerator *generator,
284
           GString       *buffer,
285
           gint           level,
286
           const gchar   *name,
287
           JsonNode      *node)
288
0
{
289
0
  JsonGeneratorPrivate *priv = generator->priv;
290
0
  gboolean pretty = priv->pretty;
291
0
  guint indent = priv->indent;
292
293
0
  if (pretty)
294
0
    {
295
0
      guint i;
296
297
0
      for (i = 0; i < (level * indent); i++)
298
0
        g_string_append_c (buffer, priv->indent_char);
299
0
    }
300
301
0
  if (name)
302
0
    {
303
0
      g_string_append_c (buffer, '"');
304
0
      json_strescape (buffer, name);
305
0
      g_string_append_c (buffer, '"');
306
307
0
      if (pretty)
308
0
        g_string_append (buffer, " : ");
309
0
      else
310
0
        g_string_append_c (buffer, ':');
311
0
    }
312
313
0
  switch (JSON_NODE_TYPE (node))
314
0
    {
315
0
    case JSON_NODE_NULL:
316
0
      g_string_append (buffer, "null");
317
0
      break;
318
319
0
    case JSON_NODE_VALUE:
320
0
      dump_value (buffer, node);
321
0
      break;
322
323
0
    case JSON_NODE_ARRAY:
324
0
      dump_array (generator, buffer, level,
325
0
                  json_node_get_array (node));
326
0
      break;
327
328
0
    case JSON_NODE_OBJECT:
329
0
      dump_object (generator, buffer, level,
330
0
                   json_node_get_object (node));
331
0
      break;
332
0
    }
333
0
}
334
335
static void
336
dump_value (GString  *buffer,
337
            JsonNode *node)
338
0
{
339
0
  const JsonValue *value;
340
341
0
  value = node->data.value;
342
343
0
  switch (value->type)
344
0
    {
345
0
    case JSON_VALUE_INT:
346
0
      g_string_append_printf (buffer, "%" G_GINT64_FORMAT, json_value_get_int (value));
347
0
      break;
348
349
0
    case JSON_VALUE_STRING:
350
0
      {
351
0
        g_string_append_c (buffer, '"');
352
0
        json_strescape (buffer, json_value_get_string (value));
353
0
        g_string_append_c (buffer, '"');
354
0
      }
355
0
      break;
356
357
0
    case JSON_VALUE_DOUBLE:
358
0
      {
359
0
        gchar buf[G_ASCII_DTOSTR_BUF_SIZE];
360
361
0
        g_string_append (buffer,
362
0
                         g_ascii_dtostr (buf, sizeof (buf),
363
0
                                         json_value_get_double (value)));
364
  /* ensure doubles don't become ints */
365
        /* also make sure not to append .0 that results in invalid exponential notation
366
         * since the numbers should be decimal, a hex 'e' or "E" can not be mistaken
367
         */
368
0
  if (g_strstr_len (buf, G_ASCII_DTOSTR_BUF_SIZE, ".") == NULL &&
369
0
            g_strstr_len (buf, G_ASCII_DTOSTR_BUF_SIZE, "e") == NULL &&
370
0
            g_strstr_len (buf, G_ASCII_DTOSTR_BUF_SIZE, "E") == NULL)
371
0
    {
372
0
      g_string_append (buffer, ".0");
373
0
          }
374
0
      }
375
0
      break;
376
377
0
    case JSON_VALUE_BOOLEAN:
378
0
      g_string_append (buffer, json_value_get_boolean (value) ? "true" : "false");
379
0
      break;
380
381
0
    case JSON_VALUE_NULL:
382
0
      g_string_append (buffer, "null");
383
0
      break;
384
385
0
    default:
386
0
      break;
387
0
    }
388
0
}
389
390
static void
391
dump_array (JsonGenerator *generator,
392
            GString       *buffer,
393
            gint           level,
394
            JsonArray     *array)
395
0
{
396
0
  JsonGeneratorPrivate *priv = generator->priv;
397
0
  guint array_len = json_array_get_length (array);
398
0
  guint i;
399
0
  gboolean pretty = priv->pretty;
400
0
  guint indent = priv->indent;
401
402
0
  g_string_append_c (buffer, '[');
403
404
0
  if (array_len == 0)
405
0
    goto out;
406
407
0
  for (i = 0; i < array_len; i++)
408
0
    {
409
0
      JsonNode *cur = json_array_get_element (array, i);
410
411
0
      if (i == 0 && pretty)
412
0
        g_string_append_c (buffer, '\n');
413
414
0
      dump_node (generator, buffer, level + 1, NULL, cur);
415
416
0
      if ((i + 1) != array_len)
417
0
        g_string_append_c (buffer, ',');
418
419
0
      if (pretty)
420
0
        g_string_append_c (buffer, '\n');
421
0
    }
422
423
0
  if (pretty)
424
0
    {
425
0
      for (i = 0; i < (level * indent); i++)
426
0
        g_string_append_c (buffer, priv->indent_char);
427
0
    }
428
429
0
out:
430
0
  g_string_append_c (buffer, ']');
431
0
}
432
433
static void
434
dump_object (JsonGenerator *generator,
435
             GString       *buffer,
436
             gint           level,
437
             JsonObject    *object)
438
0
{
439
0
  JsonGeneratorPrivate *priv = generator->priv;
440
0
  GQueue *members;
441
0
  GList *l;
442
0
  gboolean pretty = priv->pretty;
443
0
  guint indent = priv->indent;
444
0
  guint i;
445
446
0
  g_string_append_c (buffer, '{');
447
448
0
  members = json_object_get_members_internal (object);
449
450
0
  for (l = members->head; l != NULL; l = l->next)
451
0
    {
452
0
      const gchar *member_name = l->data;
453
0
      JsonNode *cur = json_object_get_member (object, member_name);
454
455
0
      if (l->prev == NULL && pretty)
456
0
        g_string_append_c (buffer, '\n');
457
458
0
      dump_node (generator, buffer, level + 1, member_name, cur);
459
460
0
      if (l->next != NULL)
461
0
        g_string_append_c (buffer, ',');
462
463
0
      if (pretty)
464
0
        g_string_append_c (buffer, '\n');
465
0
    }
466
467
0
  if (pretty)
468
0
    {
469
0
      for (i = 0; i < (level * indent); i++)
470
0
        g_string_append_c (buffer, priv->indent_char);
471
0
    }
472
473
0
  g_string_append_c (buffer, '}');
474
0
}
475
476
/**
477
 * json_generator_new:
478
 * 
479
 * Creates a new `JsonGenerator`.
480
 *
481
 * You can use this object to generate a JSON data stream starting from a
482
 * data object model composed by [struct@Json.Node]s.
483
 *
484
 * Return value: the newly created generator instance
485
 */
486
JsonGenerator *
487
json_generator_new (void)
488
0
{
489
0
  return g_object_new (JSON_TYPE_GENERATOR, NULL);
490
0
}
491
492
/**
493
 * json_generator_to_gstring:
494
 * @generator: a generator
495
 * @string: a string buffer
496
 *
497
 * Generates a JSON data stream and appends it to the string buffer.
498
 *
499
 * Return value: (transfer none): the passed string, updated with
500
 *   the generated JSON data
501
 *
502
 * Since: 1.4
503
 */
504
GString *
505
json_generator_to_gstring (JsonGenerator *generator,
506
                           GString       *string)
507
0
{
508
0
  JsonNode *root;
509
510
0
  g_return_val_if_fail (JSON_IS_GENERATOR (generator), NULL);
511
0
  g_return_val_if_fail (string != NULL, NULL);
512
513
0
  root = generator->priv->root;
514
0
  if (root != NULL)
515
0
    dump_node (generator, string, 0, NULL, root);
516
517
0
  return string;
518
0
}
519
520
/**
521
 * json_generator_to_data:
522
 * @generator: a generator
523
 * @length: (out) (optional): return location for the length of the returned
524
 *   buffer
525
 *
526
 * Generates a JSON data stream from @generator and returns it as a
527
 * buffer.
528
 *
529
 * Return value: (transfer full): a newly allocated string holding a JSON data stream
530
 */
531
gchar *
532
json_generator_to_data (JsonGenerator *generator,
533
                        gsize         *length)
534
0
{
535
0
  GString *string;
536
537
0
  g_return_val_if_fail (JSON_IS_GENERATOR (generator), NULL);
538
539
0
  string = g_string_new ("");
540
0
  json_generator_to_gstring (generator, string);
541
542
0
  if (length)
543
0
    *length = string->len;
544
545
0
  return g_string_free (string, FALSE);
546
0
}
547
548
/**
549
 * json_generator_to_file:
550
 * @generator: a generator
551
 * @filename: (type filename): the path to the target file
552
 * @error: return location for a #GError, or %NULL
553
 *
554
 * Creates a JSON data stream and puts it inside `filename`, overwriting
555
 * the file's current contents.
556
 *
557
 * This operation is atomic, in the sense that the data is written to a
558
 * temporary file which is then renamed to the given `filename`.
559
 *
560
 * Return value: %TRUE if saving was successful.
561
 */
562
gboolean
563
json_generator_to_file (JsonGenerator  *generator,
564
                        const gchar    *filename,
565
                        GError        **error)
566
0
{
567
0
  gchar *buffer;
568
0
  gsize len;
569
0
  gboolean retval;
570
571
0
  g_return_val_if_fail (JSON_IS_GENERATOR (generator), FALSE);
572
0
  g_return_val_if_fail (filename != NULL, FALSE);
573
574
0
  buffer = json_generator_to_data (generator, &len);
575
0
  retval = g_file_set_contents (filename, buffer, len, error);
576
0
  g_free (buffer);
577
578
0
  return retval;
579
0
}
580
581
/**
582
 * json_generator_to_stream:
583
 * @generator: a generator
584
 * @stream: the output stream used to write the JSON data
585
 * @cancellable: (nullable): a `GCancellable`
586
 * @error: return location for a #GError, or %NULL
587
 *
588
 * Outputs JSON data and writes it (synchronously) to the given stream.
589
 *
590
 * Return value: whether the write operation was successful
591
 *
592
 * Since: 0.12
593
 */
594
gboolean
595
json_generator_to_stream (JsonGenerator  *generator,
596
                          GOutputStream  *stream,
597
                          GCancellable   *cancellable,
598
                          GError        **error)
599
0
{
600
0
  gboolean retval;
601
0
  gchar *buffer;
602
0
  gsize len;
603
604
0
  g_return_val_if_fail (JSON_IS_GENERATOR (generator), FALSE);
605
0
  g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE);
606
607
0
  if (g_cancellable_set_error_if_cancelled (cancellable, error))
608
0
    return FALSE;
609
610
0
  buffer = json_generator_to_data (generator, &len);
611
0
  retval = g_output_stream_write (stream, buffer, len, cancellable, error);
612
0
  g_free (buffer);
613
614
0
  return retval;
615
0
}
616
617
/**
618
 * json_generator_set_root: (attributes org.gtk.Method.set_property=root)
619
 * @generator: a generator
620
 * @node: the root node
621
 *
622
 * Sets the root of the JSON data stream to be serialized by
623
 * the given generator.
624
 *
625
 * The passed `node` is copied by the generator object, so it can be
626
 * safely freed after calling this function.
627
 */
628
void
629
json_generator_set_root (JsonGenerator *generator,
630
                         JsonNode      *node)
631
0
{
632
0
  g_return_if_fail (JSON_IS_GENERATOR (generator));
633
634
0
  if (generator->priv->root == node)
635
0
    return;
636
637
0
  if (generator->priv->root != NULL)
638
0
    {
639
0
      json_node_unref (generator->priv->root);
640
0
      generator->priv->root = NULL;
641
0
    }
642
643
0
  if (node != NULL)
644
0
    generator->priv->root = json_node_copy (node);
645
646
0
  g_object_notify_by_pspec (G_OBJECT (generator), generator_props[PROP_ROOT]);
647
0
}
648
649
/**
650
 * json_generator_take_root:
651
 * @generator: a generator
652
 * @node: (transfer full) (nullable): the root node
653
 *
654
 * Sets the root of the JSON data stream to be serialized by
655
 * the given generator.
656
 *
657
 * The ownership of the passed `node` is transferred to the generator object.
658
 *
659
 * Since: 1.10
660
 */
661
void
662
json_generator_take_root (JsonGenerator *generator,
663
                          JsonNode      *node)
664
0
{
665
0
  JsonGeneratorPrivate *priv = json_generator_get_instance_private (generator);
666
667
0
  g_return_if_fail (JSON_IS_GENERATOR (generator));
668
669
0
  if (generator->priv->root == node)
670
0
    return;
671
672
0
  g_clear_pointer (&priv->root, json_node_unref);
673
0
  if (node != NULL)
674
0
    priv->root = node;
675
676
0
  g_object_notify_by_pspec (G_OBJECT (generator), generator_props[PROP_ROOT]);
677
0
}
678
679
/**
680
 * json_generator_get_root: (attributes org.gtk.Method.get_property=root)
681
 * @generator: a generator
682
 *
683
 * Retrieves a pointer to the root node set using
684
 * [method@Json.Generator.set_root].
685
 *
686
 * Return value: (nullable) (transfer none): the root node
687
 *
688
 * Since: 0.14
689
 */
690
JsonNode *
691
json_generator_get_root (JsonGenerator *generator)
692
0
{
693
0
  g_return_val_if_fail (JSON_IS_GENERATOR (generator), NULL);
694
695
0
  return generator->priv->root;
696
0
}
697
698
/**
699
 * json_generator_set_pretty: (attributes org.gtk.Method.set_property=pretty)
700
 * @generator: a generator
701
 * @is_pretty: whether the generated string should be pretty printed
702
 *
703
 * Sets whether the generated JSON should be pretty printed.
704
 *
705
 * Pretty printing will use indentation character specified in the
706
 * [property@Json.Generator:indent-char] property and the spacing
707
 * specified in the [property@Json.Generator:indent] property.
708
 *
709
 * Since: 0.14
710
 */
711
void
712
json_generator_set_pretty (JsonGenerator *generator,
713
                           gboolean       is_pretty)
714
0
{
715
0
  JsonGeneratorPrivate *priv;
716
717
0
  g_return_if_fail (JSON_IS_GENERATOR (generator));
718
719
0
  priv = generator->priv;
720
721
0
  is_pretty = !!is_pretty;
722
723
0
  if (priv->pretty != is_pretty)
724
0
    {
725
0
      priv->pretty = is_pretty;
726
727
0
      g_object_notify_by_pspec (G_OBJECT (generator), generator_props[PROP_PRETTY]);
728
0
    }
729
0
}
730
731
/**
732
 * json_generator_get_pretty: (attributes org.gtk.Method.get_property=pretty)
733
 * @generator: a generator
734
 *
735
 * Retrieves the value set using [method@Json.Generator.set_pretty].
736
 *
737
 * Return value: `TRUE` if the generated JSON should be pretty-printed, and
738
 *   `FALSE` otherwise
739
 *
740
 * Since: 0.14
741
 */
742
gboolean
743
json_generator_get_pretty (JsonGenerator *generator)
744
0
{
745
0
  g_return_val_if_fail (JSON_IS_GENERATOR (generator), FALSE);
746
747
0
  return generator->priv->pretty;
748
0
}
749
750
/**
751
 * json_generator_set_indent: (attributes org.gtk.Method.set_property=indent)
752
 * @generator: a generator
753
 * @indent_level: the number of repetitions of the indentation character
754
 *   that should be applied when pretty printing
755
 *
756
 * Sets the number of repetitions for each indentation level.
757
 *
758
 * Since: 0.14
759
 */
760
void
761
json_generator_set_indent (JsonGenerator *generator,
762
                           guint          indent_level)
763
0
{
764
0
  JsonGeneratorPrivate *priv;
765
766
0
  g_return_if_fail (JSON_IS_GENERATOR (generator));
767
768
0
  priv = generator->priv;
769
770
0
  if (priv->indent != indent_level)
771
0
    {
772
0
      priv->indent = indent_level;
773
774
0
      g_object_notify_by_pspec (G_OBJECT (generator), generator_props[PROP_INDENT]);
775
0
    }
776
0
}
777
778
/**
779
 * json_generator_get_indent: (attributes org.gtk.Method.get_property=indent)
780
 * @generator: a generator
781
 *
782
 * Retrieves the value set using [method@Json.Generator.set_indent].
783
 *
784
 * Return value: the number of repetitions per indentation level
785
 *
786
 * Since: 0.14
787
 */
788
guint
789
json_generator_get_indent (JsonGenerator *generator)
790
0
{
791
0
  g_return_val_if_fail (JSON_IS_GENERATOR (generator), 0);
792
793
0
  return generator->priv->indent;
794
0
}
795
796
/**
797
 * json_generator_set_indent_char: (attributes org.gtk.Method.set_property=indent-char)
798
 * @generator: a generator
799
 * @indent_char: a Unicode character to be used when indenting
800
 *
801
 * Sets the character to be used when indenting.
802
 *
803
 * Since: 0.14
804
 */
805
void
806
json_generator_set_indent_char (JsonGenerator *generator,
807
                                gunichar       indent_char)
808
0
{
809
0
  JsonGeneratorPrivate *priv;
810
811
0
  g_return_if_fail (JSON_IS_GENERATOR (generator));
812
813
0
  priv = generator->priv;
814
815
0
  if (priv->indent_char != indent_char)
816
0
    {
817
0
      priv->indent_char = indent_char;
818
819
0
      g_object_notify_by_pspec (G_OBJECT (generator), generator_props[PROP_INDENT_CHAR]);
820
0
    }
821
0
}
822
823
/**
824
 * json_generator_get_indent_char: (attributes org.gtk.Method.get_property=indent-char)
825
 * @generator: a generator
826
 *
827
 * Retrieves the value set using [method@Json.Generator.set_indent_char].
828
 *
829
 * Return value: the character to be used when indenting
830
 *
831
 * Since: 0.14
832
 */
833
gunichar
834
json_generator_get_indent_char (JsonGenerator *generator)
835
0
{
836
0
  g_return_val_if_fail (JSON_IS_GENERATOR (generator), FALSE);
837
838
0
  return generator->priv->indent_char;
839
0
}