Coverage Report

Created: 2025-07-12 06:31

/src/tinysparql/subprojects/json-glib-1.10.6/json-glib/json-array.c
Line
Count
Source (jump to first uncovered line)
1
/* json-array.c - JSON array implementation
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
#include "config.h"
27
28
#include "json-types-private.h"
29
30
/**
31
 * JsonArray:
32
 *
33
 * `JsonArray` is the representation of the array type inside JSON.
34
 *
35
 * A `JsonArray` contains [struct@Json.Node] elements, which may contain
36
 * fundamental types, other arrays or objects.
37
 *
38
 * Since arrays can be arbitrarily big, copying them can be expensive; for
39
 * this reason, they are reference counted. You can control the lifetime of
40
 * a `JsonArray` using [method@Json.Array.ref] and [method@Json.Array.unref].
41
 *
42
 * To append an element, use [method@Json.Array.add_element].
43
 *
44
 * To extract an element at a given index, use [method@Json.Array.get_element].
45
 *
46
 * To retrieve the entire array in list form, use [method@Json.Array.get_elements].
47
 *
48
 * To retrieve the length of the array, use [method@Json.Array.get_length].
49
 */
50
51
G_DEFINE_BOXED_TYPE (JsonArray, json_array, json_array_ref, json_array_unref);
52
53
/**
54
 * json_array_new: (constructor)
55
 *
56
 * Creates a new array.
57
 *
58
 * Return value: (transfer full): the newly created array
59
 */
60
JsonArray *
61
json_array_new (void)
62
176k
{
63
176k
  JsonArray *array;
64
65
176k
  array = g_new0 (JsonArray, 1);
66
67
176k
  g_ref_count_init (&array->ref_count);
68
176k
  array->elements = g_ptr_array_new ();
69
70
176k
  return array;
71
176k
}
72
73
/**
74
 * json_array_sized_new: (constructor)
75
 * @n_elements: number of slots to pre-allocate
76
 *
77
 * Creates a new array with `n_elements` slots already allocated.
78
 *
79
 * Return value: (transfer full): the newly created array
80
 */
81
JsonArray *
82
json_array_sized_new (guint n_elements)
83
0
{
84
0
  JsonArray *array;
85
86
0
  array = g_new0 (JsonArray, 1);
87
88
0
  g_ref_count_init (&array->ref_count);
89
0
  array->elements = g_ptr_array_sized_new (n_elements);
90
91
0
  return array;
92
0
}
93
94
/**
95
 * json_array_ref:
96
 * @array: the array to reference
97
 *
98
 * Acquires a reference on the given array.
99
 *
100
 * Return value: (transfer none): the passed array, with the reference count
101
 *   increased by one
102
 */
103
JsonArray *
104
json_array_ref (JsonArray *array)
105
3.38k
{
106
3.38k
  g_return_val_if_fail (array != NULL, NULL);
107
108
3.38k
  g_ref_count_inc (&array->ref_count);
109
110
3.38k
  return array;
111
3.38k
}
112
113
/**
114
 * json_array_unref:
115
 * @array: the array to unreference
116
 *
117
 * Releases a reference on the given array.
118
 *
119
 * If the reference count reaches zero, the array is destroyed and all
120
 * its allocated resources are freed.
121
 */
122
void
123
json_array_unref (JsonArray *array)
124
180k
{
125
180k
  g_return_if_fail (array != NULL);
126
127
180k
  if (g_ref_count_dec (&array->ref_count))
128
176k
    {
129
941k
      for (guint i = 0; i < array->elements->len; i++)
130
764k
        json_node_unref (g_ptr_array_index (array->elements, i));
131
132
176k
      g_ptr_array_free (array->elements, TRUE);
133
176k
      array->elements = NULL;
134
135
176k
      g_free (array);
136
176k
    }
137
180k
}
138
139
/**
140
 * json_array_seal:
141
 * @array: the array to seal
142
 *
143
 * Seals the given array, making it immutable to further changes.
144
 *
145
 * This function will recursively seal all elements in the array too.
146
 *
147
 * If the `array` is already immutable, this is a no-op.
148
 *
149
 * Since: 1.2
150
 */
