demux: libmp4: add and parse 3DDS uuid
[vlc.git] / modules / misc / webservices / json.c
blob0afc01c614c0c075b3850558d019e20a2b890894
1 /* vim: set et ts=3 sw=3 ft=c:
3 * Copyright (C) 2012 James McLaughlin et al. All rights reserved.
4 * https://github.com/udp/json-parser
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
30 #include "json.h"
32 #ifdef _MSC_VER
33 #ifndef _CRT_SECURE_NO_WARNINGS
34 #define _CRT_SECURE_NO_WARNINGS
35 #endif
36 #endif
38 #ifdef __cplusplus
39 const struct _json_value json_value_none; /* zero-d by ctor */
40 #else
41 const struct _json_value json_value_none = { 0, 0, { 0 }, { 0 } };
42 #endif
44 #include <stdlib.h>
45 #include <stdio.h>
46 #include <string.h>
47 #include <ctype.h>
48 #include <math.h>
50 typedef unsigned short json_uchar;
52 static unsigned char hex_value (json_char c)
54 if (c >= 'A' && c <= 'F')
55 return (c - 'A') + 10;
57 if (c >= 'a' && c <= 'f')
58 return (c - 'a') + 10;
60 if (c >= '0' && c <= '9')
61 return c - '0';
63 return 0xFF;
66 typedef struct
68 json_settings settings;
69 int first_pass;
71 unsigned long used_memory;
73 unsigned int uint_max;
74 unsigned long ulong_max;
76 } json_state;
78 static void * json_alloc (json_state * state, unsigned long size, int zero)
80 void * mem;
82 if ((state->ulong_max - state->used_memory) < size)
83 return 0;
85 if (state->settings.max_memory
86 && (state->used_memory += size) > state->settings.max_memory)
88 return 0;
91 if (! (mem = zero ? calloc (size, 1) : malloc (size)))
92 return 0;
94 return mem;
97 static int new_value
98 (json_state * state, json_value ** top, json_value ** root, json_value ** alloc, json_type type)
100 json_value * value;
101 int values_size;
103 if (!state->first_pass)
105 value = *top = *alloc;
106 *alloc = (*alloc)->_reserved.next_alloc;
108 if (!*root)
109 *root = value;
111 switch (value->type)
113 case json_array:
115 if (! (value->u.array.values = (json_value **) json_alloc
116 (state, value->u.array.length * sizeof (json_value *), 0)) )
118 return 0;
121 value->u.array.length = 0;
122 break;
124 case json_object:
126 values_size = sizeof (*value->u.object.values) * value->u.object.length;
128 if (! ((*(void **) &value->u.object.values) = json_alloc
129 (state, values_size + ((unsigned long) value->u.object.values), 0)) )
131 return 0;
134 value->_reserved.object_mem = (*(char **) &value->u.object.values) + values_size;
136 value->u.object.length = 0;
137 break;
139 case json_string:
141 if (! (value->u.string.ptr = (json_char *) json_alloc
142 (state, (value->u.string.length + 1) * sizeof (json_char), 0)) )
144 return 0;
147 value->u.string.length = 0;
148 break;
150 default:
151 break;
154 return 1;
157 value = (json_value *) json_alloc (state, sizeof (json_value), 1);
159 if (!value)
160 return 0;
162 if (!*root)
163 *root = value;
165 value->type = type;
166 value->parent = *top;
168 if (*alloc)
169 (*alloc)->_reserved.next_alloc = value;
171 *alloc = *top = value;
173 return 1;
176 #define e_off \
177 ((int) (i - cur_line_begin))
179 #define whitespace \
180 case '\n': ++ cur_line; cur_line_begin = i; \
181 /* fall through */ \
182 case ' ': case '\t': case '\r'
184 #define string_add(b) \
185 do { if (!state.first_pass) string [string_length] = b; ++ string_length; } while (0);
187 static const long
188 flag_next = 1, flag_reproc = 2, flag_need_comma = 4, flag_seek_value = 8,
189 flag_escaped = 16, flag_string = 32, flag_need_colon = 64, flag_done = 128,
190 flag_num_negative = 256, flag_num_zero = 512, flag_num_e = 1024,
191 flag_num_e_got_sign = 2048, flag_num_e_negative = 4096;
193 json_value * json_parse_ex (json_settings * settings, const json_char * json, char * error_buf)
195 json_char error [128];
196 unsigned int cur_line;
197 const json_char * cur_line_begin, * i;
198 json_value * top, * root, * alloc = 0;
199 json_state state;
200 long flags;
201 long num_digits = 0, num_fraction = 0, num_e = 0;
203 error[0] = '\0';
205 memset (&state, 0, sizeof (json_state));
206 memcpy (&state.settings, settings, sizeof (json_settings));
208 memset (&state.uint_max, 0xFF, sizeof (state.uint_max));
209 memset (&state.ulong_max, 0xFF, sizeof (state.ulong_max));
211 state.uint_max -= 8; /* limit of how much can be added before next check */
212 state.ulong_max -= 8;
214 for (state.first_pass = 1; state.first_pass >= 0; -- state.first_pass)
216 json_uchar uchar;
217 unsigned char uc_b1, uc_b2, uc_b3, uc_b4;
218 json_char * string = NULL;
219 unsigned int string_length = 0;
221 top = root = 0;
222 flags = flag_seek_value;
224 cur_line = 1;
225 cur_line_begin = json;
227 for (i = json ;; ++ i)
229 json_char b = *i;
231 if (flags & flag_done)
233 if (!b)
234 break;
236 switch (b)
238 whitespace:
239 continue;
241 default:
242 sprintf (error, "%d:%d: Trailing garbage: `%c`", cur_line, e_off, b);
243 goto e_failed;
247 if (flags & flag_string)
249 if (!b)
250 { sprintf (error, "Unexpected EOF in string (at %d:%d)", cur_line, e_off);
251 goto e_failed;
254 if (string_length > state.uint_max)
255 goto e_overflow;
257 if (flags & flag_escaped)
259 flags &= ~ flag_escaped;
261 switch (b)
263 case 'b': string_add ('\b'); break;
264 case 'f': string_add ('\f'); break;
265 case 'n': string_add ('\n'); break;
266 case 'r': string_add ('\r'); break;
267 case 't': string_add ('\t'); break;
268 case 'u':
270 if ((uc_b1 = hex_value (*++ i)) == 0xFF || (uc_b2 = hex_value (*++ i)) == 0xFF
271 || (uc_b3 = hex_value (*++ i)) == 0xFF || (uc_b4 = hex_value (*++ i)) == 0xFF)
273 sprintf (error, "Invalid character value `%c` (at %d:%d)", b, cur_line, e_off);
274 goto e_failed;
277 uc_b1 = uc_b1 * 16 + uc_b2;
278 uc_b2 = uc_b3 * 16 + uc_b4;
280 uchar = ((json_char) uc_b1) * 256 + uc_b2;
282 if (sizeof (json_char) >= sizeof (json_uchar) || (uc_b1 == 0 && uc_b2 <= 0x7F))
284 string_add ((json_char) uchar);
285 break;
288 if (uchar <= 0x7FF)
290 if (state.first_pass)
291 string_length += 2;
292 else
293 { string [string_length ++] = 0xC0 | ((uc_b2 & 0xC0) >> 6) | ((uc_b1 & 0x7) << 2);
294 string [string_length ++] = 0x80 | (uc_b2 & 0x3F);
297 break;
300 if (state.first_pass)
301 string_length += 3;
302 else
303 { string [string_length ++] = 0xE0 | ((uc_b1 & 0xF0) >> 4);
304 string [string_length ++] = 0x80 | ((uc_b1 & 0xF) << 2) | ((uc_b2 & 0xC0) >> 6);
305 string [string_length ++] = 0x80 | (uc_b2 & 0x3F);
308 break;
310 default:
311 string_add (b);
314 continue;
317 if (b == '\\')
319 flags |= flag_escaped;
320 continue;
323 if (b == '"')
325 if (!state.first_pass)
326 string [string_length] = 0;
328 flags &= ~ flag_string;
329 string = 0;
331 switch (top->type)
333 case json_string:
335 top->u.string.length = string_length;
336 flags |= flag_next;
338 break;
340 case json_object:
342 if (state.first_pass)
343 (*(json_char **) &top->u.object.values) += string_length + 1;
344 else
346 top->u.object.values [top->u.object.length].name
347 = (json_char *) top->_reserved.object_mem;
349 (*(json_char **) &top->_reserved.object_mem) += string_length + 1;
352 flags |= flag_seek_value | flag_need_colon;
353 continue;
355 default:
356 break;
359 else
361 string_add (b);
362 continue;
366 if (flags & flag_seek_value)
368 switch (b)
370 whitespace:
371 continue;
373 case ']':
375 if (top->type == json_array)
376 flags = (flags & ~ (flag_need_comma | flag_seek_value)) | flag_next;
377 else if (!state.settings.settings & json_relaxed_commas)
378 { sprintf (error, "%d:%d: Unexpected ]", cur_line, e_off);
379 goto e_failed;
382 break;
384 default:
386 if (flags & flag_need_comma)
388 if (b == ',')
389 { flags &= ~ flag_need_comma;
390 continue;
392 else
393 { sprintf (error, "%d:%d: Expected , before %c", cur_line, e_off, b);
394 goto e_failed;
398 if (flags & flag_need_colon)
400 if (b == ':')
401 { flags &= ~ flag_need_colon;
402 continue;
404 else
405 { sprintf (error, "%d:%d: Expected : before %c", cur_line, e_off, b);
406 goto e_failed;
410 flags &= ~ flag_seek_value;
412 switch (b)
414 case '{':
416 if (!new_value (&state, &top, &root, &alloc, json_object))
417 goto e_alloc_failure;
419 continue;
421 case '[':
423 if (!new_value (&state, &top, &root, &alloc, json_array))
424 goto e_alloc_failure;
426 flags |= flag_seek_value;
427 continue;
429 case '"':
431 if (!new_value (&state, &top, &root, &alloc, json_string))
432 goto e_alloc_failure;
434 flags |= flag_string;
436 string = top->u.string.ptr;
437 string_length = 0;
439 continue;
441 case 't':
443 if (*(++ i) != 'r' || *(++ i) != 'u' || *(++ i) != 'e')
444 goto e_unknown_value;
446 if (!new_value (&state, &top, &root, &alloc, json_boolean))
447 goto e_alloc_failure;
449 top->u.boolean = 1;
451 flags |= flag_next;
452 break;
454 case 'f':
456 if (*(++ i) != 'a' || *(++ i) != 'l' || *(++ i) != 's' || *(++ i) != 'e')
457 goto e_unknown_value;
459 if (!new_value (&state, &top, &root, &alloc, json_boolean))
460 goto e_alloc_failure;
462 flags |= flag_next;
463 break;
465 case 'n':
467 if (*(++ i) != 'u' || *(++ i) != 'l' || *(++ i) != 'l')
468 goto e_unknown_value;
470 if (!new_value (&state, &top, &root, &alloc, json_null))
471 goto e_alloc_failure;
473 flags |= flag_next;
474 break;
476 default:
478 if (isdigit (b) || b == '-')
480 if (!new_value (&state, &top, &root, &alloc, json_integer))
481 goto e_alloc_failure;
483 if (!state.first_pass)
485 while (isdigit (b) || b == '+' || b == '-'
486 || b == 'e' || b == 'E' || b == '.')
488 b = *++ i;
491 flags |= flag_next | flag_reproc;
492 break;
495 flags &= ~ (flag_num_negative | flag_num_e |
496 flag_num_e_got_sign | flag_num_e_negative |
497 flag_num_zero);
499 num_digits = 0;
500 num_fraction = 0;
501 num_e = 0;
503 if (b != '-')
505 flags |= flag_reproc;
506 break;
509 flags |= flag_num_negative;
510 continue;
512 else
513 { sprintf (error, "%d:%d: Unexpected %c when seeking value", cur_line, e_off, b);
514 goto e_failed;
519 else
521 switch (top->type)
523 case json_object:
525 switch (b)
527 whitespace:
528 continue;
530 case '"':
532 if (flags & flag_need_comma && (!state.settings.settings & json_relaxed_commas))
534 sprintf (error, "%d:%d: Expected , before \"", cur_line, e_off);
535 goto e_failed;
538 flags |= flag_string;
540 string = (json_char *) top->_reserved.object_mem;
541 string_length = 0;
543 break;
545 case '}':
547 flags = (flags & ~ flag_need_comma) | flag_next;
548 break;
550 case ',':
552 if (flags & flag_need_comma)
554 flags &= ~ flag_need_comma;
555 break;
558 /* fall through */
559 default:
561 sprintf (error, "%d:%d: Unexpected `%c` in object", cur_line, e_off, b);
562 goto e_failed;
565 break;
567 case json_integer:
568 case json_double:
570 if (isdigit (b))
572 ++ num_digits;
574 if (top->type == json_integer || flags & flag_num_e)
576 if (! (flags & flag_num_e))
578 if (flags & flag_num_zero)
579 { sprintf (error, "%d:%d: Unexpected `0` before `%c`", cur_line, e_off, b);
580 goto e_failed;
583 if (num_digits == 1 && b == '0')
584 flags |= flag_num_zero;
586 else
588 flags |= flag_num_e_got_sign;
589 num_e = (num_e * 10) + (b - '0');
590 continue;
593 top->u.integer = (top->u.integer * 10) + (b - '0');
594 continue;
597 num_fraction = (num_fraction * 10) + (b - '0');
598 continue;
601 if (b == '+' || b == '-')
603 if ( (flags & flag_num_e) && !(flags & flag_num_e_got_sign))
605 flags |= flag_num_e_got_sign;
607 if (b == '-')
608 flags |= flag_num_e_negative;
610 continue;
613 else if (b == '.' && top->type == json_integer)
615 if (!num_digits)
616 { sprintf (error, "%d:%d: Expected digit before `.`", cur_line, e_off);
617 goto e_failed;
620 top->type = json_double;
621 top->u.dbl = (double) top->u.integer;
623 num_digits = 0;
624 continue;
627 if (! (flags & flag_num_e))
629 if (top->type == json_double)
631 if (!num_digits)
632 { sprintf (error, "%d:%d: Expected digit after `.`", cur_line, e_off);
633 goto e_failed;
636 top->u.dbl += ((double) num_fraction) / (pow ( (double) 10.0, (double) num_digits));
639 if (b == 'e' || b == 'E')
641 flags |= flag_num_e;
643 if (top->type == json_integer)
645 top->type = json_double;
646 top->u.dbl = (double) top->u.integer;
649 num_digits = 0;
650 flags &= ~ flag_num_zero;
652 continue;
655 else
657 if (!num_digits)
658 { sprintf (error, "%d:%d: Expected digit after `e`", cur_line, e_off);
659 goto e_failed;
662 top->u.dbl *= pow (10, (double) (flags & flag_num_e_negative ? - num_e : num_e));
665 if (flags & flag_num_negative)
667 if (top->type == json_integer)
668 top->u.integer = - top->u.integer;
669 else
670 top->u.dbl = - top->u.dbl;
673 flags |= flag_next | flag_reproc;
674 break;
676 default:
677 break;
681 if (flags & flag_reproc)
683 flags &= ~ flag_reproc;
684 -- i;
687 if (flags & flag_next)
689 flags = (flags & ~ flag_next) | flag_need_comma;
691 if (!top->parent)
693 /* root value done */
695 flags |= flag_done;
696 continue;
699 if (top->parent->type == json_array)
700 flags |= flag_seek_value;
702 if (!state.first_pass)
704 json_value * parent = top->parent;
706 switch (parent->type)
708 case json_object:
710 parent->u.object.values
711 [parent->u.object.length].value = top;
713 break;
715 case json_array:
717 parent->u.array.values
718 [parent->u.array.length] = top;
720 break;
722 default:
723 break;
727 if ( (++ top->parent->u.array.length) > state.uint_max)
728 goto e_overflow;
730 top = top->parent;
732 continue;
736 alloc = root;
739 return root;
741 e_unknown_value:
743 sprintf (error, "%d:%d: Unknown value", cur_line, e_off);
744 goto e_failed;
746 e_alloc_failure:
748 strcpy (error, "Memory allocation failure");
749 goto e_failed;
751 e_overflow:
753 sprintf (error, "%d:%d: Too long (caught overflow)", cur_line, e_off);
754 goto e_failed;
756 e_failed:
758 if (error_buf)
760 if (*error)
761 strcpy (error_buf, error);
762 else
763 strcpy (error_buf, "Unknown error");
766 if (state.first_pass)
767 alloc = root;
769 while (alloc)
771 top = alloc->_reserved.next_alloc;
772 free (alloc);
773 alloc = top;
776 if (!state.first_pass)
777 json_value_free (root);
779 return 0;
782 json_value * json_parse (const json_char * json)
784 json_settings settings;
785 memset (&settings, 0, sizeof (json_settings));
787 return json_parse_ex (&settings, json, 0);
790 void json_value_free (json_value * value)
792 json_value * cur_value;
794 if (!value)
795 return;
797 value->parent = 0;
799 while (value)
801 switch (value->type)
803 case json_array:
805 if (!value->u.array.length)
807 free (value->u.array.values);
808 break;
811 value = value->u.array.values [-- value->u.array.length];
812 continue;
814 case json_object:
816 if (!value->u.object.length)
818 free (value->u.object.values);
819 break;
822 value = value->u.object.values [-- value->u.object.length].value;
823 continue;
825 case json_string:
827 free (value->u.string.ptr);
828 break;
830 default:
831 break;
834 cur_value = value;
835 value = value->parent;
836 free (cur_value);