source: trunk/libtransmission/JSON_parser.c @ 6354

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

(libT) fix some minor warnings foudn by clang's scan-build and reported by m1b

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