26 #ifndef _CRT_SECURE_NO_WARNINGS
27 #define _CRT_SECURE_NO_WARNINGS
33 #define PARSON_IMPL_VERSION_MAJOR 1
34 #define PARSON_IMPL_VERSION_MINOR 5
35 #define PARSON_IMPL_VERSION_PATCH 3
37 #if (PARSON_VERSION_MAJOR != PARSON_IMPL_VERSION_MAJOR) || \
38 (PARSON_VERSION_MINOR != PARSON_IMPL_VERSION_MINOR) || \
39 (PARSON_VERSION_PATCH != PARSON_IMPL_VERSION_PATCH)
40 #error "parson version mismatch between parson.c and parson.h"
52 #pragma GCC visibility push(hidden)
59 #define sscanf THINK_TWICE_ABOUT_USING_SSCANF
66 #define strcpy USE_MEMCPY_INSTEAD_OF_STRCPY
68 #define STARTING_CAPACITY 16
69 #define MAX_NESTING 2048
71 #ifndef PARSON_DEFAULT_FLOAT_FORMAT
72 #define PARSON_DEFAULT_FLOAT_FORMAT \
76 #ifndef PARSON_NUM_BUF_SIZE
77 #define PARSON_NUM_BUF_SIZE \
82 #ifndef PARSON_INDENT_STR
83 #define PARSON_INDENT_STR " "
86 #define SIZEOF_TOKEN(a) (sizeof(a) - 1)
87 #define SKIP_CHAR(str) ((*str)++)
88 #define SKIP_WHITESPACES(str) \
89 while (isspace((unsigned char)(**str))) { \
92 #define MAX(a, b) ((a) > (b) ? (a) : (b))
97 #if defined(isnan) && defined(isinf)
98 #define IS_NUMBER_INVALID(x) (isnan((x)) || isinf((x)))
100 #define IS_NUMBER_INVALID(x) (((x) * 0.0) != 0.0)
103 #define OBJECT_INVALID_IX ((size_t) - 1)
108 static int parson_escape_slashes = 1;
110 static char *parson_float_format =
NULL;
116 (((unsigned char)(b) & 0xC0) == 0x80)
120 #define PARSON_TRUE 1
121 #define PARSON_FALSE 0
129 typedef union json_value_value {
138 struct json_value_t {
144 struct json_object_t {
147 unsigned long *hashes;
152 size_t item_capacity;
153 size_t cell_capacity;
156 struct json_array_t {
164 static char *read_file(
const char *filename);
165 static void remove_comments(
char *
string,
const char *start_token,
166 const char *end_token);
167 static char *parson_strndup(
const char *
string,
size_t n);
168 static char *parson_strdup(
const char *
string);
169 static int parson_sprintf(
char *s,
const char *format, ...);
170 static int hex_char_to_int(
char c);
171 static JSON_Status parse_utf16_hex(
const char *
string,
unsigned int *result);
172 static int num_bytes_in_utf8_sequence(
unsigned char c);
173 static JSON_Status verify_utf8_sequence(
const unsigned char *
string,
int *len);
174 static parson_bool_t is_valid_utf8(
const char *
string,
size_t string_len);
175 static parson_bool_t is_decimal(
const char *
string,
size_t length);
176 static unsigned long hash_string(
const char *
string,
size_t n);
184 static size_t json_object_get_cell_ix(
const JSON_Object *
object,
185 const char *key,
size_t key_len,
191 const char *
name,
size_t name_len);
204 static void json_array_free(
JSON_Array *array);
207 static JSON_Value *json_value_init_string_no_copy(
char *
string,
size_t length);
211 static JSON_Status skip_quotes(
const char **
string);
212 static JSON_Status parse_utf16(
const char **unprocessed,
char **processed);
213 static char *process_string(
const char *input,
size_t input_len,
215 static char *get_quoted_string(
const char **
string,
size_t *output_string_len);
216 static JSON_Value *parse_object_value(
const char **
string,
size_t nesting);
217 static JSON_Value *parse_array_value(
const char **
string,
size_t nesting);
218 static JSON_Value *parse_string_value(
const char **
string);
219 static JSON_Value *parse_boolean_value(
const char **
string);
220 static JSON_Value *parse_number_value(
const char **
string);
221 static JSON_Value *parse_null_value(
const char **
string);
222 static JSON_Value *parse_value(
const char **
string,
size_t nesting);
225 static int json_serialize_to_buffer_r(
const JSON_Value *value,
char *buf,
228 static int json_serialize_string(
const char *
string,
size_t len,
char *buf);
231 static char *read_file(
const char *filename)
233 FILE *fp = fopen(filename,
"r");
234 size_t size_to_read = 0;
235 size_t size_read = 0;
241 fseek(fp, 0L, SEEK_END);
249 file_contents = (
char *)parson_malloc(
sizeof(
char) * (size_to_read + 1));
250 if (!file_contents) {
254 size_read = fread(file_contents, 1, size_to_read, fp);
255 if (size_read == 0 || ferror(fp)) {
257 parson_free(file_contents);
261 file_contents[size_read] =
'\0';
262 return file_contents;
265 static void remove_comments(
char *
string,
const char *start_token,
266 const char *end_token)
270 char *ptr =
NULL, current_char;
271 size_t start_token_len = strlen(start_token);
272 size_t end_token_len = strlen(end_token);
273 if (start_token_len == 0 || end_token_len == 0) {
276 while ((current_char = *
string) !=
'\0') {
277 if (current_char ==
'\\' && !escaped) {
282 else if (current_char ==
'\"' && !escaped) {
283 in_string = !in_string;
285 else if (!in_string &&
286 strncmp(
string, start_token, start_token_len) == 0) {
287 for (i = 0; i < start_token_len; i++) {
290 string =
string + start_token_len;
291 ptr = strstr(
string, end_token);
295 for (i = 0; i < (ptr - string) + end_token_len; i++) {
298 string = ptr + end_token_len - 1;
305 static char *parson_strndup(
const char *
string,
size_t n)
309 char *output_string = (
char *)parson_malloc(n + 1);
310 if (!output_string) {
313 output_string[n] =
'\0';
314 memcpy(output_string,
string, n);
315 return output_string;
318 static char *parson_strdup(
const char *
string)
320 return parson_strndup(
string, strlen(
string));
323 static int parson_sprintf(
char *s,
const char *format, ...)
327 va_start(args, format);
329 #if defined(__APPLE__) && defined(__clang__)
330 #pragma clang diagnostic push
331 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
333 result = vsprintf(s, format, args);
334 #if defined(__APPLE__) && defined(__clang__)
335 #pragma clang diagnostic pop
342 static int hex_char_to_int(
char c)
344 if (c >=
'0' && c <=
'9') {
347 else if (c >=
'a' && c <=
'f') {
350 else if (c >=
'A' && c <=
'F') {
356 static JSON_Status parse_utf16_hex(
const char *s,
unsigned int *result)
359 if (s[0] ==
'\0' || s[1] ==
'\0' || s[2] ==
'\0' || s[3] ==
'\0') {
362 x1 = hex_char_to_int(s[0]);
363 x2 = hex_char_to_int(s[1]);
364 x3 = hex_char_to_int(s[2]);
365 x4 = hex_char_to_int(s[3]);
366 if (x1 == -1 || x2 == -1 || x3 == -1 || x4 == -1) {
369 *result = (
unsigned int)((x1 << 12) | (x2 << 8) | (x3 << 4) | x4);
373 static int num_bytes_in_utf8_sequence(
unsigned char c)
375 if (c == 0xC0 || c == 0xC1 || c > 0xF4 ||
IS_CONT(c)) {
378 else if ((c & 0x80) == 0) {
381 else if ((c & 0xE0) == 0xC0) {
384 else if ((c & 0xF0) == 0xE0) {
387 else if ((c & 0xF8) == 0xF0) {
393 static JSON_Status verify_utf8_sequence(
const unsigned char *
string,
int *len)
396 *len = num_bytes_in_utf8_sequence(
string[0]);
401 else if (*len == 2 &&
IS_CONT(
string[1])) {
402 cp =
string[0] & 0x1F;
403 cp = (cp << 6) | (
string[1] & 0x3F);
406 cp = ((
unsigned char)
string[0]) & 0xF;
407 cp = (cp << 6) | (
string[1] & 0x3F);
408 cp = (cp << 6) | (
string[2] & 0x3F);
412 cp =
string[0] & 0x7;
413 cp = (cp << 6) | (
string[1] & 0x3F);
414 cp = (cp << 6) | (
string[2] & 0x3F);
415 cp = (cp << 6) | (
string[3] & 0x3F);
422 if ((cp < 0x80 && *len > 1) || (cp < 0x800 && *len > 2) ||
423 (cp < 0x10000 && *len > 3)) {
433 if (cp >= 0xD800 && cp <= 0xDFFF) {
440 static int is_valid_utf8(
const char *
string,
size_t string_len)
443 const char *string_end =
string + string_len;
444 while (
string < string_end) {
445 if (verify_utf8_sequence((
const unsigned char *)
string, &len) !=
454 static parson_bool_t is_decimal(
const char *
string,
size_t length)
456 if (length > 1 &&
string[0] ==
'0' &&
string[1] !=
'.') {
459 if (length > 2 && !strncmp(
string,
"-0", 2) &&
string[2] !=
'.') {
463 if (strchr(
"xX",
string[length])) {
470 static unsigned long hash_string(
const char *
string,
size_t n)
472 #ifdef PARSON_FORCE_HASH_COLLISIONS
477 unsigned long hash = 5381;
480 for (i = 0; i < n; i++) {
485 hash = ((hash << 5) + hash) + c;
496 if (new_obj ==
NULL) {
499 new_obj->wrapping_value = wrapping_value;
500 res = json_object_init(new_obj, 0);
502 parson_free(new_obj);
512 object->cells =
NULL;
513 object->names =
NULL;
514 object->values =
NULL;
515 object->cell_ixs =
NULL;
516 object->hashes =
NULL;
519 object->cell_capacity = capacity;
520 object->item_capacity = (
unsigned int)(capacity * 7 / 10);
527 (
size_t *)parson_malloc(object->cell_capacity *
sizeof(*object->cells));
529 (
char **)parson_malloc(object->item_capacity *
sizeof(*object->names));
530 object->values = (
JSON_Value **)parson_malloc(object->item_capacity *
531 sizeof(*object->values));
532 object->cell_ixs = (
size_t *)parson_malloc(object->item_capacity *
533 sizeof(*object->cell_ixs));
534 object->hashes = (
unsigned long *)parson_malloc(object->item_capacity *
535 sizeof(*object->hashes));
536 if (object->cells ==
NULL || object->names ==
NULL ||
537 object->values ==
NULL || object->cell_ixs ==
NULL ||
538 object->hashes ==
NULL) {
541 for (i = 0; i <
object->cell_capacity; i++) {
546 parson_free(object->cells);
547 parson_free(object->names);
548 parson_free(object->values);
549 parson_free(object->cell_ixs);
550 parson_free(object->hashes);
558 for (i = 0; i <
object->count; i++) {
560 parson_free(object->names[i]);
568 object->item_capacity = 0;
569 object->cell_capacity = 0;
571 parson_free(object->cells);
572 parson_free(object->names);
573 parson_free(object->values);
574 parson_free(object->cell_ixs);
575 parson_free(object->hashes);
577 object->cells =
NULL;
578 object->names =
NULL;
579 object->values =
NULL;
580 object->cell_ixs =
NULL;
581 object->hashes =
NULL;
592 JSON_Status res = json_object_init(&new_object, new_capacity);
598 new_object.wrapping_value = wrapping_value;
600 for (i = 0; i <
object->count; i++) {
601 key =
object->names[i];
602 value =
object->values[i];
603 res = json_object_add(&new_object, key, value);
608 value->parent = wrapping_value;
611 *
object = new_object;
615 static size_t json_object_get_cell_ix(
const JSON_Object *
object,
616 const char *key,
size_t key_len,
620 size_t cell_ix = hash & (
object->cell_capacity - 1);
624 unsigned long hash_to_check = 0;
625 const char *key_to_check =
NULL;
626 size_t key_to_check_len = 0;
630 for (i = 0; i <
object->cell_capacity; i++) {
631 ix = (cell_ix + i) & (object->cell_capacity - 1);
632 cell =
object->cells[ix];
636 hash_to_check =
object->hashes[cell];
637 if (hash != hash_to_check) {
640 key_to_check =
object->names[cell];
641 key_to_check_len = strlen(key_to_check);
642 if (key_to_check_len == key_len &&
643 strncmp(key, key_to_check, key_len) == 0) {
654 unsigned long hash = 0;
659 if (!
object || !
name || !value) {
663 hash = hash_string(
name, strlen(
name));
665 cell_ix = json_object_get_cell_ix(
object,
name, strlen(
name), hash, &found);
670 if (object->count >= object->item_capacity) {
671 res = json_object_grow_and_rehash(
object);
676 json_object_get_cell_ix(
object,
name, strlen(
name), hash, &found);
679 object->names[
object->count] =
name;
680 object->cells[cell_ix] =
object->count;
681 object->values[
object->count] = value;
682 object->cell_ixs[
object->count] = cell_ix;
683 object->hashes[
object->count] = hash;
691 const char *
name,
size_t name_len)
693 unsigned long hash = 0;
697 if (!
object || !
name) {
700 hash = hash_string(
name, name_len);
702 cell_ix = json_object_get_cell_ix(
object,
name, name_len, hash, &found);
706 item_ix =
object->cells[cell_ix];
707 return object->values[item_ix];
714 unsigned long hash = 0;
718 size_t last_item_ix = 0;
725 if (
object ==
NULL) {
729 hash = hash_string(
name, strlen(
name));
731 cell = json_object_get_cell_ix(
object,
name, strlen(
name), hash, &found);
736 item_ix =
object->cells[cell];
738 val =
object->values[item_ix];
743 parson_free(object->names[item_ix]);
744 last_item_ix =
object->count - 1;
745 if (item_ix < last_item_ix) {
746 object->names[item_ix] =
object->names[last_item_ix];
747 object->values[item_ix] =
object->values[last_item_ix];
748 object->cell_ixs[item_ix] =
object->cell_ixs[last_item_ix];
749 object->hashes[item_ix] =
object->hashes[last_item_ix];
750 object->cells[
object->cell_ixs[item_ix]] = item_ix;
756 for (
x = 0;
x < (
object->cell_capacity - 1);
x++) {
757 j = (j + 1) & (object->cell_capacity - 1);
761 k =
object->hashes[
object->cells[j]] & (
object->cell_capacity - 1);
762 if ((j > i && (k <= i || k > j)) || (j < i && (k <= i && k > j))) {
763 object->cell_ixs[
object->cells[j]] = i;
764 object->cells[i] =
object->cells[j];
778 const char *dot_pos = strchr(
name,
'.');
780 return json_object_remove_internal(
object,
name, free_value);
782 temp_value = json_object_getn_value(
object,
name, dot_pos -
name);
787 return json_object_dotremove_internal(temp_object, dot_pos + 1, free_value);
800 if (new_array ==
NULL) {
803 new_array->wrapping_value = wrapping_value;
805 new_array->capacity = 0;
806 new_array->count = 0;
812 if (array->count >= array->capacity) {
814 if (json_array_resize(array, new_capacity) !=
JSONSuccess) {
819 array->items[array->count] = value;
827 if (new_capacity == 0) {
832 if (new_items ==
NULL) {
835 if (array->items !=
NULL && array->count > 0) {
836 memcpy(new_items, array->items, array->count *
sizeof(
JSON_Value *));
838 parson_free(array->items);
839 array->items = new_items;
840 array->capacity = new_capacity;
844 static void json_array_free(
JSON_Array *array)
847 for (i = 0; i < array->count; i++) {
850 parson_free(array->items);
855 static JSON_Value *json_value_init_string_no_copy(
char *
string,
size_t length)
861 new_value->parent =
NULL;
863 new_value->value.string.chars = string;
864 new_value->value.string.length = length;
869 static JSON_Status skip_quotes(
const char **
string)
871 if (**
string !=
'\"') {
875 while (**
string !=
'\"') {
876 if (**
string ==
'\0') {
879 else if (**
string ==
'\\') {
881 if (**
string ==
'\0') {
891 static JSON_Status parse_utf16(
const char **unprocessed,
char **processed)
893 unsigned int cp, lead, trail;
894 char *processed_ptr = *processed;
895 const char *unprocessed_ptr = *unprocessed;
898 status = parse_utf16_hex(unprocessed_ptr, &cp);
903 processed_ptr[0] = (char)cp;
905 else if (cp < 0x800) {
906 processed_ptr[0] = ((cp >> 6) & 0x1F) | 0xC0;
907 processed_ptr[1] = ((cp) & 0x3F) | 0x80;
910 else if (cp < 0xD800 || cp > 0xDFFF) {
911 processed_ptr[0] = ((cp >> 12) & 0x0F) | 0xE0;
912 processed_ptr[1] = ((cp >> 6) & 0x3F) | 0x80;
913 processed_ptr[2] = ((cp) & 0x3F) | 0x80;
916 else if (cp >= 0xD800 &&
919 unprocessed_ptr += 4;
921 if (*unprocessed_ptr++ !=
'\\' || *unprocessed_ptr++ !=
'u') {
924 status = parse_utf16_hex(unprocessed_ptr, &trail);
929 cp = ((((lead - 0xD800) & 0x3FF) << 10) | ((trail - 0xDC00) & 0x3FF)) +
931 processed_ptr[0] = (((cp >> 18) & 0x07) | 0xF0);
932 processed_ptr[1] = (((cp >> 12) & 0x3F) | 0x80);
933 processed_ptr[2] = (((cp >> 6) & 0x3F) | 0x80);
934 processed_ptr[3] = (((cp) & 0x3F) | 0x80);
940 unprocessed_ptr += 3;
941 *processed = processed_ptr;
942 *unprocessed = unprocessed_ptr;
948 static char *process_string(
const char *input,
size_t input_len,
951 const char *input_ptr = input;
952 size_t initial_size = (input_len + 1) *
sizeof(
char);
953 size_t final_size = 0;
955 output = (
char *)parson_malloc(initial_size);
960 while ((*input_ptr !=
'\0') && (size_t)(input_ptr - input) < input_len) {
961 if (*input_ptr ==
'\\') {
963 switch (*input_ptr) {
989 if (parse_utf16(&input_ptr, &output_ptr) !=
JSONSuccess) {
997 else if ((
unsigned char)*input_ptr < 0x20) {
1002 *output_ptr = *input_ptr;
1009 final_size = (size_t)(output_ptr -
output) + 1;
1011 resized_output = (
char *)parson_malloc(final_size);
1012 if (resized_output ==
NULL) {
1015 memcpy(resized_output,
output, final_size);
1016 *output_len = final_size - 1;
1018 return resized_output;
1026 static char *get_quoted_string(
const char **
string,
size_t *output_string_len)
1028 const char *string_start = *string;
1029 size_t input_string_len = 0;
1034 input_string_len = *
string - string_start - 2;
1035 return process_string(string_start + 1, input_string_len,
1039 static JSON_Value *parse_value(
const char **
string,
size_t nesting)
1047 return parse_object_value(
string, nesting + 1);
1049 return parse_array_value(
string, nesting + 1);
1051 return parse_string_value(
string);
1054 return parse_boolean_value(
string);
1066 return parse_number_value(
string);
1068 return parse_null_value(
string);
1074 static JSON_Value *parse_object_value(
const char **
string,
size_t nesting)
1079 char *new_key =
NULL;
1082 if (output_value ==
NULL) {
1085 if (**
string !=
'{') {
1092 if (**
string ==
'}') {
1094 return output_value;
1096 while (**
string !=
'\0') {
1098 new_key = get_quoted_string(
string, &key_len);
1104 if (key_len != strlen(new_key)) {
1105 parson_free(new_key);
1110 if (**
string !=
':') {
1111 parson_free(new_key);
1116 new_value = parse_value(
string, nesting);
1117 if (new_value ==
NULL) {
1118 parson_free(new_key);
1122 status = json_object_add(output_object, new_key, new_value);
1124 parson_free(new_key);
1130 if (**
string !=
',') {
1135 if (**
string ==
'}') {
1140 if (**
string !=
'}') {
1145 return output_value;
1148 static JSON_Value *parse_array_value(
const char **
string,
size_t nesting)
1153 if (output_value ==
NULL) {
1156 if (**
string !=
'[') {
1163 if (**
string ==
']') {
1165 return output_value;
1167 while (**
string !=
'\0') {
1168 new_array_value = parse_value(
string, nesting);
1169 if (new_array_value ==
NULL) {
1173 if (json_array_add(output_array, new_array_value) !=
JSONSuccess) {
1179 if (**
string !=
',') {
1184 if (**
string ==
']') {
1189 if (**
string !=
']' ||
1196 return output_value;
1199 static JSON_Value *parse_string_value(
const char **
string)
1202 size_t new_string_len = 0;
1203 char *new_string = get_quoted_string(
string, &new_string_len);
1204 if (new_string ==
NULL) {
1207 value = json_value_init_string_no_copy(new_string, new_string_len);
1208 if (value ==
NULL) {
1209 parson_free(new_string);
1215 static JSON_Value *parse_boolean_value(
const char **
string)
1219 if (strncmp(
"true", *
string, true_token_size) == 0) {
1220 *
string += true_token_size;
1223 else if (strncmp(
"false", *
string, false_token_size) == 0) {
1224 *
string += false_token_size;
1230 static JSON_Value *parse_number_value(
const char **
string)
1235 number = strtod(*
string, &end);
1236 if (errno == ERANGE && (number <= -HUGE_VAL || number >=
HUGE_VAL)) {
1239 if ((errno && errno != ERANGE) || !is_decimal(*
string, end - *
string)) {
1246 static JSON_Value *parse_null_value(
const char **
string)
1249 if (strncmp(
"null", *
string, token_size) == 0) {
1250 *
string += token_size;
1263 #define APPEND_STRING(str) \
1265 written = SIZEOF_TOKEN((str)); \
1266 if (buf != NULL) { \
1267 memcpy(buf, (str), written); \
1268 buf[written] = '\0'; \
1271 written_total += written; \
1274 #define APPEND_INDENT(level) \
1277 for (level_i = 0; level_i < (level); level_i++) { \
1278 APPEND_STRING(PARSON_INDENT_STR); \
1282 static int json_serialize_to_buffer_r(
const JSON_Value *value,
char *buf,
1286 const char *key =
NULL, *
string =
NULL;
1290 size_t i = 0,
count = 0;
1292 int written = -1, written_total = 0;
1300 if (
count > 0 && is_pretty) {
1303 for (i = 0; i <
count; i++) {
1308 written = json_serialize_to_buffer_r(temp_value, buf, level + 1,
1309 is_pretty, num_buf);
1316 written_total += written;
1317 if (i < (
count - 1)) {
1324 if (
count > 0 && is_pretty) {
1328 return written_total;
1333 if (
count > 0 && is_pretty) {
1336 for (i = 0; i <
count; i++) {
1345 written = json_serialize_string(key, strlen(key), buf);
1352 written_total += written;
1358 written = json_serialize_to_buffer_r(temp_value, buf, level + 1,
1359 is_pretty, num_buf);
1366 written_total += written;
1367 if (i < (
count - 1)) {
1374 if (
count > 0 && is_pretty) {
1378 return written_total;
1381 if (
string ==
NULL) {
1385 written = json_serialize_string(
string, len, buf);
1392 written_total += written;
1393 return written_total;
1401 return written_total;
1407 if (parson_number_serialization_function) {
1408 written = parson_number_serialization_function(num, num_buf);
1411 const char *float_format = parson_float_format
1412 ? parson_float_format
1414 written = parson_sprintf(num_buf, float_format, num);
1422 written_total += written;
1423 return written_total;
1426 return written_total;
1434 static int json_serialize_string(
const char *
string,
size_t len,
char *buf)
1438 int written = -1, written_total = 0;
1440 for (i = 0; i < len; i++) {
1551 if (parson_escape_slashes) {
1568 return written_total;
1571 #undef APPEND_STRING
1572 #undef APPEND_INDENT
1577 char *file_contents = read_file(filename);
1579 if (file_contents ==
NULL) {
1583 parson_free(file_contents);
1584 return output_value;
1589 char *file_contents = read_file(filename);
1591 if (file_contents ==
NULL) {
1595 parson_free(file_contents);
1596 return output_value;
1601 if (
string ==
NULL) {
1604 if (
string[0] ==
'\xEF' &&
string[1] ==
'\xBB' &&
string[2] ==
'\xBF') {
1605 string =
string + 3;
1607 return parse_value((
const char **)&
string, 0);
1613 char *string_mutable_copy =
NULL, *string_mutable_copy_ptr =
NULL;
1614 string_mutable_copy = parson_strdup(
string);
1615 if (string_mutable_copy ==
NULL) {
1618 remove_comments(string_mutable_copy,
"/*",
"*/");
1619 remove_comments(string_mutable_copy,
"//",
"\n");
1620 string_mutable_copy_ptr = string_mutable_copy;
1621 result = parse_value((
const char **)&string_mutable_copy_ptr, 0);
1622 parson_free(string_mutable_copy);
1633 return json_object_getn_value(
object,
name, strlen(
name));
1669 const char *dot_position = strchr(
name,
'.');
1670 if (!dot_position) {
1674 json_object_getn_value(
object,
name, dot_position -
name));
1714 return object ?
object->count : 0;
1722 return object->names[index];
1730 return object->values[index];
1738 return object->wrapping_value;
1771 return array->items[index];
1806 return array ? array->count : 0;
1814 return array->wrapping_value;
1842 const JSON_String *str = json_value_get_string_desc(value);
1843 return str ? str->chars :
NULL;
1848 const JSON_String *str = json_value_get_string_desc(value);
1849 return str ? str->length : 0;
1865 return value ? value->parent :
NULL;
1872 json_object_free(value->value.object);
1875 parson_free(value->value.string.chars);
1878 json_array_free(value->value.array);
1892 new_value->parent =
NULL;
1894 new_value->value.object = json_object_make(new_value);
1895 if (!new_value->value.object) {
1896 parson_free(new_value);
1908 new_value->parent =
NULL;
1910 new_value->value.array = json_array_make(new_value);
1911 if (!new_value->value.array) {
1912 parson_free(new_value);
1920 if (
string ==
NULL) {
1930 if (
string ==
NULL) {
1933 if (!is_valid_utf8(
string, length)) {
1936 copy = parson_strndup(
string, length);
1940 value = json_value_init_string_no_copy(copy, length);
1941 if (value ==
NULL) {
1954 if (new_value ==
NULL) {
1957 new_value->parent =
NULL;
1959 new_value->value.number = number;
1969 new_value->parent =
NULL;
1971 new_value->value.boolean =
boolean ? 1 : 0;
1981 new_value->parent =
NULL;
1992 const char *temp_key =
NULL;
1993 char *temp_string_copy =
NULL;
1997 char *key_copy =
NULL;
2003 if (return_value ==
NULL) {
2010 if (temp_value_copy ==
NULL) {
2014 if (json_array_add(temp_array_copy, temp_value_copy) !=
2021 return return_value;
2025 if (!return_value) {
2033 if (!temp_value_copy) {
2037 key_copy = parson_strdup(temp_key);
2043 res = json_object_add(temp_object_copy, key_copy, temp_value_copy);
2045 parson_free(key_copy);
2051 return return_value;
2057 temp_string = json_value_get_string_desc(value);
2058 if (temp_string ==
NULL) {
2062 parson_strndup(temp_string->chars, temp_string->length);
2063 if (temp_string_copy ==
NULL) {
2066 return_value = json_value_init_string_no_copy(temp_string_copy,
2067 temp_string->length);
2068 if (return_value ==
NULL) {
2069 parson_free(temp_string_copy);
2071 return return_value;
2086 int res = json_serialize_to_buffer_r(value,
NULL, 0,
PARSON_FALSE, num_buf);
2087 return res < 0 ? 0 : (size_t)(res) + 1;
2091 size_t buf_size_in_bytes)
2095 if (needed_size_in_bytes == 0 || buf_size_in_bytes < needed_size_in_bytes) {
2106 const char *filename)
2111 if (serialized_string ==
NULL) {
2114 fp = fopen(filename,
"w");
2119 if (fputs(serialized_string, fp) == EOF) {
2122 if (fclose(fp) == EOF) {
2134 if (buf_size_bytes == 0) {
2137 buf = (
char *)parson_malloc(buf_size_bytes);
2154 int res = json_serialize_to_buffer_r(value,
NULL, 0,
PARSON_TRUE, num_buf);
2155 return res < 0 ? 0 : (size_t)(res) + 1;
2159 size_t buf_size_in_bytes)
2163 if (needed_size_in_bytes == 0 || buf_size_in_bytes < needed_size_in_bytes) {
2166 written = json_serialize_to_buffer_r(value, buf, 0,
PARSON_TRUE,
NULL);
2174 const char *filename)
2179 if (serialized_string ==
NULL) {
2182 fp = fopen(filename,
"w");
2187 if (fputs(serialized_string, fp) == EOF) {
2190 if (fclose(fp) == EOF) {
2202 if (buf_size_bytes == 0) {
2205 buf = (
char *)parson_malloc(buf_size_bytes);
2209 serialization_result =
2220 parson_free(
string);
2225 size_t to_move_bytes = 0;
2232 memmove(array->items + ix, array->items + ix + 1, to_move_bytes);
2240 if (array ==
NULL || value ==
NULL || value->parent !=
NULL ||
2246 array->items[ix] = value;
2254 if (value ==
NULL) {
2265 const char *
string,
size_t len)
2268 if (value ==
NULL) {
2282 if (value ==
NULL) {
2295 if (value ==
NULL) {
2308 if (value ==
NULL) {
2321 if (array ==
NULL) {
2333 if (array ==
NULL || value ==
NULL || value->parent !=
NULL) {
2336 return json_array_add(array, value);
2342 if (value ==
NULL) {
2353 const char *
string,
size_t len)
2356 if (value ==
NULL) {
2369 if (value ==
NULL) {
2382 if (value ==
NULL) {
2395 if (value ==
NULL) {
2408 unsigned long hash = 0;
2413 char *key_copy =
NULL;
2415 if (!
object || !
name || !value || value->parent) {
2418 hash = hash_string(
name, strlen(
name));
2420 cell_ix = json_object_get_cell_ix(
object,
name, strlen(
name), hash, &found);
2422 item_ix =
object->cells[cell_ix];
2423 old_value =
object->values[item_ix];
2425 object->values[item_ix] = value;
2429 if (object->count >= object->item_capacity) {
2430 JSON_Status res = json_object_grow_and_rehash(
object);
2435 json_object_get_cell_ix(
object,
name, strlen(
name), hash, &found);
2437 key_copy = parson_strdup(
name);
2441 object->names[
object->count] = key_copy;
2442 object->cells[cell_ix] =
object->count;
2443 object->values[
object->count] = value;
2444 object->cell_ixs[
object->count] = cell_ix;
2445 object->hashes[
object->count] = hash;
2464 const char *
string,
size_t len)
2509 const char *dot_pos =
NULL;
2513 size_t name_len = 0;
2514 char *name_copy =
NULL;
2519 dot_pos = strchr(
name,
'.');
2520 if (dot_pos ==
NULL) {
2523 name_len = dot_pos -
name;
2524 temp_value = json_object_getn_value(
object,
name, name_len);
2535 if (new_value ==
NULL) {
2544 name_copy = parson_strndup(
name, name_len);
2546 json_object_dotremove_internal(new_object, dot_pos + 1, 0);
2550 status = json_object_add(
object, name_copy, new_value);
2552 parson_free(name_copy);
2553 json_object_dotremove_internal(new_object, dot_pos + 1, 0);
2564 if (value ==
NULL) {
2576 const char *
string,
size_t len)
2579 if (value ==
NULL) {
2593 if (value ==
NULL) {
2607 if (value ==
NULL) {
2620 if (value ==
NULL) {
2643 if (
object ==
NULL) {
2647 parson_free(object->names[i]);
2648 object->names[i] =
NULL;
2651 object->values[i] =
NULL;
2654 for (i = 0; i <
object->cell_capacity; i++) {
2666 const char *key =
NULL;
2667 size_t i = 0,
count = 0;
2668 if (schema ==
NULL || value ==
NULL) {
2673 if (schema_type != value_type &&
2677 switch (schema_type) {
2705 for (i = 0; i <
count; i++) {
2709 if (temp_value ==
NULL) {
2733 const char *key =
NULL;
2734 size_t a_count = 0, b_count = 0, i = 0;
2738 if (a_type != b_type) {
2747 if (a_count != b_count) {
2750 for (i = 0; i < a_count; i++) {
2762 if (a_count != b_count) {
2765 for (i = 0; i < a_count; i++) {
2774 a_string = json_value_get_string_desc(a);
2775 b_string = json_value_get_string_desc(
b);
2776 if (a_string ==
NULL || b_string ==
NULL) {
2779 return a_string->length == b_string->length &&
2780 memcmp(a_string->chars, b_string->chars, a_string->length) == 0;
2833 parson_malloc = malloc_fun;
2834 parson_free = free_fun;
2839 parson_escape_slashes = escape_slashes;
2844 if (parson_float_format) {
2845 parson_free(parson_float_format);
2846 parson_float_format =
NULL;
2849 parson_float_format =
NULL;
2852 parson_float_format = parson_strdup(format);
2858 parson_number_serialization_function = func;
2861 #if defined(__GNUC__)
2862 #pragma GCC visibility pop
#define HUGE_VAL
Values needed for Ray-Convex Polyhedron Intersection Test below originally by Eric Haines,...
JSON_Status json_object_dotset_string(JSON_Object *object, const char *name, const char *string)
size_t json_object_get_string_len(const JSON_Object *object, const char *name)
JSON_Value * json_parse_file_with_comments(const char *filename)
JSON_Status json_array_replace_null(JSON_Array *array, size_t i)
JSON_Object * json_object_dotget_object(const JSON_Object *object, const char *name)
int json_object_get_boolean(const JSON_Object *object, const char *name)
size_t json_value_get_string_len(const JSON_Value *value)
size_t json_string_len(const JSON_Value *value)
JSON_Value * json_value_init_array(void)
JSON_Value * json_array_get_value(const JSON_Array *array, size_t index)
JSON_Status json_object_dotset_boolean(JSON_Object *object, const char *name, int boolean)
JSON_Status json_array_append_null(JSON_Array *array)
JSON_Status json_array_replace_boolean(JSON_Array *array, size_t i, int boolean)
JSON_Value * json_value_deep_copy(const JSON_Value *value)
JSON_Status json_object_remove(JSON_Object *object, const char *name)
JSON_Object * json_value_get_object(const JSON_Value *value)
JSON_Status json_serialize_to_buffer_pretty(const JSON_Value *value, char *buf, size_t buf_size_in_bytes)
#define IS_NUMBER_INVALID(x)
JSON_Object * json_array_get_object(const JSON_Array *array, size_t index)
size_t json_serialization_size_pretty(const JSON_Value *value)
JSON_Status json_array_replace_value(JSON_Array *array, size_t ix, JSON_Value *value)
JSON_Value * json_value_init_string(const char *string)
JSON_Value * json_value_init_string_with_len(const char *string, size_t length)
JSON_Status json_array_append_boolean(JSON_Array *array, int boolean)
JSON_Value_Type json_type(const JSON_Value *value)
int json_object_dotget_boolean(const JSON_Object *object, const char *name)
JSON_Value * json_object_get_value(const JSON_Object *object, const char *name)
JSON_Status json_array_replace_string_with_len(JSON_Array *array, size_t i, const char *string, size_t len)
const char * json_value_get_string(const JSON_Value *value)
JSON_Status json_object_dotset_null(JSON_Object *object, const char *name)
JSON_Status json_object_set_string_with_len(JSON_Object *object, const char *name, const char *string, size_t len)
struct json_string JSON_String
#define SKIP_WHITESPACES(str)
JSON_Status json_object_set_number(JSON_Object *object, const char *name, double number)
int json_object_has_value_of_type(const JSON_Object *object, const char *name, JSON_Value_Type type)
void json_set_float_serialization_format(const char *format)
size_t json_array_get_count(const JSON_Array *array)
double json_array_get_number(const JSON_Array *array, size_t index)
JSON_Status json_array_replace_number(JSON_Array *array, size_t i, double number)
const char * json_array_get_string(const JSON_Array *array, size_t index)
void json_set_number_serialization_function(JSON_Number_Serialization_Function func)
JSON_Status json_array_clear(JSON_Array *array)
JSON_Array * json_value_get_array(const JSON_Value *value)
JSON_Status json_object_set_string(JSON_Object *object, const char *name, const char *string)
JSON_Status json_object_set_boolean(JSON_Object *object, const char *name, int boolean)
void json_free_serialized_string(char *string)
JSON_Object * json_object_get_object(const JSON_Object *object, const char *name)
JSON_Status json_array_remove(JSON_Array *array, size_t ix)
int json_value_equals(const JSON_Value *a, const JSON_Value *b)
union json_value_value JSON_Value_Value
JSON_Status json_validate(const JSON_Value *schema, const JSON_Value *value)
JSON_Value * json_object_get_wrapping_value(const JSON_Object *object)
JSON_Status json_serialize_to_file(const JSON_Value *value, const char *filename)
JSON_Status json_array_append_string_with_len(JSON_Array *array, const char *string, size_t len)
#define PARSON_DEFAULT_FLOAT_FORMAT
JSON_Value * json_object_dotget_value(const JSON_Object *object, const char *name)
char * json_serialize_to_string_pretty(const JSON_Value *value)
int json_object_dothas_value_of_type(const JSON_Object *object, const char *name, JSON_Value_Type type)
void json_set_escape_slashes(int escape_slashes)
JSON_Status json_object_dotremove(JSON_Object *object, const char *name)
JSON_Status json_object_dotset_value(JSON_Object *object, const char *name, JSON_Value *value)
size_t json_object_get_count(const JSON_Object *object)
#define STARTING_CAPACITY
JSON_Value * json_parse_string(const char *string)
int json_boolean(const JSON_Value *value)
JSON_Value * json_value_get_parent(const JSON_Value *value)
double json_number(const JSON_Value *value)
JSON_Value * json_parse_string_with_comments(const char *string)
JSON_Value * json_object_get_value_at(const JSON_Object *object, size_t index)
JSON_Status json_array_append_value(JSON_Array *array, JSON_Value *value)
int json_object_dothas_value(const JSON_Object *object, const char *name)
#define APPEND_INDENT(level)
#define PARSON_NUM_BUF_SIZE
const char * json_string(const JSON_Value *value)
JSON_Object * json_object(const JSON_Value *value)
int json_object_has_value(const JSON_Object *object, const char *name)
int json_value_get_boolean(const JSON_Value *value)
JSON_Value * json_value_init_object(void)
JSON_Status json_object_clear(JSON_Object *object)
JSON_Array * json_array_get_array(const JSON_Array *array, size_t index)
JSON_Value * json_value_init_null(void)
int json_array_get_boolean(const JSON_Array *array, size_t index)
JSON_Status json_object_set_value(JSON_Object *object, const char *name, JSON_Value *value)
JSON_Status json_object_dotset_string_with_len(JSON_Object *object, const char *name, const char *string, size_t len)
size_t json_array_get_string_len(const JSON_Array *array, size_t index)
void json_value_free(JSON_Value *value)
JSON_Status json_object_set_null(JSON_Object *object, const char *name)
JSON_Status json_serialize_to_file_pretty(const JSON_Value *value, const char *filename)
size_t json_serialization_size(const JSON_Value *value)
JSON_Array * json_object_get_array(const JSON_Object *object, const char *name)
const char * json_object_dotget_string(const JSON_Object *object, const char *name)
#define APPEND_STRING(str)
JSON_Status json_array_append_string(JSON_Array *array, const char *string)
const char * json_object_get_string(const JSON_Object *object, const char *name)
size_t json_object_dotget_string_len(const JSON_Object *object, const char *name)
double json_value_get_number(const JSON_Value *value)
double json_object_get_number(const JSON_Object *object, const char *name)
double json_object_dotget_number(const JSON_Object *object, const char *name)
JSON_Value * json_parse_file(const char *filename)
JSON_Value_Type json_value_get_type(const JSON_Value *value)
JSON_Array * json_array(const JSON_Value *value)
JSON_Value * json_value_init_boolean(int boolean)
char * json_serialize_to_string(const JSON_Value *value)
JSON_Status json_object_dotset_number(JSON_Object *object, const char *name, double number)
#define OBJECT_INVALID_IX
const char * json_object_get_name(const JSON_Object *object, size_t index)
void json_set_allocation_functions(JSON_Malloc_Function malloc_fun, JSON_Free_Function free_fun)
JSON_Array * json_object_dotget_array(const JSON_Object *object, const char *name)
JSON_Value * json_array_get_wrapping_value(const JSON_Array *array)
JSON_Value * json_value_init_number(double number)
JSON_Status json_array_append_number(JSON_Array *array, double number)
JSON_Status json_array_replace_string(JSON_Array *array, size_t i, const char *string)
JSON_Status json_serialize_to_buffer(const JSON_Value *value, char *buf, size_t buf_size_in_bytes)
void *(* JSON_Malloc_Function)(size_t)
int(* JSON_Number_Serialization_Function)(double num, char *buf)
struct json_array_t JSON_Array
struct json_value_t JSON_Value
void(* JSON_Free_Function)(void *)
struct json_object_t JSON_Object
void output(const char *fmt,...)