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"
55 #define sscanf THINK_TWICE_ABOUT_USING_SSCANF
62 #define strcpy USE_MEMCPY_INSTEAD_OF_STRCPY
64 #define STARTING_CAPACITY 16
65 #define MAX_NESTING 2048
67 #ifndef PARSON_DEFAULT_FLOAT_FORMAT
68 #define PARSON_DEFAULT_FLOAT_FORMAT \
72 #ifndef PARSON_NUM_BUF_SIZE
73 #define PARSON_NUM_BUF_SIZE \
78 #ifndef PARSON_INDENT_STR
79 #define PARSON_INDENT_STR " "
82 #define SIZEOF_TOKEN(a) (sizeof(a) - 1)
83 #define SKIP_CHAR(str) ((*str)++)
84 #define SKIP_WHITESPACES(str) \
85 while (isspace((unsigned char)(**str))) { \
88 #define MAX(a, b) ((a) > (b) ? (a) : (b))
93 #if defined(isnan) && defined(isinf)
94 #define IS_NUMBER_INVALID(x) (isnan((x)) || isinf((x)))
96 #define IS_NUMBER_INVALID(x) (((x) * 0.0) != 0.0)
99 #define OBJECT_INVALID_IX ((size_t) - 1)
104 static int parson_escape_slashes = 1;
106 static char *parson_float_format =
NULL;
112 (((unsigned char)(b) & 0xC0) == 0x80)
116 #define PARSON_TRUE 1
117 #define PARSON_FALSE 0
125 typedef union json_value_value {
134 struct json_value_t {
140 struct json_object_t {
143 unsigned long *hashes;
148 size_t item_capacity;
149 size_t cell_capacity;
152 struct json_array_t {
160 static char *read_file(
const char *filename);
161 static void remove_comments(
char *
string,
const char *start_token,
162 const char *end_token);
163 static char *parson_strndup(
const char *
string,
size_t n);
164 static char *parson_strdup(
const char *
string);
165 static int parson_sprintf(
char *s,
const char *format, ...);
166 static int hex_char_to_int(
char c);
167 static JSON_Status parse_utf16_hex(
const char *
string,
unsigned int *result);
168 static int num_bytes_in_utf8_sequence(
unsigned char c);
169 static JSON_Status verify_utf8_sequence(
const unsigned char *
string,
int *len);
170 static parson_bool_t is_valid_utf8(
const char *
string,
size_t string_len);
171 static parson_bool_t is_decimal(
const char *
string,
size_t length);
172 static unsigned long hash_string(
const char *
string,
size_t n);
180 static size_t json_object_get_cell_ix(
const JSON_Object *
object,
181 const char *key,
size_t key_len,
187 const char *
name,
size_t name_len);
200 static void json_array_free(
JSON_Array *array);
203 static JSON_Value *json_value_init_string_no_copy(
char *
string,
size_t length);
207 static JSON_Status skip_quotes(
const char **
string);
208 static JSON_Status parse_utf16(
const char **unprocessed,
char **processed);
209 static char *process_string(
const char *input,
size_t input_len,
211 static char *get_quoted_string(
const char **
string,
size_t *output_string_len);
212 static JSON_Value *parse_object_value(
const char **
string,
size_t nesting);
213 static JSON_Value *parse_array_value(
const char **
string,
size_t nesting);
214 static JSON_Value *parse_string_value(
const char **
string);
215 static JSON_Value *parse_boolean_value(
const char **
string);
216 static JSON_Value *parse_number_value(
const char **
string);
217 static JSON_Value *parse_null_value(
const char **
string);
218 static JSON_Value *parse_value(
const char **
string,
size_t nesting);
221 static int json_serialize_to_buffer_r(
const JSON_Value *value,
char *buf,
224 static int json_serialize_string(
const char *
string,
size_t len,
char *buf);
227 static char *read_file(
const char *filename)
229 FILE *fp = fopen(filename,
"r");
230 size_t size_to_read = 0;
231 size_t size_read = 0;
237 fseek(fp, 0L, SEEK_END);
245 file_contents = (
char *)parson_malloc(
sizeof(
char) * (size_to_read + 1));
246 if (!file_contents) {
250 size_read = fread(file_contents, 1, size_to_read, fp);
251 if (size_read == 0 || ferror(fp)) {
253 parson_free(file_contents);
257 file_contents[size_read] =
'\0';
258 return file_contents;
261 static void remove_comments(
char *
string,
const char *start_token,
262 const char *end_token)
266 char *ptr =
NULL, current_char;
267 size_t start_token_len = strlen(start_token);
268 size_t end_token_len = strlen(end_token);
269 if (start_token_len == 0 || end_token_len == 0) {
272 while ((current_char = *
string) !=
'\0') {
273 if (current_char ==
'\\' && !escaped) {
278 else if (current_char ==
'\"' && !escaped) {
279 in_string = !in_string;
281 else if (!in_string &&
282 strncmp(
string, start_token, start_token_len) == 0) {
283 for (i = 0; i < start_token_len; i++) {
286 string =
string + start_token_len;
287 ptr = strstr(
string, end_token);
291 for (i = 0; i < (ptr - string) + end_token_len; i++) {
294 string = ptr + end_token_len - 1;
301 static char *parson_strndup(
const char *
string,
size_t n)
305 char *output_string = (
char *)parson_malloc(n + 1);
306 if (!output_string) {
309 output_string[n] =
'\0';
310 memcpy(output_string,
string, n);
311 return output_string;
314 static char *parson_strdup(
const char *
string)
316 return parson_strndup(
string, strlen(
string));
319 static int parson_sprintf(
char *s,
const char *format, ...)
323 va_start(args, format);
325 #if defined(__APPLE__) && defined(__clang__)
326 #pragma clang diagnostic push
327 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
329 result = vsprintf(s, format, args);
330 #if defined(__APPLE__) && defined(__clang__)
331 #pragma clang diagnostic pop
338 static int hex_char_to_int(
char c)
340 if (c >=
'0' && c <=
'9') {
343 else if (c >=
'a' && c <=
'f') {
346 else if (c >=
'A' && c <=
'F') {
352 static JSON_Status parse_utf16_hex(
const char *s,
unsigned int *result)
355 if (s[0] ==
'\0' || s[1] ==
'\0' || s[2] ==
'\0' || s[3] ==
'\0') {
358 x1 = hex_char_to_int(s[0]);
359 x2 = hex_char_to_int(s[1]);
360 x3 = hex_char_to_int(s[2]);
361 x4 = hex_char_to_int(s[3]);
362 if (x1 == -1 || x2 == -1 || x3 == -1 || x4 == -1) {
365 *result = (
unsigned int)((x1 << 12) | (x2 << 8) | (x3 << 4) | x4);
369 static int num_bytes_in_utf8_sequence(
unsigned char c)
371 if (c == 0xC0 || c == 0xC1 || c > 0xF4 ||
IS_CONT(c)) {
374 else if ((c & 0x80) == 0) {
377 else if ((c & 0xE0) == 0xC0) {
380 else if ((c & 0xF0) == 0xE0) {
383 else if ((c & 0xF8) == 0xF0) {
389 static JSON_Status verify_utf8_sequence(
const unsigned char *
string,
int *len)
392 *len = num_bytes_in_utf8_sequence(
string[0]);
397 else if (*len == 2 &&
IS_CONT(
string[1])) {
398 cp =
string[0] & 0x1F;
399 cp = (cp << 6) | (
string[1] & 0x3F);
402 cp = ((
unsigned char)
string[0]) & 0xF;
403 cp = (cp << 6) | (
string[1] & 0x3F);
404 cp = (cp << 6) | (
string[2] & 0x3F);
408 cp =
string[0] & 0x7;
409 cp = (cp << 6) | (
string[1] & 0x3F);
410 cp = (cp << 6) | (
string[2] & 0x3F);
411 cp = (cp << 6) | (
string[3] & 0x3F);
418 if ((cp < 0x80 && *len > 1) || (cp < 0x800 && *len > 2) ||
419 (cp < 0x10000 && *len > 3)) {
429 if (cp >= 0xD800 && cp <= 0xDFFF) {
436 static int is_valid_utf8(
const char *
string,
size_t string_len)
439 const char *string_end =
string + string_len;
440 while (
string < string_end) {
441 if (verify_utf8_sequence((
const unsigned char *)
string, &len) !=
450 static parson_bool_t is_decimal(
const char *
string,
size_t length)
452 if (length > 1 &&
string[0] ==
'0' &&
string[1] !=
'.') {
455 if (length > 2 && !strncmp(
string,
"-0", 2) &&
string[2] !=
'.') {
459 if (strchr(
"xX",
string[length])) {
466 static unsigned long hash_string(
const char *
string,
size_t n)
468 #ifdef PARSON_FORCE_HASH_COLLISIONS
473 unsigned long hash = 5381;
476 for (i = 0; i < n; i++) {
481 hash = ((hash << 5) + hash) + c;
492 if (new_obj ==
NULL) {
495 new_obj->wrapping_value = wrapping_value;
496 res = json_object_init(new_obj, 0);
498 parson_free(new_obj);
508 object->cells =
NULL;
509 object->names =
NULL;
510 object->values =
NULL;
511 object->cell_ixs =
NULL;
512 object->hashes =
NULL;
515 object->cell_capacity = capacity;
516 object->item_capacity = (
unsigned int)(capacity * 7 / 10);
523 (
size_t *)parson_malloc(object->cell_capacity *
sizeof(*object->cells));
525 (
char **)parson_malloc(object->item_capacity *
sizeof(*object->names));
526 object->values = (
JSON_Value **)parson_malloc(object->item_capacity *
527 sizeof(*object->values));
528 object->cell_ixs = (
size_t *)parson_malloc(object->item_capacity *
529 sizeof(*object->cell_ixs));
530 object->hashes = (
unsigned long *)parson_malloc(object->item_capacity *
531 sizeof(*object->hashes));
532 if (object->cells ==
NULL || object->names ==
NULL ||
533 object->values ==
NULL || object->cell_ixs ==
NULL ||
534 object->hashes ==
NULL) {
537 for (i = 0; i <
object->cell_capacity; i++) {
542 parson_free(object->cells);
543 parson_free(object->names);
544 parson_free(object->values);
545 parson_free(object->cell_ixs);
546 parson_free(object->hashes);
554 for (i = 0; i <
object->count; i++) {
556 parson_free(object->names[i]);
564 object->item_capacity = 0;
565 object->cell_capacity = 0;
567 parson_free(object->cells);
568 parson_free(object->names);
569 parson_free(object->values);
570 parson_free(object->cell_ixs);
571 parson_free(object->hashes);
573 object->cells =
NULL;
574 object->names =
NULL;
575 object->values =
NULL;
576 object->cell_ixs =
NULL;
577 object->hashes =
NULL;
588 JSON_Status res = json_object_init(&new_object, new_capacity);
594 new_object.wrapping_value = wrapping_value;
596 for (i = 0; i <
object->count; i++) {
597 key =
object->names[i];
598 value =
object->values[i];
599 res = json_object_add(&new_object, key, value);
604 value->parent = wrapping_value;
607 *
object = new_object;
611 static size_t json_object_get_cell_ix(
const JSON_Object *
object,
612 const char *key,
size_t key_len,
616 size_t cell_ix = hash & (
object->cell_capacity - 1);
620 unsigned long hash_to_check = 0;
621 const char *key_to_check =
NULL;
622 size_t key_to_check_len = 0;
626 for (i = 0; i <
object->cell_capacity; i++) {
627 ix = (cell_ix + i) & (object->cell_capacity - 1);
628 cell =
object->cells[ix];
632 hash_to_check =
object->hashes[cell];
633 if (hash != hash_to_check) {
636 key_to_check =
object->names[cell];
637 key_to_check_len = strlen(key_to_check);
638 if (key_to_check_len == key_len &&
639 strncmp(key, key_to_check, key_len) == 0) {
650 unsigned long hash = 0;
655 if (!
object || !
name || !value) {
659 hash = hash_string(
name, strlen(
name));
661 cell_ix = json_object_get_cell_ix(
object,
name, strlen(
name), hash, &found);
666 if (object->count >= object->item_capacity) {
667 res = json_object_grow_and_rehash(
object);
672 json_object_get_cell_ix(
object,
name, strlen(
name), hash, &found);
675 object->names[
object->count] =
name;
676 object->cells[cell_ix] =
object->count;
677 object->values[
object->count] = value;
678 object->cell_ixs[
object->count] = cell_ix;
679 object->hashes[
object->count] = hash;
687 const char *
name,
size_t name_len)
689 unsigned long hash = 0;
693 if (!
object || !
name) {
696 hash = hash_string(
name, name_len);
698 cell_ix = json_object_get_cell_ix(
object,
name, name_len, hash, &found);
702 item_ix =
object->cells[cell_ix];
703 return object->values[item_ix];
710 unsigned long hash = 0;
714 size_t last_item_ix = 0;
721 if (
object ==
NULL) {
725 hash = hash_string(
name, strlen(
name));
727 cell = json_object_get_cell_ix(
object,
name, strlen(
name), hash, &found);
732 item_ix =
object->cells[cell];
734 val =
object->values[item_ix];
739 parson_free(object->names[item_ix]);
740 last_item_ix =
object->count - 1;
741 if (item_ix < last_item_ix) {
742 object->names[item_ix] =
object->names[last_item_ix];
743 object->values[item_ix] =
object->values[last_item_ix];
744 object->cell_ixs[item_ix] =
object->cell_ixs[last_item_ix];
745 object->hashes[item_ix] =
object->hashes[last_item_ix];
746 object->cells[
object->cell_ixs[item_ix]] = item_ix;
752 for (
x = 0;
x < (
object->cell_capacity - 1);
x++) {
753 j = (j + 1) & (object->cell_capacity - 1);
757 k =
object->hashes[
object->cells[j]] & (
object->cell_capacity - 1);
758 if ((j > i && (k <= i || k > j)) || (j < i && (k <= i && k > j))) {
759 object->cell_ixs[
object->cells[j]] = i;
760 object->cells[i] =
object->cells[j];
774 const char *dot_pos = strchr(
name,
'.');
776 return json_object_remove_internal(
object,
name, free_value);
778 temp_value = json_object_getn_value(
object,
name, dot_pos -
name);
783 return json_object_dotremove_internal(temp_object, dot_pos + 1, free_value);
796 if (new_array ==
NULL) {
799 new_array->wrapping_value = wrapping_value;
801 new_array->capacity = 0;
802 new_array->count = 0;
808 if (array->count >= array->capacity) {
810 if (json_array_resize(array, new_capacity) !=
JSONSuccess) {
815 array->items[array->count] = value;
823 if (new_capacity == 0) {
828 if (new_items ==
NULL) {
831 if (array->items !=
NULL && array->count > 0) {
832 memcpy(new_items, array->items, array->count *
sizeof(
JSON_Value *));
834 parson_free(array->items);
835 array->items = new_items;
836 array->capacity = new_capacity;
840 static void json_array_free(
JSON_Array *array)
843 for (i = 0; i < array->count; i++) {
846 parson_free(array->items);
851 static JSON_Value *json_value_init_string_no_copy(
char *
string,
size_t length)
857 new_value->parent =
NULL;
859 new_value->value.string.chars = string;
860 new_value->value.string.length = length;
865 static JSON_Status skip_quotes(
const char **
string)
867 if (**
string !=
'\"') {
871 while (**
string !=
'\"') {
872 if (**
string ==
'\0') {
875 else if (**
string ==
'\\') {
877 if (**
string ==
'\0') {
887 static JSON_Status parse_utf16(
const char **unprocessed,
char **processed)
889 unsigned int cp, lead, trail;
890 char *processed_ptr = *processed;
891 const char *unprocessed_ptr = *unprocessed;
894 status = parse_utf16_hex(unprocessed_ptr, &cp);
899 processed_ptr[0] = (char)cp;
901 else if (cp < 0x800) {
902 processed_ptr[0] = ((cp >> 6) & 0x1F) | 0xC0;
903 processed_ptr[1] = ((cp) & 0x3F) | 0x80;
906 else if (cp < 0xD800 || cp > 0xDFFF) {
907 processed_ptr[0] = ((cp >> 12) & 0x0F) | 0xE0;
908 processed_ptr[1] = ((cp >> 6) & 0x3F) | 0x80;
909 processed_ptr[2] = ((cp) & 0x3F) | 0x80;
912 else if (cp >= 0xD800 &&
915 unprocessed_ptr += 4;
917 if (*unprocessed_ptr++ !=
'\\' || *unprocessed_ptr++ !=
'u') {
920 status = parse_utf16_hex(unprocessed_ptr, &trail);
925 cp = ((((lead - 0xD800) & 0x3FF) << 10) | ((trail - 0xDC00) & 0x3FF)) +
927 processed_ptr[0] = (((cp >> 18) & 0x07) | 0xF0);
928 processed_ptr[1] = (((cp >> 12) & 0x3F) | 0x80);
929 processed_ptr[2] = (((cp >> 6) & 0x3F) | 0x80);
930 processed_ptr[3] = (((cp) & 0x3F) | 0x80);
936 unprocessed_ptr += 3;
937 *processed = processed_ptr;
938 *unprocessed = unprocessed_ptr;
944 static char *process_string(
const char *input,
size_t input_len,
947 const char *input_ptr = input;
948 size_t initial_size = (input_len + 1) *
sizeof(
char);
949 size_t final_size = 0;
951 output = (
char *)parson_malloc(initial_size);
956 while ((*input_ptr !=
'\0') && (size_t)(input_ptr - input) < input_len) {
957 if (*input_ptr ==
'\\') {
959 switch (*input_ptr) {
985 if (parse_utf16(&input_ptr, &output_ptr) !=
JSONSuccess) {
993 else if ((
unsigned char)*input_ptr < 0x20) {
998 *output_ptr = *input_ptr;
1005 final_size = (size_t)(output_ptr -
output) + 1;
1007 resized_output = (
char *)parson_malloc(final_size);
1008 if (resized_output ==
NULL) {
1011 memcpy(resized_output,
output, final_size);
1012 *output_len = final_size - 1;
1014 return resized_output;
1022 static char *get_quoted_string(
const char **
string,
size_t *output_string_len)
1024 const char *string_start = *string;
1025 size_t input_string_len = 0;
1030 input_string_len = *
string - string_start - 2;
1031 return process_string(string_start + 1, input_string_len,
1035 static JSON_Value *parse_value(
const char **
string,
size_t nesting)
1043 return parse_object_value(
string, nesting + 1);
1045 return parse_array_value(
string, nesting + 1);
1047 return parse_string_value(
string);
1050 return parse_boolean_value(
string);
1062 return parse_number_value(
string);
1064 return parse_null_value(
string);
1070 static JSON_Value *parse_object_value(
const char **
string,
size_t nesting)
1075 char *new_key =
NULL;
1078 if (output_value ==
NULL) {
1081 if (**
string !=
'{') {
1088 if (**
string ==
'}') {
1090 return output_value;
1092 while (**
string !=
'\0') {
1094 new_key = get_quoted_string(
string, &key_len);
1100 if (key_len != strlen(new_key)) {
1101 parson_free(new_key);
1106 if (**
string !=
':') {
1107 parson_free(new_key);
1112 new_value = parse_value(
string, nesting);
1113 if (new_value ==
NULL) {
1114 parson_free(new_key);
1118 status = json_object_add(output_object, new_key, new_value);
1120 parson_free(new_key);
1126 if (**
string !=
',') {
1131 if (**
string ==
'}') {
1136 if (**
string !=
'}') {
1141 return output_value;
1144 static JSON_Value *parse_array_value(
const char **
string,
size_t nesting)
1149 if (output_value ==
NULL) {
1152 if (**
string !=
'[') {
1159 if (**
string ==
']') {
1161 return output_value;
1163 while (**
string !=
'\0') {
1164 new_array_value = parse_value(
string, nesting);
1165 if (new_array_value ==
NULL) {
1169 if (json_array_add(output_array, new_array_value) !=
JSONSuccess) {
1175 if (**
string !=
',') {
1180 if (**
string ==
']') {
1185 if (**
string !=
']' ||
1192 return output_value;
1195 static JSON_Value *parse_string_value(
const char **
string)
1198 size_t new_string_len = 0;
1199 char *new_string = get_quoted_string(
string, &new_string_len);
1200 if (new_string ==
NULL) {
1203 value = json_value_init_string_no_copy(new_string, new_string_len);
1204 if (value ==
NULL) {
1205 parson_free(new_string);
1211 static JSON_Value *parse_boolean_value(
const char **
string)
1215 if (strncmp(
"true", *
string, true_token_size) == 0) {
1216 *
string += true_token_size;
1219 else if (strncmp(
"false", *
string, false_token_size) == 0) {
1220 *
string += false_token_size;
1226 static JSON_Value *parse_number_value(
const char **
string)
1231 number = strtod(*
string, &end);
1232 if (errno == ERANGE && (number <= -HUGE_VAL || number >=
HUGE_VAL)) {
1235 if ((errno && errno != ERANGE) || !is_decimal(*
string, end - *
string)) {
1242 static JSON_Value *parse_null_value(
const char **
string)
1245 if (strncmp(
"null", *
string, token_size) == 0) {
1246 *
string += token_size;
1259 #define APPEND_STRING(str) \
1261 written = SIZEOF_TOKEN((str)); \
1262 if (buf != NULL) { \
1263 memcpy(buf, (str), written); \
1264 buf[written] = '\0'; \
1267 written_total += written; \
1270 #define APPEND_INDENT(level) \
1273 for (level_i = 0; level_i < (level); level_i++) { \
1274 APPEND_STRING(PARSON_INDENT_STR); \
1278 static int json_serialize_to_buffer_r(
const JSON_Value *value,
char *buf,
1282 const char *key =
NULL, *
string =
NULL;
1286 size_t i = 0,
count = 0;
1288 int written = -1, written_total = 0;
1296 if (
count > 0 && is_pretty) {
1299 for (i = 0; i <
count; i++) {
1304 written = json_serialize_to_buffer_r(temp_value, buf, level + 1,
1305 is_pretty, num_buf);
1312 written_total += written;
1313 if (i < (
count - 1)) {
1320 if (
count > 0 && is_pretty) {
1324 return written_total;
1329 if (
count > 0 && is_pretty) {
1332 for (i = 0; i <
count; i++) {
1341 written = json_serialize_string(key, strlen(key), buf);
1348 written_total += written;
1354 written = json_serialize_to_buffer_r(temp_value, buf, level + 1,
1355 is_pretty, num_buf);
1362 written_total += written;
1363 if (i < (
count - 1)) {
1370 if (
count > 0 && is_pretty) {
1374 return written_total;
1377 if (
string ==
NULL) {
1381 written = json_serialize_string(
string, len, buf);
1388 written_total += written;
1389 return written_total;
1397 return written_total;
1403 if (parson_number_serialization_function) {
1404 written = parson_number_serialization_function(num, num_buf);
1407 const char *float_format = parson_float_format
1408 ? parson_float_format
1410 written = parson_sprintf(num_buf, float_format, num);
1418 written_total += written;
1419 return written_total;
1422 return written_total;
1430 static int json_serialize_string(
const char *
string,
size_t len,
char *buf)
1434 int written = -1, written_total = 0;
1436 for (i = 0; i < len; i++) {
1547 if (parson_escape_slashes) {
1564 return written_total;
1567 #undef APPEND_STRING
1568 #undef APPEND_INDENT
1573 char *file_contents = read_file(filename);
1575 if (file_contents ==
NULL) {
1579 parson_free(file_contents);
1580 return output_value;
1585 char *file_contents = read_file(filename);
1587 if (file_contents ==
NULL) {
1591 parson_free(file_contents);
1592 return output_value;
1597 if (
string ==
NULL) {
1600 if (
string[0] ==
'\xEF' &&
string[1] ==
'\xBB' &&
string[2] ==
'\xBF') {
1601 string =
string + 3;
1603 return parse_value((
const char **)&
string, 0);
1609 char *string_mutable_copy =
NULL, *string_mutable_copy_ptr =
NULL;
1610 string_mutable_copy = parson_strdup(
string);
1611 if (string_mutable_copy ==
NULL) {
1614 remove_comments(string_mutable_copy,
"/*",
"*/");
1615 remove_comments(string_mutable_copy,
"//",
"\n");
1616 string_mutable_copy_ptr = string_mutable_copy;
1617 result = parse_value((
const char **)&string_mutable_copy_ptr, 0);
1618 parson_free(string_mutable_copy);
1629 return json_object_getn_value(
object,
name, strlen(
name));
1665 const char *dot_position = strchr(
name,
'.');
1666 if (!dot_position) {
1670 json_object_getn_value(
object,
name, dot_position -
name));
1710 return object ?
object->count : 0;
1718 return object->names[index];
1726 return object->values[index];
1734 return object->wrapping_value;
1767 return array->items[index];
1802 return array ? array->count : 0;
1810 return array->wrapping_value;
1838 const JSON_String *str = json_value_get_string_desc(value);
1839 return str ? str->chars :
NULL;
1844 const JSON_String *str = json_value_get_string_desc(value);
1845 return str ? str->length : 0;
1861 return value ? value->parent :
NULL;
1868 json_object_free(value->value.object);
1871 parson_free(value->value.string.chars);
1874 json_array_free(value->value.array);
1888 new_value->parent =
NULL;
1890 new_value->value.object = json_object_make(new_value);
1891 if (!new_value->value.object) {
1892 parson_free(new_value);
1904 new_value->parent =
NULL;
1906 new_value->value.array = json_array_make(new_value);
1907 if (!new_value->value.array) {
1908 parson_free(new_value);
1916 if (
string ==
NULL) {
1926 if (
string ==
NULL) {
1929 if (!is_valid_utf8(
string, length)) {
1932 copy = parson_strndup(
string, length);
1936 value = json_value_init_string_no_copy(copy, length);
1937 if (value ==
NULL) {
1950 if (new_value ==
NULL) {
1953 new_value->parent =
NULL;
1955 new_value->value.number = number;
1965 new_value->parent =
NULL;
1967 new_value->value.boolean =
boolean ? 1 : 0;
1977 new_value->parent =
NULL;
1988 const char *temp_key =
NULL;
1989 char *temp_string_copy =
NULL;
1993 char *key_copy =
NULL;
1999 if (return_value ==
NULL) {
2006 if (temp_value_copy ==
NULL) {
2010 if (json_array_add(temp_array_copy, temp_value_copy) !=
2017 return return_value;
2021 if (!return_value) {
2029 if (!temp_value_copy) {
2033 key_copy = parson_strdup(temp_key);
2039 res = json_object_add(temp_object_copy, key_copy, temp_value_copy);
2041 parson_free(key_copy);
2047 return return_value;
2053 temp_string = json_value_get_string_desc(value);
2054 if (temp_string ==
NULL) {
2058 parson_strndup(temp_string->chars, temp_string->length);
2059 if (temp_string_copy ==
NULL) {
2062 return_value = json_value_init_string_no_copy(temp_string_copy,
2063 temp_string->length);
2064 if (return_value ==
NULL) {
2065 parson_free(temp_string_copy);
2067 return return_value;
2082 int res = json_serialize_to_buffer_r(value,
NULL, 0,
PARSON_FALSE, num_buf);
2083 return res < 0 ? 0 : (size_t)(res) + 1;
2087 size_t buf_size_in_bytes)
2091 if (needed_size_in_bytes == 0 || buf_size_in_bytes < needed_size_in_bytes) {
2102 const char *filename)
2107 if (serialized_string ==
NULL) {
2110 fp = fopen(filename,
"w");
2115 if (fputs(serialized_string, fp) == EOF) {
2118 if (fclose(fp) == EOF) {
2130 if (buf_size_bytes == 0) {
2133 buf = (
char *)parson_malloc(buf_size_bytes);
2150 int res = json_serialize_to_buffer_r(value,
NULL, 0,
PARSON_TRUE, num_buf);
2151 return res < 0 ? 0 : (size_t)(res) + 1;
2155 size_t buf_size_in_bytes)
2159 if (needed_size_in_bytes == 0 || buf_size_in_bytes < needed_size_in_bytes) {
2162 written = json_serialize_to_buffer_r(value, buf, 0,
PARSON_TRUE,
NULL);
2170 const char *filename)
2175 if (serialized_string ==
NULL) {
2178 fp = fopen(filename,
"w");
2183 if (fputs(serialized_string, fp) == EOF) {
2186 if (fclose(fp) == EOF) {
2198 if (buf_size_bytes == 0) {
2201 buf = (
char *)parson_malloc(buf_size_bytes);
2205 serialization_result =
2216 parson_free(
string);
2221 size_t to_move_bytes = 0;
2228 memmove(array->items + ix, array->items + ix + 1, to_move_bytes);
2236 if (array ==
NULL || value ==
NULL || value->parent !=
NULL ||
2242 array->items[ix] = value;
2250 if (value ==
NULL) {
2261 const char *
string,
size_t len)
2264 if (value ==
NULL) {
2278 if (value ==
NULL) {
2291 if (value ==
NULL) {
2304 if (value ==
NULL) {
2317 if (array ==
NULL) {
2329 if (array ==
NULL || value ==
NULL || value->parent !=
NULL) {
2332 return json_array_add(array, value);
2338 if (value ==
NULL) {
2349 const char *
string,
size_t len)
2352 if (value ==
NULL) {
2365 if (value ==
NULL) {
2378 if (value ==
NULL) {
2391 if (value ==
NULL) {
2404 unsigned long hash = 0;
2409 char *key_copy =
NULL;
2411 if (!
object || !
name || !value || value->parent) {
2414 hash = hash_string(
name, strlen(
name));
2416 cell_ix = json_object_get_cell_ix(
object,
name, strlen(
name), hash, &found);
2418 item_ix =
object->cells[cell_ix];
2419 old_value =
object->values[item_ix];
2421 object->values[item_ix] = value;
2425 if (object->count >= object->item_capacity) {
2426 JSON_Status res = json_object_grow_and_rehash(
object);
2431 json_object_get_cell_ix(
object,
name, strlen(
name), hash, &found);
2433 key_copy = parson_strdup(
name);
2437 object->names[
object->count] = key_copy;
2438 object->cells[cell_ix] =
object->count;
2439 object->values[
object->count] = value;
2440 object->cell_ixs[
object->count] = cell_ix;
2441 object->hashes[
object->count] = hash;
2460 const char *
string,
size_t len)
2505 const char *dot_pos =
NULL;
2509 size_t name_len = 0;
2510 char *name_copy =
NULL;
2515 dot_pos = strchr(
name,
'.');
2516 if (dot_pos ==
NULL) {
2519 name_len = dot_pos -
name;
2520 temp_value = json_object_getn_value(
object,
name, name_len);
2531 if (new_value ==
NULL) {
2540 name_copy = parson_strndup(
name, name_len);
2542 json_object_dotremove_internal(new_object, dot_pos + 1, 0);
2546 status = json_object_add(
object, name_copy, new_value);
2548 parson_free(name_copy);
2549 json_object_dotremove_internal(new_object, dot_pos + 1, 0);
2560 if (value ==
NULL) {
2572 const char *
string,
size_t len)
2575 if (value ==
NULL) {
2589 if (value ==
NULL) {
2603 if (value ==
NULL) {
2616 if (value ==
NULL) {
2639 if (
object ==
NULL) {
2643 parson_free(object->names[i]);
2644 object->names[i] =
NULL;
2647 object->values[i] =
NULL;
2650 for (i = 0; i <
object->cell_capacity; i++) {
2662 const char *key =
NULL;
2663 size_t i = 0,
count = 0;
2664 if (schema ==
NULL || value ==
NULL) {
2669 if (schema_type != value_type &&
2673 switch (schema_type) {
2701 for (i = 0; i <
count; i++) {
2705 if (temp_value ==
NULL) {
2729 const char *key =
NULL;
2730 size_t a_count = 0, b_count = 0, i = 0;
2734 if (a_type != b_type) {
2743 if (a_count != b_count) {
2746 for (i = 0; i < a_count; i++) {
2758 if (a_count != b_count) {
2761 for (i = 0; i < a_count; i++) {
2770 a_string = json_value_get_string_desc(a);
2771 b_string = json_value_get_string_desc(
b);
2772 if (a_string ==
NULL || b_string ==
NULL) {
2775 return a_string->length == b_string->length &&
2776 memcmp(a_string->chars, b_string->chars, a_string->length) == 0;
2829 parson_malloc = malloc_fun;
2830 parson_free = free_fun;
2835 parson_escape_slashes = escape_slashes;
2840 if (parson_float_format) {
2841 parson_free(parson_float_format);
2842 parson_float_format =
NULL;
2845 parson_float_format =
NULL;
2848 parson_float_format = parson_strdup(format);
2854 parson_number_serialization_function = func;
#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,...)