source: trunk/libtransmission/JSON_parser.c @ 6795

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

run libT, cli, daemon, gtk through the source-code formatter "uncrustify" as promised/threatened

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