151
void
152
json_array_seal (JsonArray *array)
153
0
{
154
0
  g_return_if_fail (array != NULL);
155
156
0
  if (array->immutable)
157
0
    return;
158
159
  /* Propagate to all members. */
160
0
  for (guint i = 0; i < array->elements->len; i++)
161
0
    json_node_seal (g_ptr_array_index (array->elements, i));
162
163
0
  array->immutable_hash = json_array_hash (array);
164
0
  array->immutable = TRUE;
165
0
}
166
167
/**
168
 * json_array_is_immutable:
169
 * @array: a JSON array
170
 *
171
 * Check whether the given `array` has been marked as immutable by calling
172
 * [method@Json.Array.seal] on it.
173
 *
174
 * Since: 1.2
175
 * Returns: %TRUE if the array is immutable
176
 */
177
gboolean
178
json_array_is_immutable (JsonArray *array)
179
0
{
180
0
  g_return_val_if_fail (array != NULL, FALSE);
181
182
0
  return array->immutable;
183
0
}
184
185
/**
186
 * json_array_get_elements:
187
 * @array: a JSON array
188
 *
189
 * Retrieves all the elements of an array as a list of nodes.
190
 *
191
 * Return value: (element-type JsonNode) (transfer container) (nullable): the elements
192
 *   of the array
193
 */
194
GList *
195
json_array_get_elements (JsonArray *array)
196
0
{
197
0
  GList *retval;
198
0
  guint i;
199
200
0
  g_return_val_if_fail (array != NULL, NULL);
201
202
0
  retval = NULL;
203
0
  for (i = 0; i < array->elements->len; i++)
204
0
    retval = g_list_prepend (retval,
205
0
                             g_ptr_array_index (array->elements, i));
206
207
0
  return g_list_reverse (retval);
208
0
}
209
210
/**
211
 * json_array_dup_element:
212
 * @array: a JSON array
213
 * @index_: the index of the element to retrieve
214
 *
215
 * Retrieves a copy of the element at the given position in the array.
216
 *
217
 * Return value: (transfer full): a copy of the element at the given position
218
 *
219
 * Since: 0.6
220
 */
221
JsonNode *
222
json_array_dup_element (JsonArray *array,
223
                        guint      index_)
224
0
{
225
0
  JsonNode *retval;
226
227
0
  g_return_val_if_fail (array != NULL, NULL);
228
0
  g_return_val_if_fail (index_ < array->elements->len, NULL);
229
230
0
  retval = json_array_get_element (array, index_);
231
0
  if (!retval)
232
0
    return NULL;
233
234
0
  return json_node_copy (retval);
235
0
}
236
237
/**
238
 * json_array_get_element:
239
 * @array: a JSON array
240
 * @index_: the index of the element to retrieve
241
 *
242
 * Retrieves the element at the given position in the array.
243
 *
244
 * Return value: (transfer none): the element at the given position
245
 */
246
JsonNode *
247
json_array_get_element (JsonArray *array,
248
                        guint      index_)
249
502k
{
250
502k
  g_return_val_if_fail (array != NULL, NULL);
251
502k
  g_return_val_if_fail (index_ < array->elements->len, NULL);
252
253
502k
  return g_ptr_array_index (array->elements, index_);
254
502k
}
255
256
/**
257
 * json_array_get_int_element:
258
 * @array: a JSON array
259
 * @index_: the index of the element to retrieve
260
 *
261
 * Conveniently retrieves the integer value of the element at the given
262
 * position inside an array.
263
 *
264
 * See also: [method@Json.Array.get_element], [method@Json.Node.get_int]
265
 *
266
 * Return value: the integer value
267
 *
268
 * Since: 0.8
269
 */
270
gint64
271
json_array_get_int_element (JsonArray *array,
272
                            guint      index_)
273
0
{
274
0
  JsonNode *node;
275
276
0
  g_return_val_if_fail (array != NULL, 0);
277
0
  g_return_val_if_fail (index_ < array->elements->len, 0);
278
279
0
  node = g_ptr_array_index (array->elements, index_);
280
0
  g_return_val_if_fail (node != NULL, 0);
281
0
  g_return_val_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_VALUE, 0);
282
283
0
  return json_node_get_int (node);
284
0
}
285
286
/**
287
 * json_array_get_double_element:
288
 * @array: a JSON array
289
 * @index_: the index of the element to retrieve
290
 *
291
 * Conveniently retrieves the floating point value of the element at
292
 * the given position inside an array.
293
 *
294
 * See also: [method@Json.Array.get_element], [method@Json.Node.get_double]
295
 *
296
 * Return value: the floating point value
297
 *
298
 * Since: 0.8
299
 */
