source: lib/parson.c @ f81d8b8

Last change on this file since f81d8b8 was 8563fe7, checked in by Wilmer van der Gaast <wilmer@…>, at 2015-05-05T22:39:39Z

Make my fork of parson non-JSON-compliant. I don't care that JavaScript's
tiny little brain doesn't comprehend integers and wants everything to be a
float, the adults need integers now. Big integers. So add them, just like
the old js lib did. This also lets me clean up some horrible things in the
RPC module.

Try to have behaviour similar to the old lib: Throw as much as possible into
an integer, only switch to double when there's a non-int or a number larger
than what fits a "signed long long".

Yes this is horrible, and no I don't think the parson upstreams will accept
this. But the alternative is to stay compliant to an accidentally popular
data interchange format based on accidentally popular joke language and do
a lot of manual string-to-int64 parsing in the Twitter codebase. How about
NOPE.

  • Property mode set to 100644
File size: 60.1 KB
RevLine 
[782a6ee]1/*
2 Parson ( http://kgabis.github.com/parson/ )
3 Copyright (c) 2012 - 2014 Krzysztof Gabis
4
5 Permission is hereby granted, free of charge, to any person obtaining a copy
6 of this software and associated documentation files (the "Software"), to deal
7 in the Software without restriction, including without limitation the rights
8 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 copies of the Software, and to permit persons to whom the Software is
10 furnished to do so, subject to the following conditions:
11
12 The above copyright notice and this permission notice shall be included in
13 all copies or substantial portions of the Software.
14
15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 THE SOFTWARE.
22*/
23#ifdef _MSC_VER
24#define _CRT_SECURE_NO_WARNINGS
25#endif
26
27#include "parson.h"
28
[8563fe7]29#include <errno.h>
[782a6ee]30#include <stdio.h>
31#include <stdlib.h>
32#include <string.h>
33#include <ctype.h>
34#include <math.h>
35
36#define STARTING_CAPACITY         15
37#define ARRAY_MAX_CAPACITY    122880 /* 15*(2^13) */
38#define OBJECT_MAX_CAPACITY      960 /* 15*(2^6)  */
39#define MAX_NESTING               19
40#define DOUBLE_SERIALIZATION_FORMAT "%f"
[8563fe7]41#define JINT_SERIALIZATION_FORMAT "%lld"
[782a6ee]42
43#define SIZEOF_TOKEN(a)       (sizeof(a) - 1)
44#define SKIP_CHAR(str)        ((*str)++)
45#define SKIP_WHITESPACES(str) while (isspace(**str)) { SKIP_CHAR(str); }
46#define MAX(a, b)             ((a) > (b) ? (a) : (b))
47
48#define PARSON_MALLOC(a)     malloc(a)
49#define PARSON_FREE(a)       free((void*)(a))
50#define PARSON_REALLOC(a, b) realloc((a), (b))
51
52#define PRINT_AND_SKIP(str, to_append) str += sprintf(str, to_append);
53#define PRINTF_AND_SKIP(str, format, to_append) str += sprintf(str, format, to_append);
54
[5726a0d]55#define IS_CONT(b) (((unsigned char)(b) & 0xC0) == 0x80) /* is utf-8 continuation byte */
56
[8563fe7]57typedef long long jint;
58
[782a6ee]59/* Type definitions */
60typedef union json_value_value {
61    const char  *string;
62    double       number;
[8563fe7]63    jint         integer;
[782a6ee]64    JSON_Object *object;
65    JSON_Array  *array;
66    int          boolean;
67    int          null;
68} JSON_Value_Value;
69
70struct json_value_t {
71    JSON_Value_Type     type;
72    JSON_Value_Value    value;
73};
74
75struct json_object_t {
76    const char **names;
77    JSON_Value **values;
78    size_t       count;
79    size_t       capacity;
80};
81
82struct json_array_t {
83    JSON_Value **items;
84    size_t       count;
85    size_t       capacity;
86};
87
88/* Various */
89static char * read_file(const char *filename);
90static void   remove_comments(char *string, const char *start_token, const char *end_token);
91static int    try_realloc(void **ptr, size_t new_size);
92static char * parson_strndup(const char *string, size_t n);
93static char * parson_strdup(const char *string);
[5726a0d]94static int    is_utf16_hex(const unsigned char *string);
95static int    num_bytes_in_utf8_sequence(unsigned char c);
96static int    verify_utf8_sequence(const unsigned char *string, int *len);
97static int    is_valid_utf8(const char *string, size_t string_len);
[782a6ee]98static int    is_decimal(const char *string, size_t length);
[5726a0d]99static size_t serialization_strlen(const char *string);
[782a6ee]100
101/* JSON Object */
102static JSON_Object * json_object_init(void);
103static JSON_Status   json_object_add(JSON_Object *object, const char *name, JSON_Value *value);
104static JSON_Status   json_object_resize(JSON_Object *object, size_t capacity);
105static JSON_Value  * json_object_nget_value(const JSON_Object *object, const char *name, size_t n);
106static void          json_object_free(JSON_Object *object);
107
108/* JSON Array */
109static JSON_Array * json_array_init(void);
110static JSON_Status  json_array_add(JSON_Array *array, JSON_Value *value);
111static JSON_Status  json_array_resize(JSON_Array *array, size_t capacity);
112static void         json_array_free(JSON_Array *array);
113
114/* JSON Value */
115static JSON_Value * json_value_init_string_no_copy(const char *string);
116
117/* Parser */
118static void         skip_quotes(const char **string);
119static int          parse_utf_16(const char **unprocessed, char **processed);
120static char*        process_string(const char *input, size_t len);
121static const char * get_quoted_string(const char **string);
122static JSON_Value * parse_object_value(const char **string, size_t nesting);
123static JSON_Value * parse_array_value(const char **string, size_t nesting);
124static JSON_Value * parse_string_value(const char **string);
125static JSON_Value * parse_boolean_value(const char **string);
126static JSON_Value * parse_number_value(const char **string);
127static JSON_Value * parse_null_value(const char **string);
128static JSON_Value * parse_value(const char **string, size_t nesting);
129
130/* Serialization */
131static size_t json_serialization_size_r(const JSON_Value *value, char *buf);
132static char * json_serialize_to_buffer_r(const JSON_Value *value, char *buf);
133static char * json_serialize_string(const char *string, char *buf);
134
135/* Various */
136static int try_realloc(void **ptr, size_t new_size) {
137    void *reallocated_ptr = NULL;
138    if (new_size == 0) {
139        return JSONFailure;
140    }
141    reallocated_ptr = PARSON_REALLOC(*ptr, new_size);
142    if (reallocated_ptr == NULL) {
143        return JSONFailure;
144    }
145    *ptr = reallocated_ptr;
146    return JSONSuccess;
147}
148
149static char * parson_strndup(const char *string, size_t n) {
150    char *output_string = (char*)PARSON_MALLOC(n + 1);
151    if (!output_string)
152        return NULL;
153    output_string[n] = '\0';
154    strncpy(output_string, string, n);
155    return output_string;
156}
157
158static char * parson_strdup(const char *string) {
159    return parson_strndup(string, strlen(string));
160}
161
[5726a0d]162static int is_utf16_hex(const unsigned char *s) {
[782a6ee]163    return isxdigit(s[0]) && isxdigit(s[1]) && isxdigit(s[2]) && isxdigit(s[3]);
164}
165
[5726a0d]166static int num_bytes_in_utf8_sequence(unsigned char c) {
167    if (c == 0xC0 || c == 0xC1 || c > 0xF4 || IS_CONT(c)) {
168        return 0;
169    } else if ((c & 0x80) == 0) {    /* 0xxxxxxx */
170        return 1;
171    } else if ((c & 0xE0) == 0xC0) { /* 110xxxxx */
172        return 2;
173    } else if ((c & 0xF0) == 0xE0) { /* 1110xxxx */
174        return 3;
175    } else if ((c & 0xF8) == 0xF0) { /* 11110xxx */
176        return 4;
177    }
178    return 0; /* won't happen */
179}
180
181static int verify_utf8_sequence(const unsigned char *string, int *len) {
182    unsigned int cp = 0;
183    *len = num_bytes_in_utf8_sequence(string[0]);
184   
185    if (*len == 1) {
186        cp = string[0];
187    } else if (*len == 2 && IS_CONT(string[1])) {
188        cp = string[0] & 0x1F;
189        cp = (cp << 6) | (string[1] & 0x3F);
190    } else if (*len == 3 && IS_CONT(string[1]) && IS_CONT(string[2])) {
191        cp = ((unsigned char)string[0]) & 0xF;
192        cp = (cp << 6) | (string[1] & 0x3F);
193        cp = (cp << 6) | (string[2] & 0x3F);
194    } else if (*len == 4 && IS_CONT(string[1]) && IS_CONT(string[2]) && IS_CONT(string[3])) {
195        cp = string[0] & 0x7;
196        cp = (cp << 6) | (string[1] & 0x3F);
197        cp = (cp << 6) | (string[2] & 0x3F);
198        cp = (cp << 6) | (string[3] & 0x3F);
199    } else {
200        return 0;
201    }
202   
203    /* overlong encodings */
204    if ((cp < 0x80    && *len > 1) ||
205        (cp < 0x800   && *len > 2) ||
206        (cp < 0x10000 && *len > 3)) {
207        return 0;
208    }
209   
210    /* invalid unicode */
211    if (cp > 0x10FFFF) {
212        return 0;
213    }
214   
215    /* surrogate halves */
216    if (cp >= 0xD800 && cp <= 0xDFFF) {
217        return 0;
218    }
219   
220    return 1;
221}
222
223static int is_valid_utf8(const char *string, size_t string_len) {
224    int len = 0;
225    const char *string_end =  string + string_len;
226    while (string < string_end) {
227        if (!verify_utf8_sequence((const unsigned char*)string, &len)) {
228            return 0;
229        }
230        string += len;
231    }
232    return 1;
233}
234
[782a6ee]235static int is_decimal(const char *string, size_t length) {
236    if (length > 1 && string[0] == '0' && string[1] != '.')
237        return 0;
238    if (length > 2 && !strncmp(string, "-0", 2) && string[2] != '.')
239        return 0;
240    while (length--)
241        if (strchr("xX", string[length]))
242            return 0;
243    return 1;
244}
245
[5726a0d]246static size_t serialization_strlen(const char *string) {
[782a6ee]247    size_t result = 0;
248    size_t i = 0, len = strlen(string);
249    for (i = 0; i < len; i++) {
250        if (strchr("\"\\\b\f\n\r\t", string[i])) /* must be escaped */
251            result += 2;
252        else
253            result += 1;
254    }
255    return result;
256}
257
258static char * read_file(const char * filename) {
259    FILE *fp = fopen(filename, "r");
260    size_t file_size;
[5726a0d]261    long pos;
[782a6ee]262    char *file_contents;
263    if (!fp)
264        return NULL;
265    fseek(fp, 0L, SEEK_END);
[5726a0d]266    pos = ftell(fp);
267    if (pos < 0) {
268        fclose(fp);
269        return NULL;
270    }
271    file_size = pos;
[782a6ee]272    rewind(fp);
273    file_contents = (char*)PARSON_MALLOC(sizeof(char) * (file_size + 1));
274    if (!file_contents) {
275        fclose(fp);
276        return NULL;
277    }
278    if (fread(file_contents, file_size, 1, fp) < 1) {
279        if (ferror(fp)) {
280            fclose(fp);
281            PARSON_FREE(file_contents);
282            return NULL;
283        }
284    }
285    fclose(fp);
286    file_contents[file_size] = '\0';
287    return file_contents;
288}
289
290static void remove_comments(char *string, const char *start_token, const char *end_token) {
291    int in_string = 0, escaped = 0;
292    size_t i;
293    char *ptr = NULL, current_char;
294    size_t start_token_len = strlen(start_token);
295    size_t end_token_len = strlen(end_token);
296    if (start_token_len == 0 || end_token_len == 0)
297        return;
298    while ((current_char = *string) != '\0') {
299        if (current_char == '\\' && !escaped) {
300            escaped = 1;
301            string++;
302            continue;
303        } else if (current_char == '\"' && !escaped) {
304            in_string = !in_string;
305        } else if (!in_string && strncmp(string, start_token, start_token_len) == 0) {
306                        for(i = 0; i < start_token_len; i++)
307                string[i] = ' ';
308                string = string + start_token_len;
309            ptr = strstr(string, end_token);
310            if (!ptr)
311                return;
312            for (i = 0; i < (ptr - string) + end_token_len; i++)
313                string[i] = ' ';
314                string = ptr + end_token_len - 1;
315        }
316        escaped = 0;
317        string++;
318    }
319}
320
321/* JSON Object */
322static JSON_Object * json_object_init(void) {
323    JSON_Object *new_obj = (JSON_Object*)PARSON_MALLOC(sizeof(JSON_Object));
324    if (!new_obj)
325        return NULL;
326    new_obj->names = (const char**)NULL;
327    new_obj->values = (JSON_Value**)NULL;
328    new_obj->capacity = 0;
329    new_obj->count = 0;
330    return new_obj;
331}
332
333static JSON_Status json_object_add(JSON_Object *object, const char *name, JSON_Value *value) {
[5726a0d]334    size_t index = 0;
335    if (object == NULL || name == NULL || value == NULL) {
336        return JSONFailure;
337    }
[782a6ee]338    if (object->count >= object->capacity) {
339        size_t new_capacity = MAX(object->capacity * 2, STARTING_CAPACITY);
340        if (new_capacity > OBJECT_MAX_CAPACITY)
341            return JSONFailure;
342        if (json_object_resize(object, new_capacity) == JSONFailure)
343            return JSONFailure;
344    }
345    if (json_object_get_value(object, name) != NULL)
346        return JSONFailure;
347    index = object->count;
348    object->names[index] = parson_strdup(name);
[5726a0d]349    if (object->names[index] == NULL)
[782a6ee]350        return JSONFailure;
351    object->values[index] = value;
352    object->count++;
353    return JSONSuccess;
354}
355
356static JSON_Status json_object_resize(JSON_Object *object, size_t capacity) {
357    if (try_realloc((void**)&object->names, capacity * sizeof(char*)) == JSONFailure)
358        return JSONFailure;
359    if (try_realloc((void**)&object->values, capacity * sizeof(JSON_Value*)) == JSONFailure)
360        return JSONFailure;
361    object->capacity = capacity;
362    return JSONSuccess;
363}
364
365static JSON_Value * json_object_nget_value(const JSON_Object *object, const char *name, size_t n) {
366    size_t i, name_length;
367    for (i = 0; i < json_object_get_count(object); i++) {
368        name_length = strlen(object->names[i]);
369        if (name_length != n)
370            continue;
371        if (strncmp(object->names[i], name, n) == 0)
372            return object->values[i];
373    }
374    return NULL;
375}
376
377static void json_object_free(JSON_Object *object) {
378    while(object->count--) {
379        PARSON_FREE(object->names[object->count]);
380        json_value_free(object->values[object->count]);
381    }
382    PARSON_FREE(object->names);
383    PARSON_FREE(object->values);
384    PARSON_FREE(object);
385}
386
387/* JSON Array */
388static JSON_Array * json_array_init(void) {
389    JSON_Array *new_array = (JSON_Array*)PARSON_MALLOC(sizeof(JSON_Array));
390    if (!new_array)
391        return NULL;
392    new_array->items = (JSON_Value**)NULL;
393    new_array->capacity = 0;
394    new_array->count = 0;
395    return new_array;
396}
397
398static JSON_Status json_array_add(JSON_Array *array, JSON_Value *value) {
399    if (array->count >= array->capacity) {
400        size_t new_capacity = MAX(array->capacity * 2, STARTING_CAPACITY);
401        if (new_capacity > ARRAY_MAX_CAPACITY)
402            return JSONFailure;
403        if (json_array_resize(array, new_capacity) == JSONFailure)
404            return JSONFailure;
405    }
406    array->items[array->count] = value;
407    array->count++;
408    return JSONSuccess;
409}
410
411static JSON_Status json_array_resize(JSON_Array *array, size_t capacity) {
412    if (try_realloc((void**)&array->items, capacity * sizeof(JSON_Value*)) == JSONFailure)
413        return JSONFailure;
414    array->capacity = capacity;
415    return JSONSuccess;
416}
417
418static void json_array_free(JSON_Array *array) {
419    while (array->count--)
420        json_value_free(array->items[array->count]);
421    PARSON_FREE(array->items);
422    PARSON_FREE(array);
423}
424
425/* JSON Value */
426static JSON_Value * json_value_init_string_no_copy(const char *string) {
427    JSON_Value *new_value = (JSON_Value*)PARSON_MALLOC(sizeof(JSON_Value));
428    if (!new_value)
429        return NULL;
430    new_value->type = JSONString;
431    new_value->value.string = string;
432    return new_value;
433}
434
435/* Parser */
436static void skip_quotes(const char **string) {
437    SKIP_CHAR(string);
438    while (**string != '\"') {
439        if (**string == '\0')
440            return;
441        if (**string == '\\') {
442            SKIP_CHAR(string);
443            if (**string == '\0')
444                return;
445        }
446        SKIP_CHAR(string);
447    }
448    SKIP_CHAR(string);
449}
450
451static int parse_utf_16(const char **unprocessed, char **processed) {
452    unsigned int cp, lead, trail;
453    char *processed_ptr = *processed;
454    const char *unprocessed_ptr = *unprocessed;
455    unprocessed_ptr++; /* skips u */
[5726a0d]456    if (!is_utf16_hex((const unsigned char*)unprocessed_ptr) || sscanf(unprocessed_ptr, "%4x", &cp) == EOF)
[782a6ee]457            return JSONFailure;
458    if (cp < 0x80) {
459        *processed_ptr = cp; /* 0xxxxxxx */
460    } else if (cp < 0x800) {
461        *processed_ptr++ = ((cp >> 6) & 0x1F) | 0xC0; /* 110xxxxx */
462        *processed_ptr   = ((cp     ) & 0x3F) | 0x80; /* 10xxxxxx */
463    } else if (cp < 0xD800 || cp > 0xDFFF) {
464        *processed_ptr++ = ((cp >> 12) & 0x0F) | 0xE0; /* 1110xxxx */
465        *processed_ptr++ = ((cp >> 6)  & 0x3F) | 0x80; /* 10xxxxxx */
466        *processed_ptr   = ((cp     )  & 0x3F) | 0x80; /* 10xxxxxx */
467    } else if (cp >= 0xD800 && cp <= 0xDBFF) { /* lead surrogate (0xD800..0xDBFF) */
468        lead = cp;
469        unprocessed_ptr += 4; /* should always be within the buffer, otherwise previous sscanf would fail */
470        if (*unprocessed_ptr++ != '\\' || *unprocessed_ptr++ != 'u' || /* starts with \u? */
[5726a0d]471            !is_utf16_hex((const unsigned char*)unprocessed_ptr)          ||
[782a6ee]472            sscanf(unprocessed_ptr, "%4x", &trail) == EOF           ||
473            trail < 0xDC00 || trail > 0xDFFF) { /* valid trail surrogate? (0xDC00..0xDFFF) */
474                return JSONFailure;
475        }
476        cp = ((((lead-0xD800)&0x3FF)<<10)|((trail-0xDC00)&0x3FF))+0x010000;
477        *processed_ptr++ = (((cp >> 18) & 0x07) | 0xF0); /* 11110xxx */
478        *processed_ptr++ = (((cp >> 12) & 0x3F) | 0x80); /* 10xxxxxx */
479        *processed_ptr++ = (((cp >> 6)  & 0x3F) | 0x80); /* 10xxxxxx */
480        *processed_ptr   = (((cp     )  & 0x3F) | 0x80); /* 10xxxxxx */
481    } else { /* trail surrogate before lead surrogate */
482        return JSONFailure;
483    }
484    unprocessed_ptr += 3;
485    *processed = processed_ptr;
486    *unprocessed = unprocessed_ptr;
487    return JSONSuccess;
488}
489
490
491/* Copies and processes passed string up to supplied length.
492Example: "\u006Corem ipsum" -> lorem ipsum */
493static char* process_string(const char *input, size_t len) {
494    const char *input_ptr = input;
495    char *output = (char*)PARSON_MALLOC((len + 1) * sizeof(char));
496    char *output_ptr = output;
497    while ((*input_ptr != '\0') && (size_t)(input_ptr - input) < len) {
498        if (*input_ptr == '\\') {
499            input_ptr++;
500            switch (*input_ptr) {
501                case '\"': *output_ptr = '\"'; break;
502                case '\\': *output_ptr = '\\'; break;
503                case '/':  *output_ptr = '/';  break;
504                case 'b':  *output_ptr = '\b'; break;
505                case 'f':  *output_ptr = '\f'; break;
506                case 'n':  *output_ptr = '\n'; break;
507                case 'r':  *output_ptr = '\r'; break;
508                case 't':  *output_ptr = '\t'; break;
509                case 'u':
510                    if (parse_utf_16(&input_ptr, &output_ptr) == JSONFailure)
511                        goto error;
512                    break;
513                default:
514                    goto error;
515            }
516        } else if ((unsigned char)*input_ptr < 0x20) {
517            goto error; /* 0x00-0x19 are invalid characters for json string (http://www.ietf.org/rfc/rfc4627.txt) */
518        } else {
519            *output_ptr = *input_ptr;
520        }
521        output_ptr++;
522        input_ptr++;
523    }
524    *output_ptr = '\0';
[5726a0d]525    if (try_realloc((void**)&output, (size_t)(output_ptr-output) + 1) == JSONFailure) /* resize to new length */
[782a6ee]526        goto error;
527    return output;
528error:
529    free(output);
530    return NULL;
531}
532
533/* Return processed contents of a string between quotes and
534   skips passed argument to a matching quote. */
535static const char * get_quoted_string(const char **string) {
536    const char *string_start = *string;
537    size_t string_len = 0;
538    skip_quotes(string);
539    if (**string == '\0')
540        return NULL;
541    string_len = *string - string_start - 2; /* length without quotes */
542    return process_string(string_start + 1, string_len);
543}
544
545static JSON_Value * parse_value(const char **string, size_t nesting) {
546    if (nesting > MAX_NESTING)
547        return NULL;
548    SKIP_WHITESPACES(string);
549    switch (**string) {
550        case '{':
551            return parse_object_value(string, nesting + 1);
552        case '[':
553            return parse_array_value(string, nesting + 1);
554        case '\"':
555            return parse_string_value(string);
556        case 'f': case 't':
557            return parse_boolean_value(string);
558        case '-':
559        case '0': case '1': case '2': case '3': case '4':
560        case '5': case '6': case '7': case '8': case '9':
561            return parse_number_value(string);
562        case 'n':
563            return parse_null_value(string);
564        default:
565            return NULL;
566    }
567}
568
569static JSON_Value * parse_object_value(const char **string, size_t nesting) {
570    JSON_Value *output_value = json_value_init_object(), *new_value = NULL;
571    JSON_Object *output_object = json_value_get_object(output_value);
572    const char *new_key = NULL;
573    if (output_value == NULL)
574        return NULL;
575    SKIP_CHAR(string);
576    SKIP_WHITESPACES(string);
577    if (**string == '}') { /* empty object */
578        SKIP_CHAR(string);
579        return output_value;
580    }
581    while (**string != '\0') {
582        new_key = get_quoted_string(string);
583        SKIP_WHITESPACES(string);
584        if (new_key == NULL || **string != ':') {
585            json_value_free(output_value);
586            return NULL;
587        }
588        SKIP_CHAR(string);
589        new_value = parse_value(string, nesting);
590        if (new_value == NULL) {
591            PARSON_FREE(new_key);
592            json_value_free(output_value);
593            return NULL;
594        }
595        if(json_object_add(output_object, new_key, new_value) == JSONFailure) {
596            PARSON_FREE(new_key);
597            PARSON_FREE(new_value);
598            json_value_free(output_value);
599            return NULL;
600        }
601        PARSON_FREE(new_key);
602        SKIP_WHITESPACES(string);
603        if (**string != ',')
604            break;
605        SKIP_CHAR(string);
606        SKIP_WHITESPACES(string);
607    }
608    SKIP_WHITESPACES(string);
609    if (**string != '}' || /* Trim object after parsing is over */
610        json_object_resize(output_object, json_object_get_count(output_object)) == JSONFailure) {
611            json_value_free(output_value);
612            return NULL;
613    }
614    SKIP_CHAR(string);
615    return output_value;
616}
617
618static JSON_Value * parse_array_value(const char **string, size_t nesting) {
619    JSON_Value *output_value = json_value_init_array(), *new_array_value = NULL;
620    JSON_Array *output_array = json_value_get_array(output_value);
621    if (!output_value)
622        return NULL;
623    SKIP_CHAR(string);
624    SKIP_WHITESPACES(string);
625    if (**string == ']') { /* empty array */
626        SKIP_CHAR(string);
627        return output_value;
628    }
629    while (**string != '\0') {
630        new_array_value = parse_value(string, nesting);
631        if (!new_array_value) {
632            json_value_free(output_value);
633            return NULL;
634        }
635        if(json_array_add(output_array, new_array_value) == JSONFailure) {
636            PARSON_FREE(new_array_value);
637            json_value_free(output_value);
638            return NULL;
639        }
640        SKIP_WHITESPACES(string);
641        if (**string != ',')
642            break;
643        SKIP_CHAR(string);
644        SKIP_WHITESPACES(string);
645    }
646    SKIP_WHITESPACES(string);
647    if (**string != ']' || /* Trim array after parsing is over */
648        json_array_resize(output_array, json_array_get_count(output_array)) == JSONFailure) {
649            json_value_free(output_value);
650            return NULL;
651    }
652    SKIP_CHAR(string);
653    return output_value;
654}
655
656static JSON_Value * parse_string_value(const char **string) {
657    const char *new_string = get_quoted_string(string);
658    if (!new_string)
659        return NULL;
660    return json_value_init_string_no_copy(new_string);
661}
662
663static JSON_Value * parse_boolean_value(const char **string) {
664    size_t true_token_size = SIZEOF_TOKEN("true");
665    size_t false_token_size = SIZEOF_TOKEN("false");
666    if (strncmp("true", *string, true_token_size) == 0) {
667        *string += true_token_size;
668        return json_value_init_boolean(1);
669    } else if (strncmp("false", *string, false_token_size) == 0) {
670        *string += false_token_size;
671        return json_value_init_boolean(0);
672    }
673    return NULL;
674}
675
676static JSON_Value * parse_number_value(const char **string) {
[8563fe7]677    char *jint_end, *double_end;
678    double number = strtod(*string, &double_end);
679    jint integer = strtoll(*string, &jint_end, 10);
[782a6ee]680    JSON_Value *output_value;
[8563fe7]681    if (double_end > jint_end || errno == ERANGE) {
682        if (is_decimal(*string, double_end - *string)) {
683            *string = double_end;
684            output_value = json_value_init_number(number);
685        } else {
686            output_value = NULL;
687        }
[782a6ee]688    } else {
[8563fe7]689        *string = jint_end;
690        output_value = json_value_init_integer(integer);
[782a6ee]691    }
692    return output_value;
693}
694
695static JSON_Value * parse_null_value(const char **string) {
696    size_t token_size = SIZEOF_TOKEN("null");
697    if (strncmp("null", *string, token_size) == 0) {
698        *string += token_size;
699        return json_value_init_null();
700    }
701    return NULL;
702}
703
704/* Serialization */
705static size_t json_serialization_size_r(const JSON_Value *value, char *buf) {
706    size_t result_size = 0;
707    const char *key = NULL;
708    JSON_Value *temp_value = NULL;
709    JSON_Array *array = NULL;
710    JSON_Object *object = NULL;
711    size_t i = 0, count = 0;
712    double num = 0.0;
[8563fe7]713    jint intnum = 0;
[782a6ee]714    switch (json_value_get_type(value)) {
715        case JSONArray:
716            array = json_value_get_array(value);
717            count = json_array_get_count(array);
718            result_size += 2; /* [ and ] brackets */
719            if (count > 0)
720                result_size += count - 1; /* , between items */
721            for (i = 0; i < count; i++) {
722                temp_value = json_array_get_value(array, i);
723                result_size += json_serialization_size_r(temp_value, buf);
724            }
725            return result_size;
726        case JSONObject:
727            object = json_value_get_object(value);
728            count  = json_object_get_count(object);
729            result_size += 2; /* { and } brackets */
730            if (count > 0)
731                result_size += (count * 2) - 1; /* : between keys and values and , between items */
732            for (i = 0; i < count; i++) {
733                key = json_object_get_name(object, i);
[5726a0d]734                result_size += serialization_strlen(key) + 2; /* string and quotes */
[782a6ee]735                result_size += json_serialization_size_r(json_object_get_value(object, key), buf);
736            }
737            return result_size;
738        case JSONString:
[5726a0d]739            return serialization_strlen(json_value_get_string(value)) + 2; /* string and quotes */
[782a6ee]740        case JSONBoolean:
741            if (json_value_get_boolean(value))
742                return 4; /* strlen("true"); */
743            else
744                return 5; /* strlen("false"); */
[8563fe7]745        case JSONInteger:
746            intnum = json_value_get_integer(value);
747            return (size_t)sprintf(buf, JINT_SERIALIZATION_FORMAT, intnum);
[782a6ee]748        case JSONNumber:
749            num = json_value_get_number(value);
[8563fe7]750            if (num == ((double)(jint)num) ) /*  check if num is integer */
751                return (size_t)sprintf(buf, JINT_SERIALIZATION_FORMAT, (jint)num);
[782a6ee]752            return (size_t)sprintf(buf, DOUBLE_SERIALIZATION_FORMAT, num);
753        case JSONNull:
754            return 4; /* strlen("null"); */
755        case JSONError:
756            return 0;
757        default:
758            return 0;
759    }
760}
761
762char* json_serialize_to_buffer_r(const JSON_Value *value, char *buf)
763{
764    const char *key = NULL, *string = NULL;
765    JSON_Value *temp_value = NULL;
766    JSON_Array *array = NULL;
767    JSON_Object *object = NULL;
768    size_t i = 0, count = 0;
769    double num = 0.0;
[8563fe7]770    jint intnum = 0;
[782a6ee]771    switch (json_value_get_type(value)) {
772        case JSONArray:
773            array = json_value_get_array(value);
774            count = json_array_get_count(array);
775            PRINT_AND_SKIP(buf, "[");
776            for (i = 0; i < count; i++) {
777                temp_value = json_array_get_value(array, i);
778                buf = json_serialize_to_buffer_r(temp_value, buf);
[5726a0d]779                if (buf == NULL)
780                    return NULL;
[782a6ee]781                if (i < (count - 1))
782                    PRINT_AND_SKIP(buf, ",");
783            }
784            PRINT_AND_SKIP(buf, "]");
785            return buf;
786        case JSONObject:
787            object = json_value_get_object(value);
788            count  = json_object_get_count(object);
789            PRINT_AND_SKIP(buf, "{");
790            for (i = 0; i < count; i++) {
791                key = json_object_get_name(object, i);
792                buf = json_serialize_string(key, buf);
[5726a0d]793                if (buf == NULL)
794                    return NULL;
[782a6ee]795                PRINT_AND_SKIP(buf, ":");
796                temp_value = json_object_get_value(object, key);
797                buf = json_serialize_to_buffer_r(temp_value, buf);
[5726a0d]798                if (buf == NULL)
799                    return NULL;
[782a6ee]800                if (i < (count - 1))
801                    PRINT_AND_SKIP(buf, ",");
802            }
803            PRINT_AND_SKIP(buf, "}");
804            return buf;
805        case JSONString:
806            string = json_value_get_string(value);
807            buf = json_serialize_string(string, buf);
808            return buf;
809        case JSONBoolean:
810            if (json_value_get_boolean(value)) {
811                PRINT_AND_SKIP(buf, "true");
812            } else {
813                PRINT_AND_SKIP(buf, "false");
814            }
815            return buf;
[8563fe7]816        case JSONInteger:
817            intnum = json_value_get_integer(value);
818            PRINTF_AND_SKIP(buf, JINT_SERIALIZATION_FORMAT, intnum);
819            return buf;
[782a6ee]820        case JSONNumber:
821            num = json_value_get_number(value);
822            if (num == ((double)(int)num)) { /*  check if num is integer */
823                PRINTF_AND_SKIP(buf, "%d", (int)num);
824            } else {
825                PRINTF_AND_SKIP(buf, DOUBLE_SERIALIZATION_FORMAT, num);
826            }
827            return buf;
828        case JSONNull:
829            PRINT_AND_SKIP(buf, "null");
830            return buf;
831        case JSONError:
832            return NULL;
833        default:
834            return NULL;
835    }
836}
837
838static char * json_serialize_string(const char *string, char *buf) {
839    size_t i = 0, len = strlen(string);
840    char c = '\0';
841    PRINT_AND_SKIP(buf, "\"")
842    for (i = 0; i < len; i++) {
843        c = string[i];
844        switch (c) {
845            case '\"': PRINT_AND_SKIP(buf, "\\\"");   break;
846            case '\\': PRINT_AND_SKIP(buf, "\\\\");   break;
847            case '\b': PRINT_AND_SKIP(buf, "\\b");    break;
848            case '\f': PRINT_AND_SKIP(buf, "\\f");    break;
849            case '\n': PRINT_AND_SKIP(buf, "\\n");    break;
850            case '\r': PRINT_AND_SKIP(buf, "\\r");    break;
851            case '\t': PRINT_AND_SKIP(buf, "\\t");    break;
852            default:   PRINTF_AND_SKIP(buf, "%c", c); break;
853        }
854    }
855    PRINT_AND_SKIP(buf, "\"");
856    return buf;
857}
858
859/* Parser API */
860JSON_Value * json_parse_file(const char *filename) {
861    char *file_contents = read_file(filename);
862    JSON_Value *output_value = NULL;
[5726a0d]863    if (file_contents == NULL)
[782a6ee]864        return NULL;
865    output_value = json_parse_string(file_contents);
866    PARSON_FREE(file_contents);
867    return output_value;
868}
869
870JSON_Value * json_parse_file_with_comments(const char *filename) {
871    char *file_contents = read_file(filename);
872    JSON_Value *output_value = NULL;
[5726a0d]873    if (file_contents == NULL)
[782a6ee]874        return NULL;
875    output_value = json_parse_string_with_comments(file_contents);
876    PARSON_FREE(file_contents);
877    return output_value;
878}
879
[989f431]880JSON_Value * json_parse_first(const char *string, const char **end) {
881    const char *pos;
882    JSON_Value *ret;
883
[5726a0d]884    if (string == NULL)
[782a6ee]885        return NULL;
886    SKIP_WHITESPACES(&string);
887    if (*string != '{' && *string != '[')
888        return NULL;
[989f431]889
890    pos = string;
891    ret = parse_value(&pos, 0);
892    if (end)
893        *end = pos;
894
895    return ret;
896}
897
898JSON_Value * json_parse_string(const char *string) {
899    return json_parse_first(string, NULL);
[782a6ee]900}
901
902JSON_Value * json_parse_string_with_comments(const char *string) {
903    JSON_Value *result = NULL;
904    char *string_mutable_copy = NULL, *string_mutable_copy_ptr = NULL;
905    string_mutable_copy = parson_strdup(string);
[5726a0d]906    if (string_mutable_copy == NULL)
[782a6ee]907        return NULL;
908    remove_comments(string_mutable_copy, "/*", "*/");
909    remove_comments(string_mutable_copy, "//", "\n");
910    string_mutable_copy_ptr = string_mutable_copy;
911    SKIP_WHITESPACES(&string_mutable_copy_ptr);
912    if (*string_mutable_copy_ptr != '{' && *string_mutable_copy_ptr != '[') {
913        PARSON_FREE(string_mutable_copy);
914        return NULL;
915    }
916    result = parse_value((const char**)&string_mutable_copy_ptr, 0);
917    PARSON_FREE(string_mutable_copy);
918    return result;
919}
920
921
922/* JSON Object API */
923
924JSON_Value * json_object_get_value(const JSON_Object *object, const char *name) {
[5726a0d]925    if (object == NULL || name == NULL)
926        return NULL;
[782a6ee]927    return json_object_nget_value(object, name, strlen(name));
928}
929
930const char * json_object_get_string(const JSON_Object *object, const char *name) {
931    return json_value_get_string(json_object_get_value(object, name));
932}
933
[8563fe7]934jint json_object_get_integer(const JSON_Object *object, const char *name) {
935    return json_value_get_integer(json_object_get_value(object, name));
936}
937
[782a6ee]938double json_object_get_number(const JSON_Object *object, const char *name) {
939    return json_value_get_number(json_object_get_value(object, name));
940}
941
942JSON_Object * json_object_get_object(const JSON_Object *object, const char *name) {
943    return json_value_get_object(json_object_get_value(object, name));
944}
945
946JSON_Array * json_object_get_array(const JSON_Object *object, const char *name) {
947    return json_value_get_array(json_object_get_value(object, name));
948}
949
950int json_object_get_boolean(const JSON_Object *object, const char *name) {
951    return json_value_get_boolean(json_object_get_value(object, name));
952}
953
954JSON_Value * json_object_dotget_value(const JSON_Object *object, const char *name) {
955    const char *dot_position = strchr(name, '.');
956    if (!dot_position)
957        return json_object_get_value(object, name);
958    object = json_value_get_object(json_object_nget_value(object, name, dot_position - name));
959    return json_object_dotget_value(object, dot_position + 1);
960}
961
962const char * json_object_dotget_string(const JSON_Object *object, const char *name) {
963    return json_value_get_string(json_object_dotget_value(object, name));
964}
965
[8563fe7]966jint json_object_dotget_integer(const JSON_Object *object, const char *name) {
967    return json_value_get_integer(json_object_dotget_value(object, name));
968}
969
[782a6ee]970double json_object_dotget_number(const JSON_Object *object, const char *name) {
971    return json_value_get_number(json_object_dotget_value(object, name));
972}
973
974JSON_Object * json_object_dotget_object(const JSON_Object *object, const char *name) {
975    return json_value_get_object(json_object_dotget_value(object, name));
976}
977
978JSON_Array * json_object_dotget_array(const JSON_Object *object, const char *name) {
979    return json_value_get_array(json_object_dotget_value(object, name));
980}
981
982int json_object_dotget_boolean(const JSON_Object *object, const char *name) {
983    return json_value_get_boolean(json_object_dotget_value(object, name));
984}
985
986size_t json_object_get_count(const JSON_Object *object) {
987    return object ? object->count : 0;
988}
989
990const char * json_object_get_name(const JSON_Object *object, size_t index) {
991    if (index >= json_object_get_count(object))
992        return NULL;
993    return object->names[index];
994}
995
[ee170a1]996int json_object_get_tuple(const JSON_Object *object, size_t index,
997                          const char **key, const JSON_Value **value) {
998    if (index >= json_object_get_count(object))
999        return 0;
1000    *key = object->names[index];
1001    *value = object->values[index];
1002    return 1;
1003}
1004
[782a6ee]1005/* JSON Array API */
1006JSON_Value * json_array_get_value(const JSON_Array *array, size_t index) {
1007    if (index >= json_array_get_count(array))
1008        return NULL;
1009    return array->items[index];
1010}
1011
1012const char * json_array_get_string(const JSON_Array *array, size_t index) {
1013    return json_value_get_string(json_array_get_value(array, index));
1014}
1015
[8563fe7]1016jint json_array_get_integer(const JSON_Array *array, size_t index) {
1017    return json_value_get_integer(json_array_get_value(array, index));
1018}
1019
[782a6ee]1020double json_array_get_number(const JSON_Array *array, size_t index) {
1021    return json_value_get_number(json_array_get_value(array, index));
1022}
1023
1024JSON_Object * json_array_get_object(const JSON_Array *array, size_t index) {
1025    return json_value_get_object(json_array_get_value(array, index));
1026}
1027
1028JSON_Array * json_array_get_array(const JSON_Array *array, size_t index) {
1029    return json_value_get_array(json_array_get_value(array, index));
1030}
1031
1032int json_array_get_boolean(const JSON_Array *array, size_t index) {
1033    return json_value_get_boolean(json_array_get_value(array, index));
1034}
1035
1036size_t json_array_get_count(const JSON_Array *array) {
1037    return array ? array->count : 0;
1038}
1039
1040/* JSON Value API */
1041JSON_Value_Type json_value_get_type(const JSON_Value *value) {
1042    return value ? value->type : JSONError;
1043}
1044
1045JSON_Object * json_value_get_object(const JSON_Value *value) {
1046    return json_value_get_type(value) == JSONObject ? value->value.object : NULL;
1047}
1048
1049JSON_Array * json_value_get_array(const JSON_Value *value) {
1050    return json_value_get_type(value) == JSONArray ? value->value.array : NULL;
1051}
1052
1053const char * json_value_get_string(const JSON_Value *value) {
1054    return json_value_get_type(value) == JSONString ? value->value.string : NULL;
1055}
1056
[8563fe7]1057jint json_value_get_integer(const JSON_Value *value) {
1058    if (json_value_get_type(value) == JSONNumber) {
1059        return value->value.number;
1060    } else if (json_value_get_type(value) == JSONInteger) {
1061        return value->value.integer;
1062    } else {
1063        return 0;
1064    }
1065}
1066
[782a6ee]1067double json_value_get_number(const JSON_Value *value) {
[8563fe7]1068    if (json_value_get_type(value) == JSONNumber) {
1069        return value->value.number;
1070    } else if (json_value_get_type(value) == JSONInteger) {
1071        return value->value.integer;
1072    } else {
1073        return 0;
1074    }
[782a6ee]1075}
1076
1077int json_value_get_boolean(const JSON_Value *value) {
1078    return json_value_get_type(value) == JSONBoolean ? value->value.boolean : -1;
1079}
1080
1081void json_value_free(JSON_Value *value) {
1082    switch (json_value_get_type(value)) {
1083        case JSONObject:
1084            json_object_free(value->value.object);
1085            break;
1086        case JSONString:
1087            if (value->value.string) { PARSON_FREE(value->value.string); }
1088            break;
1089        case JSONArray:
1090            json_array_free(value->value.array);
1091            break;
1092        default:
1093            break;
1094    }
1095    PARSON_FREE(value);
1096}
1097
1098JSON_Value * json_value_init_object(void) {
1099    JSON_Value *new_value = (JSON_Value*)PARSON_MALLOC(sizeof(JSON_Value));
1100    if (!new_value)
1101        return NULL;
1102    new_value->type = JSONObject;
1103    new_value->value.object = json_object_init();
1104    if (!new_value->value.object) {
1105        PARSON_FREE(new_value);
1106        return NULL;
1107    }
1108    return new_value;
1109}
1110
1111JSON_Value * json_value_init_array(void) {
1112    JSON_Value *new_value = (JSON_Value*)PARSON_MALLOC(sizeof(JSON_Value));
1113    if (!new_value)
1114        return NULL;
1115    new_value->type = JSONArray;
1116    new_value->value.array = json_array_init();
1117    if (!new_value->value.array) {
1118        PARSON_FREE(new_value);
1119        return NULL;
1120    }
1121    return new_value;
1122}
1123
1124JSON_Value * json_value_init_string(const char *string) {
[5726a0d]1125    char *copy = NULL;
1126    JSON_Value *value;
1127    size_t string_len = 0;
1128    if (string == NULL)
1129        return NULL;
1130    string_len = strlen(string);
1131    if (!is_valid_utf8(string, string_len))
[782a6ee]1132        return NULL;
[5726a0d]1133    copy = parson_strndup(string, string_len);
1134    if (copy == NULL)
1135        return NULL;
1136    value = json_value_init_string_no_copy(copy);
1137    if (value == NULL)
1138        PARSON_FREE(copy);
1139    return value;
[782a6ee]1140}
1141
[8563fe7]1142JSON_Value * json_value_init_integer(jint number) {
1143    JSON_Value *new_value = (JSON_Value*)PARSON_MALLOC(sizeof(JSON_Value));
1144    if (!new_value)
1145        return NULL;
1146    new_value->type = JSONInteger;
1147    new_value->value.integer = number;
1148    return new_value;
1149}
1150
[782a6ee]1151JSON_Value * json_value_init_number(double number) {
1152    JSON_Value *new_value = (JSON_Value*)PARSON_MALLOC(sizeof(JSON_Value));
1153    if (!new_value)
1154        return NULL;
1155    new_value->type = JSONNumber;
1156    new_value->value.number = number;
1157    return new_value;
1158}
1159
1160JSON_Value * json_value_init_boolean(int boolean) {
1161    JSON_Value *new_value = (JSON_Value*)PARSON_MALLOC(sizeof(JSON_Value));
1162    if (!new_value)
1163        return NULL;
1164    new_value->type = JSONBoolean;
1165    new_value->value.boolean = boolean ? 1 : 0;
1166    return new_value;
1167}
1168
1169JSON_Value * json_value_init_null(void) {
1170    JSON_Value *new_value = (JSON_Value*)PARSON_MALLOC(sizeof(JSON_Value));
1171    if (!new_value)
1172        return NULL;
1173    new_value->type = JSONNull;
1174    return new_value;
1175}
1176
1177JSON_Value * json_value_deep_copy(const JSON_Value *value) {
1178    size_t i = 0;
1179    JSON_Value *return_value = NULL, *temp_value_copy = NULL, *temp_value = NULL;
1180    const char *temp_string = NULL, *temp_string_copy = NULL, *temp_key = NULL;
1181    JSON_Array *temp_array = NULL, *temp_array_copy = NULL;
1182    JSON_Object *temp_object = NULL, *temp_object_copy = NULL;
1183   
1184    switch (json_value_get_type(value)) {
1185        case JSONArray:
1186            temp_array = json_value_get_array(value);
1187            return_value = json_value_init_array();
1188            if (return_value == NULL)
1189                return NULL;
1190            temp_array_copy = json_value_get_array(return_value);
1191            for (i = 0; i < json_array_get_count(temp_array); i++) {
1192                temp_value = json_array_get_value(temp_array, i);
1193                temp_value_copy = json_value_deep_copy(temp_value);
1194                if (temp_value_copy == NULL) {
1195                    json_value_free(return_value);
1196                    return NULL;
1197                }
1198                if (json_array_add(temp_array_copy, temp_value_copy) == JSONFailure) {
1199                    json_value_free(return_value);
1200                    json_value_free(temp_value_copy);
1201                    return NULL;
1202                }
1203            }
1204            return return_value;
1205        case JSONObject:
1206            temp_object = json_value_get_object(value);
1207            return_value = json_value_init_object();
1208            if (return_value == NULL)
1209                return NULL;
1210            temp_object_copy = json_value_get_object(return_value);
1211            for (i = 0; i < json_object_get_count(temp_object); i++) {
1212                temp_key = json_object_get_name(temp_object, i);
1213                temp_value = json_object_get_value(temp_object, temp_key);
1214                temp_value_copy = json_value_deep_copy(temp_value);
1215                if (temp_value_copy == NULL) {
1216                    json_value_free(return_value);
1217                    return NULL;
1218                }
1219                if (json_object_add(temp_object_copy, temp_key, temp_value_copy) == JSONFailure) {
1220                    json_value_free(return_value);
1221                    json_value_free(temp_value_copy);
1222                    return NULL;
1223                }
1224            }
1225            return return_value;
1226        case JSONBoolean:
1227            return json_value_init_boolean(json_value_get_boolean(value));
1228        case JSONNumber:
1229            return json_value_init_number(json_value_get_number(value));
1230        case JSONString:
1231            temp_string = json_value_get_string(value);
1232            temp_string_copy = parson_strdup(temp_string);
1233            if (temp_string_copy == NULL)
1234                return NULL;
[5726a0d]1235            return_value = json_value_init_string_no_copy(temp_string_copy);
1236            if (return_value == NULL)
1237                PARSON_FREE(temp_string_copy);
1238            return return_value;
[782a6ee]1239        case JSONNull:
1240            return json_value_init_null();
1241        case JSONError:
1242            return NULL;
1243        default:
1244            return NULL;
1245    }
1246}
1247
1248size_t json_serialization_size(const JSON_Value *value) {
1249    char buf[1100]; /* recursively allocating buffer on stack is a bad idea, so let's do it only once */
1250    return json_serialization_size_r(value, buf) + 1;
1251}
1252
1253JSON_Status json_serialize_to_buffer(const JSON_Value *value, char *buf, size_t buf_size_in_bytes) {
1254    char *serialization_result = NULL;
1255    size_t needed_size_in_bytes = json_serialization_size(value);
1256    if (buf_size_in_bytes < needed_size_in_bytes) {
1257        return JSONFailure;
1258    }
1259    serialization_result = json_serialize_to_buffer_r(value, buf);
1260    if(serialization_result == NULL)
1261        return JSONFailure;
1262    return JSONSuccess;
1263}
1264
1265JSON_Status json_serialize_to_file(const JSON_Value *value, const char *filename) {
1266    JSON_Status return_code = JSONSuccess;
1267    FILE *fp = NULL;
1268    char *serialized_string = json_serialize_to_string(value);
1269    if (serialized_string == NULL) {
1270        return JSONFailure;
1271    }
1272    fp = fopen (filename, "w");
1273    if (fp != NULL) {
1274        if (fputs (serialized_string, fp) == EOF) {
1275            return_code = JSONFailure;
1276        }
1277        if (fclose (fp) == EOF) {
1278            return_code = JSONFailure;
1279        }
1280    }
1281    json_free_serialized_string(serialized_string);
1282    return return_code;
1283}
1284
1285char * json_serialize_to_string(const JSON_Value *value) {
1286    JSON_Status serialization_result = JSONFailure;
1287    size_t buf_size_bytes = json_serialization_size(value);
1288    char *buf = (char*)PARSON_MALLOC(buf_size_bytes);
1289    if (buf == NULL)
1290        return NULL;
1291    serialization_result = json_serialize_to_buffer(value, buf, buf_size_bytes);
1292    if (serialization_result == JSONFailure) {
1293        json_free_serialized_string(buf);
1294        return NULL;
1295    }
1296    return buf;
1297}
1298
1299void json_free_serialized_string(char *string) {
1300    PARSON_FREE(string);
1301}
1302
1303JSON_Status json_array_remove(JSON_Array *array, size_t ix) {
1304    size_t last_element_ix = 0;
1305    if (array == NULL || ix >= json_array_get_count(array)) {
1306        return JSONFailure;
1307    }
1308    last_element_ix = json_array_get_count(array) - 1;
1309    json_value_free(json_array_get_value(array, ix));
1310    array->count -= 1;
1311    if (ix != last_element_ix) /* Replace value with one from the end of array */
1312        array->items[ix] = json_array_get_value(array, last_element_ix);
1313    return JSONSuccess;
1314}
1315
1316JSON_Status json_array_replace_value(JSON_Array *array, size_t ix, JSON_Value *value) {
1317    if (array == NULL || value == NULL || ix >= json_array_get_count(array)) {
1318        return JSONFailure;
1319    }
1320    json_value_free(json_array_get_value(array, ix));
1321    array->items[ix] = value;
1322    return JSONSuccess;
1323}
1324
1325JSON_Status json_array_replace_string(JSON_Array *array, size_t i, const char* string) {
[5726a0d]1326    JSON_Value *value = json_value_init_string(string);
1327    if (value == NULL)
1328        return JSONFailure;
1329    if (json_array_replace_value(array, i, value) == JSONFailure) {
1330        json_value_free(value);
1331        return JSONFailure;
1332    }
1333    return JSONSuccess;
[782a6ee]1334}
1335
[8563fe7]1336JSON_Status json_array_replace_integer(JSON_Array *array, size_t i, jint integer) {
1337    JSON_Value *value = json_value_init_integer(integer);
1338    if (value == NULL)
1339        return JSONFailure;
1340    if (json_array_replace_value(array, i, value) == JSONFailure) {
1341        json_value_free(value);
1342        return JSONFailure;
1343    }
1344    return JSONSuccess;
1345}
1346
[782a6ee]1347JSON_Status json_array_replace_number(JSON_Array *array, size_t i, double number) {
[5726a0d]1348    JSON_Value *value = json_value_init_number(number);
1349    if (value == NULL)
1350        return JSONFailure;
1351    if (json_array_replace_value(array, i, value) == JSONFailure) {
1352        json_value_free(value);
1353        return JSONFailure;
1354    }
1355    return JSONSuccess;
[782a6ee]1356}
1357
1358JSON_Status json_array_replace_boolean(JSON_Array *array, size_t i, int boolean) {
[5726a0d]1359    JSON_Value *value = json_value_init_boolean(boolean);
1360    if (value == NULL)
1361        return JSONFailure;
1362    if (json_array_replace_value(array, i, value) == JSONFailure) {
1363        json_value_free(value);
1364        return JSONFailure;
1365    }
1366    return JSONSuccess;
[782a6ee]1367}
1368
1369JSON_Status json_array_replace_null(JSON_Array *array, size_t i) {
[5726a0d]1370    JSON_Value *value = json_value_init_null();
1371    if (value == NULL)
1372        return JSONFailure;
1373    if (json_array_replace_value(array, i, value) == JSONFailure) {
1374        json_value_free(value);
1375        return JSONFailure;
1376    }
1377    return JSONSuccess;
[782a6ee]1378}
1379
1380JSON_Status json_array_clear(JSON_Array *array) {
1381    size_t i = 0;
1382    if (array == NULL)
1383        return JSONFailure;
1384    for (i = 0; i < json_array_get_count(array); i++) {
1385        json_value_free(json_array_get_value(array, i));
1386    }
1387    array->count = 0;
1388    return JSONSuccess;
1389}
1390
1391JSON_Status json_array_append_value(JSON_Array *array, JSON_Value *value) {
1392    if (array == NULL || value == NULL)
1393        return JSONFailure;
1394    return json_array_add(array, value);
1395}
1396
1397JSON_Status json_array_append_string(JSON_Array *array, const char *string) {
[5726a0d]1398    JSON_Value *value = json_value_init_string(string);
1399    if (value == NULL)
1400        return JSONFailure;
1401    if (json_array_append_value(array, value) == JSONFailure) {
1402        json_value_free(value);
1403        return JSONFailure;
1404    }
1405    return JSONSuccess;
[782a6ee]1406}
1407
[8563fe7]1408JSON_Status json_array_append_integer(JSON_Array *array, jint integer) {
1409    JSON_Value *value = json_value_init_integer(integer);
1410    if (value == NULL)
1411        return JSONFailure;
1412    if (json_array_append_value(array, value) == JSONFailure) {
1413        json_value_free(value);
1414        return JSONFailure;
1415    }
1416    return JSONSuccess;
1417}
1418
[782a6ee]1419JSON_Status json_array_append_number(JSON_Array *array, double number) {
[5726a0d]1420    JSON_Value *value = json_value_init_number(number);
1421    if (value == NULL)
1422        return JSONFailure;
1423    if (json_array_append_value(array, value) == JSONFailure) {
1424        json_value_free(value);
1425        return JSONFailure;
1426    }
1427    return JSONSuccess;
[782a6ee]1428}
1429
1430JSON_Status json_array_append_boolean(JSON_Array *array, int boolean) {
[5726a0d]1431    JSON_Value *value = json_value_init_boolean(boolean);
1432    if (value == NULL)
1433        return JSONFailure;
1434    if (json_array_append_value(array, value) == JSONFailure) {
1435        json_value_free(value);
1436        return JSONFailure;
1437    }
1438    return JSONSuccess;
[782a6ee]1439}
1440
1441JSON_Status json_array_append_null(JSON_Array *array) {
[5726a0d]1442    JSON_Value *value = json_value_init_null();
1443    if (value == NULL)
1444        return JSONFailure;
1445    if (json_array_append_value(array, value) == JSONFailure) {
1446        json_value_free(value);
1447        return JSONFailure;
1448    }
1449    return JSONSuccess;
[782a6ee]1450}
1451
1452JSON_Status json_object_set_value(JSON_Object *object, const char *name, JSON_Value *value) {
1453    size_t i = 0;
1454    JSON_Value *old_value;
[5726a0d]1455    if (object == NULL || name == NULL || value == NULL)
[782a6ee]1456        return JSONFailure;
1457    old_value = json_object_get_value(object, name);
1458    if (old_value != NULL) { /* free and overwrite old value */
1459        json_value_free(old_value);
1460        for (i = 0; i < json_object_get_count(object); i++) {
1461            if (strcmp(object->names[i], name) == 0) {
1462                object->values[i] = value;
1463                return JSONSuccess;
1464            }
1465        }
1466    }
[5726a0d]1467    /* add new key value pair */
1468    return json_object_add(object, name, value);
[782a6ee]1469}
1470
1471JSON_Status json_object_set_string(JSON_Object *object, const char *name, const char *string) {
1472    return json_object_set_value(object, name, json_value_init_string(string));
1473}
1474
[8563fe7]1475JSON_Status json_object_set_integer(JSON_Object *object, const char *name, jint integer) {
1476    return json_object_set_value(object, name, json_value_init_integer(integer));
1477}
1478
[782a6ee]1479JSON_Status json_object_set_number(JSON_Object *object, const char *name, double number) {
1480    return json_object_set_value(object, name, json_value_init_number(number));
1481}
1482
1483JSON_Status json_object_set_boolean(JSON_Object *object, const char *name, int boolean) {
1484    return json_object_set_value(object, name, json_value_init_boolean(boolean));
1485}
1486
1487JSON_Status json_object_set_null(JSON_Object *object, const char *name) {
1488    return json_object_set_value(object, name, json_value_init_null());
1489}
1490
1491JSON_Status json_object_dotset_value(JSON_Object *object, const char *name, JSON_Value *value) {
[5726a0d]1492    const char *dot_pos = NULL;
[782a6ee]1493    const char *current_name = NULL;
1494    JSON_Object *temp_obj = NULL;
1495    JSON_Value *new_value = NULL;
[5726a0d]1496    if (value == NULL || name == NULL || value == NULL)
[782a6ee]1497        return JSONFailure;
[5726a0d]1498    dot_pos = strchr(name, '.');
1499    if (dot_pos == NULL) {
[782a6ee]1500        return json_object_set_value(object, name, value);
1501    } else {
1502        current_name = parson_strndup(name, dot_pos - name);
1503        temp_obj = json_object_get_object(object, current_name);
1504        if (temp_obj == NULL) {
1505            new_value = json_value_init_object();
1506            if (new_value == NULL) {
1507                PARSON_FREE(current_name);
1508                return JSONFailure;
1509            }
1510            if (json_object_add(object, current_name, new_value) == JSONFailure) {
1511                json_value_free(new_value);
1512                PARSON_FREE(current_name);
1513                return JSONFailure;
1514            }
1515            temp_obj = json_object_get_object(object, current_name);
1516        }
1517        PARSON_FREE(current_name);
1518        return json_object_dotset_value(temp_obj, dot_pos + 1, value);
1519    }
1520}
1521
1522JSON_Status json_object_dotset_string(JSON_Object *object, const char *name, const char *string) {
[5726a0d]1523    JSON_Value *value = json_value_init_string(string);
1524    if (value == NULL)
1525        return JSONFailure;
1526    if (json_object_dotset_value(object, name, value) == JSONFailure) {
1527        json_value_free(value);
1528        return JSONFailure;
1529    }
1530    return JSONSuccess;
[782a6ee]1531}
1532
[8563fe7]1533JSON_Status json_object_dotset_integer(JSON_Object *object, const char *name, jint integer) {
1534    JSON_Value *value = json_value_init_integer(integer);
1535    if (value == NULL)
1536        return JSONFailure;
1537    if (json_object_dotset_value(object, name, value) == JSONFailure) {
1538        json_value_free(value);
1539        return JSONFailure;
1540    }
1541    return JSONSuccess;
1542}
1543
[782a6ee]1544JSON_Status json_object_dotset_number(JSON_Object *object, const char *name, double number) {
[5726a0d]1545    JSON_Value *value = json_value_init_number(number);
1546    if (value == NULL)
1547        return JSONFailure;
1548    if (json_object_dotset_value(object, name, value) == JSONFailure) {
1549        json_value_free(value);
1550        return JSONFailure;
1551    }
1552    return JSONSuccess;
[782a6ee]1553}
1554
1555JSON_Status json_object_dotset_boolean(JSON_Object *object, const char *name, int boolean) {
[5726a0d]1556    JSON_Value *value = json_value_init_boolean(boolean);
1557    if (value == NULL)
1558        return JSONFailure;
1559    if (json_object_dotset_value(object, name, value) == JSONFailure) {
1560        json_value_free(value);
1561        return JSONFailure;
1562    }
1563    return JSONSuccess;
[782a6ee]1564}
1565
1566JSON_Status json_object_dotset_null(JSON_Object *object, const char *name) {
[5726a0d]1567    JSON_Value *value = json_value_init_null();
1568    if (value == NULL)
1569        return JSONFailure;
1570    if (json_object_dotset_value(object, name, value) == JSONFailure) {
1571        json_value_free(value);
1572        return JSONFailure;
1573    }
1574    return JSONSuccess;
[782a6ee]1575}
1576
1577JSON_Status json_object_remove(JSON_Object *object, const char *name) {
1578    size_t i = 0, last_item_index = 0;
1579    if (object == NULL || json_object_get_value(object, name) == NULL)
1580        return JSONFailure;
1581    last_item_index = json_object_get_count(object) - 1;
1582    for (i = 0; i < json_object_get_count(object); i++) {
1583        if (strcmp(object->names[i], name) == 0) {
1584            PARSON_FREE(object->names[i]);
1585            json_value_free(object->values[i]);
1586            if (i != last_item_index) { /* Replace key value pair with one from the end */
1587                object->names[i] = object->names[last_item_index];
1588                object->values[i] = object->values[last_item_index];
1589            }
1590            object->count -= 1;
1591            return JSONSuccess;
1592        }
1593    }
1594    return JSONFailure; /* No execution path should end here */
1595}
1596
1597JSON_Status json_object_dotremove(JSON_Object *object, const char *name) {
1598    const char *dot_pos = strchr(name, '.');
1599    const char *current_name = NULL;
1600    JSON_Object *temp_obj = NULL;
1601    if (dot_pos == NULL) {
1602        return json_object_remove(object, name);
1603    } else {
1604        current_name = parson_strndup(name, dot_pos - name);
1605        temp_obj = json_object_get_object(object, current_name);
1606        if (temp_obj == NULL) {
1607            PARSON_FREE(current_name);
1608            return JSONFailure;
1609        }
1610        PARSON_FREE(current_name);
1611        return json_object_dotremove(temp_obj, dot_pos + 1);
1612    }
1613}
1614
1615JSON_Status json_object_clear(JSON_Object *object) {
1616    size_t i = 0;
1617    if (object == NULL) {
1618        return JSONFailure;
1619    }
1620    for (i = 0; i < json_object_get_count(object); i++) {       
1621        PARSON_FREE(object->names[i]);
1622        json_value_free(object->values[i]);
1623    }
1624    object->count = 0;
1625    return JSONSuccess;
1626}
1627
1628JSON_Status json_validate(const JSON_Value *schema, const JSON_Value *value) {
1629    JSON_Value *temp_schema_value = NULL, *temp_value = NULL;
1630    JSON_Array *schema_array = NULL, *value_array = NULL;
1631    JSON_Object *schema_object = NULL, *value_object = NULL;
1632    JSON_Value_Type schema_type = JSONError, value_type = JSONError;
1633    const char *key = NULL;
1634    size_t i = 0, count = 0;
1635    if (schema == NULL || value == NULL)
1636        return JSONFailure;
1637    schema_type = json_value_get_type(schema);
1638    value_type = json_value_get_type(value);
1639    if (schema_type != value_type && schema_type != JSONNull) /* null represents all values */
1640        return JSONFailure;
1641    switch (schema_type) {
1642        case JSONArray:
1643            schema_array = json_value_get_array(schema);
1644            value_array = json_value_get_array(value);
1645            count = json_array_get_count(schema_array);
1646            if (count == 0)
1647                return JSONSuccess; /* Empty array allows all types */
1648            /* Get first value from array, rest is ignored */
1649            temp_schema_value = json_array_get_value(schema_array, 0);
1650            for (i = 0; i < json_array_get_count(value_array); i++) {
1651                temp_value = json_array_get_value(value_array, i);
1652                if (json_validate(temp_schema_value, temp_value) == 0) {
1653                    return JSONFailure;
1654                }
1655            }
1656            return JSONSuccess;
1657        case JSONObject:
1658            schema_object = json_value_get_object(schema);
1659            value_object = json_value_get_object(value);
1660            count = json_object_get_count(schema_object);
1661            if (count == 0)
1662                return JSONSuccess; /* Empty object allows all objects */
1663            else if (json_object_get_count(value_object) < count)
1664                return JSONFailure; /* Tested object mustn't have less name-value pairs than schema */
1665            for (i = 0; i < count; i++) {
1666                key = json_object_get_name(schema_object, i);
1667                temp_schema_value = json_object_get_value(schema_object, key);
1668                temp_value = json_object_get_value(value_object, key);
1669                if (temp_value == NULL)
1670                    return JSONFailure;
1671                if (json_validate(temp_schema_value, temp_value) == JSONFailure)
1672                    return JSONFailure;
1673            }
1674            return JSONSuccess;
1675        case JSONString: case JSONNumber: case JSONBoolean: case JSONNull:
1676            return JSONSuccess; /* equality already tested before switch */
1677        case JSONError: default:
1678            return JSONFailure;
1679    }
1680}
1681
1682JSON_Status json_value_equals(const JSON_Value *a, const JSON_Value *b) {
1683    JSON_Object *a_object = NULL, *b_object = NULL;
1684    JSON_Array *a_array = NULL, *b_array = NULL;
1685    const char *a_string = NULL, *b_string = NULL;
1686    const char *key = NULL;
1687    size_t a_count = 0, b_count = 0, i = 0;
1688    JSON_Value_Type a_type, b_type;
1689    a_type = json_value_get_type(a);
1690    b_type = json_value_get_type(b);
1691    if (a_type != b_type) {
1692        return 0;
1693    }
1694    switch (a_type) {
1695        case JSONArray:
1696            a_array = json_value_get_array(a);
1697            b_array = json_value_get_array(b);
1698            a_count = json_array_get_count(a_array);
1699            b_count = json_array_get_count(b_array);
1700            if (a_count != b_count) {
1701                return 0;
1702            }
1703            for (i = 0; i < a_count; i++) {
1704                if (!json_value_equals(json_array_get_value(a_array, i),
1705                                       json_array_get_value(b_array, i))) {
1706                    return 0;
1707                }
1708            }
1709            return 1;
1710        case JSONObject:
1711            a_object = json_value_get_object(a);
1712            b_object = json_value_get_object(b);
1713            a_count = json_object_get_count(a_object);
1714            b_count = json_object_get_count(b_object);
1715            if (a_count != b_count) {
1716                return 0;
1717            }
1718            for (i = 0; i < a_count; i++) {
1719                key = json_object_get_name(a_object, i);
1720                if (!json_value_equals(json_object_get_value(a_object, key),
1721                                       json_object_get_value(b_object, key))) {
1722                    return 0;
1723                }
1724            }
1725            return 1;
1726        case JSONString:
1727            a_string = json_value_get_string(a);
1728            b_string = json_value_get_string(b);
1729            return strcmp(a_string, b_string) == 0;
1730        case JSONBoolean:
1731            return json_value_get_boolean(a) == json_value_get_boolean(b);
1732        case JSONNumber:
1733            return fabs(json_value_get_number(a) - json_value_get_number(b)) < 0.000001; /* EPSILON */
1734        case JSONError:
1735            return 1;
1736        case JSONNull:
1737            return 1;
1738        default:
1739            return 1;
1740    }
1741}
1742
1743JSON_Value_Type json_type(const JSON_Value *value) {
1744    return json_value_get_type(value);
1745}
1746
1747JSON_Object * json_object (const JSON_Value *value) {
1748    return json_value_get_object(value);
1749}
1750
1751JSON_Array * json_array  (const JSON_Value *value) {
1752    return json_value_get_array(value);
1753}
1754
1755const char * json_string (const JSON_Value *value) {
1756    return json_value_get_string(value);
1757}
1758
[8563fe7]1759jint json_integer (const JSON_Value *value) {
1760    return json_value_get_integer(value);
1761}
1762
[782a6ee]1763double json_number (const JSON_Value *value) {
1764    return json_value_get_number(value);
1765}
1766
1767int json_boolean(const JSON_Value *value) {
1768    return json_value_get_boolean(value);
1769}
Note: See TracBrowser for help on using the repository browser.