source: trunk/libtransmission/JSON_parser.c @ 6971

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

janitorial.
(1) re-enable `deflate' in transmission-remote iff libz is installed
(2) change c++-style comments to c-style comments
(3) add positional arguments to a couple of libT strings marked for translation

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