300
gdouble
301
json_array_get_double_element (JsonArray *array,
302
                               guint      index_)
303
0
{
304
0
  JsonNode *node;
305
306
0
  g_return_val_if_fail (array != NULL, 0.0);
307
0
  g_return_val_if_fail (index_ < array->elements->len, 0.0);
308
309
0
  node = g_ptr_array_index (array->elements, index_);
310
0
  g_return_val_if_fail (node != NULL, 0.0);
311
0
  g_return_val_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_VALUE, 0.0);
312
313
0
  return json_node_get_double (node);
314
0
}
315
316
/**
317
 * json_array_get_boolean_element:
318
 * @array: a JSON array
319
 * @index_: the index of the element to retrieve
320
 *
321
 * Conveniently retrieves the boolean value of the element at the given
322
 * position inside an array.
323
 *
324
 * See also: [method@Json.Array.get_element], [method@Json.Node.get_boolean]
325
 *
326
 * Return value: the boolean value
327
 *
328
 * Since: 0.8
329
 */
330
gboolean
331
json_array_get_boolean_element (JsonArray *array,
332
                                guint      index_)
333
0
{
334
0
  JsonNode *node;
335
336
0
  g_return_val_if_fail (array != NULL, FALSE);
337
0
  g_return_val_if_fail (index_ < array->elements->len, FALSE);
338
339
0
  node = g_ptr_array_index (array->elements, index_);
340
0
  g_return_val_if_fail (node != NULL, FALSE);
341
0
  g_return_val_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_VALUE, FALSE);
342
343
0
  return json_node_get_boolean (node);
344
0
}
345
346
/**
347
 * json_array_get_string_element:
348
 * @array: a JSON array
349
 * @index_: the index of the element to retrieve
350
 *
351
 * Conveniently retrieves the string value of the element at the given
352
 * position inside an array.
353
 *
354
 * See also: [method@Json.Array.get_element], [method@Json.Node.get_string]
355
 *
356
 * Return value: (transfer none): the string value
357
 *
358
 * Since: 0.8
359
 */
360
const gchar *
361
json_array_get_string_element (JsonArray *array,
362
                               guint      index_)
363
0
{
364
0
  JsonNode *node;
365
366
0
  g_return_val_if_fail (array != NULL, NULL);
367
0
  g_return_val_if_fail (index_ < array->elements->len, NULL);
368
369
0
  node = g_ptr_array_index (array->elements, index_);
370
0
  g_return_val_if_fail (node != NULL, NULL);
371
0
  g_return_val_if_fail (JSON_NODE_HOLDS_VALUE (node) || JSON_NODE_HOLDS_NULL (node), NULL);
372
373
0
  if (JSON_NODE_HOLDS_NULL (node))
374
0
    return NULL;
375
376
0
  return json_node_get_string (node);
377
0
}
378
379
/**
380
 * json_array_get_null_element:
381
 * @array: a JSON array
382
 * @index_: the index of the element to retrieve
383
 *
384
 * Conveniently checks whether the element at the given position inside the
385
 * array contains a `null` value.
386
 *
387
 * See also: [method@Json.Array.get_element], [method@Json.Node.is_null]
388
 *
389
 * Return value: `TRUE` if the element is `null`
390
 *
391
 * Since: 0.8
392
 */
393
gboolean
394
json_array_get_null_element (JsonArray *array,
395
                             guint      index_)
396
0
{
397
0
  JsonNode *node;
398
399
0
  g_return_val_if_fail (array != NULL, FALSE);
400
0
  g_return_val_if_fail (index_ < array->elements->len, FALSE);
401
402
0
  node = g_ptr_array_index (array->elements, index_);
403
0
  g_return_val_if_fail (node != NULL, FALSE);
404
405
0
  if (JSON_NODE_HOLDS_NULL (node))
406
0
    return TRUE;
407
408
0
  if (JSON_NODE_HOLDS_ARRAY (node))
409
0
    return json_node_get_array (node) == NULL;
410
411
0
  if (JSON_NODE_HOLDS_OBJECT (node))
412
0
    return json_node_get_object (node) == NULL;
413
414
0
  return FALSE;
415
0
}
416
417
/**
418
 * json_array_get_array_element:
419
 * @array: a JSON array
420
 * @index_: the index of the element to retrieve
421
 *
422
 * Conveniently retrieves the array at the given position inside an array.
423
 *
424
 * See also: [method@Json.Array.get_element], [method@Json.Node.get_array]
425
 *
426
 * Return value: (transfer none): the array
427
 *
428
 * Since: 0.8
429
 */
