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