source: trunk/libtransmission/JSON_parser.c @ 8799

Last change on this file since 8799 was 8799, checked in by charles, 12 years ago

(trunk libT) update JSON_parser.c: has UTF16 fix

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