Duplication */
| 2398 | |
| 2399 | /* Duplication */ |
| 2400 | cJSON *cJSON_Duplicate(const cJSON *item, cjbool recurse) |
| 2401 | { |
| 2402 | cJSON *newitem = NULL; |
| 2403 | cJSON *child = NULL; |
| 2404 | cJSON *next = NULL; |
| 2405 | cJSON *newchild = NULL; |
| 2406 | |
| 2407 | /* Bail on bad ptr */ |
| 2408 | if (!item) |
| 2409 | { |
| 2410 | goto fail; |
| 2411 | } |
| 2412 | /* Create new item */ |
| 2413 | newitem = cJSON_New_Item(); |
| 2414 | if (!newitem) |
| 2415 | { |
| 2416 | goto fail; |
| 2417 | } |
| 2418 | /* Copy over all vars */ |
| 2419 | newitem->type = item->type & (~cJSON_IsReference); |
| 2420 | newitem->valueint = item->valueint; |
| 2421 | newitem->valuedouble = item->valuedouble; |
| 2422 | if (item->valuestring) |
| 2423 | { |
| 2424 | newitem->valuestring = (char*)cJSON_strdup((unsigned char*)item->valuestring); |
| 2425 | if (!newitem->valuestring) |
| 2426 | { |
| 2427 | goto fail; |
| 2428 | } |
| 2429 | } |
| 2430 | if (item->string) |
| 2431 | { |
| 2432 | newitem->string = (item->type&cJSON_StringIsConst) ? item->string : (char*)cJSON_strdup((unsigned char*)item->string); |
| 2433 | if (!newitem->string) |
| 2434 | { |
| 2435 | goto fail; |
| 2436 | } |
| 2437 | } |
| 2438 | /* If non-recursive, then we're done! */ |
| 2439 | if (!recurse) |
| 2440 | { |
| 2441 | return newitem; |
| 2442 | } |
| 2443 | /* Walk the ->next chain for the child. */ |
| 2444 | child = item->child; |
| 2445 | while (child != NULL) |
| 2446 | { |
| 2447 | newchild = cJSON_Duplicate(child, true); /* Duplicate (with recurse) each item in the ->next chain */ |
| 2448 | if (!newchild) |
| 2449 | { |
| 2450 | goto fail; |
| 2451 | } |
| 2452 | if (next != NULL) |
| 2453 | { |
| 2454 | /* If newitem->child already set, then crosswire ->prev and ->next and move on */ |
| 2455 | next->next = newchild; |
| 2456 | newchild->prev = next; |
| 2457 | next = newchild; |
no test coverage detected