]> iEval git - fdkaac.git/blame - src/parson.c
update ChangeLog
[fdkaac.git] / src / parson.c
CommitLineData
cbb23cdb 1/*
2 Parson ( http://kgabis.github.com/parson/ )
3 Copyright (c) 2012 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
24#include "parson.h"
25
26#include <stdio.h>
27#include <stdlib.h>
28#include <string.h>
29#include <ctype.h>
30
31#define ERROR 0
32#define SUCCESS 1
33#define STARTING_CAPACITY 15
34#define ARRAY_MAX_CAPACITY 122880 /* 15*(2^13) */
35#define OBJECT_MAX_CAPACITY 960 /* 15*(2^6) */
36#define MAX_NESTING 19
37#define sizeof_token(a) (sizeof(a) - 1)
38#define skip_char(str) ((*str)++)
39#define skip_whitespaces(str) while (isspace(**string)) { skip_char(string); }
40#define MAX(a, b) ((a) > (b) ? (a) : (b))
41
42#define parson_malloc(a) malloc(a)
43#define parson_free(a) free((void*)a)
44#define parson_realloc(a, b) realloc(a, b)
45
46/* Type definitions */
47typedef union json_value_value {
48 const char *string;
49 double number;
50 JSON_Object *object;
51 JSON_Array *array;
52 int boolean;
53 int null;
54} JSON_Value_Value;
55
56struct json_value_t {
57 JSON_Value_Type type;
58 JSON_Value_Value value;
59};
60
61struct json_object_t {
62 const char **names;
63 JSON_Value **values;
64 size_t count;
65 size_t capacity;
66};
67
68struct json_array_t {
69 JSON_Value **items;
70 size_t count;
71 size_t capacity;
72};
73
74/* Various */
75static int try_realloc(void **ptr, size_t new_size);
76static char * parson_strndup(const char *string, size_t n);
77static int is_utf(const unsigned char *string);
78static int is_decimal(const char *string, size_t length);
79
80/* JSON Object */
81static JSON_Object * json_object_init(void);
82static int json_object_add(JSON_Object *object, const char *name, JSON_Value *value);
83static int json_object_resize(JSON_Object *object, size_t capacity);
84static JSON_Value * json_object_nget_value(const JSON_Object *object, const char *name, size_t n);
85static void json_object_free(JSON_Object *object);
86
87/* JSON Array */
88static JSON_Array * json_array_init(void);
89static int json_array_add(JSON_Array *array, JSON_Value *value);
90static int json_array_resize(JSON_Array *array, size_t capacity);
91static void json_array_free(JSON_Array *array);
92
93/* JSON Value */
94static JSON_Value * json_value_init_object(void);
95static JSON_Value * json_value_init_array(void);
96static JSON_Value * json_value_init_string(const char *string);
97static JSON_Value * json_value_init_number(double number);
98static JSON_Value * json_value_init_boolean(int boolean);
99static JSON_Value * json_value_init_null(void);
100
101/* Parser */
102static void skip_quotes(const char **string);
103static const char * get_processed_string(const char **string);
104static JSON_Value * parse_object_value(const char **string, size_t nesting);
105static JSON_Value * parse_array_value(const char **string, size_t nesting);
106static JSON_Value * parse_string_value(const char **string);
107static JSON_Value * parse_boolean_value(const char **string);
108static JSON_Value * parse_number_value(const char **string);
109static JSON_Value * parse_null_value(const char **string);
110static JSON_Value * parse_value(const char **string, size_t nesting);
111
112/* Various */
113static int try_realloc(void **ptr, size_t new_size) {
114 void *reallocated_ptr = parson_realloc(*ptr, new_size);
115 if (!reallocated_ptr) { return ERROR; }
116 *ptr = reallocated_ptr;
117 return SUCCESS;
118}
119
120static char * parson_strndup(const char *string, size_t n) {
121 char *output_string = (char*)parson_malloc(n + 1);
122 if (!output_string) { return NULL; }
123 output_string[n] = '\0';
124 strncpy(output_string, string, n);
125 return output_string;
126}
127
128static int is_utf(const unsigned char *s) {
129 return isxdigit(s[0]) && isxdigit(s[1]) && isxdigit(s[2]) && isxdigit(s[3]);
130}
131
132static int is_decimal(const char *string, size_t length) {
133 if (length > 1 && string[0] == '0' && string[1] != '.') { return 0; }
134 if (length > 2 && !strncmp(string, "-0", 2) && string[2] != '.') { return 0; }
135 while (length--) { if (strchr("xX", string[length])) { return 0; } }
136 return 1;
137}
138
139/* JSON Object */
140static JSON_Object * json_object_init(void) {
141 JSON_Object *new_obj = (JSON_Object*)parson_malloc(sizeof(JSON_Object));
142 if (!new_obj) { return NULL; }
143 new_obj->names = (const char**)NULL;
144 new_obj->values = (JSON_Value**)NULL;
145 new_obj->capacity = 0;
146 new_obj->count = 0;
147 return new_obj;
148}
149
150static int json_object_add(JSON_Object *object, const char *name, JSON_Value *value) {
151 size_t index;
152 if (object->count >= object->capacity) {
153 size_t new_capacity = MAX(object->capacity * 2, STARTING_CAPACITY);
154 if (new_capacity > OBJECT_MAX_CAPACITY) { return ERROR; }
155 if (json_object_resize(object, new_capacity) == ERROR) { return ERROR; }
156 }
157 if (json_object_get_value(object, name) != NULL) { return ERROR; }
158 index = object->count;
159 object->names[index] = parson_strndup(name, strlen(name));
160 if (!object->names[index]) { return ERROR; }
161 object->values[index] = value;
162 object->count++;
163 return SUCCESS;
164}
165
166static int json_object_resize(JSON_Object *object, size_t capacity) {
167 if (try_realloc((void**)&object->names, capacity * sizeof(char*)) == ERROR) { return ERROR; }
168 if (try_realloc((void**)&object->values, capacity * sizeof(JSON_Value*)) == ERROR) { return ERROR; }
169 object->capacity = capacity;
170 return SUCCESS;
171}
172
173static JSON_Value * json_object_nget_value(const JSON_Object *object, const char *name, size_t n) {
174 size_t i, name_length;
175 for (i = 0; i < json_object_get_count(object); i++) {
176 name_length = strlen(object->names[i]);
177 if (name_length != n) { continue; }
178 if (strncmp(object->names[i], name, n) == 0) { return object->values[i]; }
179 }
180 return NULL;
181}
182
183static void json_object_free(JSON_Object *object) {
184 while(object->count--) {
185 parson_free(object->names[object->count]);
186 json_value_free(object->values[object->count]);
187 }
188 parson_free(object->names);
189 parson_free(object->values);
190 parson_free(object);
191}
192
193/* JSON Array */
194static JSON_Array * json_array_init(void) {
195 JSON_Array *new_array = (JSON_Array*)parson_malloc(sizeof(JSON_Array));
196 if (!new_array) { return NULL; }
197 new_array->items = (JSON_Value**)NULL;
198 new_array->capacity = 0;
199 new_array->count = 0;
200 return new_array;
201}
202
203static int json_array_add(JSON_Array *array, JSON_Value *value) {
204 if (array->count >= array->capacity) {
205 size_t new_capacity = MAX(array->capacity * 2, STARTING_CAPACITY);
206 if (new_capacity > ARRAY_MAX_CAPACITY) { return ERROR; }
207 if (!json_array_resize(array, new_capacity)) { return ERROR; }
208 }
209 array->items[array->count] = value;
210 array->count++;
211 return SUCCESS;
212}
213
214static int json_array_resize(JSON_Array *array, size_t capacity) {
215 if (try_realloc((void**)&array->items, capacity * sizeof(JSON_Value*)) == ERROR) { return ERROR; }
216 array->capacity = capacity;
217 return SUCCESS;
218}
219
220static void json_array_free(JSON_Array *array) {
221 while (array->count--) { json_value_free(array->items[array->count]); }
222 parson_free(array->items);
223 parson_free(array);
224}
225
226/* JSON Value */
227static JSON_Value * json_value_init_object(void) {
228 JSON_Value *new_value = (JSON_Value*)parson_malloc(sizeof(JSON_Value));
229 if (!new_value) { return NULL; }
230 new_value->type = JSONObject;
231 new_value->value.object = json_object_init();
232 if (!new_value->value.object) { parson_free(new_value); return NULL; }
233 return new_value;
234}
235
236static JSON_Value * json_value_init_array(void) {
237 JSON_Value *new_value = (JSON_Value*)parson_malloc(sizeof(JSON_Value));
238 if (!new_value) { return NULL; }
239 new_value->type = JSONArray;
240 new_value->value.array = json_array_init();
241 if (!new_value->value.array) { parson_free(new_value); return NULL; }
242 return new_value;
243}
244
245static JSON_Value * json_value_init_string(const char *string) {
246 JSON_Value *new_value = (JSON_Value*)parson_malloc(sizeof(JSON_Value));
247 if (!new_value) { return NULL; }
248 new_value->type = JSONString;
249 new_value->value.string = string;
250 return new_value;
251}
252
253static JSON_Value * json_value_init_number(double number) {
254 JSON_Value *new_value = (JSON_Value*)parson_malloc(sizeof(JSON_Value));
255 if (!new_value) { return NULL; }
256 new_value->type = JSONNumber;
257 new_value->value.number = number;
258 return new_value;
259}
260
261static JSON_Value * json_value_init_boolean(int boolean) {
262 JSON_Value *new_value = (JSON_Value*)parson_malloc(sizeof(JSON_Value));
263 if (!new_value) { return NULL; }
264 new_value->type = JSONBoolean;
265 new_value->value.boolean = boolean;
266 return new_value;
267}
268
269static JSON_Value * json_value_init_null(void) {
270 JSON_Value *new_value = (JSON_Value*)parson_malloc(sizeof(JSON_Value));
271 if (!new_value) { return NULL; }
272 new_value->type = JSONNull;
273 return new_value;
274}
275
276/* Parser */
277static void skip_quotes(const char **string) {
278 skip_char(string);
279 while (**string != '\"') {
280 if (**string == '\0') { return; }
281 if (**string == '\\') { skip_char(string); if (**string == '\0') { return; }}
282 skip_char(string);
283 }
284 skip_char(string);
285}
286
287/* Returns contents of a string inside double quotes and parses escaped
288 characters inside.
289 Example: "\u006Corem ipsum" -> lorem ipsum */
290static const char * get_processed_string(const char **string) {
291 const char *string_start = *string;
292 char *output, *processed_ptr, *unprocessed_ptr, current_char;
293 unsigned int utf_val;
294 skip_quotes(string);
295 if (**string == '\0') { return NULL; }
296 output = parson_strndup(string_start + 1, *string - string_start - 2);
297 if (!output) { return NULL; }
298 processed_ptr = unprocessed_ptr = output;
299 while (*unprocessed_ptr) {
300 current_char = *unprocessed_ptr;
301 if (current_char == '\\') {
302 unprocessed_ptr++;
303 current_char = *unprocessed_ptr;
304 switch (current_char) {
305 case '\"': case '\\': case '/': break;
306 case 'b': current_char = '\b'; break;
307 case 'f': current_char = '\f'; break;
308 case 'n': current_char = '\n'; break;
309 case 'r': current_char = '\r'; break;
310 case 't': current_char = '\t'; break;
311 case 'u':
312 unprocessed_ptr++;
313 if (!is_utf((const unsigned char*)unprocessed_ptr) ||
314 sscanf(unprocessed_ptr, "%4x", &utf_val) == EOF) {
315 parson_free(output); return NULL;
316 }
317 if (utf_val < 0x80) {
318 current_char = utf_val;
319 } else if (utf_val < 0x800) {
320 *processed_ptr++ = (utf_val >> 6) | 0xC0;
321 current_char = ((utf_val | 0x80) & 0xBF);
322 } else {
323 *processed_ptr++ = (utf_val >> 12) | 0xE0;
324 *processed_ptr++ = (((utf_val >> 6) | 0x80) & 0xBF);
325 current_char = ((utf_val | 0x80) & 0xBF);
326 }
327 unprocessed_ptr += 3;
328 break;
329 default:
330 parson_free(output);
331 return NULL;
332 break;
333 }
334 } else if ((unsigned char)current_char < 0x20) { /* 0x00-0x19 are invalid characters for json string (http://www.ietf.org/rfc/rfc4627.txt) */
335 parson_free(output);
336 return NULL;
337 }
338 *processed_ptr = current_char;
339 processed_ptr++;
340 unprocessed_ptr++;
341 }
342 *processed_ptr = '\0';
343 if (try_realloc((void**)&output, strlen(output) + 1) == ERROR) { return NULL; }
344 return output;
345}
346
347static JSON_Value * parse_value(const char **string, size_t nesting) {
348 if (nesting > MAX_NESTING) { return NULL; }
349 skip_whitespaces(string);
350 switch (**string) {
351 case '{':
352 return parse_object_value(string, nesting + 1);
353 case '[':
354 return parse_array_value(string, nesting + 1);
355 case '\"':
356 return parse_string_value(string);
357 case 'f': case 't':
358 return parse_boolean_value(string);
359 case '-':
360 case '0': case '1': case '2': case '3': case '4':
361 case '5': case '6': case '7': case '8': case '9':
362 return parse_number_value(string);
363 case 'n':
364 return parse_null_value(string);
365 default:
366 return NULL;
367 }
368}
369
370static JSON_Value * parse_object_value(const char **string, size_t nesting) {
371 JSON_Value *output_value = json_value_init_object(), *new_value = NULL;
372 JSON_Object *output_object = json_value_get_object(output_value);
373 const char *new_key = NULL;
374 if (!output_value) { return NULL; }
375 skip_char(string);
376 skip_whitespaces(string);
377 if (**string == '}') { skip_char(string); return output_value; } /* empty object */
378 while (**string != '\0') {
379 new_key = get_processed_string(string);
380 skip_whitespaces(string);
381 if (!new_key || **string != ':') {
382 json_value_free(output_value);
383 return NULL;
384 }
385 skip_char(string);
386 new_value = parse_value(string, nesting);
387 if (!new_value) {
388 parson_free(new_key);
389 json_value_free(output_value);
390 return NULL;
391 }
392 if(!json_object_add(output_object, new_key, new_value)) {
393 parson_free(new_key);
394 parson_free(new_value);
395 json_value_free(output_value);
396 return NULL;
397 }
398 parson_free(new_key);
399 skip_whitespaces(string);
400 if (**string != ',') { break; }
401 skip_char(string);
402 skip_whitespaces(string);
403 }
404 skip_whitespaces(string);
405 if (**string != '}' || /* Trim object after parsing is over */
406 json_object_resize(output_object, json_object_get_count(output_object)) == ERROR) {
407 json_value_free(output_value);
408 return NULL;
409 }
410 skip_char(string);
411 return output_value;
412}
413
414static JSON_Value * parse_array_value(const char **string, size_t nesting) {
415 JSON_Value *output_value = json_value_init_array(), *new_array_value = NULL;
416 JSON_Array *output_array = json_value_get_array(output_value);
417 if (!output_value) { return NULL; }
418 skip_char(string);
419 skip_whitespaces(string);
420 if (**string == ']') { /* empty array */
421 skip_char(string);
422 return output_value;
423 }
424 while (**string != '\0') {
425 new_array_value = parse_value(string, nesting);
426 if (!new_array_value) {
427 json_value_free(output_value);
428 return NULL;
429 }
430 if(json_array_add(output_array, new_array_value) == ERROR) {
431 parson_free(new_array_value);
432 json_value_free(output_value);
433 return NULL;
434 }
435 skip_whitespaces(string);
436 if (**string != ',') { break; }
437 skip_char(string);
438 skip_whitespaces(string);
439 }
440 skip_whitespaces(string);
441 if (**string != ']' || /* Trim array after parsing is over */
442 json_array_resize(output_array, json_array_get_count(output_array)) == ERROR) {
443 json_value_free(output_value);
444 return NULL;
445 }
446 skip_char(string);
447 return output_value;
448}
449
450static JSON_Value * parse_string_value(const char **string) {
451 const char *new_string = get_processed_string(string);
452 if (!new_string) { return NULL; }
453 return json_value_init_string(new_string);
454}
455
456static JSON_Value * parse_boolean_value(const char **string) {
457 size_t true_token_size = sizeof_token("true");
458 size_t false_token_size = sizeof_token("false");
459 if (strncmp("true", *string, true_token_size) == 0) {
460 *string += true_token_size;
461 return json_value_init_boolean(1);
462 } else if (strncmp("false", *string, false_token_size) == 0) {
463 *string += false_token_size;
464 return json_value_init_boolean(0);
465 }
466 return NULL;
467}
468
469static JSON_Value * parse_number_value(const char **string) {
470 char *end;
471 double number = strtod(*string, &end);
472 JSON_Value *output_value;
473 if (is_decimal(*string, end - *string)) {
474 *string = end;
475 output_value = json_value_init_number(number);
476 } else {
477 output_value = NULL;
478 }
479 return output_value;
480}
481
482static JSON_Value * parse_null_value(const char **string) {
483 size_t token_size = sizeof_token("null");
484 if (strncmp("null", *string, token_size) == 0) {
485 *string += token_size;
486 return json_value_init_null();
487 }
488 return NULL;
489}
490
491/* Parser API */
492JSON_Value * json_parse_file(const char *filename) {
493 FILE *fp = fopen(filename, "r");
494 size_t file_size;
495 char *file_contents;
496 JSON_Value *output_value;
497 if (!fp) { return NULL; }
498 fseek(fp, 0L, SEEK_END);
499 file_size = ftell(fp);
500 rewind(fp);
501 file_contents = (char*)parson_malloc(sizeof(char) * (file_size + 1));
502 if (!file_contents) { fclose(fp); return NULL; }
503 fread(file_contents, file_size, 1, fp);
504 fclose(fp);
505 file_contents[file_size] = '\0';
506 output_value = json_parse_string(file_contents);
507 parson_free(file_contents);
508 return output_value;
509}
510
511JSON_Value * json_parse_string(const char *string) {
512 if (!string || (*string != '{' && *string != '[')) { return NULL; }
513 return parse_value((const char**)&string, 0);
514}
515
516/* JSON Object API */
517JSON_Value * json_object_get_value(const JSON_Object *object, const char *name) {
518 return json_object_nget_value(object, name, strlen(name));
519}
520
521const char * json_object_get_string(const JSON_Object *object, const char *name) {
522 return json_value_get_string(json_object_get_value(object, name));
523}
524
525double json_object_get_number(const JSON_Object *object, const char *name) {
526 return json_value_get_number(json_object_get_value(object, name));
527}
528
529JSON_Object * json_object_get_object(const JSON_Object *object, const char *name) {
530 return json_value_get_object(json_object_get_value(object, name));
531}
532
533JSON_Array * json_object_get_array(const JSON_Object *object, const char *name) {
534 return json_value_get_array(json_object_get_value(object, name));
535}
536
537int json_object_get_boolean(const JSON_Object *object, const char *name) {
538 return json_value_get_boolean(json_object_get_value(object, name));
539}
540
541JSON_Value * json_object_dotget_value(const JSON_Object *object, const char *name) {
542 const char *dot_position = strchr(name, '.');
543 if (!dot_position) { return json_object_get_value(object, name); }
544 object = json_value_get_object(json_object_nget_value(object, name, dot_position - name));
545 return json_object_dotget_value(object, dot_position + 1);
546}
547
548const char * json_object_dotget_string(const JSON_Object *object, const char *name) {
549 return json_value_get_string(json_object_dotget_value(object, name));
550}
551
552double json_object_dotget_number(const JSON_Object *object, const char *name) {
553 return json_value_get_number(json_object_dotget_value(object, name));
554}
555
556JSON_Object * json_object_dotget_object(const JSON_Object *object, const char *name) {
557 return json_value_get_object(json_object_dotget_value(object, name));
558}
559
560JSON_Array * json_object_dotget_array(const JSON_Object *object, const char *name) {
561 return json_value_get_array(json_object_dotget_value(object, name));
562}
563
564int json_object_dotget_boolean(const JSON_Object *object, const char *name) {
565 return json_value_get_boolean(json_object_dotget_value(object, name));
566}
567
568size_t json_object_get_count(const JSON_Object *object) {
569 return object ? object->count : 0;
570}
571
572const char * json_object_get_name(const JSON_Object *object, size_t index) {
573 if (index >= json_object_get_count(object)) { return NULL; }
574 return object->names[index];
575}
576
577/* JSON Array API */
578JSON_Value * json_array_get_value(const JSON_Array *array, size_t index) {
579 if (index >= json_array_get_count(array)) { return NULL; }
580 return array->items[index];
581}
582
583const char * json_array_get_string(const JSON_Array *array, size_t index) {
584 return json_value_get_string(json_array_get_value(array, index));
585}
586
587double json_array_get_number(const JSON_Array *array, size_t index) {
588 return json_value_get_number(json_array_get_value(array, index));
589}
590
591JSON_Object * json_array_get_object(const JSON_Array *array, size_t index) {
592 return json_value_get_object(json_array_get_value(array, index));
593}
594
595JSON_Array * json_array_get_array(const JSON_Array *array, size_t index) {
596 return json_value_get_array(json_array_get_value(array, index));
597}
598
599int json_array_get_boolean(const JSON_Array *array, size_t index) {
600 return json_value_get_boolean(json_array_get_value(array, index));
601}
602
603size_t json_array_get_count(const JSON_Array *array) {
604 return array ? array->count : 0;
605}
606
607/* JSON Value API */
608JSON_Value_Type json_value_get_type(const JSON_Value *value) {
609 return value ? value->type : JSONError;
610}
611
612JSON_Object * json_value_get_object(const JSON_Value *value) {
613 return json_value_get_type(value) == JSONObject ? value->value.object : NULL;
614}
615
616JSON_Array * json_value_get_array(const JSON_Value *value) {
617 return json_value_get_type(value) == JSONArray ? value->value.array : NULL;
618}
619
620const char * json_value_get_string(const JSON_Value *value) {
621 return json_value_get_type(value) == JSONString ? value->value.string : NULL;
622}
623
624double json_value_get_number(const JSON_Value *value) {
625 return json_value_get_type(value) == JSONNumber ? value->value.number : 0;
626}
627
628int json_value_get_boolean(const JSON_Value *value) {
629 return json_value_get_type(value) == JSONBoolean ? value->value.boolean : -1;
630}
631
632void json_value_free(JSON_Value *value) {
633 switch (json_value_get_type(value)) {
634 case JSONObject:
635 json_object_free(value->value.object);
636 break;
637 case JSONString:
638 if (value->value.string) { parson_free(value->value.string); }
639 break;
640 case JSONArray:
641 json_array_free(value->value.array);
642 break;
643 default:
644 break;
645 }
646 parson_free(value);
647}
This page took 0.109264 seconds and 4 git commands to generate.