Coverage Report

Created: 2025-11-02 06:51

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/tinysparql/subprojects/json-glib-1.10.6/json-glib/json-parser.c
Line
Count
Source
1
/* json-parser.c - JSON streams parser
2
 * 
3
 * This file is part of JSON-GLib
4
 *
5
 * SPDX-FileCopyrightText: 2007, 2008, 2009 OpenedHand Ltd
6
 * SPDX-FileCopyrightText: 2009, 2010 Intel Corp.
7
 * SPDX-FileCopyrightText: 2015 Collabora Ltd.
8
 * SPDX-License-Identifier: LGPL-2.1-or-later
9
 *
10
 * This library is free software; you can redistribute it and/or
11
 * modify it under the terms of the GNU Lesser General Public
12
 * License as published by the Free Software Foundation; either
13
 * version 2.1 of the License, or (at your option) any later version.
14
 *
15
 * This library is distributed in the hope that it will be useful,
16
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18
 * Lesser General Public License for more details.
19
 *
20
 * You should have received a copy of the GNU Lesser General Public
21
 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
22
 *
23
 * Author:
24
 *   Emmanuele Bassi  <ebassi@linux.intel.com>
25
 *   Philip Withnall  <philip.withnall@collabora.co.uk>
26
 */
27
28
/**
29
 * JsonParser:
30
 *
31
 * `JsonParser` provides an object for parsing a JSON data stream, either
32
 * inside a file or inside a static buffer.
33
 *
34
 * ## Using `JsonParser`
35
 *
36
 * The `JsonParser` API is fairly simple:
37
 *
38
 * ```c
39
 * gboolean
40
 * parse_json (const char *filename)
41
 * {
42
 *   g_autoptr(JsonParser) parser = json_parser_new ();
43
 *   g_autoptr(GError) error = NULL
44
 *
45
 *   json_parser_load_from_file (parser, filename, &error);
46
 *   if (error != NULL)
47
 *     {
48
 *       g_critical ("Unable to parse '%s': %s", filename, error->message);
49
 *       return FALSE;
50
 *     }
51
 *
52
 *   g_autoptr(JsonNode) root = json_parser_get_root (parser);
53
 *
54
 *   // manipulate the object tree from the root node
55
 *
56
 *   return TRUE
57
 * }
58
 * ```
59
 *
60
 * By default, the entire process of loading the data and parsing it is
61
 * synchronous; the [method@Json.Parser.load_from_stream_async] API will
62
 * load the data asynchronously, but parse it in the main context as the
63
 * signals of the parser must be emitted in the same thread. If you do
64
 * not use signals, and you wish to also parse the JSON data without blocking,
65
 * you should use a `GTask` and the synchronous `JsonParser` API inside the
66
 * task itself.
67
 */
68
69
#include "config.h"
70
71
#include <string.h>
72
73
#include <glib/gi18n-lib.h>
74
75
#include "json-types-private.h"
76
77
#include "json-debug.h"
78
#include "json-parser.h"
79
#include "json-scanner.h"
80
81
struct _JsonParserPrivate
82
{
83
  JsonNode *root;
84
  JsonNode *current_node;
85
86
  JsonScanner *scanner;
87
88
  JsonParserError error_code;
89
  GError *last_error;
90
91
  gchar *variable_name;
92
  gchar *filename;
93
94
  bool multi_root;
95
96
  guint has_assignment : 1;
97
  guint is_filename    : 1;
98
  guint is_immutable   : 1;
99
  guint is_strict      : 1;
100
};
101
102
enum
103
{
104
  PARSE_START,
105
  OBJECT_START,
106
  OBJECT_MEMBER,
107
  OBJECT_END,
108
  ARRAY_START,
109
  ARRAY_ELEMENT,
110
  ARRAY_END,
111
  PARSE_END,
112
  ERROR,
113
114
  LAST_SIGNAL
115
};
116
117
static guint parser_signals[LAST_SIGNAL] = { 0, };
118
119
enum
120
{
121
  PROP_IMMUTABLE = 1,
122
  PROP_STRICT,
123
  PROP_LAST
124
};
125
126
static GParamSpec *parser_props[PROP_LAST] = { NULL, };
127
128
G_DEFINE_QUARK (json-parser-error-quark, json_parser_error)
129
130
55.2k
G_DEFINE_TYPE_WITH_PRIVATE (JsonParser, json_parser, G_TYPE_OBJECT)
131
55.2k
132
55.2k
static guint json_parse_array  (JsonParser    *parser,
133
55.2k
                                JsonScanner   *scanner,
134
55.2k
                                JsonNode     **node,
135
55.2k
                                unsigned int   nesting);
136
55.2k
static guint json_parse_object (JsonParser    *parser,
137
55.2k
                                JsonScanner   *scanner,
138
55.2k
                                JsonNode     **node,
139
55.2k
                                unsigned int   nesting);
140
55.2k
141
55.2k
static inline void
142
55.2k
json_parser_clear (JsonParser *parser)
143
55.2k
{
144
13.1k
  JsonParserPrivate *priv = parser->priv;
145
146
13.1k
  g_clear_pointer (&priv->variable_name, g_free);
147
13.1k
  g_clear_pointer (&priv->last_error, g_error_free);
148
13.1k
  g_clear_pointer (&priv->root, json_node_unref);
149
150
13.1k
  priv->multi_root = false;
151
13.1k
}
152
153
static inline void
154
json_parser_emit_array_start (JsonParser *parser)
155
184k
{
156
184k
  JsonParserClass *klass = JSON_PARSER_GET_CLASS (parser);
157
158
184k
  if (g_signal_has_handler_pending (parser, parser_signals[ARRAY_START], 0, FALSE))
159
0
    g_signal_emit (parser, parser_signals[ARRAY_START], 0);
160
184k
  else if (klass->array_start != NULL)
161
0
    klass->array_start (parser);
162
184k
}
163
164
static inline void
165
json_parser_emit_array_element (JsonParser *parser,
166
                                JsonArray  *array,
167
                                guint       idx)
168
284k
{
169
284k
  JsonParserClass *klass = JSON_PARSER_GET_CLASS (parser);
170
171
284k
  if (g_signal_has_handler_pending (parser, parser_signals[ARRAY_ELEMENT], 0, FALSE))
172
0
    g_signal_emit (parser, parser_signals[ARRAY_ELEMENT], 0, array, idx);
173
284k
  else if (klass->array_element != NULL)
174
0
    klass->array_element (parser, array, idx);
175
284k
}
176
177
static inline void
178
json_parser_emit_array_end (JsonParser *parser,
179
                            JsonArray  *array)
180
167k
{
181
167k
  JsonParserClass *klass = JSON_PARSER_GET_CLASS (parser);
182
183
167k
  if (g_signal_has_handler_pending (parser, parser_signals[ARRAY_END], 0, FALSE))
184
0
    g_signal_emit (parser, parser_signals[ARRAY_END], 0, array);
185
167k
  else if (klass->array_end != NULL)
186
0
    klass->array_end (parser, array);
187
167k
}
188
189
static inline void
190
json_parser_emit_object_start (JsonParser *parser)
191
1.82M
{
192
1.82M
  JsonParserClass *klass = JSON_PARSER_GET_CLASS (parser);
193
194
1.82M
  if (g_signal_has_handler_pending (parser, parser_signals[OBJECT_START], 0, FALSE))
195
0
    g_signal_emit (parser, parser_signals[OBJECT_START], 0);
196
1.82M
  else if (klass->object_start != NULL)
197
0
    klass->object_start (parser);
198
1.82M
}
199
200
static inline void
201
json_parser_emit_object_member (JsonParser *parser,
202
                                JsonObject *object,
203
                                const char *name)
204
1.87M
{
205
1.87M
  JsonParserClass *klass = JSON_PARSER_GET_CLASS (parser);
206
207
1.87M
  if (g_signal_has_handler_pending (parser, parser_signals[OBJECT_MEMBER], 0, FALSE))
208
0
    g_signal_emit (parser, parser_signals[OBJECT_MEMBER], 0, object, name);
209
1.87M
  else if (klass->object_member != NULL)
210
0
    klass->object_member (parser, object, name);
211
1.87M
}
212
213
static inline void
214
json_parser_emit_object_end (JsonParser *parser,
215
                             JsonObject *object)
216
1.82M
{
217
1.82M
  JsonParserClass *klass = JSON_PARSER_GET_CLASS (parser);
218
219
1.82M
  if (g_signal_has_handler_pending (parser, parser_signals[OBJECT_END], 0, FALSE))
220
0
    g_signal_emit (parser, parser_signals[OBJECT_END], 0, object);
221
1.82M
  else if (klass->object_end != NULL)
222
0
    klass->object_end (parser, object);
223
1.82M
}
224
225
static inline void
226
json_parser_emit_error (JsonParser *parser,
227
                        GError     *error)
