19750e409Sopenharmony_ci/*
29750e409Sopenharmony_ci  Copyright (c) 2009-2017 Dave Gamble and cJSON contributors
39750e409Sopenharmony_ci
49750e409Sopenharmony_ci  Permission is hereby granted, free of charge, to any person obtaining a copy
59750e409Sopenharmony_ci  of this software and associated documentation files (the "Software"), to deal
69750e409Sopenharmony_ci  in the Software without restriction, including without limitation the rights
79750e409Sopenharmony_ci  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
89750e409Sopenharmony_ci  copies of the Software, and to permit persons to whom the Software is
99750e409Sopenharmony_ci  furnished to do so, subject to the following conditions:
109750e409Sopenharmony_ci
119750e409Sopenharmony_ci  The above copyright notice and this permission notice shall be included in
129750e409Sopenharmony_ci  all copies or substantial portions of the Software.
139750e409Sopenharmony_ci
149750e409Sopenharmony_ci  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
159750e409Sopenharmony_ci  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
169750e409Sopenharmony_ci  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
179750e409Sopenharmony_ci  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
189750e409Sopenharmony_ci  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
199750e409Sopenharmony_ci  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
209750e409Sopenharmony_ci  THE SOFTWARE.
219750e409Sopenharmony_ci*/
229750e409Sopenharmony_ci
239750e409Sopenharmony_ci/* cJSON */
249750e409Sopenharmony_ci/* JSON parser in C. */
259750e409Sopenharmony_ci
269750e409Sopenharmony_ci/* disable warnings about old C89 functions in MSVC */
279750e409Sopenharmony_ci#if !defined(_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER)
289750e409Sopenharmony_ci#define _CRT_SECURE_NO_DEPRECATE
299750e409Sopenharmony_ci#endif
309750e409Sopenharmony_ci
319750e409Sopenharmony_ci#ifdef __GNUC__
329750e409Sopenharmony_ci#pragma GCC visibility push(default)
339750e409Sopenharmony_ci#endif
349750e409Sopenharmony_ci#if defined(_MSC_VER)
359750e409Sopenharmony_ci#pragma warning (push)
369750e409Sopenharmony_ci/* disable warning about single line comments in system headers */
379750e409Sopenharmony_ci#pragma warning (disable : 4001)
389750e409Sopenharmony_ci#endif
399750e409Sopenharmony_ci
409750e409Sopenharmony_ci#include <string.h>
419750e409Sopenharmony_ci#include <stdio.h>
429750e409Sopenharmony_ci#include <math.h>
439750e409Sopenharmony_ci#include <stdlib.h>
449750e409Sopenharmony_ci#include <limits.h>
459750e409Sopenharmony_ci#include <ctype.h>
469750e409Sopenharmony_ci#include <float.h>
479750e409Sopenharmony_ci
489750e409Sopenharmony_ci#ifdef ENABLE_LOCALES
499750e409Sopenharmony_ci#include <locale.h>
509750e409Sopenharmony_ci#endif
519750e409Sopenharmony_ci
529750e409Sopenharmony_ci#if defined(_MSC_VER)
539750e409Sopenharmony_ci#pragma warning (pop)
549750e409Sopenharmony_ci#endif
559750e409Sopenharmony_ci#ifdef __GNUC__
569750e409Sopenharmony_ci#pragma GCC visibility pop
579750e409Sopenharmony_ci#endif
589750e409Sopenharmony_ci
599750e409Sopenharmony_ci#include "cJSON.h"
609750e409Sopenharmony_ci
619750e409Sopenharmony_ci/* define our own boolean type */
629750e409Sopenharmony_ci#ifdef true
639750e409Sopenharmony_ci#undef true
649750e409Sopenharmony_ci#endif
659750e409Sopenharmony_ci#define true ((cJSON_bool)1)
669750e409Sopenharmony_ci
679750e409Sopenharmony_ci#ifdef false
689750e409Sopenharmony_ci#undef false
699750e409Sopenharmony_ci#endif
709750e409Sopenharmony_ci#define false ((cJSON_bool)0)
719750e409Sopenharmony_ci
729750e409Sopenharmony_ci/* define isnan and isinf for ANSI C, if in C99 or above, isnan and isinf has been defined in math.h */
739750e409Sopenharmony_ci#ifndef isinf
749750e409Sopenharmony_ci#define isinf(d) (isnan((d - d)) && !isnan(d))
759750e409Sopenharmony_ci#endif
769750e409Sopenharmony_ci#ifndef isnan
779750e409Sopenharmony_ci#define isnan(d) (d != d)
789750e409Sopenharmony_ci#endif
799750e409Sopenharmony_ci
809750e409Sopenharmony_ci#ifndef NAN
819750e409Sopenharmony_ci#ifdef _WIN32
829750e409Sopenharmony_ci#define NAN sqrt(-1.0)
839750e409Sopenharmony_ci#else
849750e409Sopenharmony_ci#define NAN 0.0/0.0
859750e409Sopenharmony_ci#endif
869750e409Sopenharmony_ci#endif
879750e409Sopenharmony_ci
889750e409Sopenharmony_citypedef struct {
899750e409Sopenharmony_ci    const unsigned char *json;
909750e409Sopenharmony_ci    size_t position;
919750e409Sopenharmony_ci} error;
929750e409Sopenharmony_cistatic error global_error = { NULL, 0 };
939750e409Sopenharmony_ci
949750e409Sopenharmony_ciCJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void)
959750e409Sopenharmony_ci{
969750e409Sopenharmony_ci    return (const char*) (global_error.json + global_error.position);
979750e409Sopenharmony_ci}
989750e409Sopenharmony_ci
999750e409Sopenharmony_ciCJSON_PUBLIC(char *) cJSON_GetStringValue(const cJSON * const item)
1009750e409Sopenharmony_ci{
1019750e409Sopenharmony_ci    if (!cJSON_IsString(item))
1029750e409Sopenharmony_ci    {
1039750e409Sopenharmony_ci        return NULL;
1049750e409Sopenharmony_ci    }
1059750e409Sopenharmony_ci
1069750e409Sopenharmony_ci    return item->valuestring;
1079750e409Sopenharmony_ci}
1089750e409Sopenharmony_ci
1099750e409Sopenharmony_ci#ifdef __CJSON_USE_INT64
1109750e409Sopenharmony_ciCJSON_PUBLIC(long long *) cJSON_GetInt64NumberValue(cJSON * const item)
1119750e409Sopenharmony_ci{
1129750e409Sopenharmony_ci    if (!cJSON_IsInt64Number(item))
1139750e409Sopenharmony_ci    {
1149750e409Sopenharmony_ci        return NULL;
1159750e409Sopenharmony_ci    }
1169750e409Sopenharmony_ci
1179750e409Sopenharmony_ci    return &(item->valueint);
1189750e409Sopenharmony_ci}
1199750e409Sopenharmony_ci#endif
1209750e409Sopenharmony_ci
1219750e409Sopenharmony_ciCJSON_PUBLIC(double) cJSON_GetNumberValue(const cJSON * const item)
1229750e409Sopenharmony_ci{
1239750e409Sopenharmony_ci    if (!cJSON_IsNumber(item))
1249750e409Sopenharmony_ci    {
1259750e409Sopenharmony_ci        return (double) NAN;
1269750e409Sopenharmony_ci    }
1279750e409Sopenharmony_ci
1289750e409Sopenharmony_ci    return item->valuedouble;
1299750e409Sopenharmony_ci}
1309750e409Sopenharmony_ci
1319750e409Sopenharmony_ci/* This is a safeguard to prevent copy-pasters from using incompatible C and header files */
1329750e409Sopenharmony_ci#if (CJSON_VERSION_MAJOR != 1) || (CJSON_VERSION_MINOR != 7) || (CJSON_VERSION_PATCH != 17)
1339750e409Sopenharmony_ci    #error cJSON.h and cJSON.c have different versions. Make sure that both have the same.
1349750e409Sopenharmony_ci#endif
1359750e409Sopenharmony_ci
1369750e409Sopenharmony_ciCJSON_PUBLIC(const char*) cJSON_Version(void)
1379750e409Sopenharmony_ci{
1389750e409Sopenharmony_ci    static char version[15];
1399750e409Sopenharmony_ci    sprintf(version, "%i.%i.%i", CJSON_VERSION_MAJOR, CJSON_VERSION_MINOR, CJSON_VERSION_PATCH);
1409750e409Sopenharmony_ci
1419750e409Sopenharmony_ci    return version;
1429750e409Sopenharmony_ci}
1439750e409Sopenharmony_ci
1449750e409Sopenharmony_ci/* Case insensitive string comparison, doesn't consider two NULL pointers equal though */
1459750e409Sopenharmony_cistatic int case_insensitive_strcmp(const unsigned char *string1, const unsigned char *string2)
1469750e409Sopenharmony_ci{
1479750e409Sopenharmony_ci    if ((string1 == NULL) || (string2 == NULL))
1489750e409Sopenharmony_ci    {
1499750e409Sopenharmony_ci        return 1;
1509750e409Sopenharmony_ci    }
1519750e409Sopenharmony_ci
1529750e409Sopenharmony_ci    if (string1 == string2)
1539750e409Sopenharmony_ci    {
1549750e409Sopenharmony_ci        return 0;
1559750e409Sopenharmony_ci    }
1569750e409Sopenharmony_ci
1579750e409Sopenharmony_ci    for(; tolower(*string1) == tolower(*string2); (void)string1++, string2++)
1589750e409Sopenharmony_ci    {
1599750e409Sopenharmony_ci        if (*string1 == '\0')
1609750e409Sopenharmony_ci        {
1619750e409Sopenharmony_ci            return 0;
1629750e409Sopenharmony_ci        }
1639750e409Sopenharmony_ci    }
1649750e409Sopenharmony_ci
1659750e409Sopenharmony_ci    return tolower(*string1) - tolower(*string2);
1669750e409Sopenharmony_ci}
1679750e409Sopenharmony_ci
1689750e409Sopenharmony_citypedef struct internal_hooks
1699750e409Sopenharmony_ci{
1709750e409Sopenharmony_ci    void *(CJSON_CDECL *allocate)(size_t size);
1719750e409Sopenharmony_ci    void (CJSON_CDECL *deallocate)(void *pointer);
1729750e409Sopenharmony_ci    void *(CJSON_CDECL *reallocate)(void *pointer, size_t size);
1739750e409Sopenharmony_ci} internal_hooks;
1749750e409Sopenharmony_ci
1759750e409Sopenharmony_ci#if defined(_MSC_VER)
1769750e409Sopenharmony_ci/* work around MSVC error C2322: '...' address of dllimport '...' is not static */
1779750e409Sopenharmony_cistatic void * CJSON_CDECL internal_malloc(size_t size)
1789750e409Sopenharmony_ci{
1799750e409Sopenharmony_ci    return malloc(size);
1809750e409Sopenharmony_ci}
1819750e409Sopenharmony_cistatic void CJSON_CDECL internal_free(void *pointer)
1829750e409Sopenharmony_ci{
1839750e409Sopenharmony_ci    free(pointer);
1849750e409Sopenharmony_ci}
1859750e409Sopenharmony_cistatic void * CJSON_CDECL internal_realloc(void *pointer, size_t size)
1869750e409Sopenharmony_ci{
1879750e409Sopenharmony_ci    return realloc(pointer, size);
1889750e409Sopenharmony_ci}
1899750e409Sopenharmony_ci#else
1909750e409Sopenharmony_ci#define internal_malloc malloc
1919750e409Sopenharmony_ci#define internal_free free
1929750e409Sopenharmony_ci#define internal_realloc realloc
1939750e409Sopenharmony_ci#endif
1949750e409Sopenharmony_ci
1959750e409Sopenharmony_ci/* strlen of character literals resolved at compile time */
1969750e409Sopenharmony_ci#define static_strlen(string_literal) (sizeof(string_literal) - sizeof(""))
1979750e409Sopenharmony_ci
1989750e409Sopenharmony_cistatic internal_hooks global_hooks = { internal_malloc, internal_free, internal_realloc };
1999750e409Sopenharmony_ci
2009750e409Sopenharmony_cistatic unsigned char* cJSON_strdup(const unsigned char* string, const internal_hooks * const hooks)
2019750e409Sopenharmony_ci{
2029750e409Sopenharmony_ci    size_t length = 0;
2039750e409Sopenharmony_ci    unsigned char *copy = NULL;
2049750e409Sopenharmony_ci
2059750e409Sopenharmony_ci    if (string == NULL)
2069750e409Sopenharmony_ci    {
2079750e409Sopenharmony_ci        return NULL;
2089750e409Sopenharmony_ci    }
2099750e409Sopenharmony_ci
2109750e409Sopenharmony_ci    length = strlen((const char*)string) + sizeof("");
2119750e409Sopenharmony_ci    copy = (unsigned char*)hooks->allocate(length);
2129750e409Sopenharmony_ci    if (copy == NULL)
2139750e409Sopenharmony_ci    {
2149750e409Sopenharmony_ci        return NULL;
2159750e409Sopenharmony_ci    }
2169750e409Sopenharmony_ci    memcpy(copy, string, length);
2179750e409Sopenharmony_ci
2189750e409Sopenharmony_ci    return copy;
2199750e409Sopenharmony_ci}
2209750e409Sopenharmony_ci
2219750e409Sopenharmony_ciCJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks* hooks)
2229750e409Sopenharmony_ci{
2239750e409Sopenharmony_ci    if (hooks == NULL)
2249750e409Sopenharmony_ci    {
2259750e409Sopenharmony_ci        /* Reset hooks */
2269750e409Sopenharmony_ci        global_hooks.allocate = malloc;
2279750e409Sopenharmony_ci        global_hooks.deallocate = free;
2289750e409Sopenharmony_ci        global_hooks.reallocate = realloc;
2299750e409Sopenharmony_ci        return;
2309750e409Sopenharmony_ci    }
2319750e409Sopenharmony_ci
2329750e409Sopenharmony_ci    global_hooks.allocate = malloc;
2339750e409Sopenharmony_ci    if (hooks->malloc_fn != NULL)
2349750e409Sopenharmony_ci    {
2359750e409Sopenharmony_ci        global_hooks.allocate = hooks->malloc_fn;
2369750e409Sopenharmony_ci    }
2379750e409Sopenharmony_ci
2389750e409Sopenharmony_ci    global_hooks.deallocate = free;
2399750e409Sopenharmony_ci    if (hooks->free_fn != NULL)
2409750e409Sopenharmony_ci    {
2419750e409Sopenharmony_ci        global_hooks.deallocate = hooks->free_fn;
2429750e409Sopenharmony_ci    }
2439750e409Sopenharmony_ci
2449750e409Sopenharmony_ci    /* use realloc only if both free and malloc are used */
2459750e409Sopenharmony_ci    global_hooks.reallocate = NULL;
2469750e409Sopenharmony_ci    if ((global_hooks.allocate == malloc) && (global_hooks.deallocate == free))
2479750e409Sopenharmony_ci    {
2489750e409Sopenharmony_ci        global_hooks.reallocate = realloc;
2499750e409Sopenharmony_ci    }
2509750e409Sopenharmony_ci}
2519750e409Sopenharmony_ci
2529750e409Sopenharmony_ci/* Internal constructor. */
2539750e409Sopenharmony_cistatic cJSON *cJSON_New_Item(const internal_hooks * const hooks)
2549750e409Sopenharmony_ci{
2559750e409Sopenharmony_ci    cJSON* node = (cJSON*)hooks->allocate(sizeof(cJSON));
2569750e409Sopenharmony_ci    if (node)
2579750e409Sopenharmony_ci    {
2589750e409Sopenharmony_ci        memset(node, '\0', sizeof(cJSON));
2599750e409Sopenharmony_ci    }
2609750e409Sopenharmony_ci
2619750e409Sopenharmony_ci    return node;
2629750e409Sopenharmony_ci}
2639750e409Sopenharmony_ci
2649750e409Sopenharmony_ci/* Delete a cJSON structure. */
2659750e409Sopenharmony_ciCJSON_PUBLIC(void) cJSON_Delete(cJSON *item)
2669750e409Sopenharmony_ci{
2679750e409Sopenharmony_ci    cJSON *next = NULL;
2689750e409Sopenharmony_ci    while (item != NULL)
2699750e409Sopenharmony_ci    {
2709750e409Sopenharmony_ci        next = item->next;
2719750e409Sopenharmony_ci        if (!(item->type & cJSON_IsReference) && (item->child != NULL))
2729750e409Sopenharmony_ci        {
2739750e409Sopenharmony_ci            cJSON_Delete(item->child);
2749750e409Sopenharmony_ci        }
2759750e409Sopenharmony_ci        if (!(item->type & cJSON_IsReference) && (item->valuestring != NULL))
2769750e409Sopenharmony_ci        {
2779750e409Sopenharmony_ci            global_hooks.deallocate(item->valuestring);
2789750e409Sopenharmony_ci            item->valuestring = NULL;
2799750e409Sopenharmony_ci        }
2809750e409Sopenharmony_ci        if (!(item->type & cJSON_StringIsConst) && (item->string != NULL))
2819750e409Sopenharmony_ci        {
2829750e409Sopenharmony_ci            global_hooks.deallocate(item->string);
2839750e409Sopenharmony_ci            item->string = NULL;
2849750e409Sopenharmony_ci        }
2859750e409Sopenharmony_ci        if (next == item)
2869750e409Sopenharmony_ci        {
2879750e409Sopenharmony_ci            break;
2889750e409Sopenharmony_ci        }
2899750e409Sopenharmony_ci        global_hooks.deallocate(item);
2909750e409Sopenharmony_ci        item = next;
2919750e409Sopenharmony_ci    }
2929750e409Sopenharmony_ci}
2939750e409Sopenharmony_ci
2949750e409Sopenharmony_ci/* get the decimal point character of the current locale */
2959750e409Sopenharmony_cistatic unsigned char get_decimal_point(void)
2969750e409Sopenharmony_ci{
2979750e409Sopenharmony_ci#ifdef ENABLE_LOCALES
2989750e409Sopenharmony_ci    struct lconv *lconv = localeconv();
2999750e409Sopenharmony_ci    return (unsigned char) lconv->decimal_point[0];
3009750e409Sopenharmony_ci#else
3019750e409Sopenharmony_ci    return '.';
3029750e409Sopenharmony_ci#endif
3039750e409Sopenharmony_ci}
3049750e409Sopenharmony_ci
3059750e409Sopenharmony_citypedef struct
3069750e409Sopenharmony_ci{
3079750e409Sopenharmony_ci    const unsigned char *content;
3089750e409Sopenharmony_ci    size_t length;
3099750e409Sopenharmony_ci    size_t offset;
3109750e409Sopenharmony_ci    size_t depth; /* How deeply nested (in arrays/objects) is the input at the current offset. */
3119750e409Sopenharmony_ci    internal_hooks hooks;
3129750e409Sopenharmony_ci} parse_buffer;
3139750e409Sopenharmony_ci
3149750e409Sopenharmony_ci/* check if the given size is left to read in a given parse buffer (starting with 1) */
3159750e409Sopenharmony_ci#define can_read(buffer, size) ((buffer != NULL) && (((buffer)->offset + size) <= (buffer)->length))
3169750e409Sopenharmony_ci/* check if the buffer can be accessed at the given index (starting with 0) */
3179750e409Sopenharmony_ci#define can_access_at_index(buffer, index) ((buffer != NULL) && (((buffer)->offset + index) < (buffer)->length))
3189750e409Sopenharmony_ci#define cannot_access_at_index(buffer, index) (!can_access_at_index(buffer, index))
3199750e409Sopenharmony_ci/* get a pointer to the buffer at the position */
3209750e409Sopenharmony_ci#define buffer_at_offset(buffer) ((buffer)->content + (buffer)->offset)
3219750e409Sopenharmony_ci
3229750e409Sopenharmony_ci#ifdef __CJSON_USE_INT64
3239750e409Sopenharmony_ci/* Parse the input text to generate a number, and populate the result into item. */
3249750e409Sopenharmony_cistatic cJSON_bool parse_number(cJSON * const item, parse_buffer * const input_buffer)
3259750e409Sopenharmony_ci{
3269750e409Sopenharmony_ci    double number = 0;
3279750e409Sopenharmony_ci    long long integer = 0;
3289750e409Sopenharmony_ci    unsigned char *after_end = NULL;
3299750e409Sopenharmony_ci    unsigned char number_c_string[64];
3309750e409Sopenharmony_ci    unsigned char decimal_point = get_decimal_point();
3319750e409Sopenharmony_ci    size_t i = 0;
3329750e409Sopenharmony_ci    cJSON_bool is_integer = true;
3339750e409Sopenharmony_ci
3349750e409Sopenharmony_ci    if ((input_buffer == NULL) || (input_buffer->content == NULL))
3359750e409Sopenharmony_ci    {
3369750e409Sopenharmony_ci        return false;
3379750e409Sopenharmony_ci    }
3389750e409Sopenharmony_ci
3399750e409Sopenharmony_ci    /* copy the number into a temporary buffer and replace '.' with the decimal point
3409750e409Sopenharmony_ci     * of the current locale (for strtod)
3419750e409Sopenharmony_ci     * This also takes care of '\0' not necessarily being available for marking the end of the input */
3429750e409Sopenharmony_ci    for (i = 0; (i < (sizeof(number_c_string) - 1)) && can_access_at_index(input_buffer, i); i++)
3439750e409Sopenharmony_ci    {
3449750e409Sopenharmony_ci        switch (buffer_at_offset(input_buffer)[i])
3459750e409Sopenharmony_ci        {
3469750e409Sopenharmony_ci            case '0':
3479750e409Sopenharmony_ci            case '1':
3489750e409Sopenharmony_ci            case '2':
3499750e409Sopenharmony_ci            case '3':
3509750e409Sopenharmony_ci            case '4':
3519750e409Sopenharmony_ci            case '5':
3529750e409Sopenharmony_ci            case '6':
3539750e409Sopenharmony_ci            case '7':
3549750e409Sopenharmony_ci            case '8':
3559750e409Sopenharmony_ci            case '9':
3569750e409Sopenharmony_ci            case '+':
3579750e409Sopenharmony_ci            case '-':
3589750e409Sopenharmony_ci                number_c_string[i] = buffer_at_offset(input_buffer)[i];
3599750e409Sopenharmony_ci                break;
3609750e409Sopenharmony_ci            case 'e':
3619750e409Sopenharmony_ci            case 'E':
3629750e409Sopenharmony_ci                number_c_string[i] = buffer_at_offset(input_buffer)[i];
3639750e409Sopenharmony_ci                is_integer = false;
3649750e409Sopenharmony_ci                break;
3659750e409Sopenharmony_ci
3669750e409Sopenharmony_ci            case '.':
3679750e409Sopenharmony_ci                number_c_string[i] = decimal_point;
3689750e409Sopenharmony_ci                is_integer = false;
3699750e409Sopenharmony_ci                break;
3709750e409Sopenharmony_ci
3719750e409Sopenharmony_ci            default:
3729750e409Sopenharmony_ci                goto loop_end;
3739750e409Sopenharmony_ci        }
3749750e409Sopenharmony_ci    }
3759750e409Sopenharmony_ciloop_end:
3769750e409Sopenharmony_ci    number_c_string[i] = '\0';
3779750e409Sopenharmony_ci
3789750e409Sopenharmony_ci    /* use guard clause to process the int64 case first */
3799750e409Sopenharmony_ci    if (is_integer)
3809750e409Sopenharmony_ci    {
3819750e409Sopenharmony_ci        /* for int64 values, set cJSON_IsInt64 */
3829750e409Sopenharmony_ci        item->type = cJSON_Number | cJSON_IsInt64;
3839750e409Sopenharmony_ci        integer = strtoll((const char*)number_c_string, (char**)&after_end, 10);
3849750e409Sopenharmony_ci        if (number_c_string == after_end)
3859750e409Sopenharmony_ci        {
3869750e409Sopenharmony_ci            return false; /* parse_error */
3879750e409Sopenharmony_ci        }
3889750e409Sopenharmony_ci        item->valueint = integer;
3899750e409Sopenharmony_ci        item->valuedouble = (double)integer;
3909750e409Sopenharmony_ci        goto parse_end;
3919750e409Sopenharmony_ci    }
3929750e409Sopenharmony_ci
3939750e409Sopenharmony_ci    number = strtod((const char*)number_c_string, (char**)&after_end);
3949750e409Sopenharmony_ci    if (number_c_string == after_end)
3959750e409Sopenharmony_ci    {
3969750e409Sopenharmony_ci        return false; /* parse_error */
3979750e409Sopenharmony_ci    }
3989750e409Sopenharmony_ci
3999750e409Sopenharmony_ci    item->valuedouble = number;
4009750e409Sopenharmony_ci
4019750e409Sopenharmony_ci    /* use saturation in case of overflow */
4029750e409Sopenharmony_ci    if (number >= (double)LLONG_MAX)
4039750e409Sopenharmony_ci    {
4049750e409Sopenharmony_ci        item->valueint = LLONG_MAX;
4059750e409Sopenharmony_ci    }
4069750e409Sopenharmony_ci    else if (number <= (double)LLONG_MIN)
4079750e409Sopenharmony_ci    {
4089750e409Sopenharmony_ci        item->valueint = LLONG_MIN;
4099750e409Sopenharmony_ci    }
4109750e409Sopenharmony_ci    else
4119750e409Sopenharmony_ci    {
4129750e409Sopenharmony_ci        item->valueint = (long long)number;
4139750e409Sopenharmony_ci    }
4149750e409Sopenharmony_ci
4159750e409Sopenharmony_ci    item->type = cJSON_Number;
4169750e409Sopenharmony_ci
4179750e409Sopenharmony_ciparse_end:
4189750e409Sopenharmony_ci    input_buffer->offset += (size_t)(after_end - number_c_string);
4199750e409Sopenharmony_ci    return true;
4209750e409Sopenharmony_ci}
4219750e409Sopenharmony_ci#else
4229750e409Sopenharmony_ci/* Parse the input text to generate a number, and populate the result into item. */
4239750e409Sopenharmony_cistatic cJSON_bool parse_number(cJSON * const item, parse_buffer * const input_buffer)
4249750e409Sopenharmony_ci{
4259750e409Sopenharmony_ci    double number = 0;
4269750e409Sopenharmony_ci    unsigned char *after_end = NULL;
4279750e409Sopenharmony_ci    unsigned char number_c_string[64];
4289750e409Sopenharmony_ci    unsigned char decimal_point = get_decimal_point();
4299750e409Sopenharmony_ci    size_t i = 0;
4309750e409Sopenharmony_ci
4319750e409Sopenharmony_ci    if ((input_buffer == NULL) || (input_buffer->content == NULL))
4329750e409Sopenharmony_ci    {
4339750e409Sopenharmony_ci        return false;
4349750e409Sopenharmony_ci    }
4359750e409Sopenharmony_ci
4369750e409Sopenharmony_ci    /* copy the number into a temporary buffer and replace '.' with the decimal point
4379750e409Sopenharmony_ci     * of the current locale (for strtod)
4389750e409Sopenharmony_ci     * This also takes care of '\0' not necessarily being available for marking the end of the input */
4399750e409Sopenharmony_ci    for (i = 0; (i < (sizeof(number_c_string) - 1)) && can_access_at_index(input_buffer, i); i++)
4409750e409Sopenharmony_ci    {
4419750e409Sopenharmony_ci        switch (buffer_at_offset(input_buffer)[i])
4429750e409Sopenharmony_ci        {
4439750e409Sopenharmony_ci            case '0':
4449750e409Sopenharmony_ci            case '1':
4459750e409Sopenharmony_ci            case '2':
4469750e409Sopenharmony_ci            case '3':
4479750e409Sopenharmony_ci            case '4':
4489750e409Sopenharmony_ci            case '5':
4499750e409Sopenharmony_ci            case '6':
4509750e409Sopenharmony_ci            case '7':
4519750e409Sopenharmony_ci            case '8':
4529750e409Sopenharmony_ci            case '9':
4539750e409Sopenharmony_ci            case '+':
4549750e409Sopenharmony_ci            case '-':
4559750e409Sopenharmony_ci            case 'e':
4569750e409Sopenharmony_ci            case 'E':
4579750e409Sopenharmony_ci                number_c_string[i] = buffer_at_offset(input_buffer)[i];
4589750e409Sopenharmony_ci                break;
4599750e409Sopenharmony_ci
4609750e409Sopenharmony_ci            case '.':
4619750e409Sopenharmony_ci                number_c_string[i] = decimal_point;
4629750e409Sopenharmony_ci                break;
4639750e409Sopenharmony_ci
4649750e409Sopenharmony_ci            default:
4659750e409Sopenharmony_ci                goto loop_end;
4669750e409Sopenharmony_ci        }
4679750e409Sopenharmony_ci    }
4689750e409Sopenharmony_ciloop_end:
4699750e409Sopenharmony_ci    number_c_string[i] = '\0';
4709750e409Sopenharmony_ci
4719750e409Sopenharmony_ci    number = strtod((const char*)number_c_string, (char**)&after_end);
4729750e409Sopenharmony_ci    if (number_c_string == after_end)
4739750e409Sopenharmony_ci    {
4749750e409Sopenharmony_ci        return false; /* parse_error */
4759750e409Sopenharmony_ci    }
4769750e409Sopenharmony_ci
4779750e409Sopenharmony_ci    item->valuedouble = number;
4789750e409Sopenharmony_ci
4799750e409Sopenharmony_ci    /* use saturation in case of overflow */
4809750e409Sopenharmony_ci    if (number >= INT_MAX)
4819750e409Sopenharmony_ci    {
4829750e409Sopenharmony_ci        item->valueint = INT_MAX;
4839750e409Sopenharmony_ci    }
4849750e409Sopenharmony_ci    else if (number <= (double)INT_MIN)
4859750e409Sopenharmony_ci    {
4869750e409Sopenharmony_ci        item->valueint = INT_MIN;
4879750e409Sopenharmony_ci    }
4889750e409Sopenharmony_ci    else
4899750e409Sopenharmony_ci    {
4909750e409Sopenharmony_ci        item->valueint = (int)number;
4919750e409Sopenharmony_ci    }
4929750e409Sopenharmony_ci
4939750e409Sopenharmony_ci    item->type = cJSON_Number;
4949750e409Sopenharmony_ci
4959750e409Sopenharmony_ci    input_buffer->offset += (size_t)(after_end - number_c_string);
4969750e409Sopenharmony_ci    return true;
4979750e409Sopenharmony_ci}
4989750e409Sopenharmony_ci#endif /* __CJSON_USE_INT64 */
4999750e409Sopenharmony_ci
5009750e409Sopenharmony_ci#ifdef __CJSON_USE_INT64
5019750e409Sopenharmony_ciCJSON_PUBLIC(long long) cJSON_SetInt64NumberValue(cJSON * const object, const long long integer)
5029750e409Sopenharmony_ci{
5039750e409Sopenharmony_ci    if (object == NULL)
5049750e409Sopenharmony_ci    {
5059750e409Sopenharmony_ci        return integer;
5069750e409Sopenharmony_ci    }
5079750e409Sopenharmony_ci
5089750e409Sopenharmony_ci    /* check the type before setting values */
5099750e409Sopenharmony_ci    if (!(object->type & cJSON_Number) || !(object->type & cJSON_IsInt64))
5109750e409Sopenharmony_ci    {
5119750e409Sopenharmony_ci        return integer;
5129750e409Sopenharmony_ci    }
5139750e409Sopenharmony_ci
5149750e409Sopenharmony_ci    object->valueint = integer;
5159750e409Sopenharmony_ci    object->valuedouble = (double)integer;
5169750e409Sopenharmony_ci
5179750e409Sopenharmony_ci    return integer;
5189750e409Sopenharmony_ci}
5199750e409Sopenharmony_ci#endif /* __CJSON_USE_INT64 */
5209750e409Sopenharmony_ci
5219750e409Sopenharmony_ci#ifdef __CJSON_USE_INT64
5229750e409Sopenharmony_ci/* note that double max(DBL_MAX) is bigger than long long max(LLONG_MAX) */
5239750e409Sopenharmony_ciCJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number)
5249750e409Sopenharmony_ci{
5259750e409Sopenharmony_ci    if (number >= (double)LLONG_MAX)
5269750e409Sopenharmony_ci    {
5279750e409Sopenharmony_ci        object->valueint = LLONG_MAX;
5289750e409Sopenharmony_ci    }
5299750e409Sopenharmony_ci    else if (number <= (double)LLONG_MIN)
5309750e409Sopenharmony_ci    {
5319750e409Sopenharmony_ci        object->valueint = LLONG_MIN;
5329750e409Sopenharmony_ci    }
5339750e409Sopenharmony_ci    else
5349750e409Sopenharmony_ci    {
5359750e409Sopenharmony_ci        object->valueint = (long long)number;
5369750e409Sopenharmony_ci    }
5379750e409Sopenharmony_ci
5389750e409Sopenharmony_ci    return object->valuedouble = number;
5399750e409Sopenharmony_ci}
5409750e409Sopenharmony_ci#else
5419750e409Sopenharmony_ci/* don't ask me, but the original cJSON_SetNumberValue returns an integer or double */
5429750e409Sopenharmony_ciCJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number)
5439750e409Sopenharmony_ci{
5449750e409Sopenharmony_ci    if (number >= INT_MAX)
5459750e409Sopenharmony_ci    {
5469750e409Sopenharmony_ci        object->valueint = INT_MAX;
5479750e409Sopenharmony_ci    }
5489750e409Sopenharmony_ci    else if (number <= (double)INT_MIN)
5499750e409Sopenharmony_ci    {
5509750e409Sopenharmony_ci        object->valueint = INT_MIN;
5519750e409Sopenharmony_ci    }
5529750e409Sopenharmony_ci    else
5539750e409Sopenharmony_ci    {
5549750e409Sopenharmony_ci        object->valueint = (int)number;
5559750e409Sopenharmony_ci    }
5569750e409Sopenharmony_ci
5579750e409Sopenharmony_ci    return object->valuedouble = number;
5589750e409Sopenharmony_ci}
5599750e409Sopenharmony_ci#endif /* #ifdef __CJSON_USE_INT64 */
5609750e409Sopenharmony_ci
5619750e409Sopenharmony_ciCJSON_PUBLIC(char*) cJSON_SetValuestring(cJSON *object, const char *valuestring)
5629750e409Sopenharmony_ci{
5639750e409Sopenharmony_ci    char *copy = NULL;
5649750e409Sopenharmony_ci    /* if object's type is not cJSON_String or is cJSON_IsReference, it should not set valuestring */
5659750e409Sopenharmony_ci    if ((object == NULL) || !(object->type & cJSON_String) || (object->type & cJSON_IsReference))
5669750e409Sopenharmony_ci    {
5679750e409Sopenharmony_ci        return NULL;
5689750e409Sopenharmony_ci    }
5699750e409Sopenharmony_ci    /* return NULL if the object is corrupted */
5709750e409Sopenharmony_ci    if (object->valuestring == NULL || valuestring == NULL)
5719750e409Sopenharmony_ci    {
5729750e409Sopenharmony_ci        return NULL;
5739750e409Sopenharmony_ci    }
5749750e409Sopenharmony_ci    if (strlen(valuestring) <= strlen(object->valuestring))
5759750e409Sopenharmony_ci    {
5769750e409Sopenharmony_ci        strcpy(object->valuestring, valuestring);
5779750e409Sopenharmony_ci        return object->valuestring;
5789750e409Sopenharmony_ci    }
5799750e409Sopenharmony_ci    copy = (char*) cJSON_strdup((const unsigned char*)valuestring, &global_hooks);
5809750e409Sopenharmony_ci    if (copy == NULL)
5819750e409Sopenharmony_ci    {
5829750e409Sopenharmony_ci        return NULL;
5839750e409Sopenharmony_ci    }
5849750e409Sopenharmony_ci    if (object->valuestring != NULL)
5859750e409Sopenharmony_ci    {
5869750e409Sopenharmony_ci        cJSON_free(object->valuestring);
5879750e409Sopenharmony_ci    }
5889750e409Sopenharmony_ci    object->valuestring = copy;
5899750e409Sopenharmony_ci
5909750e409Sopenharmony_ci    return copy;
5919750e409Sopenharmony_ci}
5929750e409Sopenharmony_ci
5939750e409Sopenharmony_citypedef struct
5949750e409Sopenharmony_ci{
5959750e409Sopenharmony_ci    unsigned char *buffer;
5969750e409Sopenharmony_ci    size_t length;
5979750e409Sopenharmony_ci    size_t offset;
5989750e409Sopenharmony_ci    size_t depth; /* current nesting depth (for formatted printing) */
5999750e409Sopenharmony_ci    cJSON_bool noalloc;
6009750e409Sopenharmony_ci    cJSON_bool format; /* is this print a formatted print */
6019750e409Sopenharmony_ci    internal_hooks hooks;
6029750e409Sopenharmony_ci} printbuffer;
6039750e409Sopenharmony_ci
6049750e409Sopenharmony_ci/* realloc printbuffer if necessary to have at least "needed" bytes more */
6059750e409Sopenharmony_cistatic unsigned char* ensure(printbuffer * const p, size_t needed)
6069750e409Sopenharmony_ci{
6079750e409Sopenharmony_ci    unsigned char *newbuffer = NULL;
6089750e409Sopenharmony_ci    size_t newsize = 0;
6099750e409Sopenharmony_ci
6109750e409Sopenharmony_ci    if ((p == NULL) || (p->buffer == NULL))
6119750e409Sopenharmony_ci    {
6129750e409Sopenharmony_ci        return NULL;
6139750e409Sopenharmony_ci    }
6149750e409Sopenharmony_ci
6159750e409Sopenharmony_ci    if ((p->length > 0) && (p->offset >= p->length))
6169750e409Sopenharmony_ci    {
6179750e409Sopenharmony_ci        /* make sure that offset is valid */
6189750e409Sopenharmony_ci        return NULL;
6199750e409Sopenharmony_ci    }
6209750e409Sopenharmony_ci
6219750e409Sopenharmony_ci    if (needed > INT_MAX)
6229750e409Sopenharmony_ci    {
6239750e409Sopenharmony_ci        /* sizes bigger than INT_MAX are currently not supported */
6249750e409Sopenharmony_ci        return NULL;
6259750e409Sopenharmony_ci    }
6269750e409Sopenharmony_ci
6279750e409Sopenharmony_ci    needed += p->offset + 1;
6289750e409Sopenharmony_ci    if (needed <= p->length)
6299750e409Sopenharmony_ci    {
6309750e409Sopenharmony_ci        return p->buffer + p->offset;
6319750e409Sopenharmony_ci    }
6329750e409Sopenharmony_ci
6339750e409Sopenharmony_ci    if (p->noalloc) {
6349750e409Sopenharmony_ci        return NULL;
6359750e409Sopenharmony_ci    }
6369750e409Sopenharmony_ci
6379750e409Sopenharmony_ci    /* calculate new buffer size */
6389750e409Sopenharmony_ci    if (needed > (INT_MAX / 2))
6399750e409Sopenharmony_ci    {
6409750e409Sopenharmony_ci        /* overflow of int, use INT_MAX if possible */
6419750e409Sopenharmony_ci        if (needed <= INT_MAX)
6429750e409Sopenharmony_ci        {
6439750e409Sopenharmony_ci            newsize = INT_MAX;
6449750e409Sopenharmony_ci        }
6459750e409Sopenharmony_ci        else
6469750e409Sopenharmony_ci        {
6479750e409Sopenharmony_ci            return NULL;
6489750e409Sopenharmony_ci        }
6499750e409Sopenharmony_ci    }
6509750e409Sopenharmony_ci    else
6519750e409Sopenharmony_ci    {
6529750e409Sopenharmony_ci        newsize = needed * 2;
6539750e409Sopenharmony_ci    }
6549750e409Sopenharmony_ci
6559750e409Sopenharmony_ci    if (p->hooks.reallocate != NULL)
6569750e409Sopenharmony_ci    {
6579750e409Sopenharmony_ci        /* reallocate with realloc if available */
6589750e409Sopenharmony_ci        newbuffer = (unsigned char*)p->hooks.reallocate(p->buffer, newsize);
6599750e409Sopenharmony_ci        if (newbuffer == NULL)
6609750e409Sopenharmony_ci        {
6619750e409Sopenharmony_ci            p->hooks.deallocate(p->buffer);
6629750e409Sopenharmony_ci            p->length = 0;
6639750e409Sopenharmony_ci            p->buffer = NULL;
6649750e409Sopenharmony_ci
6659750e409Sopenharmony_ci            return NULL;
6669750e409Sopenharmony_ci        }
6679750e409Sopenharmony_ci    }
6689750e409Sopenharmony_ci    else
6699750e409Sopenharmony_ci    {
6709750e409Sopenharmony_ci        /* otherwise reallocate manually */
6719750e409Sopenharmony_ci        newbuffer = (unsigned char*)p->hooks.allocate(newsize);
6729750e409Sopenharmony_ci        if (!newbuffer)
6739750e409Sopenharmony_ci        {
6749750e409Sopenharmony_ci            p->hooks.deallocate(p->buffer);
6759750e409Sopenharmony_ci            p->length = 0;
6769750e409Sopenharmony_ci            p->buffer = NULL;
6779750e409Sopenharmony_ci
6789750e409Sopenharmony_ci            return NULL;
6799750e409Sopenharmony_ci        }
6809750e409Sopenharmony_ci
6819750e409Sopenharmony_ci        memcpy(newbuffer, p->buffer, p->offset + 1);
6829750e409Sopenharmony_ci        p->hooks.deallocate(p->buffer);
6839750e409Sopenharmony_ci    }
6849750e409Sopenharmony_ci    p->length = newsize;
6859750e409Sopenharmony_ci    p->buffer = newbuffer;
6869750e409Sopenharmony_ci
6879750e409Sopenharmony_ci    return newbuffer + p->offset;
6889750e409Sopenharmony_ci}
6899750e409Sopenharmony_ci
6909750e409Sopenharmony_ci/* calculate the new length of the string in a printbuffer and update the offset */
6919750e409Sopenharmony_cistatic void update_offset(printbuffer * const buffer)
6929750e409Sopenharmony_ci{
6939750e409Sopenharmony_ci    const unsigned char *buffer_pointer = NULL;
6949750e409Sopenharmony_ci    if ((buffer == NULL) || (buffer->buffer == NULL))
6959750e409Sopenharmony_ci    {
6969750e409Sopenharmony_ci        return;
6979750e409Sopenharmony_ci    }
6989750e409Sopenharmony_ci    buffer_pointer = buffer->buffer + buffer->offset;
6999750e409Sopenharmony_ci
7009750e409Sopenharmony_ci    buffer->offset += strlen((const char*)buffer_pointer);
7019750e409Sopenharmony_ci}
7029750e409Sopenharmony_ci
7039750e409Sopenharmony_ci/* securely comparison of floating-point variables */
7049750e409Sopenharmony_cistatic cJSON_bool compare_double(double a, double b)
7059750e409Sopenharmony_ci{
7069750e409Sopenharmony_ci    double maxVal = fabs(a) > fabs(b) ? fabs(a) : fabs(b);
7079750e409Sopenharmony_ci    return (fabs(a - b) <= maxVal * DBL_EPSILON);
7089750e409Sopenharmony_ci}
7099750e409Sopenharmony_ci
7109750e409Sopenharmony_ci#ifdef __CJSON_USE_INT64
7119750e409Sopenharmony_ci/* Render the number nicely from the given item into a string. */
7129750e409Sopenharmony_cistatic cJSON_bool print_number(const cJSON * const item, printbuffer * const output_buffer)
7139750e409Sopenharmony_ci{
7149750e409Sopenharmony_ci    unsigned char *output_pointer = NULL;
7159750e409Sopenharmony_ci    double d = item->valuedouble;
7169750e409Sopenharmony_ci    long long integer = item->valueint;
7179750e409Sopenharmony_ci    int length = 0;
7189750e409Sopenharmony_ci    size_t i = 0;
7199750e409Sopenharmony_ci    unsigned char number_buffer[26] = {0}; /* temporary buffer to print the number into */
7209750e409Sopenharmony_ci    unsigned char decimal_point = get_decimal_point();
7219750e409Sopenharmony_ci    double test = 0.0;
7229750e409Sopenharmony_ci
7239750e409Sopenharmony_ci    if (output_buffer == NULL)
7249750e409Sopenharmony_ci    {
7259750e409Sopenharmony_ci        return false;
7269750e409Sopenharmony_ci    }
7279750e409Sopenharmony_ci
7289750e409Sopenharmony_ci    if (item->type & cJSON_IsInt64)
7299750e409Sopenharmony_ci    {
7309750e409Sopenharmony_ci        /* use lld to print the long long integer */
7319750e409Sopenharmony_ci        length = sprintf((char*)number_buffer, "%lld", integer);
7329750e409Sopenharmony_ci    }
7339750e409Sopenharmony_ci    else /* item->type == cJSON_Number */
7349750e409Sopenharmony_ci    {
7359750e409Sopenharmony_ci        /* This checks for NaN and Infinity */
7369750e409Sopenharmony_ci        if (isnan(d) || isinf(d))
7379750e409Sopenharmony_ci        {
7389750e409Sopenharmony_ci            length = sprintf((char*)number_buffer, "null");
7399750e409Sopenharmony_ci        }
7409750e409Sopenharmony_ci        else
7419750e409Sopenharmony_ci        {
7429750e409Sopenharmony_ci            /* Try 15 decimal places of precision to avoid nonsignificant nonzero digits */
7439750e409Sopenharmony_ci            length = sprintf((char*)number_buffer, "%1.15g", d);
7449750e409Sopenharmony_ci
7459750e409Sopenharmony_ci            /* Check whether the original double can be recovered */
7469750e409Sopenharmony_ci            if ((sscanf((char*)number_buffer, "%lg", &test) != 1) || !compare_double((double)test, d))
7479750e409Sopenharmony_ci            {
7489750e409Sopenharmony_ci                /* If not, print with 17 decimal places of precision */
7499750e409Sopenharmony_ci                length = sprintf((char*)number_buffer, "%1.17g", d);
7509750e409Sopenharmony_ci            }
7519750e409Sopenharmony_ci        }
7529750e409Sopenharmony_ci    }
7539750e409Sopenharmony_ci
7549750e409Sopenharmony_ci    /* sprintf failed or buffer overrun occurred */
7559750e409Sopenharmony_ci    if ((length < 0) || (length > (int)(sizeof(number_buffer) - 1)))
7569750e409Sopenharmony_ci    {
7579750e409Sopenharmony_ci        return false;
7589750e409Sopenharmony_ci    }
7599750e409Sopenharmony_ci
7609750e409Sopenharmony_ci    /* reserve appropriate space in the output */
7619750e409Sopenharmony_ci    output_pointer = ensure(output_buffer, (size_t)length + sizeof(""));
7629750e409Sopenharmony_ci    if (output_pointer == NULL)
7639750e409Sopenharmony_ci    {
7649750e409Sopenharmony_ci        return false;
7659750e409Sopenharmony_ci    }
7669750e409Sopenharmony_ci
7679750e409Sopenharmony_ci    /* copy the printed number to the output and replace locale
7689750e409Sopenharmony_ci     * dependent decimal point with '.' */
7699750e409Sopenharmony_ci    for (i = 0; i < ((size_t)length); i++)
7709750e409Sopenharmony_ci    {
7719750e409Sopenharmony_ci        if (number_buffer[i] == decimal_point)
7729750e409Sopenharmony_ci        {
7739750e409Sopenharmony_ci            output_pointer[i] = '.';
7749750e409Sopenharmony_ci            continue;
7759750e409Sopenharmony_ci        }
7769750e409Sopenharmony_ci
7779750e409Sopenharmony_ci        output_pointer[i] = number_buffer[i];
7789750e409Sopenharmony_ci    }
7799750e409Sopenharmony_ci    output_pointer[i] = '\0';
7809750e409Sopenharmony_ci
7819750e409Sopenharmony_ci    output_buffer->offset += (size_t)length;
7829750e409Sopenharmony_ci
7839750e409Sopenharmony_ci    return true;
7849750e409Sopenharmony_ci}
7859750e409Sopenharmony_ci#else
7869750e409Sopenharmony_ci/* Render the number nicely from the given item into a string. */
7879750e409Sopenharmony_cistatic cJSON_bool print_number(const cJSON * const item, printbuffer * const output_buffer)
7889750e409Sopenharmony_ci{
7899750e409Sopenharmony_ci    unsigned char *output_pointer = NULL;
7909750e409Sopenharmony_ci    double d = item->valuedouble;
7919750e409Sopenharmony_ci    int length = 0;
7929750e409Sopenharmony_ci    size_t i = 0;
7939750e409Sopenharmony_ci    unsigned char number_buffer[26] = {0}; /* temporary buffer to print the number into */
7949750e409Sopenharmony_ci    unsigned char decimal_point = get_decimal_point();
7959750e409Sopenharmony_ci    double test = 0.0;
7969750e409Sopenharmony_ci
7979750e409Sopenharmony_ci    if (output_buffer == NULL)
7989750e409Sopenharmony_ci    {
7999750e409Sopenharmony_ci        return false;
8009750e409Sopenharmony_ci    }
8019750e409Sopenharmony_ci
8029750e409Sopenharmony_ci    /* This checks for NaN and Infinity */
8039750e409Sopenharmony_ci    if (isnan(d) || isinf(d))
8049750e409Sopenharmony_ci    {
8059750e409Sopenharmony_ci        length = sprintf((char*)number_buffer, "null");
8069750e409Sopenharmony_ci    }
8079750e409Sopenharmony_ci	else if(d == (double)item->valueint)
8089750e409Sopenharmony_ci	{
8099750e409Sopenharmony_ci		length = sprintf((char*)number_buffer, "%d", item->valueint);
8109750e409Sopenharmony_ci	}
8119750e409Sopenharmony_ci    else
8129750e409Sopenharmony_ci    {
8139750e409Sopenharmony_ci        /* Try 15 decimal places of precision to avoid nonsignificant nonzero digits */
8149750e409Sopenharmony_ci        length = sprintf((char*)number_buffer, "%1.15g", d);
8159750e409Sopenharmony_ci
8169750e409Sopenharmony_ci        /* Check whether the original double can be recovered */
8179750e409Sopenharmony_ci        if ((sscanf((char*)number_buffer, "%lg", &test) != 1) || !compare_double((double)test, d))
8189750e409Sopenharmony_ci        {
8199750e409Sopenharmony_ci            /* If not, print with 17 decimal places of precision */
8209750e409Sopenharmony_ci            length = sprintf((char*)number_buffer, "%1.17g", d);
8219750e409Sopenharmony_ci        }
8229750e409Sopenharmony_ci    }
8239750e409Sopenharmony_ci
8249750e409Sopenharmony_ci    /* sprintf failed or buffer overrun occurred */
8259750e409Sopenharmony_ci    if ((length < 0) || (length > (int)(sizeof(number_buffer) - 1)))
8269750e409Sopenharmony_ci    {
8279750e409Sopenharmony_ci        return false;
8289750e409Sopenharmony_ci    }
8299750e409Sopenharmony_ci
8309750e409Sopenharmony_ci    /* reserve appropriate space in the output */
8319750e409Sopenharmony_ci    output_pointer = ensure(output_buffer, (size_t)length + sizeof(""));
8329750e409Sopenharmony_ci    if (output_pointer == NULL)
8339750e409Sopenharmony_ci    {
8349750e409Sopenharmony_ci        return false;
8359750e409Sopenharmony_ci    }
8369750e409Sopenharmony_ci
8379750e409Sopenharmony_ci    /* copy the printed number to the output and replace locale
8389750e409Sopenharmony_ci     * dependent decimal point with '.' */
8399750e409Sopenharmony_ci    for (i = 0; i < ((size_t)length); i++)
8409750e409Sopenharmony_ci    {
8419750e409Sopenharmony_ci        if (number_buffer[i] == decimal_point)
8429750e409Sopenharmony_ci        {
8439750e409Sopenharmony_ci            output_pointer[i] = '.';
8449750e409Sopenharmony_ci            continue;
8459750e409Sopenharmony_ci        }
8469750e409Sopenharmony_ci
8479750e409Sopenharmony_ci        output_pointer[i] = number_buffer[i];
8489750e409Sopenharmony_ci    }
8499750e409Sopenharmony_ci    output_pointer[i] = '\0';
8509750e409Sopenharmony_ci
8519750e409Sopenharmony_ci    output_buffer->offset += (size_t)length;
8529750e409Sopenharmony_ci
8539750e409Sopenharmony_ci    return true;
8549750e409Sopenharmony_ci}
8559750e409Sopenharmony_ci#endif /* __CJSON_USE_INT64 */
8569750e409Sopenharmony_ci
8579750e409Sopenharmony_ci/* parse 4 digit hexadecimal number */
8589750e409Sopenharmony_cistatic unsigned parse_hex4(const unsigned char * const input)
8599750e409Sopenharmony_ci{
8609750e409Sopenharmony_ci    unsigned int h = 0;
8619750e409Sopenharmony_ci    size_t i = 0;
8629750e409Sopenharmony_ci
8639750e409Sopenharmony_ci    for (i = 0; i < 4; i++)
8649750e409Sopenharmony_ci    {
8659750e409Sopenharmony_ci        /* parse digit */
8669750e409Sopenharmony_ci        if ((input[i] >= '0') && (input[i] <= '9'))
8679750e409Sopenharmony_ci        {
8689750e409Sopenharmony_ci            h += (unsigned int) input[i] - '0';
8699750e409Sopenharmony_ci        }
8709750e409Sopenharmony_ci        else if ((input[i] >= 'A') && (input[i] <= 'F'))
8719750e409Sopenharmony_ci        {
8729750e409Sopenharmony_ci            h += (unsigned int) 10 + input[i] - 'A';
8739750e409Sopenharmony_ci        }
8749750e409Sopenharmony_ci        else if ((input[i] >= 'a') && (input[i] <= 'f'))
8759750e409Sopenharmony_ci        {
8769750e409Sopenharmony_ci            h += (unsigned int) 10 + input[i] - 'a';
8779750e409Sopenharmony_ci        }
8789750e409Sopenharmony_ci        else /* invalid */
8799750e409Sopenharmony_ci        {
8809750e409Sopenharmony_ci            return 0;
8819750e409Sopenharmony_ci        }
8829750e409Sopenharmony_ci
8839750e409Sopenharmony_ci        if (i < 3)
8849750e409Sopenharmony_ci        {
8859750e409Sopenharmony_ci            /* shift left to make place for the next nibble */
8869750e409Sopenharmony_ci            h = h << 4;
8879750e409Sopenharmony_ci        }
8889750e409Sopenharmony_ci    }
8899750e409Sopenharmony_ci
8909750e409Sopenharmony_ci    return h;
8919750e409Sopenharmony_ci}
8929750e409Sopenharmony_ci
8939750e409Sopenharmony_ci/* converts a UTF-16 literal to UTF-8
8949750e409Sopenharmony_ci * A literal can be one or two sequences of the form \uXXXX */
8959750e409Sopenharmony_cistatic unsigned char utf16_literal_to_utf8(const unsigned char * const input_pointer, const unsigned char * const input_end, unsigned char **output_pointer)
8969750e409Sopenharmony_ci{
8979750e409Sopenharmony_ci    long unsigned int codepoint = 0;
8989750e409Sopenharmony_ci    unsigned int first_code = 0;
8999750e409Sopenharmony_ci    const unsigned char *first_sequence = input_pointer;
9009750e409Sopenharmony_ci    unsigned char utf8_length = 0;
9019750e409Sopenharmony_ci    unsigned char utf8_position = 0;
9029750e409Sopenharmony_ci    unsigned char sequence_length = 0;
9039750e409Sopenharmony_ci    unsigned char first_byte_mark = 0;
9049750e409Sopenharmony_ci
9059750e409Sopenharmony_ci    if ((input_end - first_sequence) < 6)
9069750e409Sopenharmony_ci    {
9079750e409Sopenharmony_ci        /* input ends unexpectedly */
9089750e409Sopenharmony_ci        goto fail;
9099750e409Sopenharmony_ci    }
9109750e409Sopenharmony_ci
9119750e409Sopenharmony_ci    /* get the first utf16 sequence */
9129750e409Sopenharmony_ci    first_code = parse_hex4(first_sequence + 2);
9139750e409Sopenharmony_ci
9149750e409Sopenharmony_ci    /* check that the code is valid */
9159750e409Sopenharmony_ci    if (((first_code >= 0xDC00) && (first_code <= 0xDFFF)))
9169750e409Sopenharmony_ci    {
9179750e409Sopenharmony_ci        goto fail;
9189750e409Sopenharmony_ci    }
9199750e409Sopenharmony_ci
9209750e409Sopenharmony_ci    /* UTF16 surrogate pair */
9219750e409Sopenharmony_ci    if ((first_code >= 0xD800) && (first_code <= 0xDBFF))
9229750e409Sopenharmony_ci    {
9239750e409Sopenharmony_ci        const unsigned char *second_sequence = first_sequence + 6;
9249750e409Sopenharmony_ci        unsigned int second_code = 0;
9259750e409Sopenharmony_ci        sequence_length = 12; /* \uXXXX\uXXXX */
9269750e409Sopenharmony_ci
9279750e409Sopenharmony_ci        if ((input_end - second_sequence) < 6)
9289750e409Sopenharmony_ci        {
9299750e409Sopenharmony_ci            /* input ends unexpectedly */
9309750e409Sopenharmony_ci            goto fail;
9319750e409Sopenharmony_ci        }
9329750e409Sopenharmony_ci
9339750e409Sopenharmony_ci        if ((second_sequence[0] != '\\') || (second_sequence[1] != 'u'))
9349750e409Sopenharmony_ci        {
9359750e409Sopenharmony_ci            /* missing second half of the surrogate pair */
9369750e409Sopenharmony_ci            goto fail;
9379750e409Sopenharmony_ci        }
9389750e409Sopenharmony_ci
9399750e409Sopenharmony_ci        /* get the second utf16 sequence */
9409750e409Sopenharmony_ci        second_code = parse_hex4(second_sequence + 2);
9419750e409Sopenharmony_ci        /* check that the code is valid */
9429750e409Sopenharmony_ci        if ((second_code < 0xDC00) || (second_code > 0xDFFF))
9439750e409Sopenharmony_ci        {
9449750e409Sopenharmony_ci            /* invalid second half of the surrogate pair */
9459750e409Sopenharmony_ci            goto fail;
9469750e409Sopenharmony_ci        }
9479750e409Sopenharmony_ci
9489750e409Sopenharmony_ci
9499750e409Sopenharmony_ci        /* calculate the unicode codepoint from the surrogate pair */
9509750e409Sopenharmony_ci        codepoint = 0x10000 + (((first_code & 0x3FF) << 10) | (second_code & 0x3FF));
9519750e409Sopenharmony_ci    }
9529750e409Sopenharmony_ci    else
9539750e409Sopenharmony_ci    {
9549750e409Sopenharmony_ci        sequence_length = 6; /* \uXXXX */
9559750e409Sopenharmony_ci        codepoint = first_code;
9569750e409Sopenharmony_ci    }
9579750e409Sopenharmony_ci
9589750e409Sopenharmony_ci    /* encode as UTF-8
9599750e409Sopenharmony_ci     * takes at maximum 4 bytes to encode:
9609750e409Sopenharmony_ci     * 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */
9619750e409Sopenharmony_ci    if (codepoint < 0x80)
9629750e409Sopenharmony_ci    {
9639750e409Sopenharmony_ci        /* normal ascii, encoding 0xxxxxxx */
9649750e409Sopenharmony_ci        utf8_length = 1;
9659750e409Sopenharmony_ci    }
9669750e409Sopenharmony_ci    else if (codepoint < 0x800)
9679750e409Sopenharmony_ci    {
9689750e409Sopenharmony_ci        /* two bytes, encoding 110xxxxx 10xxxxxx */
9699750e409Sopenharmony_ci        utf8_length = 2;
9709750e409Sopenharmony_ci        first_byte_mark = 0xC0; /* 11000000 */
9719750e409Sopenharmony_ci    }
9729750e409Sopenharmony_ci    else if (codepoint < 0x10000)
9739750e409Sopenharmony_ci    {
9749750e409Sopenharmony_ci        /* three bytes, encoding 1110xxxx 10xxxxxx 10xxxxxx */
9759750e409Sopenharmony_ci        utf8_length = 3;
9769750e409Sopenharmony_ci        first_byte_mark = 0xE0; /* 11100000 */
9779750e409Sopenharmony_ci    }
9789750e409Sopenharmony_ci    else if (codepoint <= 0x10FFFF)
9799750e409Sopenharmony_ci    {
9809750e409Sopenharmony_ci        /* four bytes, encoding 1110xxxx 10xxxxxx 10xxxxxx 10xxxxxx */
9819750e409Sopenharmony_ci        utf8_length = 4;
9829750e409Sopenharmony_ci        first_byte_mark = 0xF0; /* 11110000 */
9839750e409Sopenharmony_ci    }
9849750e409Sopenharmony_ci    else
9859750e409Sopenharmony_ci    {
9869750e409Sopenharmony_ci        /* invalid unicode codepoint */
9879750e409Sopenharmony_ci        goto fail;
9889750e409Sopenharmony_ci    }
9899750e409Sopenharmony_ci
9909750e409Sopenharmony_ci    /* encode as utf8 */
9919750e409Sopenharmony_ci    for (utf8_position = (unsigned char)(utf8_length - 1); utf8_position > 0; utf8_position--)
9929750e409Sopenharmony_ci    {
9939750e409Sopenharmony_ci        /* 10xxxxxx */
9949750e409Sopenharmony_ci        (*output_pointer)[utf8_position] = (unsigned char)((codepoint | 0x80) & 0xBF);
9959750e409Sopenharmony_ci        codepoint >>= 6;
9969750e409Sopenharmony_ci    }
9979750e409Sopenharmony_ci    /* encode first byte */
9989750e409Sopenharmony_ci    if (utf8_length > 1)
9999750e409Sopenharmony_ci    {
10009750e409Sopenharmony_ci        (*output_pointer)[0] = (unsigned char)((codepoint | first_byte_mark) & 0xFF);
10019750e409Sopenharmony_ci    }
10029750e409Sopenharmony_ci    else
10039750e409Sopenharmony_ci    {
10049750e409Sopenharmony_ci        (*output_pointer)[0] = (unsigned char)(codepoint & 0x7F);
10059750e409Sopenharmony_ci    }
10069750e409Sopenharmony_ci
10079750e409Sopenharmony_ci    *output_pointer += utf8_length;
10089750e409Sopenharmony_ci
10099750e409Sopenharmony_ci    return sequence_length;
10109750e409Sopenharmony_ci
10119750e409Sopenharmony_cifail:
10129750e409Sopenharmony_ci    return 0;
10139750e409Sopenharmony_ci}
10149750e409Sopenharmony_ci
10159750e409Sopenharmony_ci/* Parse the input text into an unescaped cinput, and populate item. */
10169750e409Sopenharmony_cistatic cJSON_bool parse_string(cJSON * const item, parse_buffer * const input_buffer)
10179750e409Sopenharmony_ci{
10189750e409Sopenharmony_ci    const unsigned char *input_pointer = buffer_at_offset(input_buffer) + 1;
10199750e409Sopenharmony_ci    const unsigned char *input_end = buffer_at_offset(input_buffer) + 1;
10209750e409Sopenharmony_ci    unsigned char *output_pointer = NULL;
10219750e409Sopenharmony_ci    unsigned char *output = NULL;
10229750e409Sopenharmony_ci
10239750e409Sopenharmony_ci    /* not a string */
10249750e409Sopenharmony_ci    if (buffer_at_offset(input_buffer)[0] != '\"')
10259750e409Sopenharmony_ci    {
10269750e409Sopenharmony_ci        goto fail;
10279750e409Sopenharmony_ci    }
10289750e409Sopenharmony_ci
10299750e409Sopenharmony_ci    {
10309750e409Sopenharmony_ci        /* calculate approximate size of the output (overestimate) */
10319750e409Sopenharmony_ci        size_t allocation_length = 0;
10329750e409Sopenharmony_ci        size_t skipped_bytes = 0;
10339750e409Sopenharmony_ci        while (((size_t)(input_end - input_buffer->content) < input_buffer->length) && (*input_end != '\"'))
10349750e409Sopenharmony_ci        {
10359750e409Sopenharmony_ci            /* is escape sequence */
10369750e409Sopenharmony_ci            if (input_end[0] == '\\')
10379750e409Sopenharmony_ci            {
10389750e409Sopenharmony_ci                if ((size_t)(input_end + 1 - input_buffer->content) >= input_buffer->length)
10399750e409Sopenharmony_ci                {
10409750e409Sopenharmony_ci                    /* prevent buffer overflow when last input character is a backslash */
10419750e409Sopenharmony_ci                    goto fail;
10429750e409Sopenharmony_ci                }
10439750e409Sopenharmony_ci                skipped_bytes++;
10449750e409Sopenharmony_ci                input_end++;
10459750e409Sopenharmony_ci            }
10469750e409Sopenharmony_ci            input_end++;
10479750e409Sopenharmony_ci        }
10489750e409Sopenharmony_ci        if (((size_t)(input_end - input_buffer->content) >= input_buffer->length) || (*input_end != '\"'))
10499750e409Sopenharmony_ci        {
10509750e409Sopenharmony_ci            goto fail; /* string ended unexpectedly */
10519750e409Sopenharmony_ci        }
10529750e409Sopenharmony_ci
10539750e409Sopenharmony_ci        /* This is at most how much we need for the output */
10549750e409Sopenharmony_ci        allocation_length = (size_t) (input_end - buffer_at_offset(input_buffer)) - skipped_bytes;
10559750e409Sopenharmony_ci        output = (unsigned char*)input_buffer->hooks.allocate(allocation_length + sizeof(""));
10569750e409Sopenharmony_ci        if (output == NULL)
10579750e409Sopenharmony_ci        {
10589750e409Sopenharmony_ci            goto fail; /* allocation failure */
10599750e409Sopenharmony_ci        }
10609750e409Sopenharmony_ci    }
10619750e409Sopenharmony_ci
10629750e409Sopenharmony_ci    output_pointer = output;
10639750e409Sopenharmony_ci    /* loop through the string literal */
10649750e409Sopenharmony_ci    while (input_pointer < input_end)
10659750e409Sopenharmony_ci    {
10669750e409Sopenharmony_ci        if (*input_pointer != '\\')
10679750e409Sopenharmony_ci        {
10689750e409Sopenharmony_ci            *output_pointer++ = *input_pointer++;
10699750e409Sopenharmony_ci        }
10709750e409Sopenharmony_ci        /* escape sequence */
10719750e409Sopenharmony_ci        else
10729750e409Sopenharmony_ci        {
10739750e409Sopenharmony_ci            unsigned char sequence_length = 2;
10749750e409Sopenharmony_ci            if ((input_end - input_pointer) < 1)
10759750e409Sopenharmony_ci            {
10769750e409Sopenharmony_ci                goto fail;
10779750e409Sopenharmony_ci            }
10789750e409Sopenharmony_ci
10799750e409Sopenharmony_ci            switch (input_pointer[1])
10809750e409Sopenharmony_ci            {
10819750e409Sopenharmony_ci                case 'b':
10829750e409Sopenharmony_ci                    *output_pointer++ = '\b';
10839750e409Sopenharmony_ci                    break;
10849750e409Sopenharmony_ci                case 'f':
10859750e409Sopenharmony_ci                    *output_pointer++ = '\f';
10869750e409Sopenharmony_ci                    break;
10879750e409Sopenharmony_ci                case 'n':
10889750e409Sopenharmony_ci                    *output_pointer++ = '\n';
10899750e409Sopenharmony_ci                    break;
10909750e409Sopenharmony_ci                case 'r':
10919750e409Sopenharmony_ci                    *output_pointer++ = '\r';
10929750e409Sopenharmony_ci                    break;
10939750e409Sopenharmony_ci                case 't':
10949750e409Sopenharmony_ci                    *output_pointer++ = '\t';
10959750e409Sopenharmony_ci                    break;
10969750e409Sopenharmony_ci                case '\"':
10979750e409Sopenharmony_ci                case '\\':
10989750e409Sopenharmony_ci                case '/':
10999750e409Sopenharmony_ci                    *output_pointer++ = input_pointer[1];
11009750e409Sopenharmony_ci                    break;
11019750e409Sopenharmony_ci
11029750e409Sopenharmony_ci                /* UTF-16 literal */
11039750e409Sopenharmony_ci                case 'u':
11049750e409Sopenharmony_ci                    sequence_length = utf16_literal_to_utf8(input_pointer, input_end, &output_pointer);
11059750e409Sopenharmony_ci                    if (sequence_length == 0)
11069750e409Sopenharmony_ci                    {
11079750e409Sopenharmony_ci                        /* failed to convert UTF16-literal to UTF-8 */
11089750e409Sopenharmony_ci                        goto fail;
11099750e409Sopenharmony_ci                    }
11109750e409Sopenharmony_ci                    break;
11119750e409Sopenharmony_ci
11129750e409Sopenharmony_ci                default:
11139750e409Sopenharmony_ci                    goto fail;
11149750e409Sopenharmony_ci            }
11159750e409Sopenharmony_ci            input_pointer += sequence_length;
11169750e409Sopenharmony_ci        }
11179750e409Sopenharmony_ci    }
11189750e409Sopenharmony_ci
11199750e409Sopenharmony_ci    /* zero terminate the output */
11209750e409Sopenharmony_ci    *output_pointer = '\0';
11219750e409Sopenharmony_ci
11229750e409Sopenharmony_ci    item->type = cJSON_String;
11239750e409Sopenharmony_ci    item->valuestring = (char*)output;
11249750e409Sopenharmony_ci
11259750e409Sopenharmony_ci    input_buffer->offset = (size_t) (input_end - input_buffer->content);
11269750e409Sopenharmony_ci    input_buffer->offset++;
11279750e409Sopenharmony_ci
11289750e409Sopenharmony_ci    return true;
11299750e409Sopenharmony_ci
11309750e409Sopenharmony_cifail:
11319750e409Sopenharmony_ci    if (output != NULL)
11329750e409Sopenharmony_ci    {
11339750e409Sopenharmony_ci        input_buffer->hooks.deallocate(output);
11349750e409Sopenharmony_ci    }
11359750e409Sopenharmony_ci
11369750e409Sopenharmony_ci    if (input_pointer != NULL)
11379750e409Sopenharmony_ci    {
11389750e409Sopenharmony_ci        input_buffer->offset = (size_t)(input_pointer - input_buffer->content);
11399750e409Sopenharmony_ci    }
11409750e409Sopenharmony_ci
11419750e409Sopenharmony_ci    return false;
11429750e409Sopenharmony_ci}
11439750e409Sopenharmony_ci
11449750e409Sopenharmony_ci/* Render the cstring provided to an escaped version that can be printed. */
11459750e409Sopenharmony_cistatic cJSON_bool print_string_ptr(const unsigned char * const input, printbuffer * const output_buffer)
11469750e409Sopenharmony_ci{
11479750e409Sopenharmony_ci    const unsigned char *input_pointer = NULL;
11489750e409Sopenharmony_ci    unsigned char *output = NULL;
11499750e409Sopenharmony_ci    unsigned char *output_pointer = NULL;
11509750e409Sopenharmony_ci    size_t output_length = 0;
11519750e409Sopenharmony_ci    /* numbers of additional characters needed for escaping */
11529750e409Sopenharmony_ci    size_t escape_characters = 0;
11539750e409Sopenharmony_ci
11549750e409Sopenharmony_ci    if (output_buffer == NULL)
11559750e409Sopenharmony_ci    {
11569750e409Sopenharmony_ci        return false;
11579750e409Sopenharmony_ci    }
11589750e409Sopenharmony_ci
11599750e409Sopenharmony_ci    /* empty string */
11609750e409Sopenharmony_ci    if (input == NULL)
11619750e409Sopenharmony_ci    {
11629750e409Sopenharmony_ci        output = ensure(output_buffer, sizeof("\"\""));
11639750e409Sopenharmony_ci        if (output == NULL)
11649750e409Sopenharmony_ci        {
11659750e409Sopenharmony_ci            return false;
11669750e409Sopenharmony_ci        }
11679750e409Sopenharmony_ci        strcpy((char*)output, "\"\"");
11689750e409Sopenharmony_ci
11699750e409Sopenharmony_ci        return true;
11709750e409Sopenharmony_ci    }
11719750e409Sopenharmony_ci
11729750e409Sopenharmony_ci    /* set "flag" to 1 if something needs to be escaped */
11739750e409Sopenharmony_ci    for (input_pointer = input; *input_pointer; input_pointer++)
11749750e409Sopenharmony_ci    {
11759750e409Sopenharmony_ci        switch (*input_pointer)
11769750e409Sopenharmony_ci        {
11779750e409Sopenharmony_ci            case '\"':
11789750e409Sopenharmony_ci            case '\\':
11799750e409Sopenharmony_ci            case '\b':
11809750e409Sopenharmony_ci            case '\f':
11819750e409Sopenharmony_ci            case '\n':
11829750e409Sopenharmony_ci            case '\r':
11839750e409Sopenharmony_ci            case '\t':
11849750e409Sopenharmony_ci                /* one character escape sequence */
11859750e409Sopenharmony_ci                escape_characters++;
11869750e409Sopenharmony_ci                break;
11879750e409Sopenharmony_ci            default:
11889750e409Sopenharmony_ci                if (*input_pointer < 32)
11899750e409Sopenharmony_ci                {
11909750e409Sopenharmony_ci                    /* UTF-16 escape sequence uXXXX */
11919750e409Sopenharmony_ci                    escape_characters += 5;
11929750e409Sopenharmony_ci                }
11939750e409Sopenharmony_ci                break;
11949750e409Sopenharmony_ci        }
11959750e409Sopenharmony_ci    }
11969750e409Sopenharmony_ci    output_length = (size_t)(input_pointer - input) + escape_characters;
11979750e409Sopenharmony_ci
11989750e409Sopenharmony_ci    output = ensure(output_buffer, output_length + sizeof("\"\""));
11999750e409Sopenharmony_ci    if (output == NULL)
12009750e409Sopenharmony_ci    {
12019750e409Sopenharmony_ci        return false;
12029750e409Sopenharmony_ci    }
12039750e409Sopenharmony_ci
12049750e409Sopenharmony_ci    /* no characters have to be escaped */
12059750e409Sopenharmony_ci    if (escape_characters == 0)
12069750e409Sopenharmony_ci    {
12079750e409Sopenharmony_ci        output[0] = '\"';
12089750e409Sopenharmony_ci        memcpy(output + 1, input, output_length);
12099750e409Sopenharmony_ci        output[output_length + 1] = '\"';
12109750e409Sopenharmony_ci        output[output_length + 2] = '\0';
12119750e409Sopenharmony_ci
12129750e409Sopenharmony_ci        return true;
12139750e409Sopenharmony_ci    }
12149750e409Sopenharmony_ci
12159750e409Sopenharmony_ci    output[0] = '\"';
12169750e409Sopenharmony_ci    output_pointer = output + 1;
12179750e409Sopenharmony_ci    /* copy the string */
12189750e409Sopenharmony_ci    for (input_pointer = input; *input_pointer != '\0'; (void)input_pointer++, output_pointer++)
12199750e409Sopenharmony_ci    {
12209750e409Sopenharmony_ci        if ((*input_pointer > 31) && (*input_pointer != '\"') && (*input_pointer != '\\'))
12219750e409Sopenharmony_ci        {
12229750e409Sopenharmony_ci            /* normal character, copy */
12239750e409Sopenharmony_ci            *output_pointer = *input_pointer;
12249750e409Sopenharmony_ci        }
12259750e409Sopenharmony_ci        else
12269750e409Sopenharmony_ci        {
12279750e409Sopenharmony_ci            /* character needs to be escaped */
12289750e409Sopenharmony_ci            *output_pointer++ = '\\';
12299750e409Sopenharmony_ci            switch (*input_pointer)
12309750e409Sopenharmony_ci            {
12319750e409Sopenharmony_ci                case '\\':
12329750e409Sopenharmony_ci                    *output_pointer = '\\';
12339750e409Sopenharmony_ci                    break;
12349750e409Sopenharmony_ci                case '\"':
12359750e409Sopenharmony_ci                    *output_pointer = '\"';
12369750e409Sopenharmony_ci                    break;
12379750e409Sopenharmony_ci                case '\b':
12389750e409Sopenharmony_ci                    *output_pointer = 'b';
12399750e409Sopenharmony_ci                    break;
12409750e409Sopenharmony_ci                case '\f':
12419750e409Sopenharmony_ci                    *output_pointer = 'f';
12429750e409Sopenharmony_ci                    break;
12439750e409Sopenharmony_ci                case '\n':
12449750e409Sopenharmony_ci                    *output_pointer = 'n';
12459750e409Sopenharmony_ci                    break;
12469750e409Sopenharmony_ci                case '\r':
12479750e409Sopenharmony_ci                    *output_pointer = 'r';
12489750e409Sopenharmony_ci                    break;
12499750e409Sopenharmony_ci                case '\t':
12509750e409Sopenharmony_ci                    *output_pointer = 't';
12519750e409Sopenharmony_ci                    break;
12529750e409Sopenharmony_ci                default:
12539750e409Sopenharmony_ci                    /* escape and print as unicode codepoint */
12549750e409Sopenharmony_ci                    sprintf((char*)output_pointer, "u%04x", *input_pointer);
12559750e409Sopenharmony_ci                    output_pointer += 4;
12569750e409Sopenharmony_ci                    break;
12579750e409Sopenharmony_ci            }
12589750e409Sopenharmony_ci        }
12599750e409Sopenharmony_ci    }
12609750e409Sopenharmony_ci    output[output_length + 1] = '\"';
12619750e409Sopenharmony_ci    output[output_length + 2] = '\0';
12629750e409Sopenharmony_ci
12639750e409Sopenharmony_ci    return true;
12649750e409Sopenharmony_ci}
12659750e409Sopenharmony_ci
12669750e409Sopenharmony_ci/* Invoke print_string_ptr (which is useful) on an item. */
12679750e409Sopenharmony_cistatic cJSON_bool print_string(const cJSON * const item, printbuffer * const p)
12689750e409Sopenharmony_ci{
12699750e409Sopenharmony_ci    return print_string_ptr((unsigned char*)item->valuestring, p);
12709750e409Sopenharmony_ci}
12719750e409Sopenharmony_ci
12729750e409Sopenharmony_ci/* Predeclare these prototypes. */
12739750e409Sopenharmony_cistatic cJSON_bool parse_value(cJSON * const item, parse_buffer * const input_buffer);
12749750e409Sopenharmony_cistatic cJSON_bool print_value(const cJSON * const item, printbuffer * const output_buffer);
12759750e409Sopenharmony_cistatic cJSON_bool parse_array(cJSON * const item, parse_buffer * const input_buffer);
12769750e409Sopenharmony_cistatic cJSON_bool print_array(const cJSON * const item, printbuffer * const output_buffer);
12779750e409Sopenharmony_cistatic cJSON_bool parse_object(cJSON * const item, parse_buffer * const input_buffer);
12789750e409Sopenharmony_cistatic cJSON_bool print_object(const cJSON * const item, printbuffer * const output_buffer);
12799750e409Sopenharmony_ci
12809750e409Sopenharmony_ci/* Utility to jump whitespace and cr/lf */
12819750e409Sopenharmony_cistatic parse_buffer *buffer_skip_whitespace(parse_buffer * const buffer)
12829750e409Sopenharmony_ci{
12839750e409Sopenharmony_ci    if ((buffer == NULL) || (buffer->content == NULL))
12849750e409Sopenharmony_ci    {
12859750e409Sopenharmony_ci        return NULL;
12869750e409Sopenharmony_ci    }
12879750e409Sopenharmony_ci
12889750e409Sopenharmony_ci    if (cannot_access_at_index(buffer, 0))
12899750e409Sopenharmony_ci    {
12909750e409Sopenharmony_ci        return buffer;
12919750e409Sopenharmony_ci    }
12929750e409Sopenharmony_ci
12939750e409Sopenharmony_ci    while (can_access_at_index(buffer, 0) && (buffer_at_offset(buffer)[0] <= 32))
12949750e409Sopenharmony_ci    {
12959750e409Sopenharmony_ci       buffer->offset++;
12969750e409Sopenharmony_ci    }
12979750e409Sopenharmony_ci
12989750e409Sopenharmony_ci    if (buffer->offset == buffer->length)
12999750e409Sopenharmony_ci    {
13009750e409Sopenharmony_ci        buffer->offset--;
13019750e409Sopenharmony_ci    }
13029750e409Sopenharmony_ci
13039750e409Sopenharmony_ci    return buffer;
13049750e409Sopenharmony_ci}
13059750e409Sopenharmony_ci
13069750e409Sopenharmony_ci/* skip the UTF-8 BOM (byte order mark) if it is at the beginning of a buffer */
13079750e409Sopenharmony_cistatic parse_buffer *skip_utf8_bom(parse_buffer * const buffer)
13089750e409Sopenharmony_ci{
13099750e409Sopenharmony_ci    if ((buffer == NULL) || (buffer->content == NULL) || (buffer->offset != 0))
13109750e409Sopenharmony_ci    {
13119750e409Sopenharmony_ci        return NULL;
13129750e409Sopenharmony_ci    }
13139750e409Sopenharmony_ci
13149750e409Sopenharmony_ci    if (can_access_at_index(buffer, 4) && (strncmp((const char*)buffer_at_offset(buffer), "\xEF\xBB\xBF", 3) == 0))
13159750e409Sopenharmony_ci    {
13169750e409Sopenharmony_ci        buffer->offset += 3;
13179750e409Sopenharmony_ci    }
13189750e409Sopenharmony_ci
13199750e409Sopenharmony_ci    return buffer;
13209750e409Sopenharmony_ci}
13219750e409Sopenharmony_ci
13229750e409Sopenharmony_ciCJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_bool require_null_terminated)
13239750e409Sopenharmony_ci{
13249750e409Sopenharmony_ci    size_t buffer_length;
13259750e409Sopenharmony_ci
13269750e409Sopenharmony_ci    if (NULL == value)
13279750e409Sopenharmony_ci    {
13289750e409Sopenharmony_ci        return NULL;
13299750e409Sopenharmony_ci    }
13309750e409Sopenharmony_ci
13319750e409Sopenharmony_ci    /* Adding null character size due to require_null_terminated. */
13329750e409Sopenharmony_ci    buffer_length = strlen(value) + sizeof("");
13339750e409Sopenharmony_ci
13349750e409Sopenharmony_ci    return cJSON_ParseWithLengthOpts(value, buffer_length, return_parse_end, require_null_terminated);
13359750e409Sopenharmony_ci}
13369750e409Sopenharmony_ci
13379750e409Sopenharmony_ci/* Parse an object - create a new root, and populate. */
13389750e409Sopenharmony_ciCJSON_PUBLIC(cJSON *) cJSON_ParseWithLengthOpts(const char *value, size_t buffer_length, const char **return_parse_end, cJSON_bool require_null_terminated)
13399750e409Sopenharmony_ci{
13409750e409Sopenharmony_ci    parse_buffer buffer = { 0, 0, 0, 0, { 0, 0, 0 } };
13419750e409Sopenharmony_ci    cJSON *item = NULL;
13429750e409Sopenharmony_ci
13439750e409Sopenharmony_ci    /* reset error position */
13449750e409Sopenharmony_ci    global_error.json = NULL;
13459750e409Sopenharmony_ci    global_error.position = 0;
13469750e409Sopenharmony_ci
13479750e409Sopenharmony_ci    if (value == NULL || 0 == buffer_length)
13489750e409Sopenharmony_ci    {
13499750e409Sopenharmony_ci        goto fail;
13509750e409Sopenharmony_ci    }
13519750e409Sopenharmony_ci
13529750e409Sopenharmony_ci    buffer.content = (const unsigned char*)value;
13539750e409Sopenharmony_ci    buffer.length = buffer_length;
13549750e409Sopenharmony_ci    buffer.offset = 0;
13559750e409Sopenharmony_ci    buffer.hooks = global_hooks;
13569750e409Sopenharmony_ci
13579750e409Sopenharmony_ci    item = cJSON_New_Item(&global_hooks);
13589750e409Sopenharmony_ci    if (item == NULL) /* memory fail */
13599750e409Sopenharmony_ci    {
13609750e409Sopenharmony_ci        goto fail;
13619750e409Sopenharmony_ci    }
13629750e409Sopenharmony_ci
13639750e409Sopenharmony_ci    if (!parse_value(item, buffer_skip_whitespace(skip_utf8_bom(&buffer))))
13649750e409Sopenharmony_ci    {
13659750e409Sopenharmony_ci        /* parse failure. ep is set. */
13669750e409Sopenharmony_ci        goto fail;
13679750e409Sopenharmony_ci    }
13689750e409Sopenharmony_ci
13699750e409Sopenharmony_ci    /* if we require null-terminated JSON without appended garbage, skip and then check for a null terminator */
13709750e409Sopenharmony_ci    if (require_null_terminated)
13719750e409Sopenharmony_ci    {
13729750e409Sopenharmony_ci        buffer_skip_whitespace(&buffer);
13739750e409Sopenharmony_ci        if ((buffer.offset >= buffer.length) || buffer_at_offset(&buffer)[0] != '\0')
13749750e409Sopenharmony_ci        {
13759750e409Sopenharmony_ci            goto fail;
13769750e409Sopenharmony_ci        }
13779750e409Sopenharmony_ci    }
13789750e409Sopenharmony_ci    if (return_parse_end)
13799750e409Sopenharmony_ci    {
13809750e409Sopenharmony_ci        *return_parse_end = (const char*)buffer_at_offset(&buffer);
13819750e409Sopenharmony_ci    }
13829750e409Sopenharmony_ci
13839750e409Sopenharmony_ci    return item;
13849750e409Sopenharmony_ci
13859750e409Sopenharmony_cifail:
13869750e409Sopenharmony_ci    if (item != NULL)
13879750e409Sopenharmony_ci    {
13889750e409Sopenharmony_ci        cJSON_Delete(item);
13899750e409Sopenharmony_ci    }
13909750e409Sopenharmony_ci
13919750e409Sopenharmony_ci    if (value != NULL)
13929750e409Sopenharmony_ci    {
13939750e409Sopenharmony_ci        error local_error;
13949750e409Sopenharmony_ci        local_error.json = (const unsigned char*)value;
13959750e409Sopenharmony_ci        local_error.position = 0;
13969750e409Sopenharmony_ci
13979750e409Sopenharmony_ci        if (buffer.offset < buffer.length)
13989750e409Sopenharmony_ci        {
13999750e409Sopenharmony_ci            local_error.position = buffer.offset;
14009750e409Sopenharmony_ci        }
14019750e409Sopenharmony_ci        else if (buffer.length > 0)
14029750e409Sopenharmony_ci        {
14039750e409Sopenharmony_ci            local_error.position = buffer.length - 1;
14049750e409Sopenharmony_ci        }
14059750e409Sopenharmony_ci
14069750e409Sopenharmony_ci        if (return_parse_end != NULL)
14079750e409Sopenharmony_ci        {
14089750e409Sopenharmony_ci            *return_parse_end = (const char*)local_error.json + local_error.position;
14099750e409Sopenharmony_ci        }
14109750e409Sopenharmony_ci
14119750e409Sopenharmony_ci        global_error = local_error;
14129750e409Sopenharmony_ci    }
14139750e409Sopenharmony_ci
14149750e409Sopenharmony_ci    return NULL;
14159750e409Sopenharmony_ci}
14169750e409Sopenharmony_ci
14179750e409Sopenharmony_ci/* Default options for cJSON_Parse */
14189750e409Sopenharmony_ciCJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value)
14199750e409Sopenharmony_ci{
14209750e409Sopenharmony_ci    return cJSON_ParseWithOpts(value, 0, 0);
14219750e409Sopenharmony_ci}
14229750e409Sopenharmony_ci
14239750e409Sopenharmony_ciCJSON_PUBLIC(cJSON *) cJSON_ParseWithLength(const char *value, size_t buffer_length)
14249750e409Sopenharmony_ci{
14259750e409Sopenharmony_ci    return cJSON_ParseWithLengthOpts(value, buffer_length, 0, 0);
14269750e409Sopenharmony_ci}
14279750e409Sopenharmony_ci
14289750e409Sopenharmony_ci#define cjson_min(a, b) (((a) < (b)) ? (a) : (b))
14299750e409Sopenharmony_ci
14309750e409Sopenharmony_cistatic unsigned char *print(const cJSON * const item, cJSON_bool format, const internal_hooks * const hooks)
14319750e409Sopenharmony_ci{
14329750e409Sopenharmony_ci    static const size_t default_buffer_size = 256;
14339750e409Sopenharmony_ci    printbuffer buffer[1];
14349750e409Sopenharmony_ci    unsigned char *printed = NULL;
14359750e409Sopenharmony_ci
14369750e409Sopenharmony_ci    memset(buffer, 0, sizeof(buffer));
14379750e409Sopenharmony_ci
14389750e409Sopenharmony_ci    /* create buffer */
14399750e409Sopenharmony_ci    buffer->buffer = (unsigned char*) hooks->allocate(default_buffer_size);
14409750e409Sopenharmony_ci    buffer->length = default_buffer_size;
14419750e409Sopenharmony_ci    buffer->format = format;
14429750e409Sopenharmony_ci    buffer->hooks = *hooks;
14439750e409Sopenharmony_ci    if (buffer->buffer == NULL)
14449750e409Sopenharmony_ci    {
14459750e409Sopenharmony_ci        goto fail;
14469750e409Sopenharmony_ci    }
14479750e409Sopenharmony_ci
14489750e409Sopenharmony_ci    /* print the value */
14499750e409Sopenharmony_ci    if (!print_value(item, buffer))
14509750e409Sopenharmony_ci    {
14519750e409Sopenharmony_ci        goto fail;
14529750e409Sopenharmony_ci    }
14539750e409Sopenharmony_ci    update_offset(buffer);
14549750e409Sopenharmony_ci
14559750e409Sopenharmony_ci    /* check if reallocate is available */
14569750e409Sopenharmony_ci    if (hooks->reallocate != NULL)
14579750e409Sopenharmony_ci    {
14589750e409Sopenharmony_ci        printed = (unsigned char*) hooks->reallocate(buffer->buffer, buffer->offset + 1);
14599750e409Sopenharmony_ci        if (printed == NULL) {
14609750e409Sopenharmony_ci            goto fail;
14619750e409Sopenharmony_ci        }
14629750e409Sopenharmony_ci        buffer->buffer = NULL;
14639750e409Sopenharmony_ci    }
14649750e409Sopenharmony_ci    else /* otherwise copy the JSON over to a new buffer */
14659750e409Sopenharmony_ci    {
14669750e409Sopenharmony_ci        printed = (unsigned char*) hooks->allocate(buffer->offset + 1);
14679750e409Sopenharmony_ci        if (printed == NULL)
14689750e409Sopenharmony_ci        {
14699750e409Sopenharmony_ci            goto fail;
14709750e409Sopenharmony_ci        }
14719750e409Sopenharmony_ci        memcpy(printed, buffer->buffer, cjson_min(buffer->length, buffer->offset + 1));
14729750e409Sopenharmony_ci        printed[buffer->offset] = '\0'; /* just to be sure */
14739750e409Sopenharmony_ci
14749750e409Sopenharmony_ci        /* free the buffer */
14759750e409Sopenharmony_ci        hooks->deallocate(buffer->buffer);
14769750e409Sopenharmony_ci    }
14779750e409Sopenharmony_ci
14789750e409Sopenharmony_ci    return printed;
14799750e409Sopenharmony_ci
14809750e409Sopenharmony_cifail:
14819750e409Sopenharmony_ci    if (buffer->buffer != NULL)
14829750e409Sopenharmony_ci    {
14839750e409Sopenharmony_ci        hooks->deallocate(buffer->buffer);
14849750e409Sopenharmony_ci    }
14859750e409Sopenharmony_ci
14869750e409Sopenharmony_ci    if (printed != NULL)
14879750e409Sopenharmony_ci    {
14889750e409Sopenharmony_ci        hooks->deallocate(printed);
14899750e409Sopenharmony_ci    }
14909750e409Sopenharmony_ci
14919750e409Sopenharmony_ci    return NULL;
14929750e409Sopenharmony_ci}
14939750e409Sopenharmony_ci
14949750e409Sopenharmony_ci/* Render a cJSON item/entity/structure to text. */
14959750e409Sopenharmony_ciCJSON_PUBLIC(char *) cJSON_Print(const cJSON *item)
14969750e409Sopenharmony_ci{
14979750e409Sopenharmony_ci    return (char*)print(item, true, &global_hooks);
14989750e409Sopenharmony_ci}
14999750e409Sopenharmony_ci
15009750e409Sopenharmony_ciCJSON_PUBLIC(char *) cJSON_PrintUnformatted(const cJSON *item)
15019750e409Sopenharmony_ci{
15029750e409Sopenharmony_ci    return (char*)print(item, false, &global_hooks);
15039750e409Sopenharmony_ci}
15049750e409Sopenharmony_ci
15059750e409Sopenharmony_ciCJSON_PUBLIC(char *) cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON_bool fmt)
15069750e409Sopenharmony_ci{
15079750e409Sopenharmony_ci    printbuffer p = { 0, 0, 0, 0, 0, 0, { 0, 0, 0 } };
15089750e409Sopenharmony_ci
15099750e409Sopenharmony_ci    if (prebuffer < 0)
15109750e409Sopenharmony_ci    {
15119750e409Sopenharmony_ci        return NULL;
15129750e409Sopenharmony_ci    }
15139750e409Sopenharmony_ci
15149750e409Sopenharmony_ci    p.buffer = (unsigned char*)global_hooks.allocate((size_t)prebuffer);
15159750e409Sopenharmony_ci    if (!p.buffer)
15169750e409Sopenharmony_ci    {
15179750e409Sopenharmony_ci        return NULL;
15189750e409Sopenharmony_ci    }
15199750e409Sopenharmony_ci
15209750e409Sopenharmony_ci    p.length = (size_t)prebuffer;
15219750e409Sopenharmony_ci    p.offset = 0;
15229750e409Sopenharmony_ci    p.noalloc = false;
15239750e409Sopenharmony_ci    p.format = fmt;
15249750e409Sopenharmony_ci    p.hooks = global_hooks;
15259750e409Sopenharmony_ci
15269750e409Sopenharmony_ci    if (!print_value(item, &p))
15279750e409Sopenharmony_ci    {
15289750e409Sopenharmony_ci        global_hooks.deallocate(p.buffer);
15299750e409Sopenharmony_ci        return NULL;
15309750e409Sopenharmony_ci    }
15319750e409Sopenharmony_ci
15329750e409Sopenharmony_ci    return (char*)p.buffer;
15339750e409Sopenharmony_ci}
15349750e409Sopenharmony_ci
15359750e409Sopenharmony_ciCJSON_PUBLIC(cJSON_bool) cJSON_PrintPreallocated(cJSON *item, char *buffer, const int length, const cJSON_bool format)
15369750e409Sopenharmony_ci{
15379750e409Sopenharmony_ci    printbuffer p = { 0, 0, 0, 0, 0, 0, { 0, 0, 0 } };
15389750e409Sopenharmony_ci
15399750e409Sopenharmony_ci    if ((length < 0) || (buffer == NULL))
15409750e409Sopenharmony_ci    {
15419750e409Sopenharmony_ci        return false;
15429750e409Sopenharmony_ci    }
15439750e409Sopenharmony_ci
15449750e409Sopenharmony_ci    p.buffer = (unsigned char*)buffer;
15459750e409Sopenharmony_ci    p.length = (size_t)length;
15469750e409Sopenharmony_ci    p.offset = 0;
15479750e409Sopenharmony_ci    p.noalloc = true;
15489750e409Sopenharmony_ci    p.format = format;
15499750e409Sopenharmony_ci    p.hooks = global_hooks;
15509750e409Sopenharmony_ci
15519750e409Sopenharmony_ci    return print_value(item, &p);
15529750e409Sopenharmony_ci}
15539750e409Sopenharmony_ci
15549750e409Sopenharmony_ci/* Parser core - when encountering text, process appropriately. */
15559750e409Sopenharmony_cistatic cJSON_bool parse_value(cJSON * const item, parse_buffer * const input_buffer)
15569750e409Sopenharmony_ci{
15579750e409Sopenharmony_ci    if ((input_buffer == NULL) || (input_buffer->content == NULL))
15589750e409Sopenharmony_ci    {
15599750e409Sopenharmony_ci        return false; /* no input */
15609750e409Sopenharmony_ci    }
15619750e409Sopenharmony_ci
15629750e409Sopenharmony_ci    /* parse the different types of values */
15639750e409Sopenharmony_ci    /* null */
15649750e409Sopenharmony_ci    if (can_read(input_buffer, 4) && (strncmp((const char*)buffer_at_offset(input_buffer), "null", 4) == 0))
15659750e409Sopenharmony_ci    {
15669750e409Sopenharmony_ci        item->type = cJSON_NULL;
15679750e409Sopenharmony_ci        input_buffer->offset += 4;
15689750e409Sopenharmony_ci        return true;
15699750e409Sopenharmony_ci    }
15709750e409Sopenharmony_ci    /* false */
15719750e409Sopenharmony_ci    if (can_read(input_buffer, 5) && (strncmp((const char*)buffer_at_offset(input_buffer), "false", 5) == 0))
15729750e409Sopenharmony_ci    {
15739750e409Sopenharmony_ci        item->type = cJSON_False;
15749750e409Sopenharmony_ci        input_buffer->offset += 5;
15759750e409Sopenharmony_ci        return true;
15769750e409Sopenharmony_ci    }
15779750e409Sopenharmony_ci    /* true */
15789750e409Sopenharmony_ci    if (can_read(input_buffer, 4) && (strncmp((const char*)buffer_at_offset(input_buffer), "true", 4) == 0))
15799750e409Sopenharmony_ci    {
15809750e409Sopenharmony_ci        item->type = cJSON_True;
15819750e409Sopenharmony_ci        item->valueint = 1;
15829750e409Sopenharmony_ci        input_buffer->offset += 4;
15839750e409Sopenharmony_ci        return true;
15849750e409Sopenharmony_ci    }
15859750e409Sopenharmony_ci    /* string */
15869750e409Sopenharmony_ci    if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '\"'))
15879750e409Sopenharmony_ci    {
15889750e409Sopenharmony_ci        return parse_string(item, input_buffer);
15899750e409Sopenharmony_ci    }
15909750e409Sopenharmony_ci    /* number */
15919750e409Sopenharmony_ci    if (can_access_at_index(input_buffer, 0) && ((buffer_at_offset(input_buffer)[0] == '-') || ((buffer_at_offset(input_buffer)[0] >= '0') && (buffer_at_offset(input_buffer)[0] <= '9'))))
15929750e409Sopenharmony_ci    {
15939750e409Sopenharmony_ci        return parse_number(item, input_buffer);
15949750e409Sopenharmony_ci    }
15959750e409Sopenharmony_ci    /* array */
15969750e409Sopenharmony_ci    if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '['))
15979750e409Sopenharmony_ci    {
15989750e409Sopenharmony_ci        return parse_array(item, input_buffer);
15999750e409Sopenharmony_ci    }
16009750e409Sopenharmony_ci    /* object */
16019750e409Sopenharmony_ci    if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '{'))
16029750e409Sopenharmony_ci    {
16039750e409Sopenharmony_ci        return parse_object(item, input_buffer);
16049750e409Sopenharmony_ci    }
16059750e409Sopenharmony_ci
16069750e409Sopenharmony_ci    return false;
16079750e409Sopenharmony_ci}
16089750e409Sopenharmony_ci
16099750e409Sopenharmony_ci/* Render a value to text. */
16109750e409Sopenharmony_cistatic cJSON_bool print_value(const cJSON * const item, printbuffer * const output_buffer)
16119750e409Sopenharmony_ci{
16129750e409Sopenharmony_ci    unsigned char *output = NULL;
16139750e409Sopenharmony_ci
16149750e409Sopenharmony_ci    if ((item == NULL) || (output_buffer == NULL))
16159750e409Sopenharmony_ci    {
16169750e409Sopenharmony_ci        return false;
16179750e409Sopenharmony_ci    }
16189750e409Sopenharmony_ci
16199750e409Sopenharmony_ci    switch ((item->type) & 0xFF)
16209750e409Sopenharmony_ci    {
16219750e409Sopenharmony_ci        case cJSON_NULL:
16229750e409Sopenharmony_ci            output = ensure(output_buffer, 5);
16239750e409Sopenharmony_ci            if (output == NULL)
16249750e409Sopenharmony_ci            {
16259750e409Sopenharmony_ci                return false;
16269750e409Sopenharmony_ci            }
16279750e409Sopenharmony_ci            strcpy((char*)output, "null");
16289750e409Sopenharmony_ci            return true;
16299750e409Sopenharmony_ci
16309750e409Sopenharmony_ci        case cJSON_False:
16319750e409Sopenharmony_ci            output = ensure(output_buffer, 6);
16329750e409Sopenharmony_ci            if (output == NULL)
16339750e409Sopenharmony_ci            {
16349750e409Sopenharmony_ci                return false;
16359750e409Sopenharmony_ci            }
16369750e409Sopenharmony_ci            strcpy((char*)output, "false");
16379750e409Sopenharmony_ci            return true;
16389750e409Sopenharmony_ci
16399750e409Sopenharmony_ci        case cJSON_True:
16409750e409Sopenharmony_ci            output = ensure(output_buffer, 5);
16419750e409Sopenharmony_ci            if (output == NULL)
16429750e409Sopenharmony_ci            {
16439750e409Sopenharmony_ci                return false;
16449750e409Sopenharmony_ci            }
16459750e409Sopenharmony_ci            strcpy((char*)output, "true");
16469750e409Sopenharmony_ci            return true;
16479750e409Sopenharmony_ci
16489750e409Sopenharmony_ci        case cJSON_Number:
16499750e409Sopenharmony_ci            return print_number(item, output_buffer);
16509750e409Sopenharmony_ci
16519750e409Sopenharmony_ci        case cJSON_Raw:
16529750e409Sopenharmony_ci        {
16539750e409Sopenharmony_ci            size_t raw_length = 0;
16549750e409Sopenharmony_ci            if (item->valuestring == NULL)
16559750e409Sopenharmony_ci            {
16569750e409Sopenharmony_ci                return false;
16579750e409Sopenharmony_ci            }
16589750e409Sopenharmony_ci
16599750e409Sopenharmony_ci            raw_length = strlen(item->valuestring) + sizeof("");
16609750e409Sopenharmony_ci            output = ensure(output_buffer, raw_length);
16619750e409Sopenharmony_ci            if (output == NULL)
16629750e409Sopenharmony_ci            {
16639750e409Sopenharmony_ci                return false;
16649750e409Sopenharmony_ci            }
16659750e409Sopenharmony_ci            memcpy(output, item->valuestring, raw_length);
16669750e409Sopenharmony_ci            return true;
16679750e409Sopenharmony_ci        }
16689750e409Sopenharmony_ci
16699750e409Sopenharmony_ci        case cJSON_String:
16709750e409Sopenharmony_ci            return print_string(item, output_buffer);
16719750e409Sopenharmony_ci
16729750e409Sopenharmony_ci        case cJSON_Array:
16739750e409Sopenharmony_ci            return print_array(item, output_buffer);
16749750e409Sopenharmony_ci
16759750e409Sopenharmony_ci        case cJSON_Object:
16769750e409Sopenharmony_ci            return print_object(item, output_buffer);
16779750e409Sopenharmony_ci
16789750e409Sopenharmony_ci        default:
16799750e409Sopenharmony_ci            return false;
16809750e409Sopenharmony_ci    }
16819750e409Sopenharmony_ci}
16829750e409Sopenharmony_ci
16839750e409Sopenharmony_ci/* Build an array from input text. */
16849750e409Sopenharmony_cistatic cJSON_bool parse_array(cJSON * const item, parse_buffer * const input_buffer)
16859750e409Sopenharmony_ci{
16869750e409Sopenharmony_ci    cJSON *head = NULL; /* head of the linked list */
16879750e409Sopenharmony_ci    cJSON *current_item = NULL;
16889750e409Sopenharmony_ci
16899750e409Sopenharmony_ci    if (input_buffer->depth >= CJSON_NESTING_LIMIT)
16909750e409Sopenharmony_ci    {
16919750e409Sopenharmony_ci        return false; /* to deeply nested */
16929750e409Sopenharmony_ci    }
16939750e409Sopenharmony_ci    input_buffer->depth++;
16949750e409Sopenharmony_ci
16959750e409Sopenharmony_ci    if (buffer_at_offset(input_buffer)[0] != '[')
16969750e409Sopenharmony_ci    {
16979750e409Sopenharmony_ci        /* not an array */
16989750e409Sopenharmony_ci        goto fail;
16999750e409Sopenharmony_ci    }
17009750e409Sopenharmony_ci
17019750e409Sopenharmony_ci    input_buffer->offset++;
17029750e409Sopenharmony_ci    buffer_skip_whitespace(input_buffer);
17039750e409Sopenharmony_ci    if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == ']'))
17049750e409Sopenharmony_ci    {
17059750e409Sopenharmony_ci        /* empty array */
17069750e409Sopenharmony_ci        goto success;
17079750e409Sopenharmony_ci    }
17089750e409Sopenharmony_ci
17099750e409Sopenharmony_ci    /* check if we skipped to the end of the buffer */
17109750e409Sopenharmony_ci    if (cannot_access_at_index(input_buffer, 0))
17119750e409Sopenharmony_ci    {
17129750e409Sopenharmony_ci        input_buffer->offset--;
17139750e409Sopenharmony_ci        goto fail;
17149750e409Sopenharmony_ci    }
17159750e409Sopenharmony_ci
17169750e409Sopenharmony_ci    /* step back to character in front of the first element */
17179750e409Sopenharmony_ci    input_buffer->offset--;
17189750e409Sopenharmony_ci    /* loop through the comma separated array elements */
17199750e409Sopenharmony_ci    do
17209750e409Sopenharmony_ci    {
17219750e409Sopenharmony_ci        /* allocate next item */
17229750e409Sopenharmony_ci        cJSON *new_item = cJSON_New_Item(&(input_buffer->hooks));
17239750e409Sopenharmony_ci        if (new_item == NULL)
17249750e409Sopenharmony_ci        {
17259750e409Sopenharmony_ci            goto fail; /* allocation failure */
17269750e409Sopenharmony_ci        }
17279750e409Sopenharmony_ci
17289750e409Sopenharmony_ci        /* attach next item to list */
17299750e409Sopenharmony_ci        if (head == NULL)
17309750e409Sopenharmony_ci        {
17319750e409Sopenharmony_ci            /* start the linked list */
17329750e409Sopenharmony_ci            current_item = head = new_item;
17339750e409Sopenharmony_ci        }
17349750e409Sopenharmony_ci        else
17359750e409Sopenharmony_ci        {
17369750e409Sopenharmony_ci            /* add to the end and advance */
17379750e409Sopenharmony_ci            current_item->next = new_item;
17389750e409Sopenharmony_ci            new_item->prev = current_item;
17399750e409Sopenharmony_ci            current_item = new_item;
17409750e409Sopenharmony_ci        }
17419750e409Sopenharmony_ci
17429750e409Sopenharmony_ci        /* parse next value */
17439750e409Sopenharmony_ci        input_buffer->offset++;
17449750e409Sopenharmony_ci        buffer_skip_whitespace(input_buffer);
17459750e409Sopenharmony_ci        if (!parse_value(current_item, input_buffer))
17469750e409Sopenharmony_ci        {
17479750e409Sopenharmony_ci            goto fail; /* failed to parse value */
17489750e409Sopenharmony_ci        }
17499750e409Sopenharmony_ci        buffer_skip_whitespace(input_buffer);
17509750e409Sopenharmony_ci    }
17519750e409Sopenharmony_ci    while (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == ','));
17529750e409Sopenharmony_ci
17539750e409Sopenharmony_ci    if (cannot_access_at_index(input_buffer, 0) || buffer_at_offset(input_buffer)[0] != ']')
17549750e409Sopenharmony_ci    {
17559750e409Sopenharmony_ci        goto fail; /* expected end of array */
17569750e409Sopenharmony_ci    }
17579750e409Sopenharmony_ci
17589750e409Sopenharmony_cisuccess:
17599750e409Sopenharmony_ci    input_buffer->depth--;
17609750e409Sopenharmony_ci
17619750e409Sopenharmony_ci    if (head != NULL) {
17629750e409Sopenharmony_ci        head->prev = current_item;
17639750e409Sopenharmony_ci    }
17649750e409Sopenharmony_ci
17659750e409Sopenharmony_ci    item->type = cJSON_Array;
17669750e409Sopenharmony_ci    item->child = head;
17679750e409Sopenharmony_ci
17689750e409Sopenharmony_ci    input_buffer->offset++;
17699750e409Sopenharmony_ci
17709750e409Sopenharmony_ci    return true;
17719750e409Sopenharmony_ci
17729750e409Sopenharmony_cifail:
17739750e409Sopenharmony_ci    if (head != NULL)
17749750e409Sopenharmony_ci    {
17759750e409Sopenharmony_ci        cJSON_Delete(head);
17769750e409Sopenharmony_ci    }
17779750e409Sopenharmony_ci
17789750e409Sopenharmony_ci    return false;
17799750e409Sopenharmony_ci}
17809750e409Sopenharmony_ci
17819750e409Sopenharmony_ci/* Render an array to text */
17829750e409Sopenharmony_cistatic cJSON_bool print_array(const cJSON * const item, printbuffer * const output_buffer)
17839750e409Sopenharmony_ci{
17849750e409Sopenharmony_ci    unsigned char *output_pointer = NULL;
17859750e409Sopenharmony_ci    size_t length = 0;
17869750e409Sopenharmony_ci    cJSON *current_element = item->child;
17879750e409Sopenharmony_ci
17889750e409Sopenharmony_ci    if (output_buffer == NULL)
17899750e409Sopenharmony_ci    {
17909750e409Sopenharmony_ci        return false;
17919750e409Sopenharmony_ci    }
17929750e409Sopenharmony_ci
17939750e409Sopenharmony_ci    /* Compose the output array. */
17949750e409Sopenharmony_ci    /* opening square bracket */
17959750e409Sopenharmony_ci    output_pointer = ensure(output_buffer, 1);
17969750e409Sopenharmony_ci    if (output_pointer == NULL)
17979750e409Sopenharmony_ci    {
17989750e409Sopenharmony_ci        return false;
17999750e409Sopenharmony_ci    }
18009750e409Sopenharmony_ci
18019750e409Sopenharmony_ci    *output_pointer = '[';
18029750e409Sopenharmony_ci    output_buffer->offset++;
18039750e409Sopenharmony_ci    output_buffer->depth++;
18049750e409Sopenharmony_ci
18059750e409Sopenharmony_ci    while (current_element != NULL)
18069750e409Sopenharmony_ci    {
18079750e409Sopenharmony_ci        if (!print_value(current_element, output_buffer))
18089750e409Sopenharmony_ci        {
18099750e409Sopenharmony_ci            return false;
18109750e409Sopenharmony_ci        }
18119750e409Sopenharmony_ci        update_offset(output_buffer);
18129750e409Sopenharmony_ci        if (current_element->next)
18139750e409Sopenharmony_ci        {
18149750e409Sopenharmony_ci            length = (size_t) (output_buffer->format ? 2 : 1);
18159750e409Sopenharmony_ci            output_pointer = ensure(output_buffer, length + 1);
18169750e409Sopenharmony_ci            if (output_pointer == NULL)
18179750e409Sopenharmony_ci            {
18189750e409Sopenharmony_ci                return false;
18199750e409Sopenharmony_ci            }
18209750e409Sopenharmony_ci            *output_pointer++ = ',';
18219750e409Sopenharmony_ci            if(output_buffer->format)
18229750e409Sopenharmony_ci            {
18239750e409Sopenharmony_ci                *output_pointer++ = ' ';
18249750e409Sopenharmony_ci            }
18259750e409Sopenharmony_ci            *output_pointer = '\0';
18269750e409Sopenharmony_ci            output_buffer->offset += length;
18279750e409Sopenharmony_ci        }
18289750e409Sopenharmony_ci        current_element = current_element->next;
18299750e409Sopenharmony_ci    }
18309750e409Sopenharmony_ci
18319750e409Sopenharmony_ci    output_pointer = ensure(output_buffer, 2);
18329750e409Sopenharmony_ci    if (output_pointer == NULL)
18339750e409Sopenharmony_ci    {
18349750e409Sopenharmony_ci        return false;
18359750e409Sopenharmony_ci    }
18369750e409Sopenharmony_ci    *output_pointer++ = ']';
18379750e409Sopenharmony_ci    *output_pointer = '\0';
18389750e409Sopenharmony_ci    output_buffer->depth--;
18399750e409Sopenharmony_ci
18409750e409Sopenharmony_ci    return true;
18419750e409Sopenharmony_ci}
18429750e409Sopenharmony_ci
18439750e409Sopenharmony_ci/* Build an object from the text. */
18449750e409Sopenharmony_cistatic cJSON_bool parse_object(cJSON * const item, parse_buffer * const input_buffer)
18459750e409Sopenharmony_ci{
18469750e409Sopenharmony_ci    cJSON *head = NULL; /* linked list head */
18479750e409Sopenharmony_ci    cJSON *current_item = NULL;
18489750e409Sopenharmony_ci
18499750e409Sopenharmony_ci    if (input_buffer->depth >= CJSON_NESTING_LIMIT)
18509750e409Sopenharmony_ci    {
18519750e409Sopenharmony_ci        return false; /* to deeply nested */
18529750e409Sopenharmony_ci    }
18539750e409Sopenharmony_ci    input_buffer->depth++;
18549750e409Sopenharmony_ci
18559750e409Sopenharmony_ci    if (cannot_access_at_index(input_buffer, 0) || (buffer_at_offset(input_buffer)[0] != '{'))
18569750e409Sopenharmony_ci    {
18579750e409Sopenharmony_ci        goto fail; /* not an object */
18589750e409Sopenharmony_ci    }
18599750e409Sopenharmony_ci
18609750e409Sopenharmony_ci    input_buffer->offset++;
18619750e409Sopenharmony_ci    buffer_skip_whitespace(input_buffer);
18629750e409Sopenharmony_ci    if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '}'))
18639750e409Sopenharmony_ci    {
18649750e409Sopenharmony_ci        goto success; /* empty object */
18659750e409Sopenharmony_ci    }
18669750e409Sopenharmony_ci
18679750e409Sopenharmony_ci    /* check if we skipped to the end of the buffer */
18689750e409Sopenharmony_ci    if (cannot_access_at_index(input_buffer, 0))
18699750e409Sopenharmony_ci    {
18709750e409Sopenharmony_ci        input_buffer->offset--;
18719750e409Sopenharmony_ci        goto fail;
18729750e409Sopenharmony_ci    }
18739750e409Sopenharmony_ci
18749750e409Sopenharmony_ci    /* step back to character in front of the first element */
18759750e409Sopenharmony_ci    input_buffer->offset--;
18769750e409Sopenharmony_ci    /* loop through the comma separated array elements */
18779750e409Sopenharmony_ci    do
18789750e409Sopenharmony_ci    {
18799750e409Sopenharmony_ci        /* allocate next item */
18809750e409Sopenharmony_ci        cJSON *new_item = cJSON_New_Item(&(input_buffer->hooks));
18819750e409Sopenharmony_ci        if (new_item == NULL)
18829750e409Sopenharmony_ci        {
18839750e409Sopenharmony_ci            goto fail; /* allocation failure */
18849750e409Sopenharmony_ci        }
18859750e409Sopenharmony_ci
18869750e409Sopenharmony_ci        /* attach next item to list */
18879750e409Sopenharmony_ci        if (head == NULL)
18889750e409Sopenharmony_ci        {
18899750e409Sopenharmony_ci            /* start the linked list */
18909750e409Sopenharmony_ci            current_item = head = new_item;
18919750e409Sopenharmony_ci        }
18929750e409Sopenharmony_ci        else
18939750e409Sopenharmony_ci        {
18949750e409Sopenharmony_ci            /* add to the end and advance */
18959750e409Sopenharmony_ci            current_item->next = new_item;
18969750e409Sopenharmony_ci            new_item->prev = current_item;
18979750e409Sopenharmony_ci            current_item = new_item;
18989750e409Sopenharmony_ci        }
18999750e409Sopenharmony_ci
19009750e409Sopenharmony_ci        if (cannot_access_at_index(input_buffer, 1))
19019750e409Sopenharmony_ci        {
19029750e409Sopenharmony_ci            goto fail; /* nothing comes after the comma */
19039750e409Sopenharmony_ci        }
19049750e409Sopenharmony_ci
19059750e409Sopenharmony_ci        /* parse the name of the child */
19069750e409Sopenharmony_ci        input_buffer->offset++;
19079750e409Sopenharmony_ci        buffer_skip_whitespace(input_buffer);
19089750e409Sopenharmony_ci        if (!parse_string(current_item, input_buffer))
19099750e409Sopenharmony_ci        {
19109750e409Sopenharmony_ci            goto fail; /* failed to parse name */
19119750e409Sopenharmony_ci        }
19129750e409Sopenharmony_ci        buffer_skip_whitespace(input_buffer);
19139750e409Sopenharmony_ci
19149750e409Sopenharmony_ci        /* swap valuestring and string, because we parsed the name */
19159750e409Sopenharmony_ci        current_item->string = current_item->valuestring;
19169750e409Sopenharmony_ci        current_item->valuestring = NULL;
19179750e409Sopenharmony_ci
19189750e409Sopenharmony_ci        if (cannot_access_at_index(input_buffer, 0) || (buffer_at_offset(input_buffer)[0] != ':'))
19199750e409Sopenharmony_ci        {
19209750e409Sopenharmony_ci            goto fail; /* invalid object */
19219750e409Sopenharmony_ci        }
19229750e409Sopenharmony_ci
19239750e409Sopenharmony_ci        /* parse the value */
19249750e409Sopenharmony_ci        input_buffer->offset++;
19259750e409Sopenharmony_ci        buffer_skip_whitespace(input_buffer);
19269750e409Sopenharmony_ci        if (!parse_value(current_item, input_buffer))
19279750e409Sopenharmony_ci        {
19289750e409Sopenharmony_ci            goto fail; /* failed to parse value */
19299750e409Sopenharmony_ci        }
19309750e409Sopenharmony_ci        buffer_skip_whitespace(input_buffer);
19319750e409Sopenharmony_ci    }
19329750e409Sopenharmony_ci    while (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == ','));
19339750e409Sopenharmony_ci
19349750e409Sopenharmony_ci    if (cannot_access_at_index(input_buffer, 0) || (buffer_at_offset(input_buffer)[0] != '}'))
19359750e409Sopenharmony_ci    {
19369750e409Sopenharmony_ci        goto fail; /* expected end of object */
19379750e409Sopenharmony_ci    }
19389750e409Sopenharmony_ci
19399750e409Sopenharmony_cisuccess:
19409750e409Sopenharmony_ci    input_buffer->depth--;
19419750e409Sopenharmony_ci
19429750e409Sopenharmony_ci    if (head != NULL) {
19439750e409Sopenharmony_ci        head->prev = current_item;
19449750e409Sopenharmony_ci    }
19459750e409Sopenharmony_ci
19469750e409Sopenharmony_ci    item->type = cJSON_Object;
19479750e409Sopenharmony_ci    item->child = head;
19489750e409Sopenharmony_ci
19499750e409Sopenharmony_ci    input_buffer->offset++;
19509750e409Sopenharmony_ci    return true;
19519750e409Sopenharmony_ci
19529750e409Sopenharmony_cifail:
19539750e409Sopenharmony_ci    if (head != NULL)
19549750e409Sopenharmony_ci    {
19559750e409Sopenharmony_ci        cJSON_Delete(head);
19569750e409Sopenharmony_ci    }
19579750e409Sopenharmony_ci
19589750e409Sopenharmony_ci    return false;
19599750e409Sopenharmony_ci}
19609750e409Sopenharmony_ci
19619750e409Sopenharmony_ci/* Render an object to text. */
19629750e409Sopenharmony_cistatic cJSON_bool print_object(const cJSON * const item, printbuffer * const output_buffer)
19639750e409Sopenharmony_ci{
19649750e409Sopenharmony_ci    unsigned char *output_pointer = NULL;
19659750e409Sopenharmony_ci    size_t length = 0;
19669750e409Sopenharmony_ci    cJSON *current_item = item->child;
19679750e409Sopenharmony_ci
19689750e409Sopenharmony_ci    if (output_buffer == NULL)
19699750e409Sopenharmony_ci    {
19709750e409Sopenharmony_ci        return false;
19719750e409Sopenharmony_ci    }
19729750e409Sopenharmony_ci
19739750e409Sopenharmony_ci    /* Compose the output: */
19749750e409Sopenharmony_ci    length = (size_t) (output_buffer->format ? 2 : 1); /* fmt: {\n */
19759750e409Sopenharmony_ci    output_pointer = ensure(output_buffer, length + 1);
19769750e409Sopenharmony_ci    if (output_pointer == NULL)
19779750e409Sopenharmony_ci    {
19789750e409Sopenharmony_ci        return false;
19799750e409Sopenharmony_ci    }
19809750e409Sopenharmony_ci
19819750e409Sopenharmony_ci    *output_pointer++ = '{';
19829750e409Sopenharmony_ci    output_buffer->depth++;
19839750e409Sopenharmony_ci    if (output_buffer->format)
19849750e409Sopenharmony_ci    {
19859750e409Sopenharmony_ci        *output_pointer++ = '\n';
19869750e409Sopenharmony_ci    }
19879750e409Sopenharmony_ci    output_buffer->offset += length;
19889750e409Sopenharmony_ci
19899750e409Sopenharmony_ci    while (current_item)
19909750e409Sopenharmony_ci    {
19919750e409Sopenharmony_ci        if (output_buffer->format)
19929750e409Sopenharmony_ci        {
19939750e409Sopenharmony_ci            size_t i;
19949750e409Sopenharmony_ci            output_pointer = ensure(output_buffer, output_buffer->depth);
19959750e409Sopenharmony_ci            if (output_pointer == NULL)
19969750e409Sopenharmony_ci            {
19979750e409Sopenharmony_ci                return false;
19989750e409Sopenharmony_ci            }
19999750e409Sopenharmony_ci            for (i = 0; i < output_buffer->depth; i++)
20009750e409Sopenharmony_ci            {
20019750e409Sopenharmony_ci                *output_pointer++ = '\t';
20029750e409Sopenharmony_ci            }
20039750e409Sopenharmony_ci            output_buffer->offset += output_buffer->depth;
20049750e409Sopenharmony_ci        }
20059750e409Sopenharmony_ci
20069750e409Sopenharmony_ci        /* print key */
20079750e409Sopenharmony_ci        if (!print_string_ptr((unsigned char*)current_item->string, output_buffer))
20089750e409Sopenharmony_ci        {
20099750e409Sopenharmony_ci            return false;
20109750e409Sopenharmony_ci        }
20119750e409Sopenharmony_ci        update_offset(output_buffer);
20129750e409Sopenharmony_ci
20139750e409Sopenharmony_ci        length = (size_t) (output_buffer->format ? 2 : 1);
20149750e409Sopenharmony_ci        output_pointer = ensure(output_buffer, length);
20159750e409Sopenharmony_ci        if (output_pointer == NULL)
20169750e409Sopenharmony_ci        {
20179750e409Sopenharmony_ci            return false;
20189750e409Sopenharmony_ci        }
20199750e409Sopenharmony_ci        *output_pointer++ = ':';
20209750e409Sopenharmony_ci        if (output_buffer->format)
20219750e409Sopenharmony_ci        {
20229750e409Sopenharmony_ci            *output_pointer++ = '\t';
20239750e409Sopenharmony_ci        }
20249750e409Sopenharmony_ci        output_buffer->offset += length;
20259750e409Sopenharmony_ci
20269750e409Sopenharmony_ci        /* print value */
20279750e409Sopenharmony_ci        if (!print_value(current_item, output_buffer))
20289750e409Sopenharmony_ci        {
20299750e409Sopenharmony_ci            return false;
20309750e409Sopenharmony_ci        }
20319750e409Sopenharmony_ci        update_offset(output_buffer);
20329750e409Sopenharmony_ci
20339750e409Sopenharmony_ci        /* print comma if not last */
20349750e409Sopenharmony_ci        length = ((size_t)(output_buffer->format ? 1 : 0) + (size_t)(current_item->next ? 1 : 0));
20359750e409Sopenharmony_ci        output_pointer = ensure(output_buffer, length + 1);
20369750e409Sopenharmony_ci        if (output_pointer == NULL)
20379750e409Sopenharmony_ci        {
20389750e409Sopenharmony_ci            return false;
20399750e409Sopenharmony_ci        }
20409750e409Sopenharmony_ci        if (current_item->next)
20419750e409Sopenharmony_ci        {
20429750e409Sopenharmony_ci            *output_pointer++ = ',';
20439750e409Sopenharmony_ci        }
20449750e409Sopenharmony_ci
20459750e409Sopenharmony_ci        if (output_buffer->format)
20469750e409Sopenharmony_ci        {
20479750e409Sopenharmony_ci            *output_pointer++ = '\n';
20489750e409Sopenharmony_ci        }
20499750e409Sopenharmony_ci        *output_pointer = '\0';
20509750e409Sopenharmony_ci        output_buffer->offset += length;
20519750e409Sopenharmony_ci
20529750e409Sopenharmony_ci        current_item = current_item->next;
20539750e409Sopenharmony_ci    }
20549750e409Sopenharmony_ci
20559750e409Sopenharmony_ci    output_pointer = ensure(output_buffer, output_buffer->format ? (output_buffer->depth + 1) : 2);
20569750e409Sopenharmony_ci    if (output_pointer == NULL)
20579750e409Sopenharmony_ci    {
20589750e409Sopenharmony_ci        return false;
20599750e409Sopenharmony_ci    }
20609750e409Sopenharmony_ci    if (output_buffer->format)
20619750e409Sopenharmony_ci    {
20629750e409Sopenharmony_ci        size_t i;
20639750e409Sopenharmony_ci        for (i = 0; i < (output_buffer->depth - 1); i++)
20649750e409Sopenharmony_ci        {
20659750e409Sopenharmony_ci            *output_pointer++ = '\t';
20669750e409Sopenharmony_ci        }
20679750e409Sopenharmony_ci    }
20689750e409Sopenharmony_ci    *output_pointer++ = '}';
20699750e409Sopenharmony_ci    *output_pointer = '\0';
20709750e409Sopenharmony_ci    output_buffer->depth--;
20719750e409Sopenharmony_ci
20729750e409Sopenharmony_ci    return true;
20739750e409Sopenharmony_ci}
20749750e409Sopenharmony_ci
20759750e409Sopenharmony_ci/* Get Array size/item / object item. */
20769750e409Sopenharmony_ciCJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array)
20779750e409Sopenharmony_ci{
20789750e409Sopenharmony_ci    cJSON *child = NULL;
20799750e409Sopenharmony_ci    size_t size = 0;
20809750e409Sopenharmony_ci
20819750e409Sopenharmony_ci    if (array == NULL)
20829750e409Sopenharmony_ci    {
20839750e409Sopenharmony_ci        return 0;
20849750e409Sopenharmony_ci    }
20859750e409Sopenharmony_ci
20869750e409Sopenharmony_ci    child = array->child;
20879750e409Sopenharmony_ci
20889750e409Sopenharmony_ci    while(child != NULL)
20899750e409Sopenharmony_ci    {
20909750e409Sopenharmony_ci        size++;
20919750e409Sopenharmony_ci        child = child->next;
20929750e409Sopenharmony_ci    }
20939750e409Sopenharmony_ci
20949750e409Sopenharmony_ci    /* FIXME: Can overflow here. Cannot be fixed without breaking the API */
20959750e409Sopenharmony_ci
20969750e409Sopenharmony_ci    return (int)size;
20979750e409Sopenharmony_ci}
20989750e409Sopenharmony_ci
20999750e409Sopenharmony_cistatic cJSON* get_array_item(const cJSON *array, size_t index)
21009750e409Sopenharmony_ci{
21019750e409Sopenharmony_ci    cJSON *current_child = NULL;
21029750e409Sopenharmony_ci
21039750e409Sopenharmony_ci    if (array == NULL)
21049750e409Sopenharmony_ci    {
21059750e409Sopenharmony_ci        return NULL;
21069750e409Sopenharmony_ci    }
21079750e409Sopenharmony_ci
21089750e409Sopenharmony_ci    current_child = array->child;
21099750e409Sopenharmony_ci    while ((current_child != NULL) && (index > 0))
21109750e409Sopenharmony_ci    {
21119750e409Sopenharmony_ci        index--;
21129750e409Sopenharmony_ci        current_child = current_child->next;
21139750e409Sopenharmony_ci    }
21149750e409Sopenharmony_ci
21159750e409Sopenharmony_ci    return current_child;
21169750e409Sopenharmony_ci}
21179750e409Sopenharmony_ci
21189750e409Sopenharmony_ciCJSON_PUBLIC(cJSON *) cJSON_GetArrayItem(const cJSON *array, int index)
21199750e409Sopenharmony_ci{
21209750e409Sopenharmony_ci    if (index < 0)
21219750e409Sopenharmony_ci    {
21229750e409Sopenharmony_ci        return NULL;
21239750e409Sopenharmony_ci    }
21249750e409Sopenharmony_ci
21259750e409Sopenharmony_ci    return get_array_item(array, (size_t)index);
21269750e409Sopenharmony_ci}
21279750e409Sopenharmony_ci
21289750e409Sopenharmony_cistatic cJSON *get_object_item(const cJSON * const object, const char * const name, const cJSON_bool case_sensitive)
21299750e409Sopenharmony_ci{
21309750e409Sopenharmony_ci    cJSON *current_element = NULL;
21319750e409Sopenharmony_ci
21329750e409Sopenharmony_ci    if ((object == NULL) || (name == NULL))
21339750e409Sopenharmony_ci    {
21349750e409Sopenharmony_ci        return NULL;
21359750e409Sopenharmony_ci    }
21369750e409Sopenharmony_ci
21379750e409Sopenharmony_ci    current_element = object->child;
21389750e409Sopenharmony_ci    if (case_sensitive)
21399750e409Sopenharmony_ci    {
21409750e409Sopenharmony_ci        while ((current_element != NULL) && (current_element->string != NULL) && (strcmp(name, current_element->string) != 0))
21419750e409Sopenharmony_ci        {
21429750e409Sopenharmony_ci            current_element = current_element->next;
21439750e409Sopenharmony_ci        }
21449750e409Sopenharmony_ci    }
21459750e409Sopenharmony_ci    else
21469750e409Sopenharmony_ci    {
21479750e409Sopenharmony_ci        while ((current_element != NULL) && (case_insensitive_strcmp((const unsigned char*)name, (const unsigned char*)(current_element->string)) != 0))
21489750e409Sopenharmony_ci        {
21499750e409Sopenharmony_ci            current_element = current_element->next;
21509750e409Sopenharmony_ci        }
21519750e409Sopenharmony_ci    }
21529750e409Sopenharmony_ci
21539750e409Sopenharmony_ci    if ((current_element == NULL) || (current_element->string == NULL)) {
21549750e409Sopenharmony_ci        return NULL;
21559750e409Sopenharmony_ci    }
21569750e409Sopenharmony_ci
21579750e409Sopenharmony_ci    return current_element;
21589750e409Sopenharmony_ci}
21599750e409Sopenharmony_ci
21609750e409Sopenharmony_ciCJSON_PUBLIC(cJSON *) cJSON_GetObjectItem(const cJSON * const object, const char * const string)
21619750e409Sopenharmony_ci{
21629750e409Sopenharmony_ci    return get_object_item(object, string, false);
21639750e409Sopenharmony_ci}
21649750e409Sopenharmony_ci
21659750e409Sopenharmony_ciCJSON_PUBLIC(cJSON *) cJSON_GetObjectItemCaseSensitive(const cJSON * const object, const char * const string)
21669750e409Sopenharmony_ci{
21679750e409Sopenharmony_ci    return get_object_item(object, string, true);
21689750e409Sopenharmony_ci}
21699750e409Sopenharmony_ci
21709750e409Sopenharmony_ciCJSON_PUBLIC(cJSON_bool) cJSON_HasObjectItem(const cJSON *object, const char *string)
21719750e409Sopenharmony_ci{
21729750e409Sopenharmony_ci    return cJSON_GetObjectItem(object, string) ? 1 : 0;
21739750e409Sopenharmony_ci}
21749750e409Sopenharmony_ci
21759750e409Sopenharmony_ci/* Utility for array list handling. */
21769750e409Sopenharmony_cistatic void suffix_object(cJSON *prev, cJSON *item)
21779750e409Sopenharmony_ci{
21789750e409Sopenharmony_ci    prev->next = item;
21799750e409Sopenharmony_ci    item->prev = prev;
21809750e409Sopenharmony_ci}
21819750e409Sopenharmony_ci
21829750e409Sopenharmony_ci/* Utility for handling references. */
21839750e409Sopenharmony_cistatic cJSON *create_reference(const cJSON *item, const internal_hooks * const hooks)
21849750e409Sopenharmony_ci{
21859750e409Sopenharmony_ci    cJSON *reference = NULL;
21869750e409Sopenharmony_ci    if (item == NULL)
21879750e409Sopenharmony_ci    {
21889750e409Sopenharmony_ci        return NULL;
21899750e409Sopenharmony_ci    }
21909750e409Sopenharmony_ci
21919750e409Sopenharmony_ci    reference = cJSON_New_Item(hooks);
21929750e409Sopenharmony_ci    if (reference == NULL)
21939750e409Sopenharmony_ci    {
21949750e409Sopenharmony_ci        return NULL;
21959750e409Sopenharmony_ci    }
21969750e409Sopenharmony_ci
21979750e409Sopenharmony_ci    memcpy(reference, item, sizeof(cJSON));
21989750e409Sopenharmony_ci    reference->string = NULL;
21999750e409Sopenharmony_ci    reference->type |= cJSON_IsReference;
22009750e409Sopenharmony_ci    reference->next = reference->prev = NULL;
22019750e409Sopenharmony_ci    return reference;
22029750e409Sopenharmony_ci}
22039750e409Sopenharmony_ci
22049750e409Sopenharmony_cistatic cJSON_bool add_item_to_array(cJSON *array, cJSON *item)
22059750e409Sopenharmony_ci{
22069750e409Sopenharmony_ci    cJSON *child = NULL;
22079750e409Sopenharmony_ci
22089750e409Sopenharmony_ci    if ((item == NULL) || (array == NULL) || (array == item))
22099750e409Sopenharmony_ci    {
22109750e409Sopenharmony_ci        return false;
22119750e409Sopenharmony_ci    }
22129750e409Sopenharmony_ci
22139750e409Sopenharmony_ci    child = array->child;
22149750e409Sopenharmony_ci    /*
22159750e409Sopenharmony_ci     * To find the last item in array quickly, we use prev in array
22169750e409Sopenharmony_ci     */
22179750e409Sopenharmony_ci    if (child == NULL)
22189750e409Sopenharmony_ci    {
22199750e409Sopenharmony_ci        /* list is empty, start new one */
22209750e409Sopenharmony_ci        array->child = item;
22219750e409Sopenharmony_ci        item->prev = item;
22229750e409Sopenharmony_ci        item->next = NULL;
22239750e409Sopenharmony_ci    }
22249750e409Sopenharmony_ci    else
22259750e409Sopenharmony_ci    {
22269750e409Sopenharmony_ci        /* append to the end */
22279750e409Sopenharmony_ci        if (child->prev)
22289750e409Sopenharmony_ci        {
22299750e409Sopenharmony_ci            suffix_object(child->prev, item);
22309750e409Sopenharmony_ci            array->child->prev = item;
22319750e409Sopenharmony_ci        }
22329750e409Sopenharmony_ci    }
22339750e409Sopenharmony_ci
22349750e409Sopenharmony_ci    return true;
22359750e409Sopenharmony_ci}
22369750e409Sopenharmony_ci
22379750e409Sopenharmony_ci/* Add item to array/object. */
22389750e409Sopenharmony_ciCJSON_PUBLIC(cJSON_bool) cJSON_AddItemToArray(cJSON *array, cJSON *item)
22399750e409Sopenharmony_ci{
22409750e409Sopenharmony_ci    return add_item_to_array(array, item);
22419750e409Sopenharmony_ci}
22429750e409Sopenharmony_ci
22439750e409Sopenharmony_ci#if defined(__clang__) || (defined(__GNUC__)  && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 5))))
22449750e409Sopenharmony_ci    #pragma GCC diagnostic push
22459750e409Sopenharmony_ci#endif
22469750e409Sopenharmony_ci#ifdef __GNUC__
22479750e409Sopenharmony_ci#pragma GCC diagnostic ignored "-Wcast-qual"
22489750e409Sopenharmony_ci#endif
22499750e409Sopenharmony_ci/* helper function to cast away const */
22509750e409Sopenharmony_cistatic void* cast_away_const(const void* string)
22519750e409Sopenharmony_ci{
22529750e409Sopenharmony_ci    return (void*)string;
22539750e409Sopenharmony_ci}
22549750e409Sopenharmony_ci#if defined(__clang__) || (defined(__GNUC__)  && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 5))))
22559750e409Sopenharmony_ci    #pragma GCC diagnostic pop
22569750e409Sopenharmony_ci#endif
22579750e409Sopenharmony_ci
22589750e409Sopenharmony_ci
22599750e409Sopenharmony_cistatic cJSON_bool add_item_to_object(cJSON * const object, const char * const string, cJSON * const item, const internal_hooks * const hooks, const cJSON_bool constant_key)
22609750e409Sopenharmony_ci{
22619750e409Sopenharmony_ci    char *new_key = NULL;
22629750e409Sopenharmony_ci    int new_type = cJSON_Invalid;
22639750e409Sopenharmony_ci
22649750e409Sopenharmony_ci    if ((object == NULL) || (string == NULL) || (item == NULL) || (object == item))
22659750e409Sopenharmony_ci    {
22669750e409Sopenharmony_ci        return false;
22679750e409Sopenharmony_ci    }
22689750e409Sopenharmony_ci
22699750e409Sopenharmony_ci    if (constant_key)
22709750e409Sopenharmony_ci    {
22719750e409Sopenharmony_ci        new_key = (char*)cast_away_const(string);
22729750e409Sopenharmony_ci        new_type = item->type | cJSON_StringIsConst;
22739750e409Sopenharmony_ci    }
22749750e409Sopenharmony_ci    else
22759750e409Sopenharmony_ci    {
22769750e409Sopenharmony_ci        new_key = (char*)cJSON_strdup((const unsigned char*)string, hooks);
22779750e409Sopenharmony_ci        if (new_key == NULL)
22789750e409Sopenharmony_ci        {
22799750e409Sopenharmony_ci            return false;
22809750e409Sopenharmony_ci        }
22819750e409Sopenharmony_ci
22829750e409Sopenharmony_ci        new_type = item->type & ~cJSON_StringIsConst;
22839750e409Sopenharmony_ci    }
22849750e409Sopenharmony_ci
22859750e409Sopenharmony_ci    if (!(item->type & cJSON_StringIsConst) && (item->string != NULL))
22869750e409Sopenharmony_ci    {
22879750e409Sopenharmony_ci        hooks->deallocate(item->string);
22889750e409Sopenharmony_ci    }
22899750e409Sopenharmony_ci
22909750e409Sopenharmony_ci    item->string = new_key;
22919750e409Sopenharmony_ci    item->type = new_type;
22929750e409Sopenharmony_ci
22939750e409Sopenharmony_ci    return add_item_to_array(object, item);
22949750e409Sopenharmony_ci}
22959750e409Sopenharmony_ci
22969750e409Sopenharmony_ciCJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item)
22979750e409Sopenharmony_ci{
22989750e409Sopenharmony_ci    return add_item_to_object(object, string, item, &global_hooks, false);
22999750e409Sopenharmony_ci}
23009750e409Sopenharmony_ci
23019750e409Sopenharmony_ci/* Add an item to an object with constant string as key */
23029750e409Sopenharmony_ciCJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item)
23039750e409Sopenharmony_ci{
23049750e409Sopenharmony_ci    return add_item_to_object(object, string, item, &global_hooks, true);
23059750e409Sopenharmony_ci}
23069750e409Sopenharmony_ci
23079750e409Sopenharmony_ciCJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item)
23089750e409Sopenharmony_ci{
23099750e409Sopenharmony_ci    if (array == NULL)
23109750e409Sopenharmony_ci    {
23119750e409Sopenharmony_ci        return false;
23129750e409Sopenharmony_ci    }
23139750e409Sopenharmony_ci
23149750e409Sopenharmony_ci    return add_item_to_array(array, create_reference(item, &global_hooks));
23159750e409Sopenharmony_ci}
23169750e409Sopenharmony_ci
23179750e409Sopenharmony_ciCJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item)
23189750e409Sopenharmony_ci{
23199750e409Sopenharmony_ci    if ((object == NULL) || (string == NULL))
23209750e409Sopenharmony_ci    {
23219750e409Sopenharmony_ci        return false;
23229750e409Sopenharmony_ci    }
23239750e409Sopenharmony_ci
23249750e409Sopenharmony_ci    return add_item_to_object(object, string, create_reference(item, &global_hooks), &global_hooks, false);
23259750e409Sopenharmony_ci}
23269750e409Sopenharmony_ci
23279750e409Sopenharmony_ciCJSON_PUBLIC(cJSON*) cJSON_AddNullToObject(cJSON * const object, const char * const name)
23289750e409Sopenharmony_ci{
23299750e409Sopenharmony_ci    cJSON *null = cJSON_CreateNull();
23309750e409Sopenharmony_ci    if (add_item_to_object(object, name, null, &global_hooks, false))
23319750e409Sopenharmony_ci    {
23329750e409Sopenharmony_ci        return null;
23339750e409Sopenharmony_ci    }
23349750e409Sopenharmony_ci
23359750e409Sopenharmony_ci    cJSON_Delete(null);
23369750e409Sopenharmony_ci    return NULL;
23379750e409Sopenharmony_ci}
23389750e409Sopenharmony_ci
23399750e409Sopenharmony_ciCJSON_PUBLIC(cJSON*) cJSON_AddTrueToObject(cJSON * const object, const char * const name)
23409750e409Sopenharmony_ci{
23419750e409Sopenharmony_ci    cJSON *true_item = cJSON_CreateTrue();
23429750e409Sopenharmony_ci    if (add_item_to_object(object, name, true_item, &global_hooks, false))
23439750e409Sopenharmony_ci    {
23449750e409Sopenharmony_ci        return true_item;
23459750e409Sopenharmony_ci    }
23469750e409Sopenharmony_ci
23479750e409Sopenharmony_ci    cJSON_Delete(true_item);
23489750e409Sopenharmony_ci    return NULL;
23499750e409Sopenharmony_ci}
23509750e409Sopenharmony_ci
23519750e409Sopenharmony_ciCJSON_PUBLIC(cJSON*) cJSON_AddFalseToObject(cJSON * const object, const char * const name)
23529750e409Sopenharmony_ci{
23539750e409Sopenharmony_ci    cJSON *false_item = cJSON_CreateFalse();
23549750e409Sopenharmony_ci    if (add_item_to_object(object, name, false_item, &global_hooks, false))
23559750e409Sopenharmony_ci    {
23569750e409Sopenharmony_ci        return false_item;
23579750e409Sopenharmony_ci    }
23589750e409Sopenharmony_ci
23599750e409Sopenharmony_ci    cJSON_Delete(false_item);
23609750e409Sopenharmony_ci    return NULL;
23619750e409Sopenharmony_ci}
23629750e409Sopenharmony_ci
23639750e409Sopenharmony_ciCJSON_PUBLIC(cJSON*) cJSON_AddBoolToObject(cJSON * const object, const char * const name, const cJSON_bool boolean)
23649750e409Sopenharmony_ci{
23659750e409Sopenharmony_ci    cJSON *bool_item = cJSON_CreateBool(boolean);
23669750e409Sopenharmony_ci    if (add_item_to_object(object, name, bool_item, &global_hooks, false))
23679750e409Sopenharmony_ci    {
23689750e409Sopenharmony_ci        return bool_item;
23699750e409Sopenharmony_ci    }
23709750e409Sopenharmony_ci
23719750e409Sopenharmony_ci    cJSON_Delete(bool_item);
23729750e409Sopenharmony_ci    return NULL;
23739750e409Sopenharmony_ci}
23749750e409Sopenharmony_ci
23759750e409Sopenharmony_ci#ifdef __CJSON_USE_INT64
23769750e409Sopenharmony_ciCJSON_PUBLIC(cJSON*) cJSON_AddInt64NumberToObject(cJSON * const object, const char * const name, const long long integer)
23779750e409Sopenharmony_ci{
23789750e409Sopenharmony_ci    cJSON *int_item = cJSON_CreateInt64Number(integer);
23799750e409Sopenharmony_ci    if (add_item_to_object(object, name, int_item, &global_hooks, false))
23809750e409Sopenharmony_ci    {
23819750e409Sopenharmony_ci        return int_item;
23829750e409Sopenharmony_ci    }
23839750e409Sopenharmony_ci
23849750e409Sopenharmony_ci    cJSON_Delete(int_item);
23859750e409Sopenharmony_ci    return NULL;
23869750e409Sopenharmony_ci}
23879750e409Sopenharmony_ci#endif /* __CJSON_USE_INT64 */
23889750e409Sopenharmony_ci
23899750e409Sopenharmony_ciCJSON_PUBLIC(cJSON*) cJSON_AddNumberToObject(cJSON * const object, const char * const name, const double number)
23909750e409Sopenharmony_ci{
23919750e409Sopenharmony_ci    cJSON *number_item = cJSON_CreateNumber(number);
23929750e409Sopenharmony_ci    if (add_item_to_object(object, name, number_item, &global_hooks, false))
23939750e409Sopenharmony_ci    {
23949750e409Sopenharmony_ci        return number_item;
23959750e409Sopenharmony_ci    }
23969750e409Sopenharmony_ci
23979750e409Sopenharmony_ci    cJSON_Delete(number_item);
23989750e409Sopenharmony_ci    return NULL;
23999750e409Sopenharmony_ci}
24009750e409Sopenharmony_ci
24019750e409Sopenharmony_ciCJSON_PUBLIC(cJSON*) cJSON_AddStringToObject(cJSON * const object, const char * const name, const char * const string)
24029750e409Sopenharmony_ci{
24039750e409Sopenharmony_ci    cJSON *string_item = cJSON_CreateString(string);
24049750e409Sopenharmony_ci    if (add_item_to_object(object, name, string_item, &global_hooks, false))
24059750e409Sopenharmony_ci    {
24069750e409Sopenharmony_ci        return string_item;
24079750e409Sopenharmony_ci    }
24089750e409Sopenharmony_ci
24099750e409Sopenharmony_ci    cJSON_Delete(string_item);
24109750e409Sopenharmony_ci    return NULL;
24119750e409Sopenharmony_ci}
24129750e409Sopenharmony_ci
24139750e409Sopenharmony_ciCJSON_PUBLIC(cJSON*) cJSON_AddRawToObject(cJSON * const object, const char * const name, const char * const raw)
24149750e409Sopenharmony_ci{
24159750e409Sopenharmony_ci    cJSON *raw_item = cJSON_CreateRaw(raw);
24169750e409Sopenharmony_ci    if (add_item_to_object(object, name, raw_item, &global_hooks, false))
24179750e409Sopenharmony_ci    {
24189750e409Sopenharmony_ci        return raw_item;
24199750e409Sopenharmony_ci    }
24209750e409Sopenharmony_ci
24219750e409Sopenharmony_ci    cJSON_Delete(raw_item);
24229750e409Sopenharmony_ci    return NULL;
24239750e409Sopenharmony_ci}
24249750e409Sopenharmony_ci
24259750e409Sopenharmony_ciCJSON_PUBLIC(cJSON*) cJSON_AddObjectToObject(cJSON * const object, const char * const name)
24269750e409Sopenharmony_ci{
24279750e409Sopenharmony_ci    cJSON *object_item = cJSON_CreateObject();
24289750e409Sopenharmony_ci    if (add_item_to_object(object, name, object_item, &global_hooks, false))
24299750e409Sopenharmony_ci    {
24309750e409Sopenharmony_ci        return object_item;
24319750e409Sopenharmony_ci    }
24329750e409Sopenharmony_ci
24339750e409Sopenharmony_ci    cJSON_Delete(object_item);
24349750e409Sopenharmony_ci    return NULL;
24359750e409Sopenharmony_ci}
24369750e409Sopenharmony_ci
24379750e409Sopenharmony_ciCJSON_PUBLIC(cJSON*) cJSON_AddArrayToObject(cJSON * const object, const char * const name)
24389750e409Sopenharmony_ci{
24399750e409Sopenharmony_ci    cJSON *array = cJSON_CreateArray();
24409750e409Sopenharmony_ci    if (add_item_to_object(object, name, array, &global_hooks, false))
24419750e409Sopenharmony_ci    {
24429750e409Sopenharmony_ci        return array;
24439750e409Sopenharmony_ci    }
24449750e409Sopenharmony_ci
24459750e409Sopenharmony_ci    cJSON_Delete(array);
24469750e409Sopenharmony_ci    return NULL;
24479750e409Sopenharmony_ci}
24489750e409Sopenharmony_ci
24499750e409Sopenharmony_ciCJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const item)
24509750e409Sopenharmony_ci{
24519750e409Sopenharmony_ci    if ((parent == NULL) || (item == NULL) || (item != parent->child && item->prev == NULL))
24529750e409Sopenharmony_ci    {
24539750e409Sopenharmony_ci        return NULL;
24549750e409Sopenharmony_ci    }
24559750e409Sopenharmony_ci
24569750e409Sopenharmony_ci    if (item != parent->child)
24579750e409Sopenharmony_ci    {
24589750e409Sopenharmony_ci        /* not the first element */
24599750e409Sopenharmony_ci        item->prev->next = item->next;
24609750e409Sopenharmony_ci    }
24619750e409Sopenharmony_ci    if (item->next != NULL)
24629750e409Sopenharmony_ci    {
24639750e409Sopenharmony_ci        /* not the last element */
24649750e409Sopenharmony_ci        item->next->prev = item->prev;
24659750e409Sopenharmony_ci    }
24669750e409Sopenharmony_ci
24679750e409Sopenharmony_ci    if (item == parent->child)
24689750e409Sopenharmony_ci    {
24699750e409Sopenharmony_ci        /* first element */
24709750e409Sopenharmony_ci        parent->child = item->next;
24719750e409Sopenharmony_ci    }
24729750e409Sopenharmony_ci    else if (item->next == NULL)
24739750e409Sopenharmony_ci    {
24749750e409Sopenharmony_ci        /* last element */
24759750e409Sopenharmony_ci        parent->child->prev = item->prev;
24769750e409Sopenharmony_ci    }
24779750e409Sopenharmony_ci
24789750e409Sopenharmony_ci    /* make sure the detached item doesn't point anywhere anymore */
24799750e409Sopenharmony_ci    item->prev = NULL;
24809750e409Sopenharmony_ci    item->next = NULL;
24819750e409Sopenharmony_ci
24829750e409Sopenharmony_ci    return item;
24839750e409Sopenharmony_ci}
24849750e409Sopenharmony_ci
24859750e409Sopenharmony_ciCJSON_PUBLIC(cJSON *) cJSON_DetachItemFromArray(cJSON *array, int which)
24869750e409Sopenharmony_ci{
24879750e409Sopenharmony_ci    if (which < 0)
24889750e409Sopenharmony_ci    {
24899750e409Sopenharmony_ci        return NULL;
24909750e409Sopenharmony_ci    }
24919750e409Sopenharmony_ci
24929750e409Sopenharmony_ci    return cJSON_DetachItemViaPointer(array, get_array_item(array, (size_t)which));
24939750e409Sopenharmony_ci}
24949750e409Sopenharmony_ci
24959750e409Sopenharmony_ciCJSON_PUBLIC(void) cJSON_DeleteItemFromArray(cJSON *array, int which)
24969750e409Sopenharmony_ci{
24979750e409Sopenharmony_ci    cJSON_Delete(cJSON_DetachItemFromArray(array, which));
24989750e409Sopenharmony_ci}
24999750e409Sopenharmony_ci
25009750e409Sopenharmony_ciCJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObject(cJSON *object, const char *string)
25019750e409Sopenharmony_ci{
25029750e409Sopenharmony_ci    cJSON *to_detach = cJSON_GetObjectItem(object, string);
25039750e409Sopenharmony_ci
25049750e409Sopenharmony_ci    return cJSON_DetachItemViaPointer(object, to_detach);
25059750e409Sopenharmony_ci}
25069750e409Sopenharmony_ci
25079750e409Sopenharmony_ciCJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObjectCaseSensitive(cJSON *object, const char *string)
25089750e409Sopenharmony_ci{
25099750e409Sopenharmony_ci    cJSON *to_detach = cJSON_GetObjectItemCaseSensitive(object, string);
25109750e409Sopenharmony_ci
25119750e409Sopenharmony_ci    return cJSON_DetachItemViaPointer(object, to_detach);
25129750e409Sopenharmony_ci}
25139750e409Sopenharmony_ci
25149750e409Sopenharmony_ciCJSON_PUBLIC(void) cJSON_DeleteItemFromObject(cJSON *object, const char *string)
25159750e409Sopenharmony_ci{
25169750e409Sopenharmony_ci    cJSON_Delete(cJSON_DetachItemFromObject(object, string));
25179750e409Sopenharmony_ci}
25189750e409Sopenharmony_ci
25199750e409Sopenharmony_ciCJSON_PUBLIC(void) cJSON_DeleteItemFromObjectCaseSensitive(cJSON *object, const char *string)
25209750e409Sopenharmony_ci{
25219750e409Sopenharmony_ci    cJSON_Delete(cJSON_DetachItemFromObjectCaseSensitive(object, string));
25229750e409Sopenharmony_ci}
25239750e409Sopenharmony_ci
25249750e409Sopenharmony_ci/* Replace array/object items with new ones. */
25259750e409Sopenharmony_ciCJSON_PUBLIC(cJSON_bool) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem)
25269750e409Sopenharmony_ci{
25279750e409Sopenharmony_ci    cJSON *after_inserted = NULL;
25289750e409Sopenharmony_ci
25299750e409Sopenharmony_ci    if (which < 0 || newitem == NULL)
25309750e409Sopenharmony_ci    {
25319750e409Sopenharmony_ci        return false;
25329750e409Sopenharmony_ci    }
25339750e409Sopenharmony_ci
25349750e409Sopenharmony_ci    after_inserted = get_array_item(array, (size_t)which);
25359750e409Sopenharmony_ci    if (after_inserted == NULL)
25369750e409Sopenharmony_ci    {
25379750e409Sopenharmony_ci        return add_item_to_array(array, newitem);
25389750e409Sopenharmony_ci    }
25399750e409Sopenharmony_ci
25409750e409Sopenharmony_ci    if (after_inserted != array->child && after_inserted->prev == NULL) {
25419750e409Sopenharmony_ci        /* return false if after_inserted is a corrupted array item */
25429750e409Sopenharmony_ci        return false;
25439750e409Sopenharmony_ci    }
25449750e409Sopenharmony_ci
25459750e409Sopenharmony_ci    newitem->next = after_inserted;
25469750e409Sopenharmony_ci    newitem->prev = after_inserted->prev;
25479750e409Sopenharmony_ci    after_inserted->prev = newitem;
25489750e409Sopenharmony_ci    if (after_inserted == array->child)
25499750e409Sopenharmony_ci    {
25509750e409Sopenharmony_ci        array->child = newitem;
25519750e409Sopenharmony_ci    }
25529750e409Sopenharmony_ci    else
25539750e409Sopenharmony_ci    {
25549750e409Sopenharmony_ci        newitem->prev->next = newitem;
25559750e409Sopenharmony_ci    }
25569750e409Sopenharmony_ci    return true;
25579750e409Sopenharmony_ci}
25589750e409Sopenharmony_ci
25599750e409Sopenharmony_ciCJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON * const item, cJSON * replacement)
25609750e409Sopenharmony_ci{
25619750e409Sopenharmony_ci    if ((parent == NULL) || (parent->child == NULL) || (replacement == NULL) || (item == NULL))
25629750e409Sopenharmony_ci    {
25639750e409Sopenharmony_ci        return false;
25649750e409Sopenharmony_ci    }
25659750e409Sopenharmony_ci
25669750e409Sopenharmony_ci    if (replacement == item)
25679750e409Sopenharmony_ci    {
25689750e409Sopenharmony_ci        return true;
25699750e409Sopenharmony_ci    }
25709750e409Sopenharmony_ci
25719750e409Sopenharmony_ci    replacement->next = item->next;
25729750e409Sopenharmony_ci    replacement->prev = item->prev;
25739750e409Sopenharmony_ci
25749750e409Sopenharmony_ci    if (replacement->next != NULL)
25759750e409Sopenharmony_ci    {
25769750e409Sopenharmony_ci        replacement->next->prev = replacement;
25779750e409Sopenharmony_ci    }
25789750e409Sopenharmony_ci    if (parent->child == item)
25799750e409Sopenharmony_ci    {
25809750e409Sopenharmony_ci        if (parent->child->prev == parent->child)
25819750e409Sopenharmony_ci        {
25829750e409Sopenharmony_ci            replacement->prev = replacement;
25839750e409Sopenharmony_ci        }
25849750e409Sopenharmony_ci        parent->child = replacement;
25859750e409Sopenharmony_ci    }
25869750e409Sopenharmony_ci    else
25879750e409Sopenharmony_ci    {   /*
25889750e409Sopenharmony_ci         * To find the last item in array quickly, we use prev in array.
25899750e409Sopenharmony_ci         * We can't modify the last item's next pointer where this item was the parent's child
25909750e409Sopenharmony_ci         */
25919750e409Sopenharmony_ci        if (replacement->prev != NULL)
25929750e409Sopenharmony_ci        {
25939750e409Sopenharmony_ci            replacement->prev->next = replacement;
25949750e409Sopenharmony_ci        }
25959750e409Sopenharmony_ci        if (replacement->next == NULL)
25969750e409Sopenharmony_ci        {
25979750e409Sopenharmony_ci            parent->child->prev = replacement;
25989750e409Sopenharmony_ci        }
25999750e409Sopenharmony_ci    }
26009750e409Sopenharmony_ci
26019750e409Sopenharmony_ci    item->next = NULL;
26029750e409Sopenharmony_ci    item->prev = NULL;
26039750e409Sopenharmony_ci    cJSON_Delete(item);
26049750e409Sopenharmony_ci
26059750e409Sopenharmony_ci    return true;
26069750e409Sopenharmony_ci}
26079750e409Sopenharmony_ci
26089750e409Sopenharmony_ciCJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem)
26099750e409Sopenharmony_ci{
26109750e409Sopenharmony_ci    if (which < 0)
26119750e409Sopenharmony_ci    {
26129750e409Sopenharmony_ci        return false;
26139750e409Sopenharmony_ci    }
26149750e409Sopenharmony_ci
26159750e409Sopenharmony_ci    return cJSON_ReplaceItemViaPointer(array, get_array_item(array, (size_t)which), newitem);
26169750e409Sopenharmony_ci}
26179750e409Sopenharmony_ci
26189750e409Sopenharmony_cistatic cJSON_bool replace_item_in_object(cJSON *object, const char *string, cJSON *replacement, cJSON_bool case_sensitive)
26199750e409Sopenharmony_ci{
26209750e409Sopenharmony_ci    if ((replacement == NULL) || (string == NULL))
26219750e409Sopenharmony_ci    {
26229750e409Sopenharmony_ci        return false;
26239750e409Sopenharmony_ci    }
26249750e409Sopenharmony_ci
26259750e409Sopenharmony_ci    /* replace the name in the replacement */
26269750e409Sopenharmony_ci    if (!(replacement->type & cJSON_StringIsConst) && (replacement->string != NULL))
26279750e409Sopenharmony_ci    {
26289750e409Sopenharmony_ci        cJSON_free(replacement->string);
26299750e409Sopenharmony_ci    }
26309750e409Sopenharmony_ci    replacement->string = (char*)cJSON_strdup((const unsigned char*)string, &global_hooks);
26319750e409Sopenharmony_ci    if (replacement->string == NULL)
26329750e409Sopenharmony_ci    {
26339750e409Sopenharmony_ci        return false;
26349750e409Sopenharmony_ci    }
26359750e409Sopenharmony_ci
26369750e409Sopenharmony_ci    replacement->type &= ~cJSON_StringIsConst;
26379750e409Sopenharmony_ci
26389750e409Sopenharmony_ci    return cJSON_ReplaceItemViaPointer(object, get_object_item(object, string, case_sensitive), replacement);
26399750e409Sopenharmony_ci}
26409750e409Sopenharmony_ci
26419750e409Sopenharmony_ciCJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInObject(cJSON *object, const char *string, cJSON *newitem)
26429750e409Sopenharmony_ci{
26439750e409Sopenharmony_ci    return replace_item_in_object(object, string, newitem, false);
26449750e409Sopenharmony_ci}
26459750e409Sopenharmony_ci
26469750e409Sopenharmony_ciCJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object, const char *string, cJSON *newitem)
26479750e409Sopenharmony_ci{
26489750e409Sopenharmony_ci    return replace_item_in_object(object, string, newitem, true);
26499750e409Sopenharmony_ci}
26509750e409Sopenharmony_ci
26519750e409Sopenharmony_ci/* Create basic types: */
26529750e409Sopenharmony_ciCJSON_PUBLIC(cJSON *) cJSON_CreateNull(void)
26539750e409Sopenharmony_ci{
26549750e409Sopenharmony_ci    cJSON *item = cJSON_New_Item(&global_hooks);
26559750e409Sopenharmony_ci    if(item)
26569750e409Sopenharmony_ci    {
26579750e409Sopenharmony_ci        item->type = cJSON_NULL;
26589750e409Sopenharmony_ci    }
26599750e409Sopenharmony_ci
26609750e409Sopenharmony_ci    return item;
26619750e409Sopenharmony_ci}
26629750e409Sopenharmony_ci
26639750e409Sopenharmony_ciCJSON_PUBLIC(cJSON *) cJSON_CreateTrue(void)
26649750e409Sopenharmony_ci{
26659750e409Sopenharmony_ci    cJSON *item = cJSON_New_Item(&global_hooks);
26669750e409Sopenharmony_ci    if(item)
26679750e409Sopenharmony_ci    {
26689750e409Sopenharmony_ci        item->type = cJSON_True;
26699750e409Sopenharmony_ci    }
26709750e409Sopenharmony_ci
26719750e409Sopenharmony_ci    return item;
26729750e409Sopenharmony_ci}
26739750e409Sopenharmony_ci
26749750e409Sopenharmony_ciCJSON_PUBLIC(cJSON *) cJSON_CreateFalse(void)
26759750e409Sopenharmony_ci{
26769750e409Sopenharmony_ci    cJSON *item = cJSON_New_Item(&global_hooks);
26779750e409Sopenharmony_ci    if(item)
26789750e409Sopenharmony_ci    {
26799750e409Sopenharmony_ci        item->type = cJSON_False;
26809750e409Sopenharmony_ci    }
26819750e409Sopenharmony_ci
26829750e409Sopenharmony_ci    return item;
26839750e409Sopenharmony_ci}
26849750e409Sopenharmony_ci
26859750e409Sopenharmony_ciCJSON_PUBLIC(cJSON *) cJSON_CreateBool(cJSON_bool boolean)
26869750e409Sopenharmony_ci{
26879750e409Sopenharmony_ci    cJSON *item = cJSON_New_Item(&global_hooks);
26889750e409Sopenharmony_ci    if(item)
26899750e409Sopenharmony_ci    {
26909750e409Sopenharmony_ci        item->type = boolean ? cJSON_True : cJSON_False;
26919750e409Sopenharmony_ci    }
26929750e409Sopenharmony_ci
26939750e409Sopenharmony_ci    return item;
26949750e409Sopenharmony_ci}
26959750e409Sopenharmony_ci
26969750e409Sopenharmony_ci#ifdef __CJSON_USE_INT64
26979750e409Sopenharmony_ciCJSON_PUBLIC(cJSON *) cJSON_CreateInt64Number(long long integer)
26989750e409Sopenharmony_ci{
26999750e409Sopenharmony_ci    cJSON *item = cJSON_New_Item(&global_hooks);
27009750e409Sopenharmony_ci    if(item)
27019750e409Sopenharmony_ci    {
27029750e409Sopenharmony_ci        item->type = cJSON_Number | cJSON_IsInt64;
27039750e409Sopenharmony_ci        item->valueint = integer;
27049750e409Sopenharmony_ci        item->valuedouble = (double)integer;
27059750e409Sopenharmony_ci    }
27069750e409Sopenharmony_ci
27079750e409Sopenharmony_ci    return item;
27089750e409Sopenharmony_ci}
27099750e409Sopenharmony_ci#endif /* __CJSON_USE_INT64 */
27109750e409Sopenharmony_ci
27119750e409Sopenharmony_ci#ifdef __CJSON_USE_INT64
27129750e409Sopenharmony_ciCJSON_PUBLIC(cJSON *) cJSON_CreateNumber(double num)
27139750e409Sopenharmony_ci{
27149750e409Sopenharmony_ci    cJSON *item = cJSON_New_Item(&global_hooks);
27159750e409Sopenharmony_ci    if(item)
27169750e409Sopenharmony_ci    {
27179750e409Sopenharmony_ci        item->type = cJSON_Number;
27189750e409Sopenharmony_ci        item->valuedouble = num;
27199750e409Sopenharmony_ci
27209750e409Sopenharmony_ci        /* use saturation in case of overflow */
27219750e409Sopenharmony_ci        /* note that double max(DBL_MAX) is bigger than long long max(LLONG_MAX) */
27229750e409Sopenharmony_ci        if (num >= (double)LLONG_MAX)
27239750e409Sopenharmony_ci        {
27249750e409Sopenharmony_ci            item->valueint = LLONG_MAX;
27259750e409Sopenharmony_ci        }
27269750e409Sopenharmony_ci        else if (num <= (double)LLONG_MIN)
27279750e409Sopenharmony_ci        {
27289750e409Sopenharmony_ci            item->valueint = LLONG_MIN;
27299750e409Sopenharmony_ci        }
27309750e409Sopenharmony_ci        else
27319750e409Sopenharmony_ci        {
27329750e409Sopenharmony_ci            item->valueint = (long long)num;
27339750e409Sopenharmony_ci        }
27349750e409Sopenharmony_ci    }
27359750e409Sopenharmony_ci
27369750e409Sopenharmony_ci    return item;
27379750e409Sopenharmony_ci}
27389750e409Sopenharmony_ci#else
27399750e409Sopenharmony_ciCJSON_PUBLIC(cJSON *) cJSON_CreateNumber(double num)
27409750e409Sopenharmony_ci{
27419750e409Sopenharmony_ci    cJSON *item = cJSON_New_Item(&global_hooks);
27429750e409Sopenharmony_ci    if(item)
27439750e409Sopenharmony_ci    {
27449750e409Sopenharmony_ci        item->type = cJSON_Number;
27459750e409Sopenharmony_ci        item->valuedouble = num;
27469750e409Sopenharmony_ci
27479750e409Sopenharmony_ci        /* use saturation in case of overflow */
27489750e409Sopenharmony_ci        if (num >= INT_MAX)
27499750e409Sopenharmony_ci        {
27509750e409Sopenharmony_ci            item->valueint = INT_MAX;
27519750e409Sopenharmony_ci        }
27529750e409Sopenharmony_ci        else if (num <= (double)INT_MIN)
27539750e409Sopenharmony_ci        {
27549750e409Sopenharmony_ci            item->valueint = INT_MIN;
27559750e409Sopenharmony_ci        }
27569750e409Sopenharmony_ci        else
27579750e409Sopenharmony_ci        {
27589750e409Sopenharmony_ci            item->valueint = (int)num;
27599750e409Sopenharmony_ci        }
27609750e409Sopenharmony_ci    }
27619750e409Sopenharmony_ci
27629750e409Sopenharmony_ci    return item;
27639750e409Sopenharmony_ci}
27649750e409Sopenharmony_ci#endif /* __CJSON_USE_INT64 */
27659750e409Sopenharmony_ci
27669750e409Sopenharmony_ciCJSON_PUBLIC(cJSON *) cJSON_CreateString(const char *string)
27679750e409Sopenharmony_ci{
27689750e409Sopenharmony_ci    cJSON *item = cJSON_New_Item(&global_hooks);
27699750e409Sopenharmony_ci    if(item)
27709750e409Sopenharmony_ci    {
27719750e409Sopenharmony_ci        item->type = cJSON_String;
27729750e409Sopenharmony_ci        item->valuestring = (char*)cJSON_strdup((const unsigned char*)string, &global_hooks);
27739750e409Sopenharmony_ci        if(!item->valuestring)
27749750e409Sopenharmony_ci        {
27759750e409Sopenharmony_ci            cJSON_Delete(item);
27769750e409Sopenharmony_ci            return NULL;
27779750e409Sopenharmony_ci        }
27789750e409Sopenharmony_ci    }
27799750e409Sopenharmony_ci
27809750e409Sopenharmony_ci    return item;
27819750e409Sopenharmony_ci}
27829750e409Sopenharmony_ci
27839750e409Sopenharmony_ciCJSON_PUBLIC(cJSON *) cJSON_CreateStringReference(const char *string)
27849750e409Sopenharmony_ci{
27859750e409Sopenharmony_ci    cJSON *item = cJSON_New_Item(&global_hooks);
27869750e409Sopenharmony_ci    if (item != NULL)
27879750e409Sopenharmony_ci    {
27889750e409Sopenharmony_ci        item->type = cJSON_String | cJSON_IsReference;
27899750e409Sopenharmony_ci        item->valuestring = (char*)cast_away_const(string);
27909750e409Sopenharmony_ci    }
27919750e409Sopenharmony_ci
27929750e409Sopenharmony_ci    return item;
27939750e409Sopenharmony_ci}
27949750e409Sopenharmony_ci
27959750e409Sopenharmony_ciCJSON_PUBLIC(cJSON *) cJSON_CreateObjectReference(const cJSON *child)
27969750e409Sopenharmony_ci{
27979750e409Sopenharmony_ci    cJSON *item = cJSON_New_Item(&global_hooks);
27989750e409Sopenharmony_ci    if (item != NULL) {
27999750e409Sopenharmony_ci        item->type = cJSON_Object | cJSON_IsReference;
28009750e409Sopenharmony_ci        item->child = (cJSON*)cast_away_const(child);
28019750e409Sopenharmony_ci    }
28029750e409Sopenharmony_ci
28039750e409Sopenharmony_ci    return item;
28049750e409Sopenharmony_ci}
28059750e409Sopenharmony_ci
28069750e409Sopenharmony_ciCJSON_PUBLIC(cJSON *) cJSON_CreateArrayReference(const cJSON *child) {
28079750e409Sopenharmony_ci    cJSON *item = cJSON_New_Item(&global_hooks);
28089750e409Sopenharmony_ci    if (item != NULL) {
28099750e409Sopenharmony_ci        item->type = cJSON_Array | cJSON_IsReference;
28109750e409Sopenharmony_ci        item->child = (cJSON*)cast_away_const(child);
28119750e409Sopenharmony_ci    }
28129750e409Sopenharmony_ci
28139750e409Sopenharmony_ci    return item;
28149750e409Sopenharmony_ci}
28159750e409Sopenharmony_ci
28169750e409Sopenharmony_ciCJSON_PUBLIC(cJSON *) cJSON_CreateRaw(const char *raw)
28179750e409Sopenharmony_ci{
28189750e409Sopenharmony_ci    cJSON *item = cJSON_New_Item(&global_hooks);
28199750e409Sopenharmony_ci    if(item)
28209750e409Sopenharmony_ci    {
28219750e409Sopenharmony_ci        item->type = cJSON_Raw;
28229750e409Sopenharmony_ci        item->valuestring = (char*)cJSON_strdup((const unsigned char*)raw, &global_hooks);
28239750e409Sopenharmony_ci        if(!item->valuestring)
28249750e409Sopenharmony_ci        {
28259750e409Sopenharmony_ci            cJSON_Delete(item);
28269750e409Sopenharmony_ci            return NULL;
28279750e409Sopenharmony_ci        }
28289750e409Sopenharmony_ci    }
28299750e409Sopenharmony_ci
28309750e409Sopenharmony_ci    return item;
28319750e409Sopenharmony_ci}
28329750e409Sopenharmony_ci
28339750e409Sopenharmony_ciCJSON_PUBLIC(cJSON *) cJSON_CreateArray(void)
28349750e409Sopenharmony_ci{
28359750e409Sopenharmony_ci    cJSON *item = cJSON_New_Item(&global_hooks);
28369750e409Sopenharmony_ci    if(item)
28379750e409Sopenharmony_ci    {
28389750e409Sopenharmony_ci        item->type=cJSON_Array;
28399750e409Sopenharmony_ci    }
28409750e409Sopenharmony_ci
28419750e409Sopenharmony_ci    return item;
28429750e409Sopenharmony_ci}
28439750e409Sopenharmony_ci
28449750e409Sopenharmony_ciCJSON_PUBLIC(cJSON *) cJSON_CreateObject(void)
28459750e409Sopenharmony_ci{
28469750e409Sopenharmony_ci    cJSON *item = cJSON_New_Item(&global_hooks);
28479750e409Sopenharmony_ci    if (item)
28489750e409Sopenharmony_ci    {
28499750e409Sopenharmony_ci        item->type = cJSON_Object;
28509750e409Sopenharmony_ci    }
28519750e409Sopenharmony_ci
28529750e409Sopenharmony_ci    return item;
28539750e409Sopenharmony_ci}
28549750e409Sopenharmony_ci
28559750e409Sopenharmony_ci/* Create Arrays: */
28569750e409Sopenharmony_ciCJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count)
28579750e409Sopenharmony_ci{
28589750e409Sopenharmony_ci    size_t i = 0;
28599750e409Sopenharmony_ci    cJSON *n = NULL;
28609750e409Sopenharmony_ci    cJSON *p = NULL;
28619750e409Sopenharmony_ci    cJSON *a = NULL;
28629750e409Sopenharmony_ci
28639750e409Sopenharmony_ci    if ((count < 0) || (numbers == NULL))
28649750e409Sopenharmony_ci    {
28659750e409Sopenharmony_ci        return NULL;
28669750e409Sopenharmony_ci    }
28679750e409Sopenharmony_ci
28689750e409Sopenharmony_ci    a = cJSON_CreateArray();
28699750e409Sopenharmony_ci
28709750e409Sopenharmony_ci    for(i = 0; a && (i < (size_t)count); i++)
28719750e409Sopenharmony_ci    {
28729750e409Sopenharmony_ci        n = cJSON_CreateNumber(numbers[i]);
28739750e409Sopenharmony_ci        if (!n)
28749750e409Sopenharmony_ci        {
28759750e409Sopenharmony_ci            cJSON_Delete(a);
28769750e409Sopenharmony_ci            return NULL;
28779750e409Sopenharmony_ci        }
28789750e409Sopenharmony_ci        if(!i)
28799750e409Sopenharmony_ci        {
28809750e409Sopenharmony_ci            a->child = n;
28819750e409Sopenharmony_ci        }
28829750e409Sopenharmony_ci        else
28839750e409Sopenharmony_ci        {
28849750e409Sopenharmony_ci            suffix_object(p, n);
28859750e409Sopenharmony_ci        }
28869750e409Sopenharmony_ci        p = n;
28879750e409Sopenharmony_ci    }
28889750e409Sopenharmony_ci
28899750e409Sopenharmony_ci    if (a && a->child) {
28909750e409Sopenharmony_ci        a->child->prev = n;
28919750e409Sopenharmony_ci    }
28929750e409Sopenharmony_ci
28939750e409Sopenharmony_ci    return a;
28949750e409Sopenharmony_ci}
28959750e409Sopenharmony_ci
28969750e409Sopenharmony_ciCJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count)
28979750e409Sopenharmony_ci{
28989750e409Sopenharmony_ci    size_t i = 0;
28999750e409Sopenharmony_ci    cJSON *n = NULL;
29009750e409Sopenharmony_ci    cJSON *p = NULL;
29019750e409Sopenharmony_ci    cJSON *a = NULL;
29029750e409Sopenharmony_ci
29039750e409Sopenharmony_ci    if ((count < 0) || (numbers == NULL))
29049750e409Sopenharmony_ci    {
29059750e409Sopenharmony_ci        return NULL;
29069750e409Sopenharmony_ci    }
29079750e409Sopenharmony_ci
29089750e409Sopenharmony_ci    a = cJSON_CreateArray();
29099750e409Sopenharmony_ci
29109750e409Sopenharmony_ci    for(i = 0; a && (i < (size_t)count); i++)
29119750e409Sopenharmony_ci    {
29129750e409Sopenharmony_ci        n = cJSON_CreateNumber((double)numbers[i]);
29139750e409Sopenharmony_ci        if(!n)
29149750e409Sopenharmony_ci        {
29159750e409Sopenharmony_ci            cJSON_Delete(a);
29169750e409Sopenharmony_ci            return NULL;
29179750e409Sopenharmony_ci        }
29189750e409Sopenharmony_ci        if(!i)
29199750e409Sopenharmony_ci        {
29209750e409Sopenharmony_ci            a->child = n;
29219750e409Sopenharmony_ci        }
29229750e409Sopenharmony_ci        else
29239750e409Sopenharmony_ci        {
29249750e409Sopenharmony_ci            suffix_object(p, n);
29259750e409Sopenharmony_ci        }
29269750e409Sopenharmony_ci        p = n;
29279750e409Sopenharmony_ci    }
29289750e409Sopenharmony_ci
29299750e409Sopenharmony_ci    if (a && a->child) {
29309750e409Sopenharmony_ci        a->child->prev = n;
29319750e409Sopenharmony_ci    }
29329750e409Sopenharmony_ci
29339750e409Sopenharmony_ci    return a;
29349750e409Sopenharmony_ci}
29359750e409Sopenharmony_ci
29369750e409Sopenharmony_ciCJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count)
29379750e409Sopenharmony_ci{
29389750e409Sopenharmony_ci    size_t i = 0;
29399750e409Sopenharmony_ci    cJSON *n = NULL;
29409750e409Sopenharmony_ci    cJSON *p = NULL;
29419750e409Sopenharmony_ci    cJSON *a = NULL;
29429750e409Sopenharmony_ci
29439750e409Sopenharmony_ci    if ((count < 0) || (numbers == NULL))
29449750e409Sopenharmony_ci    {
29459750e409Sopenharmony_ci        return NULL;
29469750e409Sopenharmony_ci    }
29479750e409Sopenharmony_ci
29489750e409Sopenharmony_ci    a = cJSON_CreateArray();
29499750e409Sopenharmony_ci
29509750e409Sopenharmony_ci    for(i = 0; a && (i < (size_t)count); i++)
29519750e409Sopenharmony_ci    {
29529750e409Sopenharmony_ci        n = cJSON_CreateNumber(numbers[i]);
29539750e409Sopenharmony_ci        if(!n)
29549750e409Sopenharmony_ci        {
29559750e409Sopenharmony_ci            cJSON_Delete(a);
29569750e409Sopenharmony_ci            return NULL;
29579750e409Sopenharmony_ci        }
29589750e409Sopenharmony_ci        if(!i)
29599750e409Sopenharmony_ci        {
29609750e409Sopenharmony_ci            a->child = n;
29619750e409Sopenharmony_ci        }
29629750e409Sopenharmony_ci        else
29639750e409Sopenharmony_ci        {
29649750e409Sopenharmony_ci            suffix_object(p, n);
29659750e409Sopenharmony_ci        }
29669750e409Sopenharmony_ci        p = n;
29679750e409Sopenharmony_ci    }
29689750e409Sopenharmony_ci
29699750e409Sopenharmony_ci    if (a && a->child) {
29709750e409Sopenharmony_ci        a->child->prev = n;
29719750e409Sopenharmony_ci    }
29729750e409Sopenharmony_ci
29739750e409Sopenharmony_ci    return a;
29749750e409Sopenharmony_ci}
29759750e409Sopenharmony_ci
29769750e409Sopenharmony_ciCJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char *const *strings, int count)
29779750e409Sopenharmony_ci{
29789750e409Sopenharmony_ci    size_t i = 0;
29799750e409Sopenharmony_ci    cJSON *n = NULL;
29809750e409Sopenharmony_ci    cJSON *p = NULL;
29819750e409Sopenharmony_ci    cJSON *a = NULL;
29829750e409Sopenharmony_ci
29839750e409Sopenharmony_ci    if ((count < 0) || (strings == NULL))
29849750e409Sopenharmony_ci    {
29859750e409Sopenharmony_ci        return NULL;
29869750e409Sopenharmony_ci    }
29879750e409Sopenharmony_ci
29889750e409Sopenharmony_ci    a = cJSON_CreateArray();
29899750e409Sopenharmony_ci
29909750e409Sopenharmony_ci    for (i = 0; a && (i < (size_t)count); i++)
29919750e409Sopenharmony_ci    {
29929750e409Sopenharmony_ci        n = cJSON_CreateString(strings[i]);
29939750e409Sopenharmony_ci        if(!n)
29949750e409Sopenharmony_ci        {
29959750e409Sopenharmony_ci            cJSON_Delete(a);
29969750e409Sopenharmony_ci            return NULL;
29979750e409Sopenharmony_ci        }
29989750e409Sopenharmony_ci        if(!i)
29999750e409Sopenharmony_ci        {
30009750e409Sopenharmony_ci            a->child = n;
30019750e409Sopenharmony_ci        }
30029750e409Sopenharmony_ci        else
30039750e409Sopenharmony_ci        {
30049750e409Sopenharmony_ci            suffix_object(p,n);
30059750e409Sopenharmony_ci        }
30069750e409Sopenharmony_ci        p = n;
30079750e409Sopenharmony_ci    }
30089750e409Sopenharmony_ci
30099750e409Sopenharmony_ci    if (a && a->child) {
30109750e409Sopenharmony_ci        a->child->prev = n;
30119750e409Sopenharmony_ci    }
30129750e409Sopenharmony_ci
30139750e409Sopenharmony_ci    return a;
30149750e409Sopenharmony_ci}
30159750e409Sopenharmony_ci
30169750e409Sopenharmony_ci/* Duplication */
30179750e409Sopenharmony_ciCJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse)
30189750e409Sopenharmony_ci{
30199750e409Sopenharmony_ci    cJSON *newitem = NULL;
30209750e409Sopenharmony_ci    cJSON *child = NULL;
30219750e409Sopenharmony_ci    cJSON *next = NULL;
30229750e409Sopenharmony_ci    cJSON *newchild = NULL;
30239750e409Sopenharmony_ci
30249750e409Sopenharmony_ci    /* Bail on bad ptr */
30259750e409Sopenharmony_ci    if (!item)
30269750e409Sopenharmony_ci    {
30279750e409Sopenharmony_ci        goto fail;
30289750e409Sopenharmony_ci    }
30299750e409Sopenharmony_ci    /* Create new item */
30309750e409Sopenharmony_ci    newitem = cJSON_New_Item(&global_hooks);
30319750e409Sopenharmony_ci    if (!newitem)
30329750e409Sopenharmony_ci    {
30339750e409Sopenharmony_ci        goto fail;
30349750e409Sopenharmony_ci    }
30359750e409Sopenharmony_ci    /* Copy over all vars */
30369750e409Sopenharmony_ci    newitem->type = item->type & (~cJSON_IsReference);
30379750e409Sopenharmony_ci    newitem->valueint = item->valueint;
30389750e409Sopenharmony_ci    newitem->valuedouble = item->valuedouble;
30399750e409Sopenharmony_ci    if (item->valuestring)
30409750e409Sopenharmony_ci    {
30419750e409Sopenharmony_ci        newitem->valuestring = (char*)cJSON_strdup((unsigned char*)item->valuestring, &global_hooks);
30429750e409Sopenharmony_ci        if (!newitem->valuestring)
30439750e409Sopenharmony_ci        {
30449750e409Sopenharmony_ci            goto fail;
30459750e409Sopenharmony_ci        }
30469750e409Sopenharmony_ci    }
30479750e409Sopenharmony_ci    if (item->string)
30489750e409Sopenharmony_ci    {
30499750e409Sopenharmony_ci        newitem->string = (item->type&cJSON_StringIsConst) ? item->string : (char*)cJSON_strdup((unsigned char*)item->string, &global_hooks);
30509750e409Sopenharmony_ci        if (!newitem->string)
30519750e409Sopenharmony_ci        {
30529750e409Sopenharmony_ci            goto fail;
30539750e409Sopenharmony_ci        }
30549750e409Sopenharmony_ci    }
30559750e409Sopenharmony_ci    /* If non-recursive, then we're done! */
30569750e409Sopenharmony_ci    if (!recurse)
30579750e409Sopenharmony_ci    {
30589750e409Sopenharmony_ci        return newitem;
30599750e409Sopenharmony_ci    }
30609750e409Sopenharmony_ci    /* Walk the ->next chain for the child. */
30619750e409Sopenharmony_ci    child = item->child;
30629750e409Sopenharmony_ci    while (child != NULL)
30639750e409Sopenharmony_ci    {
30649750e409Sopenharmony_ci        newchild = cJSON_Duplicate(child, true); /* Duplicate (with recurse) each item in the ->next chain */
30659750e409Sopenharmony_ci        if (!newchild)
30669750e409Sopenharmony_ci        {
30679750e409Sopenharmony_ci            goto fail;
30689750e409Sopenharmony_ci        }
30699750e409Sopenharmony_ci        if (next != NULL)
30709750e409Sopenharmony_ci        {
30719750e409Sopenharmony_ci            /* If newitem->child already set, then crosswire ->prev and ->next and move on */
30729750e409Sopenharmony_ci            next->next = newchild;
30739750e409Sopenharmony_ci            newchild->prev = next;
30749750e409Sopenharmony_ci            next = newchild;
30759750e409Sopenharmony_ci        }
30769750e409Sopenharmony_ci        else
30779750e409Sopenharmony_ci        {
30789750e409Sopenharmony_ci            /* Set newitem->child and move to it */
30799750e409Sopenharmony_ci            newitem->child = newchild;
30809750e409Sopenharmony_ci            next = newchild;
30819750e409Sopenharmony_ci        }
30829750e409Sopenharmony_ci        child = child->next;
30839750e409Sopenharmony_ci    }
30849750e409Sopenharmony_ci    if (newitem && newitem->child)
30859750e409Sopenharmony_ci    {
30869750e409Sopenharmony_ci        newitem->child->prev = newchild;
30879750e409Sopenharmony_ci    }
30889750e409Sopenharmony_ci
30899750e409Sopenharmony_ci    return newitem;
30909750e409Sopenharmony_ci
30919750e409Sopenharmony_cifail:
30929750e409Sopenharmony_ci    if (newitem != NULL)
30939750e409Sopenharmony_ci    {
30949750e409Sopenharmony_ci        cJSON_Delete(newitem);
30959750e409Sopenharmony_ci    }
30969750e409Sopenharmony_ci
30979750e409Sopenharmony_ci    return NULL;
30989750e409Sopenharmony_ci}
30999750e409Sopenharmony_ci
31009750e409Sopenharmony_cistatic void skip_oneline_comment(char **input)
31019750e409Sopenharmony_ci{
31029750e409Sopenharmony_ci    *input += static_strlen("//");
31039750e409Sopenharmony_ci
31049750e409Sopenharmony_ci    for (; (*input)[0] != '\0'; ++(*input))
31059750e409Sopenharmony_ci    {
31069750e409Sopenharmony_ci        if ((*input)[0] == '\n') {
31079750e409Sopenharmony_ci            *input += static_strlen("\n");
31089750e409Sopenharmony_ci            return;
31099750e409Sopenharmony_ci        }
31109750e409Sopenharmony_ci    }
31119750e409Sopenharmony_ci}
31129750e409Sopenharmony_ci
31139750e409Sopenharmony_cistatic void skip_multiline_comment(char **input)
31149750e409Sopenharmony_ci{
31159750e409Sopenharmony_ci    *input += static_strlen("/*");
31169750e409Sopenharmony_ci
31179750e409Sopenharmony_ci    for (; (*input)[0] != '\0'; ++(*input))
31189750e409Sopenharmony_ci    {
31199750e409Sopenharmony_ci        if (((*input)[0] == '*') && ((*input)[1] == '/'))
31209750e409Sopenharmony_ci        {
31219750e409Sopenharmony_ci            *input += static_strlen("*/");
31229750e409Sopenharmony_ci            return;
31239750e409Sopenharmony_ci        }
31249750e409Sopenharmony_ci    }
31259750e409Sopenharmony_ci}
31269750e409Sopenharmony_ci
31279750e409Sopenharmony_cistatic void minify_string(char **input, char **output) {
31289750e409Sopenharmony_ci    (*output)[0] = (*input)[0];
31299750e409Sopenharmony_ci    *input += static_strlen("\"");
31309750e409Sopenharmony_ci    *output += static_strlen("\"");
31319750e409Sopenharmony_ci
31329750e409Sopenharmony_ci
31339750e409Sopenharmony_ci    for (; (*input)[0] != '\0'; (void)++(*input), ++(*output)) {
31349750e409Sopenharmony_ci        (*output)[0] = (*input)[0];
31359750e409Sopenharmony_ci
31369750e409Sopenharmony_ci        if ((*input)[0] == '\"') {
31379750e409Sopenharmony_ci            (*output)[0] = '\"';
31389750e409Sopenharmony_ci            *input += static_strlen("\"");
31399750e409Sopenharmony_ci            *output += static_strlen("\"");
31409750e409Sopenharmony_ci            return;
31419750e409Sopenharmony_ci        } else if (((*input)[0] == '\\') && ((*input)[1] == '\"')) {
31429750e409Sopenharmony_ci            (*output)[1] = (*input)[1];
31439750e409Sopenharmony_ci            *input += static_strlen("\"");
31449750e409Sopenharmony_ci            *output += static_strlen("\"");
31459750e409Sopenharmony_ci        }
31469750e409Sopenharmony_ci    }
31479750e409Sopenharmony_ci}
31489750e409Sopenharmony_ci
31499750e409Sopenharmony_ciCJSON_PUBLIC(void) cJSON_Minify(char *json)
31509750e409Sopenharmony_ci{
31519750e409Sopenharmony_ci    char *into = json;
31529750e409Sopenharmony_ci
31539750e409Sopenharmony_ci    if (json == NULL)
31549750e409Sopenharmony_ci    {
31559750e409Sopenharmony_ci        return;
31569750e409Sopenharmony_ci    }
31579750e409Sopenharmony_ci
31589750e409Sopenharmony_ci    while (json[0] != '\0')
31599750e409Sopenharmony_ci    {
31609750e409Sopenharmony_ci        switch (json[0])
31619750e409Sopenharmony_ci        {
31629750e409Sopenharmony_ci            case ' ':
31639750e409Sopenharmony_ci            case '\t':
31649750e409Sopenharmony_ci            case '\r':
31659750e409Sopenharmony_ci            case '\n':
31669750e409Sopenharmony_ci                json++;
31679750e409Sopenharmony_ci                break;
31689750e409Sopenharmony_ci
31699750e409Sopenharmony_ci            case '/':
31709750e409Sopenharmony_ci                if (json[1] == '/')
31719750e409Sopenharmony_ci                {
31729750e409Sopenharmony_ci                    skip_oneline_comment(&json);
31739750e409Sopenharmony_ci                }
31749750e409Sopenharmony_ci                else if (json[1] == '*')
31759750e409Sopenharmony_ci                {
31769750e409Sopenharmony_ci                    skip_multiline_comment(&json);
31779750e409Sopenharmony_ci                } else {
31789750e409Sopenharmony_ci                    json++;
31799750e409Sopenharmony_ci                }
31809750e409Sopenharmony_ci                break;
31819750e409Sopenharmony_ci
31829750e409Sopenharmony_ci            case '\"':
31839750e409Sopenharmony_ci                minify_string(&json, (char**)&into);
31849750e409Sopenharmony_ci                break;
31859750e409Sopenharmony_ci
31869750e409Sopenharmony_ci            default:
31879750e409Sopenharmony_ci                into[0] = json[0];
31889750e409Sopenharmony_ci                json++;
31899750e409Sopenharmony_ci                into++;
31909750e409Sopenharmony_ci        }
31919750e409Sopenharmony_ci    }
31929750e409Sopenharmony_ci
31939750e409Sopenharmony_ci    /* and null-terminate. */
31949750e409Sopenharmony_ci    *into = '\0';
31959750e409Sopenharmony_ci}
31969750e409Sopenharmony_ci
31979750e409Sopenharmony_ciCJSON_PUBLIC(cJSON_bool) cJSON_IsInvalid(const cJSON * const item)
31989750e409Sopenharmony_ci{
31999750e409Sopenharmony_ci    if (item == NULL)
32009750e409Sopenharmony_ci    {
32019750e409Sopenharmony_ci        return false;
32029750e409Sopenharmony_ci    }
32039750e409Sopenharmony_ci
32049750e409Sopenharmony_ci    return (item->type & 0xFF) == cJSON_Invalid;
32059750e409Sopenharmony_ci}
32069750e409Sopenharmony_ci
32079750e409Sopenharmony_ciCJSON_PUBLIC(cJSON_bool) cJSON_IsFalse(const cJSON * const item)
32089750e409Sopenharmony_ci{
32099750e409Sopenharmony_ci    if (item == NULL)
32109750e409Sopenharmony_ci    {
32119750e409Sopenharmony_ci        return false;
32129750e409Sopenharmony_ci    }
32139750e409Sopenharmony_ci
32149750e409Sopenharmony_ci    return (item->type & 0xFF) == cJSON_False;
32159750e409Sopenharmony_ci}
32169750e409Sopenharmony_ci
32179750e409Sopenharmony_ciCJSON_PUBLIC(cJSON_bool) cJSON_IsTrue(const cJSON * const item)
32189750e409Sopenharmony_ci{
32199750e409Sopenharmony_ci    if (item == NULL)
32209750e409Sopenharmony_ci    {
32219750e409Sopenharmony_ci        return false;
32229750e409Sopenharmony_ci    }
32239750e409Sopenharmony_ci
32249750e409Sopenharmony_ci    return (item->type & 0xff) == cJSON_True;
32259750e409Sopenharmony_ci}
32269750e409Sopenharmony_ci
32279750e409Sopenharmony_ci
32289750e409Sopenharmony_ciCJSON_PUBLIC(cJSON_bool) cJSON_IsBool(const cJSON * const item)
32299750e409Sopenharmony_ci{
32309750e409Sopenharmony_ci    if (item == NULL)
32319750e409Sopenharmony_ci    {
32329750e409Sopenharmony_ci        return false;
32339750e409Sopenharmony_ci    }
32349750e409Sopenharmony_ci
32359750e409Sopenharmony_ci    return (item->type & (cJSON_True | cJSON_False)) != 0;
32369750e409Sopenharmony_ci}
32379750e409Sopenharmony_ciCJSON_PUBLIC(cJSON_bool) cJSON_IsNull(const cJSON * const item)
32389750e409Sopenharmony_ci{
32399750e409Sopenharmony_ci    if (item == NULL)
32409750e409Sopenharmony_ci    {
32419750e409Sopenharmony_ci        return false;
32429750e409Sopenharmony_ci    }
32439750e409Sopenharmony_ci
32449750e409Sopenharmony_ci    return (item->type & 0xFF) == cJSON_NULL;
32459750e409Sopenharmony_ci}
32469750e409Sopenharmony_ci
32479750e409Sopenharmony_ci#ifdef __CJSON_USE_INT64
32489750e409Sopenharmony_ciCJSON_PUBLIC(cJSON_bool) cJSON_IsInt64Number(const cJSON * const item)
32499750e409Sopenharmony_ci{
32509750e409Sopenharmony_ci    if (item == NULL)
32519750e409Sopenharmony_ci    {
32529750e409Sopenharmony_ci        return false;
32539750e409Sopenharmony_ci    }
32549750e409Sopenharmony_ci
32559750e409Sopenharmony_ci    return cJSON_IsNumber(item) && (item->type & cJSON_IsInt64);
32569750e409Sopenharmony_ci}
32579750e409Sopenharmony_ci#endif /* __CJSON_USE_INT64 */
32589750e409Sopenharmony_ci
32599750e409Sopenharmony_ciCJSON_PUBLIC(cJSON_bool) cJSON_IsNumber(const cJSON * const item)
32609750e409Sopenharmony_ci{
32619750e409Sopenharmony_ci    if (item == NULL)
32629750e409Sopenharmony_ci    {
32639750e409Sopenharmony_ci        return false;
32649750e409Sopenharmony_ci    }
32659750e409Sopenharmony_ci
32669750e409Sopenharmony_ci    return (item->type & 0xFF) == cJSON_Number;
32679750e409Sopenharmony_ci}
32689750e409Sopenharmony_ci
32699750e409Sopenharmony_ciCJSON_PUBLIC(cJSON_bool) cJSON_IsString(const cJSON * const item)
32709750e409Sopenharmony_ci{
32719750e409Sopenharmony_ci    if (item == NULL)
32729750e409Sopenharmony_ci    {
32739750e409Sopenharmony_ci        return false;
32749750e409Sopenharmony_ci    }
32759750e409Sopenharmony_ci
32769750e409Sopenharmony_ci    return (item->type & 0xFF) == cJSON_String;
32779750e409Sopenharmony_ci}
32789750e409Sopenharmony_ci
32799750e409Sopenharmony_ciCJSON_PUBLIC(cJSON_bool) cJSON_IsArray(const cJSON * const item)
32809750e409Sopenharmony_ci{
32819750e409Sopenharmony_ci    if (item == NULL)
32829750e409Sopenharmony_ci    {
32839750e409Sopenharmony_ci        return false;
32849750e409Sopenharmony_ci    }
32859750e409Sopenharmony_ci
32869750e409Sopenharmony_ci    return (item->type & 0xFF) == cJSON_Array;
32879750e409Sopenharmony_ci}
32889750e409Sopenharmony_ci
32899750e409Sopenharmony_ciCJSON_PUBLIC(cJSON_bool) cJSON_IsObject(const cJSON * const item)
32909750e409Sopenharmony_ci{
32919750e409Sopenharmony_ci    if (item == NULL)
32929750e409Sopenharmony_ci    {
32939750e409Sopenharmony_ci        return false;
32949750e409Sopenharmony_ci    }
32959750e409Sopenharmony_ci
32969750e409Sopenharmony_ci    return (item->type & 0xFF) == cJSON_Object;
32979750e409Sopenharmony_ci}
32989750e409Sopenharmony_ci
32999750e409Sopenharmony_ciCJSON_PUBLIC(cJSON_bool) cJSON_IsRaw(const cJSON * const item)
33009750e409Sopenharmony_ci{
33019750e409Sopenharmony_ci    if (item == NULL)
33029750e409Sopenharmony_ci    {
33039750e409Sopenharmony_ci        return false;
33049750e409Sopenharmony_ci    }
33059750e409Sopenharmony_ci
33069750e409Sopenharmony_ci    return (item->type & 0xFF) == cJSON_Raw;
33079750e409Sopenharmony_ci}
33089750e409Sopenharmony_ci
33099750e409Sopenharmony_ciCJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * const b, const cJSON_bool case_sensitive)
33109750e409Sopenharmony_ci{
33119750e409Sopenharmony_ci    if ((a == NULL) || (b == NULL) || ((a->type & 0xFF) != (b->type & 0xFF)))
33129750e409Sopenharmony_ci    {
33139750e409Sopenharmony_ci        return false;
33149750e409Sopenharmony_ci    }
33159750e409Sopenharmony_ci
33169750e409Sopenharmony_ci    /* check if type is valid */
33179750e409Sopenharmony_ci    switch (a->type & 0xFF)
33189750e409Sopenharmony_ci    {
33199750e409Sopenharmony_ci        case cJSON_False:
33209750e409Sopenharmony_ci        case cJSON_True:
33219750e409Sopenharmony_ci        case cJSON_NULL:
33229750e409Sopenharmony_ci        case cJSON_Number:
33239750e409Sopenharmony_ci        case cJSON_String:
33249750e409Sopenharmony_ci        case cJSON_Raw:
33259750e409Sopenharmony_ci        case cJSON_Array:
33269750e409Sopenharmony_ci        case cJSON_Object:
33279750e409Sopenharmony_ci            break;
33289750e409Sopenharmony_ci
33299750e409Sopenharmony_ci        default:
33309750e409Sopenharmony_ci            return false;
33319750e409Sopenharmony_ci    }
33329750e409Sopenharmony_ci
33339750e409Sopenharmony_ci    /* identical objects are equal */
33349750e409Sopenharmony_ci    if (a == b)
33359750e409Sopenharmony_ci    {
33369750e409Sopenharmony_ci        return true;
33379750e409Sopenharmony_ci    }
33389750e409Sopenharmony_ci
33399750e409Sopenharmony_ci    switch (a->type & 0xFF)
33409750e409Sopenharmony_ci    {
33419750e409Sopenharmony_ci        /* in these cases and equal type is enough */
33429750e409Sopenharmony_ci        case cJSON_False:
33439750e409Sopenharmony_ci        case cJSON_True:
33449750e409Sopenharmony_ci        case cJSON_NULL:
33459750e409Sopenharmony_ci            return true;
33469750e409Sopenharmony_ci
33479750e409Sopenharmony_ci#ifdef __CJSON_USE_INT64
33489750e409Sopenharmony_ci        case cJSON_Number:
33499750e409Sopenharmony_ci            if (!compare_double(a->valuedouble, b->valuedouble))
33509750e409Sopenharmony_ci            {
33519750e409Sopenharmony_ci                return false;
33529750e409Sopenharmony_ci            }
33539750e409Sopenharmony_ci
33549750e409Sopenharmony_ci            if ((a->type & cJSON_IsInt64) != (b->type & cJSON_IsInt64))
33559750e409Sopenharmony_ci            {
33569750e409Sopenharmony_ci                /* cJSON_IsInt64 should also be considered */
33579750e409Sopenharmony_ci                return false;
33589750e409Sopenharmony_ci            }
33599750e409Sopenharmony_ci
33609750e409Sopenharmony_ci            if ((a->type & cJSON_IsInt64) && (b->type & cJSON_IsInt64))
33619750e409Sopenharmony_ci            {
33629750e409Sopenharmony_ci                /* compare valueint if both of them are int64 */
33639750e409Sopenharmony_ci                return a->valueint == b->valueint;
33649750e409Sopenharmony_ci            }
33659750e409Sopenharmony_ci
33669750e409Sopenharmony_ci            return true;
33679750e409Sopenharmony_ci#else
33689750e409Sopenharmony_ci        case cJSON_Number:
33699750e409Sopenharmony_ci            if (compare_double(a->valuedouble, b->valuedouble))
33709750e409Sopenharmony_ci            {
33719750e409Sopenharmony_ci                return true;
33729750e409Sopenharmony_ci            }
33739750e409Sopenharmony_ci            return false;
33749750e409Sopenharmony_ci#endif /* __CJSON_USE_INT64 */
33759750e409Sopenharmony_ci
33769750e409Sopenharmony_ci        case cJSON_String:
33779750e409Sopenharmony_ci        case cJSON_Raw:
33789750e409Sopenharmony_ci            if ((a->valuestring == NULL) || (b->valuestring == NULL))
33799750e409Sopenharmony_ci            {
33809750e409Sopenharmony_ci                return false;
33819750e409Sopenharmony_ci            }
33829750e409Sopenharmony_ci            if (strcmp(a->valuestring, b->valuestring) == 0)
33839750e409Sopenharmony_ci            {
33849750e409Sopenharmony_ci                return true;
33859750e409Sopenharmony_ci            }
33869750e409Sopenharmony_ci
33879750e409Sopenharmony_ci            return false;
33889750e409Sopenharmony_ci
33899750e409Sopenharmony_ci        case cJSON_Array:
33909750e409Sopenharmony_ci        {
33919750e409Sopenharmony_ci            cJSON *a_element = a->child;
33929750e409Sopenharmony_ci            cJSON *b_element = b->child;
33939750e409Sopenharmony_ci
33949750e409Sopenharmony_ci            for (; (a_element != NULL) && (b_element != NULL);)
33959750e409Sopenharmony_ci            {
33969750e409Sopenharmony_ci                if (!cJSON_Compare(a_element, b_element, case_sensitive))
33979750e409Sopenharmony_ci                {
33989750e409Sopenharmony_ci                    return false;
33999750e409Sopenharmony_ci                }
34009750e409Sopenharmony_ci
34019750e409Sopenharmony_ci                a_element = a_element->next;
34029750e409Sopenharmony_ci                b_element = b_element->next;
34039750e409Sopenharmony_ci            }
34049750e409Sopenharmony_ci
34059750e409Sopenharmony_ci            /* one of the arrays is longer than the other */
34069750e409Sopenharmony_ci            if (a_element != b_element) {
34079750e409Sopenharmony_ci                return false;
34089750e409Sopenharmony_ci            }
34099750e409Sopenharmony_ci
34109750e409Sopenharmony_ci            return true;
34119750e409Sopenharmony_ci        }
34129750e409Sopenharmony_ci
34139750e409Sopenharmony_ci        case cJSON_Object:
34149750e409Sopenharmony_ci        {
34159750e409Sopenharmony_ci            cJSON *a_element = NULL;
34169750e409Sopenharmony_ci            cJSON *b_element = NULL;
34179750e409Sopenharmony_ci            cJSON_ArrayForEach(a_element, a)
34189750e409Sopenharmony_ci            {
34199750e409Sopenharmony_ci                /* TODO This has O(n^2) runtime, which is horrible! */
34209750e409Sopenharmony_ci                b_element = get_object_item(b, a_element->string, case_sensitive);
34219750e409Sopenharmony_ci                if (b_element == NULL)
34229750e409Sopenharmony_ci                {
34239750e409Sopenharmony_ci                    return false;
34249750e409Sopenharmony_ci                }
34259750e409Sopenharmony_ci
34269750e409Sopenharmony_ci                if (!cJSON_Compare(a_element, b_element, case_sensitive))
34279750e409Sopenharmony_ci                {
34289750e409Sopenharmony_ci                    return false;
34299750e409Sopenharmony_ci                }
34309750e409Sopenharmony_ci            }
34319750e409Sopenharmony_ci
34329750e409Sopenharmony_ci            /* doing this twice, once on a and b to prevent true comparison if a subset of b
34339750e409Sopenharmony_ci             * TODO: Do this the proper way, this is just a fix for now */
34349750e409Sopenharmony_ci            cJSON_ArrayForEach(b_element, b)
34359750e409Sopenharmony_ci            {
34369750e409Sopenharmony_ci                a_element = get_object_item(a, b_element->string, case_sensitive);
34379750e409Sopenharmony_ci                if (a_element == NULL)
34389750e409Sopenharmony_ci                {
34399750e409Sopenharmony_ci                    return false;
34409750e409Sopenharmony_ci                }
34419750e409Sopenharmony_ci
34429750e409Sopenharmony_ci                if (!cJSON_Compare(b_element, a_element, case_sensitive))
34439750e409Sopenharmony_ci                {
34449750e409Sopenharmony_ci                    return false;
34459750e409Sopenharmony_ci                }
34469750e409Sopenharmony_ci            }
34479750e409Sopenharmony_ci
34489750e409Sopenharmony_ci            return true;
34499750e409Sopenharmony_ci        }
34509750e409Sopenharmony_ci
34519750e409Sopenharmony_ci        default:
34529750e409Sopenharmony_ci            return false;
34539750e409Sopenharmony_ci    }
34549750e409Sopenharmony_ci}
34559750e409Sopenharmony_ci
34569750e409Sopenharmony_ciCJSON_PUBLIC(void *) cJSON_malloc(size_t size)
34579750e409Sopenharmony_ci{
34589750e409Sopenharmony_ci    return global_hooks.allocate(size);
34599750e409Sopenharmony_ci}
34609750e409Sopenharmony_ci
34619750e409Sopenharmony_ciCJSON_PUBLIC(void) cJSON_free(void *object)
34629750e409Sopenharmony_ci{
34639750e409Sopenharmony_ci    global_hooks.deallocate(object);
34649750e409Sopenharmony_ci}
3465