source: lib/parson.c @ 989f431

Last change on this file since 989f431 was 989f431, checked in by Wilmer van der Gaast <wilmer@…>, at 2015-02-22T16:15:28Z

json_parse_first() which lets me find out where it stopped parsing, needed
for safe and proper stream parsing.

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