0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024 #ifdef _MSC_VER
0025 #ifndef _CRT_SECURE_NO_WARNINGS
0026 #define _CRT_SECURE_NO_WARNINGS
0027 #endif
0028 #endif
0029
0030 #include "exparson.h"
0031
0032 #include <stdio.h>
0033 #include <stdlib.h>
0034 #include <string.h>
0035 #include <ctype.h>
0036 #include <math.h>
0037 #include <errno.h>
0038 #include <ubf_int.h>
0039
0040
0041
0042 #define sscanf THINK_TWICE_ABOUT_USING_SSCANF
0043
0044 #define STARTING_CAPACITY 16
0045 #define MAX_NESTING 2048
0046 #define FLOAT_FORMAT "%1.17g"
0047
0048 #define SIZEOF_TOKEN(a) (sizeof(a) - 1)
0049 #define SKIP_CHAR(str) ((*str)++)
0050 #define SKIP_WHITESPACES(str) while (isspace(**str)) { SKIP_CHAR(str); }
0051 #define MAX(a, b) ((a) > (b) ? (a) : (b))
0052
0053 #undef malloc
0054 #undef free
0055
0056 static EXJSON_Malloc_Function exparson_malloc = malloc;
0057 static EXJSON_Free_Function exparson_free = free;
0058
0059 #define IS_CONT(b) (((unsigned char)(b) & 0xC0) == 0x80)
0060
0061
0062 struct exjson_value_num {
0063 double number;
0064 long intnumber;
0065 };
0066
0067
0068 typedef union exjson_value_value {
0069 char *string;
0070 struct exjson_value_num num;
0071 EXJSON_Object *object;
0072 EXJSON_Array *array;
0073 int boolean;
0074 int null;
0075 } EXJSON_Value_Value;
0076
0077 struct exjson_value_t {
0078 EXJSON_Value *parent;
0079 EXJSON_Value_Type type;
0080 EXJSON_Value_Value value;
0081 };
0082
0083 struct exjson_object_t {
0084 EXJSON_Value *wrapping_value;
0085 char **names;
0086 EXJSON_Value **values;
0087 size_t count;
0088 size_t capacity;
0089 };
0090
0091 struct exjson_array_t {
0092 EXJSON_Value *wrapping_value;
0093 EXJSON_Value **items;
0094 size_t count;
0095 size_t capacity;
0096 };
0097
0098
0099 static char * read_file(const char *filename);
0100 static void remove_comments(char *string, const char *start_token, const char *end_token);
0101 static char * exparson_strndup(const char *string, size_t n);
0102 static char * exparson_strdup(const char *string);
0103 static int hex_char_to_int(char c);
0104 static int parse_utf16_hex(const char *string, unsigned int *result);
0105 static int num_bytes_in_utf8_sequence(unsigned char c);
0106 static int verify_utf8_sequence(const unsigned char *string, int *len);
0107 static int is_valid_utf8(const char *string, size_t string_len);
0108 static int is_decimal(const char *string, size_t length);
0109
0110
0111 static EXJSON_Object * exjson_object_init(EXJSON_Value *wrapping_value);
0112 static EXJSON_Status exjson_object_add(EXJSON_Object *object, const char *name, EXJSON_Value *value);
0113 static EXJSON_Status exjson_object_resize(EXJSON_Object *object, size_t new_capacity);
0114 static EXJSON_Value * exjson_object_nget_value(const EXJSON_Object *object, const char *name, size_t n);
0115 static void exjson_object_free(EXJSON_Object *object);
0116
0117
0118 static EXJSON_Array * exjson_array_init(EXJSON_Value *wrapping_value);
0119 static EXJSON_Status exjson_array_add(EXJSON_Array *array, EXJSON_Value *value);
0120 static EXJSON_Status exjson_array_resize(EXJSON_Array *array, size_t new_capacity);
0121 static void exjson_array_free(EXJSON_Array *array);
0122
0123
0124 static EXJSON_Value * exjson_value_init_string_no_copy(char *string);
0125
0126
0127 static EXJSON_Status skip_quotes(const char **string);
0128 static int parse_utf16(const char **unprocessed, char **processed);
0129 static char * process_string(const char *input, size_t len);
0130 static char * get_quoted_string(const char **string);
0131 static EXJSON_Value * parse_object_value(const char **string, size_t nesting);
0132 static EXJSON_Value * parse_array_value(const char **string, size_t nesting);
0133 static EXJSON_Value * parse_string_value(const char **string);
0134 static EXJSON_Value * parse_boolean_value(const char **string);
0135 static EXJSON_Value * parse_number_value(const char **string);
0136 static EXJSON_Value * parse_null_value(const char **string);
0137 static EXJSON_Value * parse_value(const char **string, size_t nesting);
0138
0139
0140 static int exjson_serialize_to_buffer_r(const EXJSON_Value *value, char *buf, int level, int is_pretty, char *num_buf);
0141 static int exjson_serialize_string(const char *string, char *buf);
0142 static int append_indent(char *buf, int level);
0143 static int append_string(char *buf, const char *string);
0144
0145
0146 static char * exparson_strndup(const char *string, size_t n) {
0147 char *output_string = (char*)exparson_malloc(n + 1);
0148 if (!output_string) {
0149 return NULL;
0150 }
0151 output_string[n] = '\0';
0152 strncpy(output_string, string, n);
0153 return output_string;
0154 }
0155
0156 static char * exparson_strdup(const char *string) {
0157 return exparson_strndup(string, strlen(string));
0158 }
0159
0160 static int hex_char_to_int(char c) {
0161 if (c >= '0' && c <= '9') {
0162 return c - '0';
0163 } else if (c >= 'a' && c <= 'f') {
0164 return c - 'a' + 10;
0165 } else if (c >= 'A' && c <= 'F') {
0166 return c - 'A' + 10;
0167 }
0168 return -1;
0169 }
0170
0171 static int parse_utf16_hex(const char *s, unsigned int *result) {
0172 int x1, x2, x3, x4;
0173 if (s[0] == '\0' || s[1] == '\0' || s[2] == '\0' || s[3] == '\0') {
0174 return 0;
0175 }
0176 x1 = hex_char_to_int(s[0]);
0177 x2 = hex_char_to_int(s[1]);
0178 x3 = hex_char_to_int(s[2]);
0179 x4 = hex_char_to_int(s[3]);
0180 if (x1 == -1 || x2 == -1 || x3 == -1 || x4 == -1) {
0181 return 0;
0182 }
0183 *result = (unsigned int)((x1 << 12) | (x2 << 8) | (x3 << 4) | x4);
0184 return 1;
0185 }
0186
0187 static int num_bytes_in_utf8_sequence(unsigned char c) {
0188 if (c == 0xC0 || c == 0xC1 || c > 0xF4 || IS_CONT(c)) {
0189 return 0;
0190 } else if ((c & 0x80) == 0) {
0191 return 1;
0192 } else if ((c & 0xE0) == 0xC0) {
0193 return 2;
0194 } else if ((c & 0xF0) == 0xE0) {
0195 return 3;
0196 } else if ((c & 0xF8) == 0xF0) {
0197 return 4;
0198 }
0199 return 0;
0200 }
0201
0202 static int verify_utf8_sequence(const unsigned char *string, int *len) {
0203 unsigned int cp = 0;
0204 *len = num_bytes_in_utf8_sequence(string[0]);
0205
0206 if (*len == 1) {
0207 cp = string[0];
0208 } else if (*len == 2 && IS_CONT(string[1])) {
0209 cp = string[0] & 0x1F;
0210 cp = (cp << 6) | (string[1] & 0x3F);
0211 } else if (*len == 3 && IS_CONT(string[1]) && IS_CONT(string[2])) {
0212 cp = ((unsigned char)string[0]) & 0xF;
0213 cp = (cp << 6) | (string[1] & 0x3F);
0214 cp = (cp << 6) | (string[2] & 0x3F);
0215 } else if (*len == 4 && IS_CONT(string[1]) && IS_CONT(string[2]) && IS_CONT(string[3])) {
0216 cp = string[0] & 0x7;
0217 cp = (cp << 6) | (string[1] & 0x3F);
0218 cp = (cp << 6) | (string[2] & 0x3F);
0219 cp = (cp << 6) | (string[3] & 0x3F);
0220 } else {
0221 return 0;
0222 }
0223
0224
0225 if ((cp < 0x80 && *len > 1) ||
0226 (cp < 0x800 && *len > 2) ||
0227 (cp < 0x10000 && *len > 3)) {
0228 return 0;
0229 }
0230
0231
0232 if (cp > 0x10FFFF) {
0233 return 0;
0234 }
0235
0236
0237 if (cp >= 0xD800 && cp <= 0xDFFF) {
0238 return 0;
0239 }
0240
0241 return 1;
0242 }
0243
0244 static int is_valid_utf8(const char *string, size_t string_len) {
0245 int len = 0;
0246 const char *string_end = string + string_len;
0247 while (string < string_end) {
0248 if (!verify_utf8_sequence((const unsigned char*)string, &len)) {
0249 return 0;
0250 }
0251 string += len;
0252 }
0253 return 1;
0254 }
0255
0256 static int is_decimal(const char *string, size_t length) {
0257 if (length > 1 && string[0] == '0' && string[1] != '.') {
0258 return 0;
0259 }
0260 if (length > 2 && !strncmp(string, "-0", 2) && string[2] != '.') {
0261 return 0;
0262 }
0263 while (length--) {
0264 if (strchr("xX", string[length])) {
0265 return 0;
0266 }
0267 }
0268 return 1;
0269 }
0270
0271 static char * read_file(const char * filename) {
0272 FILE *fp = fopen(filename, "r");
0273 size_t file_size;
0274 long pos;
0275 char *file_contents;
0276 if (!fp) {
0277 return NULL;
0278 }
0279 fseek(fp, 0L, SEEK_END);
0280 pos = ftell(fp);
0281 if (pos < 0) {
0282 fclose(fp);
0283 return NULL;
0284 }
0285 file_size = pos;
0286 rewind(fp);
0287 file_contents = (char*)exparson_malloc(sizeof(char) * (file_size + 1));
0288 if (!file_contents) {
0289 fclose(fp);
0290 return NULL;
0291 }
0292 if (fread(file_contents, file_size, 1, fp) < 1) {
0293 if (ferror(fp)) {
0294 fclose(fp);
0295 exparson_free(file_contents);
0296 return NULL;
0297 }
0298 }
0299 fclose(fp);
0300 file_contents[file_size] = '\0';
0301 return file_contents;
0302 }
0303
0304 static void remove_comments(char *string, const char *start_token, const char *end_token) {
0305 int in_string = 0, escaped = 0;
0306 size_t i;
0307 char *ptr = NULL, current_char;
0308 size_t start_token_len = strlen(start_token);
0309 size_t end_token_len = strlen(end_token);
0310 if (start_token_len == 0 || end_token_len == 0) {
0311 return;
0312 }
0313 while ((current_char = *string) != '\0') {
0314 if (current_char == '\\' && !escaped) {
0315 escaped = 1;
0316 string++;
0317 continue;
0318 } else if (current_char == '\"' && !escaped) {
0319 in_string = !in_string;
0320 } else if (!in_string && strncmp(string, start_token, start_token_len) == 0) {
0321 for(i = 0; i < start_token_len; i++) {
0322 string[i] = ' ';
0323 }
0324 string = string + start_token_len;
0325 ptr = strstr(string, end_token);
0326 if (!ptr) {
0327 return;
0328 }
0329 for (i = 0; i < (ptr - string) + end_token_len; i++) {
0330 string[i] = ' ';
0331 }
0332 string = ptr + end_token_len - 1;
0333 }
0334 escaped = 0;
0335 string++;
0336 }
0337 }
0338
0339
0340 static EXJSON_Object * exjson_object_init(EXJSON_Value *wrapping_value) {
0341 EXJSON_Object *new_obj = (EXJSON_Object*)exparson_malloc(sizeof(EXJSON_Object));
0342 if (new_obj == NULL) {
0343 return NULL;
0344 }
0345 new_obj->wrapping_value = wrapping_value;
0346 new_obj->names = (char**)NULL;
0347 new_obj->values = (EXJSON_Value**)NULL;
0348 new_obj->capacity = 0;
0349 new_obj->count = 0;
0350 return new_obj;
0351 }
0352
0353 static EXJSON_Status exjson_object_add(EXJSON_Object *object, const char *name, EXJSON_Value *value) {
0354 size_t index = 0;
0355 if (object == NULL || name == NULL || value == NULL) {
0356 return EXJSONFailure;
0357 }
0358 if (exjson_object_get_value(object, name) != NULL) {
0359 return EXJSONFailure;
0360 }
0361 if (object->count >= object->capacity) {
0362 size_t new_capacity = MAX(object->capacity * 2, STARTING_CAPACITY);
0363 if (exjson_object_resize(object, new_capacity) == EXJSONFailure) {
0364 return EXJSONFailure;
0365 }
0366 }
0367 index = object->count;
0368 object->names[index] = exparson_strdup(name);
0369 if (object->names[index] == NULL) {
0370 return EXJSONFailure;
0371 }
0372 value->parent = exjson_object_get_wrapping_value(object);
0373 object->values[index] = value;
0374 object->count++;
0375 return EXJSONSuccess;
0376 }
0377
0378 static EXJSON_Status exjson_object_resize(EXJSON_Object *object, size_t new_capacity) {
0379 char **temp_names = NULL;
0380 EXJSON_Value **temp_values = NULL;
0381
0382 if ((object->names == NULL && object->values != NULL) ||
0383 (object->names != NULL && object->values == NULL) ||
0384 new_capacity == 0) {
0385 return EXJSONFailure;
0386 }
0387 temp_names = (char**)exparson_malloc(new_capacity * sizeof(char*));
0388 if (temp_names == NULL) {
0389 return EXJSONFailure;
0390 }
0391 temp_values = (EXJSON_Value**)exparson_malloc(new_capacity * sizeof(EXJSON_Value*));
0392 if (temp_values == NULL) {
0393 exparson_free(temp_names);
0394 return EXJSONFailure;
0395 }
0396 if (object->names != NULL && object->values != NULL && object->count > 0) {
0397 memcpy(temp_names, object->names, object->count * sizeof(char*));
0398 memcpy(temp_values, object->values, object->count * sizeof(EXJSON_Value*));
0399 }
0400 exparson_free(object->names);
0401 exparson_free(object->values);
0402 object->names = temp_names;
0403 object->values = temp_values;
0404 object->capacity = new_capacity;
0405 return EXJSONSuccess;
0406 }
0407
0408 static EXJSON_Value * exjson_object_nget_value(const EXJSON_Object *object, const char *name, size_t n) {
0409 size_t i, name_length;
0410 for (i = 0; i < exjson_object_get_count(object); i++) {
0411 name_length = strlen(object->names[i]);
0412 if (name_length != n) {
0413 continue;
0414 }
0415 if (strncmp(object->names[i], name, n) == 0) {
0416 return object->values[i];
0417 }
0418 }
0419 return NULL;
0420 }
0421
0422 static void exjson_object_free(EXJSON_Object *object) {
0423 size_t i;
0424 for (i = 0; i < object->count; i++) {
0425 exparson_free(object->names[i]);
0426 exjson_value_free(object->values[i]);
0427 }
0428 exparson_free(object->names);
0429 exparson_free(object->values);
0430 exparson_free(object);
0431 }
0432
0433
0434 static EXJSON_Array * exjson_array_init(EXJSON_Value *wrapping_value) {
0435 EXJSON_Array *new_array = (EXJSON_Array*)exparson_malloc(sizeof(EXJSON_Array));
0436 if (new_array == NULL) {
0437 return NULL;
0438 }
0439 new_array->wrapping_value = wrapping_value;
0440 new_array->items = (EXJSON_Value**)NULL;
0441 new_array->capacity = 0;
0442 new_array->count = 0;
0443 return new_array;
0444 }
0445
0446 static EXJSON_Status exjson_array_add(EXJSON_Array *array, EXJSON_Value *value) {
0447 if (array->count >= array->capacity) {
0448 size_t new_capacity = MAX(array->capacity * 2, STARTING_CAPACITY);
0449 if (exjson_array_resize(array, new_capacity) == EXJSONFailure) {
0450 return EXJSONFailure;
0451 }
0452 }
0453 value->parent = exjson_array_get_wrapping_value(array);
0454 array->items[array->count] = value;
0455 array->count++;
0456 return EXJSONSuccess;
0457 }
0458
0459 static EXJSON_Status exjson_array_resize(EXJSON_Array *array, size_t new_capacity) {
0460 EXJSON_Value **new_items = NULL;
0461 if (new_capacity == 0) {
0462 return EXJSONFailure;
0463 }
0464 new_items = (EXJSON_Value**)exparson_malloc(new_capacity * sizeof(EXJSON_Value*));
0465 if (new_items == NULL) {
0466 return EXJSONFailure;
0467 }
0468 if (array->items != NULL && array->count > 0) {
0469 memcpy(new_items, array->items, array->count * sizeof(EXJSON_Value*));
0470 }
0471 exparson_free(array->items);
0472 array->items = new_items;
0473 array->capacity = new_capacity;
0474 return EXJSONSuccess;
0475 }
0476
0477 static void exjson_array_free(EXJSON_Array *array) {
0478 size_t i;
0479 for (i = 0; i < array->count; i++) {
0480 exjson_value_free(array->items[i]);
0481 }
0482 exparson_free(array->items);
0483 exparson_free(array);
0484 }
0485
0486
0487 static EXJSON_Value * exjson_value_init_string_no_copy(char *string) {
0488 EXJSON_Value *new_value = (EXJSON_Value*)exparson_malloc(sizeof(EXJSON_Value));
0489 if (!new_value) {
0490 return NULL;
0491 }
0492 new_value->parent = NULL;
0493 new_value->type = EXJSONString;
0494 new_value->value.string = string;
0495 return new_value;
0496 }
0497
0498
0499 static EXJSON_Status skip_quotes(const char **string) {
0500 if (**string != '\"') {
0501 return EXJSONFailure;
0502 }
0503 SKIP_CHAR(string);
0504 while (**string != '\"') {
0505 if (**string == '\0') {
0506 return EXJSONFailure;
0507 } else if (**string == '\\') {
0508 SKIP_CHAR(string);
0509 if (**string == '\0') {
0510 return EXJSONFailure;
0511 }
0512 }
0513 SKIP_CHAR(string);
0514 }
0515 SKIP_CHAR(string);
0516 return EXJSONSuccess;
0517 }
0518
0519 static int parse_utf16(const char **unprocessed, char **processed) {
0520 unsigned int cp, lead, trail;
0521 int parse_succeeded = 0;
0522 char *processed_ptr = *processed;
0523 const char *unprocessed_ptr = *unprocessed;
0524 unprocessed_ptr++;
0525 parse_succeeded = parse_utf16_hex(unprocessed_ptr, &cp);
0526 if (!parse_succeeded) {
0527 return EXJSONFailure;
0528 }
0529 if (cp < 0x80) {
0530 processed_ptr[0] = (char)cp;
0531 } else if (cp < 0x800) {
0532 processed_ptr[0] = ((cp >> 6) & 0x1F) | 0xC0;
0533 processed_ptr[1] = ((cp) & 0x3F) | 0x80;
0534 processed_ptr += 1;
0535 } else if (cp < 0xD800 || cp > 0xDFFF) {
0536 processed_ptr[0] = ((cp >> 12) & 0x0F) | 0xE0;
0537 processed_ptr[1] = ((cp >> 6) & 0x3F) | 0x80;
0538 processed_ptr[2] = ((cp) & 0x3F) | 0x80;
0539 processed_ptr += 2;
0540 } else if (cp >= 0xD800 && cp <= 0xDBFF) {
0541 lead = cp;
0542 unprocessed_ptr += 4;
0543 if (*unprocessed_ptr++ != '\\' || *unprocessed_ptr++ != 'u') {
0544 return EXJSONFailure;
0545 }
0546 parse_succeeded = parse_utf16_hex(unprocessed_ptr, &trail);
0547 if (!parse_succeeded || trail < 0xDC00 || trail > 0xDFFF) {
0548 return EXJSONFailure;
0549 }
0550 cp = ((((lead - 0xD800) & 0x3FF) << 10) | ((trail - 0xDC00) & 0x3FF)) + 0x010000;
0551 processed_ptr[0] = (((cp >> 18) & 0x07) | 0xF0);
0552 processed_ptr[1] = (((cp >> 12) & 0x3F) | 0x80);
0553 processed_ptr[2] = (((cp >> 6) & 0x3F) | 0x80);
0554 processed_ptr[3] = (((cp) & 0x3F) | 0x80);
0555 processed_ptr += 3;
0556 } else {
0557 return EXJSONFailure;
0558 }
0559 unprocessed_ptr += 3;
0560 *processed = processed_ptr;
0561 *unprocessed = unprocessed_ptr;
0562 return EXJSONSuccess;
0563 }
0564
0565
0566
0567
0568 static char* process_string(const char *input, size_t len) {
0569 const char *input_ptr = input;
0570 size_t initial_size = (len + 1) * sizeof(char);
0571 size_t final_size = 0;
0572 char *output = NULL, *output_ptr = NULL, *resized_output = NULL;
0573 output = (char*)exparson_malloc(initial_size);
0574 if (output == NULL) {
0575 goto error;
0576 }
0577 output_ptr = output;
0578 while ((*input_ptr != '\0') && (size_t)(input_ptr - input) < len) {
0579 if (*input_ptr == '\\') {
0580 input_ptr++;
0581 switch (*input_ptr) {
0582 case '\"': *output_ptr = '\"'; break;
0583 case '\\': *output_ptr = '\\'; break;
0584 case '/': *output_ptr = '/'; break;
0585 case 'b': *output_ptr = '\b'; break;
0586 case 'f': *output_ptr = '\f'; break;
0587 case 'n': *output_ptr = '\n'; break;
0588 case 'r': *output_ptr = '\r'; break;
0589 case 't': *output_ptr = '\t'; break;
0590 case 'u':
0591 if (parse_utf16(&input_ptr, &output_ptr) == EXJSONFailure) {
0592 goto error;
0593 }
0594 break;
0595 default:
0596 goto error;
0597 }
0598 } else if ((unsigned char)*input_ptr < 0x20) {
0599 goto error;
0600 } else {
0601 *output_ptr = *input_ptr;
0602 }
0603 output_ptr++;
0604 input_ptr++;
0605 }
0606 *output_ptr = '\0';
0607
0608 final_size = (size_t)(output_ptr-output) + 1;
0609
0610 resized_output = (char*)exparson_malloc(final_size);
0611 if (resized_output == NULL) {
0612 goto error;
0613 }
0614 memcpy(resized_output, output, final_size);
0615 exparson_free(output);
0616 return resized_output;
0617 error:
0618 exparson_free(output);
0619 return NULL;
0620 }
0621
0622
0623
0624 static char * get_quoted_string(const char **string) {
0625 const char *string_start = *string;
0626 size_t string_len = 0;
0627 EXJSON_Status status = skip_quotes(string);
0628 if (status != EXJSONSuccess) {
0629 return NULL;
0630 }
0631 string_len = *string - string_start - 2;
0632 return process_string(string_start + 1, string_len);
0633 }
0634
0635 static EXJSON_Value * parse_value(const char **string, size_t nesting) {
0636 if (nesting > MAX_NESTING) {
0637 return NULL;
0638 }
0639 SKIP_WHITESPACES(string);
0640 switch (**string) {
0641 case '{':
0642 return parse_object_value(string, nesting + 1);
0643 case '[':
0644 return parse_array_value(string, nesting + 1);
0645 case '\"':
0646 return parse_string_value(string);
0647 case 'f': case 't':
0648 return parse_boolean_value(string);
0649 case '-':
0650 case '0': case '1': case '2': case '3': case '4':
0651 case '5': case '6': case '7': case '8': case '9':
0652 return parse_number_value(string);
0653 case 'n':
0654 return parse_null_value(string);
0655 default:
0656 return NULL;
0657 }
0658 }
0659
0660 static EXJSON_Value * parse_object_value(const char **string, size_t nesting) {
0661 EXJSON_Value *output_value = exjson_value_init_object(), *new_value = NULL;
0662 EXJSON_Object *output_object = exjson_value_get_object(output_value);
0663 char *new_key = NULL;
0664 if (output_value == NULL || **string != '{') {
0665 return NULL;
0666 }
0667 SKIP_CHAR(string);
0668 SKIP_WHITESPACES(string);
0669 if (**string == '}') {
0670 SKIP_CHAR(string);
0671 return output_value;
0672 }
0673 while (**string != '\0') {
0674 new_key = get_quoted_string(string);
0675 if (new_key == NULL) {
0676 exjson_value_free(output_value);
0677 return NULL;
0678 }
0679 SKIP_WHITESPACES(string);
0680 if (**string != ':') {
0681 exparson_free(new_key);
0682 exjson_value_free(output_value);
0683 return NULL;
0684 }
0685 SKIP_CHAR(string);
0686 new_value = parse_value(string, nesting);
0687 if (new_value == NULL) {
0688 exparson_free(new_key);
0689 exjson_value_free(output_value);
0690 return NULL;
0691 }
0692 if (exjson_object_add(output_object, new_key, new_value) == EXJSONFailure) {
0693 exparson_free(new_key);
0694 exjson_value_free(new_value);
0695 exjson_value_free(output_value);
0696 return NULL;
0697 }
0698 exparson_free(new_key);
0699 SKIP_WHITESPACES(string);
0700 if (**string != ',') {
0701 break;
0702 }
0703 SKIP_CHAR(string);
0704 SKIP_WHITESPACES(string);
0705 }
0706 SKIP_WHITESPACES(string);
0707 if (**string != '}' ||
0708 exjson_object_resize(output_object, exjson_object_get_count(output_object)) == EXJSONFailure) {
0709 exjson_value_free(output_value);
0710 return NULL;
0711 }
0712 SKIP_CHAR(string);
0713 return output_value;
0714 }
0715
0716 static EXJSON_Value * parse_array_value(const char **string, size_t nesting) {
0717 EXJSON_Value *output_value = exjson_value_init_array(), *new_array_value = NULL;
0718 EXJSON_Array *output_array = exjson_value_get_array(output_value);
0719 if (!output_value || **string != '[') {
0720 return NULL;
0721 }
0722 SKIP_CHAR(string);
0723 SKIP_WHITESPACES(string);
0724 if (**string == ']') {
0725 SKIP_CHAR(string);
0726 return output_value;
0727 }
0728 while (**string != '\0') {
0729 new_array_value = parse_value(string, nesting);
0730 if (new_array_value == NULL) {
0731 exjson_value_free(output_value);
0732 return NULL;
0733 }
0734 if (exjson_array_add(output_array, new_array_value) == EXJSONFailure) {
0735 exjson_value_free(new_array_value);
0736 exjson_value_free(output_value);
0737 return NULL;
0738 }
0739 SKIP_WHITESPACES(string);
0740 if (**string != ',') {
0741 break;
0742 }
0743 SKIP_CHAR(string);
0744 SKIP_WHITESPACES(string);
0745 }
0746 SKIP_WHITESPACES(string);
0747 if (**string != ']' ||
0748 exjson_array_resize(output_array, exjson_array_get_count(output_array)) == EXJSONFailure) {
0749 exjson_value_free(output_value);
0750 return NULL;
0751 }
0752 SKIP_CHAR(string);
0753 return output_value;
0754 }
0755
0756 static EXJSON_Value * parse_string_value(const char **string) {
0757 EXJSON_Value *value = NULL;
0758 char *new_string = get_quoted_string(string);
0759 if (new_string == NULL) {
0760 return NULL;
0761 }
0762 value = exjson_value_init_string_no_copy(new_string);
0763 if (value == NULL) {
0764 exparson_free(new_string);
0765 return NULL;
0766 }
0767 return value;
0768 }
0769
0770 static EXJSON_Value * parse_boolean_value(const char **string) {
0771 size_t true_token_size = SIZEOF_TOKEN("true");
0772 size_t false_token_size = SIZEOF_TOKEN("false");
0773 if (strncmp("true", *string, true_token_size) == 0) {
0774 *string += true_token_size;
0775 return exjson_value_init_boolean(1);
0776 } else if (strncmp("false", *string, false_token_size) == 0) {
0777 *string += false_token_size;
0778 return exjson_value_init_boolean(0);
0779 }
0780 return NULL;
0781 }
0782
0783
0784
0785
0786 static EXJSON_Value * parse_number_value(const char **string) {
0787 char *end;
0788 double number = 0;
0789 EXJSON_Value *ret;
0790
0791 errno = 0;
0792 number = strtod(*string, &end);
0793 if (errno || !is_decimal(*string, end - *string)) {
0794 return NULL;
0795 }
0796
0797 ret=exjson_value_init_number(number);
0798
0799 if (NULL!=ret)
0800 {
0801 ret->value.num.intnumber = atol(*string);
0802 }
0803
0804 *string = end;
0805
0806 return ret;
0807 }
0808
0809 static EXJSON_Value * parse_null_value(const char **string) {
0810 size_t token_size = SIZEOF_TOKEN("null");
0811 if (strncmp("null", *string, token_size) == 0) {
0812 *string += token_size;
0813 return exjson_value_init_null();
0814 }
0815 return NULL;
0816 }
0817
0818
0819 #define APPEND_STRING(str) do { written = append_string(buf, (str));\
0820 if (written < 0) { return -1; }\
0821 if (buf != NULL) { buf += written; }\
0822 written_total += written; } while(0)
0823
0824 #define APPEND_INDENT(level) do { written = append_indent(buf, (level));\
0825 if (written < 0) { return -1; }\
0826 if (buf != NULL) { buf += written; }\
0827 written_total += written; } while(0)
0828
0829 static int exjson_serialize_to_buffer_r(const EXJSON_Value *value, char *buf, int level, int is_pretty, char *num_buf)
0830 {
0831 const char *key = NULL, *string = NULL;
0832 EXJSON_Value *temp_value = NULL;
0833 EXJSON_Array *array = NULL;
0834 EXJSON_Object *object = NULL;
0835 size_t i = 0, count = 0;
0836 double num = 0.0;
0837 long intnumber = 0.0;
0838 int written = -1, written_total = 0;
0839
0840 switch (exjson_value_get_type(value)) {
0841 case EXJSONArray:
0842 array = exjson_value_get_array(value);
0843 count = exjson_array_get_count(array);
0844 APPEND_STRING("[");
0845 if (count > 0 && is_pretty) {
0846 APPEND_STRING("\n");
0847 }
0848 for (i = 0; i < count; i++) {
0849 if (is_pretty) {
0850 APPEND_INDENT(level+1);
0851 }
0852 temp_value = exjson_array_get_value(array, i);
0853 written = exjson_serialize_to_buffer_r(temp_value, buf, level+1, is_pretty, num_buf);
0854 if (written < 0) {
0855 return -1;
0856 }
0857 if (buf != NULL) {
0858 buf += written;
0859 }
0860 written_total += written;
0861 if (i < (count - 1)) {
0862 APPEND_STRING(",");
0863 }
0864 if (is_pretty) {
0865 APPEND_STRING("\n");
0866 }
0867 }
0868 if (count > 0 && is_pretty) {
0869 APPEND_INDENT(level);
0870 }
0871 APPEND_STRING("]");
0872 return written_total;
0873 case EXJSONObject:
0874 object = exjson_value_get_object(value);
0875 count = exjson_object_get_count(object);
0876 APPEND_STRING("{");
0877 if (count > 0 && is_pretty) {
0878 APPEND_STRING("\n");
0879 }
0880 for (i = 0; i < count; i++) {
0881 key = exjson_object_get_name(object, i);
0882 if (key == NULL) {
0883 return -1;
0884 }
0885 if (is_pretty) {
0886 APPEND_INDENT(level+1);
0887 }
0888 written = exjson_serialize_string(key, buf);
0889 if (written < 0) {
0890 return -1;
0891 }
0892 if (buf != NULL) {
0893 buf += written;
0894 }
0895 written_total += written;
0896 APPEND_STRING(":");
0897 if (is_pretty) {
0898 APPEND_STRING(" ");
0899 }
0900 temp_value = exjson_object_get_value(object, key);
0901 written = exjson_serialize_to_buffer_r(temp_value, buf, level+1, is_pretty, num_buf);
0902 if (written < 0) {
0903 return -1;
0904 }
0905 if (buf != NULL) {
0906 buf += written;
0907 }
0908 written_total += written;
0909 if (i < (count - 1)) {
0910 APPEND_STRING(",");
0911 }
0912 if (is_pretty) {
0913 APPEND_STRING("\n");
0914 }
0915 }
0916 if (count > 0 && is_pretty) {
0917 APPEND_INDENT(level);
0918 }
0919 APPEND_STRING("}");
0920 return written_total;
0921 case EXJSONString:
0922 string = exjson_value_get_string(value);
0923 if (string == NULL) {
0924 return -1;
0925 }
0926 written = exjson_serialize_string(string, buf);
0927 if (written < 0) {
0928 return -1;
0929 }
0930 if (buf != NULL) {
0931 buf += written;
0932 }
0933 written_total += written;
0934 return written_total;
0935 case EXJSONBoolean:
0936 if (exjson_value_get_boolean(value)) {
0937 APPEND_STRING("true");
0938 } else {
0939 APPEND_STRING("false");
0940 }
0941 return written_total;
0942 case EXJSONIntnumber:
0943 intnumber = exjson_value_get_intnumber(value);
0944 if (buf != NULL) {
0945 num_buf = buf;
0946 }
0947 written = sprintf(num_buf, "%ld", intnumber);
0948
0949 if (written < 0) {
0950 return -1;
0951 }
0952 if (buf != NULL) {
0953 buf += written;
0954 }
0955 written_total += written;
0956 return written_total;
0957 case EXJSONNumber:
0958 num = exjson_value_get_number(value);
0959 if (buf != NULL) {
0960 num_buf = buf;
0961 }
0962
0963 if (num == ((double)(long)num))
0964 written = sprintf(num_buf, "%ld", (long)num);
0965 else
0966 written = sprintf(num_buf, "%.*lf", DOUBLE_RESOLUTION, num);
0967
0968 if (written < 0) {
0969 return -1;
0970 }
0971 if (buf != NULL) {
0972 buf += written;
0973 }
0974 written_total += written;
0975 return written_total;
0976 case EXJSONNull:
0977 APPEND_STRING("null");
0978 return written_total;
0979 case EXJSONError:
0980 return -1;
0981 default:
0982 return -1;
0983 }
0984 }
0985
0986 static int exjson_serialize_string(const char *string, char *buf) {
0987 size_t i = 0, len = strlen(string);
0988 char c = '\0';
0989 int written = -1, written_total = 0;
0990 APPEND_STRING("\"");
0991 for (i = 0; i < len; i++) {
0992 c = string[i];
0993 switch (c) {
0994 case '\"': APPEND_STRING("\\\""); break;
0995 case '\\': APPEND_STRING("\\\\"); break;
0996 case '/': APPEND_STRING("\\/"); break;
0997 case '\b': APPEND_STRING("\\b"); break;
0998 case '\f': APPEND_STRING("\\f"); break;
0999 case '\n': APPEND_STRING("\\n"); break;
1000 case '\r': APPEND_STRING("\\r"); break;
1001 case '\t': APPEND_STRING("\\t"); break;
1002 case '\x00': APPEND_STRING("\\u0000"); break;
1003 case '\x01': APPEND_STRING("\\u0001"); break;
1004 case '\x02': APPEND_STRING("\\u0002"); break;
1005 case '\x03': APPEND_STRING("\\u0003"); break;
1006 case '\x04': APPEND_STRING("\\u0004"); break;
1007 case '\x05': APPEND_STRING("\\u0005"); break;
1008 case '\x06': APPEND_STRING("\\u0006"); break;
1009 case '\x07': APPEND_STRING("\\u0007"); break;
1010
1011
1012
1013 case '\x0b': APPEND_STRING("\\u000b"); break;
1014
1015
1016 case '\x0e': APPEND_STRING("\\u000e"); break;
1017 case '\x0f': APPEND_STRING("\\u000f"); break;
1018 case '\x10': APPEND_STRING("\\u0010"); break;
1019 case '\x11': APPEND_STRING("\\u0011"); break;
1020 case '\x12': APPEND_STRING("\\u0012"); break;
1021 case '\x13': APPEND_STRING("\\u0013"); break;
1022 case '\x14': APPEND_STRING("\\u0014"); break;
1023 case '\x15': APPEND_STRING("\\u0015"); break;
1024 case '\x16': APPEND_STRING("\\u0016"); break;
1025 case '\x17': APPEND_STRING("\\u0017"); break;
1026 case '\x18': APPEND_STRING("\\u0018"); break;
1027 case '\x19': APPEND_STRING("\\u0019"); break;
1028 case '\x1a': APPEND_STRING("\\u001a"); break;
1029 case '\x1b': APPEND_STRING("\\u001b"); break;
1030 case '\x1c': APPEND_STRING("\\u001c"); break;
1031 case '\x1d': APPEND_STRING("\\u001d"); break;
1032 case '\x1e': APPEND_STRING("\\u001e"); break;
1033 case '\x1f': APPEND_STRING("\\u001f"); break;
1034 default:
1035 if (buf != NULL) {
1036 buf[0] = c;
1037 buf += 1;
1038 }
1039 written_total += 1;
1040 break;
1041 }
1042 }
1043 APPEND_STRING("\"");
1044 return written_total;
1045 }
1046
1047 static int append_indent(char *buf, int level) {
1048 int i;
1049 int written = -1, written_total = 0;
1050 for (i = 0; i < level; i++) {
1051 APPEND_STRING(" ");
1052 }
1053 return written_total;
1054 }
1055
1056 static int append_string(char *buf, const char *string) {
1057 if (buf == NULL) {
1058 return (int)strlen(string);
1059 }
1060 return sprintf(buf, "%s", string);
1061 }
1062
1063 #undef APPEND_STRING
1064 #undef APPEND_INDENT
1065
1066
1067 EXJSON_Value * exjson_parse_file(const char *filename) {
1068 char *file_contents = read_file(filename);
1069 EXJSON_Value *output_value = NULL;
1070 if (file_contents == NULL) {
1071 return NULL;
1072 }
1073 output_value = exjson_parse_string(file_contents);
1074 exparson_free(file_contents);
1075 return output_value;
1076 }
1077
1078 EXJSON_Value * exjson_parse_file_with_comments(const char *filename) {
1079 char *file_contents = read_file(filename);
1080 EXJSON_Value *output_value = NULL;
1081 if (file_contents == NULL) {
1082 return NULL;
1083 }
1084 output_value = exjson_parse_string_with_comments(file_contents);
1085 exparson_free(file_contents);
1086 return output_value;
1087 }
1088
1089 EXJSON_Value * exjson_parse_string(const char *string) {
1090 if (string == NULL) {
1091 return NULL;
1092 }
1093 if (string[0] == '\xEF' && string[1] == '\xBB' && string[2] == '\xBF') {
1094 string = string + 3;
1095 }
1096 return parse_value((const char**)&string, 0);
1097 }
1098
1099 EXJSON_Value * exjson_parse_string_with_comments(const char *string) {
1100 EXJSON_Value *result = NULL;
1101 char *string_mutable_copy = NULL, *string_mutable_copy_ptr = NULL;
1102 string_mutable_copy = exparson_strdup(string);
1103 if (string_mutable_copy == NULL) {
1104 return NULL;
1105 }
1106 remove_comments(string_mutable_copy, "/*", "*/");
1107 remove_comments(string_mutable_copy, "//", "\n");
1108 string_mutable_copy_ptr = string_mutable_copy;
1109 result = parse_value((const char**)&string_mutable_copy_ptr, 0);
1110 exparson_free(string_mutable_copy);
1111 return result;
1112 }
1113
1114
1115
1116 EXJSON_Value * exjson_object_get_value(const EXJSON_Object *object, const char *name) {
1117 if (object == NULL || name == NULL) {
1118 return NULL;
1119 }
1120 return exjson_object_nget_value(object, name, strlen(name));
1121 }
1122
1123 const char * exjson_object_get_string(const EXJSON_Object *object, const char *name) {
1124 return exjson_value_get_string(exjson_object_get_value(object, name));
1125 }
1126
1127 double exjson_object_get_number(const EXJSON_Object *object, const char *name) {
1128 return exjson_value_get_number(exjson_object_get_value(object, name));
1129 }
1130
1131 long exjson_object_get_intnumber(const EXJSON_Object *object, const char *name) {
1132 return exjson_value_get_intnumber(exjson_object_get_value(object, name));
1133 }
1134
1135 EXJSON_Object * exjson_object_get_object(const EXJSON_Object *object, const char *name) {
1136 return exjson_value_get_object(exjson_object_get_value(object, name));
1137 }
1138
1139 EXJSON_Array * exjson_object_get_array(const EXJSON_Object *object, const char *name) {
1140 return exjson_value_get_array(exjson_object_get_value(object, name));
1141 }
1142
1143 int exjson_object_get_boolean(const EXJSON_Object *object, const char *name) {
1144 return exjson_value_get_boolean(exjson_object_get_value(object, name));
1145 }
1146
1147 EXJSON_Value * exjson_object_dotget_value(const EXJSON_Object *object, const char *name) {
1148 const char *dot_position = strchr(name, '.');
1149 if (!dot_position) {
1150 return exjson_object_get_value(object, name);
1151 }
1152 object = exjson_value_get_object(exjson_object_nget_value(object, name, dot_position - name));
1153 return exjson_object_dotget_value(object, dot_position + 1);
1154 }
1155
1156 const char * exjson_object_dotget_string(const EXJSON_Object *object, const char *name) {
1157 return exjson_value_get_string(exjson_object_dotget_value(object, name));
1158 }
1159
1160 double exjson_object_dotget_number(const EXJSON_Object *object, const char *name) {
1161 return exjson_value_get_number(exjson_object_dotget_value(object, name));
1162 }
1163
1164 long exjson_object_dotget_intnumber(const EXJSON_Object *object, const char *name) {
1165 return exjson_value_get_intnumber(exjson_object_dotget_value(object, name));
1166 }
1167
1168 EXJSON_Object * exjson_object_dotget_object(const EXJSON_Object *object, const char *name) {
1169 return exjson_value_get_object(exjson_object_dotget_value(object, name));
1170 }
1171
1172 EXJSON_Array * exjson_object_dotget_array(const EXJSON_Object *object, const char *name) {
1173 return exjson_value_get_array(exjson_object_dotget_value(object, name));
1174 }
1175
1176 int exjson_object_dotget_boolean(const EXJSON_Object *object, const char *name) {
1177 return exjson_value_get_boolean(exjson_object_dotget_value(object, name));
1178 }
1179
1180 size_t exjson_object_get_count(const EXJSON_Object *object) {
1181 return object ? object->count : 0;
1182 }
1183
1184 const char * exjson_object_get_name(const EXJSON_Object *object, size_t index) {
1185 if (object == NULL || index >= exjson_object_get_count(object)) {
1186 return NULL;
1187 }
1188 return object->names[index];
1189 }
1190
1191 EXJSON_Value * exjson_object_get_value_at(const EXJSON_Object *object, size_t index) {
1192 if (object == NULL || index >= exjson_object_get_count(object)) {
1193 return NULL;
1194 }
1195 return object->values[index];
1196 }
1197
1198 EXJSON_Value *exjson_object_get_wrapping_value(const EXJSON_Object *object) {
1199 return object->wrapping_value;
1200 }
1201
1202 int exjson_object_has_value (const EXJSON_Object *object, const char *name) {
1203 return exjson_object_get_value(object, name) != NULL;
1204 }
1205
1206 int exjson_object_has_value_of_type(const EXJSON_Object *object, const char *name, EXJSON_Value_Type type) {
1207 EXJSON_Value *val = exjson_object_get_value(object, name);
1208 return val != NULL && exjson_value_get_type(val) == type;
1209 }
1210
1211 int exjson_object_dothas_value (const EXJSON_Object *object, const char *name) {
1212 return exjson_object_dotget_value(object, name) != NULL;
1213 }
1214
1215 int exjson_object_dothas_value_of_type(const EXJSON_Object *object, const char *name, EXJSON_Value_Type type) {
1216 EXJSON_Value *val = exjson_object_dotget_value(object, name);
1217 return val != NULL && exjson_value_get_type(val) == type;
1218 }
1219
1220
1221 EXJSON_Value * exjson_array_get_value(const EXJSON_Array *array, size_t index) {
1222 if (array == NULL || index >= exjson_array_get_count(array)) {
1223 return NULL;
1224 }
1225 return array->items[index];
1226 }
1227
1228 const char * exjson_array_get_string(const EXJSON_Array *array, size_t index) {
1229 return exjson_value_get_string(exjson_array_get_value(array, index));
1230 }
1231
1232 double exjson_array_get_number(const EXJSON_Array *array, size_t index) {
1233 return exjson_value_get_number(exjson_array_get_value(array, index));
1234 }
1235
1236 long exjson_array_get_intnumber(const EXJSON_Array *array, size_t index) {
1237 return exjson_value_get_intnumber(exjson_array_get_value(array, index));
1238 }
1239
1240 EXJSON_Object * exjson_array_get_object(const EXJSON_Array *array, size_t index) {
1241 return exjson_value_get_object(exjson_array_get_value(array, index));
1242 }
1243
1244 EXJSON_Array * exjson_array_get_array(const EXJSON_Array *array, size_t index) {
1245 return exjson_value_get_array(exjson_array_get_value(array, index));
1246 }
1247
1248 int exjson_array_get_boolean(const EXJSON_Array *array, size_t index) {
1249 return exjson_value_get_boolean(exjson_array_get_value(array, index));
1250 }
1251
1252 size_t exjson_array_get_count(const EXJSON_Array *array) {
1253 return array ? array->count : 0;
1254 }
1255
1256 EXJSON_Value * exjson_array_get_wrapping_value(const EXJSON_Array *array) {
1257 return array->wrapping_value;
1258 }
1259
1260
1261 EXJSON_Value_Type exjson_value_get_type(const EXJSON_Value *value) {
1262 return value ? value->type : EXJSONError;
1263 }
1264
1265 EXJSON_Object * exjson_value_get_object(const EXJSON_Value *value) {
1266 return exjson_value_get_type(value) == EXJSONObject ? value->value.object : NULL;
1267 }
1268
1269 EXJSON_Array * exjson_value_get_array(const EXJSON_Value *value) {
1270 return exjson_value_get_type(value) == EXJSONArray ? value->value.array : NULL;
1271 }
1272
1273 const char * exjson_value_get_string(const EXJSON_Value *value) {
1274 return exjson_value_get_type(value) == EXJSONString ? value->value.string : NULL;
1275 }
1276
1277 double exjson_value_get_number(const EXJSON_Value *value) {
1278 return exjson_value_get_type(value) == EXJSONNumber ? value->value.num.number : 0;
1279 }
1280
1281
1282
1283
1284
1285 long exjson_value_get_intnumber(const EXJSON_Value *value) {
1286 EXJSON_Value_Type typ = exjson_value_get_type(value);
1287
1288 if ( EXJSONIntnumber == typ || EXJSONNumber == typ )
1289 return value->value.num.intnumber;
1290 else
1291 return 0;
1292 }
1293
1294 int exjson_value_get_boolean(const EXJSON_Value *value) {
1295 return exjson_value_get_type(value) == EXJSONBoolean ? value->value.boolean : -1;
1296 }
1297
1298 EXJSON_Value * exjson_value_get_parent (const EXJSON_Value *value) {
1299 return value ? value->parent : NULL;
1300 }
1301
1302 void exjson_value_free(EXJSON_Value *value) {
1303 switch (exjson_value_get_type(value)) {
1304 case EXJSONObject:
1305 exjson_object_free(value->value.object);
1306 break;
1307 case EXJSONString:
1308 exparson_free(value->value.string);
1309 break;
1310 case EXJSONArray:
1311 exjson_array_free(value->value.array);
1312 break;
1313 default:
1314 break;
1315 }
1316 exparson_free(value);
1317 }
1318
1319 EXJSON_Value * exjson_value_init_object(void) {
1320 EXJSON_Value *new_value = (EXJSON_Value*)exparson_malloc(sizeof(EXJSON_Value));
1321 if (!new_value) {
1322 return NULL;
1323 }
1324 new_value->parent = NULL;
1325 new_value->type = EXJSONObject;
1326 new_value->value.object = exjson_object_init(new_value);
1327 if (!new_value->value.object) {
1328 exparson_free(new_value);
1329 return NULL;
1330 }
1331 return new_value;
1332 }
1333
1334 EXJSON_Value * exjson_value_init_array(void) {
1335 EXJSON_Value *new_value = (EXJSON_Value*)exparson_malloc(sizeof(EXJSON_Value));
1336 if (!new_value) {
1337 return NULL;
1338 }
1339 new_value->parent = NULL;
1340 new_value->type = EXJSONArray;
1341 new_value->value.array = exjson_array_init(new_value);
1342 if (!new_value->value.array) {
1343 exparson_free(new_value);
1344 return NULL;
1345 }
1346 return new_value;
1347 }
1348
1349 EXJSON_Value * exjson_value_init_string(const char *string) {
1350 char *copy = NULL;
1351 EXJSON_Value *value;
1352 size_t string_len = 0;
1353 if (string == NULL) {
1354 return NULL;
1355 }
1356 string_len = strlen(string);
1357 if (!is_valid_utf8(string, string_len)) {
1358 return NULL;
1359 }
1360 copy = exparson_strndup(string, string_len);
1361 if (copy == NULL) {
1362 return NULL;
1363 }
1364 value = exjson_value_init_string_no_copy(copy);
1365 if (value == NULL) {
1366 exparson_free(copy);
1367 }
1368 return value;
1369 }
1370
1371 EXJSON_Value * exjson_value_init_number(double number) {
1372 EXJSON_Value *new_value = NULL;
1373 if ((number * 0.0) != 0.0) {
1374 return NULL;
1375 }
1376 new_value = (EXJSON_Value*)exparson_malloc(sizeof(EXJSON_Value));
1377 if (new_value == NULL) {
1378 return NULL;
1379 }
1380 new_value->parent = NULL;
1381 new_value->type = EXJSONNumber;
1382 new_value->value.num.number = number;
1383 new_value->value.num.intnumber = number;
1384 return new_value;
1385 }
1386
1387 EXJSON_Value * exjson_value_init_intnumber(long number) {
1388 EXJSON_Value *new_value = NULL;
1389
1390 new_value = (EXJSON_Value*)exparson_malloc(sizeof(EXJSON_Value));
1391 if (new_value == NULL) {
1392 return NULL;
1393 }
1394
1395 new_value->parent = NULL;
1396 new_value->type = EXJSONIntnumber;
1397 new_value->value.num.intnumber = number;
1398
1399 return new_value;
1400 }
1401 EXJSON_Value * exjson_value_init_boolean(int boolean) {
1402 EXJSON_Value *new_value = (EXJSON_Value*)exparson_malloc(sizeof(EXJSON_Value));
1403 if (!new_value) {
1404 return NULL;
1405 }
1406 new_value->parent = NULL;
1407 new_value->type = EXJSONBoolean;
1408 new_value->value.boolean = boolean ? 1 : 0;
1409 return new_value;
1410 }
1411
1412 EXJSON_Value * exjson_value_init_null(void) {
1413 EXJSON_Value *new_value = (EXJSON_Value*)exparson_malloc(sizeof(EXJSON_Value));
1414 if (!new_value) {
1415 return NULL;
1416 }
1417 new_value->parent = NULL;
1418 new_value->type = EXJSONNull;
1419 return new_value;
1420 }
1421
1422 EXJSON_Value * exjson_value_deep_copy(const EXJSON_Value *value) {
1423 size_t i = 0;
1424 EXJSON_Value *return_value = NULL, *temp_value_copy = NULL, *temp_value = NULL;
1425 const char *temp_string = NULL, *temp_key = NULL;
1426 char *temp_string_copy = NULL;
1427 EXJSON_Array *temp_array = NULL, *temp_array_copy = NULL;
1428 EXJSON_Object *temp_object = NULL, *temp_object_copy = NULL;
1429
1430 switch (exjson_value_get_type(value)) {
1431 case EXJSONArray:
1432 temp_array = exjson_value_get_array(value);
1433 return_value = exjson_value_init_array();
1434 if (return_value == NULL) {
1435 return NULL;
1436 }
1437 temp_array_copy = exjson_value_get_array(return_value);
1438 for (i = 0; i < exjson_array_get_count(temp_array); i++) {
1439 temp_value = exjson_array_get_value(temp_array, i);
1440 temp_value_copy = exjson_value_deep_copy(temp_value);
1441 if (temp_value_copy == NULL) {
1442 exjson_value_free(return_value);
1443 return NULL;
1444 }
1445 if (exjson_array_add(temp_array_copy, temp_value_copy) == EXJSONFailure) {
1446 exjson_value_free(return_value);
1447 exjson_value_free(temp_value_copy);
1448 return NULL;
1449 }
1450 }
1451 return return_value;
1452 case EXJSONObject:
1453 temp_object = exjson_value_get_object(value);
1454 return_value = exjson_value_init_object();
1455 if (return_value == NULL) {
1456 return NULL;
1457 }
1458 temp_object_copy = exjson_value_get_object(return_value);
1459 for (i = 0; i < exjson_object_get_count(temp_object); i++) {
1460 temp_key = exjson_object_get_name(temp_object, i);
1461 temp_value = exjson_object_get_value(temp_object, temp_key);
1462 temp_value_copy = exjson_value_deep_copy(temp_value);
1463 if (temp_value_copy == NULL) {
1464 exjson_value_free(return_value);
1465 return NULL;
1466 }
1467 if (exjson_object_add(temp_object_copy, temp_key, temp_value_copy) == EXJSONFailure) {
1468 exjson_value_free(return_value);
1469 exjson_value_free(temp_value_copy);
1470 return NULL;
1471 }
1472 }
1473 return return_value;
1474 case EXJSONBoolean:
1475 return exjson_value_init_boolean(exjson_value_get_boolean(value));
1476 case EXJSONNumber:
1477 return exjson_value_init_number(exjson_value_get_number(value));
1478 case EXJSONIntnumber:
1479 return exjson_value_init_intnumber(exjson_value_get_intnumber(value));
1480 case EXJSONString:
1481 temp_string = exjson_value_get_string(value);
1482 if (temp_string == NULL) {
1483 return NULL;
1484 }
1485 temp_string_copy = exparson_strdup(temp_string);
1486 if (temp_string_copy == NULL) {
1487 return NULL;
1488 }
1489 return_value = exjson_value_init_string_no_copy(temp_string_copy);
1490 if (return_value == NULL) {
1491 exparson_free(temp_string_copy);
1492 }
1493 return return_value;
1494 case EXJSONNull:
1495 return exjson_value_init_null();
1496 case EXJSONError:
1497 return NULL;
1498 default:
1499 return NULL;
1500 }
1501 }
1502
1503 size_t exjson_serialization_size(const EXJSON_Value *value) {
1504 char num_buf[1100];
1505 int res = exjson_serialize_to_buffer_r(value, NULL, 0, 0, num_buf);
1506 return res < 0 ? 0 : (size_t)(res + 1);
1507 }
1508
1509 EXJSON_Status exjson_serialize_to_buffer(const EXJSON_Value *value, char *buf, size_t buf_size_in_bytes) {
1510 int written = -1;
1511 size_t needed_size_in_bytes = exjson_serialization_size(value);
1512 if (needed_size_in_bytes == 0 || buf_size_in_bytes < needed_size_in_bytes) {
1513 return EXJSONFailure;
1514 }
1515 written = exjson_serialize_to_buffer_r(value, buf, 0, 0, NULL);
1516 if (written < 0) {
1517 return EXJSONFailure;
1518 }
1519 return EXJSONSuccess;
1520 }
1521
1522 EXJSON_Status exjson_serialize_to_file(const EXJSON_Value *value, const char *filename) {
1523 EXJSON_Status return_code = EXJSONSuccess;
1524 FILE *fp = NULL;
1525 char *serialized_string = exjson_serialize_to_string(value);
1526 if (serialized_string == NULL) {
1527 return EXJSONFailure;
1528 }
1529 fp = fopen (filename, "w");
1530 if (fp == NULL) {
1531 exjson_free_serialized_string(serialized_string);
1532 return EXJSONFailure;
1533 }
1534 if (fputs(serialized_string, fp) == EOF) {
1535 return_code = EXJSONFailure;
1536 }
1537 if (fclose(fp) == EOF) {
1538 return_code = EXJSONFailure;
1539 }
1540 exjson_free_serialized_string(serialized_string);
1541 return return_code;
1542 }
1543
1544 char * exjson_serialize_to_string(const EXJSON_Value *value) {
1545 EXJSON_Status serialization_result = EXJSONFailure;
1546 size_t buf_size_bytes = exjson_serialization_size(value);
1547 char *buf = NULL;
1548 if (buf_size_bytes == 0) {
1549 return NULL;
1550 }
1551 buf = (char*)exparson_malloc(buf_size_bytes);
1552 if (buf == NULL) {
1553 return NULL;
1554 }
1555 serialization_result = exjson_serialize_to_buffer(value, buf, buf_size_bytes);
1556 if (serialization_result == EXJSONFailure) {
1557 exjson_free_serialized_string(buf);
1558 return NULL;
1559 }
1560 return buf;
1561 }
1562
1563 size_t exjson_serialization_size_pretty(const EXJSON_Value *value) {
1564 char num_buf[1100];
1565 int res = exjson_serialize_to_buffer_r(value, NULL, 0, 1, num_buf);
1566 return res < 0 ? 0 : (size_t)(res + 1);
1567 }
1568
1569 EXJSON_Status exjson_serialize_to_buffer_pretty(const EXJSON_Value *value, char *buf, size_t buf_size_in_bytes) {
1570 int written = -1;
1571 size_t needed_size_in_bytes = exjson_serialization_size_pretty(value);
1572 if (needed_size_in_bytes == 0 || buf_size_in_bytes < needed_size_in_bytes) {
1573 return EXJSONFailure;
1574 }
1575 written = exjson_serialize_to_buffer_r(value, buf, 0, 1, NULL);
1576 if (written < 0) {
1577 return EXJSONFailure;
1578 }
1579 return EXJSONSuccess;
1580 }
1581
1582 EXJSON_Status exjson_serialize_to_file_pretty(const EXJSON_Value *value, const char *filename) {
1583 EXJSON_Status return_code = EXJSONSuccess;
1584 FILE *fp = NULL;
1585 char *serialized_string = exjson_serialize_to_string_pretty(value);
1586 if (serialized_string == NULL) {
1587 return EXJSONFailure;
1588 }
1589 fp = fopen (filename, "w");
1590 if (fp == NULL) {
1591 exjson_free_serialized_string(serialized_string);
1592 return EXJSONFailure;
1593 }
1594 if (fputs(serialized_string, fp) == EOF) {
1595 return_code = EXJSONFailure;
1596 }
1597 if (fclose(fp) == EOF) {
1598 return_code = EXJSONFailure;
1599 }
1600 exjson_free_serialized_string(serialized_string);
1601 return return_code;
1602 }
1603
1604 char * exjson_serialize_to_string_pretty(const EXJSON_Value *value) {
1605 EXJSON_Status serialization_result = EXJSONFailure;
1606 size_t buf_size_bytes = exjson_serialization_size_pretty(value);
1607 char *buf = NULL;
1608 if (buf_size_bytes == 0) {
1609 return NULL;
1610 }
1611 buf = (char*)exparson_malloc(buf_size_bytes);
1612 if (buf == NULL) {
1613 return NULL;
1614 }
1615 serialization_result = exjson_serialize_to_buffer_pretty(value, buf, buf_size_bytes);
1616 if (serialization_result == EXJSONFailure) {
1617 exjson_free_serialized_string(buf);
1618 return NULL;
1619 }
1620 return buf;
1621 }
1622
1623 void exjson_free_serialized_string(char *string) {
1624 exparson_free(string);
1625 }
1626
1627 EXJSON_Status exjson_array_remove(EXJSON_Array *array, size_t ix) {
1628 size_t to_move_bytes = 0;
1629 if (array == NULL || ix >= exjson_array_get_count(array)) {
1630 return EXJSONFailure;
1631 }
1632 exjson_value_free(exjson_array_get_value(array, ix));
1633 to_move_bytes = (exjson_array_get_count(array) - 1 - ix) * sizeof(EXJSON_Value*);
1634 memmove(array->items + ix, array->items + ix + 1, to_move_bytes);
1635 array->count -= 1;
1636 return EXJSONSuccess;
1637 }
1638
1639 EXJSON_Status exjson_array_replace_value(EXJSON_Array *array, size_t ix, EXJSON_Value *value) {
1640 if (array == NULL || value == NULL || value->parent != NULL || ix >= exjson_array_get_count(array)) {
1641 return EXJSONFailure;
1642 }
1643 exjson_value_free(exjson_array_get_value(array, ix));
1644 value->parent = exjson_array_get_wrapping_value(array);
1645 array->items[ix] = value;
1646 return EXJSONSuccess;
1647 }
1648
1649 EXJSON_Status exjson_array_replace_string(EXJSON_Array *array, size_t i, const char* string) {
1650 EXJSON_Value *value = exjson_value_init_string(string);
1651 if (value == NULL) {
1652 return EXJSONFailure;
1653 }
1654 if (exjson_array_replace_value(array, i, value) == EXJSONFailure) {
1655 exjson_value_free(value);
1656 return EXJSONFailure;
1657 }
1658 return EXJSONSuccess;
1659 }
1660
1661 EXJSON_Status exjson_array_replace_number(EXJSON_Array *array, size_t i, double number) {
1662 EXJSON_Value *value = exjson_value_init_number(number);
1663 if (value == NULL) {
1664 return EXJSONFailure;
1665 }
1666 if (exjson_array_replace_value(array, i, value) == EXJSONFailure) {
1667 exjson_value_free(value);
1668 return EXJSONFailure;
1669 }
1670 return EXJSONSuccess;
1671 }
1672
1673 EXJSON_Status exjson_array_replace_intnumber(EXJSON_Array *array, size_t i, long number) {
1674 EXJSON_Value *value = exjson_value_init_intnumber(number);
1675 if (value == NULL) {
1676 return EXJSONFailure;
1677 }
1678 if (exjson_array_replace_value(array, i, value) == EXJSONFailure) {
1679 exjson_value_free(value);
1680 return EXJSONFailure;
1681 }
1682 return EXJSONSuccess;
1683 }
1684
1685 EXJSON_Status exjson_array_replace_boolean(EXJSON_Array *array, size_t i, int boolean) {
1686 EXJSON_Value *value = exjson_value_init_boolean(boolean);
1687 if (value == NULL) {
1688 return EXJSONFailure;
1689 }
1690 if (exjson_array_replace_value(array, i, value) == EXJSONFailure) {
1691 exjson_value_free(value);
1692 return EXJSONFailure;
1693 }
1694 return EXJSONSuccess;
1695 }
1696
1697 EXJSON_Status exjson_array_replace_null(EXJSON_Array *array, size_t i) {
1698 EXJSON_Value *value = exjson_value_init_null();
1699 if (value == NULL) {
1700 return EXJSONFailure;
1701 }
1702 if (exjson_array_replace_value(array, i, value) == EXJSONFailure) {
1703 exjson_value_free(value);
1704 return EXJSONFailure;
1705 }
1706 return EXJSONSuccess;
1707 }
1708
1709 EXJSON_Status exjson_array_clear(EXJSON_Array *array) {
1710 size_t i = 0;
1711 if (array == NULL) {
1712 return EXJSONFailure;
1713 }
1714 for (i = 0; i < exjson_array_get_count(array); i++) {
1715 exjson_value_free(exjson_array_get_value(array, i));
1716 }
1717 array->count = 0;
1718 return EXJSONSuccess;
1719 }
1720
1721 EXJSON_Status exjson_array_append_value(EXJSON_Array *array, EXJSON_Value *value) {
1722 if (array == NULL || value == NULL || value->parent != NULL) {
1723 return EXJSONFailure;
1724 }
1725 return exjson_array_add(array, value);
1726 }
1727
1728 EXJSON_Status exjson_array_append_string(EXJSON_Array *array, const char *string) {
1729 EXJSON_Value *value = exjson_value_init_string(string);
1730 if (value == NULL) {
1731 return EXJSONFailure;
1732 }
1733 if (exjson_array_append_value(array, value) == EXJSONFailure) {
1734 exjson_value_free(value);
1735 return EXJSONFailure;
1736 }
1737 return EXJSONSuccess;
1738 }
1739
1740 EXJSON_Status exjson_array_append_number(EXJSON_Array *array, double number) {
1741 EXJSON_Value *value = exjson_value_init_number(number);
1742 if (value == NULL) {
1743 return EXJSONFailure;
1744 }
1745 if (exjson_array_append_value(array, value) == EXJSONFailure) {
1746 exjson_value_free(value);
1747 return EXJSONFailure;
1748 }
1749 return EXJSONSuccess;
1750 }
1751
1752 EXJSON_Status exjson_array_append_intnumber(EXJSON_Array *array, long number) {
1753 EXJSON_Value *value = exjson_value_init_intnumber(number);
1754 if (value == NULL) {
1755 return EXJSONFailure;
1756 }
1757 if (exjson_array_append_value(array, value) == EXJSONFailure) {
1758 exjson_value_free(value);
1759 return EXJSONFailure;
1760 }
1761 return EXJSONSuccess;
1762 }
1763
1764 EXJSON_Status exjson_array_append_boolean(EXJSON_Array *array, int boolean) {
1765 EXJSON_Value *value = exjson_value_init_boolean(boolean);
1766 if (value == NULL) {
1767 return EXJSONFailure;
1768 }
1769 if (exjson_array_append_value(array, value) == EXJSONFailure) {
1770 exjson_value_free(value);
1771 return EXJSONFailure;
1772 }
1773 return EXJSONSuccess;
1774 }
1775
1776 EXJSON_Status exjson_array_append_null(EXJSON_Array *array) {
1777 EXJSON_Value *value = exjson_value_init_null();
1778 if (value == NULL) {
1779 return EXJSONFailure;
1780 }
1781 if (exjson_array_append_value(array, value) == EXJSONFailure) {
1782 exjson_value_free(value);
1783 return EXJSONFailure;
1784 }
1785 return EXJSONSuccess;
1786 }
1787
1788
1789
1790
1791 EXJSON_Status exjson_object_set_value(EXJSON_Object *object, const char *name, EXJSON_Value *value) {
1792 size_t i = 0;
1793 EXJSON_Value *old_value;
1794 if (object == NULL || name == NULL || value == NULL || value->parent != NULL) {
1795 return EXJSONFailure;
1796 }
1797 old_value = exjson_object_get_value(object, name);
1798 if (old_value != NULL) {
1799 exjson_value_free(old_value);
1800 for (i = 0; i < exjson_object_get_count(object); i++) {
1801 if (strcmp(object->names[i], name) == 0) {
1802 value->parent = exjson_object_get_wrapping_value(object);
1803 object->values[i] = value;
1804 return EXJSONSuccess;
1805 }
1806 }
1807 }
1808
1809 return exjson_object_add(object, name, value);
1810 }
1811
1812 EXJSON_Status exjson_object_set_string(EXJSON_Object *object, const char *name, const char *string) {
1813 return exjson_object_set_value(object, name, exjson_value_init_string(string));
1814 }
1815
1816 EXJSON_Status exjson_object_set_number(EXJSON_Object *object, const char *name, double number) {
1817 return exjson_object_set_value(object, name, exjson_value_init_number(number));
1818 }
1819
1820 EXJSON_Status exjson_object_set_intnumber(EXJSON_Object *object, const char *name, long number) {
1821 return exjson_object_set_value(object, name, exjson_value_init_intnumber(number));
1822 }
1823
1824 EXJSON_Status exjson_object_set_boolean(EXJSON_Object *object, const char *name, int boolean) {
1825 return exjson_object_set_value(object, name, exjson_value_init_boolean(boolean));
1826 }
1827
1828 EXJSON_Status exjson_object_set_null(EXJSON_Object *object, const char *name) {
1829 return exjson_object_set_value(object, name, exjson_value_init_null());
1830 }
1831
1832 EXJSON_Status exjson_object_dotset_value(EXJSON_Object *object, const char *name, EXJSON_Value *value) {
1833 const char *dot_pos = NULL;
1834 char *current_name = NULL;
1835 EXJSON_Object *temp_obj = NULL;
1836 EXJSON_Value *new_value = NULL;
1837 if (object == NULL || name == NULL || value == NULL) {
1838 return EXJSONFailure;
1839 }
1840 dot_pos = strchr(name, '.');
1841 if (dot_pos == NULL) {
1842 return exjson_object_set_value(object, name, value);
1843 } else {
1844 current_name = exparson_strndup(name, dot_pos - name);
1845 temp_obj = exjson_object_get_object(object, current_name);
1846 if (temp_obj == NULL) {
1847 new_value = exjson_value_init_object();
1848 if (new_value == NULL) {
1849 exparson_free(current_name);
1850 return EXJSONFailure;
1851 }
1852 if (exjson_object_add(object, current_name, new_value) == EXJSONFailure) {
1853 exjson_value_free(new_value);
1854 exparson_free(current_name);
1855 return EXJSONFailure;
1856 }
1857 temp_obj = exjson_object_get_object(object, current_name);
1858 }
1859 exparson_free(current_name);
1860 return exjson_object_dotset_value(temp_obj, dot_pos + 1, value);
1861 }
1862 }
1863
1864 EXJSON_Status exjson_object_dotset_string(EXJSON_Object *object, const char *name, const char *string) {
1865 EXJSON_Value *value = exjson_value_init_string(string);
1866 if (value == NULL) {
1867 return EXJSONFailure;
1868 }
1869 if (exjson_object_dotset_value(object, name, value) == EXJSONFailure) {
1870 exjson_value_free(value);
1871 return EXJSONFailure;
1872 }
1873 return EXJSONSuccess;
1874 }
1875
1876 EXJSON_Status exjson_object_dotset_number(EXJSON_Object *object, const char *name, double number) {
1877 EXJSON_Value *value = exjson_value_init_number(number);
1878 if (value == NULL) {
1879 return EXJSONFailure;
1880 }
1881 if (exjson_object_dotset_value(object, name, value) == EXJSONFailure) {
1882 exjson_value_free(value);
1883 return EXJSONFailure;
1884 }
1885 return EXJSONSuccess;
1886 }
1887
1888 EXJSON_Status exjson_object_dotset_intnumber(EXJSON_Object *object, const char *name, long number) {
1889 EXJSON_Value *value = exjson_value_init_intnumber(number);
1890 if (value == NULL) {
1891 return EXJSONFailure;
1892 }
1893 if (exjson_object_dotset_value(object, name, value) == EXJSONFailure) {
1894 exjson_value_free(value);
1895 return EXJSONFailure;
1896 }
1897 return EXJSONSuccess;
1898 }
1899
1900 EXJSON_Status exjson_object_dotset_boolean(EXJSON_Object *object, const char *name, int boolean) {
1901 EXJSON_Value *value = exjson_value_init_boolean(boolean);
1902 if (value == NULL) {
1903 return EXJSONFailure;
1904 }
1905 if (exjson_object_dotset_value(object, name, value) == EXJSONFailure) {
1906 exjson_value_free(value);
1907 return EXJSONFailure;
1908 }
1909 return EXJSONSuccess;
1910 }
1911
1912 EXJSON_Status exjson_object_dotset_null(EXJSON_Object *object, const char *name) {
1913 EXJSON_Value *value = exjson_value_init_null();
1914 if (value == NULL) {
1915 return EXJSONFailure;
1916 }
1917 if (exjson_object_dotset_value(object, name, value) == EXJSONFailure) {
1918 exjson_value_free(value);
1919 return EXJSONFailure;
1920 }
1921 return EXJSONSuccess;
1922 }
1923
1924 EXJSON_Status exjson_object_remove(EXJSON_Object *object, const char *name) {
1925 size_t i = 0, last_item_index = 0;
1926 if (object == NULL || exjson_object_get_value(object, name) == NULL) {
1927 return EXJSONFailure;
1928 }
1929 last_item_index = exjson_object_get_count(object) - 1;
1930 for (i = 0; i < exjson_object_get_count(object); i++) {
1931 if (strcmp(object->names[i], name) == 0) {
1932 exparson_free(object->names[i]);
1933 exjson_value_free(object->values[i]);
1934 if (i != last_item_index) {
1935 object->names[i] = object->names[last_item_index];
1936 object->values[i] = object->values[last_item_index];
1937 }
1938 object->count -= 1;
1939 return EXJSONSuccess;
1940 }
1941 }
1942 return EXJSONFailure;
1943 }
1944
1945 EXJSON_Status exjson_object_dotremove(EXJSON_Object *object, const char *name) {
1946 const char *dot_pos = strchr(name, '.');
1947 char *current_name = NULL;
1948 EXJSON_Object *temp_obj = NULL;
1949 if (dot_pos == NULL) {
1950 return exjson_object_remove(object, name);
1951 } else {
1952 current_name = exparson_strndup(name, dot_pos - name);
1953 temp_obj = exjson_object_get_object(object, current_name);
1954 exparson_free(current_name);
1955 if (temp_obj == NULL) {
1956 return EXJSONFailure;
1957 }
1958 return exjson_object_dotremove(temp_obj, dot_pos + 1);
1959 }
1960 }
1961
1962 EXJSON_Status exjson_object_clear(EXJSON_Object *object) {
1963 size_t i = 0;
1964 if (object == NULL) {
1965 return EXJSONFailure;
1966 }
1967 for (i = 0; i < exjson_object_get_count(object); i++) {
1968 exparson_free(object->names[i]);
1969 exjson_value_free(object->values[i]);
1970 }
1971 object->count = 0;
1972 return EXJSONSuccess;
1973 }
1974
1975 EXJSON_Status exjson_validate(const EXJSON_Value *schema, const EXJSON_Value *value) {
1976 EXJSON_Value *temp_schema_value = NULL, *temp_value = NULL;
1977 EXJSON_Array *schema_array = NULL, *value_array = NULL;
1978 EXJSON_Object *schema_object = NULL, *value_object = NULL;
1979 EXJSON_Value_Type schema_type = EXJSONError, value_type = EXJSONError;
1980 const char *key = NULL;
1981 size_t i = 0, count = 0;
1982 if (schema == NULL || value == NULL) {
1983 return EXJSONFailure;
1984 }
1985 schema_type = exjson_value_get_type(schema);
1986 value_type = exjson_value_get_type(value);
1987 if (schema_type != value_type && schema_type != EXJSONNull) {
1988 return EXJSONFailure;
1989 }
1990 switch (schema_type) {
1991 case EXJSONArray:
1992 schema_array = exjson_value_get_array(schema);
1993 value_array = exjson_value_get_array(value);
1994 count = exjson_array_get_count(schema_array);
1995 if (count == 0) {
1996 return EXJSONSuccess;
1997 }
1998
1999 temp_schema_value = exjson_array_get_value(schema_array, 0);
2000 for (i = 0; i < exjson_array_get_count(value_array); i++) {
2001 temp_value = exjson_array_get_value(value_array, i);
2002 if (exjson_validate(temp_schema_value, temp_value) == EXJSONFailure) {
2003 return EXJSONFailure;
2004 }
2005 }
2006 return EXJSONSuccess;
2007 case EXJSONObject:
2008 schema_object = exjson_value_get_object(schema);
2009 value_object = exjson_value_get_object(value);
2010 count = exjson_object_get_count(schema_object);
2011 if (count == 0) {
2012 return EXJSONSuccess;
2013 } else if (exjson_object_get_count(value_object) < count) {
2014 return EXJSONFailure;
2015 }
2016 for (i = 0; i < count; i++) {
2017 key = exjson_object_get_name(schema_object, i);
2018 temp_schema_value = exjson_object_get_value(schema_object, key);
2019 temp_value = exjson_object_get_value(value_object, key);
2020 if (temp_value == NULL) {
2021 return EXJSONFailure;
2022 }
2023 if (exjson_validate(temp_schema_value, temp_value) == EXJSONFailure) {
2024 return EXJSONFailure;
2025 }
2026 }
2027 return EXJSONSuccess;
2028 case EXJSONString: case EXJSONNumber: case EXJSONIntnumber: case EXJSONBoolean: case EXJSONNull:
2029 return EXJSONSuccess;
2030 case EXJSONError: default:
2031 return EXJSONFailure;
2032 }
2033 }
2034
2035 int exjson_value_equals(const EXJSON_Value *a, const EXJSON_Value *b) {
2036 EXJSON_Object *a_object = NULL, *b_object = NULL;
2037 EXJSON_Array *a_array = NULL, *b_array = NULL;
2038 const char *a_string = NULL, *b_string = NULL;
2039 const char *key = NULL;
2040 size_t a_count = 0, b_count = 0, i = 0;
2041 EXJSON_Value_Type a_type, b_type;
2042 a_type = exjson_value_get_type(a);
2043 b_type = exjson_value_get_type(b);
2044 if (a_type != b_type) {
2045 return 0;
2046 }
2047 switch (a_type) {
2048 case EXJSONArray:
2049 a_array = exjson_value_get_array(a);
2050 b_array = exjson_value_get_array(b);
2051 a_count = exjson_array_get_count(a_array);
2052 b_count = exjson_array_get_count(b_array);
2053 if (a_count != b_count) {
2054 return 0;
2055 }
2056 for (i = 0; i < a_count; i++) {
2057 if (!exjson_value_equals(exjson_array_get_value(a_array, i),
2058 exjson_array_get_value(b_array, i))) {
2059 return 0;
2060 }
2061 }
2062 return 1;
2063 case EXJSONObject:
2064 a_object = exjson_value_get_object(a);
2065 b_object = exjson_value_get_object(b);
2066 a_count = exjson_object_get_count(a_object);
2067 b_count = exjson_object_get_count(b_object);
2068 if (a_count != b_count) {
2069 return 0;
2070 }
2071 for (i = 0; i < a_count; i++) {
2072 key = exjson_object_get_name(a_object, i);
2073 if (!exjson_value_equals(exjson_object_get_value(a_object, key),
2074 exjson_object_get_value(b_object, key))) {
2075 return 0;
2076 }
2077 }
2078 return 1;
2079 case EXJSONString:
2080 a_string = exjson_value_get_string(a);
2081 b_string = exjson_value_get_string(b);
2082 if (a_string == NULL || b_string == NULL) {
2083 return 0;
2084 }
2085 return strcmp(a_string, b_string) == 0;
2086 case EXJSONBoolean:
2087 return exjson_value_get_boolean(a) == exjson_value_get_boolean(b);
2088 case EXJSONNumber:
2089 return fabs(exjson_value_get_number(a) - exjson_value_get_number(b)) < 0.000001;
2090 case EXJSONIntnumber:
2091 return labs(exjson_value_get_intnumber(a) - exjson_value_get_intnumber(b)) ==0;
2092 case EXJSONError:
2093 return 1;
2094 case EXJSONNull:
2095 return 1;
2096 default:
2097 return 1;
2098 }
2099 }
2100
2101 EXJSON_Value_Type exjson_type(const EXJSON_Value *value) {
2102 return exjson_value_get_type(value);
2103 }
2104
2105 EXJSON_Object * exjson_object (const EXJSON_Value *value) {
2106 return exjson_value_get_object(value);
2107 }
2108
2109 EXJSON_Array * exjson_array (const EXJSON_Value *value) {
2110 return exjson_value_get_array(value);
2111 }
2112
2113 const char * exjson_string (const EXJSON_Value *value) {
2114 return exjson_value_get_string(value);
2115 }
2116
2117 double exjson_number (const EXJSON_Value *value) {
2118 return exjson_value_get_number(value);
2119 }
2120
2121 long exjson_intnumber (const EXJSON_Value *value) {
2122 return exjson_value_get_intnumber(value);
2123 }
2124
2125 int exjson_boolean(const EXJSON_Value *value) {
2126 return exjson_value_get_boolean(value);
2127 }
2128
2129 void exjson_set_allocation_functions(EXJSON_Malloc_Function malloc_fun, EXJSON_Free_Function free_fun) {
2130 exparson_malloc = malloc_fun;
2131 exparson_free = free_fun;
2132 }