The function is an iterative DFS, walks the entire json and sorts the key-value iteratively. Arrays are only traversed, only objects are sorted. */
| 352 | objects are sorted. |
| 353 | */ |
| 354 | static void json_normalize_sort(struct json_norm_value *root) |
| 355 | { |
| 356 | DYNAMIC_ARRAY stack; |
| 357 | struct json_norm_frame frame, child; |
| 358 | struct json_norm_value *val; |
| 359 | size_t i; |
| 360 | |
| 361 | if (json_norm_init_dynamic_array(sizeof(struct json_norm_frame), &stack)) |
| 362 | return; |
| 363 | |
| 364 | frame.val= root; |
| 365 | frame.index= 0; |
| 366 | frame.visited= UNPROCESSED; |
| 367 | push_dynamic(&stack, &frame); |
| 368 | |
| 369 | do |
| 370 | { |
| 371 | frame= *(struct json_norm_frame *)pop_dynamic(&stack); |
| 372 | val= frame.val; |
| 373 | |
| 374 | if (!val) |
| 375 | continue; |
| 376 | |
| 377 | if (frame.visited > UNPROCESSED) |
| 378 | { |
| 379 | if (val->type == JSON_VALUE_OBJECT) |
| 380 | { |
| 381 | my_qsort(dynamic_element(&val->value.object.kv_pairs, 0, |
| 382 | struct json_norm_kv*), val->value.object.kv_pairs.elements, |
| 383 | sizeof(struct json_norm_kv), json_norm_kv_comp); |
| 384 | } |
| 385 | continue; |
| 386 | } |
| 387 | |
| 388 | frame.visited= CLOSE_NON_SCALAR; |
| 389 | push_dynamic(&stack, &frame); |
| 390 | |
| 391 | switch (val->type) |
| 392 | { |
| 393 | case JSON_VALUE_OBJECT: |
| 394 | { |
| 395 | DYNAMIC_ARRAY *pairs= &val->value.object.kv_pairs; |
| 396 | for (i= pairs->elements; i > 0; i--) |
| 397 | { |
| 398 | struct json_norm_kv *kv= |
| 399 | dynamic_element(pairs, i-1, struct json_norm_kv*); |
| 400 | child.val= &kv->value; |
| 401 | child.index= 0; |
| 402 | child.visited= UNPROCESSED; |
| 403 | push_dynamic(&stack, &child); |
| 404 | } |
| 405 | break; |
| 406 | } |
| 407 | |
| 408 | case JSON_VALUE_ARRAY: |
| 409 | { |
| 410 | DYNAMIC_ARRAY *values= &val->value.array.values; |
| 411 | for (i= values->elements; i > 0; i--) |
no test coverage detected