Duplication */
| 2556 | |
| 2557 | /* Duplication */ |
| 2558 | CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse) |
| 2559 | { |
| 2560 | cJSON *newitem = NULL; |
| 2561 | cJSON *child = NULL; |
| 2562 | cJSON *next = NULL; |
| 2563 | cJSON *newchild = NULL; |
| 2564 | |
| 2565 | /* Bail on bad ptr */ |
| 2566 | if (!item) |
| 2567 | { |
| 2568 | goto fail; |
| 2569 | } |
| 2570 | /* Create new item */ |
| 2571 | newitem = cJSON_New_Item(&global_hooks); |
| 2572 | if (!newitem) |
| 2573 | { |
| 2574 | goto fail; |
| 2575 | } |
| 2576 | /* Copy over all vars */ |
| 2577 | newitem->type = item->type & (~cJSON_IsReference); |
| 2578 | newitem->valueint = item->valueint; |
| 2579 | newitem->valuedouble = item->valuedouble; |
| 2580 | if (item->valuestring) |
| 2581 | { |
| 2582 | newitem->valuestring = (char*)cJSON_strdup((unsigned char*)item->valuestring, &global_hooks); |
| 2583 | if (!newitem->valuestring) |
| 2584 | { |
| 2585 | goto fail; |
| 2586 | } |
| 2587 | } |
| 2588 | if (item->string) |
| 2589 | { |
| 2590 | newitem->string = (item->type&cJSON_StringIsConst) ? item->string : (char*)cJSON_strdup((unsigned char*)item->string, &global_hooks); |
| 2591 | if (!newitem->string) |
| 2592 | { |
| 2593 | goto fail; |
| 2594 | } |
| 2595 | } |
| 2596 | /* If non-recursive, then we're done! */ |
| 2597 | if (!recurse) |
| 2598 | { |
| 2599 | return newitem; |
| 2600 | } |
| 2601 | /* Walk the ->next chain for the child. */ |
| 2602 | child = item->child; |
| 2603 | while (child != NULL) |
| 2604 | { |
| 2605 | newchild = cJSON_Duplicate(child, true); /* Duplicate (with recurse) each item in the ->next chain */ |
| 2606 | if (!newchild) |
| 2607 | { |
| 2608 | goto fail; |
| 2609 | } |
| 2610 | if (next != NULL) |
| 2611 | { |
| 2612 | /* If newitem->child already set, then crosswire ->prev and ->next and move on */ |
| 2613 | next->next = newchild; |
| 2614 | newchild->prev = next; |
| 2615 | next = newchild; |
nothing calls this directly
no test coverage detected