source: trunk/libtransmission/JSON_parser.c @ 5969

Last change on this file since 5969 was 5969, checked in by charles, 14 years ago

#972: merge upstream version of Jean Gressmann's JSON_parser

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        int result = 1;
450        JSON_value value, *arg = NULL;
451       
452        if (jc->type != JSON_T_NONE) {
453            assert(
454                jc->type == JSON_T_NULL ||
455                jc->type == JSON_T_FALSE ||
456                jc->type == JSON_T_TRUE ||
457                jc->type == JSON_T_FLOAT ||
458                jc->type == JSON_T_INTEGER ||
459                jc->type == JSON_T_STRING);
460               
461       
462            switch(jc->type) {
463                case JSON_T_FLOAT:
464                    arg = &value;
465                    if (jc->handle_floats_manually) {
466                        value.vu.str.value = jc->parse_buffer;
467                        value.vu.str.length = jc->parse_buffer_count;
468                    } else { 
469                        result = sscanf(jc->parse_buffer, "%Lf", &value.vu.float_value);
470                    }
471                    break;
472                case JSON_T_INTEGER:
473                    arg = &value;
474                    result = sscanf(jc->parse_buffer, JSON_PARSER_INTEGER_SSCANF_TOKEN, &value.vu.integer_value);
475                    break;
476                case JSON_T_STRING:
477                    arg = &value;
478                    value.vu.str.value = jc->parse_buffer;
479                    value.vu.str.length = jc->parse_buffer_count;
480                    break;
481            }
482           
483            if (!(*jc->callback)(jc->ctx, jc->type, arg)) {
484                return false;
485            }
486        }
487    }
488   
489    parse_buffer_clear(jc);
490   
491    return true;
492}
493
494static int decode_unicode_char(JSON_parser jc)
495{
496    const unsigned chars = jc->utf16_decode_buffer[0] ? 2 : 1;
497    int i;
498    UTF16 *uc = chars == 1 ? &jc->utf16_decode_buffer[0] : &jc->utf16_decode_buffer[1];
499    UTF16 x;
500    char* p;
501   
502    assert(jc->parse_buffer_count >= 6);
503   
504    p = &jc->parse_buffer[jc->parse_buffer_count - 4];
505   
506    for (i = 0; i < 4; ++i, ++p) {
507        x = *p;
508       
509        if (x >= 'a') {
510            x -= ('a' - 10);
511        } else if (x >= 'A') {
512            x -= ('A' - 10);
513        } else {
514            x &= ~((UTF16) 0x30);
515        }
516       
517        assert(x < 16);
518       
519        *uc |= x << ((3u - i) << 2);
520    }
521   
522    /* clear UTF-16 char form buffer */
523    jc->parse_buffer_count -= 6;
524    jc->parse_buffer[jc->parse_buffer_count] = 0;
525   
526    /* attempt decoding ... */
527    {
528        UTF8* dec_start = (UTF8*)&jc->parse_buffer[jc->parse_buffer_count];
529        UTF8* dec_start_dup = dec_start;
530        UTF8* dec_end = dec_start + 6;
531       
532        const UTF16* enc_start = &jc->utf16_decode_buffer[0];
533        const UTF16* enc_end = enc_start + chars;
534   
535        const ConversionResult result = ConvertUTF16toUTF8(
536            &enc_start, enc_end, &dec_start, dec_end, strictConversion);
537       
538        const size_t new_chars = dec_start - dec_start_dup;
539       
540        /* was it a surrogate UTF-16 char? */
541        if (chars == 1 && result == sourceExhausted) {
542            return true;
543        }
544       
545        if (result != conversionOK) {
546            return false;
547        }
548       
549        /* NOTE: clear decode buffer to resume string reading,
550           otherwise we continue to read UTF-16 */
551        jc->utf16_decode_buffer[0] = 0;
552       
553        assert(new_chars <= 6);
554       
555        jc->parse_buffer_count += new_chars;
556        jc->parse_buffer[jc->parse_buffer_count] = 0;
557    }
558   
559    return true;
560}
561
562
563int
564JSON_parser_char(JSON_parser jc, int next_char)
565{
566/*
567    After calling new_JSON_parser, call this function for each character (or
568    partial character) in your JSON text. It can accept UTF-8, UTF-16, or
569    UTF-32. It returns true if things are looking ok so far. If it rejects the
570    text, it returns false.
571*/
572    int next_class, next_state;
573   
574/*
575    Determine the character's class.
576*/
577    if (next_char < 0) {
578        return false;
579    }
580    if (next_char >= 128) {
581        next_class = C_ETC;
582    } else {
583        next_class = ascii_class[next_char];
584        if (next_class <= __) {
585            return false;
586        }
587    }
588   
589    if (jc->escaped) {
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    } else if (!jc->comment) { 
626        if (jc->type != JSON_T_NONE || !(next_class == C_SPACE || next_class == C_WHITE) /* non-white-space */) {
627            parse_buffer_push_back_char(jc, (char)next_char);
628        }
629    }
630   
631   
632   
633/*
634    Get the next state from the state transition table.
635*/
636    next_state = state_transition_table[jc->state][next_class];
637    if (next_state >= 0) {
638/*
639    Change the state.
640*/
641        jc->state = next_state;
642    } else {
643/*
644    Or perform one of the actions.
645*/
646        switch (next_state) {
647/* Unicode character */       
648        case UC:
649            if(!decode_unicode_char(jc)) {
650                return false;
651            }
652            /* check if we need to read a second UTF-16 char */
653            if (jc->utf16_decode_buffer[0]) {
654                jc->state = D1;
655            } else {
656                jc->state = ST;
657            }
658            break;
659/* escaped char */
660        case EX:
661            jc->escaped = 1;
662            jc->state = ES;
663            break;
664/* integer detected by minus */
665        case MX:
666            jc->type = JSON_T_INTEGER;
667            jc->state = MI;
668            break; 
669/* integer detected by zero */           
670        case ZX:
671            jc->type = JSON_T_INTEGER;
672            jc->state = ZE;
673            break; 
674/* integer detected by 1-9 */           
675        case IX:
676            jc->type = JSON_T_INTEGER;
677            jc->state = IN;
678            break; 
679           
680/* floating point number detected by exponent*/
681        case DE:
682            assert(jc->type != JSON_T_FALSE);
683            assert(jc->type != JSON_T_TRUE);
684            assert(jc->type != JSON_T_NULL);
685            assert(jc->type != JSON_T_STRING);
686            jc->type = JSON_T_FLOAT;
687            jc->state = E1;
688            break;   
689       
690/* floating point number detected by fraction */
691        case DF:
692            assert(jc->type != JSON_T_FALSE);
693            assert(jc->type != JSON_T_TRUE);
694            assert(jc->type != JSON_T_NULL);
695            assert(jc->type != JSON_T_STRING);
696            jc->type = JSON_T_FLOAT;
697            jc->state = FX;
698            break;   
699/* string begin " */
700        case SB:
701            parse_buffer_clear(jc);
702            assert(jc->type == JSON_T_NONE);
703            jc->type = JSON_T_STRING;
704            jc->state = ST;
705            break;       
706       
707/* n */
708        case NU:
709            assert(jc->type == JSON_T_NONE);
710            jc->type = JSON_T_NULL;
711            jc->state = N1;
712            break;       
713/* f */
714        case FA:
715            assert(jc->type == JSON_T_NONE);
716            jc->type = JSON_T_FALSE;
717            jc->state = F1;
718            break;       
719/* t */
720        case TR:
721            assert(jc->type == JSON_T_NONE);
722            jc->type = JSON_T_TRUE;
723            jc->state = T1;
724            break;       
725       
726/* closing comment */
727        case CE:
728            jc->comment = 0;
729            assert(jc->parse_buffer_count == 0);
730            assert(jc->type == JSON_T_NONE);
731            jc->state = jc->before_comment_state;
732            break;       
733       
734/* opening comment  */
735        case CB:
736            if (!jc->allow_comments) {
737                return false;
738            }
739            parse_buffer_pop_back_char(jc);
740            if (!parse_parse_buffer(jc)) {
741                return false;
742            }
743            assert(jc->parse_buffer_count == 0);
744            assert(jc->type != JSON_T_STRING);
745            switch (jc->stack[jc->top]) {
746            case MODE_ARRAY:
747            case MODE_OBJECT:   
748                switch(jc->state) {
749                case VA:
750                case AR:
751                    jc->before_comment_state = jc->state;
752                    break;
753                default:
754                    jc->before_comment_state = OK;
755                    break;
756                }
757                break;
758            default:
759                jc->before_comment_state = jc->state;
760                break;
761            }
762            jc->type = JSON_T_NONE;
763            jc->state = C1;
764            jc->comment = 1;
765            break;
766/* empty } */
767        case -9:       
768            parse_buffer_clear(jc);
769            if (jc->callback && !(*jc->callback)(jc->ctx, JSON_T_OBJECT_END, NULL)) {
770                return false;
771            }
772            if (!pop(jc, MODE_KEY)) {
773                return false;
774            }
775            jc->state = OK;
776            break;
777
778/* } */ case -8:
779            parse_buffer_pop_back_char(jc);
780            if (!parse_parse_buffer(jc)) {
781                return false;
782            }
783            if (jc->callback && !(*jc->callback)(jc->ctx, JSON_T_OBJECT_END, NULL)) {
784                return false;
785            }
786            if (!pop(jc, MODE_OBJECT)) {
787                return false;
788            }
789            jc->type = JSON_T_NONE;
790            jc->state = OK;
791            break;
792
793/* ] */ case -7:
794            parse_buffer_pop_back_char(jc);
795            if (!parse_parse_buffer(jc)) {
796                return false;
797            }
798            if (jc->callback && !(*jc->callback)(jc->ctx, JSON_T_ARRAY_END, NULL)) {
799                return false;
800            }
801            if (!pop(jc, MODE_ARRAY)) {
802                return false;
803            }
804           
805            jc->type = JSON_T_NONE;
806            jc->state = OK;
807            break;
808
809/* { */ case -6:
810            parse_buffer_pop_back_char(jc);
811            if (jc->callback && !(*jc->callback)(jc->ctx, JSON_T_OBJECT_BEGIN, NULL)) {
812                return false;
813            }
814            if (!push(jc, MODE_KEY)) {
815                return false;
816            }
817            assert(jc->type == JSON_T_NONE);
818            jc->state = OB;
819            break;
820
821/* [ */ case -5:
822            parse_buffer_pop_back_char(jc);
823            if (jc->callback && !(*jc->callback)(jc->ctx, JSON_T_ARRAY_BEGIN, NULL)) {
824                return false;
825            }
826            if (!push(jc, MODE_ARRAY)) {
827                return false;
828            }
829            assert(jc->type == JSON_T_NONE);
830            jc->state = AR;
831            break;
832
833/* string end " */ case -4:
834            parse_buffer_pop_back_char(jc);
835            switch (jc->stack[jc->top]) {
836            case MODE_KEY:
837                assert(jc->type == JSON_T_STRING);
838                jc->type = JSON_T_NONE;
839                jc->state = CO;
840               
841                if (jc->callback) {
842                    JSON_value value;
843                    value.vu.str.value = jc->parse_buffer;
844                    value.vu.str.length = jc->parse_buffer_count;
845                    if (!(*jc->callback)(jc->ctx, JSON_T_KEY, &value)) {
846                        return false;
847                    }
848                }
849                parse_buffer_clear(jc);
850                break;
851            case MODE_ARRAY:
852            case MODE_OBJECT:
853                assert(jc->type == JSON_T_STRING);
854                if (!parse_parse_buffer(jc)) {
855                    return false;
856                }
857                jc->type = JSON_T_NONE;
858                jc->state = OK;
859                break;
860            default:
861                return false;
862            }
863            break;
864
865/* , */ case -3:
866            parse_buffer_pop_back_char(jc);
867            if (!parse_parse_buffer(jc)) {
868                return false;
869            }
870            switch (jc->stack[jc->top]) {
871            case MODE_OBJECT:
872/*
873    A comma causes a flip from object mode to key mode.
874*/
875                if (!pop(jc, MODE_OBJECT) || !push(jc, MODE_KEY)) {
876                    return false;
877                }
878                assert(jc->type != JSON_T_STRING);
879                jc->type = JSON_T_NONE;
880                jc->state = KE;
881                break;
882            case MODE_ARRAY:
883                assert(jc->type != JSON_T_STRING);
884                jc->type = JSON_T_NONE;
885                jc->state = VA;
886                break;
887            default:
888                return false;
889            }
890            break;
891
892/* : */ case -2:
893/*
894    A colon causes a flip from key mode to object mode.
895*/
896            parse_buffer_pop_back_char(jc);
897            if (!pop(jc, MODE_KEY) || !push(jc, MODE_OBJECT)) {
898                return false;
899            }
900            assert(jc->type == JSON_T_NONE);
901            jc->state = VA;
902            break;
903/*
904    Bad action.
905*/
906        default:
907            return false;
908        }
909    }
910    return true;
911}
912
913
914int
915JSON_parser_done(JSON_parser jc)
916{
917    const int result = jc->state == OK && pop(jc, MODE_DONE);
918
919    return result;
920}
921
922
923int JSON_parser_is_legal_white_space_string(const char* s)
924{
925    int c, char_class;
926   
927    if (s == NULL) {
928        return false;
929    }
930   
931    for (; *s; ++s) {   
932        c = *s;
933       
934        if (c < 0 || c >= 128) {
935            return false;
936        }
937       
938        char_class = ascii_class[c];
939       
940        if (char_class != C_SPACE && char_class != C_WHITE) {
941            return false;
942        }
943    }
944   
945    return true;
946}
947
948
949
950void init_JSON_config(JSON_config* config)
951{
952    if (config) {
953        memset(config, 0, sizeof(*config));
954       
955        config->depth = JSON_PARSER_STACK_SIZE - 1;
956    }
957}
Note: See TracBrowser for help on using the repository browser.