430
JsonArray *
431
json_array_get_array_element (JsonArray *array,
432
                              guint      index_)
433
0
{
434
0
  JsonNode *node;
435
436
0
  g_return_val_if_fail (array != NULL, NULL);
437
0
  g_return_val_if_fail (index_ < array->elements->len, NULL);
438
439
0
  node = g_ptr_array_index (array->elements, index_);
440
0
  g_return_val_if_fail (node != NULL, NULL);
441
0
  g_return_val_if_fail (JSON_NODE_HOLDS_ARRAY (node) || JSON_NODE_HOLDS_NULL (node), NULL);
442
443
0
  if (JSON_NODE_HOLDS_NULL (node))
444
0
    return NULL;
445
446
0
  return json_node_get_array (node);
447
0
}
448
449
/**
450
 * json_array_get_object_element:
451
 * @array: a JSON array
452
 * @index_: the index of the element to retrieve
453
 *
454
 * Conveniently retrieves the object at the given position inside an array.
455
 *
456
 * See also: [method@Json.Array.get_element], [method@Json.Node.get_object]
457
 *
458
 * Return value: (transfer none): the object
459
 *
460
 * Since: 0.8
461
 */
462
JsonObject *
463
json_array_get_object_element (JsonArray *array,
464
                               guint      index_)
465
0
{
466
0
  JsonNode *node;
467
468
0
  g_return_val_if_fail (array != NULL, NULL);
469
0
  g_return_val_if_fail (index_ < array->elements->len, NULL);
470
471
0
  node = g_ptr_array_index (array->elements, index_);
472
0
  g_return_val_if_fail (node != NULL, NULL);
473
0
  g_return_val_if_fail (JSON_NODE_HOLDS_OBJECT (node) || JSON_NODE_HOLDS_NULL (node), NULL);
474
475
0
  if (JSON_NODE_HOLDS_NULL (node))
476
0
    return NULL;
477
478
0
  return json_node_get_object (node);
479
0
}
480
481
/**
482
 * json_array_get_length:
483
 * @array: a JSON array
484
 *
485
 * Retrieves the length of the given array
486
 *
487
 * Return value: the length of the array
488
 */
489
guint
490
json_array_get_length (JsonArray *array)
491
647k
{
492
647k
  g_return_val_if_fail (array != NULL, 0);
493
494
647k
  return array->elements->len;
495
647k
}
496
497
/**
498
 * json_array_add_element:
499
 * @array: a JSON array
500
 * @node: (transfer full): the element to add
501
 *
502
 * Appends the given `node` inside an array.
503
 */
504
void
505
json_array_add_element (JsonArray *array,
506
                        JsonNode  *node)
507
764k
{
508
764k
  g_return_if_fail (array != NULL);
509
764k
  g_return_if_fail (node != NULL);
510
511
764k
  g_ptr_array_add (array->elements, node);
512
764k
}
513
514
/**
515
 * json_array_add_int_element:
516
 * @array: a JSON array
517
 * @value: the integer value to add
518
 *
519
 * Conveniently adds the given integer value into an array.
520
 *
521
 * See also: [method@Json.Array.add_element], [method@Json.Node.set_int]
522
 *
523
 * Since: 0.8
524
 */
525
void
526
json_array_add_int_element (JsonArray *array,
527
                            gint64     value)
528
0
{
529
0
  g_return_if_fail (array != NULL);
530
531
0
  json_array_add_element (array, json_node_init_int (json_node_alloc (), value));
532
0
}
533
534
/**
535
 * json_array_add_double_element:
536
 * @array: a JSON array
537
 * @value: the floating point value to add
538
 *
539
 * Conveniently adds the given floating point value into an array.
540
 *
541
 * See also: [method@Json.Array.add_element], [method@Json.Node.set_double]
542
 *
543
 * Since: 0.8
544
 */
545
void
546
json_array_add_double_element (JsonArray *array,
547
                               gdouble    value)
