xref: /third_party/vulkan-loader/loader/cJSON.c (revision 5db71995)
15db71995Sopenharmony_ci/*
25db71995Sopenharmony_ci  Copyright (c) 2009 Dave Gamble
35db71995Sopenharmony_ci  Copyright (c) 2015-2021 The Khronos Group Inc.
45db71995Sopenharmony_ci  Copyright (c) 2015-2021 Valve Corporation
55db71995Sopenharmony_ci  Copyright (c) 2015-2021 LunarG, Inc.
65db71995Sopenharmony_ci
75db71995Sopenharmony_ci  Permission is hereby granted, free of charge, to any person obtaining a copy
85db71995Sopenharmony_ci  of this software and associated documentation files (the "Software"), to deal
95db71995Sopenharmony_ci  in the Software without restriction, including without limitation the rights
105db71995Sopenharmony_ci  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
115db71995Sopenharmony_ci  copies of the Software, and to permit persons to whom the Software is
125db71995Sopenharmony_ci  furnished to do so, subject to the following conditions:
135db71995Sopenharmony_ci
145db71995Sopenharmony_ci  The above copyright notice and this permission notice shall be included in
155db71995Sopenharmony_ci  all copies or substantial portions of the Software.
165db71995Sopenharmony_ci
175db71995Sopenharmony_ci  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
185db71995Sopenharmony_ci  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
195db71995Sopenharmony_ci  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
205db71995Sopenharmony_ci  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
215db71995Sopenharmony_ci  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
225db71995Sopenharmony_ci  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
235db71995Sopenharmony_ci  THE SOFTWARE.
245db71995Sopenharmony_ci*/
255db71995Sopenharmony_ci
265db71995Sopenharmony_ci/* cJSON */
275db71995Sopenharmony_ci/* JSON parser in C. */
285db71995Sopenharmony_ci
295db71995Sopenharmony_ci#include <ctype.h>
305db71995Sopenharmony_ci#include <float.h>
315db71995Sopenharmony_ci#include <limits.h>
325db71995Sopenharmony_ci#include <math.h>
335db71995Sopenharmony_ci#include <stdio.h>
345db71995Sopenharmony_ci#include <stdlib.h>
355db71995Sopenharmony_ci#include <string.h>
365db71995Sopenharmony_ci
375db71995Sopenharmony_ci#include "cJSON.h"
385db71995Sopenharmony_ci
395db71995Sopenharmony_ci#include "allocation.h"
405db71995Sopenharmony_ci#include "loader.h"
415db71995Sopenharmony_ci#include "log.h"
425db71995Sopenharmony_ci
435db71995Sopenharmony_cistatic void *cJSON_malloc(const VkAllocationCallbacks *pAllocator, size_t size) {
445db71995Sopenharmony_ci    return loader_calloc(pAllocator, size, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
455db71995Sopenharmony_ci}
465db71995Sopenharmony_ci
475db71995Sopenharmony_cistatic void *cJSON_malloc_instance_scope(const VkAllocationCallbacks *pAllocator, size_t size) {
485db71995Sopenharmony_ci    return loader_calloc(pAllocator, size, VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
495db71995Sopenharmony_ci}
505db71995Sopenharmony_ci
515db71995Sopenharmony_cistatic void cJSON_Free(const VkAllocationCallbacks *pAllocator, void *pMemory) { loader_free(pAllocator, pMemory); }
525db71995Sopenharmony_ci
535db71995Sopenharmony_ci/*
545db71995Sopenharmony_ci// commented out as it is unused - static error code channel requires external locks to be used.
555db71995Sopenharmony_cistatic const char *ep;
565db71995Sopenharmony_ci
575db71995Sopenharmony_ciconst char *cJSON_GetErrorPtr(void) { return ep; }
585db71995Sopenharmony_ci*/
595db71995Sopenharmony_ci
605db71995Sopenharmony_cistatic char *cJSON_strdup(const VkAllocationCallbacks *pAllocator, const char *str) {
615db71995Sopenharmony_ci    size_t len;
625db71995Sopenharmony_ci    char *copy;
635db71995Sopenharmony_ci
645db71995Sopenharmony_ci    len = strlen(str) + 1;
655db71995Sopenharmony_ci    copy = (char *)cJSON_malloc(pAllocator, len);
665db71995Sopenharmony_ci    if (!copy) return 0;
675db71995Sopenharmony_ci    memcpy(copy, str, len);
685db71995Sopenharmony_ci    return copy;
695db71995Sopenharmony_ci}
705db71995Sopenharmony_ci
715db71995Sopenharmony_ci/* Internal constructor. */
725db71995Sopenharmony_cistatic cJSON *cJSON_New_Item(const VkAllocationCallbacks *pAllocator) {
735db71995Sopenharmony_ci    cJSON *node = (cJSON *)cJSON_malloc(pAllocator, sizeof(cJSON));
745db71995Sopenharmony_ci    if (node) {
755db71995Sopenharmony_ci        memset(node, 0, sizeof(cJSON));
765db71995Sopenharmony_ci        node->pAllocator = (VkAllocationCallbacks *)pAllocator;
775db71995Sopenharmony_ci    }
785db71995Sopenharmony_ci    return node;
795db71995Sopenharmony_ci}
805db71995Sopenharmony_ci
815db71995Sopenharmony_ci/* Delete a cJSON structure. */
825db71995Sopenharmony_civoid loader_cJSON_Delete(cJSON *c) {
835db71995Sopenharmony_ci    cJSON *next;
845db71995Sopenharmony_ci    while (c) {
855db71995Sopenharmony_ci        next = c->next;
865db71995Sopenharmony_ci        if (!(c->type & cJSON_IsReference) && c->child) loader_cJSON_Delete(c->child);
875db71995Sopenharmony_ci        if (!(c->type & cJSON_IsReference) && c->valuestring) cJSON_Free(c->pAllocator, c->valuestring);
885db71995Sopenharmony_ci        if (!(c->type & cJSON_StringIsConst) && c->string) cJSON_Free(c->pAllocator, c->string);
895db71995Sopenharmony_ci        cJSON_Free(c->pAllocator, c);
905db71995Sopenharmony_ci        c = next;
915db71995Sopenharmony_ci    }
925db71995Sopenharmony_ci}
935db71995Sopenharmony_ci
945db71995Sopenharmony_ci/* Parse the input text to generate a number, and populate the result into item.
955db71995Sopenharmony_ci */
965db71995Sopenharmony_cistatic const char *parse_number(cJSON *item, const char *num) {
975db71995Sopenharmony_ci    double n = 0, sign = 1, scale = 0;
985db71995Sopenharmony_ci    int subscale = 0, signsubscale = 1;
995db71995Sopenharmony_ci
1005db71995Sopenharmony_ci    if (*num == '-') sign = -1, num++; /* Has sign? */
1015db71995Sopenharmony_ci    if (*num == '0') num++;            /* is zero */
1025db71995Sopenharmony_ci    if (*num >= '1' && *num <= '9') do
1035db71995Sopenharmony_ci            n = (n * 10.0) + (*num++ - '0');
1045db71995Sopenharmony_ci        while (*num >= '0' && *num <= '9'); /* Number? */
1055db71995Sopenharmony_ci    if (*num == '.' && num[1] >= '0' && num[1] <= '9') {
1065db71995Sopenharmony_ci        num++;
1075db71995Sopenharmony_ci        do n = (n * 10.0) + (*num++ - '0'), scale--;
1085db71995Sopenharmony_ci        while (*num >= '0' && *num <= '9');
1095db71995Sopenharmony_ci    }                               /* Fractional part? */
1105db71995Sopenharmony_ci    if (*num == 'e' || *num == 'E') /* Exponent? */
1115db71995Sopenharmony_ci    {
1125db71995Sopenharmony_ci        num++;
1135db71995Sopenharmony_ci        if (*num == '+')
1145db71995Sopenharmony_ci            num++;
1155db71995Sopenharmony_ci        else if (*num == '-')
1165db71995Sopenharmony_ci            signsubscale = -1, num++;                                                   /* With sign? */
1175db71995Sopenharmony_ci        while (*num >= '0' && *num <= '9') subscale = (subscale * 10) + (*num++ - '0'); /* Number? */
1185db71995Sopenharmony_ci    }
1195db71995Sopenharmony_ci
1205db71995Sopenharmony_ci    n = sign * n * pow(10.0, (scale + subscale * signsubscale)); /* number = +/-
1215db71995Sopenharmony_ci                                                                    number.fraction *
1225db71995Sopenharmony_ci                                                                    10^+/- exponent */
1235db71995Sopenharmony_ci
1245db71995Sopenharmony_ci    item->valuedouble = n;
1255db71995Sopenharmony_ci    item->valueint = (int)n;
1265db71995Sopenharmony_ci    item->type = cJSON_Number;
1275db71995Sopenharmony_ci    return num;
1285db71995Sopenharmony_ci}
1295db71995Sopenharmony_ci
1305db71995Sopenharmony_cistatic size_t pow2gt(size_t x) {
1315db71995Sopenharmony_ci    --x;
1325db71995Sopenharmony_ci    x |= x >> 1;
1335db71995Sopenharmony_ci    x |= x >> 2;
1345db71995Sopenharmony_ci    x |= x >> 4;
1355db71995Sopenharmony_ci    x |= x >> 8;
1365db71995Sopenharmony_ci    x |= x >> 16;
1375db71995Sopenharmony_ci    return x + 1;
1385db71995Sopenharmony_ci}
1395db71995Sopenharmony_ci
1405db71995Sopenharmony_citypedef struct {
1415db71995Sopenharmony_ci    char *buffer;
1425db71995Sopenharmony_ci    size_t length;
1435db71995Sopenharmony_ci    size_t offset;
1445db71995Sopenharmony_ci} printbuffer;
1455db71995Sopenharmony_ci
1465db71995Sopenharmony_cistatic char *ensure(const VkAllocationCallbacks *pAllocator, printbuffer *p, size_t needed) {
1475db71995Sopenharmony_ci    char *newbuffer;
1485db71995Sopenharmony_ci    size_t newsize;
1495db71995Sopenharmony_ci    if (!p || !p->buffer) return 0;
1505db71995Sopenharmony_ci    needed += p->offset;
1515db71995Sopenharmony_ci    if (needed <= p->length) return p->buffer + p->offset;
1525db71995Sopenharmony_ci
1535db71995Sopenharmony_ci    newsize = pow2gt(needed);
1545db71995Sopenharmony_ci    newbuffer = (char *)cJSON_malloc(pAllocator, newsize);
1555db71995Sopenharmony_ci    if (!newbuffer) {
1565db71995Sopenharmony_ci        cJSON_Free(pAllocator, p->buffer);
1575db71995Sopenharmony_ci        p->length = 0, p->buffer = 0;
1585db71995Sopenharmony_ci        return 0;
1595db71995Sopenharmony_ci    }
1605db71995Sopenharmony_ci    if (newbuffer) memcpy(newbuffer, p->buffer, p->length);
1615db71995Sopenharmony_ci    cJSON_Free(pAllocator, p->buffer);
1625db71995Sopenharmony_ci    p->length = newsize;
1635db71995Sopenharmony_ci    p->buffer = newbuffer;
1645db71995Sopenharmony_ci    return newbuffer + p->offset;
1655db71995Sopenharmony_ci}
1665db71995Sopenharmony_ci
1675db71995Sopenharmony_cistatic size_t cJSON_update(printbuffer *p) {
1685db71995Sopenharmony_ci    char *str;
1695db71995Sopenharmony_ci    if (!p || !p->buffer) return 0;
1705db71995Sopenharmony_ci    str = p->buffer + p->offset;
1715db71995Sopenharmony_ci    return p->offset + strlen(str);
1725db71995Sopenharmony_ci}
1735db71995Sopenharmony_ci
1745db71995Sopenharmony_ci/* Render the number nicely from the given item into a string. */
1755db71995Sopenharmony_cistatic char *print_number(cJSON *item, printbuffer *p) {
1765db71995Sopenharmony_ci    char *str = 0;
1775db71995Sopenharmony_ci    size_t str_buf_size;
1785db71995Sopenharmony_ci    double d = item->valuedouble;
1795db71995Sopenharmony_ci    if (d == 0) {
1805db71995Sopenharmony_ci        str_buf_size = 2; /* special case for 0. */
1815db71995Sopenharmony_ci        if (p)
1825db71995Sopenharmony_ci            str = ensure(item->pAllocator, p, str_buf_size);
1835db71995Sopenharmony_ci        else
1845db71995Sopenharmony_ci            str = (char *)cJSON_malloc(item->pAllocator, str_buf_size);
1855db71995Sopenharmony_ci        if (str) loader_strncpy(str, str_buf_size, "0", 2);
1865db71995Sopenharmony_ci    } else if (fabs(((double)item->valueint) - d) <= DBL_EPSILON && d <= INT_MAX && d >= INT_MIN) {
1875db71995Sopenharmony_ci        str_buf_size = 21; /* 2^64+1 can be represented in 21 chars. */
1885db71995Sopenharmony_ci        if (p)
1895db71995Sopenharmony_ci            str = ensure(item->pAllocator, p, str_buf_size);
1905db71995Sopenharmony_ci        else
1915db71995Sopenharmony_ci            str = (char *)cJSON_malloc(item->pAllocator, str_buf_size);
1925db71995Sopenharmony_ci        if (str) snprintf(str, str_buf_size, "%d", item->valueint);
1935db71995Sopenharmony_ci    } else {
1945db71995Sopenharmony_ci        str_buf_size = 64; /* This is a nice tradeoff. */
1955db71995Sopenharmony_ci        if (p)
1965db71995Sopenharmony_ci            str = ensure(item->pAllocator, p, str_buf_size);
1975db71995Sopenharmony_ci        else
1985db71995Sopenharmony_ci            str = (char *)cJSON_malloc(item->pAllocator, str_buf_size);
1995db71995Sopenharmony_ci        if (str) {
2005db71995Sopenharmony_ci            if (fabs(floor(d) - d) <= DBL_EPSILON && fabs(d) < 1.0e60)
2015db71995Sopenharmony_ci                snprintf(str, str_buf_size, "%.0f", d);
2025db71995Sopenharmony_ci            else if (fabs(d) < 1.0e-6 || fabs(d) > 1.0e9)
2035db71995Sopenharmony_ci                snprintf(str, str_buf_size, "%e", d);
2045db71995Sopenharmony_ci            else
2055db71995Sopenharmony_ci                snprintf(str, str_buf_size, "%f", d);
2065db71995Sopenharmony_ci        }
2075db71995Sopenharmony_ci    }
2085db71995Sopenharmony_ci    return str;
2095db71995Sopenharmony_ci}
2105db71995Sopenharmony_ci
2115db71995Sopenharmony_cistatic unsigned parse_hex4(const char *str) {
2125db71995Sopenharmony_ci    unsigned h = 0;
2135db71995Sopenharmony_ci    if (*str >= '0' && *str <= '9')
2145db71995Sopenharmony_ci        h += (*str) - '0';
2155db71995Sopenharmony_ci    else if (*str >= 'A' && *str <= 'F')
2165db71995Sopenharmony_ci        h += 10 + (*str) - 'A';
2175db71995Sopenharmony_ci    else if (*str >= 'a' && *str <= 'f')
2185db71995Sopenharmony_ci        h += 10 + (*str) - 'a';
2195db71995Sopenharmony_ci    else
2205db71995Sopenharmony_ci        return 0;
2215db71995Sopenharmony_ci    h = h << 4;
2225db71995Sopenharmony_ci    str++;
2235db71995Sopenharmony_ci    if (*str >= '0' && *str <= '9')
2245db71995Sopenharmony_ci        h += (*str) - '0';
2255db71995Sopenharmony_ci    else if (*str >= 'A' && *str <= 'F')
2265db71995Sopenharmony_ci        h += 10 + (*str) - 'A';
2275db71995Sopenharmony_ci    else if (*str >= 'a' && *str <= 'f')
2285db71995Sopenharmony_ci        h += 10 + (*str) - 'a';
2295db71995Sopenharmony_ci    else
2305db71995Sopenharmony_ci        return 0;
2315db71995Sopenharmony_ci    h = h << 4;
2325db71995Sopenharmony_ci    str++;
2335db71995Sopenharmony_ci    if (*str >= '0' && *str <= '9')
2345db71995Sopenharmony_ci        h += (*str) - '0';
2355db71995Sopenharmony_ci    else if (*str >= 'A' && *str <= 'F')
2365db71995Sopenharmony_ci        h += 10 + (*str) - 'A';
2375db71995Sopenharmony_ci    else if (*str >= 'a' && *str <= 'f')
2385db71995Sopenharmony_ci        h += 10 + (*str) - 'a';
2395db71995Sopenharmony_ci    else
2405db71995Sopenharmony_ci        return 0;
2415db71995Sopenharmony_ci    h = h << 4;
2425db71995Sopenharmony_ci    str++;
2435db71995Sopenharmony_ci    if (*str >= '0' && *str <= '9')
2445db71995Sopenharmony_ci        h += (*str) - '0';
2455db71995Sopenharmony_ci    else if (*str >= 'A' && *str <= 'F')
2465db71995Sopenharmony_ci        h += 10 + (*str) - 'A';
2475db71995Sopenharmony_ci    else if (*str >= 'a' && *str <= 'f')
2485db71995Sopenharmony_ci        h += 10 + (*str) - 'a';
2495db71995Sopenharmony_ci    else
2505db71995Sopenharmony_ci        return 0;
2515db71995Sopenharmony_ci    return h;
2525db71995Sopenharmony_ci}
2535db71995Sopenharmony_ci
2545db71995Sopenharmony_ci/* Parse the input text into an unescaped cstring, and populate item. */
2555db71995Sopenharmony_cistatic const unsigned char firstByteMark[7] = {0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC};
2565db71995Sopenharmony_cistatic const char *parse_string(cJSON *item, const char *str, bool *out_of_memory) {
2575db71995Sopenharmony_ci    const char *ptr = str + 1;
2585db71995Sopenharmony_ci    char *ptr2;
2595db71995Sopenharmony_ci    char *out;
2605db71995Sopenharmony_ci    int len = 0;
2615db71995Sopenharmony_ci    unsigned uc, uc2;
2625db71995Sopenharmony_ci    if (*str != '\"') {
2635db71995Sopenharmony_ci        // ep = str; // commented out as it is unused
2645db71995Sopenharmony_ci        return 0;
2655db71995Sopenharmony_ci    } /* not a string! */
2665db71995Sopenharmony_ci
2675db71995Sopenharmony_ci    while (*ptr != '\"' && *ptr && ++len)
2685db71995Sopenharmony_ci        if (*ptr++ == '\\') ptr++; /* Skip escaped quotes. */
2695db71995Sopenharmony_ci
2705db71995Sopenharmony_ci    out = (char *)cJSON_malloc(item->pAllocator, len + 1); /* This is how long we need for the string, roughly. */
2715db71995Sopenharmony_ci    if (!out) {
2725db71995Sopenharmony_ci        *out_of_memory = true;
2735db71995Sopenharmony_ci        return 0;
2745db71995Sopenharmony_ci    }
2755db71995Sopenharmony_ci
2765db71995Sopenharmony_ci    ptr = str + 1;
2775db71995Sopenharmony_ci    ptr2 = out;
2785db71995Sopenharmony_ci    while (*ptr != '\"' && *ptr) {
2795db71995Sopenharmony_ci        if (*ptr != '\\')
2805db71995Sopenharmony_ci            *ptr2++ = *ptr++;
2815db71995Sopenharmony_ci        else {
2825db71995Sopenharmony_ci            ptr++;
2835db71995Sopenharmony_ci            switch (*ptr) {
2845db71995Sopenharmony_ci                case 'b':
2855db71995Sopenharmony_ci                    *ptr2++ = '\b';
2865db71995Sopenharmony_ci                    break;
2875db71995Sopenharmony_ci                case 'f':
2885db71995Sopenharmony_ci                    *ptr2++ = '\f';
2895db71995Sopenharmony_ci                    break;
2905db71995Sopenharmony_ci                case 'n':
2915db71995Sopenharmony_ci                    *ptr2++ = '\n';
2925db71995Sopenharmony_ci                    break;
2935db71995Sopenharmony_ci                case 'r':
2945db71995Sopenharmony_ci                    *ptr2++ = '\r';
2955db71995Sopenharmony_ci                    break;
2965db71995Sopenharmony_ci                case 't':
2975db71995Sopenharmony_ci                    *ptr2++ = '\t';
2985db71995Sopenharmony_ci                    break;
2995db71995Sopenharmony_ci                case 'u': /* transcode utf16 to utf8. */
3005db71995Sopenharmony_ci                    uc = parse_hex4(ptr + 1);
3015db71995Sopenharmony_ci                    ptr += 4; /* get the unicode char. */
3025db71995Sopenharmony_ci
3035db71995Sopenharmony_ci                    if ((uc >= 0xDC00 && uc <= 0xDFFF) || uc == 0) break; /* check for invalid.	*/
3045db71995Sopenharmony_ci
3055db71995Sopenharmony_ci                    if (uc >= 0xD800 && uc <= 0xDBFF) /* UTF16 surrogate pairs.	*/
3065db71995Sopenharmony_ci                    {
3075db71995Sopenharmony_ci                        if (ptr[1] != '\\' || ptr[2] != 'u') break; /* missing second-half of surrogate.	*/
3085db71995Sopenharmony_ci                        uc2 = parse_hex4(ptr + 3);
3095db71995Sopenharmony_ci                        ptr += 6;
3105db71995Sopenharmony_ci                        if (uc2 < 0xDC00 || uc2 > 0xDFFF) break; /* invalid second-half of surrogate.	*/
3115db71995Sopenharmony_ci                        uc = 0x10000 + (((uc & 0x3FF) << 10) | (uc2 & 0x3FF));
3125db71995Sopenharmony_ci                    }
3135db71995Sopenharmony_ci
3145db71995Sopenharmony_ci                    len = 4;
3155db71995Sopenharmony_ci                    if (uc < 0x80)
3165db71995Sopenharmony_ci                        len = 1;
3175db71995Sopenharmony_ci                    else if (uc < 0x800)
3185db71995Sopenharmony_ci                        len = 2;
3195db71995Sopenharmony_ci                    else if (uc < 0x10000)
3205db71995Sopenharmony_ci                        len = 3;
3215db71995Sopenharmony_ci                    ptr2 += len;
3225db71995Sopenharmony_ci
3235db71995Sopenharmony_ci                    for (size_t i = len; i > 0; i--) {
3245db71995Sopenharmony_ci                        if (i == 1) {
3255db71995Sopenharmony_ci                            *--ptr2 = ((unsigned char)uc | firstByteMark[len]);
3265db71995Sopenharmony_ci                        } else if (i >= 2) {
3275db71995Sopenharmony_ci                            *--ptr2 = ((uc | 0x80) & 0xBF);
3285db71995Sopenharmony_ci                            uc >>= 6;
3295db71995Sopenharmony_ci                        }
3305db71995Sopenharmony_ci                    }
3315db71995Sopenharmony_ci                    ptr2 += len;
3325db71995Sopenharmony_ci                    break;
3335db71995Sopenharmony_ci                default:
3345db71995Sopenharmony_ci                    *ptr2++ = *ptr;
3355db71995Sopenharmony_ci                    break;
3365db71995Sopenharmony_ci            }
3375db71995Sopenharmony_ci            ptr++;
3385db71995Sopenharmony_ci        }
3395db71995Sopenharmony_ci    }
3405db71995Sopenharmony_ci    *ptr2 = 0;
3415db71995Sopenharmony_ci    if (*ptr == '\"') ptr++;
3425db71995Sopenharmony_ci    item->valuestring = out;
3435db71995Sopenharmony_ci    item->type = cJSON_String;
3445db71995Sopenharmony_ci    return ptr;
3455db71995Sopenharmony_ci}
3465db71995Sopenharmony_ci
3475db71995Sopenharmony_ci/* Render the cstring provided to an escaped version that can be printed. */
3485db71995Sopenharmony_cistatic char *print_string_ptr(const VkAllocationCallbacks *pAllocator, const char *str, printbuffer *p) {
3495db71995Sopenharmony_ci    const char *ptr;
3505db71995Sopenharmony_ci    char *ptr2;
3515db71995Sopenharmony_ci    char *out;
3525db71995Sopenharmony_ci    size_t out_buf_size, len = 0, flag = 0;
3535db71995Sopenharmony_ci    unsigned char token;
3545db71995Sopenharmony_ci
3555db71995Sopenharmony_ci    for (ptr = str; *ptr; ptr++) flag |= ((*ptr > 0 && *ptr < 32) || (*ptr == '\"') || (*ptr == '\\')) ? 1 : 0;
3565db71995Sopenharmony_ci    if (!flag) {
3575db71995Sopenharmony_ci        len = ptr - str;
3585db71995Sopenharmony_ci        out_buf_size = len + 1;
3595db71995Sopenharmony_ci        // out_buf_size = len + 3; // Modified to not put quotes around the string
3605db71995Sopenharmony_ci        if (p)
3615db71995Sopenharmony_ci            out = ensure(pAllocator, p, out_buf_size);
3625db71995Sopenharmony_ci        else
3635db71995Sopenharmony_ci            out = (char *)cJSON_malloc_instance_scope(pAllocator, out_buf_size);
3645db71995Sopenharmony_ci        if (!out) return 0;
3655db71995Sopenharmony_ci        ptr2 = out;
3665db71995Sopenharmony_ci        // *ptr2++ = '\"'; // Modified to not put quotes around the string
3675db71995Sopenharmony_ci        loader_strncpy(ptr2, out_buf_size, str, out_buf_size);
3685db71995Sopenharmony_ci        // ptr2[len] = '\"'; // Modified to not put quotes around the string
3695db71995Sopenharmony_ci        ptr2[len] = 0;  // ptr2[len + 1] = 0; // Modified to not put quotes around the string
3705db71995Sopenharmony_ci        return out;
3715db71995Sopenharmony_ci    }
3725db71995Sopenharmony_ci
3735db71995Sopenharmony_ci    if (!str) {
3745db71995Sopenharmony_ci        out_buf_size = 3;
3755db71995Sopenharmony_ci        if (p)
3765db71995Sopenharmony_ci            out = ensure(pAllocator, p, out_buf_size);
3775db71995Sopenharmony_ci        else
3785db71995Sopenharmony_ci            out = (char *)cJSON_malloc_instance_scope(pAllocator, out_buf_size);
3795db71995Sopenharmony_ci        if (!out) return 0;
3805db71995Sopenharmony_ci        loader_strncpy(out, out_buf_size, "\"\"", 3);
3815db71995Sopenharmony_ci        return out;
3825db71995Sopenharmony_ci    }
3835db71995Sopenharmony_ci    ptr = str;
3845db71995Sopenharmony_ci    token = *ptr;
3855db71995Sopenharmony_ci    while (token && ++len) {
3865db71995Sopenharmony_ci        if (strchr("\"\\\b\f\n\r\t", token))
3875db71995Sopenharmony_ci            len++;
3885db71995Sopenharmony_ci        else if (token < 32)
3895db71995Sopenharmony_ci            len += 5;
3905db71995Sopenharmony_ci        ptr++;
3915db71995Sopenharmony_ci        token = *ptr;
3925db71995Sopenharmony_ci    }
3935db71995Sopenharmony_ci
3945db71995Sopenharmony_ci    out_buf_size = len + 1;
3955db71995Sopenharmony_ci    // out_buf_size = len + 3; // Modified to not put quotes around the string
3965db71995Sopenharmony_ci    if (p)
3975db71995Sopenharmony_ci        out = ensure(pAllocator, p, out_buf_size);
3985db71995Sopenharmony_ci    else
3995db71995Sopenharmony_ci        out = (char *)cJSON_malloc_instance_scope(pAllocator, out_buf_size);
4005db71995Sopenharmony_ci    if (!out) return 0;
4015db71995Sopenharmony_ci
4025db71995Sopenharmony_ci    ptr2 = out;
4035db71995Sopenharmony_ci    ptr = str;
4045db71995Sopenharmony_ci    // *ptr2++ = '\"'; // Modified to not put quotes around the string
4055db71995Sopenharmony_ci    while (*ptr) {
4065db71995Sopenharmony_ci        if ((unsigned char)*ptr > 31 && *ptr != '\"' && *ptr != '\\')
4075db71995Sopenharmony_ci            *ptr2++ = *ptr++;
4085db71995Sopenharmony_ci        else {
4095db71995Sopenharmony_ci            switch (token = *ptr++) {
4105db71995Sopenharmony_ci                case '\\':
4115db71995Sopenharmony_ci                    *ptr2++ = '\\';
4125db71995Sopenharmony_ci                    break;
4135db71995Sopenharmony_ci                case '\"':
4145db71995Sopenharmony_ci                    *ptr2++ = '\"';
4155db71995Sopenharmony_ci                    break;
4165db71995Sopenharmony_ci                case '\b':
4175db71995Sopenharmony_ci                    *ptr2++ = '\b';
4185db71995Sopenharmony_ci                    break;
4195db71995Sopenharmony_ci                case '\f':
4205db71995Sopenharmony_ci                    *ptr2++ = '\f';
4215db71995Sopenharmony_ci                    break;
4225db71995Sopenharmony_ci                case '\n':
4235db71995Sopenharmony_ci                    *ptr2++ = '\n';
4245db71995Sopenharmony_ci                    break;
4255db71995Sopenharmony_ci                case '\r':
4265db71995Sopenharmony_ci                    *ptr2++ = '\r';
4275db71995Sopenharmony_ci                    break;
4285db71995Sopenharmony_ci                case '\t':
4295db71995Sopenharmony_ci                    *ptr2++ = '\t';
4305db71995Sopenharmony_ci                    break;
4315db71995Sopenharmony_ci                default:
4325db71995Sopenharmony_ci                    snprintf(ptr2, out_buf_size - (ptr2 - out), "u%04x", token);
4335db71995Sopenharmony_ci                    ptr2 += 5;
4345db71995Sopenharmony_ci                    break; /* escape and print */
4355db71995Sopenharmony_ci            }
4365db71995Sopenharmony_ci        }
4375db71995Sopenharmony_ci    }
4385db71995Sopenharmony_ci    // *ptr2++ = '\"'; // Modified to not put quotes around the string
4395db71995Sopenharmony_ci    *ptr2++ = 0;
4405db71995Sopenharmony_ci    return out;
4415db71995Sopenharmony_ci}
4425db71995Sopenharmony_ci/* Invoke print_string_ptr (which is useful) on an item. */
4435db71995Sopenharmony_cistatic char *print_string(cJSON *item, printbuffer *p) { return print_string_ptr(item->pAllocator, item->valuestring, p); }
4445db71995Sopenharmony_ci
4455db71995Sopenharmony_ci/* Declare these prototypes. */
4465db71995Sopenharmony_cistatic const char *parse_value(cJSON *item, const char *value, bool *out_of_memory);
4475db71995Sopenharmony_cistatic char *print_value(cJSON *item, int depth, int fmt, printbuffer *p);
4485db71995Sopenharmony_cistatic const char *parse_array(cJSON *item, const char *value, bool *out_of_memory);
4495db71995Sopenharmony_cistatic char *print_array(cJSON *item, int depth, int fmt, printbuffer *p);
4505db71995Sopenharmony_cistatic const char *parse_object(cJSON *item, const char *value, bool *out_of_memory);
4515db71995Sopenharmony_cistatic char *print_object(cJSON *item, int depth, int fmt, printbuffer *p);
4525db71995Sopenharmony_ci
4535db71995Sopenharmony_ci/* Utility to jump whitespace and cr/lf */
4545db71995Sopenharmony_cistatic const char *skip(const char *in) {
4555db71995Sopenharmony_ci    while (in && *in && (unsigned char)*in <= 32) in++;
4565db71995Sopenharmony_ci    return in;
4575db71995Sopenharmony_ci}
4585db71995Sopenharmony_ci
4595db71995Sopenharmony_ci/* Parse an object - create a new root, and populate. */
4605db71995Sopenharmony_cistatic cJSON *cJSON_ParseWithOpts(const VkAllocationCallbacks *pAllocator, const char *value, const char **return_parse_end,
4615db71995Sopenharmony_ci                                  int require_null_terminated, bool *out_of_memory) {
4625db71995Sopenharmony_ci    const char *end = 0;
4635db71995Sopenharmony_ci    cJSON *c = cJSON_New_Item(pAllocator);
4645db71995Sopenharmony_ci    // ep = 0; // commented out as it is unused
4655db71995Sopenharmony_ci    if (!c) {
4665db71995Sopenharmony_ci        *out_of_memory = true;
4675db71995Sopenharmony_ci        return 0; /* memory fail */
4685db71995Sopenharmony_ci    }
4695db71995Sopenharmony_ci
4705db71995Sopenharmony_ci    end = parse_value(c, skip(value), out_of_memory);
4715db71995Sopenharmony_ci    if (!end) {
4725db71995Sopenharmony_ci        loader_cJSON_Delete(c);
4735db71995Sopenharmony_ci        return 0;
4745db71995Sopenharmony_ci    } /* parse failure. ep is set. */
4755db71995Sopenharmony_ci
4765db71995Sopenharmony_ci    /* if we require null-terminated JSON without appended garbage, skip and
4775db71995Sopenharmony_ci     * then check for a null terminator */
4785db71995Sopenharmony_ci    if (require_null_terminated) {
4795db71995Sopenharmony_ci        end = skip(end);
4805db71995Sopenharmony_ci        if (*end) {
4815db71995Sopenharmony_ci            loader_cJSON_Delete(c);
4825db71995Sopenharmony_ci            // ep = end; // commented out as it is unused
4835db71995Sopenharmony_ci            return 0;
4845db71995Sopenharmony_ci        }
4855db71995Sopenharmony_ci    }
4865db71995Sopenharmony_ci    if (return_parse_end) *return_parse_end = end;
4875db71995Sopenharmony_ci    return c;
4885db71995Sopenharmony_ci}
4895db71995Sopenharmony_ci/* Default options for cJSON_Parse */
4905db71995Sopenharmony_cistatic cJSON *cJSON_Parse(const VkAllocationCallbacks *pAllocator, const char *value, bool *out_of_memory) {
4915db71995Sopenharmony_ci    return cJSON_ParseWithOpts(pAllocator, value, 0, 0, out_of_memory);
4925db71995Sopenharmony_ci}
4935db71995Sopenharmony_ci
4945db71995Sopenharmony_ci/* Render a cJSON item/entity/structure to text. */
4955db71995Sopenharmony_cichar *loader_cJSON_Print(cJSON *item) { return print_value(item, 0, 1, 0); }
4965db71995Sopenharmony_cichar *loader_cJSON_PrintUnformatted(cJSON *item) { return print_value(item, 0, 0, 0); }
4975db71995Sopenharmony_ci
4985db71995Sopenharmony_ci/* Parser core - when encountering text, process appropriately. */
4995db71995Sopenharmony_cistatic const char *parse_value(cJSON *item, const char *value, bool *out_of_memory) {
5005db71995Sopenharmony_ci    if (!value) return 0; /* Fail on null. */
5015db71995Sopenharmony_ci    if (!strncmp(value, "null", 4)) {
5025db71995Sopenharmony_ci        item->type = cJSON_NULL;
5035db71995Sopenharmony_ci        return value + 4;
5045db71995Sopenharmony_ci    }
5055db71995Sopenharmony_ci    if (!strncmp(value, "false", 5)) {
5065db71995Sopenharmony_ci        item->type = cJSON_False;
5075db71995Sopenharmony_ci        return value + 5;
5085db71995Sopenharmony_ci    }
5095db71995Sopenharmony_ci    if (!strncmp(value, "true", 4)) {
5105db71995Sopenharmony_ci        item->type = cJSON_True;
5115db71995Sopenharmony_ci        item->valueint = 1;
5125db71995Sopenharmony_ci        return value + 4;
5135db71995Sopenharmony_ci    }
5145db71995Sopenharmony_ci    if (*value == '\"') {
5155db71995Sopenharmony_ci        return parse_string(item, value, out_of_memory);
5165db71995Sopenharmony_ci    }
5175db71995Sopenharmony_ci    if (*value == '-' || (*value >= '0' && *value <= '9')) {
5185db71995Sopenharmony_ci        return parse_number(item, value);
5195db71995Sopenharmony_ci    }
5205db71995Sopenharmony_ci    if (*value == '[') {
5215db71995Sopenharmony_ci        return parse_array(item, value, out_of_memory);
5225db71995Sopenharmony_ci    }
5235db71995Sopenharmony_ci    if (*value == '{') {
5245db71995Sopenharmony_ci        return parse_object(item, value, out_of_memory);
5255db71995Sopenharmony_ci    }
5265db71995Sopenharmony_ci
5275db71995Sopenharmony_ci    // ep = value; // commented out as it is unused
5285db71995Sopenharmony_ci    return 0; /* failure. */
5295db71995Sopenharmony_ci}
5305db71995Sopenharmony_ci
5315db71995Sopenharmony_ci/* Render a value to text. */
5325db71995Sopenharmony_cistatic char *print_value(cJSON *item, int depth, int fmt, printbuffer *p) {
5335db71995Sopenharmony_ci    char *out = 0;
5345db71995Sopenharmony_ci    if (!item) return 0;
5355db71995Sopenharmony_ci    if (p) {
5365db71995Sopenharmony_ci        switch ((item->type) & 255) {
5375db71995Sopenharmony_ci            case cJSON_NULL: {
5385db71995Sopenharmony_ci                out = ensure(item->pAllocator, p, 5);
5395db71995Sopenharmony_ci                if (out) loader_strncpy(out, 5, "null", 5);
5405db71995Sopenharmony_ci                break;
5415db71995Sopenharmony_ci            }
5425db71995Sopenharmony_ci            case cJSON_False: {
5435db71995Sopenharmony_ci                out = ensure(item->pAllocator, p, 6);
5445db71995Sopenharmony_ci                if (out) loader_strncpy(out, 6, "false", 6);
5455db71995Sopenharmony_ci                break;
5465db71995Sopenharmony_ci            }
5475db71995Sopenharmony_ci            case cJSON_True: {
5485db71995Sopenharmony_ci                out = ensure(item->pAllocator, p, 5);
5495db71995Sopenharmony_ci                if (out) loader_strncpy(out, 5, "true", 5);
5505db71995Sopenharmony_ci                break;
5515db71995Sopenharmony_ci            }
5525db71995Sopenharmony_ci            case cJSON_Number:
5535db71995Sopenharmony_ci                out = print_number(item, p);
5545db71995Sopenharmony_ci                break;
5555db71995Sopenharmony_ci            case cJSON_String:
5565db71995Sopenharmony_ci                out = print_string(item, p);
5575db71995Sopenharmony_ci                break;
5585db71995Sopenharmony_ci            case cJSON_Array:
5595db71995Sopenharmony_ci                out = print_array(item, depth, fmt, p);
5605db71995Sopenharmony_ci                break;
5615db71995Sopenharmony_ci            case cJSON_Object:
5625db71995Sopenharmony_ci                out = print_object(item, depth, fmt, p);
5635db71995Sopenharmony_ci                break;
5645db71995Sopenharmony_ci        }
5655db71995Sopenharmony_ci    } else {
5665db71995Sopenharmony_ci        switch ((item->type) & 255) {
5675db71995Sopenharmony_ci            case cJSON_NULL:
5685db71995Sopenharmony_ci                out = cJSON_strdup(item->pAllocator, "null");
5695db71995Sopenharmony_ci                break;
5705db71995Sopenharmony_ci            case cJSON_False:
5715db71995Sopenharmony_ci                out = cJSON_strdup(item->pAllocator, "false");
5725db71995Sopenharmony_ci                break;
5735db71995Sopenharmony_ci            case cJSON_True:
5745db71995Sopenharmony_ci                out = cJSON_strdup(item->pAllocator, "true");
5755db71995Sopenharmony_ci                break;
5765db71995Sopenharmony_ci            case cJSON_Number:
5775db71995Sopenharmony_ci                out = print_number(item, 0);
5785db71995Sopenharmony_ci                break;
5795db71995Sopenharmony_ci            case cJSON_String:
5805db71995Sopenharmony_ci                out = print_string(item, 0);
5815db71995Sopenharmony_ci                break;
5825db71995Sopenharmony_ci            case cJSON_Array:
5835db71995Sopenharmony_ci                out = print_array(item, depth, fmt, 0);
5845db71995Sopenharmony_ci                break;
5855db71995Sopenharmony_ci            case cJSON_Object:
5865db71995Sopenharmony_ci                out = print_object(item, depth, fmt, 0);
5875db71995Sopenharmony_ci                break;
5885db71995Sopenharmony_ci        }
5895db71995Sopenharmony_ci    }
5905db71995Sopenharmony_ci    return out;
5915db71995Sopenharmony_ci}
5925db71995Sopenharmony_ci
5935db71995Sopenharmony_ci/* Build an array from input text. */
5945db71995Sopenharmony_cistatic const char *parse_array(cJSON *item, const char *value, bool *out_of_memory) {
5955db71995Sopenharmony_ci    cJSON *child;
5965db71995Sopenharmony_ci    if (*value != '[') {
5975db71995Sopenharmony_ci        // ep = value; // commented out as it is unused
5985db71995Sopenharmony_ci        return 0;
5995db71995Sopenharmony_ci    } /* not an array! */
6005db71995Sopenharmony_ci
6015db71995Sopenharmony_ci    item->type = cJSON_Array;
6025db71995Sopenharmony_ci    value = skip(value + 1);
6035db71995Sopenharmony_ci    if (*value == ']') return value + 1; /* empty array. */
6045db71995Sopenharmony_ci
6055db71995Sopenharmony_ci    item->child = child = cJSON_New_Item(item->pAllocator);
6065db71995Sopenharmony_ci    if (!item->child) {
6075db71995Sopenharmony_ci        *out_of_memory = true;
6085db71995Sopenharmony_ci        return 0; /* memory fail */
6095db71995Sopenharmony_ci    }
6105db71995Sopenharmony_ci    value = skip(parse_value(child, skip(value), out_of_memory)); /* skip any spacing, get the value. */
6115db71995Sopenharmony_ci    if (!value) return 0;
6125db71995Sopenharmony_ci
6135db71995Sopenharmony_ci    while (*value == ',') {
6145db71995Sopenharmony_ci        cJSON *new_item;
6155db71995Sopenharmony_ci        new_item = cJSON_New_Item(item->pAllocator);
6165db71995Sopenharmony_ci        if (!new_item) {
6175db71995Sopenharmony_ci            *out_of_memory = true;
6185db71995Sopenharmony_ci            return 0; /* memory fail */
6195db71995Sopenharmony_ci        }
6205db71995Sopenharmony_ci        child->next = new_item;
6215db71995Sopenharmony_ci        new_item->prev = child;
6225db71995Sopenharmony_ci        child = new_item;
6235db71995Sopenharmony_ci        value = skip(parse_value(child, skip(value + 1), out_of_memory));
6245db71995Sopenharmony_ci        if (!value) return 0; /* memory fail */
6255db71995Sopenharmony_ci    }
6265db71995Sopenharmony_ci
6275db71995Sopenharmony_ci    if (*value == ']') return value + 1; /* end of array */
6285db71995Sopenharmony_ci    // ep = value; // commented out as it is unused
6295db71995Sopenharmony_ci    return 0; /* malformed. */
6305db71995Sopenharmony_ci}
6315db71995Sopenharmony_ci
6325db71995Sopenharmony_ci/* Render an array to text */
6335db71995Sopenharmony_cistatic char *print_array(cJSON *item, int depth, int fmt, printbuffer *p) {
6345db71995Sopenharmony_ci    char **entries;
6355db71995Sopenharmony_ci    char *out = 0, *ptr, *ret;
6365db71995Sopenharmony_ci    size_t len = 5;
6375db71995Sopenharmony_ci    cJSON *child = item->child;
6385db71995Sopenharmony_ci    int numentries = 0, fail = 0, j = 0;
6395db71995Sopenharmony_ci    size_t tmplen = 0, i = 0;
6405db71995Sopenharmony_ci
6415db71995Sopenharmony_ci    /* How many entries in the array? */
6425db71995Sopenharmony_ci    while (child) numentries++, child = child->next;
6435db71995Sopenharmony_ci    /* Explicitly handle numentries==0 */
6445db71995Sopenharmony_ci    if (!numentries) {
6455db71995Sopenharmony_ci        if (p)
6465db71995Sopenharmony_ci            out = ensure(item->pAllocator, p, 3);
6475db71995Sopenharmony_ci        else
6485db71995Sopenharmony_ci            out = (char *)cJSON_malloc(item->pAllocator, 3);
6495db71995Sopenharmony_ci        if (out) loader_strncpy(out, 3, "[]", 3);
6505db71995Sopenharmony_ci        return out;
6515db71995Sopenharmony_ci    }
6525db71995Sopenharmony_ci
6535db71995Sopenharmony_ci    if (p) {
6545db71995Sopenharmony_ci        /* Compose the output array. */
6555db71995Sopenharmony_ci        i = p->offset;
6565db71995Sopenharmony_ci        ptr = ensure(item->pAllocator, p, 1);
6575db71995Sopenharmony_ci        if (!ptr) return 0;
6585db71995Sopenharmony_ci        *ptr = '[';
6595db71995Sopenharmony_ci        p->offset++;
6605db71995Sopenharmony_ci        child = item->child;
6615db71995Sopenharmony_ci        while (child && !fail) {
6625db71995Sopenharmony_ci            print_value(child, depth + 1, fmt, p);
6635db71995Sopenharmony_ci            p->offset = cJSON_update(p);
6645db71995Sopenharmony_ci            if (child->next) {
6655db71995Sopenharmony_ci                len = fmt ? 2 : 1;
6665db71995Sopenharmony_ci                ptr = ensure(item->pAllocator, p, len + 1);
6675db71995Sopenharmony_ci                if (!ptr) return 0;
6685db71995Sopenharmony_ci                *ptr++ = ',';
6695db71995Sopenharmony_ci                if (fmt) *ptr++ = ' ';
6705db71995Sopenharmony_ci                *ptr = 0;
6715db71995Sopenharmony_ci                p->offset += len;
6725db71995Sopenharmony_ci            }
6735db71995Sopenharmony_ci            child = child->next;
6745db71995Sopenharmony_ci        }
6755db71995Sopenharmony_ci        ptr = ensure(item->pAllocator, p, 2);
6765db71995Sopenharmony_ci        if (!ptr) return 0;
6775db71995Sopenharmony_ci        *ptr++ = ']';
6785db71995Sopenharmony_ci        *ptr = 0;
6795db71995Sopenharmony_ci        out = (p->buffer) + i;
6805db71995Sopenharmony_ci    } else {
6815db71995Sopenharmony_ci        /* Allocate an array to hold the values for each */
6825db71995Sopenharmony_ci        entries = (char **)cJSON_malloc(item->pAllocator, numentries * sizeof(char *));
6835db71995Sopenharmony_ci        if (!entries) return 0;
6845db71995Sopenharmony_ci        memset(entries, 0, numentries * sizeof(char *));
6855db71995Sopenharmony_ci        /* Retrieve all the results: */
6865db71995Sopenharmony_ci        child = item->child;
6875db71995Sopenharmony_ci        while (child && !fail) {
6885db71995Sopenharmony_ci            ret = print_value(child, depth + 1, fmt, 0);
6895db71995Sopenharmony_ci            entries[i++] = ret;
6905db71995Sopenharmony_ci            if (ret)
6915db71995Sopenharmony_ci                len += strlen(ret) + 2 + (fmt ? 1 : 0);
6925db71995Sopenharmony_ci            else
6935db71995Sopenharmony_ci                fail = 1;
6945db71995Sopenharmony_ci            child = child->next;
6955db71995Sopenharmony_ci        }
6965db71995Sopenharmony_ci
6975db71995Sopenharmony_ci        /* If we didn't fail, try to malloc the output string */
6985db71995Sopenharmony_ci        if (!fail) out = (char *)cJSON_malloc(item->pAllocator, len);
6995db71995Sopenharmony_ci        /* If that fails, we fail. */
7005db71995Sopenharmony_ci        if (!out) fail = 1;
7015db71995Sopenharmony_ci
7025db71995Sopenharmony_ci        /* Handle failure. */
7035db71995Sopenharmony_ci        if (fail) {
7045db71995Sopenharmony_ci            for (j = 0; j < numentries; j++)
7055db71995Sopenharmony_ci                if (entries[j]) cJSON_Free(item->pAllocator, entries[j]);
7065db71995Sopenharmony_ci            cJSON_Free(item->pAllocator, entries);
7075db71995Sopenharmony_ci            return 0;
7085db71995Sopenharmony_ci        }
7095db71995Sopenharmony_ci
7105db71995Sopenharmony_ci        /* Compose the output array. */
7115db71995Sopenharmony_ci        *out = '[';
7125db71995Sopenharmony_ci        ptr = out + 1;
7135db71995Sopenharmony_ci        *ptr = 0;
7145db71995Sopenharmony_ci        for (j = 0; j < numentries; j++) {
7155db71995Sopenharmony_ci            tmplen = strlen(entries[j]);
7165db71995Sopenharmony_ci            memcpy(ptr, entries[j], tmplen);
7175db71995Sopenharmony_ci            ptr += tmplen;
7185db71995Sopenharmony_ci            if (j != numentries - 1) {
7195db71995Sopenharmony_ci                *ptr++ = ',';
7205db71995Sopenharmony_ci                if (fmt) *ptr++ = ' ';
7215db71995Sopenharmony_ci                *ptr = 0;
7225db71995Sopenharmony_ci            }
7235db71995Sopenharmony_ci            cJSON_Free(item->pAllocator, entries[j]);
7245db71995Sopenharmony_ci        }
7255db71995Sopenharmony_ci        cJSON_Free(item->pAllocator, entries);
7265db71995Sopenharmony_ci        *ptr++ = ']';
7275db71995Sopenharmony_ci        *ptr++ = 0;
7285db71995Sopenharmony_ci    }
7295db71995Sopenharmony_ci    return out;
7305db71995Sopenharmony_ci}
7315db71995Sopenharmony_ci
7325db71995Sopenharmony_ci/* Build an object from the text. */
7335db71995Sopenharmony_cistatic const char *parse_object(cJSON *item, const char *value, bool *out_of_memory) {
7345db71995Sopenharmony_ci    cJSON *child;
7355db71995Sopenharmony_ci    if (*value != '{') {
7365db71995Sopenharmony_ci        // ep = value; // commented out as it is unused
7375db71995Sopenharmony_ci        return 0;
7385db71995Sopenharmony_ci    } /* not an object! */
7395db71995Sopenharmony_ci
7405db71995Sopenharmony_ci    item->type = cJSON_Object;
7415db71995Sopenharmony_ci    value = skip(value + 1);
7425db71995Sopenharmony_ci    if (*value == '}') return value + 1; /* empty array. */
7435db71995Sopenharmony_ci
7445db71995Sopenharmony_ci    item->child = child = cJSON_New_Item(item->pAllocator);
7455db71995Sopenharmony_ci    if (!item->child) {
7465db71995Sopenharmony_ci        *out_of_memory = true;
7475db71995Sopenharmony_ci        return 0;
7485db71995Sopenharmony_ci    }
7495db71995Sopenharmony_ci    value = skip(parse_string(child, skip(value), out_of_memory));
7505db71995Sopenharmony_ci    if (!value) return 0;
7515db71995Sopenharmony_ci    child->string = child->valuestring;
7525db71995Sopenharmony_ci    child->valuestring = 0;
7535db71995Sopenharmony_ci    if (*value != ':') {
7545db71995Sopenharmony_ci        // ep = value; // commented out as it is unused
7555db71995Sopenharmony_ci        return 0;
7565db71995Sopenharmony_ci    }                                                                 /* fail! */
7575db71995Sopenharmony_ci    value = skip(parse_value(child, skip(value + 1), out_of_memory)); /* skip any spacing, get the value. */
7585db71995Sopenharmony_ci    if (!value) return 0;
7595db71995Sopenharmony_ci
7605db71995Sopenharmony_ci    while (*value == ',') {
7615db71995Sopenharmony_ci        cJSON *new_item;
7625db71995Sopenharmony_ci        new_item = cJSON_New_Item(item->pAllocator);
7635db71995Sopenharmony_ci        if (!new_item) {
7645db71995Sopenharmony_ci            *out_of_memory = true;
7655db71995Sopenharmony_ci            return 0; /* memory fail */
7665db71995Sopenharmony_ci        }
7675db71995Sopenharmony_ci        child->next = new_item;
7685db71995Sopenharmony_ci        new_item->prev = child;
7695db71995Sopenharmony_ci        child = new_item;
7705db71995Sopenharmony_ci        value = skip(parse_string(child, skip(value + 1), out_of_memory));
7715db71995Sopenharmony_ci        if (!value) return 0;
7725db71995Sopenharmony_ci        child->string = child->valuestring;
7735db71995Sopenharmony_ci        child->valuestring = 0;
7745db71995Sopenharmony_ci        if (*value != ':') {
7755db71995Sopenharmony_ci            // ep = value; // commented out as it is unused
7765db71995Sopenharmony_ci            return 0;
7775db71995Sopenharmony_ci        }                                                                 /* fail! */
7785db71995Sopenharmony_ci        value = skip(parse_value(child, skip(value + 1), out_of_memory)); /* skip any spacing, get the value. */
7795db71995Sopenharmony_ci        if (!value) return 0;
7805db71995Sopenharmony_ci    }
7815db71995Sopenharmony_ci
7825db71995Sopenharmony_ci    if (*value == '}') return value + 1; /* end of array */
7835db71995Sopenharmony_ci    // ep = value; // commented out as it is unused
7845db71995Sopenharmony_ci    return 0; /* malformed. */
7855db71995Sopenharmony_ci}
7865db71995Sopenharmony_ci
7875db71995Sopenharmony_ci/* Render an object to text. */
7885db71995Sopenharmony_cistatic char *print_object(cJSON *item, int depth, int fmt, printbuffer *p) {
7895db71995Sopenharmony_ci    char **entries = 0, **names = 0;
7905db71995Sopenharmony_ci    char *out = 0, *ptr, *ret, *str;
7915db71995Sopenharmony_ci    int j;
7925db71995Sopenharmony_ci    cJSON *child = item->child;
7935db71995Sopenharmony_ci    int numentries = 0, fail = 0, k;
7945db71995Sopenharmony_ci    size_t tmplen = 0, i = 0, len = 7;
7955db71995Sopenharmony_ci    /* Count the number of entries. */
7965db71995Sopenharmony_ci    while (child) numentries++, child = child->next;
7975db71995Sopenharmony_ci    /* Explicitly handle empty object case */
7985db71995Sopenharmony_ci    if (!numentries) {
7995db71995Sopenharmony_ci        if (p)
8005db71995Sopenharmony_ci            out = ensure(item->pAllocator, p, fmt ? depth + 4 : 3);
8015db71995Sopenharmony_ci        else
8025db71995Sopenharmony_ci            out = (char *)cJSON_malloc(item->pAllocator, fmt ? depth + 4 : 3);
8035db71995Sopenharmony_ci        if (!out) return 0;
8045db71995Sopenharmony_ci        ptr = out;
8055db71995Sopenharmony_ci        *ptr++ = '{';
8065db71995Sopenharmony_ci        if (fmt) {
8075db71995Sopenharmony_ci            *ptr++ = '\n';
8085db71995Sopenharmony_ci            for (j = 0; j < depth - 1; j++) *ptr++ = '\t';
8095db71995Sopenharmony_ci        }
8105db71995Sopenharmony_ci        *ptr++ = '}';
8115db71995Sopenharmony_ci        *ptr++ = 0;
8125db71995Sopenharmony_ci        return out;
8135db71995Sopenharmony_ci    }
8145db71995Sopenharmony_ci    if (p) {
8155db71995Sopenharmony_ci        /* Compose the output: */
8165db71995Sopenharmony_ci        i = p->offset;
8175db71995Sopenharmony_ci        len = fmt ? 2 : 1;
8185db71995Sopenharmony_ci        ptr = ensure(item->pAllocator, p, len + 1);
8195db71995Sopenharmony_ci        if (!ptr) return 0;
8205db71995Sopenharmony_ci        *ptr++ = '{';
8215db71995Sopenharmony_ci        if (fmt) *ptr++ = '\n';
8225db71995Sopenharmony_ci        *ptr = 0;
8235db71995Sopenharmony_ci        p->offset += len;
8245db71995Sopenharmony_ci        child = item->child;
8255db71995Sopenharmony_ci        depth++;
8265db71995Sopenharmony_ci        while (child) {
8275db71995Sopenharmony_ci            if (fmt) {
8285db71995Sopenharmony_ci                ptr = ensure(item->pAllocator, p, depth);
8295db71995Sopenharmony_ci                if (!ptr) return 0;
8305db71995Sopenharmony_ci                for (j = 0; j < depth; j++) *ptr++ = '\t';
8315db71995Sopenharmony_ci                p->offset += depth;
8325db71995Sopenharmony_ci            }
8335db71995Sopenharmony_ci            print_string_ptr(item->pAllocator, child->string, p);
8345db71995Sopenharmony_ci            p->offset = cJSON_update(p);
8355db71995Sopenharmony_ci
8365db71995Sopenharmony_ci            len = fmt ? 2 : 1;
8375db71995Sopenharmony_ci            ptr = ensure(item->pAllocator, p, len);
8385db71995Sopenharmony_ci            if (!ptr) return 0;
8395db71995Sopenharmony_ci            *ptr++ = ':';
8405db71995Sopenharmony_ci            if (fmt) *ptr++ = '\t';
8415db71995Sopenharmony_ci            p->offset += len;
8425db71995Sopenharmony_ci
8435db71995Sopenharmony_ci            print_value(child, depth, fmt, p);
8445db71995Sopenharmony_ci            p->offset = cJSON_update(p);
8455db71995Sopenharmony_ci
8465db71995Sopenharmony_ci            len = (fmt ? 1 : 0) + (child->next ? 1 : 0);
8475db71995Sopenharmony_ci            ptr = ensure(item->pAllocator, p, len + 1);
8485db71995Sopenharmony_ci            if (!ptr) return 0;
8495db71995Sopenharmony_ci            if (child->next) *ptr++ = ',';
8505db71995Sopenharmony_ci            if (fmt) *ptr++ = '\n';
8515db71995Sopenharmony_ci            *ptr = 0;
8525db71995Sopenharmony_ci            p->offset += len;
8535db71995Sopenharmony_ci            child = child->next;
8545db71995Sopenharmony_ci        }
8555db71995Sopenharmony_ci        ptr = ensure(item->pAllocator, p, fmt ? (depth + 1) : 2);
8565db71995Sopenharmony_ci        if (!ptr) return 0;
8575db71995Sopenharmony_ci        if (fmt)
8585db71995Sopenharmony_ci            for (j = 0; j < depth - 1; j++) *ptr++ = '\t';
8595db71995Sopenharmony_ci        *ptr++ = '}';
8605db71995Sopenharmony_ci        *ptr = 0;
8615db71995Sopenharmony_ci        out = (p->buffer) + i;
8625db71995Sopenharmony_ci    } else {
8635db71995Sopenharmony_ci        /* Allocate space for the names and the objects */
8645db71995Sopenharmony_ci        entries = (char **)cJSON_malloc(item->pAllocator, numentries * sizeof(char *));
8655db71995Sopenharmony_ci        if (!entries) return 0;
8665db71995Sopenharmony_ci        names = (char **)cJSON_malloc(item->pAllocator, numentries * sizeof(char *));
8675db71995Sopenharmony_ci        if (!names) {
8685db71995Sopenharmony_ci            cJSON_Free(item->pAllocator, entries);
8695db71995Sopenharmony_ci            return 0;
8705db71995Sopenharmony_ci        }
8715db71995Sopenharmony_ci        memset(entries, 0, sizeof(char *) * numentries);
8725db71995Sopenharmony_ci        memset(names, 0, sizeof(char *) * numentries);
8735db71995Sopenharmony_ci
8745db71995Sopenharmony_ci        /* Collect all the results into our arrays: */
8755db71995Sopenharmony_ci        child = item->child;
8765db71995Sopenharmony_ci        depth++;
8775db71995Sopenharmony_ci        if (fmt) len += depth;
8785db71995Sopenharmony_ci        while (child) {
8795db71995Sopenharmony_ci            names[i] = str = print_string_ptr(item->pAllocator, child->string, 0);
8805db71995Sopenharmony_ci            entries[i++] = ret = print_value(child, depth, fmt, 0);
8815db71995Sopenharmony_ci            if (str && ret)
8825db71995Sopenharmony_ci                len += strlen(ret) + strlen(str) + 2 + (fmt ? 2 + depth : 0);
8835db71995Sopenharmony_ci            else
8845db71995Sopenharmony_ci                fail = 1;
8855db71995Sopenharmony_ci            child = child->next;
8865db71995Sopenharmony_ci        }
8875db71995Sopenharmony_ci
8885db71995Sopenharmony_ci        /* Try to allocate the output string */
8895db71995Sopenharmony_ci        if (!fail) out = (char *)cJSON_malloc(item->pAllocator, len);
8905db71995Sopenharmony_ci        if (!out) fail = 1;
8915db71995Sopenharmony_ci
8925db71995Sopenharmony_ci        /* Handle failure */
8935db71995Sopenharmony_ci        if (fail) {
8945db71995Sopenharmony_ci            for (j = 0; j < numentries; j++) {
8955db71995Sopenharmony_ci                if (names[i]) cJSON_Free(item->pAllocator, names[j]);
8965db71995Sopenharmony_ci                if (entries[j]) cJSON_Free(item->pAllocator, entries[j]);
8975db71995Sopenharmony_ci            }
8985db71995Sopenharmony_ci            cJSON_Free(item->pAllocator, names);
8995db71995Sopenharmony_ci            cJSON_Free(item->pAllocator, entries);
9005db71995Sopenharmony_ci            return 0;
9015db71995Sopenharmony_ci        }
9025db71995Sopenharmony_ci
9035db71995Sopenharmony_ci        /* Compose the output: */
9045db71995Sopenharmony_ci        *out = '{';
9055db71995Sopenharmony_ci        ptr = out + 1;
9065db71995Sopenharmony_ci        if (fmt) *ptr++ = '\n';
9075db71995Sopenharmony_ci        *ptr = 0;
9085db71995Sopenharmony_ci        for (j = 0; j < numentries; j++) {
9095db71995Sopenharmony_ci            if (fmt)
9105db71995Sopenharmony_ci                for (k = 0; k < depth; k++) *ptr++ = '\t';
9115db71995Sopenharmony_ci            tmplen = strlen(names[j]);
9125db71995Sopenharmony_ci            memcpy(ptr, names[j], tmplen);
9135db71995Sopenharmony_ci            ptr += tmplen;
9145db71995Sopenharmony_ci            *ptr++ = ':';
9155db71995Sopenharmony_ci            if (fmt) *ptr++ = '\t';
9165db71995Sopenharmony_ci            size_t entries_size = strlen(entries[j]);
9175db71995Sopenharmony_ci            loader_strncpy(ptr, len - (ptr - out), entries[j], entries_size);
9185db71995Sopenharmony_ci            ptr += entries_size;
9195db71995Sopenharmony_ci            if (j != numentries - 1) *ptr++ = ',';
9205db71995Sopenharmony_ci            if (fmt) *ptr++ = '\n';
9215db71995Sopenharmony_ci            *ptr = 0;
9225db71995Sopenharmony_ci            cJSON_Free(item->pAllocator, names[j]);
9235db71995Sopenharmony_ci            cJSON_Free(item->pAllocator, entries[j]);
9245db71995Sopenharmony_ci        }
9255db71995Sopenharmony_ci
9265db71995Sopenharmony_ci        cJSON_Free(item->pAllocator, names);
9275db71995Sopenharmony_ci        cJSON_Free(item->pAllocator, entries);
9285db71995Sopenharmony_ci        if (fmt)
9295db71995Sopenharmony_ci            for (j = 0; j < depth - 1; j++) *ptr++ = '\t';
9305db71995Sopenharmony_ci        *ptr++ = '}';
9315db71995Sopenharmony_ci        *ptr++ = 0;
9325db71995Sopenharmony_ci    }
9335db71995Sopenharmony_ci    return out;
9345db71995Sopenharmony_ci}
9355db71995Sopenharmony_ci
9365db71995Sopenharmony_ci/* Get Array size/item / object item. */
9375db71995Sopenharmony_ciint loader_cJSON_GetArraySize(cJSON *array) {
9385db71995Sopenharmony_ci    cJSON *c = array->child;
9395db71995Sopenharmony_ci    int i = 0;
9405db71995Sopenharmony_ci    while (c) i++, c = c->next;
9415db71995Sopenharmony_ci    return i;
9425db71995Sopenharmony_ci}
9435db71995Sopenharmony_cicJSON *loader_cJSON_GetArrayItem(cJSON *array, int item) {
9445db71995Sopenharmony_ci    cJSON *c = array->child;
9455db71995Sopenharmony_ci    while (c && item > 0) item--, c = c->next;
9465db71995Sopenharmony_ci    return c;
9475db71995Sopenharmony_ci}
9485db71995Sopenharmony_cicJSON *loader_cJSON_GetObjectItem(cJSON *object, const char *string) {
9495db71995Sopenharmony_ci    cJSON *c = object->child;
9505db71995Sopenharmony_ci    while (c && strcmp(c->string, string)) c = c->next;
9515db71995Sopenharmony_ci    return c;
9525db71995Sopenharmony_ci}
9535db71995Sopenharmony_ci
9545db71995Sopenharmony_ciVkResult loader_get_json(const struct loader_instance *inst, const char *filename, cJSON **json) {
9555db71995Sopenharmony_ci    FILE *file = NULL;
9565db71995Sopenharmony_ci    char *json_buf = NULL;
9575db71995Sopenharmony_ci    size_t len;
9585db71995Sopenharmony_ci    VkResult res = VK_SUCCESS;
9595db71995Sopenharmony_ci
9605db71995Sopenharmony_ci    assert(json != NULL);
9615db71995Sopenharmony_ci
9625db71995Sopenharmony_ci    *json = NULL;
9635db71995Sopenharmony_ci
9645db71995Sopenharmony_ci#if defined(_WIN32)
9655db71995Sopenharmony_ci    int filename_utf16_size = MultiByteToWideChar(CP_UTF8, 0, filename, -1, NULL, 0);
9665db71995Sopenharmony_ci    if (filename_utf16_size > 0) {
9675db71995Sopenharmony_ci        wchar_t *filename_utf16 = (wchar_t *)loader_stack_alloc(filename_utf16_size * sizeof(wchar_t));
9685db71995Sopenharmony_ci        if (MultiByteToWideChar(CP_UTF8, 0, filename, -1, filename_utf16, filename_utf16_size) == filename_utf16_size) {
9695db71995Sopenharmony_ci            errno_t wfopen_error = _wfopen_s(&file, filename_utf16, L"rb");
9705db71995Sopenharmony_ci            if (0 != wfopen_error) {
9715db71995Sopenharmony_ci                loader_log(inst, VULKAN_LOADER_ERROR_BIT, 0, "loader_get_json: Failed to open JSON file %s", filename);
9725db71995Sopenharmony_ci            }
9735db71995Sopenharmony_ci        }
9745db71995Sopenharmony_ci    }
9755db71995Sopenharmony_ci#elif COMMON_UNIX_PLATFORMS
9765db71995Sopenharmony_ci    file = fopen(filename, "rb");
9775db71995Sopenharmony_ci#else
9785db71995Sopenharmony_ci#warning fopen not available on this platform
9795db71995Sopenharmony_ci#endif
9805db71995Sopenharmony_ci
9815db71995Sopenharmony_ci    if (!file) {
9825db71995Sopenharmony_ci        loader_log(inst, VULKAN_LOADER_ERROR_BIT, 0, "loader_get_json: Failed to open JSON file %s", filename);
9835db71995Sopenharmony_ci        res = VK_ERROR_INITIALIZATION_FAILED;
9845db71995Sopenharmony_ci        goto out;
9855db71995Sopenharmony_ci    }
9865db71995Sopenharmony_ci    // NOTE: We can't just use fseek(file, 0, SEEK_END) because that isn't guaranteed to be supported on all systems
9875db71995Sopenharmony_ci    size_t fread_ret_count = 0;
9885db71995Sopenharmony_ci    do {
9895db71995Sopenharmony_ci        char buffer[256];
9905db71995Sopenharmony_ci        fread_ret_count = fread(buffer, 1, 256, file);
9915db71995Sopenharmony_ci    } while (fread_ret_count == 256 && !feof(file));
9925db71995Sopenharmony_ci    len = ftell(file);
9935db71995Sopenharmony_ci    fseek(file, 0, SEEK_SET);
9945db71995Sopenharmony_ci    json_buf = (char *)loader_instance_heap_calloc(inst, len + 1, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
9955db71995Sopenharmony_ci    if (json_buf == NULL) {
9965db71995Sopenharmony_ci        loader_log(inst, VULKAN_LOADER_ERROR_BIT, 0,
9975db71995Sopenharmony_ci                   "loader_get_json: Failed to allocate space for JSON file %s buffer of length %lu", filename, len);
9985db71995Sopenharmony_ci        res = VK_ERROR_OUT_OF_HOST_MEMORY;
9995db71995Sopenharmony_ci        goto out;
10005db71995Sopenharmony_ci    }
10015db71995Sopenharmony_ci    if (fread(json_buf, sizeof(char), len, file) != len) {
10025db71995Sopenharmony_ci        loader_log(inst, VULKAN_LOADER_ERROR_BIT, 0, "loader_get_json: Failed to read JSON file %s.", filename);
10035db71995Sopenharmony_ci        res = VK_ERROR_INITIALIZATION_FAILED;
10045db71995Sopenharmony_ci        goto out;
10055db71995Sopenharmony_ci    }
10065db71995Sopenharmony_ci    json_buf[len] = '\0';
10075db71995Sopenharmony_ci
10085db71995Sopenharmony_ci    // Can't be a valid json if the string is of length zero
10095db71995Sopenharmony_ci    if (len == 0) {
10105db71995Sopenharmony_ci        res = VK_ERROR_INITIALIZATION_FAILED;
10115db71995Sopenharmony_ci        goto out;
10125db71995Sopenharmony_ci    }
10135db71995Sopenharmony_ci    // Parse text from file
10145db71995Sopenharmony_ci    bool out_of_memory = false;
10155db71995Sopenharmony_ci    *json = cJSON_Parse(inst ? &inst->alloc_callbacks : NULL, json_buf, &out_of_memory);
10165db71995Sopenharmony_ci    if (out_of_memory) {
10175db71995Sopenharmony_ci        loader_log(inst, VULKAN_LOADER_ERROR_BIT, 0, "loader_get_json: Out of Memory error occurred while parsing JSON file %s.",
10185db71995Sopenharmony_ci                   filename);
10195db71995Sopenharmony_ci        res = VK_ERROR_OUT_OF_HOST_MEMORY;
10205db71995Sopenharmony_ci        goto out;
10215db71995Sopenharmony_ci    } else if (*json == NULL) {
10225db71995Sopenharmony_ci        loader_log(inst, VULKAN_LOADER_ERROR_BIT, 0, "loader_get_json: Invalid JSON file %s.", filename);
10235db71995Sopenharmony_ci        goto out;
10245db71995Sopenharmony_ci    }
10255db71995Sopenharmony_ci
10265db71995Sopenharmony_ciout:
10275db71995Sopenharmony_ci    loader_instance_heap_free(inst, json_buf);
10285db71995Sopenharmony_ci    if (NULL != file) {
10295db71995Sopenharmony_ci        fclose(file);
10305db71995Sopenharmony_ci    }
10315db71995Sopenharmony_ci    if (res != VK_SUCCESS && *json != NULL) {
10325db71995Sopenharmony_ci        loader_cJSON_Delete(*json);
10335db71995Sopenharmony_ci        *json = NULL;
10345db71995Sopenharmony_ci    }
10355db71995Sopenharmony_ci
10365db71995Sopenharmony_ci    return res;
10375db71995Sopenharmony_ci}
10385db71995Sopenharmony_ci
10395db71995Sopenharmony_ciVkResult loader_parse_json_string_to_existing_str(const struct loader_instance *inst, cJSON *object, const char *key,
10405db71995Sopenharmony_ci                                                  size_t out_str_len, char *out_string) {
10415db71995Sopenharmony_ci    cJSON *item = loader_cJSON_GetObjectItem(object, key);
10425db71995Sopenharmony_ci    if (NULL == item) {
10435db71995Sopenharmony_ci        return VK_ERROR_INITIALIZATION_FAILED;
10445db71995Sopenharmony_ci    }
10455db71995Sopenharmony_ci
10465db71995Sopenharmony_ci    char *str = loader_cJSON_Print(item);
10475db71995Sopenharmony_ci    if (str == NULL) {
10485db71995Sopenharmony_ci        return VK_ERROR_OUT_OF_HOST_MEMORY;
10495db71995Sopenharmony_ci    }
10505db71995Sopenharmony_ci    if (NULL != out_string) {
10515db71995Sopenharmony_ci        loader_strncpy(out_string, out_str_len, str, out_str_len);
10525db71995Sopenharmony_ci        if (out_str_len > 0) {
10535db71995Sopenharmony_ci            out_string[out_str_len - 1] = '\0';
10545db71995Sopenharmony_ci        }
10555db71995Sopenharmony_ci    }
10565db71995Sopenharmony_ci    loader_instance_heap_free(inst, str);
10575db71995Sopenharmony_ci    return VK_SUCCESS;
10585db71995Sopenharmony_ci}
10595db71995Sopenharmony_ci
10605db71995Sopenharmony_ciVkResult loader_parse_json_string(cJSON *object, const char *key, char **out_string) {
10615db71995Sopenharmony_ci    cJSON *item = loader_cJSON_GetObjectItem(object, key);
10625db71995Sopenharmony_ci    if (NULL == item) {
10635db71995Sopenharmony_ci        return VK_ERROR_INITIALIZATION_FAILED;
10645db71995Sopenharmony_ci    }
10655db71995Sopenharmony_ci
10665db71995Sopenharmony_ci    char *str = loader_cJSON_Print(item);
10675db71995Sopenharmony_ci    if (str == NULL) {
10685db71995Sopenharmony_ci        return VK_ERROR_OUT_OF_HOST_MEMORY;
10695db71995Sopenharmony_ci    }
10705db71995Sopenharmony_ci    if (NULL != out_string) {
10715db71995Sopenharmony_ci        *out_string = str;
10725db71995Sopenharmony_ci    }
10735db71995Sopenharmony_ci    return VK_SUCCESS;
10745db71995Sopenharmony_ci}
10755db71995Sopenharmony_ciVkResult loader_parse_json_array_of_strings(const struct loader_instance *inst, cJSON *object, const char *key,
10765db71995Sopenharmony_ci                                            struct loader_string_list *string_list) {
10775db71995Sopenharmony_ci    VkResult res = VK_SUCCESS;
10785db71995Sopenharmony_ci    cJSON *item = loader_cJSON_GetObjectItem(object, key);
10795db71995Sopenharmony_ci    if (NULL == item) {
10805db71995Sopenharmony_ci        return VK_ERROR_INITIALIZATION_FAILED;
10815db71995Sopenharmony_ci    }
10825db71995Sopenharmony_ci
10835db71995Sopenharmony_ci    uint32_t count = loader_cJSON_GetArraySize(item);
10845db71995Sopenharmony_ci    if (count == 0) {
10855db71995Sopenharmony_ci        return VK_SUCCESS;
10865db71995Sopenharmony_ci    }
10875db71995Sopenharmony_ci
10885db71995Sopenharmony_ci    res = create_string_list(inst, count, string_list);
10895db71995Sopenharmony_ci    if (VK_ERROR_OUT_OF_HOST_MEMORY == res) {
10905db71995Sopenharmony_ci        goto out;
10915db71995Sopenharmony_ci    }
10925db71995Sopenharmony_ci    for (uint32_t i = 0; i < count; i++) {
10935db71995Sopenharmony_ci        cJSON *element = loader_cJSON_GetArrayItem(item, i);
10945db71995Sopenharmony_ci        if (element == NULL) {
10955db71995Sopenharmony_ci            return VK_ERROR_INITIALIZATION_FAILED;
10965db71995Sopenharmony_ci        }
10975db71995Sopenharmony_ci        char *out_data = loader_cJSON_Print(element);
10985db71995Sopenharmony_ci        if (out_data == NULL) {
10995db71995Sopenharmony_ci            res = VK_ERROR_OUT_OF_HOST_MEMORY;
11005db71995Sopenharmony_ci            goto out;
11015db71995Sopenharmony_ci        }
11025db71995Sopenharmony_ci        res = append_str_to_string_list(inst, string_list, out_data);
11035db71995Sopenharmony_ci        if (VK_ERROR_OUT_OF_HOST_MEMORY == res) {
11045db71995Sopenharmony_ci            goto out;
11055db71995Sopenharmony_ci        }
11065db71995Sopenharmony_ci    }
11075db71995Sopenharmony_ciout:
11085db71995Sopenharmony_ci    if (res == VK_ERROR_OUT_OF_HOST_MEMORY && NULL != string_list->list) {
11095db71995Sopenharmony_ci        free_string_list(inst, string_list);
11105db71995Sopenharmony_ci    }
11115db71995Sopenharmony_ci
11125db71995Sopenharmony_ci    return res;
11135db71995Sopenharmony_ci}
1114