source: trunk/libtransmission/JSON_parser.c @ 8372

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

(trunk libT) #2046: fix JSON bug when parsing floating point numbers in some locales

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