548
0
{
549
0
  g_return_if_fail (array != NULL);
550
551
0
  json_array_add_element (array, json_node_init_double (json_node_alloc (), value));
552
0
}
553
554
/**
555
 * json_array_add_boolean_element:
556
 * @array: a JSON array
557
 * @value: the boolean value to add
558
 *
559
 * Conveniently adds the given boolean value into an array.
560
 *
561
 * See also: [method@Json.Array.add_element], [method@Json.Node.set_boolean]
562
 *
563
 * Since: 0.8
564
 */
565
void
566
json_array_add_boolean_element (JsonArray *array,
567
                                gboolean   value)
568
0
{
569
0
  g_return_if_fail (array != NULL);
570
571
0
  json_array_add_element (array, json_node_init_boolean (json_node_alloc (), value));
572
0
}
573
574
/**
575
 * json_array_add_string_element:
576
 * @array: a JSON array
577
 * @value: the string value to add
578
 *
579
 * Conveniently adds the given string value into an array.
580
 *
581
 * See also: [method@Json.Array.add_element], [method@Json.Node.set_string]
582
 *
583
 * Since: 0.8
584
 */
585
void
586
json_array_add_string_element (JsonArray   *array,
587
                               const gchar *value)
588
0
{
589
0
  JsonNode *node;
590
591
0
  g_return_if_fail (array != NULL);
592
593
0
  node = json_node_alloc ();
594
595
0
  if (value != NULL)
596
0
    json_node_init_string (node, value);
597
0
  else
598
0
    json_node_init_null (node);
599
600
0
  json_array_add_element (array, node);
601
0
}
602
603
/**
604
 * json_array_add_null_element:
605
 * @array: a JSON array
606
 *
607
 * Conveniently adds a `null` element into an array
608
 *
609
 * See also: [method@Json.Array.add_element], `JSON_NODE_NULL`
610
 *
611
 * Since: 0.8
612
 */
613
void
614
json_array_add_null_element (JsonArray *array)
615
0
{
616
0
  g_return_if_fail (array != NULL);
617
618
0
  json_array_add_element (array, json_node_init_null (json_node_alloc ()));
619
0
}
620
621
/**
622
 * json_array_add_array_element:
623
 * @array: a JSON array
624
 * @value: (nullable) (transfer full): the array to add
625
 *
626
 * Conveniently adds an array element into an array.
627
 *
628
 * If `value` is `NULL`, a `null` element will be added instead.
629
 *
630
 * See also: [method@Json.Array.add_element], [method@Json.Node.take_array]
631
 *
632
 * Since: 0.8
633
 */
634
void
635
json_array_add_array_element (JsonArray *array,
636
                              JsonArray *value)
637
0
{
638
0
  JsonNode *node;
639
640
0
  g_return_if_fail (array != NULL);
641
642
0
  node = json_node_alloc ();
643
644
0
  if (value != NULL)
645
0
    {
646
0
      json_node_init_array (node, value);
647
0
      json_array_unref (value);
648
0
    }
649
0
  else
650
0
    json_node_init_null (node);
651
652
0
  json_array_add_element (array, node);
653
0
}
654
655
/**
656
 * json_array_add_object_element:
657
 * @array: a JSON array
658
 * @value: (transfer full) (nullable): the object to add
659
 *
660
 * Conveniently adds an object into an array.
661
 *
662
 * If `value` is `NULL`, a `null` element will be added instead.
663
 *
664
 * See also: [method@Json.Array.add_element], [method@Json.Node.take_object]
665
 *
666
 * Since: 0.8
667
 */
668
void
669
json_array_add_object_element (JsonArray  *array,
670
                               JsonObject *value)
671
0
{
672
0
  JsonNode *node;
673
674
0
  g_return_if_fail (array != NULL);
675
676
0
  node = json_node_alloc ();
677
678
0
  if (value != NULL)
679
0
    {
680
0
      json_node_init_object (node, value);
681
0
      json_object_unref (value);
682
0
    }
683
0
  else
684
0
    json_node_init_null (node);
685
686
0
  json_array_add_element (array, node);
687
0
}
688
689
/**
690
 * json_array_remove_element:
691
 * @array: a JSON array
692
 * @index_: the position of the element to be removed
693
 *
694
 * Removes the element at the given position inside an array.
695
 *
696
 * This function will release the reference held on the element.
697
 */
698
void
699
json_array_remove_element (JsonArray *array,
700
                           guint      index_)