228
1.32k
{
229
1.32k
  JsonParserClass *klass = JSON_PARSER_GET_CLASS (parser);
230
231
1.32k
  if (g_signal_has_handler_pending (parser, parser_signals[ERROR], 0, FALSE))
232
0
    g_signal_emit (parser, parser_signals[ERROR], 0, error);
233
1.32k
  else if (klass->error != NULL)
234
0
    klass->error (parser, error);
235
1.32k
}
236
237
static inline void
238
json_parser_emit_parse_start (JsonParser *parser)
239
6.50k
{
240
6.50k
  JsonParserClass *klass = JSON_PARSER_GET_CLASS (parser);
241
242
6.50k
  if (g_signal_has_handler_pending (parser, parser_signals[PARSE_START], 0, FALSE))
243
0
    g_signal_emit (parser, parser_signals[PARSE_START], 0);
244
6.50k
  else if (klass->parse_start != NULL)
245
0
    klass->parse_start (parser);
246
6.50k
}
247
248
static inline void
249
json_parser_emit_parse_end (JsonParser *parser)
250
6.50k
{
251
6.50k
  JsonParserClass *klass = JSON_PARSER_GET_CLASS (parser);
252
253
6.50k
  if (g_signal_has_handler_pending (parser, parser_signals[PARSE_END], 0, FALSE))
254
0
    g_signal_emit (parser, parser_signals[PARSE_END], 0);
255
6.50k
  else if (klass->parse_end != NULL)
256
0
    klass->parse_end (parser);
257
6.50k
}
258
259
static void
260
json_parser_dispose (GObject *gobject)
261
6.57k
{
262
6.57k
  json_parser_clear (JSON_PARSER (gobject));
263
264
6.57k
  G_OBJECT_CLASS (json_parser_parent_class)->dispose (gobject);
265
6.57k
}
266
267
static void
268
json_parser_finalize (GObject *gobject)
269
6.57k
{
270
6.57k
  JsonParserPrivate *priv = JSON_PARSER (gobject)->priv;
271
272
6.57k
  g_free (priv->variable_name);
273
6.57k
  g_free (priv->filename);
274
275
6.57k
  G_OBJECT_CLASS (json_parser_parent_class)->finalize (gobject);
276
6.57k
}
277
278
static void
279
json_parser_set_property (GObject      *gobject,
280
                          guint         prop_id,
281
                          const GValue *value,
282
                          GParamSpec   *pspec)
283
6.57k
{
284
6.57k
  JsonParserPrivate *priv = JSON_PARSER (gobject)->priv;
285
286
6.57k
  switch (prop_id)
287
6.57k
    {
288
6.57k
    case PROP_IMMUTABLE:
289
      /* Construct-only. */
290
6.57k
      priv->is_immutable = g_value_get_boolean (value);
291
6.57k
      break;
292
293
0
    case PROP_STRICT:
294
0
      json_parser_set_strict (JSON_PARSER (gobject),
295
0
                              g_value_get_boolean (value));
296
0
      break;
297
298
0
    default:
299
0
      G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
300
0
      break;
301
6.57k
    }
302
6.57k
}
303
304
static void
305
json_parser_get_property (GObject    *gobject,
306
                          guint       prop_id,
307
                          GValue     *value,
308
                          GParamSpec *pspec)
