source: trunk/libtransmission/JSON_parser.c @ 6375

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

update snapshot of Jean Gressmann's JSON parser

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