701
0
{
702
0
  g_return_if_fail (array != NULL);
703
0
  g_return_if_fail (index_ < array->elements->len);
704
705
0
  json_node_unref (g_ptr_array_remove_index (array->elements, index_));
706
0
}
707
708
/**
709
 * json_array_foreach_element:
710
 * @array: a JSON array
711
 * @func: (scope call) (closure data): the function to be called on each element
712
 * @data: data to be passed to the function
713
 *
714
 * Iterates over all elements of an array, and calls a function on
715
 * each one of them.
716
 *
717
 * It is safe to change the value of an element of the array while
718
 * iterating over it, but it is not safe to add or remove elements
719
 * from the array.
720
 *
721
 * Since: 0.8
722
 */
723
void
724
json_array_foreach_element (JsonArray        *array,
725
                            JsonArrayForeach  func,
726
                            gpointer          data)
727
0
{
728
0
  g_return_if_fail (array != NULL);
729
0
  g_return_if_fail (func != NULL);
730
731
0
  for (guint i = 0; i < array->elements->len; i++)
732
0
    {
733
0
      JsonNode *element_node;
734
735
0
      element_node = g_ptr_array_index (array->elements, i);
736
737
0
      (* func) (array, i, element_node, data);
738
0
    }
739
0
}
740
741
/**
742
 * json_array_hash:
743
 * @key: (type JsonArray) (not nullable): a JSON array to hash
744
 *
745
 * Calculates a hash value for the given `key`.
746
 *
747
 * The hash is calculated over the array and all its elements, recursively.
748
 *
749
 * If the array is immutable, this is a fast operation; otherwise, it scales
750
 * proportionally with the length of the array.
751
 *
752
 * Returns: hash value for the key
753
 * Since: 1.2
754
 */
755
guint
756
json_array_hash (gconstpointer key)
757
0
{
758
0
  JsonArray *array;  /* unowned */
759
0
  guint hash = 0;
760
0
  guint i;
761
762
0
  g_return_val_if_fail (key != NULL, 0);
763
764
0
  array = (JsonArray *) key;
765
766
  /* If the array is immutable, we can use the calculated hash. */
767
0
  if (array->immutable)
768
0
    return array->immutable_hash;
769
770
  /* Otherwise, calculate the hash. */
771
0
  for (i = 0; i < array->elements->len; i++)
772
0
    {
773
0
      JsonNode *node = g_ptr_array_index (array->elements, i);
774
0
      hash ^= (i ^ json_node_hash (node));
775
0
    }
776
777
0
  return hash;
778
0
}
779
780
/**
781
 * json_array_equal:
782
 * @a: (type JsonArray) (not nullable): a JSON array
783
 * @b: (type JsonArray) (not nullable): another JSON array
784
 *
785
 * Check whether two arrays are equal.
786
 *
787
 * Equality is defined as:
788
 *
789
 *  - the array have the same number of elements
790
 *  - the values of elements in corresponding positions are equal
791
 *
792
 * Returns: `TRUE` if the arrays are equal, and `FALSE` otherwise
793
 * Since: 1.2
794
 */
795
gboolean
796
json_array_equal (gconstpointer a,
797
                  gconstpointer b)
798
0
{
799
0
  JsonArray *array_a, *array_b;  /* unowned */
800
0
  guint length_a, length_b, i;
801
802
0
  g_return_val_if_fail (a != NULL, FALSE);
803
0
  g_return_val_if_fail (b != NULL, FALSE);
804
805
0
  array_a = (JsonArray *) a;
806
0
  array_b = (JsonArray *) b;
807
808
  /* Identity comparison. */
809
0
  if (array_a == array_b)
810
0
    return TRUE;
811
812
  /* Check lengths. */
813
0
  length_a = json_array_get_length (array_a);
814
0
  length_b = json_array_get_length (array_b);
815
816
0
  if (length_a != length_b)
817
0
    return FALSE;
818
819
  /* Check elements. */
820
0
  for (i = 0; i < length_a; i++)
821
0
    {
822
0
      JsonNode *child_a, *child_b;  /* unowned */
823
824
0
      child_a = json_array_get_element (array_a, i);
825
0
      child_b = json_array_get_element (array_b, i);
826
827
0
      if (!json_node_equal (child_a, child_b))
828
0
        return FALSE;
829
0
    }
830
831
0
  return TRUE;
832
0
}