309
0
{
310
0
  JsonParserPrivate *priv = JSON_PARSER (gobject)->priv;
311
312
0
  switch (prop_id)
313
0
    {
314
0
    case PROP_IMMUTABLE:
315
0
      g_value_set_boolean (value, priv->is_immutable);
316
0
      break;
317
318
0
    case PROP_STRICT:
319
0
      g_value_set_boolean (value, priv->is_strict);
320
0
      break;
321
322
0
    default:
323
0
      G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
324
0
      break;
325
0
    }
326
0
}
327
328
static void
329
json_parser_class_init (JsonParserClass *klass)
330
1
{
331
1
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
332
333
1
  gobject_class->set_property = json_parser_set_property;
334
1
  gobject_class->get_property = json_parser_get_property;
335
1
  gobject_class->dispose = json_parser_dispose;
336
1
  gobject_class->finalize = json_parser_finalize;
337
338
  /**
339
   * JsonParser:immutable:
340
   *
341
   * Whether the tree built by the parser should be immutable
342
   * when created.
343
   *
344
   * Making the output immutable on creation avoids the expense
345
   * of traversing it to make it immutable later.
346
   *
347
   * Since: 1.2
348
   */
349
1
  parser_props[PROP_IMMUTABLE] =
350
1
    g_param_spec_boolean ("immutable", NULL, NULL,
351
1
                          FALSE,
352
1
                          G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
353
354
  /**
355
   * JsonParser:strict:
356
   *
357
   * Whether the parser should be strictly conforming to the
358
   * JSON format, or allow custom extensions like comments.
359
   *
360
   * Since: 1.10
361
   */
362
1
  parser_props[PROP_STRICT] =
363
1
    g_param_spec_boolean ("strict", NULL, NULL, FALSE,
364
1
                          G_PARAM_READWRITE |
365
1
                          G_PARAM_EXPLICIT_NOTIFY);
366
367
1
  g_object_class_install_properties (gobject_class, PROP_LAST, parser_props);
368
369
  /**
370
   * JsonParser::parse-start:
371
   * @parser: the parser that emitted the signal
372
   * 
373
   * This signal is emitted when a parser starts parsing a JSON data stream.
374
   *
375
   * Deprecated: 1.10: Derive your own parser type from `JsonParser` and
376
   *   override the [vfunc@Json.Parser.parse_start] virtual function
377
   */
378
1
  parser_signals[PARSE_START] =
379
1
    g_signal_new ("parse-start",
380
1
                  G_OBJECT_CLASS_TYPE (gobject_class),
381
1
                  G_SIGNAL_RUN_LAST,
382
1
                  G_STRUCT_OFFSET (JsonParserClass, parse_start),
383
1
                  NULL, NULL,
384
1
                  NULL,
385
1
                  G_TYPE_NONE, 0);
386
  /**
387
   * JsonParser::parse-end:
388
   * @parser: the parser that emitted the signal
389
   *
390
   * This signal is emitted when a parser successfully finished parsing a
391
   * JSON data stream.
392
   *
393
   * Deprecated: 1.10: Derive your own parser type from `JsonParser` and
394
   *   override the [vfunc@Json.Parser.parse_end] virtual function
395
   */
396
1
  parser_signals[PARSE_END] =
397
1
    g_signal_new ("parse-end",
398
1
                  G_OBJECT_CLASS_TYPE (gobject_class),
399
1
                  G_SIGNAL_RUN_LAST,
400
1
                  G_STRUCT_OFFSET (JsonParserClass, parse_end),
401
1
                  NULL, NULL, NULL,
402
1
                  G_TYPE_NONE, 0);
403
  /**
404
   * JsonParser::object-start:
405
   * @parser: the parser that emitted the signal
406
   *
407
   * This signal is emitted each time a parser starts parsing a JSON object.
408
   *
409
   * Deprecated: 1.10: Derive your own parser type from `JsonParser` and
410
   *   override the [vfunc@Json.Parser.object_start] virtual function
411
   */
412
1
  parser_signals[OBJECT_START] =
413
1
    g_signal_new ("object-start",
414
1
                  G_OBJECT_CLASS_TYPE (gobject_class),
415
1
                  G_SIGNAL_RUN_LAST,
416
1
                  G_STRUCT_OFFSET (JsonParserClass, object_start),
417
1
                  NULL, NULL, NULL,
418
1
                  G_TYPE_NONE, 0);
419
  /**
420
   * JsonParser::object-member:
421
   * @parser: the parser that emitted the signal
422
   * @object: the JSON object being parsed
423
   * @member_name: the name of the newly parsed member
424
   *
425
   * The `::object-member` signal is emitted each time a parser
426
   * has successfully parsed a single member of a JSON object.
427
   *
428
   * Deprecated: 1.10: Derive your own parser type from `JsonParser` and
429
   *   override the [vfunc@Json.Parser.object_member] virtual function
430
   */
431
1
  parser_signals[OBJECT_MEMBER] =
432
1
    g_signal_new ("object-member",
433
1
                  G_OBJECT_CLASS_TYPE (gobject_class),
434
1
                  G_SIGNAL_RUN_LAST,
435
1
                  G_STRUCT_OFFSET (JsonParserClass, object_member),
436
1
                  NULL, NULL, NULL,
437
1
                  G_TYPE_NONE, 2,
438
1
                  JSON_TYPE_OBJECT,
439
1
                  G_TYPE_STRING);
440
  /**
441
   * JsonParser::object-end:
442
   * @parser: the parser that emitted the signal
443
   * @object: the parsed JSON object
444
   *
445
   * The `::object-end` signal is emitted each time a parser
446
   * has successfully parsed an entire JSON object.
447
   *
448
   * Deprecated: 1.10: Derive your own parser type from `JsonParser` and
449
   *   override the [vfunc@Json.Parser.object_end] virtual function
450
   */
451
1
  parser_signals[OBJECT_END] =
452
1
    g_signal_new ("object-end",
453
1
                  G_OBJECT_CLASS_TYPE (gobject_class),
454
1
                  G_SIGNAL_RUN_LAST,
455
1
                  G_STRUCT_OFFSET (JsonParserClass, object_end),
456
1
                  NULL, NULL, NULL,
457
1
                  G_TYPE_NONE, 1,
458
1
                  JSON_TYPE_OBJECT);
459
  /**
460
   * JsonParser::array-start:
461
   * @parser: the parser that emitted the signal
462
   *
463
   * The `::array-start` signal is emitted each time a parser
464
   * starts parsing a JSON array.
465
   *
466
   * Deprecated: 1.10: Derive your own parser type from `JsonParser` and
467
   *   override the [vfunc@Json.Parser.array_start] virtual function
468
   */
469
1
  parser_signals[ARRAY_START] =
470
1
    g_signal_new ("array-start",
471
1
                  G_OBJECT_CLASS_TYPE (gobject_class),
472
1
                  G_SIGNAL_RUN_LAST,
473
1
                  G_STRUCT_OFFSET (JsonParserClass, array_start),
474
1
                  NULL, NULL, NULL,
475
1
                  G_TYPE_NONE, 0);
476
  /**
477
   * JsonParser::array-element:
478
   * @parser: the parser that emitted the signal
479
   * @array: a JSON array
480
   * @index_: the index of the newly parsed array element
481
   *
482
   * The `::array-element` signal is emitted each time a parser
483
   * has successfully parsed a single element of a JSON array.
484
   *
485
   * Deprecated: 1.10: Derive your own parser type from `JsonParser` and
486
   *   override the [vfunc@Json.Parser.array_element] virtual function
487
   */
488
1
  parser_signals[ARRAY_ELEMENT] =
489
1
    g_signal_new ("array-element",
490
1
                  G_OBJECT_CLASS_TYPE (gobject_class),
491
1
                  G_SIGNAL_RUN_LAST,
492
1
                  G_STRUCT_OFFSET (JsonParserClass, array_element),
493
1
                  NULL, NULL, NULL,
494
1
                  G_TYPE_NONE, 2,
495
1
                  JSON_TYPE_ARRAY,
496
1
                  G_TYPE_INT);
497
  /**
498
   * JsonParser::array-end:
499
   * @parser: the parser that emitted the signal
500
   * @array: the parsed JSON array
501
   *
502
   * The `::array-end` signal is emitted each time a parser
503
   * has successfully parsed an entire JSON array.
504
   *
505
   * Deprecated: 1.10: Derive your own parser type from `JsonParser` and
506
   *   override the [vfunc@Json.Parser.array_end] virtual function
507
   */
508
1
  parser_signals[ARRAY_END] =
509
1
    g_signal_new ("array-end",
510
1
                  G_OBJECT_CLASS_TYPE (gobject_class),
511
1
                  G_SIGNAL_RUN_LAST,
512
1
                  G_STRUCT_OFFSET (JsonParserClass, array_end),
513
1
                  NULL, NULL, NULL,
514
1
                  G_TYPE_NONE, 1,
515
1
                  JSON_TYPE_ARRAY);
516
  /**
517
   * JsonParser::error:
518
   * @parser: the parser that emitted the signal
519
   * @error: the error
520
   *
521
   * The `::error` signal is emitted each time a parser encounters
522
   * an error in a JSON stream.
523
   *
524
   * Deprecated: 1.10: Derive your own parser type from `JsonParser` and
525
   *   override the [vfunc@Json.Parser.error] virtual function
526
   */
527
1
  parser_signals[ERROR] =
528
1
    g_signal_new ("error",
529
1
                  G_OBJECT_CLASS_TYPE (gobject_class),
530
1
                  G_SIGNAL_RUN_LAST,
531
1
                  G_STRUCT_OFFSET (JsonParserClass, error),
532
1
                  NULL, NULL, NULL,
533
1
                  G_TYPE_NONE, 1,
534
1
                  G_TYPE_POINTER);
535
1
}
536
537
static void
538
json_parser_init (JsonParser *parser)
539
6.57k
{
540
6.57k
  JsonParserPrivate *priv = json_parser_get_instance_private (parser);
541
542
6.57k
  parser->priv = priv;
543
544
6.57k
  priv->root = NULL;
545
6.57k
  priv->current_node = NULL;
546
547
6.57k
  priv->error_code = JSON_PARSER_ERROR_PARSE;
548
6.57k
  priv->last_error = NULL;
549
550
6.57k
  priv->has_assignment = FALSE;
551
6.57k
  priv->variable_name = NULL;
552
553
6.57k
  priv->is_filename = FALSE;
554
6.57k
  priv->filename = FALSE;
555
6.57k
}
556
557
static guint
558
json_parse_value (JsonParser   *parser,
559
                  JsonScanner  *scanner,
560
                  guint         token,
561
                  JsonNode    **node)
562
799k
{
563
799k
  JsonParserPrivate *priv = parser->priv;
564
799k
  JsonNode *current_node = priv->current_node;
565
566
799k
  switch (token)
567
799k
    {
568
120k
    case JSON_TOKEN_INT:
569
120k
      {
570
120k
        gint64 value = json_scanner_get_int64_value (scanner);
571
572
120k
        JSON_NOTE (PARSER, "node: %" G_GINT64_FORMAT, value);
573
120k
        *node = json_node_init_int (json_node_alloc (), value);
574
120k
      }
575
120k
      break;
576
577
1.56k
    case JSON_TOKEN_FLOAT:
578
1.56k
      {
579
1.56k
        double value = json_scanner_get_float_value (scanner);
580
581
1.56k
        JSON_NOTE (PARSER, "abs(node): %.6f", value);
582
1.56k
        *node = json_node_init_double (json_node_alloc (), value);
583
1.56k
      }
584
1.56k
      break;
585
586
674k
    case JSON_TOKEN_STRING:
587
674k
      {
588
674k
        const char *value = json_scanner_get_string_value (scanner);
589
590
674k
        JSON_NOTE (PARSER, "node: '%s'", value);
591
674k
        *node = json_node_init_string (json_node_alloc (), value);
592
674k
      }
593
674k
      break;
594
595
646
    case JSON_TOKEN_TRUE:
596
842
    case JSON_TOKEN_FALSE:
597
842
      JSON_NOTE (PARSER, "node: '%s'",
598
842
                 JSON_TOKEN_TRUE ? "<true>" : "<false>");
599
842
      *node = json_node_init_boolean (json_node_alloc (), token == JSON_TOKEN_TRUE ? TRUE : FALSE);
600
842
      break;
601
602
427
    case JSON_TOKEN_NULL:
603
427
      JSON_NOTE (PARSER, "node: <null>");
604
427
      *node = json_node_init_null (json_node_alloc ());
605
427
      break;
606
607
416
    case JSON_TOKEN_IDENTIFIER:
608
416
      JSON_NOTE (PARSER, "node: identifier '%s'", json_scanner_get_identifier (scanner));
609
416
      priv->error_code = JSON_PARSER_ERROR_INVALID_BAREWORD;
610
416
      *node = NULL;
611
416
      return JSON_TOKEN_SYMBOL;
612
613
471
    default:
614
471
      {
615
471
        JsonNodeType cur_type;
616
617
471
        *node = NULL;
618
619
471
        JSON_NOTE (PARSER, "node: invalid token");
620
621
471
        cur_type = json_node_get_node_type (current_node);
622
471
        if (cur_type == JSON_NODE_ARRAY)
623
132
          {
624
132
            priv->error_code = JSON_PARSER_ERROR_PARSE;
625
132
            return JSON_TOKEN_RIGHT_BRACE;
626
132
          }
627
339
        else if (cur_type == JSON_NODE_OBJECT)
628
339
          {
629
339
            priv->error_code = JSON_PARSER_ERROR_PARSE;
630
339
            return JSON_TOKEN_RIGHT_CURLY;
631
339
          }
632
0
        else
633
0
          {
634
0
            priv->error_code = JSON_PARSER_ERROR_INVALID_BAREWORD;
635
0
            return JSON_TOKEN_SYMBOL;
636
0
          }
637
471
      }
638
0
      break;
639
799k
    }
640
641
798k
  if (priv->is_immutable && *node != NULL)
642
0
    json_node_seal (*node);
643
644
798k
  return JSON_TOKEN_NONE;
645
799k
}
646
647
static guint
648
json_parse_array (JsonParser    *parser,
649
                  JsonScanner   *scanner,
650
                  JsonNode     **node,
651
                  unsigned int   nesting_level)
652
184k
{
653
184k
  JsonParserPrivate *priv = parser->priv;
654
184k
  JsonNode *old_current;
655
184k
  JsonArray *array;
656
184k
  guint token;
657
184k
  gint idx;
658
659
184k
  if (nesting_level >= JSON_PARSER_MAX_RECURSION_DEPTH)
660
1
    {
661
1
      priv->error_code = JSON_PARSER_ERROR_NESTING;
662
1
      return JSON_TOKEN_RIGHT_BRACE;
663
1
    }
664
665
184k
  old_current = priv->current_node;
666
184k
  priv->current_node = json_node_init_array (json_node_alloc (), NULL);
667
668
184k
  array = json_array_new ();
669
670
184k
  token = json_scanner_get_next_token (scanner);
671
184k
  g_assert (token == JSON_TOKEN_LEFT_BRACE);
672
673
184k
  json_parser_emit_array_start (parser);
674
675
184k
  idx = 0;
676
468k
  while (token != JSON_TOKEN_RIGHT_BRACE)
677
304k
    {
678
304k
      guint next_token = json_scanner_peek_next_token (scanner);
679
304k
      JsonNode *element = NULL;
680
681
      /* parse the element */
682
304k
      switch (next_token)
683
304k
        {
684
15.9k
        case JSON_TOKEN_LEFT_BRACE:
685
15.9k
          JSON_NOTE (PARSER, "Nested array at index %d", idx);
686
15.9k
          token = json_parse_array (parser, scanner, &element, nesting_level + 1);
687
15.9k
          break;
688
689
164k
        case JSON_TOKEN_LEFT_CURLY:
690
164k
          JSON_NOTE (PARSER, "Nested object at index %d", idx);
691
164k
          token = json_parse_object (parser, scanner, &element, nesting_level + 1);
692
164k
          break;
693
694
3.44k
        case JSON_TOKEN_RIGHT_BRACE:
695
3.44k
          goto array_done;
696
697
121k
        default:
698
121k
          token = json_scanner_get_next_token (scanner);
699
121k
          token = json_parse_value (parser, scanner, token, &element);
700
121k
          break;
701
304k
        }
702
703
301k
      if (token != JSON_TOKEN_NONE || element == NULL)
704
16.4k
        {
705
          /* the json_parse_* functions will have set the error code */
706
16.4k
          json_array_unref (array);
707
16.4k
          json_node_unref (priv->current_node);
708
16.4k
          priv->current_node = old_current;
709
710
16.4k
          return token;
711
16.4k
        }
712
713
285k
      next_token = json_scanner_peek_next_token (scanner);
714
715
      /* look for missing commas */
716
285k
      if (next_token != JSON_TOKEN_COMMA && next_token != JSON_TOKEN_RIGHT_BRACE)
717
419
        {
718
419
          priv->error_code = JSON_PARSER_ERROR_MISSING_COMMA;
719
720
419
          json_array_unref (array);
721
419
          json_node_free (priv->current_node);
722
419
          json_node_free (element);
723
419
          priv->current_node = old_current;
724
725
419
          return JSON_TOKEN_COMMA;
726
419
        }
727
728
      /* look for trailing commas */
729
284k
      if (next_token == JSON_TOKEN_COMMA)
730
120k
        {
731
          /* advance the cursor */
732
120k
          json_scanner_get_next_token (scanner);
733
734
120k
          next_token = json_scanner_peek_next_token (scanner);
735
120k
          if (next_token == JSON_TOKEN_RIGHT_BRACE)
736
1
            {
737
1
              priv->error_code = JSON_PARSER_ERROR_TRAILING_COMMA;
738
739
1
              json_array_unref (array);
740
1
              json_node_unref (priv->current_node);
741
1
              json_node_unref (element);
742
1
              priv->current_node = old_current;
743
744
1
              return JSON_TOKEN_RIGHT_BRACE;
745
1
            }
746
120k
        }
747
748
284k
      JSON_NOTE (PARSER, "Array element %d completed", idx);
749
284k
      json_node_set_parent (element, priv->current_node);
750
284k
      if (priv->is_immutable)
751
0
        json_node_seal (element);
752
284k
      json_array_add_element (array, element);
753
754
284k
      json_parser_emit_array_element (parser, array, idx);
755
756
284k
      idx += 1;
757
284k
      token = next_token;
758
284k
    }
759
760
167k
array_done:
761
167k
  json_scanner_get_next_token (scanner);
762
763
167k
  if (priv->is_immutable)
764
0
    json_array_seal (array);
765
766
167k
  json_node_take_array (priv->current_node, array);
767
167k
  if (priv->is_immutable)
768
0
    json_node_seal (priv->current_node);
769
167k
  json_node_set_parent (priv->current_node, old_current);
770
771
167k
  json_parser_emit_array_end (parser, array);
772
773
167k
  if (node != NULL && *node == NULL)
774
167k
    *node = priv->current_node;
775
776
167k
  priv->current_node = old_current;
777
778
167k
  return JSON_TOKEN_NONE;
779
184k
}
780
781
static guint
782
json_parse_object (JsonParser    *parser,
783
                   JsonScanner   *scanner,
784
                   JsonNode     **node,
785
                   unsigned int   nesting)
786
1.82M
{
787
1.82M
  JsonParserPrivate *priv = parser->priv;
788
1.82M
  JsonObject *object;
789
1.82M
  JsonNode *old_current;
790
1.82M
  guint token;
791
792
1.82M
  if (nesting >= JSON_PARSER_MAX_RECURSION_DEPTH)
793
1
    {
794
1
      priv->error_code = JSON_PARSER_ERROR_NESTING;
795
1
      return JSON_TOKEN_RIGHT_CURLY;
796
1
    }
797
798
1.82M
  old_current = priv->current_node;
799
1.82M
  priv->current_node = json_node_init_object (json_node_alloc (), NULL);
800
801
1.82M
  object = json_object_new ();
802
803
1.82M
  token = json_scanner_get_next_token (scanner);
804
1.82M
  g_assert (token == JSON_TOKEN_LEFT_CURLY);
805
806
1.82M
  json_parser_emit_object_start (parser);
807
808
3.70M
  while (token != JSON_TOKEN_RIGHT_CURLY)
809
2.11M
    {
810
2.11M
      guint next_token = json_scanner_peek_next_token (scanner);
811
2.11M
      JsonNode *member = NULL;
812
2.11M
      gchar *name;
813
814
      /* we need to abort here because empty objects do not
815
       * have member names
816
       */
817
2.11M
      if (next_token == JSON_TOKEN_RIGHT_CURLY)
818
235k
        break;
819
820
      /* parse the member's name */
821
1.88M
      if (next_token != JSON_TOKEN_STRING)
822
269
        {
823
269
          JSON_NOTE (PARSER, "Missing object member name");
824
825
269
          priv->error_code = JSON_PARSER_ERROR_INVALID_BAREWORD;
826
827
269
          json_object_unref (object);
828
269
          json_node_unref (priv->current_node);
829
269
          priv->current_node = old_current;
830
831
269
          return JSON_TOKEN_STRING;
832
269
        }
833
834
      /* member name */
835
1.88M
      json_scanner_get_next_token (scanner);
836
837
1.88M
      name = json_scanner_dup_string_value (scanner);
838
1.88M
      if (name == NULL)
839
0
        {
840
0
          JSON_NOTE (PARSER, "Empty object member name");
841
842
0
          priv->error_code = JSON_PARSER_ERROR_EMPTY_MEMBER_NAME;
843
844
0
          json_object_unref (object);
845
0
          json_node_unref (priv->current_node);
846
0
          priv->current_node = old_current;
847
848
0
          return JSON_TOKEN_STRING;
849
0
        }
850
851
1.88M
      JSON_NOTE (PARSER, "Object member '%s'", name);
852
853
      /* a colon separates names from values */
854
1.88M
      next_token = json_scanner_peek_next_token (scanner);
855
1.88M
      if (next_token != JSON_TOKEN_COLON)
856
350
        {
857
350
          JSON_NOTE (PARSER, "Missing object member name separator");
858
859
350
          priv->error_code = JSON_PARSER_ERROR_MISSING_COLON;
860
861
350
          g_free (name);
862
350
          json_object_unref (object);
863
350
          json_node_unref (priv->current_node);
864
350
          priv->current_node = old_current;
865
866
350
          return JSON_TOKEN_COLON;
867
350
        }
868
869
      /* we swallow the ':' */
870
1.88M
      token = json_scanner_get_next_token (scanner);
871
1.88M
      g_assert (token == JSON_TOKEN_COLON);
872
1.88M
      next_token = json_scanner_peek_next_token (scanner);
873
874
      /* parse the member's value */
875
1.88M
      switch (next_token)
876
1.88M
        {
877
166k
        case JSON_TOKEN_LEFT_BRACE:
878
166k
          JSON_NOTE (PARSER, "Nested array at member %s", name);
879
166k
          token = json_parse_array (parser, scanner, &member, nesting + 1);
880
166k
          break;
881
882
1.03M
        case JSON_TOKEN_LEFT_CURLY:
883
1.03M
          JSON_NOTE (PARSER, "Nested object at member %s", name);
884
1.03M
          token = json_parse_object (parser, scanner, &member, nesting + 1);
885
1.03M
          break;
886
887
677k
        default:
888
          /* once a member name is defined we need a value */
889
677k
          token = json_scanner_get_next_token (scanner);
890
677k
          token = json_parse_value (parser, scanner, token, &member);
891
677k
          break;
892
1.88M
        }
893
894
1.88M
      if (token != JSON_TOKEN_NONE || member == NULL)
895
3.65k
        {
896
          /* the json_parse_* functions will have set the error code */
897
3.65k
          g_free (name);
898
3.65k
          json_object_unref (object);
899
3.65k
          json_node_unref (priv->current_node);
900
3.65k
          priv->current_node = old_current;
901
902
3.65k
          return token;
903
3.65k
        }
904
905
1.87M
      next_token = json_scanner_peek_next_token (scanner);
906
1.87M
      if (next_token == JSON_TOKEN_COMMA)
907
294k
        {
908
294k
          json_scanner_get_next_token (scanner);
909
910
          /* look for trailing commas */
911
294k
          next_token = json_scanner_peek_next_token (scanner);
912
294k
          if (next_token == JSON_TOKEN_RIGHT_CURLY)
913
1
            {
914
1
              priv->error_code = JSON_PARSER_ERROR_TRAILING_COMMA;
915
916
1
              g_free (name);
917
1
              json_object_unref (object);
918
1
              json_node_unref (member);
919
1
              json_node_unref (priv->current_node);
920
1
              priv->current_node = old_current;
921
922
1
              return JSON_TOKEN_RIGHT_BRACE;
923
1
            }
924
294k
        }
925
1.58M
      else if (next_token == JSON_TOKEN_STRING)
926
2
        {
927
2
          priv->error_code = JSON_PARSER_ERROR_MISSING_COMMA;
928
929
2
          g_free (name);
930
2
          json_object_unref (object);
931
2
          json_node_unref (member);
932
2
          json_node_unref (priv->current_node);
933
2
          priv->current_node = old_current;
934
935
2
          return JSON_TOKEN_COMMA;
936
2
        }
937
938
1.87M
      JSON_NOTE (PARSER, "Object member '%s' completed", name);
939
1.87M
      json_node_set_parent (member, priv->current_node);
940
1.87M
      if (priv->is_immutable)
941
0
        json_node_seal (member);
942
1.87M
      json_object_set_member (object, name, member);
943
944
1.87M
      json_parser_emit_object_member (parser, object, name);
945
946
1.87M
      g_free (name);
947
948
1.87M
      token = next_token;
949
1.87M
    }
950
951
1.82M
  json_scanner_get_next_token (scanner);
952
953
1.82M
  if (priv->is_immutable)
954
0
    json_object_seal (object);
955
956
1.82M
  json_node_take_object (priv->current_node, object);
957
1.82M
  if (priv->is_immutable)
958
0
    json_node_seal (priv->current_node);
959
1.82M
  json_node_set_parent (priv->current_node, old_current);
960
961
1.82M
  json_parser_emit_object_end (parser, object);
962
963
1.82M
  if (node != NULL && *node == NULL)
964
1.82M
    *node = priv->current_node;
965
966
1.82M
  priv->current_node = old_current;
967
968
1.82M
  return JSON_TOKEN_NONE;
969
1.82M
}
970
971
static guint
972
json_parse_statement (JsonParser  *parser,
973
                      JsonScanner *scanner)
974
629k
{
975
629k
  JsonParserPrivate *priv = parser->priv;
976
629k
  guint token;
977
978
629k
  token = json_scanner_peek_next_token (scanner);
979
629k
  switch (token)
980
629k
    {
981
620k
    case JSON_TOKEN_LEFT_CURLY:
982
620k
      if (priv->is_strict && priv->root != NULL)
983
0
        {
984
0
          JSON_NOTE (PARSER, "Only one top level object is possible");
985
0
          json_scanner_get_next_token (scanner);
986
0
          priv->error_code = JSON_PARSER_ERROR_INVALID_STRUCTURE;
987
0
          return JSON_TOKEN_EOF;
988
0
        }
989
620k
      else if (priv->root != NULL)
990
615k
        {
991
615k
          JsonArray *array;
992
993
615k
          if (!priv->multi_root)
994
3.29k
            {
995
3.29k
              JSON_NOTE (PARSER, "Replacing new root with an array");
996
997
3.29k
              JsonNode *old_root = g_steal_pointer (&priv->root);
998
3.29k
              priv->root = json_node_new (JSON_NODE_ARRAY);
999
1000
3.29k
              array = json_array_new ();
1001
3.29k
              json_array_add_element (array, old_root);
1002
3.29k
              json_node_set_parent (old_root, priv->root);
1003
1004
3.29k
              json_node_take_array (priv->root, array);
1005
1006
3.29k
              priv->multi_root = true;
1007
3.29k
            }
1008
611k
          else
1009
611k
            {
1010
611k
              g_assert (JSON_NODE_HOLDS_ARRAY (priv->root));
1011
611k
              array = json_node_get_array (priv->root);
1012
611k
            }
1013
1014
615k
          JsonNode *node = NULL;
1015
615k
          guint res;
1016
1017
615k
          res = json_parse_object (parser, scanner, &node, 0);
1018
615k
          if (node != NULL)
1019
614k
            json_array_add_element (array, node);
1020
615k
          return res;
1021
615k
        }
1022
5.44k
      else
1023
5.44k
        {
1024
5.44k
          JSON_NOTE (PARSER, "Statement is object declaration");
1025
5.44k
          return json_parse_object (parser, scanner, &priv->root, 0);
1026
5.44k
        }
1027
0
      break;
1028
1029
1.91k
    case JSON_TOKEN_LEFT_BRACE:
1030
1.91k
      if (priv->is_strict && priv->root != NULL)
1031
0
        {
1032
0
          JSON_NOTE (PARSER, "Only one top level array is possible");
1033
0
          json_scanner_get_next_token (scanner);
1034
0
          priv->error_code = JSON_PARSER_ERROR_INVALID_STRUCTURE;
1035
0
          return JSON_TOKEN_EOF;
1036
0
        }
1037
1.91k
      else if (priv->root != NULL)
1038
1.42k
        {
1039
1.42k
          JsonArray *array;
1040
1041
1.42k
          if (!priv->multi_root)
1042
117
            {
1043
117
              JSON_NOTE (PARSER, "Replacing new root with an array");
1044
1045
117
              JsonNode *old_root = g_steal_pointer (&priv->root);
1046
117
              priv->root = json_node_new (JSON_NODE_ARRAY);
1047
1048
117
              array = json_array_new ();
1049
117
              json_array_add_element (array, old_root);
1050
117
              json_node_set_parent (old_root, priv->root);
1051
1052
117
              json_node_take_array (priv->root, array);
1053
1054
117
              priv->multi_root = true;
1055
117
            }
1056
1.30k
          else
1057
1.30k
            {
1058
1.30k
              g_assert (JSON_NODE_HOLDS_ARRAY (priv->root));
1059
1.30k
              array = json_node_get_array (priv->root);
1060
1.30k
            }
1061
1062
1.42k
          JsonNode *node = NULL;
1063
1.42k
          guint res;
1064
1065
1.42k
          res = json_parse_array (parser, scanner, &node, 0);
1066
1.42k
          if (node != NULL)
1067
1.26k
            json_array_add_element (array, node);
1068
1.42k
          return res;
1069
1.42k
        }
1070
486
      else
1071
486
        {
1072
486
          JSON_NOTE (PARSER, "Statement is array declaration");
1073
486
          return json_parse_array (parser, scanner, &priv->root, 0);
1074
486
        }
1075
0
      break;
1076
1077
    /* some web APIs are not only passing the data structures: they are
1078
     * also passing an assigment, which makes parsing horribly complicated
1079
     * only because web developers are lazy, and writing "var foo = " is
1080
     * evidently too much to request from them.
1081
     */
1082
4.15k
    case JSON_TOKEN_VAR:
1083
4.15k
      {
1084
4.15k
        guint next_token;
1085
4.15k
        gchar *name;
1086
1087
4.15k
        JSON_NOTE (PARSER, "Statement is an assignment");
1088
1089
4.15k
        if (priv->is_strict)
1090
0
          {
1091
0
            json_scanner_get_next_token (scanner);
1092
0
            priv->error_code = JSON_PARSER_ERROR_INVALID_ASSIGNMENT;
1093
0
            return JSON_TOKEN_EOF;
1094
0
          }
1095
1096
        /* swallow the 'var' token... */
1097
4.15k
        json_scanner_get_next_token (scanner);
1098
1099
        /* ... swallow the variable name... */
1100
4.15k
        next_token = json_scanner_get_next_token (scanner);
1101
4.15k
        if (next_token != JSON_TOKEN_IDENTIFIER)
1102
501
          {
1103
501
            priv->error_code = JSON_PARSER_ERROR_INVALID_BAREWORD;
1104
501
            return JSON_TOKEN_IDENTIFIER;
1105
501
          }
1106
1107
3.65k
        name = json_scanner_dup_identifier (scanner);
1108
1109
        /* ... and finally swallow the '=' */
1110
3.65k
        next_token = json_scanner_get_next_token (scanner);
1111
3.65k
        if (next_token != '=')
1112
33
          {
1113
33
            priv->error_code = JSON_PARSER_ERROR_INVALID_BAREWORD;
1114
33
            g_free (name);
1115
33
            return '=';
1116
33
          }
1117
1118
3.62k
        if (priv->has_assignment)
1119
3.45k
          g_free (priv->variable_name);
1120
3.62k
        priv->has_assignment = TRUE;
1121
3.62k
        priv->variable_name = name;
1122
1123
3.62k
        token = json_parse_statement (parser, scanner);
1124
1125
        /* remove the trailing semi-colon */
1126
3.62k
        next_token = json_scanner_peek_next_token (scanner);
1127
3.62k
        if (next_token == ';')
1128
3.21k
          {
1129
3.21k
            json_scanner_get_next_token (scanner);
1130
3.21k
            return JSON_TOKEN_NONE;
1131
3.21k
          }
1132
1133
407
        return token;
1134
3.62k
      }
1135
0
      break;
1136
1137
11
    case JSON_TOKEN_NULL:
1138
19
    case JSON_TOKEN_TRUE:
1139
22
    case JSON_TOKEN_FALSE:
1140
22
    case '-':
1141
253
    case JSON_TOKEN_INT:
1142
271
    case JSON_TOKEN_FLOAT:
1143
373
    case JSON_TOKEN_STRING:
1144
1.11k
    case JSON_TOKEN_IDENTIFIER:
1145
1.11k
      if (priv->root != NULL)
1146
440
        {
1147
440
          JSON_NOTE (PARSER, "Only one top level statement is possible");
1148
440
          json_scanner_get_next_token (scanner);
1149
440
          priv->error_code = JSON_PARSER_ERROR_INVALID_BAREWORD;
1150
440
          return JSON_TOKEN_EOF;
1151
440
        }
1152
1153
1.11k
      JSON_NOTE (PARSER, "Statement is a value");
1154
670
      token = json_scanner_get_next_token (scanner);
1155
670
      return json_parse_value (parser, scanner, token, &priv->root);
1156
1157
1.45k
    default:
1158
1.45k
      JSON_NOTE (PARSER, "Unknown statement");
1159
1.45k
      json_scanner_get_next_token (scanner);
1160
1.45k
      priv->error_code = JSON_PARSER_ERROR_INVALID_BAREWORD;
1161
1.45k
      return priv->root != NULL ? JSON_TOKEN_EOF : JSON_TOKEN_SYMBOL;
1162
629k
    }
1163
629k
}
1164
1165
static void
1166
json_scanner_msg_handler (JsonScanner *scanner,
1167
                          const char  *message,
1168
                          gpointer     user_data)
1169
1.25k
{
1170
1.25k
  JsonParser *parser = user_data;
1171
1.25k
  JsonParserPrivate *priv = parser->priv;
1172
1.25k
  GError *error = NULL;
1173
1174
1.25k
  g_set_error (&error, JSON_PARSER_ERROR,
1175
1.25k
               priv->error_code,
1176
               /* translators: %s: is the file name, the first %d is the line
1177
                * number, the second %d is the position on the line, and %s is
1178
                * the error message
1179
                */
1180
1.25k
               _("%s:%d:%d: Parse error: %s"),
1181
1.25k
               priv->is_filename ? priv->filename : "<data>",
1182
1.25k
               json_scanner_get_current_line (scanner),
1183
1.25k
               json_scanner_get_current_position (scanner),
1184
1.25k
               message);
1185
      
1186
1.25k
  parser->priv->last_error = error;
1187
1188
1.25k
  json_parser_emit_error (parser, error);
1189
1.25k
}
1190
1191
static JsonScanner *
1192
json_scanner_create (JsonParser *parser)
1193
6.50k
{
1194
6.50k
  JsonParserPrivate *priv = json_parser_get_instance_private (parser);
1195
6.50k
  JsonScanner *scanner;
1196
1197
6.50k
  scanner = json_scanner_new (priv->is_strict);
1198
6.50k
  json_scanner_set_msg_handler (scanner, json_scanner_msg_handler, parser);
1199
1200
6.50k
  return scanner;
1201
6.50k
}
1202
1203
/**
1204
 * json_parser_new:
1205
 * 
1206
 * Creates a new JSON parser.
1207
 *
1208
 * You can use the `JsonParser` to load a JSON stream from either a file or a
1209
 * buffer and then walk the hierarchy using the data types API.
1210
 *
1211
 * Returns: (transfer full): the newly created parser
1212
 */
1213
JsonParser *
1214
json_parser_new (void)
1215
6.57k
{
1216
6.57k
  return g_object_new (JSON_TYPE_PARSER, NULL);
1217
6.57k
}
1218
1219
/**
1220
 * json_parser_new_immutable:
1221
 *
1222
 * Creates a new parser instance with its [property@Json.Parser:immutable]
1223
 * property set to `TRUE` to create immutable output trees.
1224
 *
1225
 * Since: 1.2
1226
 * Returns: (transfer full): the newly created parser 
1227
 */
1228
JsonParser *
1229
json_parser_new_immutable (void)
1230
0
{
1231
0
  return g_object_new (JSON_TYPE_PARSER, "immutable", TRUE, NULL);
1232
0
}
1233
1234
static gboolean
1235
json_parser_load (JsonParser   *parser,
1236
                  const gchar  *input_data,
1237
                  gsize         length,
1238
                  GError      **error)
1239
6.57k
{
1240
6.57k
  JsonParserPrivate *priv = parser->priv;
1241
6.57k
  JsonScanner *scanner;
1242
6.57k
  gboolean done;
1243
6.57k
  gboolean retval = TRUE;
1244
6.57k
  const char *data = input_data;
1245
1246
6.57k
  if (priv->is_strict && (length == 0 || data == NULL || *data == '\0'))
1247
0
    {
1248
0
      g_set_error_literal (error, JSON_PARSER_ERROR,
1249
0
                           JSON_PARSER_ERROR_INVALID_DATA,
1250
0
                           "JSON data must not be empty");
1251
0
      json_parser_emit_error (parser, *error);
1252
0
      return FALSE;
1253
0
    }
1254
1255
6.57k
  json_parser_clear (parser);
1256
1257
6.57k
  if (!g_utf8_validate (data, length, NULL))
1258
72
    {
1259
72
      g_set_error_literal (error, JSON_PARSER_ERROR,
1260
72
                           JSON_PARSER_ERROR_INVALID_DATA,
1261
72
                           _("JSON data must be UTF-8 encoded"));
1262
72
      json_parser_emit_error (parser, *error);
1263
72
      return FALSE;
1264
72
    }
1265
1266
6.50k
  if (length >= 3)
1267
6.41k
    {
1268
      /* Check for UTF-8 signature and skip it if necessary */
1269
6.41k
       if (((data[0] & 0xFF) == 0xEF) &&
1270
6
           ((data[1] & 0xFF) == 0xBB) &&
1271
2
           ((data[2] & 0xFF) == 0xBF))
1272
1
         {
1273
1
           JSON_NOTE (PARSER, "Skipping BOM");
1274
1
           data += 3;
1275
1
           length -= 3;
1276
1
         }
1277
1278
6.41k
       if (priv->is_strict && length == 0)
1279
0
         {
1280
0
           g_set_error_literal (error, JSON_PARSER_ERROR,
1281
0
                                JSON_PARSER_ERROR_INVALID_DATA,
1282
0
                                "JSON data must not be empty after BOM character");
1283
0
           json_parser_emit_error (parser, *error);
1284
0
           return FALSE;
1285
0
         }
1286
6.41k
    }
1287
1288
  /* Skip leading space */
1289
6.50k
  if (priv->is_strict)
1290
0
    {
1291
0
      const char *p = data;
1292
0
      while (length > 0 && (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n'))
1293
0
        {
1294
0
          length -= 1;
1295
0
          data += 1;
1296
0
          p = data;
1297
0
        }
1298
1299
0
      if (length == 0)
1300
0
        {
1301
0
          g_set_error_literal (error, JSON_PARSER_ERROR,
1302
0
                               JSON_PARSER_ERROR_INVALID_DATA,
1303
0
                               "JSON data must not be empty after leading whitespace");
1304
0
          json_parser_emit_error (parser, *error);
1305
0
          return FALSE;
1306
0
        }
1307
0
    }
1308
1309
6.50k
  scanner = json_scanner_create (parser);
1310
6.50k
  json_scanner_input_text (scanner, data, length);
1311
1312
6.50k
  priv->scanner = scanner;
1313
1314
6.50k
  json_parser_emit_parse_start (parser);
1315
1316
6.50k
  done = FALSE;
1317
637k
  while (!done)
1318
630k
    {
1319
630k
      if (json_scanner_peek_next_token (scanner) == JSON_TOKEN_EOF)
1320
5.25k
        done = TRUE;
1321
625k
      else
1322
625k
        {
1323
625k
          unsigned int expected_token;
1324
1325
          /* we try to show the expected token, if possible */
1326
625k
          expected_token = json_parse_statement (parser, scanner);
1327
625k
          if (expected_token != JSON_TOKEN_NONE)
1328
1.25k
            {
1329
              /* this will emit the ::error signal via the custom
1330
               * message handler we install
1331
               */
1332
1.25k
              json_scanner_unknown_token (scanner, expected_token);
1333
1334
              /* and this will propagate the error we create in the
1335
               * same message handler
1336
               */
1337
1.25k
              if (priv->last_error)
1338
1.25k
                {
1339
1.25k
                  g_propagate_error (error, priv->last_error);
1340
1.25k
                  priv->last_error = NULL;
1341
1.25k
                }
1342
1343
1.25k
              retval = FALSE;
1344
1.25k
              done = TRUE;
1345
1.25k
            }
1346
625k
        }
1347
630k
    }
1348
1349
6.50k
  json_parser_emit_parse_end (parser);
1350
1351
  /* remove the scanner */
1352
6.50k
  json_scanner_destroy (scanner);
1353
6.50k
  priv->scanner = NULL;
1354
6.50k
  priv->current_node = NULL;
1355
1356
6.50k
  return retval;
1357
6.50k
}
1358
1359
/**
1360
 * json_parser_load_from_file:
1361
 * @parser: a parser
1362
 * @filename: (type filename): the path for the file to parse
1363
 * @error: return location for a #GError
1364
 *
1365
 * Loads a JSON stream from the content of `filename` and parses it.
1366
 *
1367
 * If the file is large or shared between processes,
1368
 * [method@Json.Parser.load_from_mapped_file] may be a more efficient
1369
 * way to load it.
1370
 *
1371
 * See also: [method@Json.Parser.load_from_data]
1372
 *
1373
 * Returns: `TRUE` if the file was successfully loaded and parsed.
1374
 */
1375
gboolean
1376
json_parser_load_from_file (JsonParser   *parser,
1377
                            const gchar  *filename,
1378
                            GError      **error)
1379
0
{
1380
0
  JsonParserPrivate *priv;
1381
0
  GError *internal_error;
1382
0
  gchar *data;
1383
0
  gsize length;
1384
0
  gboolean retval = TRUE;
1385
1386
0
  g_return_val_if_fail (JSON_IS_PARSER (parser), FALSE);
1387
0
  g_return_val_if_fail (filename != NULL, FALSE);
1388
1389
0
  priv = parser->priv;
1390
1391
0
  internal_error = NULL;
1392
0
  if (!g_file_get_contents (filename, &data, &length, &internal_error))
1393
0
    {
1394
0
      g_propagate_error (error, internal_error);
1395
0
      return FALSE;
1396
0
    }
1397
1398
0
  g_free (priv->filename);
1399
1400
0
  priv->is_filename = TRUE;
1401
0
  priv->filename = g_strdup (filename);
1402
1403
0
  if (!json_parser_load (parser, data, length, &internal_error))
1404
0
    {
1405
0
      g_propagate_error (error, internal_error);
1406
0
      retval = FALSE;
1407
0
    }
1408
1409
0
  g_free (data);
1410
1411
0
  return retval;
1412
0
}
1413
1414
/**
1415
 * json_parser_load_from_mapped_file:
1416
 * @parser: a parser
1417
 * @filename: (type filename): the path for the file to parse
1418
 * @error: return location for a #GError
1419
 *
1420
 * Loads a JSON stream from the content of `filename` and parses it.
1421
 *
1422
 * Unlike [method@Json.Parser.load_from_file], `filename` will be memory
1423
 * mapped as read-only and parsed. `filename` will be unmapped before this
1424
 * function returns.
1425
 *
1426
 * If mapping or reading the file fails, a `G_FILE_ERROR` will be returned.
1427
 *
1428
 * Returns: `TRUE` if the file was successfully loaded and parsed.
1429
 * Since: 1.6
1430
 */
1431
gboolean
1432
json_parser_load_from_mapped_file (JsonParser   *parser,
1433
                                   const gchar  *filename,
1434
                                   GError      **error)
1435
0
{
1436
0
  JsonParserPrivate *priv;
1437
0
  GError *internal_error = NULL;
1438
0
  gboolean retval = TRUE;
1439
0
  GMappedFile *mapped_file = NULL;
1440
1441
0
  g_return_val_if_fail (JSON_IS_PARSER (parser), FALSE);
1442
0
  g_return_val_if_fail (filename != NULL, FALSE);
1443
1444
0
  priv = parser->priv;
1445
1446
0
  mapped_file = g_mapped_file_new (filename, FALSE, &internal_error);
1447
0
  if (mapped_file == NULL)
1448
0
    {
1449
0
      g_propagate_error (error, internal_error);
1450
0
      return FALSE;
1451
0
    }
1452
1453
0
  g_free (priv->filename);
1454
1455
0
  priv->is_filename = TRUE;
1456
0
  priv->filename = g_strdup (filename);
1457
1458
0
  if (!json_parser_load (parser, g_mapped_file_get_contents (mapped_file),
1459
0
                         g_mapped_file_get_length (mapped_file), &internal_error))
1460
0
    {
1461
0
      g_propagate_error (error, internal_error);
1462
0
      retval = FALSE;
1463
0
    }
1464
1465
0
  g_clear_pointer (&mapped_file, g_mapped_file_unref);
1466
1467
0
  return retval;
1468
0
}
1469
1470
/**
1471
 * json_parser_load_from_data:
1472
 * @parser: a parser
1473
 * @data: the buffer to parse
1474
 * @length: the length of the buffer, or -1 if it is `NUL` terminated
1475
 * @error: return location for a #GError
1476
 *
1477
 * Loads a JSON stream from a buffer and parses it.
1478
 *
1479
 * You can call this function multiple times with the same parser, but the
1480
 * contents of the parser will be destroyed each time.
1481
 *
1482
 * Returns: `TRUE` if the buffer was succesfully parsed
1483
 */
1484
gboolean
1485
json_parser_load_from_data (JsonParser   *parser,
1486
                            const gchar  *data,
1487
                            gssize        length,
1488
                            GError      **error)
1489
0
{
1490
0
  JsonParserPrivate *priv;
1491
0
  GError *internal_error;
1492
0
  gboolean retval = TRUE;
1493
1494
0
  g_return_val_if_fail (JSON_IS_PARSER (parser), FALSE);
1495
0
  g_return_val_if_fail (data != NULL, FALSE);
1496
1497
0
  priv = parser->priv;
1498
1499
0
  if (length < 0)
1500
0
    length = strlen (data);
1501
1502
0
  priv->is_filename = FALSE;
1503
0
  g_free (priv->filename);
1504
0
  priv->filename = NULL;
1505
1506
0
  internal_error = NULL;
1507
0
  if (!json_parser_load (parser, data, length, &internal_error))
1508
0
    {
1509
0
      g_propagate_error (error, internal_error);
1510
0
      retval = FALSE;
1511
0
    }
1512
1513
0
  return retval;
1514
0
}
1515
1516
/**
1517
 * json_parser_get_root:
1518
 * @parser: a parser
1519
 *
1520
 * Retrieves the top level node from the parsed JSON stream.
1521
 *
1522
 * If the parser input was an empty string, or if parsing failed, the root
1523
 * will be `NULL`. It will also be `NULL` if it has been stolen using
1524
 * [method@Json.Parser.steal_root].
1525
 *
1526
 * Returns: (transfer none) (nullable): the root node.
1527
 */
1528
JsonNode *
1529
json_parser_get_root (JsonParser *parser)
1530
5.25k
{
1531
5.25k
  g_return_val_if_fail (JSON_IS_PARSER (parser), NULL);
1532
1533
  /* Sanity check. */
1534
5.25k
  g_assert (parser->priv->root == NULL ||
1535
5.25k
            !parser->priv->is_immutable ||
1536
5.25k
            json_node_is_immutable (parser->priv->root));
1537
1538
5.25k
  return parser->priv->root;
1539
5.25k
}
1540
1541
/**
1542
 * json_parser_steal_root:
1543
 * @parser: a parser
1544
 *
1545
 * Steals the top level node from the parsed JSON stream.
1546
 *
1547
 * This will be `NULL` in the same situations as [method@Json.Parser.get_root]
1548
 * return `NULL`.
1549
 *
1550
 * Returns: (transfer full) (nullable): the root node
1551
 *
1552
 * Since: 1.4
1553
 */
1554
JsonNode *
1555
json_parser_steal_root (JsonParser *parser)
1556
0
{
1557
0
  JsonParserPrivate *priv = json_parser_get_instance_private (parser);
1558
1559
0
  g_return_val_if_fail (JSON_IS_PARSER (parser), NULL);
1560
1561
  /* Sanity check. */
1562
0
  g_assert (parser->priv->root == NULL ||
1563
0
            !parser->priv->is_immutable ||
1564
0
            json_node_is_immutable (parser->priv->root));
1565
1566
0
  return g_steal_pointer (&priv->root);
1567
0
}
1568
1569
/**
1570
 * json_parser_get_current_line:
1571
 * @parser: a parser
1572
 *
1573
 * Retrieves the line currently parsed, starting from 1.
1574
 *
1575
 * This function has defined behaviour only while parsing; calling this
1576
 * function from outside the signal handlers emitted by the parser will
1577
 * yield 0.
1578
 *
1579
 * Returns: the currently parsed line, or 0.
1580
 */
1581
guint
1582
json_parser_get_current_line (JsonParser *parser)
1583
0
{
1584
0
  g_return_val_if_fail (JSON_IS_PARSER (parser), 0);
1585
1586
0
  if (parser->priv->scanner != NULL)
1587
0
    return json_scanner_get_current_line (parser->priv->scanner);
1588
1589
0
  return 0;
1590
0
}
1591
1592
/**
1593
 * json_parser_get_current_pos:
1594
 * @parser: a parser
1595
 *
1596
 * Retrieves the current position inside the current line, starting
1597
 * from 0.
1598
 *
1599
 * This function has defined behaviour only while parsing; calling this
1600
 * function from outside the signal handlers emitted by the parser will
1601
 * yield 0.
1602
 *
1603
 * Returns: the position in the current line, or 0.
1604
 */
1605
guint
1606
json_parser_get_current_pos (JsonParser *parser)
1607
0
{
1608
0
  g_return_val_if_fail (JSON_IS_PARSER (parser), 0);
1609
1610
0
  if (parser->priv->scanner != NULL)
1611
0
    return json_scanner_get_current_position (parser->priv->scanner);
1612
1613
0
  return 0;
1614
0
}
1615
1616
/**
1617
 * json_parser_has_assignment:
1618
 * @parser: a parser
1619
 * @variable_name: (out) (optional) (transfer none): the variable name
1620
 *
1621
 * A JSON data stream might sometimes contain an assignment, like:
1622
 *
1623
 * ```
1624
 * var _json_data = { "member_name" : [ ...
1625
 * ```
1626
 *
1627
 * even though it would technically constitute a violation of the RFC.
1628
 *
1629
 * `JsonParser` will ignore the left hand identifier and parse the right
1630
 * hand value of the assignment. `JsonParser` will record, though, the
1631
 * existence of the assignment in the data stream and the variable name
1632
 * used.
1633
 *
1634
 * Returns: `TRUE` if there was an assignment, and `FALSE` otherwise
1635
 *
1636
 * Since: 0.4
1637
 */
1638
gboolean
1639
json_parser_has_assignment (JsonParser  *parser,
1640
                            gchar      **variable_name)
1641
0
{
1642
0
  JsonParserPrivate *priv;
1643
1644
0
  g_return_val_if_fail (JSON_IS_PARSER (parser), FALSE);
1645
1646
0
  priv = parser->priv;
1647
1648
0
  if (priv->has_assignment && variable_name)
1649
0
    *variable_name = priv->variable_name;
1650
1651
0
  return priv->has_assignment;
1652
0
}
1653
1654
60.5k
#define GET_DATA_BLOCK_SIZE     8192
1655
1656
/**
1657
 * json_parser_load_from_stream:
1658
 * @parser: a parser
1659
 * @stream: the input stream with the JSON data
1660
 * @cancellable: (nullable): a #GCancellable
1661
 * @error: the return location for a #GError
1662
 *
1663
 * Loads the contents of an input stream and parses them.
1664
 *
1665
 * If `cancellable` is not `NULL`, then the operation can be cancelled by
1666
 * triggering the cancellable object from another thread. If the
1667
 * operation was cancelled, `G_IO_ERROR_CANCELLED` will be set
1668
 * on the given `error`.
1669
 *
1670
 * Returns: `TRUE` if the data stream was successfully read and
1671
 *   parsed, and `FALSE` otherwise
1672
 *
1673
 * Since: 0.12
1674
 */
1675
gboolean
1676
json_parser_load_from_stream (JsonParser    *parser,
1677
                              GInputStream  *stream,
1678
                              GCancellable  *cancellable,
1679
                              GError       **error)
1680
6.57k
{
1681
6.57k
  GByteArray *content;
1682
6.57k
  gsize pos;
1683
6.57k
  gssize res;
1684
6.57k
  gboolean retval = FALSE;
1685
6.57k
  GError *internal_error;
1686
1687
6.57k
  g_return_val_if_fail (JSON_IS_PARSER (parser), FALSE);
1688
6.57k
  g_return_val_if_fail (G_IS_INPUT_STREAM (stream), FALSE);
1689
6.57k
  g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE);
1690
1691
6.57k
  if (g_cancellable_set_error_if_cancelled (cancellable, error))
1692
0
    return FALSE;
1693
1694
6.57k
  content = g_byte_array_new ();
1695
6.57k
  pos = 0;
1696
1697
6.57k
  g_byte_array_set_size (content, pos + GET_DATA_BLOCK_SIZE + 1);
1698
30.2k
  while ((res = g_input_stream_read (stream, content->data + pos,
1699
30.2k
                                     GET_DATA_BLOCK_SIZE,
1700
30.2k
                                     cancellable, error)) > 0)
1701
23.6k
    {
1702
23.6k
      pos += res;
1703
23.6k
      g_byte_array_set_size (content, pos + GET_DATA_BLOCK_SIZE + 1);
1704
23.6k
    }
1705
1706
6.57k
  if (res < 0)
1707
0
    {
1708
      /* error has already been set */
1709
0
      retval = FALSE;
1710
0
      goto out;
1711
0
    }
1712
1713
  /* zero-terminate the content; we allocated an extra byte for this */
1714
6.57k
  content->data[pos] = 0;
1715
1716
6.57k
  internal_error = NULL;
1717
6.57k
  retval = json_parser_load (parser, (const gchar *) content->data, pos, &internal_error);
1718
1719
6.57k
  if (internal_error != NULL)
1720
1.32k
    g_propagate_error (error, internal_error);
1721
1722
6.57k
out:
1723
6.57k
  g_byte_array_free (content, TRUE);
1724
1725
6.57k
  return retval;
1726
6.57k
}
1727
1728
typedef struct {
1729
  GInputStream *stream;
1730
  GByteArray *content;
1731
  gsize pos;
1732
} LoadData;
1733
1734
static void
1735
load_data_free (gpointer data_)
1736
0
{
1737
0
  if (data_ != NULL)
1738
0
    {
1739
0
      LoadData *data = data_;
1740
1741
0
      g_object_unref (data->stream);
1742
0
      g_byte_array_unref (data->content);
1743
0
      g_free (data);
1744
0
    }
1745
0
}
1746
1747
/**
1748
 * json_parser_load_from_stream_finish:
1749
 * @parser: a parser
1750
 * @result: the result of the asynchronous operation
1751
 * @error: the return location for a #GError
1752
 *
1753
 * Finishes an asynchronous stream loading started with
1754
 * [method@Json.Parser.load_from_stream_async].
1755
 *
1756
 * Returns: `TRUE` if the content of the stream was successfully retrieved
1757
 *   and parsed, and `FALSE` otherwise
1758
 *
1759
 * Since: 0.12
1760
 */
1761
gboolean
1762
json_parser_load_from_stream_finish (JsonParser    *parser,
1763
                                     GAsyncResult  *result,
1764
                                     GError       **error)
1765
0
{
1766
0
  gboolean res;
1767
1768
0
  g_return_val_if_fail (JSON_IS_PARSER (parser), FALSE);
1769
0
  g_return_val_if_fail (g_task_is_valid (result, parser), FALSE);
1770
1771
0
  res = g_task_propagate_boolean (G_TASK (result), error);
1772
0
  if (res)
1773
0
    {
1774
0
      LoadData *data = g_task_get_task_data (G_TASK (result));
1775
0
      GError *internal_error = NULL;
1776
1777
      /* We need to do this inside the finish() function because JsonParser will emit
1778
       * signals, and we need to ensure that the signals are emitted in the right
1779
       * context; it's easier to do that if we just rely on the async callback being
1780
       * called in the right context, even if it means making the finish() function
1781
       * necessary to complete the async operation.
1782
       */
1783
0
      res = json_parser_load (parser, (const gchar *) data->content->data, data->pos, &internal_error);
1784
0
      if (internal_error != NULL)
1785
0
        g_propagate_error (error, internal_error);
1786
0
    }
1787
1788
0
  return res;
1789
0
}
1790
1791
static void
1792
read_from_stream (GTask *task,
1793
                  gpointer source_obj G_GNUC_UNUSED,
1794
                  gpointer task_data,
1795
                  GCancellable *cancellable)
1796
0
{
1797
0
  LoadData *data = task_data;
1798
0
  GError *error = NULL;
1799
0
  gssize res;
1800
1801
0
  data->pos = 0;
1802
0
  g_byte_array_set_size (data->content, data->pos + GET_DATA_BLOCK_SIZE + 1);
1803
0
  while ((res = g_input_stream_read (data->stream,
1804
0
                                     data->content->data + data->pos,
1805
0
                                     GET_DATA_BLOCK_SIZE,
1806
0
                                     cancellable, &error)) > 0)
1807
0
    {
1808
0
      data->pos += res;
1809
0
      g_byte_array_set_size (data->content, data->pos + GET_DATA_BLOCK_SIZE + 1);
1810
0
    }
1811
1812
0
  if (res < 0)
1813
0
    {
1814
0
      g_task_return_error (task, error);
1815
0
      return;
1816
0
    }
1817
1818
  /* zero-terminate the content; we allocated an extra byte for this */
1819
0
  data->content->data[data->pos] = 0;
1820
0
  g_task_return_boolean (task, TRUE);
1821
0
}
1822
1823
/**
1824
 * json_parser_load_from_stream_async:
1825
 * @parser: a parser
1826
 * @stream: the input stream with the JSON data
1827
 * @cancellable: (nullable): a #GCancellable
1828
 * @callback: (scope async): the function to call when the request is satisfied
1829
 * @user_data: the data to pass to @callback
1830
 *
1831
 * Asynchronously reads the contents of a stream.
1832
 *
1833
 * For more details, see [method@Json.Parser.load_from_stream], which is the
1834
 * synchronous version of this call.
1835
 *
1836
 * When the operation is finished, @callback will be called. You should
1837
 * then call [method@Json.Parser.load_from_stream_finish] to get the result
1838
 * of the operation.
1839
 *
1840
 * Since: 0.12
1841
 */
1842
void
1843
json_parser_load_from_stream_async (JsonParser          *parser,
1844
                                    GInputStream        *stream,
1845
                                    GCancellable        *cancellable,
1846
                                    GAsyncReadyCallback  callback,
1847
                                    gpointer             user_data)
1848
0
{
1849
0
  LoadData *data;
1850
0
  GTask *task;
1851
1852
0
  g_return_if_fail (JSON_IS_PARSER (parser));
1853
0
  g_return_if_fail (G_IS_INPUT_STREAM (stream));
1854
0
  g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
1855
1856
0
  data = g_new (LoadData, 1);
1857
0
  data->stream = g_object_ref (stream);
1858
0
  data->content = g_byte_array_new ();
1859
0
  data->pos = 0;
1860
1861
0
  task = g_task_new (parser, cancellable, callback, user_data);
1862
0
  g_task_set_task_data (task, data, load_data_free);
1863
1864
0
  g_task_run_in_thread (task, read_from_stream);
1865
0
  g_object_unref (task);
1866
0
}
1867
1868
/**
1869
 * json_parser_set_strict:
1870
 * @parser: the JSON parser
1871
 * @strict: whether the parser should be strict
1872
 *
1873
 * Sets whether the parser should operate in strict mode.
1874
 *
1875
 * If @strict is true, `JsonParser` will strictly conform to
1876
 * the JSON format.
1877
 *
1878
 * If @strict is false, `JsonParser` will allow custom extensions
1879
 * to the JSON format, like comments.
1880
 *
1881
 * Since: 1.10
1882
 */
1883
void
1884
json_parser_set_strict (JsonParser *parser,
1885
                        gboolean    strict)
1886
0
{
1887
0
  g_return_if_fail (JSON_IS_PARSER (parser));
1888
1889
0
  JsonParserPrivate *priv = json_parser_get_instance_private (parser);
1890
1891
0
  strict = !!strict;
1892
1893
0
  if (priv->is_strict != strict)
1894
0
    {
1895
0
      priv->is_strict = strict;
1896
0
      g_object_notify_by_pspec (G_OBJECT (parser), parser_props[PROP_STRICT]);
1897
0
    }
1898
0
}
1899
1900
/**
1901
 * json_parser_get_strict:
1902
 * @parser: the JSON parser
1903
 *
1904
 * Retrieves whether the parser is operating in strict mode.
1905
 *
1906
 * Returns: true if the parser is strict, and false otherwise
1907
 *
1908
 * Since: 1.10
1909
 */
1910
gboolean
1911
json_parser_get_strict (JsonParser *parser)
1912
0
{
1913
0
  g_return_val_if_fail (JSON_IS_PARSER (parser), FALSE);
1914
1915
0
  JsonParserPrivate *priv = json_parser_get_instance_private (parser);
1916
1917
0
  return priv->is_strict;
1918
0
}