source: lib/parson.c @ f3af614

Last change on this file since f3af614 was ee170a1, checked in by Wilmer van der Gaast <wilmer@…>, at 2015-02-22T17:01:53Z

Added json_object_get_tuple() which helps with implementing a JSON Object
foreach.

  • Property mode set to 100644
File size: 51.6 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
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
[989f431]771JSON_Value * json_parse_first(const char *string, const char **end) {
772    const char *pos;
773    JSON_Value *ret;
774
[782a6ee]775    if (!string)
776        return NULL;
777    SKIP_WHITESPACES(&string);
778    if (*string != '{' && *string != '[')
779        return NULL;
[989f431]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);
[782a6ee]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
[ee170a1]877int json_object_get_tuple(const JSON_Object *object, size_t index,
878                          const char **key, const JSON_Value **value) {
879    if (index >= json_object_get_count(object))
880        return 0;
881    *key = object->names[index];
882    *value = object->values[index];
883    return 1;
884}
885
[782a6ee]886/* JSON Array API */
887JSON_Value * json_array_get_value(const JSON_Array *array, size_t index) {
888    if (index >= json_array_get_count(array))
889        return NULL;
890    return array->items[index];
891}
892
893const char * json_array_get_string(const JSON_Array *array, size_t index) {
894    return json_value_get_string(json_array_get_value(array, index));
895}
896
897double json_array_get_number(const JSON_Array *array, size_t index) {
898    return json_value_get_number(json_array_get_value(array, index));
899}
900
901JSON_Object * json_array_get_object(const JSON_Array *array, size_t index) {
902    return json_value_get_object(json_array_get_value(array, index));
903}
904
905JSON_Array * json_array_get_array(const JSON_Array *array, size_t index) {
906    return json_value_get_array(json_array_get_value(array, index));
907}
908
909int json_array_get_boolean(const JSON_Array *array, size_t index) {
910    return json_value_get_boolean(json_array_get_value(array, index));
911}
912
913size_t json_array_get_count(const JSON_Array *array) {
914    return array ? array->count : 0;
915}
916
917/* JSON Value API */
918JSON_Value_Type json_value_get_type(const JSON_Value *value) {
919    return value ? value->type : JSONError;
920}
921
922JSON_Object * json_value_get_object(const JSON_Value *value) {
923    return json_value_get_type(value) == JSONObject ? value->value.object : NULL;
924}
925
926JSON_Array * json_value_get_array(const JSON_Value *value) {
927    return json_value_get_type(value) == JSONArray ? value->value.array : NULL;
928}
929
930const char * json_value_get_string(const JSON_Value *value) {
931    return json_value_get_type(value) == JSONString ? value->value.string : NULL;
932}
933
934double json_value_get_number(const JSON_Value *value) {
935    return json_value_get_type(value) == JSONNumber ? value->value.number : 0;
936}
937
938int json_value_get_boolean(const JSON_Value *value) {
939    return json_value_get_type(value) == JSONBoolean ? value->value.boolean : -1;
940}
941
942void json_value_free(JSON_Value *value) {
943    switch (json_value_get_type(value)) {
944        case JSONObject:
945            json_object_free(value->value.object);
946            break;
947        case JSONString:
948            if (value->value.string) { PARSON_FREE(value->value.string); }
949            break;
950        case JSONArray:
951            json_array_free(value->value.array);
952            break;
953        default:
954            break;
955    }
956    PARSON_FREE(value);
957}
958
959JSON_Value * json_value_init_object(void) {
960    JSON_Value *new_value = (JSON_Value*)PARSON_MALLOC(sizeof(JSON_Value));
961    if (!new_value)
962        return NULL;
963    new_value->type = JSONObject;
964    new_value->value.object = json_object_init();
965    if (!new_value->value.object) {
966        PARSON_FREE(new_value);
967        return NULL;
968    }
969    return new_value;
970}
971
972JSON_Value * json_value_init_array(void) {
973    JSON_Value *new_value = (JSON_Value*)PARSON_MALLOC(sizeof(JSON_Value));
974    if (!new_value)
975        return NULL;
976    new_value->type = JSONArray;
977    new_value->value.array = json_array_init();
978    if (!new_value->value.array) {
979        PARSON_FREE(new_value);
980        return NULL;
981    }
982    return new_value;
983}
984
985JSON_Value * json_value_init_string(const char *string) {
986    char *processed_copy = process_string(string, strlen(string));
987    if (processed_copy == NULL)
988        return NULL;
989    return json_value_init_string_no_copy(processed_copy);
990}
991
992JSON_Value * json_value_init_number(double number) {
993    JSON_Value *new_value = (JSON_Value*)PARSON_MALLOC(sizeof(JSON_Value));
994    if (!new_value)
995        return NULL;
996    new_value->type = JSONNumber;
997    new_value->value.number = number;
998    return new_value;
999}
1000
1001JSON_Value * json_value_init_boolean(int boolean) {
1002    JSON_Value *new_value = (JSON_Value*)PARSON_MALLOC(sizeof(JSON_Value));
1003    if (!new_value)
1004        return NULL;
1005    new_value->type = JSONBoolean;
1006    new_value->value.boolean = boolean ? 1 : 0;
1007    return new_value;
1008}
1009
1010JSON_Value * json_value_init_null(void) {
1011    JSON_Value *new_value = (JSON_Value*)PARSON_MALLOC(sizeof(JSON_Value));
1012    if (!new_value)
1013        return NULL;
1014    new_value->type = JSONNull;
1015    return new_value;
1016}
1017
1018JSON_Value * json_value_deep_copy(const JSON_Value *value) {
1019    size_t i = 0;
1020    JSON_Value *return_value = NULL, *temp_value_copy = NULL, *temp_value = NULL;
1021    const char *temp_string = NULL, *temp_string_copy = NULL, *temp_key = NULL;
1022    JSON_Array *temp_array = NULL, *temp_array_copy = NULL;
1023    JSON_Object *temp_object = NULL, *temp_object_copy = NULL;
1024   
1025    switch (json_value_get_type(value)) {
1026        case JSONArray:
1027            temp_array = json_value_get_array(value);
1028            return_value = json_value_init_array();
1029            if (return_value == NULL)
1030                return NULL;
1031            temp_array_copy = json_value_get_array(return_value);
1032            for (i = 0; i < json_array_get_count(temp_array); i++) {
1033                temp_value = json_array_get_value(temp_array, i);
1034                temp_value_copy = json_value_deep_copy(temp_value);
1035                if (temp_value_copy == NULL) {
1036                    json_value_free(return_value);
1037                    return NULL;
1038                }
1039                if (json_array_add(temp_array_copy, temp_value_copy) == JSONFailure) {
1040                    json_value_free(return_value);
1041                    json_value_free(temp_value_copy);
1042                    return NULL;
1043                }
1044            }
1045            return return_value;
1046        case JSONObject:
1047            temp_object = json_value_get_object(value);
1048            return_value = json_value_init_object();
1049            if (return_value == NULL)
1050                return NULL;
1051            temp_object_copy = json_value_get_object(return_value);
1052            for (i = 0; i < json_object_get_count(temp_object); i++) {
1053                temp_key = json_object_get_name(temp_object, i);
1054                temp_value = json_object_get_value(temp_object, temp_key);
1055                temp_value_copy = json_value_deep_copy(temp_value);
1056                if (temp_value_copy == NULL) {
1057                    json_value_free(return_value);
1058                    return NULL;
1059                }
1060                if (json_object_add(temp_object_copy, temp_key, temp_value_copy) == JSONFailure) {
1061                    json_value_free(return_value);
1062                    json_value_free(temp_value_copy);
1063                    return NULL;
1064                }
1065            }
1066            return return_value;
1067        case JSONBoolean:
1068            return json_value_init_boolean(json_value_get_boolean(value));
1069        case JSONNumber:
1070            return json_value_init_number(json_value_get_number(value));
1071        case JSONString:
1072            temp_string = json_value_get_string(value);
1073            temp_string_copy = parson_strdup(temp_string);
1074            if (temp_string_copy == NULL)
1075                return NULL;
1076            return json_value_init_string_no_copy(temp_string_copy);
1077        case JSONNull:
1078            return json_value_init_null();
1079        case JSONError:
1080            return NULL;
1081        default:
1082            return NULL;
1083    }
1084}
1085
1086size_t json_serialization_size(const JSON_Value *value) {
1087    char buf[1100]; /* recursively allocating buffer on stack is a bad idea, so let's do it only once */
1088    return json_serialization_size_r(value, buf) + 1;
1089}
1090
1091JSON_Status json_serialize_to_buffer(const JSON_Value *value, char *buf, size_t buf_size_in_bytes) {
1092    char *serialization_result = NULL;
1093    size_t needed_size_in_bytes = json_serialization_size(value);
1094    if (buf_size_in_bytes < needed_size_in_bytes) {
1095        return JSONFailure;
1096    }
1097    serialization_result = json_serialize_to_buffer_r(value, buf);
1098    if(serialization_result == NULL)
1099        return JSONFailure;
1100    return JSONSuccess;
1101}
1102
1103JSON_Status json_serialize_to_file(const JSON_Value *value, const char *filename) {
1104    JSON_Status return_code = JSONSuccess;
1105    FILE *fp = NULL;
1106    char *serialized_string = json_serialize_to_string(value);
1107    if (serialized_string == NULL) {
1108        return JSONFailure;
1109    }
1110    fp = fopen (filename, "w");
1111    if (fp != NULL) {
1112        if (fputs (serialized_string, fp) == EOF) {
1113            return_code = JSONFailure;
1114        }
1115        if (fclose (fp) == EOF) {
1116            return_code = JSONFailure;
1117        }
1118    }
1119    json_free_serialized_string(serialized_string);
1120    return return_code;
1121}
1122
1123char * json_serialize_to_string(const JSON_Value *value) {
1124    JSON_Status serialization_result = JSONFailure;
1125    size_t buf_size_bytes = json_serialization_size(value);
1126    char *buf = (char*)PARSON_MALLOC(buf_size_bytes);
1127    if (buf == NULL)
1128        return NULL;
1129    serialization_result = json_serialize_to_buffer(value, buf, buf_size_bytes);
1130    if (serialization_result == JSONFailure) {
1131        json_free_serialized_string(buf);
1132        return NULL;
1133    }
1134    return buf;
1135}
1136
1137void json_free_serialized_string(char *string) {
1138    PARSON_FREE(string);
1139}
1140
1141JSON_Status json_array_remove(JSON_Array *array, size_t ix) {
1142    size_t last_element_ix = 0;
1143    if (array == NULL || ix >= json_array_get_count(array)) {
1144        return JSONFailure;
1145    }
1146    last_element_ix = json_array_get_count(array) - 1;
1147    json_value_free(json_array_get_value(array, ix));
1148    array->count -= 1;
1149    if (ix != last_element_ix) /* Replace value with one from the end of array */
1150        array->items[ix] = json_array_get_value(array, last_element_ix);
1151    return JSONSuccess;
1152}
1153
1154JSON_Status json_array_replace_value(JSON_Array *array, size_t ix, JSON_Value *value) {
1155    if (array == NULL || value == NULL || ix >= json_array_get_count(array)) {
1156        return JSONFailure;
1157    }
1158    json_value_free(json_array_get_value(array, ix));
1159    array->items[ix] = value;
1160    return JSONSuccess;
1161}
1162
1163JSON_Status json_array_replace_string(JSON_Array *array, size_t i, const char* string) {
1164    return json_array_replace_value(array, i, json_value_init_string(string));
1165}
1166
1167JSON_Status json_array_replace_number(JSON_Array *array, size_t i, double number) {
1168    return json_array_replace_value(array, i, json_value_init_number(number));
1169}
1170
1171JSON_Status json_array_replace_boolean(JSON_Array *array, size_t i, int boolean) {
1172    return json_array_replace_value(array, i, json_value_init_boolean(boolean));
1173}
1174
1175JSON_Status json_array_replace_null(JSON_Array *array, size_t i) {
1176    return json_array_replace_value(array, i, json_value_init_null());
1177}
1178
1179JSON_Status json_array_clear(JSON_Array *array) {
1180    size_t i = 0;
1181    if (array == NULL)
1182        return JSONFailure;
1183    for (i = 0; i < json_array_get_count(array); i++) {
1184        json_value_free(json_array_get_value(array, i));
1185    }
1186    array->count = 0;
1187    return JSONSuccess;
1188}
1189
1190JSON_Status json_array_append_value(JSON_Array *array, JSON_Value *value) {
1191    if (array == NULL || value == NULL)
1192        return JSONFailure;
1193    return json_array_add(array, value);
1194}
1195
1196JSON_Status json_array_append_string(JSON_Array *array, const char *string) {
1197    return json_array_append_value(array, json_value_init_string(string));
1198}
1199
1200JSON_Status json_array_append_number(JSON_Array *array, double number) {
1201    return json_array_append_value(array, json_value_init_number(number));
1202}
1203
1204JSON_Status json_array_append_boolean(JSON_Array *array, int boolean) {
1205    return json_array_append_value(array, json_value_init_boolean(boolean));
1206}
1207
1208JSON_Status json_array_append_null(JSON_Array *array) {
1209    return json_array_append_value(array, json_value_init_null());
1210}
1211
1212JSON_Status json_object_set_value(JSON_Object *object, const char *name, JSON_Value *value) {
1213    size_t i = 0;
1214    JSON_Value *old_value;
1215    if (object == NULL)
1216        return JSONFailure;
1217    old_value = json_object_get_value(object, name);
1218    if (old_value != NULL) { /* free and overwrite old value */
1219        json_value_free(old_value);
1220        for (i = 0; i < json_object_get_count(object); i++) {
1221            if (strcmp(object->names[i], name) == 0) {
1222                object->values[i] = value;
1223                return JSONSuccess;
1224            }
1225        }
1226    }
1227    json_object_add(object, name, value); /* add new key value pair */
1228    return JSONSuccess;
1229}
1230
1231JSON_Status json_object_set_string(JSON_Object *object, const char *name, const char *string) {
1232    return json_object_set_value(object, name, json_value_init_string(string));
1233}
1234
1235JSON_Status json_object_set_number(JSON_Object *object, const char *name, double number) {
1236    return json_object_set_value(object, name, json_value_init_number(number));
1237}
1238
1239JSON_Status json_object_set_boolean(JSON_Object *object, const char *name, int boolean) {
1240    return json_object_set_value(object, name, json_value_init_boolean(boolean));
1241}
1242
1243JSON_Status json_object_set_null(JSON_Object *object, const char *name) {
1244    return json_object_set_value(object, name, json_value_init_null());
1245}
1246
1247JSON_Status json_object_dotset_value(JSON_Object *object, const char *name, JSON_Value *value) {
1248    const char *dot_pos = strchr(name, '.');
1249    const char *current_name = NULL;
1250    JSON_Object *temp_obj = NULL;
1251    JSON_Value *new_value = NULL;
1252    if (value == NULL) {
1253        return JSONFailure;
1254    } else if (dot_pos == NULL) {
1255        return json_object_set_value(object, name, value);
1256    } else {
1257        current_name = parson_strndup(name, dot_pos - name);
1258        temp_obj = json_object_get_object(object, current_name);
1259        if (temp_obj == NULL) {
1260            new_value = json_value_init_object();
1261            if (new_value == NULL) {
1262                PARSON_FREE(current_name);
1263                return JSONFailure;
1264            }
1265            if (json_object_add(object, current_name, new_value) == JSONFailure) {
1266                json_value_free(new_value);
1267                PARSON_FREE(current_name);
1268                return JSONFailure;
1269            }
1270            temp_obj = json_object_get_object(object, current_name);
1271        }
1272        PARSON_FREE(current_name);
1273        return json_object_dotset_value(temp_obj, dot_pos + 1, value);
1274    }
1275    return JSONFailure;
1276}
1277
1278JSON_Status json_object_dotset_string(JSON_Object *object, const char *name, const char *string) {
1279    return json_object_dotset_value(object, name, json_value_init_string(string));
1280}
1281
1282JSON_Status json_object_dotset_number(JSON_Object *object, const char *name, double number) {
1283    return json_object_dotset_value(object, name, json_value_init_number(number));
1284}
1285
1286JSON_Status json_object_dotset_boolean(JSON_Object *object, const char *name, int boolean) {
1287    return json_object_dotset_value(object, name, json_value_init_boolean(boolean));
1288}
1289
1290JSON_Status json_object_dotset_null(JSON_Object *object, const char *name) {
1291    return json_object_dotset_value(object, name, json_value_init_null());
1292}
1293
1294JSON_Status json_object_remove(JSON_Object *object, const char *name) {
1295    size_t i = 0, last_item_index = 0;
1296    if (object == NULL || json_object_get_value(object, name) == NULL)
1297        return JSONFailure;
1298    last_item_index = json_object_get_count(object) - 1;
1299    for (i = 0; i < json_object_get_count(object); i++) {
1300        if (strcmp(object->names[i], name) == 0) {
1301            PARSON_FREE(object->names[i]);
1302            json_value_free(object->values[i]);
1303            if (i != last_item_index) { /* Replace key value pair with one from the end */
1304                object->names[i] = object->names[last_item_index];
1305                object->values[i] = object->values[last_item_index];
1306            }
1307            object->count -= 1;
1308            return JSONSuccess;
1309        }
1310    }
1311    return JSONFailure; /* No execution path should end here */
1312}
1313
1314JSON_Status json_object_dotremove(JSON_Object *object, const char *name) {
1315    const char *dot_pos = strchr(name, '.');
1316    const char *current_name = NULL;
1317    JSON_Object *temp_obj = NULL;
1318    if (dot_pos == NULL) {
1319        return json_object_remove(object, name);
1320    } else {
1321        current_name = parson_strndup(name, dot_pos - name);
1322        temp_obj = json_object_get_object(object, current_name);
1323        if (temp_obj == NULL) {
1324            PARSON_FREE(current_name);
1325            return JSONFailure;
1326        }
1327        PARSON_FREE(current_name);
1328        return json_object_dotremove(temp_obj, dot_pos + 1);
1329    }
1330    return JSONFailure;
1331}
1332
1333JSON_Status json_object_clear(JSON_Object *object) {
1334    size_t i = 0;
1335    if (object == NULL) {
1336        return JSONFailure;
1337    }
1338    for (i = 0; i < json_object_get_count(object); i++) {       
1339        PARSON_FREE(object->names[i]);
1340        json_value_free(object->values[i]);
1341    }
1342    object->count = 0;
1343    return JSONSuccess;
1344}
1345
1346JSON_Status json_validate(const JSON_Value *schema, const JSON_Value *value) {
1347    JSON_Value *temp_schema_value = NULL, *temp_value = NULL;
1348    JSON_Array *schema_array = NULL, *value_array = NULL;
1349    JSON_Object *schema_object = NULL, *value_object = NULL;
1350    JSON_Value_Type schema_type = JSONError, value_type = JSONError;
1351    const char *key = NULL;
1352    size_t i = 0, count = 0;
1353    if (schema == NULL || value == NULL)
1354        return JSONFailure;
1355    schema_type = json_value_get_type(schema);
1356    value_type = json_value_get_type(value);
1357    if (schema_type != value_type && schema_type != JSONNull) /* null represents all values */
1358        return JSONFailure;
1359    switch (schema_type) {
1360        case JSONArray:
1361            schema_array = json_value_get_array(schema);
1362            value_array = json_value_get_array(value);
1363            count = json_array_get_count(schema_array);
1364            if (count == 0)
1365                return JSONSuccess; /* Empty array allows all types */
1366            /* Get first value from array, rest is ignored */
1367            temp_schema_value = json_array_get_value(schema_array, 0);
1368            for (i = 0; i < json_array_get_count(value_array); i++) {
1369                temp_value = json_array_get_value(value_array, i);
1370                if (json_validate(temp_schema_value, temp_value) == 0) {
1371                    return JSONFailure;
1372                }
1373            }
1374            return JSONSuccess;
1375        case JSONObject:
1376            schema_object = json_value_get_object(schema);
1377            value_object = json_value_get_object(value);
1378            count = json_object_get_count(schema_object);
1379            if (count == 0)
1380                return JSONSuccess; /* Empty object allows all objects */
1381            else if (json_object_get_count(value_object) < count)
1382                return JSONFailure; /* Tested object mustn't have less name-value pairs than schema */
1383            for (i = 0; i < count; i++) {
1384                key = json_object_get_name(schema_object, i);
1385                temp_schema_value = json_object_get_value(schema_object, key);
1386                temp_value = json_object_get_value(value_object, key);
1387                if (temp_value == NULL)
1388                    return JSONFailure;
1389                if (json_validate(temp_schema_value, temp_value) == JSONFailure)
1390                    return JSONFailure;
1391            }
1392            return JSONSuccess;
1393        case JSONString: case JSONNumber: case JSONBoolean: case JSONNull:
1394            return JSONSuccess; /* equality already tested before switch */
1395        case JSONError: default:
1396            return JSONFailure;
1397    }
1398}
1399
1400JSON_Status json_value_equals(const JSON_Value *a, const JSON_Value *b) {
1401    JSON_Object *a_object = NULL, *b_object = NULL;
1402    JSON_Array *a_array = NULL, *b_array = NULL;
1403    const char *a_string = NULL, *b_string = NULL;
1404    const char *key = NULL;
1405    size_t a_count = 0, b_count = 0, i = 0;
1406    JSON_Value_Type a_type, b_type;
1407    a_type = json_value_get_type(a);
1408    b_type = json_value_get_type(b);
1409    if (a_type != b_type) {
1410        return 0;
1411    }
1412    switch (a_type) {
1413        case JSONArray:
1414            a_array = json_value_get_array(a);
1415            b_array = json_value_get_array(b);
1416            a_count = json_array_get_count(a_array);
1417            b_count = json_array_get_count(b_array);
1418            if (a_count != b_count) {
1419                return 0;
1420            }
1421            for (i = 0; i < a_count; i++) {
1422                if (!json_value_equals(json_array_get_value(a_array, i),
1423                                       json_array_get_value(b_array, i))) {
1424                    return 0;
1425                }
1426            }
1427            return 1;
1428        case JSONObject:
1429            a_object = json_value_get_object(a);
1430            b_object = json_value_get_object(b);
1431            a_count = json_object_get_count(a_object);
1432            b_count = json_object_get_count(b_object);
1433            if (a_count != b_count) {
1434                return 0;
1435            }
1436            for (i = 0; i < a_count; i++) {
1437                key = json_object_get_name(a_object, i);
1438                if (!json_value_equals(json_object_get_value(a_object, key),
1439                                       json_object_get_value(b_object, key))) {
1440                    return 0;
1441                }
1442            }
1443            return 1;
1444        case JSONString:
1445            a_string = json_value_get_string(a);
1446            b_string = json_value_get_string(b);
1447            return strcmp(a_string, b_string) == 0;
1448        case JSONBoolean:
1449            return json_value_get_boolean(a) == json_value_get_boolean(b);
1450        case JSONNumber:
1451            return fabs(json_value_get_number(a) - json_value_get_number(b)) < 0.000001; /* EPSILON */
1452        case JSONError:
1453            return 1;
1454        case JSONNull:
1455            return 1;
1456        default:
1457            return 1;
1458    }
1459}
1460
1461JSON_Value_Type json_type(const JSON_Value *value) {
1462    return json_value_get_type(value);
1463}
1464
1465JSON_Object * json_object (const JSON_Value *value) {
1466    return json_value_get_object(value);
1467}
1468
1469JSON_Array * json_array  (const JSON_Value *value) {
1470    return json_value_get_array(value);
1471}
1472
1473const char * json_string (const JSON_Value *value) {
1474    return json_value_get_string(value);
1475}
1476
1477double json_number (const JSON_Value *value) {
1478    return json_value_get_number(value);
1479}
1480
1481int json_boolean(const JSON_Value *value) {
1482    return json_value_get_boolean(value);
1483}
Note: See TracBrowser for help on using the repository browser.