source: trunk/libtransmission/JSON_parser.c @ 7632

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

(trunk libT) update the copyrights on some files that no longer have old code in them

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