]>
iEval git - fdkaac.git/blob - src/parson.c
2 Parson ( http://kgabis.github.com/parson/ )
3 Copyright (c) 2012 Krzysztof Gabis
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:
12 The above copyright notice and this permission notice shall be included in
13 all copies or substantial portions of the Software.
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
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))
42 #define parson_malloc(a) malloc(a)
43 #define parson_free(a) free((void*)a)
44 #define parson_realloc(a, b) realloc(a, b)
46 /* Type definitions */
47 typedef union json_value_value
{
58 JSON_Value_Value value
;
61 struct json_object_t
{
75 static int try_realloc(void **ptr
, size_t new_size
);
76 static char * parson_strndup(const char *string
, size_t n
);
77 static int is_utf(const unsigned char *string
);
78 static int is_decimal(const char *string
, size_t length
);
81 static JSON_Object
* json_object_init(void);
82 static int json_object_add(JSON_Object
*object
, const char *name
, JSON_Value
*value
);
83 static int json_object_resize(JSON_Object
*object
, size_t capacity
);
84 static JSON_Value
* json_object_nget_value(const JSON_Object
*object
, const char *name
, size_t n
);
85 static void json_object_free(JSON_Object
*object
);
88 static JSON_Array
* json_array_init(void);
89 static int json_array_add(JSON_Array
*array
, JSON_Value
*value
);
90 static int json_array_resize(JSON_Array
*array
, size_t capacity
);
91 static void json_array_free(JSON_Array
*array
);
94 static JSON_Value
* json_value_init_object(void);
95 static JSON_Value
* json_value_init_array(void);
96 static JSON_Value
* json_value_init_string(const char *string
);
97 static JSON_Value
* json_value_init_number(double number
);
98 static JSON_Value
* json_value_init_boolean(int boolean
);
99 static JSON_Value
* json_value_init_null(void);
102 static void skip_quotes(const char **string
);
103 static const char * get_processed_string(const char **string
);
104 static JSON_Value
* parse_object_value(const char **string
, size_t nesting
);
105 static JSON_Value
* parse_array_value(const char **string
, size_t nesting
);
106 static JSON_Value
* parse_string_value(const char **string
);
107 static JSON_Value
* parse_boolean_value(const char **string
);
108 static JSON_Value
* parse_number_value(const char **string
);
109 static JSON_Value
* parse_null_value(const char **string
);
110 static JSON_Value
* parse_value(const char **string
, size_t nesting
);
113 static 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
;
120 static 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
;
128 static int is_utf(const unsigned char *s
) {
129 return isxdigit(s
[0]) && isxdigit(s
[1]) && isxdigit(s
[2]) && isxdigit(s
[3]);
132 static 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; } }
140 static 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;
150 static int json_object_add(JSON_Object
*object
, const char *name
, JSON_Value
*value
) {
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
; }
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
;
166 static 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
;
173 static 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
]; }
183 static 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
]);
188 parson_free(object
->names
);
189 parson_free(object
->values
);
194 static 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;
203 static 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
; }
209 array
->items
[array
->count
] = value
;
214 static 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
;
220 static void json_array_free(JSON_Array
*array
) {
221 while (array
->count
--) { json_value_free(array
->items
[array
->count
]); }
222 parson_free(array
->items
);
227 static 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
; }
236 static 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
; }
245 static 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
;
253 static 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
;
261 static 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
;
269 static 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
;
277 static void skip_quotes(const char **string
) {
279 while (**string
!= '\"') {
280 if (**string
== '\0') { return; }
281 if (**string
== '\\') { skip_char(string
); if (**string
== '\0') { return; }}
287 /* Returns contents of a string inside double quotes and parses escaped
289 Example: "\u006Corem ipsum" -> lorem ipsum */
290 static 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
;
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
== '\\') {
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;
313 if (!is_utf((const unsigned char*)unprocessed_ptr
) ||
314 sscanf(unprocessed_ptr
, "%4x", &utf_val
) == EOF
) {
315 parson_free(output
); return NULL
;
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);
323 *processed_ptr
++ = (utf_val
>> 12) | 0xE0;
324 *processed_ptr
++ = (((utf_val
>> 6) | 0x80) & 0xBF);
325 current_char
= ((utf_val
| 0x80) & 0xBF);
327 unprocessed_ptr
+= 3;
334 } else if ((unsigned char)current_char
< 0x20) { /* 0x00-0x19 are invalid characters for json string (http://www.ietf.org/rfc/rfc4627.txt) */
338 *processed_ptr
= current_char
;
342 *processed_ptr
= '\0';
343 if (try_realloc((void**)&output
, strlen(output
) + 1) == ERROR
) { return NULL
; }
347 static JSON_Value
* parse_value(const char **string
, size_t nesting
) {
348 if (nesting
> MAX_NESTING
) { return NULL
; }
349 skip_whitespaces(string
);
352 return parse_object_value(string
, nesting
+ 1);
354 return parse_array_value(string
, nesting
+ 1);
356 return parse_string_value(string
);
358 return parse_boolean_value(string
);
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
);
364 return parse_null_value(string
);
370 static 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
; }
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
);
386 new_value
= parse_value(string
, nesting
);
388 parson_free(new_key
);
389 json_value_free(output_value
);
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
);
398 parson_free(new_key
);
399 skip_whitespaces(string
);
400 if (**string
!= ',') { break; }
402 skip_whitespaces(string
);
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
);
414 static 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
; }
419 skip_whitespaces(string
);
420 if (**string
== ']') { /* empty array */
424 while (**string
!= '\0') {
425 new_array_value
= parse_value(string
, nesting
);
426 if (!new_array_value
) {
427 json_value_free(output_value
);
430 if(json_array_add(output_array
, new_array_value
) == ERROR
) {
431 parson_free(new_array_value
);
432 json_value_free(output_value
);
435 skip_whitespaces(string
);
436 if (**string
!= ',') { break; }
438 skip_whitespaces(string
);
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
);
450 static 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
);
456 static 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);
469 static JSON_Value
* parse_number_value(const char **string
) {
471 double number
= strtod(*string
, &end
);
472 JSON_Value
*output_value
;
473 if (is_decimal(*string
, end
- *string
)) {
475 output_value
= json_value_init_number(number
);
482 static 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();
492 JSON_Value
* json_parse_file(const char *filename
) {
493 FILE *fp
= fopen(filename
, "r");
496 JSON_Value
*output_value
;
497 if (!fp
) { return NULL
; }
498 fseek(fp
, 0L, SEEK_END
);
499 file_size
= ftell(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
);
505 file_contents
[file_size
] = '\0';
506 output_value
= json_parse_string(file_contents
);
507 parson_free(file_contents
);
511 JSON_Value
* json_parse_string(const char *string
) {
512 if (!string
|| (*string
!= '{' && *string
!= '[')) { return NULL
; }
513 return parse_value((const char**)&string
, 0);
516 /* JSON Object API */
517 JSON_Value
* json_object_get_value(const JSON_Object
*object
, const char *name
) {
518 return json_object_nget_value(object
, name
, strlen(name
));
521 const char * json_object_get_string(const JSON_Object
*object
, const char *name
) {
522 return json_value_get_string(json_object_get_value(object
, name
));
525 double json_object_get_number(const JSON_Object
*object
, const char *name
) {
526 return json_value_get_number(json_object_get_value(object
, name
));
529 JSON_Object
* json_object_get_object(const JSON_Object
*object
, const char *name
) {
530 return json_value_get_object(json_object_get_value(object
, name
));
533 JSON_Array
* json_object_get_array(const JSON_Object
*object
, const char *name
) {
534 return json_value_get_array(json_object_get_value(object
, name
));
537 int json_object_get_boolean(const JSON_Object
*object
, const char *name
) {
538 return json_value_get_boolean(json_object_get_value(object
, name
));
541 JSON_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);
548 const char * json_object_dotget_string(const JSON_Object
*object
, const char *name
) {
549 return json_value_get_string(json_object_dotget_value(object
, name
));
552 double json_object_dotget_number(const JSON_Object
*object
, const char *name
) {
553 return json_value_get_number(json_object_dotget_value(object
, name
));
556 JSON_Object
* json_object_dotget_object(const JSON_Object
*object
, const char *name
) {
557 return json_value_get_object(json_object_dotget_value(object
, name
));
560 JSON_Array
* json_object_dotget_array(const JSON_Object
*object
, const char *name
) {
561 return json_value_get_array(json_object_dotget_value(object
, name
));
564 int json_object_dotget_boolean(const JSON_Object
*object
, const char *name
) {
565 return json_value_get_boolean(json_object_dotget_value(object
, name
));
568 size_t json_object_get_count(const JSON_Object
*object
) {
569 return object
? object
->count
: 0;
572 const 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
];
578 JSON_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
];
583 const char * json_array_get_string(const JSON_Array
*array
, size_t index
) {
584 return json_value_get_string(json_array_get_value(array
, index
));
587 double json_array_get_number(const JSON_Array
*array
, size_t index
) {
588 return json_value_get_number(json_array_get_value(array
, index
));
591 JSON_Object
* json_array_get_object(const JSON_Array
*array
, size_t index
) {
592 return json_value_get_object(json_array_get_value(array
, index
));
595 JSON_Array
* json_array_get_array(const JSON_Array
*array
, size_t index
) {
596 return json_value_get_array(json_array_get_value(array
, index
));
599 int json_array_get_boolean(const JSON_Array
*array
, size_t index
) {
600 return json_value_get_boolean(json_array_get_value(array
, index
));
603 size_t json_array_get_count(const JSON_Array
*array
) {
604 return array
? array
->count
: 0;
608 JSON_Value_Type
json_value_get_type(const JSON_Value
*value
) {
609 return value
? value
->type
: JSONError
;
612 JSON_Object
* json_value_get_object(const JSON_Value
*value
) {
613 return json_value_get_type(value
) == JSONObject
? value
->value
.object
: NULL
;
616 JSON_Array
* json_value_get_array(const JSON_Value
*value
) {
617 return json_value_get_type(value
) == JSONArray
? value
->value
.array
: NULL
;
620 const char * json_value_get_string(const JSON_Value
*value
) {
621 return json_value_get_type(value
) == JSONString
? value
->value
.string
: NULL
;
624 double json_value_get_number(const JSON_Value
*value
) {
625 return json_value_get_type(value
) == JSONNumber
? value
->value
.number
: 0;
628 int json_value_get_boolean(const JSON_Value
*value
) {
629 return json_value_get_type(value
) == JSONBoolean
? value
->value
.boolean
: -1;
632 void json_value_free(JSON_Value
*value
) {
633 switch (json_value_get_type(value
)) {
635 json_object_free(value
->value
.object
);
638 if (value
->value
.string
) { parson_free(value
->value
.string
); }
641 json_array_free(value
->value
.array
);
This page took 0.093406 seconds and 4 git commands to generate.