summaryrefslogtreecommitdiff
path: root/thirdparty/vulkan/loader/cJSON.c
diff options
context:
space:
mode:
Diffstat (limited to 'thirdparty/vulkan/loader/cJSON.c')
-rw-r--r--thirdparty/vulkan/loader/cJSON.c1215
1 files changed, 0 insertions, 1215 deletions
diff --git a/thirdparty/vulkan/loader/cJSON.c b/thirdparty/vulkan/loader/cJSON.c
deleted file mode 100644
index 8da6d83c32..0000000000
--- a/thirdparty/vulkan/loader/cJSON.c
+++ /dev/null
@@ -1,1215 +0,0 @@
-/*
- Copyright (c) 2009 Dave Gamble
- Copyright (c) 2015-2016 The Khronos Group Inc.
- Copyright (c) 2015-2016 Valve Corporation
- Copyright (c) 2015-2016 LunarG, Inc.
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- THE SOFTWARE.
-*/
-
-/* cJSON */
-/* JSON parser in C. */
-
-#include <string.h>
-#include <stdio.h>
-#include <math.h>
-#include <stdlib.h>
-#include <float.h>
-#include <limits.h>
-#include <ctype.h>
-#include "cJSON.h"
-
-static const char *ep;
-
-const char *cJSON_GetErrorPtr(void) { return ep; }
-
-static void *(*cJSON_malloc)(size_t sz) = malloc;
-static void (*cJSON_free)(void *ptr) = free;
-
-static char *cJSON_strdup(const char *str) {
- size_t len;
- char *copy;
-
- len = strlen(str) + 1;
- if (!(copy = (char *)cJSON_malloc(len))) return 0;
- memcpy(copy, str, len);
- return copy;
-}
-
-void cJSON_InitHooks(cJSON_Hooks *hooks) {
- if (!hooks) { /* Reset hooks */
- cJSON_malloc = malloc;
- cJSON_free = free;
- return;
- }
-
- cJSON_malloc = (hooks->malloc_fn) ? hooks->malloc_fn : malloc;
- cJSON_free = (hooks->free_fn) ? hooks->free_fn : free;
-}
-
-/* Internal constructor. */
-static cJSON *cJSON_New_Item(void) {
- cJSON *node = (cJSON *)cJSON_malloc(sizeof(cJSON));
- if (node) memset(node, 0, sizeof(cJSON));
- return node;
-}
-
-/* Delete a cJSON structure. */
-void cJSON_Delete(cJSON *c) {
- cJSON *next;
- while (c) {
- next = c->next;
- if (!(c->type & cJSON_IsReference) && c->child) cJSON_Delete(c->child);
- if (!(c->type & cJSON_IsReference) && c->valuestring) cJSON_free(c->valuestring);
- if (!(c->type & cJSON_StringIsConst) && c->string) cJSON_free(c->string);
- cJSON_free(c);
- c = next;
- }
-}
-
-void cJSON_Free(void *p) { cJSON_free(p); }
-
-/* Parse the input text to generate a number, and populate the result into item.
- */
-static const char *parse_number(cJSON *item, const char *num) {
- double n = 0, sign = 1, scale = 0;
- int subscale = 0, signsubscale = 1;
-
- if (*num == '-') sign = -1, num++; /* Has sign? */
- if (*num == '0') num++; /* is zero */
- if (*num >= '1' && *num <= '9') do
- n = (n * 10.0) + (*num++ - '0');
- while (*num >= '0' && *num <= '9'); /* Number? */
- if (*num == '.' && num[1] >= '0' && num[1] <= '9') {
- num++;
- do
- n = (n * 10.0) + (*num++ - '0'), scale--;
- while (*num >= '0' && *num <= '9');
- } /* Fractional part? */
- if (*num == 'e' || *num == 'E') /* Exponent? */
- {
- num++;
- if (*num == '+')
- num++;
- else if (*num == '-')
- signsubscale = -1, num++; /* With sign? */
- while (*num >= '0' && *num <= '9') subscale = (subscale * 10) + (*num++ - '0'); /* Number? */
- }
-
- n = sign * n * pow(10.0, (scale + subscale * signsubscale)); /* number = +/-
- number.fraction *
- 10^+/- exponent */
-
- item->valuedouble = n;
- item->valueint = (int)n;
- item->type = cJSON_Number;
- return num;
-}
-
-static size_t pow2gt(size_t x) {
- --x;
- x |= x >> 1;
- x |= x >> 2;
- x |= x >> 4;
- x |= x >> 8;
- x |= x >> 16;
- return x + 1;
-}
-
-typedef struct {
- char *buffer;
- size_t length;
- size_t offset;
-} printbuffer;
-
-static char *ensure(printbuffer *p, size_t needed) {
- char *newbuffer;
- size_t newsize;
- if (!p || !p->buffer) return 0;
- needed += p->offset;
- if (needed <= p->length) return p->buffer + p->offset;
-
- newsize = pow2gt(needed);
- newbuffer = (char *)cJSON_malloc(newsize);
- if (!newbuffer) {
- cJSON_free(p->buffer);
- p->length = 0, p->buffer = 0;
- return 0;
- }
- if (newbuffer) memcpy(newbuffer, p->buffer, p->length);
- cJSON_free(p->buffer);
- p->length = newsize;
- p->buffer = newbuffer;
- return newbuffer + p->offset;
-}
-
-static size_t update(printbuffer *p) {
- char *str;
- if (!p || !p->buffer) return 0;
- str = p->buffer + p->offset;
- return p->offset + strlen(str);
-}
-
-/* Render the number nicely from the given item into a string. */
-static char *print_number(cJSON *item, printbuffer *p) {
- char *str = 0;
- double d = item->valuedouble;
- if (d == 0) {
- if (p)
- str = ensure(p, 2);
- else
- str = (char *)cJSON_malloc(2); /* special case for 0. */
- if (str) strcpy(str, "0");
- } else if (fabs(((double)item->valueint) - d) <= DBL_EPSILON && d <= INT_MAX && d >= INT_MIN) {
- if (p)
- str = ensure(p, 21);
- else
- str = (char *)cJSON_malloc(21); /* 2^64+1 can be represented in 21 chars. */
- if (str) sprintf(str, "%d", item->valueint);
- } else {
- if (p)
- str = ensure(p, 64);
- else
- str = (char *)cJSON_malloc(64); /* This is a nice tradeoff. */
- if (str) {
- if (fabs(floor(d) - d) <= DBL_EPSILON && fabs(d) < 1.0e60)
- sprintf(str, "%.0f", d);
- else if (fabs(d) < 1.0e-6 || fabs(d) > 1.0e9)
- sprintf(str, "%e", d);
- else
- sprintf(str, "%f", d);
- }
- }
- return str;
-}
-
-static unsigned parse_hex4(const char *str) {
- unsigned h = 0;
- if (*str >= '0' && *str <= '9')
- h += (*str) - '0';
- else if (*str >= 'A' && *str <= 'F')
- h += 10 + (*str) - 'A';
- else if (*str >= 'a' && *str <= 'f')
- h += 10 + (*str) - 'a';
- else
- return 0;
- h = h << 4;
- str++;
- if (*str >= '0' && *str <= '9')
- h += (*str) - '0';
- else if (*str >= 'A' && *str <= 'F')
- h += 10 + (*str) - 'A';
- else if (*str >= 'a' && *str <= 'f')
- h += 10 + (*str) - 'a';
- else
- return 0;
- h = h << 4;
- str++;
- if (*str >= '0' && *str <= '9')
- h += (*str) - '0';
- else if (*str >= 'A' && *str <= 'F')
- h += 10 + (*str) - 'A';
- else if (*str >= 'a' && *str <= 'f')
- h += 10 + (*str) - 'a';
- else
- return 0;
- h = h << 4;
- str++;
- if (*str >= '0' && *str <= '9')
- h += (*str) - '0';
- else if (*str >= 'A' && *str <= 'F')
- h += 10 + (*str) - 'A';
- else if (*str >= 'a' && *str <= 'f')
- h += 10 + (*str) - 'a';
- else
- return 0;
- return h;
-}
-
-/* Parse the input text into an unescaped cstring, and populate item. */
-static const unsigned char firstByteMark[7] = {0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC};
-static const char *parse_string(cJSON *item, const char *str) {
- const char *ptr = str + 1;
- char *ptr2;
- char *out;
- int len = 0;
- unsigned uc, uc2;
- if (*str != '\"') {
- ep = str;
- return 0;
- } /* not a string! */
-
- while (*ptr != '\"' && *ptr && ++len)
- if (*ptr++ == '\\') ptr++; /* Skip escaped quotes. */
-
- out = (char *)cJSON_malloc(len + 1); /* This is how long we need for the string, roughly. */
- if (!out) return 0;
-
- ptr = str + 1;
- ptr2 = out;
- while (*ptr != '\"' && *ptr) {
- if (*ptr != '\\')
- *ptr2++ = *ptr++;
- else {
- ptr++;
- switch (*ptr) {
- case 'b':
- *ptr2++ = '\b';
- break;
- case 'f':
- *ptr2++ = '\f';
- break;
- case 'n':
- *ptr2++ = '\n';
- break;
- case 'r':
- *ptr2++ = '\r';
- break;
- case 't':
- *ptr2++ = '\t';
- break;
- case 'u': /* transcode utf16 to utf8. */
- uc = parse_hex4(ptr + 1);
- ptr += 4; /* get the unicode char. */
-
- if ((uc >= 0xDC00 && uc <= 0xDFFF) || uc == 0) break; /* check for invalid. */
-
- if (uc >= 0xD800 && uc <= 0xDBFF) /* UTF16 surrogate pairs. */
- {
- if (ptr[1] != '\\' || ptr[2] != 'u') break; /* missing second-half of surrogate. */
- uc2 = parse_hex4(ptr + 3);
- ptr += 6;
- if (uc2 < 0xDC00 || uc2 > 0xDFFF) break; /* invalid second-half of surrogate. */
- uc = 0x10000 + (((uc & 0x3FF) << 10) | (uc2 & 0x3FF));
- }
-
- len = 4;
- if (uc < 0x80)
- len = 1;
- else if (uc < 0x800)
- len = 2;
- else if (uc < 0x10000)
- len = 3;
- ptr2 += len;
-
- switch (len) {
- case 4:
- *--ptr2 = ((uc | 0x80) & 0xBF);
- uc >>= 6;
- // fall through
- case 3:
- *--ptr2 = ((uc | 0x80) & 0xBF);
- uc >>= 6;
- // fall through
- case 2:
- *--ptr2 = ((uc | 0x80) & 0xBF);
- uc >>= 6;
- // fall through
- case 1:
- *--ptr2 = ((unsigned char)uc | firstByteMark[len]);
- }
- ptr2 += len;
- break;
- default:
- *ptr2++ = *ptr;
- break;
- }
- ptr++;
- }
- }
- *ptr2 = 0;
- if (*ptr == '\"') ptr++;
- item->valuestring = out;
- item->type = cJSON_String;
- return ptr;
-}
-
-/* Render the cstring provided to an escaped version that can be printed. */
-static char *print_string_ptr(const char *str, printbuffer *p) {
- const char *ptr;
- char *ptr2;
- char *out;
- size_t len = 0, flag = 0;
- unsigned char token;
-
- for (ptr = str; *ptr; ptr++) flag |= ((*ptr > 0 && *ptr < 32) || (*ptr == '\"') || (*ptr == '\\')) ? 1 : 0;
- if (!flag) {
- len = ptr - str;
- if (p)
- out = ensure(p, len + 3);
- else
- out = (char *)cJSON_malloc(len + 3);
- if (!out) return 0;
- ptr2 = out;
- *ptr2++ = '\"';
- strcpy(ptr2, str);
- ptr2[len] = '\"';
- ptr2[len + 1] = 0;
- return out;
- }
-
- if (!str) {
- if (p)
- out = ensure(p, 3);
- else
- out = (char *)cJSON_malloc(3);
- if (!out) return 0;
- strcpy(out, "\"\"");
- return out;
- }
- ptr = str;
- while ((token = *ptr) && ++len) {
- if (strchr("\"\\\b\f\n\r\t", token))
- len++;
- else if (token < 32)
- len += 5;
- ptr++;
- }
-
- if (p)
- out = ensure(p, len + 3);
- else
- out = (char *)cJSON_malloc(len + 3);
- if (!out) return 0;
-
- ptr2 = out;
- ptr = str;
- *ptr2++ = '\"';
- while (*ptr) {
- if ((unsigned char)*ptr > 31 && *ptr != '\"' && *ptr != '\\')
- *ptr2++ = *ptr++;
- else {
- switch (token = *ptr++) {
- case '\\':
- *ptr2++ = '\\';
- break;
- case '\"':
- *ptr2++ = '\"';
- break;
- case '\b':
- *ptr2++ = '\b';
- break;
- case '\f':
- *ptr2++ = '\f';
- break;
- case '\n':
- *ptr2++ = '\n';
- break;
- case '\r':
- *ptr2++ = '\r';
- break;
- case '\t':
- *ptr2++ = '\t';
- break;
- default:
- sprintf(ptr2, "u%04x", token);
- ptr2 += 5;
- break; /* escape and print */
- }
- }
- }
- *ptr2++ = '\"';
- *ptr2++ = 0;
- return out;
-}
-/* Invote print_string_ptr (which is useful) on an item. */
-static char *print_string(cJSON *item, printbuffer *p) { return print_string_ptr(item->valuestring, p); }
-
-/* Predeclare these prototypes. */
-static const char *parse_value(cJSON *item, const char *value);
-static char *print_value(cJSON *item, int depth, int fmt, printbuffer *p);
-static const char *parse_array(cJSON *item, const char *value);
-static char *print_array(cJSON *item, int depth, int fmt, printbuffer *p);
-static const char *parse_object(cJSON *item, const char *value);
-static char *print_object(cJSON *item, int depth, int fmt, printbuffer *p);
-
-/* Utility to jump whitespace and cr/lf */
-static const char *skip(const char *in) {
- while (in && *in && (unsigned char)*in <= 32) in++;
- return in;
-}
-
-/* Parse an object - create a new root, and populate. */
-cJSON *cJSON_ParseWithOpts(const char *value, const char **return_parse_end, int require_null_terminated) {
- const char *end = 0;
- cJSON *c = cJSON_New_Item();
- ep = 0;
- if (!c) return 0; /* memory fail */
-
- end = parse_value(c, skip(value));
- if (!end) {
- cJSON_Delete(c);
- return 0;
- } /* parse failure. ep is set. */
-
- /* if we require null-terminated JSON without appended garbage, skip and
- * then check for a null terminator */
- if (require_null_terminated) {
- end = skip(end);
- if (*end) {
- cJSON_Delete(c);
- ep = end;
- return 0;
- }
- }
- if (return_parse_end) *return_parse_end = end;
- return c;
-}
-/* Default options for cJSON_Parse */
-cJSON *cJSON_Parse(const char *value) { return cJSON_ParseWithOpts(value, 0, 0); }
-
-/* Render a cJSON item/entity/structure to text. */
-char *cJSON_Print(cJSON *item) { return print_value(item, 0, 1, 0); }
-char *cJSON_PrintUnformatted(cJSON *item) { return print_value(item, 0, 0, 0); }
-
-char *cJSON_PrintBuffered(cJSON *item, int prebuffer, int fmt) {
- printbuffer p;
- p.buffer = (char *)cJSON_malloc(prebuffer);
- p.length = prebuffer;
- p.offset = 0;
- return print_value(item, 0, fmt, &p);
-}
-
-/* Parser core - when encountering text, process appropriately. */
-static const char *parse_value(cJSON *item, const char *value) {
- if (!value) return 0; /* Fail on null. */
- if (!strncmp(value, "null", 4)) {
- item->type = cJSON_NULL;
- return value + 4;
- }
- if (!strncmp(value, "false", 5)) {
- item->type = cJSON_False;
- return value + 5;
- }
- if (!strncmp(value, "true", 4)) {
- item->type = cJSON_True;
- item->valueint = 1;
- return value + 4;
- }
- if (*value == '\"') {
- return parse_string(item, value);
- }
- if (*value == '-' || (*value >= '0' && *value <= '9')) {
- return parse_number(item, value);
- }
- if (*value == '[') {
- return parse_array(item, value);
- }
- if (*value == '{') {
- return parse_object(item, value);
- }
-
- ep = value;
- return 0; /* failure. */
-}
-
-/* Render a value to text. */
-static char *print_value(cJSON *item, int depth, int fmt, printbuffer *p) {
- char *out = 0;
- if (!item) return 0;
- if (p) {
- switch ((item->type) & 255) {
- case cJSON_NULL: {
- out = ensure(p, 5);
- if (out) strcpy(out, "null");
- break;
- }
- case cJSON_False: {
- out = ensure(p, 6);
- if (out) strcpy(out, "false");
- break;
- }
- case cJSON_True: {
- out = ensure(p, 5);
- if (out) strcpy(out, "true");
- break;
- }
- case cJSON_Number:
- out = print_number(item, p);
- break;
- case cJSON_String:
- out = print_string(item, p);
- break;
- case cJSON_Array:
- out = print_array(item, depth, fmt, p);
- break;
- case cJSON_Object:
- out = print_object(item, depth, fmt, p);
- break;
- }
- } else {
- switch ((item->type) & 255) {
- case cJSON_NULL:
- out = cJSON_strdup("null");
- break;
- case cJSON_False:
- out = cJSON_strdup("false");
- break;
- case cJSON_True:
- out = cJSON_strdup("true");
- break;
- case cJSON_Number:
- out = print_number(item, 0);
- break;
- case cJSON_String:
- out = print_string(item, 0);
- break;
- case cJSON_Array:
- out = print_array(item, depth, fmt, 0);
- break;
- case cJSON_Object:
- out = print_object(item, depth, fmt, 0);
- break;
- }
- }
- return out;
-}
-
-/* Build an array from input text. */
-static const char *parse_array(cJSON *item, const char *value) {
- cJSON *child;
- if (*value != '[') {
- ep = value;
- return 0;
- } /* not an array! */
-
- item->type = cJSON_Array;
- value = skip(value + 1);
- if (*value == ']') return value + 1; /* empty array. */
-
- item->child = child = cJSON_New_Item();
- if (!item->child) return 0; /* memory fail */
- value = skip(parse_value(child, skip(value))); /* skip any spacing, get the value. */
- if (!value) return 0;
-
- while (*value == ',') {
- cJSON *new_item;
- if (!(new_item = cJSON_New_Item())) return 0; /* memory fail */
- child->next = new_item;
- new_item->prev = child;
- child = new_item;
- value = skip(parse_value(child, skip(value + 1)));
- if (!value) return 0; /* memory fail */
- }
-
- if (*value == ']') return value + 1; /* end of array */
- ep = value;
- return 0; /* malformed. */
-}
-
-/* Render an array to text */
-static char *print_array(cJSON *item, int depth, int fmt, printbuffer *p) {
- char **entries;
- char *out = 0, *ptr, *ret;
- size_t len = 5;
- cJSON *child = item->child;
- int numentries = 0, fail = 0, j = 0;
- size_t tmplen = 0, i = 0;
-
- /* How many entries in the array? */
- while (child) numentries++, child = child->next;
- /* Explicitly handle numentries==0 */
- if (!numentries) {
- if (p)
- out = ensure(p, 3);
- else
- out = (char *)cJSON_malloc(3);
- if (out) strcpy(out, "[]");
- return out;
- }
-
- if (p) {
- /* Compose the output array. */
- i = p->offset;
- ptr = ensure(p, 1);
- if (!ptr) return 0;
- *ptr = '[';
- p->offset++;
- child = item->child;
- while (child && !fail) {
- print_value(child, depth + 1, fmt, p);
- p->offset = update(p);
- if (child->next) {
- len = fmt ? 2 : 1;
- ptr = ensure(p, len + 1);
- if (!ptr) return 0;
- *ptr++ = ',';
- if (fmt) *ptr++ = ' ';
- *ptr = 0;
- p->offset += len;
- }
- child = child->next;
- }
- ptr = ensure(p, 2);
- if (!ptr) return 0;
- *ptr++ = ']';
- *ptr = 0;
- out = (p->buffer) + i;
- } else {
- /* Allocate an array to hold the values for each */
- entries = (char **)cJSON_malloc(numentries * sizeof(char *));
- if (!entries) return 0;
- memset(entries, 0, numentries * sizeof(char *));
- /* Retrieve all the results: */
- child = item->child;
- while (child && !fail) {
- ret = print_value(child, depth + 1, fmt, 0);
- entries[i++] = ret;
- if (ret)
- len += strlen(ret) + 2 + (fmt ? 1 : 0);
- else
- fail = 1;
- child = child->next;
- }
-
- /* If we didn't fail, try to malloc the output string */
- if (!fail) out = (char *)cJSON_malloc(len);
- /* If that fails, we fail. */
- if (!out) fail = 1;
-
- /* Handle failure. */
- if (fail) {
- for (j = 0; j < numentries; j++)
- if (entries[j]) cJSON_free(entries[j]);
- cJSON_free(entries);
- return 0;
- }
-
- /* Compose the output array. */
- *out = '[';
- ptr = out + 1;
- *ptr = 0;
- for (j = 0; j < numentries; j++) {
- tmplen = strlen(entries[j]);
- memcpy(ptr, entries[j], tmplen);
- ptr += tmplen;
- if (j != numentries - 1) {
- *ptr++ = ',';
- if (fmt) *ptr++ = ' ';
- *ptr = 0;
- }
- cJSON_free(entries[j]);
- }
- cJSON_free(entries);
- *ptr++ = ']';
- *ptr++ = 0;
- }
- return out;
-}
-
-/* Build an object from the text. */
-static const char *parse_object(cJSON *item, const char *value) {
- cJSON *child;
- if (*value != '{') {
- ep = value;
- return 0;
- } /* not an object! */
-
- item->type = cJSON_Object;
- value = skip(value + 1);
- if (*value == '}') return value + 1; /* empty array. */
-
- item->child = child = cJSON_New_Item();
- if (!item->child) return 0;
- value = skip(parse_string(child, skip(value)));
- if (!value) return 0;
- child->string = child->valuestring;
- child->valuestring = 0;
- if (*value != ':') {
- ep = value;
- return 0;
- } /* fail! */
- value = skip(parse_value(child, skip(value + 1))); /* skip any spacing, get the value. */
- if (!value) return 0;
-
- while (*value == ',') {
- cJSON *new_item;
- if (!(new_item = cJSON_New_Item())) return 0; /* memory fail */
- child->next = new_item;
- new_item->prev = child;
- child = new_item;
- value = skip(parse_string(child, skip(value + 1)));
- if (!value) return 0;
- child->string = child->valuestring;
- child->valuestring = 0;
- if (*value != ':') {
- ep = value;
- return 0;
- } /* fail! */
- value = skip(parse_value(child, skip(value + 1))); /* skip any spacing, get the value. */
- if (!value) return 0;
- }
-
- if (*value == '}') return value + 1; /* end of array */
- ep = value;
- return 0; /* malformed. */
-}
-
-/* Render an object to text. */
-static char *print_object(cJSON *item, int depth, int fmt, printbuffer *p) {
- char **entries = 0, **names = 0;
- char *out = 0, *ptr, *ret, *str;
- int j;
- cJSON *child = item->child;
- int numentries = 0, fail = 0, k;
- size_t tmplen = 0, i = 0, len = 7;
- /* Count the number of entries. */
- while (child) numentries++, child = child->next;
- /* Explicitly handle empty object case */
- if (!numentries) {
- if (p)
- out = ensure(p, fmt ? depth + 4 : 3);
- else
- out = (char *)cJSON_malloc(fmt ? depth + 4 : 3);
- if (!out) return 0;
- ptr = out;
- *ptr++ = '{';
- if (fmt) {
- *ptr++ = '\n';
- for (j = 0; j < depth - 1; j++) *ptr++ = '\t';
- }
- *ptr++ = '}';
- *ptr++ = 0;
- return out;
- }
- if (p) {
- /* Compose the output: */
- i = p->offset;
- len = fmt ? 2 : 1;
- ptr = ensure(p, len + 1);
- if (!ptr) return 0;
- *ptr++ = '{';
- if (fmt) *ptr++ = '\n';
- *ptr = 0;
- p->offset += len;
- child = item->child;
- depth++;
- while (child) {
- if (fmt) {
- ptr = ensure(p, depth);
- if (!ptr) return 0;
- for (j = 0; j < depth; j++) *ptr++ = '\t';
- p->offset += depth;
- }
- print_string_ptr(child->string, p);
- p->offset = update(p);
-
- len = fmt ? 2 : 1;
- ptr = ensure(p, len);
- if (!ptr) return 0;
- *ptr++ = ':';
- if (fmt) *ptr++ = '\t';
- p->offset += len;
-
- print_value(child, depth, fmt, p);
- p->offset = update(p);
-
- len = (fmt ? 1 : 0) + (child->next ? 1 : 0);
- ptr = ensure(p, len + 1);
- if (!ptr) return 0;
- if (child->next) *ptr++ = ',';
- if (fmt) *ptr++ = '\n';
- *ptr = 0;
- p->offset += len;
- child = child->next;
- }
- ptr = ensure(p, fmt ? (depth + 1) : 2);
- if (!ptr) return 0;
- if (fmt)
- for (j = 0; j < depth - 1; j++) *ptr++ = '\t';
- *ptr++ = '}';
- *ptr = 0;
- out = (p->buffer) + i;
- } else {
- /* Allocate space for the names and the objects */
- entries = (char **)cJSON_malloc(numentries * sizeof(char *));
- if (!entries) return 0;
- names = (char **)cJSON_malloc(numentries * sizeof(char *));
- if (!names) {
- cJSON_free(entries);
- return 0;
- }
- memset(entries, 0, sizeof(char *) * numentries);
- memset(names, 0, sizeof(char *) * numentries);
-
- /* Collect all the results into our arrays: */
- child = item->child;
- depth++;
- if (fmt) len += depth;
- while (child) {
- names[i] = str = print_string_ptr(child->string, 0);
- entries[i++] = ret = print_value(child, depth, fmt, 0);
- if (str && ret)
- len += strlen(ret) + strlen(str) + 2 + (fmt ? 2 + depth : 0);
- else
- fail = 1;
- child = child->next;
- }
-
- /* Try to allocate the output string */
- if (!fail) out = (char *)cJSON_malloc(len);
- if (!out) fail = 1;
-
- /* Handle failure */
- if (fail) {
- for (j = 0; j < numentries; j++) {
- if (names[i]) cJSON_free(names[j]);
- if (entries[j]) cJSON_free(entries[j]);
- }
- cJSON_free(names);
- cJSON_free(entries);
- return 0;
- }
-
- /* Compose the output: */
- *out = '{';
- ptr = out + 1;
- if (fmt) *ptr++ = '\n';
- *ptr = 0;
- for (j = 0; j < numentries; j++) {
- if (fmt)
- for (k = 0; k < depth; k++) *ptr++ = '\t';
- tmplen = strlen(names[j]);
- memcpy(ptr, names[j], tmplen);
- ptr += tmplen;
- *ptr++ = ':';
- if (fmt) *ptr++ = '\t';
- strcpy(ptr, entries[j]);
- ptr += strlen(entries[j]);
- if (j != numentries - 1) *ptr++ = ',';
- if (fmt) *ptr++ = '\n';
- *ptr = 0;
- cJSON_free(names[j]);
- cJSON_free(entries[j]);
- }
-
- cJSON_free(names);
- cJSON_free(entries);
- if (fmt)
- for (j = 0; j < depth - 1; j++) *ptr++ = '\t';
- *ptr++ = '}';
- *ptr++ = 0;
- }
- return out;
-}
-
-/* Get Array size/item / object item. */
-int cJSON_GetArraySize(cJSON *array) {
- cJSON *c = array->child;
- int i = 0;
- while (c) i++, c = c->next;
- return i;
-}
-cJSON *cJSON_GetArrayItem(cJSON *array, int item) {
- cJSON *c = array->child;
- while (c && item > 0) item--, c = c->next;
- return c;
-}
-cJSON *cJSON_GetObjectItem(cJSON *object, const char *string) {
- cJSON *c = object->child;
- while (c && strcmp(c->string, string)) c = c->next;
- return c;
-}
-
-/* Utility for array list handling. */
-static void suffix_object(cJSON *prev, cJSON *item) {
- prev->next = item;
- item->prev = prev;
-}
-/* Utility for handling references. */
-static cJSON *create_reference(cJSON *item) {
- cJSON *ref = cJSON_New_Item();
- if (!ref) return 0;
- memcpy(ref, item, sizeof(cJSON));
- ref->string = 0;
- ref->type |= cJSON_IsReference;
- ref->next = ref->prev = 0;
- return ref;
-}
-
-/* Add item to array/object. */
-void cJSON_AddItemToArray(cJSON *array, cJSON *item) {
- cJSON *c = array->child;
- if (!item) return;
- if (!c) {
- array->child = item;
- } else {
- while (c && c->next) c = c->next;
- suffix_object(c, item);
- }
-}
-void cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item) {
- if (!item) return;
- if (item->string) cJSON_free(item->string);
- item->string = cJSON_strdup(string);
- cJSON_AddItemToArray(object, item);
-}
-void cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item) {
- if (!item) return;
- if (!(item->type & cJSON_StringIsConst) && item->string) cJSON_free(item->string);
- item->string = (char *)string;
- item->type |= cJSON_StringIsConst;
- cJSON_AddItemToArray(object, item);
-}
-void cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item) { cJSON_AddItemToArray(array, create_reference(item)); }
-void cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item) {
- cJSON_AddItemToObject(object, string, create_reference(item));
-}
-
-cJSON *cJSON_DetachItemFromArray(cJSON *array, int which) {
- cJSON *c = array->child;
- while (c && which > 0) c = c->next, which--;
- if (!c) return 0;
- if (c->prev) c->prev->next = c->next;
- if (c->next) c->next->prev = c->prev;
- if (c == array->child) array->child = c->next;
- c->prev = c->next = 0;
- return c;
-}
-void cJSON_DeleteItemFromArray(cJSON *array, int which) { cJSON_Delete(cJSON_DetachItemFromArray(array, which)); }
-cJSON *cJSON_DetachItemFromObject(cJSON *object, const char *string) {
- int i = 0;
- cJSON *c = object->child;
- while (c && strcmp(c->string, string)) i++, c = c->next;
- if (c) return cJSON_DetachItemFromArray(object, i);
- return 0;
-}
-void cJSON_DeleteItemFromObject(cJSON *object, const char *string) { cJSON_Delete(cJSON_DetachItemFromObject(object, string)); }
-
-/* Replace array/object items with new ones. */
-void cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem) {
- cJSON *c = array->child;
- while (c && which > 0) c = c->next, which--;
- if (!c) {
- cJSON_AddItemToArray(array, newitem);
- return;
- }
- newitem->next = c;
- newitem->prev = c->prev;
- c->prev = newitem;
- if (c == array->child)
- array->child = newitem;
- else
- newitem->prev->next = newitem;
-}
-void cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem) {
- cJSON *c = array->child;
- while (c && which > 0) c = c->next, which--;
- if (!c) return;
- newitem->next = c->next;
- newitem->prev = c->prev;
- if (newitem->next) newitem->next->prev = newitem;
- if (c == array->child)
- array->child = newitem;
- else
- newitem->prev->next = newitem;
- c->next = c->prev = 0;
- cJSON_Delete(c);
-}
-void cJSON_ReplaceItemInObject(cJSON *object, const char *string, cJSON *newitem) {
- int i = 0;
- cJSON *c = object->child;
- while (c && strcmp(c->string, string)) i++, c = c->next;
- if (c) {
- newitem->string = cJSON_strdup(string);
- cJSON_ReplaceItemInArray(object, i, newitem);
- }
-}
-
-/* Create basic types: */
-cJSON *cJSON_CreateNull(void) {
- cJSON *item = cJSON_New_Item();
- if (item) item->type = cJSON_NULL;
- return item;
-}
-cJSON *cJSON_CreateTrue(void) {
- cJSON *item = cJSON_New_Item();
- if (item) item->type = cJSON_True;
- return item;
-}
-cJSON *cJSON_CreateFalse(void) {
- cJSON *item = cJSON_New_Item();
- if (item) item->type = cJSON_False;
- return item;
-}
-cJSON *cJSON_CreateBool(int b) {
- cJSON *item = cJSON_New_Item();
- if (item) item->type = b ? cJSON_True : cJSON_False;
- return item;
-}
-cJSON *cJSON_CreateNumber(double num) {
- cJSON *item = cJSON_New_Item();
- if (item) {
- item->type = cJSON_Number;
- item->valuedouble = num;
- item->valueint = (int)num;
- }
- return item;
-}
-cJSON *cJSON_CreateString(const char *string) {
- cJSON *item = cJSON_New_Item();
- if (item) {
- item->type = cJSON_String;
- item->valuestring = cJSON_strdup(string);
- }
- return item;
-}
-cJSON *cJSON_CreateArray(void) {
- cJSON *item = cJSON_New_Item();
- if (item) item->type = cJSON_Array;
- return item;
-}
-cJSON *cJSON_CreateObject(void) {
- cJSON *item = cJSON_New_Item();
- if (item) item->type = cJSON_Object;
- return item;
-}
-
-/* Create Arrays: */
-cJSON *cJSON_CreateIntArray(const int *numbers, int count) {
- int i;
- cJSON *n = 0, *p = 0, *a = cJSON_CreateArray();
- for (i = 0; a && i < count; i++) {
- n = cJSON_CreateNumber(numbers[i]);
- if (!i)
- a->child = n;
- else
- suffix_object(p, n);
- p = n;
- }
- return a;
-}
-cJSON *cJSON_CreateFloatArray(const float *numbers, int count) {
- int i;
- cJSON *n = 0, *p = 0, *a = cJSON_CreateArray();
- for (i = 0; a && i < count; i++) {
- n = cJSON_CreateNumber(numbers[i]);
- if (!i)
- a->child = n;
- else
- suffix_object(p, n);
- p = n;
- }
- return a;
-}
-cJSON *cJSON_CreateDoubleArray(const double *numbers, int count) {
- int i;
- cJSON *n = 0, *p = 0, *a = cJSON_CreateArray();
- for (i = 0; a && i < count; i++) {
- n = cJSON_CreateNumber(numbers[i]);
- if (!i)
- a->child = n;
- else
- suffix_object(p, n);
- p = n;
- }
- return a;
-}
-cJSON *cJSON_CreateStringArray(const char **strings, int count) {
- int i;
- cJSON *n = 0, *p = 0, *a = cJSON_CreateArray();
- for (i = 0; a && i < count; i++) {
- n = cJSON_CreateString(strings[i]);
- if (!i)
- a->child = n;
- else
- suffix_object(p, n);
- p = n;
- }
- return a;
-}
-
-/* Duplication */
-cJSON *cJSON_Duplicate(cJSON *item, int recurse) {
- cJSON *newitem, *cptr, *nptr = 0, *newchild;
- /* Bail on bad ptr */
- if (!item) return 0;
- /* Create new item */
- newitem = cJSON_New_Item();
- if (!newitem) return 0;
- /* Copy over all vars */
- newitem->type = item->type & (~cJSON_IsReference), newitem->valueint = item->valueint, newitem->valuedouble = item->valuedouble;
- if (item->valuestring) {
- newitem->valuestring = cJSON_strdup(item->valuestring);
- if (!newitem->valuestring) {
- cJSON_Delete(newitem);
- return 0;
- }
- }
- if (item->string) {
- newitem->string = cJSON_strdup(item->string);
- if (!newitem->string) {
- cJSON_Delete(newitem);
- return 0;
- }
- }
- /* If non-recursive, then we're done! */
- if (!recurse) return newitem;
- /* Walk the ->next chain for the child. */
- cptr = item->child;
- while (cptr) {
- newchild = cJSON_Duplicate(cptr, 1); /* Duplicate (with recurse) each item in the ->next chain */
- if (!newchild) {
- cJSON_Delete(newitem);
- return 0;
- }
- if (nptr) {
- nptr->next = newchild, newchild->prev = nptr;
- nptr = newchild;
- } /* If newitem->child already set, then crosswire ->prev and ->next and
- move on */
- else {
- newitem->child = newchild;
- nptr = newchild;
- } /* Set newitem->child and move to it */
- cptr = cptr->next;
- }
- return newitem;
-}
-
-void cJSON_Minify(char *json) {
- char *into = json;
- while (*json) {
- if (*json == ' ')
- json++;
- else if (*json == '\t')
- json++; /* Whitespace characters. */
- else if (*json == '\r')
- json++;
- else if (*json == '\n')
- json++;
- else if (*json == '/' && json[1] == '/')
- while (*json && *json != '\n') json++; /* double-slash comments, to end of line. */
- else if (*json == '/' && json[1] == '*') {
- while (*json && !(*json == '*' && json[1] == '/')) json++;
- json += 2;
- } /* multiline comments. */
- else if (*json == '\"') {
- *into++ = *json++;
- while (*json && *json != '\"') {
- if (*json == '\\') *into++ = *json++;
- *into++ = *json++;
- }
- *into++ = *json++;
- } /* string literals, which are \" sensitive. */
- else
- *into++ = *json++; /* All other characters. */
- }
- *into = 0; /* and null-terminate. */
-}