source: trunk/libtransmission/JSON_parser.c @ 8409

Last change on this file since 8409 was 8409, checked in by charles, 13 years ago

(trunk libT) update our copy of Jean's JSON parser

File size: 31.2 KB
Line 
1/* JSON_parser.c */
2
3/* 2007-08-24 */
4
5/*
6Copyright (c) 2005 JSON.org
7
8Permission is hereby granted, free of charge, to any person obtaining a copy
9of this software and associated documentation files (the "Software"), to deal
10in the Software without restriction, including without limitation the rights
11to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12copies of the Software, and to permit persons to whom the Software is
13furnished to do so, subject to the following conditions:
14
15The above copyright notice and this permission notice shall be included in all
16copies or substantial portions of the Software.
17
18The Software shall be used for Good, not Evil.
19
20THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26SOFTWARE.
27*/
28
29/*
30    Callbacks, comments, Unicode handling by Jean Gressmann (jean@0x42.de), 2007-2009.
31   
32    For the added features the license above applies also.
33   
34    Changelog:
35        2009-05-14
36            Fixed float parsing bug related to a locale being set that didn't
37            use '.' as decimal point character (charles@transmissionbt.com).
38           
39        2008-10-14
40            Renamed states.IN to states.IT to avoid name clash which IN macro
41            defined in windef.h (alexey.pelykh@gmail.com)
42           
43        2008-07-19
44            Removed some duplicate code & debugging variable (charles@transmissionbt.com)
45       
46        2008-05-28
47            Made JSON_value structure ansi C compliant. This bug was report by
48            trisk@acm.jhu.edu
49       
50        2008-05-20
51            Fixed bug reported by charles@transmissionbt.com where the switching
52            from static to dynamic parse buffer did not copy the static parse
53            buffer's content.
54*/
55
56
57
58#include <assert.h>
59#include <ctype.h>
60#include <float.h>
61#include <stddef.h>
62#include <stdio.h>
63#include <stdlib.h>
64#include <string.h>
65#include <locale.h>
66
67#include "JSON_parser.h"
68#include "ConvertUTF.h"
69
70#ifdef _MSC_VER
71#   if _MSC_VER >= 1400 /* Visual Studio 2005 and up */
72#      pragma warning(disable:4996) // unsecure sscanf
73#   endif
74#endif
75
76
77#define true  1
78#define false 0
79#define __   -1     /* the universal error code */
80
81/* values chosen so that the object size is approx equal to one page (4K) */
82#ifndef JSON_PARSER_STACK_SIZE
83#   define JSON_PARSER_STACK_SIZE 128
84#endif
85
86#ifndef JSON_PARSER_PARSE_BUFFER_SIZE
87#   define JSON_PARSER_PARSE_BUFFER_SIZE 3500
88#endif
89
90
91struct JSON_parser_struct {
92    JSON_parser_callback callback;
93    void* ctx;
94    signed char state, before_comment_state, type, escaped, comment, allow_comments, handle_floats_manually;
95    UTF16 utf16_decode_buffer[2];
96    long depth;
97    long top;
98    signed char* stack;
99    long stack_capacity;
100    char decimal_point;
101    char* parse_buffer;
102    size_t parse_buffer_capacity;
103    size_t parse_buffer_count;
104    size_t comment_begin_offset;
105    signed char static_stack[JSON_PARSER_STACK_SIZE];
106    char static_parse_buffer[JSON_PARSER_PARSE_BUFFER_SIZE];
107};
108
109#define COUNTOF(x) (sizeof(x)/sizeof(x[0]))
110
111/*
112    Characters are mapped into these character classes. This allows for
113    a significant reduction in the size of the state transition table.
114*/
115
116
117
118enum classes {
119    C_SPACE,  /* space */
120    C_WHITE,  /* other whitespace */
121    C_LCURB,  /* {  */
122    C_RCURB,  /* } */
123    C_LSQRB,  /* [ */
124    C_RSQRB,  /* ] */
125    C_COLON,  /* : */
126    C_COMMA,  /* , */
127    C_QUOTE,  /* " */
128    C_BACKS,  /* \ */
129    C_SLASH,  /* / */
130    C_PLUS,   /* + */
131    C_MINUS,  /* - */
132    C_POINT,  /* . */
133    C_ZERO ,  /* 0 */
134    C_DIGIT,  /* 123456789 */
135    C_LOW_A,  /* a */
136    C_LOW_B,  /* b */
137    C_LOW_C,  /* c */
138    C_LOW_D,  /* d */
139    C_LOW_E,  /* e */
140    C_LOW_F,  /* f */
141    C_LOW_L,  /* l */
142    C_LOW_N,  /* n */
143    C_LOW_R,  /* r */
144    C_LOW_S,  /* s */
145    C_LOW_T,  /* t */
146    C_LOW_U,  /* u */
147    C_ABCDF,  /* ABCDF */
148    C_E,      /* E */
149    C_ETC,    /* everything else */
150    C_STAR,   /* * */   
151    NR_CLASSES
152};
153
154static int ascii_class[128] = {
155/*
156    This array maps the 128 ASCII characters into character classes.
157    The remaining Unicode characters should be mapped to C_ETC.
158    Non-whitespace control characters are errors.
159*/
160    __,      __,      __,      __,      __,      __,      __,      __,
161    __,      C_WHITE, C_WHITE, __,      __,      C_WHITE, __,      __,
162    __,      __,      __,      __,      __,      __,      __,      __,
163    __,      __,      __,      __,      __,      __,      __,      __,
164
165    C_SPACE, C_ETC,   C_QUOTE, C_ETC,   C_ETC,   C_ETC,   C_ETC,   C_ETC,
166    C_ETC,   C_ETC,   C_STAR,   C_PLUS,  C_COMMA, C_MINUS, C_POINT, C_SLASH,
167    C_ZERO,  C_DIGIT, C_DIGIT, C_DIGIT, C_DIGIT, C_DIGIT, C_DIGIT, C_DIGIT,
168    C_DIGIT, C_DIGIT, C_COLON, C_ETC,   C_ETC,   C_ETC,   C_ETC,   C_ETC,
169
170    C_ETC,   C_ABCDF, C_ABCDF, C_ABCDF, C_ABCDF, C_E,     C_ABCDF, C_ETC,
171    C_ETC,   C_ETC,   C_ETC,   C_ETC,   C_ETC,   C_ETC,   C_ETC,   C_ETC,
172    C_ETC,   C_ETC,   C_ETC,   C_ETC,   C_ETC,   C_ETC,   C_ETC,   C_ETC,
173    C_ETC,   C_ETC,   C_ETC,   C_LSQRB, C_BACKS, C_RSQRB, C_ETC,   C_ETC,
174
175    C_ETC,   C_LOW_A, C_LOW_B, C_LOW_C, C_LOW_D, C_LOW_E, C_LOW_F, C_ETC,
176    C_ETC,   C_ETC,   C_ETC,   C_ETC,   C_LOW_L, C_ETC,   C_LOW_N, C_ETC,
177    C_ETC,   C_ETC,   C_LOW_R, C_LOW_S, C_LOW_T, C_LOW_U, C_ETC,   C_ETC,
178    C_ETC,   C_ETC,   C_ETC,   C_LCURB, C_ETC,   C_RCURB, C_ETC,   C_ETC
179};
180
181
182/*
183    The state codes.
184*/
185enum states {
186    GO,  /* start    */
187    OK,  /* ok       */
188    OB,  /* object   */
189    KE,  /* key      */
190    CO,  /* colon    */
191    VA,  /* value    */
192    AR,  /* array    */
193    ST,  /* string   */
194    ES,  /* escape   */
195    U1,  /* u1       */
196    U2,  /* u2       */
197    U3,  /* u3       */
198    U4,  /* u4       */
199    MI,  /* minus    */
200    ZE,  /* zero     */
201    IT,  /* integer  */
202    FR,  /* fraction */
203    E1,  /* e        */
204    E2,  /* ex       */
205    E3,  /* exp      */
206    T1,  /* tr       */
207    T2,  /* tru      */
208    T3,  /* true     */
209    F1,  /* fa       */
210    F2,  /* fal      */
211    F3,  /* fals     */
212    F4,  /* false    */
213    N1,  /* nu       */
214    N2,  /* nul      */
215    N3,  /* null     */
216    C1,  /* /        */
217    C2,  /* / *     */
218    C3,  /* *        */
219    FX,  /* *.* *eE* */
220    D1,  /* second UTF-16 character decoding started by \ */
221    D2,  /* second UTF-16 character proceeded by u */
222    NR_STATES
223};
224
225enum actions
226{
227    CB = -10, /* comment begin */
228    CE = -11, /* comment end */
229    FA = -12, /* false */
230    TR = -13, /* false */
231    NU = -14, /* null */
232    DE = -15, /* double detected by exponent e E */
233    DF = -16, /* double detected by fraction . */
234    SB = -17, /* string begin */
235    MX = -18, /* integer detected by minus */
236    ZX = -19, /* integer detected by zero */
237    IX = -20, /* integer detected by 1-9 */
238    EX = -21, /* next char is escaped */
239    UC = -22, /* Unicode character read */
240};
241
242
243static int state_transition_table[NR_STATES][NR_CLASSES] = {
244/*
245    The state transition table takes the current state and the current symbol,
246    and returns either a new state or an action. An action is represented as a
247    negative number. A JSON text is accepted if at the end of the text the
248    state is OK and if the mode is MODE_DONE.
249
250                 white                                      1-9                                   ABCDF  etc
251             space |  {  }  [  ]  :  ,  "  \  /  +  -  .  0  |  a  b  c  d  e  f  l  n  r  s  t  u  |  E  |  * */
252/*start  GO*/ {GO,GO,-6,__,-5,__,__,__,__,__,CB,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__},
253/*ok     OK*/ {OK,OK,__,-8,__,-7,__,-3,__,__,CB,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__},
254/*object OB*/ {OB,OB,__,-9,__,__,__,__,SB,__,CB,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__},
255/*key    KE*/ {KE,KE,__,__,__,__,__,__,SB,__,CB,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__},
256/*colon  CO*/ {CO,CO,__,__,__,__,-2,__,__,__,CB,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__},
257/*value  VA*/ {VA,VA,-6,__,-5,__,__,__,SB,__,CB,__,MX,__,ZX,IX,__,__,__,__,__,FA,__,NU,__,__,TR,__,__,__,__,__},
258/*array  AR*/ {AR,AR,-6,__,-5,-7,__,__,SB,__,CB,__,MX,__,ZX,IX,__,__,__,__,__,FA,__,NU,__,__,TR,__,__,__,__,__},
259/*string ST*/ {ST,__,ST,ST,ST,ST,ST,ST,-4,EX,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST},
260/*escape ES*/ {__,__,__,__,__,__,__,__,ST,ST,ST,__,__,__,__,__,__,ST,__,__,__,ST,__,ST,ST,__,ST,U1,__,__,__,__},
261/*u1     U1*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,U2,U2,U2,U2,U2,U2,U2,U2,__,__,__,__,__,__,U2,U2,__,__},
262/*u2     U2*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,U3,U3,U3,U3,U3,U3,U3,U3,__,__,__,__,__,__,U3,U3,__,__},
263/*u3     U3*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,U4,U4,U4,U4,U4,U4,U4,U4,__,__,__,__,__,__,U4,U4,__,__},
264/*u4     U4*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,UC,UC,UC,UC,UC,UC,UC,UC,__,__,__,__,__,__,UC,UC,__,__},
265/*minus  MI*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,ZE,IT,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__},
266/*zero   ZE*/ {OK,OK,__,-8,__,-7,__,-3,__,__,CB,__,__,DF,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__},
267/*int    IT*/ {OK,OK,__,-8,__,-7,__,-3,__,__,CB,__,__,DF,IT,IT,__,__,__,__,DE,__,__,__,__,__,__,__,__,DE,__,__},
268/*frac   FR*/ {OK,OK,__,-8,__,-7,__,-3,__,__,CB,__,__,__,FR,FR,__,__,__,__,E1,__,__,__,__,__,__,__,__,E1,__,__},
269/*e      E1*/ {__,__,__,__,__,__,__,__,__,__,__,E2,E2,__,E3,E3,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__},
270/*ex     E2*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,E3,E3,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__},
271/*exp    E3*/ {OK,OK,__,-8,__,-7,__,-3,__,__,__,__,__,__,E3,E3,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__},
272/*tr     T1*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,T2,__,__,__,__,__,__,__},
273/*tru    T2*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,T3,__,__,__,__},
274/*true   T3*/ {__,__,__,__,__,__,__,__,__,__,CB,__,__,__,__,__,__,__,__,__,OK,__,__,__,__,__,__,__,__,__,__,__},
275/*fa     F1*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,F2,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__},
276/*fal    F2*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,F3,__,__,__,__,__,__,__,__,__},
277/*fals   F3*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,F4,__,__,__,__,__,__},
278/*false  F4*/ {__,__,__,__,__,__,__,__,__,__,CB,__,__,__,__,__,__,__,__,__,OK,__,__,__,__,__,__,__,__,__,__,__},
279/*nu     N1*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,N2,__,__,__,__},
280/*nul    N2*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,N3,__,__,__,__,__,__,__,__,__},
281/*null   N3*/ {__,__,__,__,__,__,__,__,__,__,CB,__,__,__,__,__,__,__,__,__,__,__,OK,__,__,__,__,__,__,__,__,__},
282/*/      C1*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,C2},
283/*/*     C2*/ {C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C3},
284/**      C3*/ {C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,CE,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C3},
285/*_.     FX*/ {OK,OK,__,-8,__,-7,__,-3,__,__,__,__,__,__,FR,FR,__,__,__,__,E1,__,__,__,__,__,__,__,__,E1,__,__},
286/*\      D1*/ {__,__,__,__,__,__,__,__,__,D2,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__},
287/*\      D2*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,U1,__,__,__,__},
288};
289
290
291/*
292    These modes can be pushed on the stack.
293*/
294enum modes {
295    MODE_ARRAY = 1, 
296    MODE_DONE = 2, 
297    MODE_KEY = 3,   
298    MODE_OBJECT = 4
299};
300
301static int
302push(JSON_parser jc, int mode)
303{
304/*
305    Push a mode onto the stack. Return false if there is overflow.
306*/
307    jc->top += 1;
308    if (jc->depth < 0) {
309        if (jc->top >= jc->stack_capacity) {
310            size_t bytes_to_allocate;
311            jc->stack_capacity *= 2;
312            bytes_to_allocate = jc->stack_capacity * sizeof(jc->static_stack[0]);
313            if (jc->stack == &jc->static_stack[0]) {
314                jc->stack = (signed char*)malloc(bytes_to_allocate);
315                memcpy(jc->stack, jc->static_stack, sizeof(jc->static_stack));
316            } else {
317                jc->stack = (signed char*)realloc(jc->stack, bytes_to_allocate);
318            }
319        }
320    } else {
321        if (jc->top >= jc->depth) {
322            return false;
323        }
324    }
325   
326    jc->stack[jc->top] = mode;
327    return true;
328}
329
330
331static int
332pop(JSON_parser jc, int mode)
333{
334/*
335    Pop the stack, assuring that the current mode matches the expectation.
336    Return false if there is underflow or if the modes mismatch.
337*/
338    if (jc->top < 0 || jc->stack[jc->top] != mode) {
339        return false;
340    }
341    jc->top -= 1;
342    return true;
343}
344
345
346#define parse_buffer_clear(jc) \
347    do {\
348        jc->parse_buffer_count = 0;\
349        jc->parse_buffer[0] = 0;\
350    } while (0)
351   
352#define parse_buffer_pop_back_char(jc)\
353    do {\
354        assert(jc->parse_buffer_count >= 1);\
355        --jc->parse_buffer_count;\
356        jc->parse_buffer[jc->parse_buffer_count] = 0;\
357    } while (0)   
358   
359void delete_JSON_parser(JSON_parser jc)
360{
361    if (jc) {
362        if (jc->stack != &jc->static_stack[0]) {
363            free((void*)jc->stack);
364        }
365        if (jc->parse_buffer != &jc->static_parse_buffer[0]) {
366            free((void*)jc->parse_buffer);
367        }
368        free((void*)jc);
369     }   
370}
371
372
373JSON_parser
374new_JSON_parser(JSON_config* config)
375{
376/*
377    new_JSON_parser starts the checking process by constructing a JSON_parser
378    object. It takes a depth parameter that restricts the level of maximum
379    nesting.
380
381    To continue the process, call JSON_parser_char for each character in the
382    JSON text, and then call JSON_parser_done to obtain the final result.
383    These functions are fully reentrant.
384*/
385
386    int depth = 0;
387    JSON_config default_config;
388   
389    JSON_parser jc = malloc(sizeof(struct JSON_parser_struct));
390   
391    memset(jc, 0, sizeof(*jc));
392   
393   
394    /* initialize configuration */
395    init_JSON_config(&default_config);
396   
397    /* set to default configuration if none was provided */
398    if (config == NULL) {
399        config = &default_config;
400    }
401
402    depth = config->depth;
403   
404    /* We need to be able to push at least one object */
405    if (depth == 0) {
406        depth = 1;
407    }
408   
409    jc->state = GO;
410    jc->top = -1;
411   
412    /* Do we want non-bound stack? */
413    if (depth > 0) {
414        jc->stack_capacity = depth;
415        jc->depth = depth;
416        if (depth <= (int)COUNTOF(jc->static_stack)) {
417            jc->stack = &jc->static_stack[0];
418        } else {
419            jc->stack = (signed char*)malloc(jc->stack_capacity * sizeof(jc->static_stack[0]));
420        }
421    } else {
422        jc->stack_capacity = COUNTOF(jc->static_stack);
423        jc->depth = -1;
424        jc->stack = &jc->static_stack[0];
425    }
426   
427    /* set parser to start */
428    push(jc, MODE_DONE);
429   
430    /* set up the parse buffer */
431    jc->parse_buffer = &jc->static_parse_buffer[0];
432    jc->parse_buffer_capacity = COUNTOF(jc->static_parse_buffer);
433    parse_buffer_clear(jc);
434   
435    /* set up callback, comment & float handling */
436    jc->callback = config->callback;
437    jc->ctx = config->callback_ctx;
438    jc->allow_comments = config->allow_comments != 0;
439    jc->handle_floats_manually = config->handle_floats_manually != 0;
440   
441    /* set up decimal point */
442    jc->decimal_point = *localeconv()->decimal_point;
443   
444    return jc;
445}
446
447static void grow_parse_buffer(JSON_parser jc)
448{
449    size_t bytes_to_allocate;
450    jc->parse_buffer_capacity *= 2;
451    bytes_to_allocate = jc->parse_buffer_capacity * sizeof(jc->parse_buffer[0]);
452    if (jc->parse_buffer == &jc->static_parse_buffer[0]) {
453        jc->parse_buffer = (char*)malloc(bytes_to_allocate);
454        memcpy(jc->parse_buffer, jc->static_parse_buffer, jc->parse_buffer_count);
455    } else {
456        jc->parse_buffer = (char*)realloc(jc->parse_buffer, bytes_to_allocate);
457    }
458}
459
460#define parse_buffer_push_back_char(jc, c)\
461    do {\
462        if (jc->parse_buffer_count + 1 >= jc->parse_buffer_capacity) grow_parse_buffer(jc);\
463        jc->parse_buffer[jc->parse_buffer_count++] = c;\
464        jc->parse_buffer[jc->parse_buffer_count]   = 0;\
465    } while (0)
466
467#define assert_is_non_container_type(jc) \
468    assert( \
469        jc->type == JSON_T_NULL || \
470        jc->type == JSON_T_FALSE || \
471        jc->type == JSON_T_TRUE || \
472        jc->type == JSON_T_FLOAT || \
473        jc->type == JSON_T_INTEGER || \
474        jc->type == JSON_T_STRING)
475   
476
477static int parse_parse_buffer(JSON_parser jc)
478{
479    if (jc->callback) {
480        JSON_value value, *arg = NULL;
481       
482        if (jc->type != JSON_T_NONE) {
483            assert_is_non_container_type(jc);
484       
485            switch(jc->type) {
486                case JSON_T_FLOAT:
487                    arg = &value;
488                    if (jc->handle_floats_manually) {
489                        value.vu.str.value = jc->parse_buffer;
490                        value.vu.str.length = jc->parse_buffer_count;
491                    } else { 
492                        /*sscanf(jc->parse_buffer, "%Lf", &value.vu.float_value);*/
493                       
494                        /* not checking with end pointer b/c there may be trailing ws */
495                        value.vu.float_value = strtold(jc->parse_buffer, NULL);
496                    }
497                    break;
498                case JSON_T_INTEGER:
499                    arg = &value;
500                    sscanf(jc->parse_buffer, JSON_PARSER_INTEGER_SSCANF_TOKEN, &value.vu.integer_value);
501                    break;
502                case JSON_T_STRING:
503                    arg = &value;
504                    value.vu.str.value = jc->parse_buffer;
505                    value.vu.str.length = jc->parse_buffer_count;
506                    break;
507            }
508           
509            if (!(*jc->callback)(jc->ctx, jc->type, arg)) {
510                return false;
511            }
512        }
513    }
514   
515    parse_buffer_clear(jc);
516   
517    return true;
518}
519
520static int decode_unicode_char(JSON_parser jc)
521{
522    const unsigned chars = jc->utf16_decode_buffer[0] ? 2 : 1;
523    int i;
524    UTF16 *uc = chars == 1 ? &jc->utf16_decode_buffer[0] : &jc->utf16_decode_buffer[1];
525    UTF16 x;
526    char* p;
527   
528    assert(jc->parse_buffer_count >= 6);
529   
530    p = &jc->parse_buffer[jc->parse_buffer_count - 4];
531   
532    for (i = 0; i < 4; ++i, ++p) {
533        x = *p;
534       
535        if (x >= 'a') {
536            x -= ('a' - 10);
537        } else if (x >= 'A') {
538            x -= ('A' - 10);
539        } else {
540            x &= ~((UTF16) 0x30);
541        }
542       
543        assert(x < 16);
544       
545        *uc |= x << ((3u - i) << 2);
546    }
547   
548    /* clear UTF-16 char form buffer */
549    jc->parse_buffer_count -= 6;
550    jc->parse_buffer[jc->parse_buffer_count] = 0;
551   
552    /* attempt decoding ... */
553    {
554        UTF8* dec_start = (UTF8*)&jc->parse_buffer[jc->parse_buffer_count];
555        UTF8* dec_start_dup = dec_start;
556        UTF8* dec_end = dec_start + 6;
557       
558        const UTF16* enc_start = &jc->utf16_decode_buffer[0];
559        const UTF16* enc_end = enc_start + chars;
560   
561        const ConversionResult result = ConvertUTF16toUTF8(
562            &enc_start, enc_end, &dec_start, dec_end, strictConversion);
563       
564        const size_t new_chars = dec_start - dec_start_dup;
565       
566        /* was it a surrogate UTF-16 char? */
567        if (chars == 1 && result == sourceExhausted) {
568            return true;
569        }
570       
571        if (result != conversionOK) {
572            return false;
573        }
574       
575        /* NOTE: clear decode buffer to resume string reading,
576           otherwise we continue to read UTF-16 */
577        jc->utf16_decode_buffer[0] = 0;
578       
579        assert(new_chars <= 6);
580       
581        jc->parse_buffer_count += new_chars;
582        jc->parse_buffer[jc->parse_buffer_count] = 0;
583    }
584   
585    return true;
586}
587
588static int add_escaped_char_to_parse_buffer(JSON_parser jc, int next_char)
589{
590    jc->escaped = 0;
591    /* remove the backslash */
592    parse_buffer_pop_back_char(jc);
593    switch(next_char) {
594        case 'b':
595            parse_buffer_push_back_char(jc, '\b');
596            break;
597        case 'f':
598            parse_buffer_push_back_char(jc, '\f');
599            break;
600        case 'n':
601            parse_buffer_push_back_char(jc, '\n');
602            break;
603        case 'r':
604            parse_buffer_push_back_char(jc, '\r');
605            break;
606        case 't':
607            parse_buffer_push_back_char(jc, '\t');
608            break;
609        case '"':
610            parse_buffer_push_back_char(jc, '"');
611            break;
612        case '\\':
613            parse_buffer_push_back_char(jc, '\\');
614            break;
615        case '/':
616            parse_buffer_push_back_char(jc, '/');
617            break;
618        case 'u':
619            parse_buffer_push_back_char(jc, '\\');
620            parse_buffer_push_back_char(jc, 'u');
621            break;
622        default:
623            return false;
624    }
625
626    return true;
627}
628
629#define add_char_to_parse_buffer(jc, next_char, next_class) \
630    do { \
631        if (jc->escaped) { \
632            if (!add_escaped_char_to_parse_buffer(jc, next_char)) \
633                return false; \
634        } else if (!jc->comment) { \
635            if ((jc->type != JSON_T_NONE) | !((next_class == C_SPACE) | (next_class == C_WHITE)) /* non-white-space */) { \
636                parse_buffer_push_back_char(jc, (char)next_char); \
637            } \
638        } \
639    } while (0)
640   
641
642#define assert_type_isnt_string_null_or_bool(jc) \
643    assert(jc->type != JSON_T_FALSE); \
644    assert(jc->type != JSON_T_TRUE); \
645    assert(jc->type != JSON_T_NULL); \
646    assert(jc->type != JSON_T_STRING)
647
648
649int
650JSON_parser_char(JSON_parser jc, int next_char)
651{
652/*
653    After calling new_JSON_parser, call this function for each character (or
654    partial character) in your JSON text. It can accept UTF-8, UTF-16, or
655    UTF-32. It returns true if things are looking ok so far. If it rejects the
656    text, it returns false.
657*/
658    int next_class, next_state;
659   
660/*
661    Determine the character's class.
662*/
663    if (next_char < 0) {
664        return false;
665    }
666    if (next_char >= 128) {
667        next_class = C_ETC;
668    } else {
669        next_class = ascii_class[next_char];
670        if (next_class <= __) {
671            return false;
672        }
673    }
674   
675    add_char_to_parse_buffer(jc, next_char, next_class);
676   
677/*
678    Get the next state from the state transition table.
679*/
680    next_state = state_transition_table[jc->state][next_class];
681    if (next_state >= 0) {
682/*
683    Change the state.
684*/
685        jc->state = next_state;
686    } else {
687/*
688    Or perform one of the actions.
689*/
690        switch (next_state) {
691/* Unicode character */       
692        case UC:
693            if(!decode_unicode_char(jc)) {
694                return false;
695            }
696            /* check if we need to read a second UTF-16 char */
697            if (jc->utf16_decode_buffer[0]) {
698                jc->state = D1;
699            } else {
700                jc->state = ST;
701            }
702            break;
703/* escaped char */
704        case EX:
705            jc->escaped = 1;
706            jc->state = ES;
707            break;
708/* integer detected by minus */
709        case MX:
710            jc->type = JSON_T_INTEGER;
711            jc->state = MI;
712            break; 
713/* integer detected by zero */           
714        case ZX:
715            jc->type = JSON_T_INTEGER;
716            jc->state = ZE;
717            break; 
718/* integer detected by 1-9 */           
719        case IX:
720            jc->type = JSON_T_INTEGER;
721            jc->state = IT;
722            break; 
723           
724/* floating point number detected by exponent*/
725        case DE:
726            assert_type_isnt_string_null_or_bool(jc);
727            jc->type = JSON_T_FLOAT;
728            jc->state = E1;
729            break;   
730       
731/* floating point number detected by fraction */
732        case DF:
733            assert_type_isnt_string_null_or_bool(jc);
734            if (!jc->handle_floats_manually) {
735/*
736    Some versions of strtod (which underlies sscanf) don't support converting
737    C-locale formated floating point values.
738*/           
739                assert(jc->parse_buffer[jc->parse_buffer_count-1] == '.');
740                jc->parse_buffer[jc->parse_buffer_count-1] = jc->decimal_point;
741            }           
742            jc->type = JSON_T_FLOAT;
743            jc->state = FX;
744            break;   
745/* string begin " */
746        case SB:
747            parse_buffer_clear(jc);
748            assert(jc->type == JSON_T_NONE);
749            jc->type = JSON_T_STRING;
750            jc->state = ST;
751            break;       
752       
753/* n */
754        case NU:
755            assert(jc->type == JSON_T_NONE);
756            jc->type = JSON_T_NULL;
757            jc->state = N1;
758            break;       
759/* f */
760        case FA:
761            assert(jc->type == JSON_T_NONE);
762            jc->type = JSON_T_FALSE;
763            jc->state = F1;
764            break;       
765/* t */
766        case TR:
767            assert(jc->type == JSON_T_NONE);
768            jc->type = JSON_T_TRUE;
769            jc->state = T1;
770            break;       
771       
772/* closing comment */
773        case CE:
774            jc->comment = 0;
775            assert(jc->parse_buffer_count == 0);
776            assert(jc->type == JSON_T_NONE);
777            jc->state = jc->before_comment_state;
778            break;       
779       
780/* opening comment  */
781        case CB:
782            if (!jc->allow_comments) {
783                return false;
784            }
785            parse_buffer_pop_back_char(jc);
786            if (!parse_parse_buffer(jc)) {
787                return false;
788            }
789            assert(jc->parse_buffer_count == 0);
790            assert(jc->type != JSON_T_STRING);
791            switch (jc->stack[jc->top]) {
792            case MODE_ARRAY:
793            case MODE_OBJECT:   
794                switch(jc->state) {
795                case VA:
796                case AR:
797                    jc->before_comment_state = jc->state;
798                    break;
799                default:
800                    jc->before_comment_state = OK;
801                    break;
802                }
803                break;
804            default:
805                jc->before_comment_state = jc->state;
806                break;
807            }
808            jc->type = JSON_T_NONE;
809            jc->state = C1;
810            jc->comment = 1;
811            break;
812/* empty } */
813        case -9:       
814            parse_buffer_clear(jc);
815            if (jc->callback && !(*jc->callback)(jc->ctx, JSON_T_OBJECT_END, NULL)) {
816                return false;
817            }
818            if (!pop(jc, MODE_KEY)) {
819                return false;
820            }
821            jc->state = OK;
822            break;
823
824/* } */ case -8:
825            parse_buffer_pop_back_char(jc);
826            if (!parse_parse_buffer(jc)) {
827                return false;
828            }
829            if (jc->callback && !(*jc->callback)(jc->ctx, JSON_T_OBJECT_END, NULL)) {
830                return false;
831            }
832            if (!pop(jc, MODE_OBJECT)) {
833                return false;
834            }
835            jc->type = JSON_T_NONE;
836            jc->state = OK;
837            break;
838
839/* ] */ case -7:
840            parse_buffer_pop_back_char(jc);
841            if (!parse_parse_buffer(jc)) {
842                return false;
843            }
844            if (jc->callback && !(*jc->callback)(jc->ctx, JSON_T_ARRAY_END, NULL)) {
845                return false;
846            }
847            if (!pop(jc, MODE_ARRAY)) {
848                return false;
849            }
850           
851            jc->type = JSON_T_NONE;
852            jc->state = OK;
853            break;
854
855/* { */ case -6:
856            parse_buffer_pop_back_char(jc);
857            if (jc->callback && !(*jc->callback)(jc->ctx, JSON_T_OBJECT_BEGIN, NULL)) {
858                return false;
859            }
860            if (!push(jc, MODE_KEY)) {
861                return false;
862            }
863            assert(jc->type == JSON_T_NONE);
864            jc->state = OB;
865            break;
866
867/* [ */ case -5:
868            parse_buffer_pop_back_char(jc);
869            if (jc->callback && !(*jc->callback)(jc->ctx, JSON_T_ARRAY_BEGIN, NULL)) {
870                return false;
871            }
872            if (!push(jc, MODE_ARRAY)) {
873                return false;
874            }
875            assert(jc->type == JSON_T_NONE);
876            jc->state = AR;
877            break;
878
879/* string end " */ case -4:
880            parse_buffer_pop_back_char(jc);
881            switch (jc->stack[jc->top]) {
882            case MODE_KEY:
883                assert(jc->type == JSON_T_STRING);
884                jc->type = JSON_T_NONE;
885                jc->state = CO;
886               
887                if (jc->callback) {
888                    JSON_value value;
889                    value.vu.str.value = jc->parse_buffer;
890                    value.vu.str.length = jc->parse_buffer_count;
891                    if (!(*jc->callback)(jc->ctx, JSON_T_KEY, &value)) {
892                        return false;
893                    }
894                }
895                parse_buffer_clear(jc);
896                break;
897            case MODE_ARRAY:
898            case MODE_OBJECT:
899                assert(jc->type == JSON_T_STRING);
900                if (!parse_parse_buffer(jc)) {
901                    return false;
902                }
903                jc->type = JSON_T_NONE;
904                jc->state = OK;
905                break;
906            default:
907                return false;
908            }
909            break;
910
911/* , */ case -3:
912            parse_buffer_pop_back_char(jc);
913            if (!parse_parse_buffer(jc)) {
914                return false;
915            }
916            switch (jc->stack[jc->top]) {
917            case MODE_OBJECT:
918/*
919    A comma causes a flip from object mode to key mode.
920*/
921                if (!pop(jc, MODE_OBJECT) || !push(jc, MODE_KEY)) {
922                    return false;
923                }
924                assert(jc->type != JSON_T_STRING);
925                jc->type = JSON_T_NONE;
926                jc->state = KE;
927                break;
928            case MODE_ARRAY:
929                assert(jc->type != JSON_T_STRING);
930                jc->type = JSON_T_NONE;
931                jc->state = VA;
932                break;
933            default:
934                return false;
935            }
936            break;
937
938/* : */ case -2:
939/*
940    A colon causes a flip from key mode to object mode.
941*/
942            parse_buffer_pop_back_char(jc);
943            if (!pop(jc, MODE_KEY) || !push(jc, MODE_OBJECT)) {
944                return false;
945            }
946            assert(jc->type == JSON_T_NONE);
947            jc->state = VA;
948            break;
949/*
950    Bad action.
951*/
952        default:
953            return false;
954        }
955    }
956    return true;
957}
958
959
960int
961JSON_parser_done(JSON_parser jc)
962{
963    const int result = jc->state == OK && pop(jc, MODE_DONE);
964
965    return result;
966}
967
968
969int JSON_parser_is_legal_white_space_string(const char* s)
970{
971    int c, char_class;
972   
973    if (s == NULL) {
974        return false;
975    }
976   
977    for (; *s; ++s) {   
978        c = *s;
979       
980        if (c < 0 || c >= 128) {
981            return false;
982        }
983       
984        char_class = ascii_class[c];
985       
986        if (char_class != C_SPACE && char_class != C_WHITE) {
987            return false;
988        }
989    }
990   
991    return true;
992}
993
994
995
996void init_JSON_config(JSON_config* config)
997{
998    if (config) {
999        memset(config, 0, sizeof(*config));
1000       
1001        config->depth = JSON_PARSER_STACK_SIZE - 1;
1002    }
1003}
Note: See TracBrowser for help on using the repository browser.