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