source: lib/parson.c @ 63cad66

Last change on this file since 63cad66 was 199d51c, checked in by Wilmer van der Gaast <wilmer@…>, at 2015-05-09T10:30:50Z

Remove duplicate jint typedef.

  • Property mode set to 100644
File size: 60.3 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
[782a6ee]57/* Type definitions */
58typedef union json_value_value {
59    const char  *string;
60    double       number;
[8563fe7]61    jint         integer;
[782a6ee]62    JSON_Object *object;
63    JSON_Array  *array;
64    int          boolean;
65    int          null;
66} JSON_Value_Value;
67
68struct json_value_t {
69    JSON_Value_Type     type;
70    JSON_Value_Value    value;
71};
72
73struct json_object_t {
74    const char **names;
75    JSON_Value **values;
76    size_t       count;
77    size_t       capacity;
78};
79
80struct json_array_t {
81    JSON_Value **items;
82    size_t       count;
83    size_t       capacity;
84};
85
86/* Various */
87static char * read_file(const char *filename);
88static void   remove_comments(char *string, const char *start_token, const char *end_token);
89static int    try_realloc(void **ptr, size_t new_size);
90static char * parson_strndup(const char *string, size_t n);
91static char * parson_strdup(const char *string);
[5726a0d]92static int    is_utf16_hex(const unsigned char *string);
93static int    num_bytes_in_utf8_sequence(unsigned char c);
94static int    verify_utf8_sequence(const unsigned char *string, int *len);
95static int    is_valid_utf8(const char *string, size_t string_len);
[782a6ee]96static int    is_decimal(const char *string, size_t length);
[5726a0d]97static size_t serialization_strlen(const char *string);
[782a6ee]98
99/* JSON Object */
100static JSON_Object * json_object_init(void);
101static JSON_Status   json_object_add(JSON_Object *object, const char *name, JSON_Value *value);
102static JSON_Status   json_object_resize(JSON_Object *object, size_t capacity);
103static JSON_Value  * json_object_nget_value(const JSON_Object *object, const char *name, size_t n);
104static void          json_object_free(JSON_Object *object);
105
106/* JSON Array */
107static JSON_Array * json_array_init(void);
108static JSON_Status  json_array_add(JSON_Array *array, JSON_Value *value);
109static JSON_Status  json_array_resize(JSON_Array *array, size_t capacity);
110static void         json_array_free(JSON_Array *array);
111
112/* JSON Value */
113static JSON_Value * json_value_init_string_no_copy(const char *string);
114
115/* Parser */
116static void         skip_quotes(const char **string);
117static int          parse_utf_16(const char **unprocessed, char **processed);
118static char*        process_string(const char *input, size_t len);
119static const char * get_quoted_string(const char **string);
120static JSON_Value * parse_object_value(const char **string, size_t nesting);
121static JSON_Value * parse_array_value(const char **string, size_t nesting);
122static JSON_Value * parse_string_value(const char **string);
123static JSON_Value * parse_boolean_value(const char **string);
124static JSON_Value * parse_number_value(const char **string);
125static JSON_Value * parse_null_value(const char **string);
126static JSON_Value * parse_value(const char **string, size_t nesting);
127
128/* Serialization */
129static size_t json_serialization_size_r(const JSON_Value *value, char *buf);
130static char * json_serialize_to_buffer_r(const JSON_Value *value, char *buf);
131static char * json_serialize_string(const char *string, char *buf);
132
133/* Various */
134static int try_realloc(void **ptr, size_t new_size) {
135    void *reallocated_ptr = NULL;
136    if (new_size == 0) {
137        return JSONFailure;
138    }
139    reallocated_ptr = PARSON_REALLOC(*ptr, new_size);
140    if (reallocated_ptr == NULL) {
141        return JSONFailure;
142    }
143    *ptr = reallocated_ptr;
144    return JSONSuccess;
145}
146
147static char * parson_strndup(const char *string, size_t n) {
148    char *output_string = (char*)PARSON_MALLOC(n + 1);
149    if (!output_string)
150        return NULL;
151    output_string[n] = '\0';
152    strncpy(output_string, string, n);
153    return output_string;
154}
155
156static char * parson_strdup(const char *string) {
157    return parson_strndup(string, strlen(string));
158}
159
[5726a0d]160static int is_utf16_hex(const unsigned char *s) {
[782a6ee]161    return isxdigit(s[0]) && isxdigit(s[1]) && isxdigit(s[2]) && isxdigit(s[3]);
162}
163
[5726a0d]164static int num_bytes_in_utf8_sequence(unsigned char c) {
165    if (c == 0xC0 || c == 0xC1 || c > 0xF4 || IS_CONT(c)) {
166        return 0;
167    } else if ((c & 0x80) == 0) {    /* 0xxxxxxx */
168        return 1;
169    } else if ((c & 0xE0) == 0xC0) { /* 110xxxxx */
170        return 2;
171    } else if ((c & 0xF0) == 0xE0) { /* 1110xxxx */
172        return 3;
173    } else if ((c & 0xF8) == 0xF0) { /* 11110xxx */
174        return 4;
175    }
176    return 0; /* won't happen */
177}
178
179static int verify_utf8_sequence(const unsigned char *string, int *len) {
180    unsigned int cp = 0;
181    *len = num_bytes_in_utf8_sequence(string[0]);
182   
183    if (*len == 1) {
184        cp = string[0];
185    } else if (*len == 2 && IS_CONT(string[1])) {
186        cp = string[0] & 0x1F;
187        cp = (cp << 6) | (string[1] & 0x3F);
188    } else if (*len == 3 && IS_CONT(string[1]) && IS_CONT(string[2])) {
189        cp = ((unsigned char)string[0]) & 0xF;
190        cp = (cp << 6) | (string[1] & 0x3F);
191        cp = (cp << 6) | (string[2] & 0x3F);
192    } else if (*len == 4 && IS_CONT(string[1]) && IS_CONT(string[2]) && IS_CONT(string[3])) {
193        cp = string[0] & 0x7;
194        cp = (cp << 6) | (string[1] & 0x3F);
195        cp = (cp << 6) | (string[2] & 0x3F);
196        cp = (cp << 6) | (string[3] & 0x3F);
197    } else {
198        return 0;
199    }
200   
201    /* overlong encodings */
202    if ((cp < 0x80    && *len > 1) ||
203        (cp < 0x800   && *len > 2) ||
204        (cp < 0x10000 && *len > 3)) {
205        return 0;
206    }
207   
208    /* invalid unicode */
209    if (cp > 0x10FFFF) {
210        return 0;
211    }
212   
213    /* surrogate halves */
214    if (cp >= 0xD800 && cp <= 0xDFFF) {
215        return 0;
216    }
217   
218    return 1;
219}
220
221static int is_valid_utf8(const char *string, size_t string_len) {
222    int len = 0;
223    const char *string_end =  string + string_len;
224    while (string < string_end) {
225        if (!verify_utf8_sequence((const unsigned char*)string, &len)) {
226            return 0;
227        }
228        string += len;
229    }
230    return 1;
231}
232
[782a6ee]233static int is_decimal(const char *string, size_t length) {
234    if (length > 1 && string[0] == '0' && string[1] != '.')
235        return 0;
236    if (length > 2 && !strncmp(string, "-0", 2) && string[2] != '.')
237        return 0;
238    while (length--)
239        if (strchr("xX", string[length]))
240            return 0;
241    return 1;
242}
243
[5726a0d]244static size_t serialization_strlen(const char *string) {
[782a6ee]245    size_t result = 0;
246    size_t i = 0, len = strlen(string);
247    for (i = 0; i < len; i++) {
248        if (strchr("\"\\\b\f\n\r\t", string[i])) /* must be escaped */
249            result += 2;
250        else
251            result += 1;
252    }
253    return result;
254}
255
256static char * read_file(const char * filename) {
257    FILE *fp = fopen(filename, "r");
258    size_t file_size;
[5726a0d]259    long pos;
[782a6ee]260    char *file_contents;
261    if (!fp)
262        return NULL;
263    fseek(fp, 0L, SEEK_END);
[5726a0d]264    pos = ftell(fp);
265    if (pos < 0) {
266        fclose(fp);
267        return NULL;
268    }
269    file_size = pos;
[782a6ee]270    rewind(fp);
271    file_contents = (char*)PARSON_MALLOC(sizeof(char) * (file_size + 1));
272    if (!file_contents) {
273        fclose(fp);
274        return NULL;
275    }
276    if (fread(file_contents, file_size, 1, fp) < 1) {
277        if (ferror(fp)) {
278            fclose(fp);
279            PARSON_FREE(file_contents);
280            return NULL;
281        }
282    }
283    fclose(fp);
284    file_contents[file_size] = '\0';
285    return file_contents;
286}
287
288static void remove_comments(char *string, const char *start_token, const char *end_token) {
289    int in_string = 0, escaped = 0;
290    size_t i;
291    char *ptr = NULL, current_char;
292    size_t start_token_len = strlen(start_token);
293    size_t end_token_len = strlen(end_token);
294    if (start_token_len == 0 || end_token_len == 0)
295        return;
296    while ((current_char = *string) != '\0') {
297        if (current_char == '\\' && !escaped) {
298            escaped = 1;
299            string++;
300            continue;
301        } else if (current_char == '\"' && !escaped) {
302            in_string = !in_string;
303        } else if (!in_string && strncmp(string, start_token, start_token_len) == 0) {
304                        for(i = 0; i < start_token_len; i++)
305                string[i] = ' ';
306                string = string + start_token_len;
307            ptr = strstr(string, end_token);
308            if (!ptr)
309                return;
310            for (i = 0; i < (ptr - string) + end_token_len; i++)
311                string[i] = ' ';
312                string = ptr + end_token_len - 1;
313        }
314        escaped = 0;
315        string++;
316    }
317}
318
319/* JSON Object */
320static JSON_Object * json_object_init(void) {
321    JSON_Object *new_obj = (JSON_Object*)PARSON_MALLOC(sizeof(JSON_Object));
322    if (!new_obj)
323        return NULL;
324    new_obj->names = (const char**)NULL;
325    new_obj->values = (JSON_Value**)NULL;
326    new_obj->capacity = 0;
327    new_obj->count = 0;
328    return new_obj;
329}
330
331static JSON_Status json_object_add(JSON_Object *object, const char *name, JSON_Value *value) {
[5726a0d]332    size_t index = 0;
333    if (object == NULL || name == NULL || value == NULL) {
334        return JSONFailure;
335    }
[782a6ee]336    if (object->count >= object->capacity) {
337        size_t new_capacity = MAX(object->capacity * 2, STARTING_CAPACITY);
338        if (new_capacity > OBJECT_MAX_CAPACITY)
339            return JSONFailure;
340        if (json_object_resize(object, new_capacity) == JSONFailure)
341            return JSONFailure;
342    }
343    if (json_object_get_value(object, name) != NULL)
344        return JSONFailure;
345    index = object->count;
346    object->names[index] = parson_strdup(name);
[5726a0d]347    if (object->names[index] == NULL)
[782a6ee]348        return JSONFailure;
349    object->values[index] = value;
350    object->count++;
351    return JSONSuccess;
352}
353
354static JSON_Status json_object_resize(JSON_Object *object, size_t capacity) {
355    if (try_realloc((void**)&object->names, capacity * sizeof(char*)) == JSONFailure)
356        return JSONFailure;
357    if (try_realloc((void**)&object->values, capacity * sizeof(JSON_Value*)) == JSONFailure)
358        return JSONFailure;
359    object->capacity = capacity;
360    return JSONSuccess;
361}
362
363static JSON_Value * json_object_nget_value(const JSON_Object *object, const char *name, size_t n) {
364    size_t i, name_length;
365    for (i = 0; i < json_object_get_count(object); i++) {
366        name_length = strlen(object->names[i]);
367        if (name_length != n)
368            continue;
369        if (strncmp(object->names[i], name, n) == 0)
370            return object->values[i];
371    }
372    return NULL;
373}
374
375static void json_object_free(JSON_Object *object) {
376    while(object->count--) {
377        PARSON_FREE(object->names[object->count]);
378        json_value_free(object->values[object->count]);
379    }
380    PARSON_FREE(object->names);
381    PARSON_FREE(object->values);
382    PARSON_FREE(object);
383}
384
385/* JSON Array */
386static JSON_Array * json_array_init(void) {
387    JSON_Array *new_array = (JSON_Array*)PARSON_MALLOC(sizeof(JSON_Array));
388    if (!new_array)
389        return NULL;
390    new_array->items = (JSON_Value**)NULL;
391    new_array->capacity = 0;
392    new_array->count = 0;
393    return new_array;
394}
395
396static JSON_Status json_array_add(JSON_Array *array, JSON_Value *value) {
397    if (array->count >= array->capacity) {
398        size_t new_capacity = MAX(array->capacity * 2, STARTING_CAPACITY);
399        if (new_capacity > ARRAY_MAX_CAPACITY)
400            return JSONFailure;
401        if (json_array_resize(array, new_capacity) == JSONFailure)
402            return JSONFailure;
403    }
404    array->items[array->count] = value;
405    array->count++;
406    return JSONSuccess;
407}
408
409static JSON_Status json_array_resize(JSON_Array *array, size_t capacity) {
410    if (try_realloc((void**)&array->items, capacity * sizeof(JSON_Value*)) == JSONFailure)
411        return JSONFailure;
412    array->capacity = capacity;
413    return JSONSuccess;
414}
415
416static void json_array_free(JSON_Array *array) {
417    while (array->count--)
418        json_value_free(array->items[array->count]);
419    PARSON_FREE(array->items);
420    PARSON_FREE(array);
421}
422
423/* JSON Value */
424static JSON_Value * json_value_init_string_no_copy(const char *string) {
425    JSON_Value *new_value = (JSON_Value*)PARSON_MALLOC(sizeof(JSON_Value));
426    if (!new_value)
427        return NULL;
428    new_value->type = JSONString;
429    new_value->value.string = string;
430    return new_value;
431}
432
433/* Parser */
434static void skip_quotes(const char **string) {
435    SKIP_CHAR(string);
436    while (**string != '\"') {
437        if (**string == '\0')
438            return;
439        if (**string == '\\') {
440            SKIP_CHAR(string);
441            if (**string == '\0')
442                return;
443        }
444        SKIP_CHAR(string);
445    }
446    SKIP_CHAR(string);
447}
448
449static int parse_utf_16(const char **unprocessed, char **processed) {
450    unsigned int cp, lead, trail;
451    char *processed_ptr = *processed;
452    const char *unprocessed_ptr = *unprocessed;
453    unprocessed_ptr++; /* skips u */
[5726a0d]454    if (!is_utf16_hex((const unsigned char*)unprocessed_ptr) || sscanf(unprocessed_ptr, "%4x", &cp) == EOF)
[782a6ee]455            return JSONFailure;
456    if (cp < 0x80) {
457        *processed_ptr = cp; /* 0xxxxxxx */
458    } else if (cp < 0x800) {
459        *processed_ptr++ = ((cp >> 6) & 0x1F) | 0xC0; /* 110xxxxx */
460        *processed_ptr   = ((cp     ) & 0x3F) | 0x80; /* 10xxxxxx */
461    } else if (cp < 0xD800 || cp > 0xDFFF) {
462        *processed_ptr++ = ((cp >> 12) & 0x0F) | 0xE0; /* 1110xxxx */
463        *processed_ptr++ = ((cp >> 6)  & 0x3F) | 0x80; /* 10xxxxxx */
464        *processed_ptr   = ((cp     )  & 0x3F) | 0x80; /* 10xxxxxx */
465    } else if (cp >= 0xD800 && cp <= 0xDBFF) { /* lead surrogate (0xD800..0xDBFF) */
466        lead = cp;
467        unprocessed_ptr += 4; /* should always be within the buffer, otherwise previous sscanf would fail */
468        if (*unprocessed_ptr++ != '\\' || *unprocessed_ptr++ != 'u' || /* starts with \u? */
[5726a0d]469            !is_utf16_hex((const unsigned char*)unprocessed_ptr)          ||
[782a6ee]470            sscanf(unprocessed_ptr, "%4x", &trail) == EOF           ||
471            trail < 0xDC00 || trail > 0xDFFF) { /* valid trail surrogate? (0xDC00..0xDFFF) */
472                return JSONFailure;
473        }
474        cp = ((((lead-0xD800)&0x3FF)<<10)|((trail-0xDC00)&0x3FF))+0x010000;
475        *processed_ptr++ = (((cp >> 18) & 0x07) | 0xF0); /* 11110xxx */
476        *processed_ptr++ = (((cp >> 12) & 0x3F) | 0x80); /* 10xxxxxx */
477        *processed_ptr++ = (((cp >> 6)  & 0x3F) | 0x80); /* 10xxxxxx */
478        *processed_ptr   = (((cp     )  & 0x3F) | 0x80); /* 10xxxxxx */
479    } else { /* trail surrogate before lead surrogate */
480        return JSONFailure;
481    }
482    unprocessed_ptr += 3;
483    *processed = processed_ptr;
484    *unprocessed = unprocessed_ptr;
485    return JSONSuccess;
486}
487
488
489/* Copies and processes passed string up to supplied length.
490Example: "\u006Corem ipsum" -> lorem ipsum */
491static char* process_string(const char *input, size_t len) {
492    const char *input_ptr = input;
493    char *output = (char*)PARSON_MALLOC((len + 1) * sizeof(char));
494    char *output_ptr = output;
495    while ((*input_ptr != '\0') && (size_t)(input_ptr - input) < len) {
496        if (*input_ptr == '\\') {
497            input_ptr++;
498            switch (*input_ptr) {
499                case '\"': *output_ptr = '\"'; break;
500                case '\\': *output_ptr = '\\'; break;
501                case '/':  *output_ptr = '/';  break;
502                case 'b':  *output_ptr = '\b'; break;
503                case 'f':  *output_ptr = '\f'; break;
504                case 'n':  *output_ptr = '\n'; break;
505                case 'r':  *output_ptr = '\r'; break;
506                case 't':  *output_ptr = '\t'; break;
507                case 'u':
508                    if (parse_utf_16(&input_ptr, &output_ptr) == JSONFailure)
509                        goto error;
510                    break;
511                default:
512                    goto error;
513            }
514        } else if ((unsigned char)*input_ptr < 0x20) {
515            goto error; /* 0x00-0x19 are invalid characters for json string (http://www.ietf.org/rfc/rfc4627.txt) */
516        } else {
517            *output_ptr = *input_ptr;
518        }
519        output_ptr++;
520        input_ptr++;
521    }
522    *output_ptr = '\0';
[5726a0d]523    if (try_realloc((void**)&output, (size_t)(output_ptr-output) + 1) == JSONFailure) /* resize to new length */
[782a6ee]524        goto error;
525    return output;
526error:
527    free(output);
528    return NULL;
529}
530
531/* Return processed contents of a string between quotes and
532   skips passed argument to a matching quote. */
533static const char * get_quoted_string(const char **string) {
534    const char *string_start = *string;
535    size_t string_len = 0;
536    skip_quotes(string);
537    if (**string == '\0')
538        return NULL;
539    string_len = *string - string_start - 2; /* length without quotes */
540    return process_string(string_start + 1, string_len);
541}
542
543static JSON_Value * parse_value(const char **string, size_t nesting) {
544    if (nesting > MAX_NESTING)
545        return NULL;
546    SKIP_WHITESPACES(string);
547    switch (**string) {
548        case '{':
549            return parse_object_value(string, nesting + 1);
550        case '[':
551            return parse_array_value(string, nesting + 1);
552        case '\"':
553            return parse_string_value(string);
554        case 'f': case 't':
555            return parse_boolean_value(string);
556        case '-':
557        case '0': case '1': case '2': case '3': case '4':
558        case '5': case '6': case '7': case '8': case '9':
559            return parse_number_value(string);
560        case 'n':
561            return parse_null_value(string);
562        default:
563            return NULL;
564    }
565}
566
567static JSON_Value * parse_object_value(const char **string, size_t nesting) {
568    JSON_Value *output_value = json_value_init_object(), *new_value = NULL;
569    JSON_Object *output_object = json_value_get_object(output_value);
570    const char *new_key = NULL;
571    if (output_value == NULL)
572        return NULL;
573    SKIP_CHAR(string);
574    SKIP_WHITESPACES(string);
575    if (**string == '}') { /* empty object */
576        SKIP_CHAR(string);
577        return output_value;
578    }
579    while (**string != '\0') {
580        new_key = get_quoted_string(string);
581        SKIP_WHITESPACES(string);
582        if (new_key == NULL || **string != ':') {
583            json_value_free(output_value);
584            return NULL;
585        }
586        SKIP_CHAR(string);
587        new_value = parse_value(string, nesting);
588        if (new_value == NULL) {
589            PARSON_FREE(new_key);
590            json_value_free(output_value);
591            return NULL;
592        }
593        if(json_object_add(output_object, new_key, new_value) == JSONFailure) {
594            PARSON_FREE(new_key);
595            PARSON_FREE(new_value);
596            json_value_free(output_value);
597            return NULL;
598        }
599        PARSON_FREE(new_key);
600        SKIP_WHITESPACES(string);
601        if (**string != ',')
602            break;
603        SKIP_CHAR(string);
604        SKIP_WHITESPACES(string);
605    }
606    SKIP_WHITESPACES(string);
607    if (**string != '}' || /* Trim object after parsing is over */
608        json_object_resize(output_object, json_object_get_count(output_object)) == JSONFailure) {
609            json_value_free(output_value);
610            return NULL;
611    }
612    SKIP_CHAR(string);
613    return output_value;
614}
615
616static JSON_Value * parse_array_value(const char **string, size_t nesting) {
617    JSON_Value *output_value = json_value_init_array(), *new_array_value = NULL;
618    JSON_Array *output_array = json_value_get_array(output_value);
619    if (!output_value)
620        return NULL;
621    SKIP_CHAR(string);
622    SKIP_WHITESPACES(string);
623    if (**string == ']') { /* empty array */
624        SKIP_CHAR(string);
625        return output_value;
626    }
627    while (**string != '\0') {
628        new_array_value = parse_value(string, nesting);
629        if (!new_array_value) {
630            json_value_free(output_value);
631            return NULL;
632        }
633        if(json_array_add(output_array, new_array_value) == JSONFailure) {
634            PARSON_FREE(new_array_value);
635            json_value_free(output_value);
636            return NULL;
637        }
638        SKIP_WHITESPACES(string);
639        if (**string != ',')
640            break;
641        SKIP_CHAR(string);
642        SKIP_WHITESPACES(string);
643    }
644    SKIP_WHITESPACES(string);
645    if (**string != ']' || /* Trim array after parsing is over */
646        json_array_resize(output_array, json_array_get_count(output_array)) == JSONFailure) {
647            json_value_free(output_value);
648            return NULL;
649    }
650    SKIP_CHAR(string);
651    return output_value;
652}
653
654static JSON_Value * parse_string_value(const char **string) {
655    const char *new_string = get_quoted_string(string);
656    if (!new_string)
657        return NULL;
658    return json_value_init_string_no_copy(new_string);
659}
660
661static JSON_Value * parse_boolean_value(const char **string) {
662    size_t true_token_size = SIZEOF_TOKEN("true");
663    size_t false_token_size = SIZEOF_TOKEN("false");
664    if (strncmp("true", *string, true_token_size) == 0) {
665        *string += true_token_size;
666        return json_value_init_boolean(1);
667    } else if (strncmp("false", *string, false_token_size) == 0) {
668        *string += false_token_size;
669        return json_value_init_boolean(0);
670    }
671    return NULL;
672}
673
674static JSON_Value * parse_number_value(const char **string) {
[8563fe7]675    char *jint_end, *double_end;
676    double number = strtod(*string, &double_end);
677    jint integer = strtoll(*string, &jint_end, 10);
[782a6ee]678    JSON_Value *output_value;
[8563fe7]679    if (double_end > jint_end || errno == ERANGE) {
680        if (is_decimal(*string, double_end - *string)) {
681            *string = double_end;
682            output_value = json_value_init_number(number);
683        } else {
684            output_value = NULL;
685        }
[782a6ee]686    } else {
[8563fe7]687        *string = jint_end;
688        output_value = json_value_init_integer(integer);
[782a6ee]689    }
690    return output_value;
691}
692
693static JSON_Value * parse_null_value(const char **string) {
694    size_t token_size = SIZEOF_TOKEN("null");
695    if (strncmp("null", *string, token_size) == 0) {
696        *string += token_size;
697        return json_value_init_null();
698    }
699    return NULL;
700}
701
702/* Serialization */
703static size_t json_serialization_size_r(const JSON_Value *value, char *buf) {
704    size_t result_size = 0;
705    const char *key = NULL;
706    JSON_Value *temp_value = NULL;
707    JSON_Array *array = NULL;
708    JSON_Object *object = NULL;
709    size_t i = 0, count = 0;
710    double num = 0.0;
[8563fe7]711    jint intnum = 0;
[782a6ee]712    switch (json_value_get_type(value)) {
713        case JSONArray:
714            array = json_value_get_array(value);
715            count = json_array_get_count(array);
716            result_size += 2; /* [ and ] brackets */
717            if (count > 0)
718                result_size += count - 1; /* , between items */
719            for (i = 0; i < count; i++) {
720                temp_value = json_array_get_value(array, i);
721                result_size += json_serialization_size_r(temp_value, buf);
722            }
723            return result_size;
724        case JSONObject:
725            object = json_value_get_object(value);
726            count  = json_object_get_count(object);
727            result_size += 2; /* { and } brackets */
728            if (count > 0)
729                result_size += (count * 2) - 1; /* : between keys and values and , between items */
730            for (i = 0; i < count; i++) {
731                key = json_object_get_name(object, i);
[5726a0d]732                result_size += serialization_strlen(key) + 2; /* string and quotes */
[782a6ee]733                result_size += json_serialization_size_r(json_object_get_value(object, key), buf);
734            }
735            return result_size;
736        case JSONString:
[5726a0d]737            return serialization_strlen(json_value_get_string(value)) + 2; /* string and quotes */
[782a6ee]738        case JSONBoolean:
739            if (json_value_get_boolean(value))
740                return 4; /* strlen("true"); */
741            else
742                return 5; /* strlen("false"); */
[8563fe7]743        case JSONInteger:
744            intnum = json_value_get_integer(value);
745            return (size_t)sprintf(buf, JINT_SERIALIZATION_FORMAT, intnum);
[782a6ee]746        case JSONNumber:
747            num = json_value_get_number(value);
[8563fe7]748            if (num == ((double)(jint)num) ) /*  check if num is integer */
749                return (size_t)sprintf(buf, JINT_SERIALIZATION_FORMAT, (jint)num);
[782a6ee]750            return (size_t)sprintf(buf, DOUBLE_SERIALIZATION_FORMAT, num);
751        case JSONNull:
752            return 4; /* strlen("null"); */
753        case JSONError:
754            return 0;
755        default:
756            return 0;
757    }
758}
759
760char* json_serialize_to_buffer_r(const JSON_Value *value, char *buf)
761{
762    const char *key = NULL, *string = NULL;
763    JSON_Value *temp_value = NULL;
764    JSON_Array *array = NULL;
765    JSON_Object *object = NULL;
766    size_t i = 0, count = 0;
767    double num = 0.0;
[8563fe7]768    jint intnum = 0;
[782a6ee]769    switch (json_value_get_type(value)) {
770        case JSONArray:
771            array = json_value_get_array(value);
772            count = json_array_get_count(array);
773            PRINT_AND_SKIP(buf, "[");
774            for (i = 0; i < count; i++) {
775                temp_value = json_array_get_value(array, i);
776                buf = json_serialize_to_buffer_r(temp_value, buf);
[5726a0d]777                if (buf == NULL)
778                    return NULL;
[782a6ee]779                if (i < (count - 1))
780                    PRINT_AND_SKIP(buf, ",");
781            }
782            PRINT_AND_SKIP(buf, "]");
783            return buf;
784        case JSONObject:
785            object = json_value_get_object(value);
786            count  = json_object_get_count(object);
787            PRINT_AND_SKIP(buf, "{");
788            for (i = 0; i < count; i++) {
789                key = json_object_get_name(object, i);
790                buf = json_serialize_string(key, buf);
[5726a0d]791                if (buf == NULL)
792                    return NULL;
[782a6ee]793                PRINT_AND_SKIP(buf, ":");
794                temp_value = json_object_get_value(object, key);
795                buf = json_serialize_to_buffer_r(temp_value, buf);
[5726a0d]796                if (buf == NULL)
797                    return NULL;
[782a6ee]798                if (i < (count - 1))
799                    PRINT_AND_SKIP(buf, ",");
800            }
801            PRINT_AND_SKIP(buf, "}");
802            return buf;
803        case JSONString:
804            string = json_value_get_string(value);
805            buf = json_serialize_string(string, buf);
806            return buf;
807        case JSONBoolean:
808            if (json_value_get_boolean(value)) {
809                PRINT_AND_SKIP(buf, "true");
810            } else {
811                PRINT_AND_SKIP(buf, "false");
812            }
813            return buf;
[8563fe7]814        case JSONInteger:
815            intnum = json_value_get_integer(value);
816            PRINTF_AND_SKIP(buf, JINT_SERIALIZATION_FORMAT, intnum);
817            return buf;
[782a6ee]818        case JSONNumber:
819            num = json_value_get_number(value);
820            if (num == ((double)(int)num)) { /*  check if num is integer */
821                PRINTF_AND_SKIP(buf, "%d", (int)num);
822            } else {
823                PRINTF_AND_SKIP(buf, DOUBLE_SERIALIZATION_FORMAT, num);
824            }
825            return buf;
826        case JSONNull:
827            PRINT_AND_SKIP(buf, "null");
828            return buf;
829        case JSONError:
830            return NULL;
831        default:
832            return NULL;
833    }
834}
835
836static char * json_serialize_string(const char *string, char *buf) {
837    size_t i = 0, len = strlen(string);
838    char c = '\0';
839    PRINT_AND_SKIP(buf, "\"")
840    for (i = 0; i < len; i++) {
841        c = string[i];
842        switch (c) {
843            case '\"': PRINT_AND_SKIP(buf, "\\\"");   break;
844            case '\\': PRINT_AND_SKIP(buf, "\\\\");   break;
845            case '\b': PRINT_AND_SKIP(buf, "\\b");    break;
846            case '\f': PRINT_AND_SKIP(buf, "\\f");    break;
847            case '\n': PRINT_AND_SKIP(buf, "\\n");    break;
848            case '\r': PRINT_AND_SKIP(buf, "\\r");    break;
849            case '\t': PRINT_AND_SKIP(buf, "\\t");    break;
850            default:   PRINTF_AND_SKIP(buf, "%c", c); break;
851        }
852    }
853    PRINT_AND_SKIP(buf, "\"");
854    return buf;
855}
856
857/* Parser API */
858JSON_Value * json_parse_file(const char *filename) {
859    char *file_contents = read_file(filename);
860    JSON_Value *output_value = NULL;
[5726a0d]861    if (file_contents == NULL)
[782a6ee]862        return NULL;
863    output_value = json_parse_string(file_contents);
864    PARSON_FREE(file_contents);
865    return output_value;
866}
867
868JSON_Value * json_parse_file_with_comments(const char *filename) {
869    char *file_contents = read_file(filename);
870    JSON_Value *output_value = NULL;
[5726a0d]871    if (file_contents == NULL)
[782a6ee]872        return NULL;
873    output_value = json_parse_string_with_comments(file_contents);
874    PARSON_FREE(file_contents);
875    return output_value;
876}
877
[989f431]878JSON_Value * json_parse_first(const char *string, const char **end) {
879    const char *pos;
880    JSON_Value *ret;
881
[5726a0d]882    if (string == NULL)
[782a6ee]883        return NULL;
884    SKIP_WHITESPACES(&string);
885    if (*string != '{' && *string != '[')
886        return NULL;
[989f431]887
888    pos = string;
889    ret = parse_value(&pos, 0);
890    if (end)
891        *end = pos;
892
893    return ret;
894}
895
896JSON_Value * json_parse_string(const char *string) {
897    return json_parse_first(string, NULL);
[782a6ee]898}
899
900JSON_Value * json_parse_string_with_comments(const char *string) {
901    JSON_Value *result = NULL;
902    char *string_mutable_copy = NULL, *string_mutable_copy_ptr = NULL;
903    string_mutable_copy = parson_strdup(string);
[5726a0d]904    if (string_mutable_copy == NULL)
[782a6ee]905        return NULL;
906    remove_comments(string_mutable_copy, "/*", "*/");
907    remove_comments(string_mutable_copy, "//", "\n");
908    string_mutable_copy_ptr = string_mutable_copy;
909    SKIP_WHITESPACES(&string_mutable_copy_ptr);
910    if (*string_mutable_copy_ptr != '{' && *string_mutable_copy_ptr != '[') {
911        PARSON_FREE(string_mutable_copy);
912        return NULL;
913    }
914    result = parse_value((const char**)&string_mutable_copy_ptr, 0);
915    PARSON_FREE(string_mutable_copy);
916    return result;
917}
918
919
920/* JSON Object API */
921
922JSON_Value * json_object_get_value(const JSON_Object *object, const char *name) {
[5726a0d]923    if (object == NULL || name == NULL)
924        return NULL;
[782a6ee]925    return json_object_nget_value(object, name, strlen(name));
926}
927
928const char * json_object_get_string(const JSON_Object *object, const char *name) {
929    return json_value_get_string(json_object_get_value(object, name));
930}
931
[8563fe7]932jint json_object_get_integer(const JSON_Object *object, const char *name) {
933    return json_value_get_integer(json_object_get_value(object, name));
934}
935
[782a6ee]936double json_object_get_number(const JSON_Object *object, const char *name) {
937    return json_value_get_number(json_object_get_value(object, name));
938}
939
940JSON_Object * json_object_get_object(const JSON_Object *object, const char *name) {
941    return json_value_get_object(json_object_get_value(object, name));
942}
943
944JSON_Array * json_object_get_array(const JSON_Object *object, const char *name) {
945    return json_value_get_array(json_object_get_value(object, name));
946}
947
948int json_object_get_boolean(const JSON_Object *object, const char *name) {
949    return json_value_get_boolean(json_object_get_value(object, name));
950}
951
952JSON_Value * json_object_dotget_value(const JSON_Object *object, const char *name) {
953    const char *dot_position = strchr(name, '.');
954    if (!dot_position)
955        return json_object_get_value(object, name);
956    object = json_value_get_object(json_object_nget_value(object, name, dot_position - name));
957    return json_object_dotget_value(object, dot_position + 1);
958}
959
960const char * json_object_dotget_string(const JSON_Object *object, const char *name) {
961    return json_value_get_string(json_object_dotget_value(object, name));
962}
963
[8563fe7]964jint json_object_dotget_integer(const JSON_Object *object, const char *name) {
965    return json_value_get_integer(json_object_dotget_value(object, name));
966}
967
[782a6ee]968double json_object_dotget_number(const JSON_Object *object, const char *name) {
969    return json_value_get_number(json_object_dotget_value(object, name));
970}
971
972JSON_Object * json_object_dotget_object(const JSON_Object *object, const char *name) {
973    return json_value_get_object(json_object_dotget_value(object, name));
974}
975
976JSON_Array * json_object_dotget_array(const JSON_Object *object, const char *name) {
977    return json_value_get_array(json_object_dotget_value(object, name));
978}
979
980int json_object_dotget_boolean(const JSON_Object *object, const char *name) {
981    return json_value_get_boolean(json_object_dotget_value(object, name));
982}
983
984size_t json_object_get_count(const JSON_Object *object) {
985    return object ? object->count : 0;
986}
987
988const char * json_object_get_name(const JSON_Object *object, size_t index) {
989    if (index >= json_object_get_count(object))
990        return NULL;
991    return object->names[index];
992}
993
[ee170a1]994int json_object_get_tuple(const JSON_Object *object, size_t index,
995                          const char **key, const JSON_Value **value) {
996    if (index >= json_object_get_count(object))
997        return 0;
998    *key = object->names[index];
999    *value = object->values[index];
1000    return 1;
1001}
1002
[782a6ee]1003/* JSON Array API */
1004JSON_Value * json_array_get_value(const JSON_Array *array, size_t index) {
1005    if (index >= json_array_get_count(array))
1006        return NULL;
1007    return array->items[index];
1008}
1009
1010const char * json_array_get_string(const JSON_Array *array, size_t index) {
1011    return json_value_get_string(json_array_get_value(array, index));
1012}
1013
[8563fe7]1014jint json_array_get_integer(const JSON_Array *array, size_t index) {
1015    return json_value_get_integer(json_array_get_value(array, index));
1016}
1017
[782a6ee]1018double json_array_get_number(const JSON_Array *array, size_t index) {
1019    return json_value_get_number(json_array_get_value(array, index));
1020}
1021
1022JSON_Object * json_array_get_object(const JSON_Array *array, size_t index) {
1023    return json_value_get_object(json_array_get_value(array, index));
1024}
1025
1026JSON_Array * json_array_get_array(const JSON_Array *array, size_t index) {
1027    return json_value_get_array(json_array_get_value(array, index));
1028}
1029
1030int json_array_get_boolean(const JSON_Array *array, size_t index) {
1031    return json_value_get_boolean(json_array_get_value(array, index));
1032}
1033
1034size_t json_array_get_count(const JSON_Array *array) {
1035    return array ? array->count : 0;
1036}
1037
1038/* JSON Value API */
1039JSON_Value_Type json_value_get_type(const JSON_Value *value) {
1040    return value ? value->type : JSONError;
1041}
1042
1043JSON_Object * json_value_get_object(const JSON_Value *value) {
1044    return json_value_get_type(value) == JSONObject ? value->value.object : NULL;
1045}
1046
1047JSON_Array * json_value_get_array(const JSON_Value *value) {
1048    return json_value_get_type(value) == JSONArray ? value->value.array : NULL;
1049}
1050
1051const char * json_value_get_string(const JSON_Value *value) {
1052    return json_value_get_type(value) == JSONString ? value->value.string : NULL;
1053}
1054
[8563fe7]1055jint json_value_get_integer(const JSON_Value *value) {
1056    if (json_value_get_type(value) == JSONNumber) {
1057        return value->value.number;
1058    } else if (json_value_get_type(value) == JSONInteger) {
1059        return value->value.integer;
1060    } else {
1061        return 0;
1062    }
1063}
1064
[782a6ee]1065double json_value_get_number(const JSON_Value *value) {
[8563fe7]1066    if (json_value_get_type(value) == JSONNumber) {
1067        return value->value.number;
1068    } else if (json_value_get_type(value) == JSONInteger) {
1069        return value->value.integer;
1070    } else {
1071        return 0;
1072    }
[782a6ee]1073}
1074
1075int json_value_get_boolean(const JSON_Value *value) {
1076    return json_value_get_type(value) == JSONBoolean ? value->value.boolean : -1;
1077}
1078
1079void json_value_free(JSON_Value *value) {
1080    switch (json_value_get_type(value)) {
1081        case JSONObject:
1082            json_object_free(value->value.object);
1083            break;
1084        case JSONString:
1085            if (value->value.string) { PARSON_FREE(value->value.string); }
1086            break;
1087        case JSONArray:
1088            json_array_free(value->value.array);
1089            break;
1090        default:
1091            break;
1092    }
1093    PARSON_FREE(value);
1094}
1095
1096JSON_Value * json_value_init_object(void) {
1097    JSON_Value *new_value = (JSON_Value*)PARSON_MALLOC(sizeof(JSON_Value));
1098    if (!new_value)
1099        return NULL;
1100    new_value->type = JSONObject;
1101    new_value->value.object = json_object_init();
1102    if (!new_value->value.object) {
1103        PARSON_FREE(new_value);
1104        return NULL;
1105    }
1106    return new_value;
1107}
1108
1109JSON_Value * json_value_init_array(void) {
1110    JSON_Value *new_value = (JSON_Value*)PARSON_MALLOC(sizeof(JSON_Value));
1111    if (!new_value)
1112        return NULL;
1113    new_value->type = JSONArray;
1114    new_value->value.array = json_array_init();
1115    if (!new_value->value.array) {
1116        PARSON_FREE(new_value);
1117        return NULL;
1118    }
1119    return new_value;
1120}
1121
1122JSON_Value * json_value_init_string(const char *string) {
[5726a0d]1123    char *copy = NULL;
1124    JSON_Value *value;
1125    size_t string_len = 0;
1126    if (string == NULL)
1127        return NULL;
1128    string_len = strlen(string);
1129    if (!is_valid_utf8(string, string_len))
[782a6ee]1130        return NULL;
[5726a0d]1131    copy = parson_strndup(string, string_len);
1132    if (copy == NULL)
1133        return NULL;
1134    value = json_value_init_string_no_copy(copy);
1135    if (value == NULL)
1136        PARSON_FREE(copy);
1137    return value;
[782a6ee]1138}
1139
[8563fe7]1140JSON_Value * json_value_init_integer(jint number) {
1141    JSON_Value *new_value = (JSON_Value*)PARSON_MALLOC(sizeof(JSON_Value));
1142    if (!new_value)
1143        return NULL;
1144    new_value->type = JSONInteger;
1145    new_value->value.integer = number;
1146    return new_value;
1147}
1148
[782a6ee]1149JSON_Value * json_value_init_number(double number) {
1150    JSON_Value *new_value = (JSON_Value*)PARSON_MALLOC(sizeof(JSON_Value));
1151    if (!new_value)
1152        return NULL;
1153    new_value->type = JSONNumber;
1154    new_value->value.number = number;
1155    return new_value;
1156}
1157
1158JSON_Value * json_value_init_boolean(int boolean) {
1159    JSON_Value *new_value = (JSON_Value*)PARSON_MALLOC(sizeof(JSON_Value));
1160    if (!new_value)
1161        return NULL;
1162    new_value->type = JSONBoolean;
1163    new_value->value.boolean = boolean ? 1 : 0;
1164    return new_value;
1165}
1166
1167JSON_Value * json_value_init_null(void) {
1168    JSON_Value *new_value = (JSON_Value*)PARSON_MALLOC(sizeof(JSON_Value));
1169    if (!new_value)
1170        return NULL;
1171    new_value->type = JSONNull;
1172    return new_value;
1173}
1174
1175JSON_Value * json_value_deep_copy(const JSON_Value *value) {
1176    size_t i = 0;
1177    JSON_Value *return_value = NULL, *temp_value_copy = NULL, *temp_value = NULL;
1178    const char *temp_string = NULL, *temp_string_copy = NULL, *temp_key = NULL;
1179    JSON_Array *temp_array = NULL, *temp_array_copy = NULL;
1180    JSON_Object *temp_object = NULL, *temp_object_copy = NULL;
1181   
1182    switch (json_value_get_type(value)) {
1183        case JSONArray:
1184            temp_array = json_value_get_array(value);
1185            return_value = json_value_init_array();
1186            if (return_value == NULL)
1187                return NULL;
1188            temp_array_copy = json_value_get_array(return_value);
1189            for (i = 0; i < json_array_get_count(temp_array); i++) {
1190                temp_value = json_array_get_value(temp_array, i);
1191                temp_value_copy = json_value_deep_copy(temp_value);
1192                if (temp_value_copy == NULL) {
1193                    json_value_free(return_value);
1194                    return NULL;
1195                }
1196                if (json_array_add(temp_array_copy, temp_value_copy) == JSONFailure) {
1197                    json_value_free(return_value);
1198                    json_value_free(temp_value_copy);
1199                    return NULL;
1200                }
1201            }
1202            return return_value;
1203        case JSONObject:
1204            temp_object = json_value_get_object(value);
1205            return_value = json_value_init_object();
1206            if (return_value == NULL)
1207                return NULL;
1208            temp_object_copy = json_value_get_object(return_value);
1209            for (i = 0; i < json_object_get_count(temp_object); i++) {
1210                temp_key = json_object_get_name(temp_object, i);
1211                temp_value = json_object_get_value(temp_object, temp_key);
1212                temp_value_copy = json_value_deep_copy(temp_value);
1213                if (temp_value_copy == NULL) {
1214                    json_value_free(return_value);
1215                    return NULL;
1216                }
1217                if (json_object_add(temp_object_copy, temp_key, temp_value_copy) == JSONFailure) {
1218                    json_value_free(return_value);
1219                    json_value_free(temp_value_copy);
1220                    return NULL;
1221                }
1222            }
1223            return return_value;
1224        case JSONBoolean:
1225            return json_value_init_boolean(json_value_get_boolean(value));
[6f903c3]1226        case JSONInteger:
1227            return json_value_init_integer(json_value_get_integer(value));
[782a6ee]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;
[6f903c3]1675        case JSONString: case JSONInteger: case JSONNumber: case JSONBoolean: case JSONNull:
[782a6ee]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);
[6f903c3]1732        case JSONInteger:
1733            return json_value_get_integer(a) == json_value_get_integer(b);
[782a6ee]1734        case JSONNumber:
1735            return fabs(json_value_get_number(a) - json_value_get_number(b)) < 0.000001; /* EPSILON */
1736        case JSONError:
1737            return 1;
1738        case JSONNull:
1739            return 1;
1740        default:
1741            return 1;
1742    }
1743}
1744
1745JSON_Value_Type json_type(const JSON_Value *value) {
1746    return json_value_get_type(value);
1747}
1748
1749JSON_Object * json_object (const JSON_Value *value) {
1750    return json_value_get_object(value);
1751}
1752
1753JSON_Array * json_array  (const JSON_Value *value) {
1754    return json_value_get_array(value);
1755}
1756
1757const char * json_string (const JSON_Value *value) {
1758    return json_value_get_string(value);
1759}
1760
[8563fe7]1761jint json_integer (const JSON_Value *value) {
1762    return json_value_get_integer(value);
1763}
1764
[782a6ee]1765double json_number (const JSON_Value *value) {
1766    return json_value_get_number(value);
1767}
1768
1769int json_boolean(const JSON_Value *value) {
1770    return json_value_get_boolean(value);
1771}
Note: See TracBrowser for help on using the repository browser.