Annotation of parser3/src/lib/json/pa_json.C, revision 1.1

1.1     ! moko        1: /*
        !             2:  * Copyright (C) 2009 Vincent Hanquez <vincent@snarc.org>
        !             3:  *
        !             4:  * This program is free software; you can redistribute it and/or modify
        !             5:  * it under the terms of the GNU Lesser General Public License as published
        !             6:  * by the Free Software Foundation; version 2.1 or version 3.0 only.
        !             7:  *
        !             8:  * This program is distributed in the hope that it will be useful,
        !             9:  * but WITHOUT ANY WARRANTY; without even the implied warranty of
        !            10:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        !            11:  * GNU General Public License for more details.
        !            12:  */
        !            13: 
        !            14: /*
        !            15:  * the class, states and state transition tables has been inspired by the JSON_parser.c
        !            16:  * available at http://json.org, but are quite different on the way that the
        !            17:  * parser handles its parse buffer and contains significant differences that affect
        !            18:  * the JSON compliance.
        !            19:  */
        !            20: 
        !            21: #include "json.h"
        !            22: 
        !            23: #ifdef TRACING_ENABLE
        !            24: #include <stdio.h>
        !            25: #define TRACING(fmt, ...)      fprintf(stderr, "tracing: " fmt, ##__VA_ARGS__)
        !            26: #else
        !            27: #define TRACING(fmt, ...)      ((void) 0)
        !            28: #endif
        !            29: 
        !            30: enum classes {
        !            31:        C_SPACE, /* space */
        !            32:        C_NL,    /* newline */
        !            33:        C_WHITE, /* tab, CR */
        !            34:        C_LCURB, C_RCURB, /* object opening/closing */
        !            35:        C_LSQRB, C_RSQRB, /* array opening/closing */
        !            36:        /* syntax symbols */
        !            37:        C_COLON,
        !            38:        C_COMMA,
        !            39:        C_QUOTE, /* " */
        !            40:        C_BACKS, /* \ */
        !            41:        C_SLASH, /* / */
        !            42:        C_PLUS,
        !            43:        C_MINUS,
        !            44:        C_DOT,
        !            45:        C_ZERO, C_DIGIT, /* digits */
        !            46:        C_a, C_b, C_c, C_d, C_e, C_f, C_l, C_n, C_r, C_s, C_t, C_u, /* nocaps letters */
        !            47:        C_ABCDF, C_E, /* caps letters */
        !            48:        C_OTHER, /* all other */
        !            49:        C_STAR, /* star in C style comment */
        !            50:        C_HASH, /* # for YAML comment */
        !            51:        C_ERROR = 0xfe,
        !            52: };
        !            53: 
        !            54: /* map from character < 128 to classes. from 128 to 256 all C_OTHER */
        !            55: static uint8_t character_class[128] = {
        !            56:        C_ERROR, C_ERROR, C_ERROR, C_ERROR, C_ERROR, C_ERROR, C_ERROR, C_ERROR,
        !            57:        C_ERROR, C_WHITE, C_NL,    C_ERROR, C_ERROR, C_WHITE, C_ERROR, C_ERROR,
        !            58:        C_ERROR, C_ERROR, C_ERROR, C_ERROR, C_ERROR, C_ERROR, C_ERROR, C_ERROR,
        !            59:        C_ERROR, C_ERROR, C_ERROR, C_ERROR, C_ERROR, C_ERROR, C_ERROR, C_ERROR,
        !            60: 
        !            61:        C_SPACE, C_OTHER, C_QUOTE, C_HASH,  C_OTHER, C_OTHER, C_OTHER, C_OTHER,
        !            62:        C_OTHER, C_OTHER, C_STAR,  C_PLUS,  C_COMMA, C_MINUS, C_DOT,   C_SLASH,
        !            63:        C_ZERO,  C_DIGIT, C_DIGIT, C_DIGIT, C_DIGIT, C_DIGIT, C_DIGIT, C_DIGIT,
        !            64:        C_DIGIT, C_DIGIT, C_COLON, C_OTHER, C_OTHER, C_OTHER, C_OTHER, C_OTHER,
        !            65: 
        !            66:        C_OTHER, C_ABCDF, C_ABCDF, C_ABCDF, C_ABCDF, C_E,     C_ABCDF, C_OTHER,
        !            67:        C_OTHER, C_OTHER, C_OTHER, C_OTHER, C_OTHER, C_OTHER, C_OTHER, C_OTHER,
        !            68:        C_OTHER, C_OTHER, C_OTHER, C_OTHER, C_OTHER, C_OTHER, C_OTHER, C_OTHER,
        !            69:        C_OTHER, C_OTHER, C_OTHER, C_LSQRB, C_BACKS, C_RSQRB, C_OTHER, C_OTHER,
        !            70: 
        !            71:        C_OTHER, C_a,     C_b,     C_c,     C_d,     C_e,     C_f,     C_OTHER,
        !            72:        C_OTHER, C_OTHER, C_OTHER, C_OTHER, C_l,     C_OTHER, C_n,     C_OTHER,
        !            73:        C_OTHER, C_OTHER, C_r,     C_s,     C_t,     C_u,     C_OTHER, C_OTHER,
        !            74:        C_OTHER, C_OTHER, C_OTHER, C_LCURB, C_OTHER, C_RCURB, C_OTHER, C_OTHER
        !            75: };
        !            76: 
        !            77: /* only the first 36 ascii characters need an escape */
        !            78: static char *character_escape[36] = {
        !            79:        "\\u0000", "\\u0001", "\\u0002", "\\u0003", "\\u0004", "\\u0005", "\\u0006", "\\u0007", /*  0-7  */
        !            80:        "\\b"    ,     "\\t",     "\\n", "\\u000b",     "\\f",     "\\r", "\\u000e", "\\u000f", /*  8-f  */
        !            81:        "\\u0010", "\\u0011", "\\u0012", "\\u0013", "\\u0014", "\\u0015", "\\u0016", "\\u0017", /* 10-17 */
        !            82:        "\\u0018", "\\u0019", "\\u001a", "\\u001b", "\\u001c", "\\u001d", "\\u001e", "\\u001f", /* 18-1f */
        !            83:        " "      , "!"      , "\\\""   , "#",
        !            84: };
        !            85: 
        !            86: /* define all states and actions that will be taken on each transition.
        !            87:  *
        !            88:  * states are defined first because of the fact they are use as index in the
        !            89:  * transitions table. they usually contains either a number or a prefix _ 
        !            90:  * for simple state like string, object, value ...
        !            91:  *
        !            92:  * actions are defined starting from 0x80. state error is defined as 0xff
        !            93:  */
        !            94: 
        !            95: enum states {
        !            96:        STATE_GO, /* start  */
        !            97:        STATE_OK, /* ok     */
        !            98:        STATE__O, /* object */
        !            99:        STATE__K, /* key    */
        !           100:        STATE_CO, /* colon  */
        !           101:        STATE__V, /* value  */
        !           102:        STATE__A, /* array  */
        !           103:        STATE__S, /* string */
        !           104:        STATE_E0, /* escape */
        !           105:        STATE_U1, STATE_U2, STATE_U3, STATE_U4, /* unicode states */
        !           106:        STATE_M0, STATE_Z0, STATE_I0, /* number states */
        !           107:        STATE_R1, STATE_R2, /* real states (after-dot digits) */
        !           108:        STATE_X1, STATE_X2, STATE_X3, /* exponant states */
        !           109:        STATE_T1, STATE_T2, STATE_T3, /* true constant states */
        !           110:        STATE_F1, STATE_F2, STATE_F3, STATE_F4, /* false constant states */
        !           111:        STATE_N1, STATE_N2, STATE_N3, /* null constant states */
        !           112:        STATE_C1, STATE_C2, STATE_C3, /* C-comment states */
        !           113:        STATE_Y1, /* YAML-comment state */
        !           114:        STATE_D1, STATE_D2, /* multi unicode states */
        !           115: };
        !           116: 
        !           117: /* the following are actions that need to be taken */
        !           118: enum actions {
        !           119:        STATE_KS = 0x80, /* key separator */
        !           120:        STATE_SP, /* comma separator */
        !           121:        STATE_AB, /* array begin */
        !           122:        STATE_AE, /* array ending */
        !           123:        STATE_OB, /* object begin */
        !           124:        STATE_OE, /* object end */
        !           125:        STATE_CB, /* C-comment begin */
        !           126:        STATE_YB, /* YAML-comment begin */
        !           127:        STATE_CE, /* YAML/C comment end */
        !           128:        STATE_FA, /* false */
        !           129:        STATE_TR, /* true */
        !           130:        STATE_NU, /* null */
        !           131:        STATE_DE, /* double detected by exponent */
        !           132:        STATE_DF, /* double detected by . */
        !           133:        STATE_SE, /* string end */
        !           134:        STATE_MX, /* integer detected by minus */
        !           135:        STATE_ZX, /* integer detected by zero */
        !           136:        STATE_IX, /* integer detected by 1-9 */
        !           137:        STATE_UC, /* Unicode character read */
        !           138: };
        !           139: 
        !           140: /* error state */
        !           141: #define STATE___       0xff
        !           142: 
        !           143: #define NR_STATES      (STATE_D2 + 1)
        !           144: #define NR_CLASSES     (C_HASH + 1)
        !           145: 
        !           146: #define IS_STATE_ACTION(s) ((s) & 0x80)
        !           147: #define S(x) STATE_##x
        !           148: #define PT_(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a1,b1,c1,d1,e1,f1,g1,h1)       \
        !           149:        { S(a),S(b),S(c),S(d),S(e),S(f),S(g),S(h),S(i),S(j),S(k),S(l),S(m),S(n),                \
        !           150:          S(o),S(p),S(q),S(r),S(s),S(t),S(u),S(v),S(w),S(x),S(y),S(z),S(a1),S(b1),              \
        !           151:          S(c1),S(d1),S(e1),S(f1),S(g1),S(h1) }
        !           152: 
        !           153: /* map from the (previous state+new character class) to the next parser transition */
        !           154: static const uint8_t state_transition_table[NR_STATES][NR_CLASSES] = {
        !           155: /*             white                                                                            ABCDF  other    */
        !           156: /*         sp nl |  {  }  [  ]  :  ,  "  \  /  +  -  .  0  19 a  b  c  d  e  f  l  n  r  s  t  u  |  E  |  *  # */
        !           157: /*GO*/ PT_(GO,GO,GO,OB,__,AB,__,__,__,__,__,CB,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,YB),
        !           158: /*OK*/ PT_(OK,OK,OK,__,OE,__,AE,__,SP,__,__,CB,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,YB),
        !           159: /*_O*/ PT_(_O,_O,_O,__,OE,__,__,__,__,_S,__,CB,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,YB),
        !           160: /*_K*/ PT_(_K,_K,_K,__,__,__,__,__,__,_S,__,CB,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,YB),
        !           161: /*CO*/ PT_(CO,CO,CO,__,__,__,__,KS,__,__,__,CB,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,YB),
        !           162: /*_V*/ PT_(_V,_V,_V,OB,__,AB,__,__,__,_S,__,CB,__,MX,__,ZX,IX,__,__,__,__,__,F1,__,N1,__,__,T1,__,__,__,__,__,YB),
        !           163: /*_A*/ PT_(_A,_A,_A,OB,__,AB,AE,__,__,_S,__,CB,__,MX,__,ZX,IX,__,__,__,__,__,F1,__,N1,__,__,T1,__,__,__,__,__,YB),
        !           164: /****************************************************************************************************************/
        !           165: /*_S*/ PT_(_S,__,__,_S,_S,_S,_S,_S,_S,SE,E0,_S,_S,_S,_S,_S,_S,_S,_S,_S,_S,_S,_S,_S,_S,_S,_S,_S,_S,_S,_S,_S,_S,_S),
        !           166: /*E0*/ PT_(__,__,__,__,__,__,__,__,__,_S,_S,_S,__,__,__,__,__,__,_S,__,__,__,_S,__,_S,_S,__,_S,U1,__,__,__,__,__),
        !           167: /*U1*/ PT_(__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,U2,U2,U2,U2,U2,U2,U2,U2,__,__,__,__,__,__,U2,U2,__,__,__),
        !           168: /*U2*/ PT_(__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,U3,U3,U3,U3,U3,U3,U3,U3,__,__,__,__,__,__,U3,U3,__,__,__),
        !           169: /*U3*/ PT_(__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,U4,U4,U4,U4,U4,U4,U4,U4,__,__,__,__,__,__,U4,U4,__,__,__),
        !           170: /*U4*/ PT_(__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,UC,UC,UC,UC,UC,UC,UC,UC,__,__,__,__,__,__,UC,UC,__,__,__),
        !           171: /****************************************************************************************************************/
        !           172: /*M0*/ PT_(__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,Z0,I0,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__),
        !           173: /*Z0*/ PT_(OK,OK,OK,__,OE,__,AE,__,SP,__,__,CB,__,__,DF,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,YB),
        !           174: /*I0*/ PT_(OK,OK,OK,__,OE,__,AE,__,SP,__,__,CB,__,__,DF,I0,I0,__,__,__,__,DE,__,__,__,__,__,__,__,__,DE,__,__,YB),
        !           175: /*R1*/ PT_(__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,R2,R2,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__),
        !           176: /*R2*/ PT_(OK,OK,OK,__,OE,__,AE,__,SP,__,__,CB,__,__,__,R2,R2,__,__,__,__,X1,__,__,__,__,__,__,__,__,X1,__,__,YB),
        !           177: /*X1*/ PT_(__,__,__,__,__,__,__,__,__,__,__,__,X2,X2,__,X3,X3,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__),
        !           178: /*X2*/ PT_(__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,X3,X3,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__),
        !           179: /*X3*/ PT_(OK,OK,OK,__,OE,__,AE,__,SP,__,__,__,__,__,__,X3,X3,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__),
        !           180: /****************************************************************************************************************/
        !           181: /*T1*/ PT_(__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,T2,__,__,__,__,__,__,__,__),
        !           182: /*T2*/ PT_(__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,T3,__,__,__,__,__),
        !           183: /*T3*/ PT_(__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,TR,__,__,__,__,__,__,__,__,__,__,__,__),
        !           184: /*F1*/ PT_(__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,F2,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__),
        !           185: /*F2*/ PT_(__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,F3,__,__,__,__,__,__,__,__,__,__),
        !           186: /*F3*/ PT_(__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,F4,__,__,__,__,__,__,__),
        !           187: /*F4*/ PT_(__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,FA,__,__,__,__,__,__,__,__,__,__,__,__),
        !           188: /*N1*/ PT_(__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,N2,__,__,__,__,__),
        !           189: /*N2*/ PT_(__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,N3,__,__,__,__,__,__,__,__,__,__),
        !           190: /*N3*/ PT_(__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,NU,__,__,__,__,__,__,__,__,__,__),
        !           191: /****************************************************************************************************************/
        !           192: /*C1*/ PT_(__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,C2,__),
        !           193: /*C2*/ PT_(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,C2),
        !           194: /*C3*/ PT_(C2,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,C2),
        !           195: /*Y1*/ PT_(Y1,CE,Y1,Y1,Y1,Y1,Y1,Y1,Y1,Y1,Y1,Y1,Y1,Y1,Y1,Y1,Y1,Y1,Y1,Y1,Y1,Y1,Y1,Y1,Y1,Y1,Y1,Y1,Y1,Y1,Y1,Y1,Y1,Y1),
        !           196: /*D1*/ PT_(__,__,__,__,__,__,__,__,__,__,D2,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__),
        !           197: /*D2*/ PT_(__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,U1,__,__,__,__,__),
        !           198: };
        !           199: #undef S
        !           200: #undef PT_
        !           201: 
        !           202: /* map from (previous state+new character class) to the buffer policy. ignore=0/append=1/escape=2 */
        !           203: static const uint8_t buffer_policy_table[NR_STATES][NR_CLASSES] = {
        !           204: /*          white                                                                            ABCDF  other     */
        !           205: /*      sp nl  |  {  }  [  ]  :  ,  "  \  /  +  -  .  0  19 a  b  c  d  e  f  l  n  r  s  t  u  |  E  |  *  # */
        !           206: /*GO*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
        !           207: /*OK*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
        !           208: /*_O*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
        !           209: /*_K*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
        !           210: /*CO*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
        !           211: /*_V*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
        !           212: /*_A*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
        !           213: /**************************************************************************************************************/
        !           214: /*_S*/ { 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
        !           215: /*E0*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 2, 2, 0, 2, 0, 0, 0, 0, 0, 0 },
        !           216: /*U1*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0 },
        !           217: /*U2*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0 },
        !           218: /*U3*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0 },
        !           219: /*U4*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0 },
        !           220: /**************************************************************************************************************/
        !           221: /*M0*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
        !           222: /*Z0*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
        !           223: /*I0*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 },
        !           224: /*R1*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
        !           225: /*R2*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 },
        !           226: /*X1*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
        !           227: /*X2*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
        !           228: /*X3*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
        !           229: /**************************************************************************************************************/
        !           230: /*T1*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
        !           231: /*T2*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
        !           232: /*T3*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
        !           233: /*F1*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
        !           234: /*F2*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
        !           235: /*F3*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
        !           236: /*F4*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
        !           237: /*N1*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
        !           238: /*N2*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
        !           239: /*N3*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
        !           240: /**************************************************************************************************************/
        !           241: /*C1*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
        !           242: /*C2*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
        !           243: /*C3*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
        !           244: /*Y1*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
        !           245: /*D1*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
        !           246: /*D2*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
        !           247: };
        !           248: 
        !           249: #define MODE_ARRAY 0
        !           250: #define MODE_OBJECT 1
        !           251: 
        !           252: #define parser_malloc(parser, s) parser->config.user_malloc(s)
        !           253: #define parser_realloc(parser, p, s) parser->config.user_realloc(p, s)
        !           254: #define parser_free(parser, p) parser->config.user_free(p)
        !           255: 
        !           256: static int state_grow(json_parser *parser)
        !           257: {
        !           258:        uint32_t newsize = parser->stack_size * 2;
        !           259:        void *ptr;
        !           260: 
        !           261:        if (parser->config.max_nesting != 0)
        !           262:                return JSON_ERROR_NESTING_LIMIT;
        !           263: 
        !           264:        ptr = parser_realloc(parser, parser->stack, newsize * sizeof(uint8_t));
        !           265:        if (!ptr)
        !           266:                return JSON_ERROR_NO_MEMORY;
        !           267:        parser->stack = ptr;
        !           268:        parser->stack_size = newsize;
        !           269:        return 0;
        !           270: }
        !           271: 
        !           272: static int state_push(json_parser *parser, int mode)
        !           273: {
        !           274:        if (parser->stack_offset >= parser->stack_size) {
        !           275:                int ret = state_grow(parser);
        !           276:                if (ret)
        !           277:                        return ret;
        !           278:        }
        !           279:        parser->stack[parser->stack_offset++] = mode;
        !           280:        return 0;
        !           281: }
        !           282: 
        !           283: static int state_pop(json_parser *parser, int mode)
        !           284: {
        !           285:        if (parser->stack_offset == 0)
        !           286:                return JSON_ERROR_POP_EMPTY;
        !           287:        parser->stack_offset--;
        !           288:        if (parser->stack[parser->stack_offset] != mode)
        !           289:                return JSON_ERROR_POP_UNEXPECTED_MODE;
        !           290:        return 0;
        !           291: }
        !           292: 
        !           293: static int buffer_grow(json_parser *parser)
        !           294: {
        !           295:        uint32_t newsize;
        !           296:        void *ptr;
        !           297:        int max = parser->config.max_data;
        !           298: 
        !           299:        if (max > 0 && parser->buffer_size == max)
        !           300:                return JSON_ERROR_DATA_LIMIT;
        !           301:        newsize = parser->buffer_size * 2;
        !           302:        if (max > 0 && newsize > max)
        !           303:                newsize = max;
        !           304: 
        !           305:        ptr = parser_realloc(parser, parser->buffer, newsize * sizeof(char));
        !           306:        if (!ptr)
        !           307:                return JSON_ERROR_NO_MEMORY;
        !           308:        parser->buffer = ptr;
        !           309:        parser->buffer_size = newsize;
        !           310:        return 0;
        !           311: }
        !           312: 
        !           313: static int buffer_push(json_parser *parser, unsigned char c)
        !           314: {
        !           315:        int ret;
        !           316: 
        !           317:        if (parser->buffer_offset + 1 >= parser->buffer_size) {
        !           318:                ret = buffer_grow(parser);
        !           319:                if (ret)
        !           320:                        return ret;
        !           321:        }
        !           322:        parser->buffer[parser->buffer_offset++] = c;
        !           323:        return 0;
        !           324: }
        !           325: 
        !           326: static int do_callback_withbuf(json_parser *parser, int type)
        !           327: {
        !           328:        if (!parser->callback)
        !           329:                return 0;
        !           330:        parser->buffer[parser->buffer_offset] = '\0';
        !           331:        return (*parser->callback)(parser->userdata, type, parser->buffer, parser->buffer_offset);
        !           332: }
        !           333: 
        !           334: static int do_callback(json_parser *parser, int type)
        !           335: {
        !           336:        if (!parser->callback)
        !           337:                return 0;
        !           338:        return (*parser->callback)(parser->userdata, type, NULL, 0);
        !           339: }
        !           340: 
        !           341: static int do_buffer(json_parser *parser)
        !           342: {
        !           343:        int ret = 0;
        !           344: 
        !           345:        switch (parser->type) {
        !           346:        case JSON_KEY: case JSON_STRING:
        !           347:        case JSON_FLOAT: case JSON_INT:
        !           348:        case JSON_NULL: case JSON_TRUE: case JSON_FALSE:
        !           349:                ret = do_callback_withbuf(parser, parser->type);
        !           350:                if (ret)
        !           351:                        return ret;
        !           352:                break;
        !           353:        default:
        !           354:                break;
        !           355:        }
        !           356:        parser->buffer_offset = 0;
        !           357:        return ret;
        !           358: }
        !           359: 
        !           360: static const uint8_t hextable[] = {
        !           361:        -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
        !           362:        -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
        !           363:        -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
        !           364:         0, 1, 2, 3, 4, 5, 6, 7, 8, 9,-1,-1,-1,-1,-1,-1,
        !           365:        -1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1,
        !           366:        -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
        !           367:        -1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1,
        !           368:        -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
        !           369: };
        !           370: 
        !           371: #define hex(c) (hextable[(uint8_t) c])
        !           372: 
        !           373: /* high surrogate range from d800 to dbff */
        !           374: /* low surrogate range dc00 to dfff */
        !           375: #define IS_HIGH_SURROGATE(uc) (((uc) & 0xfc00) == 0xd800)
        !           376: #define IS_LOW_SURROGATE(uc)  (((uc) & 0xfc00) == 0xdc00)
        !           377: 
        !           378: /* transform an unicode [0-9A-Fa-f]{4} sequence into a proper value */
        !           379: static int decode_unicode_char(json_parser *parser)
        !           380: {
        !           381:        uint32_t uval;
        !           382:        char *b = parser->buffer;
        !           383:        int offset = parser->buffer_offset;
        !           384: 
        !           385:        uval = (hex(b[offset - 4]) << 12) | (hex(b[offset - 3]) << 8)
        !           386:             | (hex(b[offset - 2]) << 4) | hex(b[offset - 1]);
        !           387: 
        !           388:        parser->buffer_offset -= 4;
        !           389: 
        !           390:        /* fast case */
        !           391:        if (!parser->unicode_multi && uval < 0x80) {
        !           392:                b[parser->buffer_offset++] = (char) uval;
        !           393:                return 0;
        !           394:        }
        !           395: 
        !           396:        if (parser->unicode_multi) {
        !           397:                if (!IS_LOW_SURROGATE(uval))
        !           398:                        return JSON_ERROR_UNICODE_MISSING_LOW_SURROGATE;
        !           399: 
        !           400:                uval = 0x10000 + ((parser->unicode_multi & 0x3ff) << 10) + (uval & 0x3ff);
        !           401:                b[parser->buffer_offset++] = (char) ((uval >> 18) | 0xf0);
        !           402:                b[parser->buffer_offset++] = (char) (((uval >> 12) & 0x3f) | 0x80);
        !           403:                b[parser->buffer_offset++] = (char) (((uval >> 6) & 0x3f) | 0x80);
        !           404:                b[parser->buffer_offset++] = (char) ((uval & 0x3f) | 0x80);
        !           405:                parser->unicode_multi = 0;
        !           406:                return 0;
        !           407:        }
        !           408: 
        !           409:        if (IS_LOW_SURROGATE(uval))
        !           410:                return JSON_ERROR_UNICODE_UNEXPECTED_LOW_SURROGATE;
        !           411:        if (IS_HIGH_SURROGATE(uval)) {
        !           412:                parser->unicode_multi = uval;
        !           413:                return 0;
        !           414:        }
        !           415: 
        !           416:        if (uval < 0x800) {
        !           417:                b[parser->buffer_offset++] = (char) ((uval >> 6) | 0xc0);
        !           418:                b[parser->buffer_offset++] = (char) ((uval & 0x3f) | 0x80);
        !           419:        } else {
        !           420:                b[parser->buffer_offset++] = (char) ((uval >> 12) | 0xe0);
        !           421:                b[parser->buffer_offset++] = (char) (((uval >> 6) & 0x3f) | 0x80);
        !           422:                b[parser->buffer_offset++] = (char) (((uval >> 0) & 0x3f) | 0x80);
        !           423:        }
        !           424:        return 0;
        !           425: }
        !           426: 
        !           427: static int buffer_push_escape(json_parser *parser, unsigned char next)
        !           428: {
        !           429:        char c = '\0';
        !           430: 
        !           431:        switch (next) {
        !           432:        case 'b': c = '\b'; break;
        !           433:        case 'f': c = '\f'; break;
        !           434:        case 'n': c = '\n'; break;
        !           435:        case 'r': c = '\r'; break;
        !           436:        case 't': c = '\t'; break;
        !           437:        case '"': c = '"'; break;
        !           438:        case '/': c = '/'; break;
        !           439:        case '\\': c = '\\'; break;
        !           440:        }
        !           441:        /* push the escaped character */
        !           442:        return buffer_push(parser, c);
        !           443: }
        !           444: 
        !           445: #define CHK(f) ({ ret = f; if (ret) return ret; })
        !           446: 
        !           447: int act_uc(json_parser *parser)
        !           448: {
        !           449:        int ret;
        !           450:        CHK(decode_unicode_char(parser));
        !           451:        parser->state = (parser->unicode_multi) ? STATE_D1 : STATE__S;
        !           452:        return 0;
        !           453: }
        !           454: 
        !           455: int act_yb(json_parser *parser)
        !           456: {
        !           457:        if (!parser->config.allow_yaml_comments)
        !           458:                return JSON_ERROR_COMMENT_NOT_ALLOWED;
        !           459:        parser->save_state = parser->state;
        !           460:        return 0;
        !           461: }
        !           462: 
        !           463: int act_cb(json_parser *parser)
        !           464: {
        !           465:        if (!parser->config.allow_c_comments)
        !           466:                return JSON_ERROR_COMMENT_NOT_ALLOWED;
        !           467:        parser->save_state = parser->state;
        !           468:        return 0;
        !           469: }
        !           470: 
        !           471: int act_ce(json_parser *parser)
        !           472: {
        !           473:        parser->state = (parser->save_state > STATE__A) ? STATE_OK : parser->save_state;
        !           474:        return 0;
        !           475: }
        !           476: 
        !           477: int act_ob(json_parser *parser)
        !           478: {
        !           479:        int ret;
        !           480:        CHK(do_callback(parser, JSON_OBJECT_BEGIN));
        !           481:        CHK(state_push(parser, MODE_OBJECT));
        !           482:        parser->expecting_key = 1;
        !           483:        return 0;
        !           484: }
        !           485: 
        !           486: int act_oe(json_parser *parser)
        !           487: {
        !           488:        int ret;
        !           489:        CHK(do_callback(parser, JSON_OBJECT_END));
        !           490:        CHK(state_pop(parser, MODE_OBJECT));
        !           491:        parser->expecting_key = 0;
        !           492:        return 0;
        !           493: }
        !           494: 
        !           495: int act_ab(json_parser *parser)
        !           496: {
        !           497:        int ret;
        !           498:        CHK(do_callback(parser, JSON_ARRAY_BEGIN));
        !           499:        CHK(state_push(parser, MODE_ARRAY));
        !           500:        return 0;
        !           501: }
        !           502: int act_ae(json_parser *parser)
        !           503: {
        !           504:        int ret;
        !           505:        CHK(do_callback(parser, JSON_ARRAY_END));
        !           506:        CHK(state_pop(parser, MODE_ARRAY));
        !           507:        return 0;
        !           508: }
        !           509: 
        !           510: int act_se(json_parser *parser)
        !           511: {
        !           512:        int ret;
        !           513:        CHK(do_callback_withbuf(parser, (parser->expecting_key) ? JSON_KEY : JSON_STRING));
        !           514:        parser->buffer_offset = 0;
        !           515:        parser->state = (parser->expecting_key) ? STATE_CO : STATE_OK;
        !           516:        parser->expecting_key = 0;
        !           517:        return 0;
        !           518: }
        !           519: 
        !           520: int act_sp(json_parser *parser)
        !           521: {
        !           522:        if (parser->stack_offset == 0)
        !           523:                return JSON_ERROR_COMMA_OUT_OF_STRUCTURE;
        !           524:        if (parser->stack[parser->stack_offset - 1] == MODE_OBJECT) {
        !           525:                parser->expecting_key = 1;
        !           526:                parser->state = STATE__K;
        !           527:        } else
        !           528:                parser->state = STATE__V;
        !           529:        return 0;
        !           530: }
        !           531: 
        !           532: struct action_descr
        !           533: {
        !           534:        int (*call)(json_parser *parser);
        !           535:        uint8_t type;
        !           536:        uint8_t state; /* 0 if we let the callback set the value it want */
        !           537:        uint8_t dobuffer;
        !           538: };
        !           539: 
        !           540: static struct action_descr actions_map[] = {
        !           541:        [STATE_MX & ~0x80] = { NULL,   JSON_INT,   STATE_M0, 0 },
        !           542:        [STATE_ZX & ~0x80] = { NULL,   JSON_INT,   STATE_Z0, 0 },
        !           543:        [STATE_IX & ~0x80] = { NULL,   JSON_INT,   STATE_I0, 0 },
        !           544:        [STATE_DE & ~0x80] = { NULL,   JSON_FLOAT, STATE_X1, 0 },
        !           545:        [STATE_DF & ~0x80] = { NULL,   JSON_FLOAT, STATE_R1, 0 },
        !           546:        [STATE_NU & ~0x80] = { NULL,   JSON_NULL,  STATE_OK, 0 },
        !           547:        [STATE_FA & ~0x80] = { NULL,   JSON_FALSE, STATE_OK, 0 },
        !           548:        [STATE_TR & ~0x80] = { NULL,   JSON_TRUE,  STATE_OK, 0 },
        !           549:        [STATE_KS & ~0x80] = { NULL,   JSON_NONE,  STATE__V, 0 },
        !           550:        [STATE_UC & ~0x80] = { act_uc, JSON_NONE,  0,        0 },
        !           551:        [STATE_YB & ~0x80] = { act_yb, JSON_NONE,  STATE_Y1, 1 },
        !           552:        [STATE_CB & ~0x80] = { act_cb, JSON_NONE,  STATE_C1, 1 },
        !           553:        [STATE_CE & ~0x80] = { act_ce, JSON_NONE,  0,        0 },
        !           554:        [STATE_OB & ~0x80] = { act_ob, JSON_NONE,  STATE__O, 0 },
        !           555:        [STATE_OE & ~0x80] = { act_oe, JSON_NONE,  STATE_OK, 1 },
        !           556:        [STATE_AB & ~0x80] = { act_ab, JSON_NONE,  STATE__A, 0 },
        !           557:        [STATE_AE & ~0x80] = { act_ae, JSON_NONE,  STATE_OK, 1 },
        !           558:        [STATE_SE & ~0x80] = { act_se, JSON_NONE,  0,        0 },
        !           559:        [STATE_SP & ~0x80] = { act_sp, JSON_NONE,  0,        1 },
        !           560: };
        !           561: 
        !           562: static int do_action(json_parser *parser, int next_state)
        !           563: {
        !           564:        struct action_descr *descr = &actions_map[next_state & ~0x80];
        !           565: 
        !           566:        if (descr->call) {
        !           567:                int ret;
        !           568:                if (descr->dobuffer)
        !           569:                        CHK(do_buffer(parser));
        !           570:                CHK((descr->call)(parser));
        !           571:        }
        !           572:        if (descr->state)
        !           573:                parser->state = descr->state;
        !           574:        parser->type = descr->type;
        !           575:        return 0;
        !           576: }
        !           577: 
        !           578: /** json_parser_init initialize a parser structure taking a config,
        !           579:  * a config and its userdata.
        !           580:  * return JSON_ERROR_NO_MEMORY if memory allocation failed or SUCCESS.
        !           581:  */
        !           582: int json_parser_init(json_parser *parser, json_config *config,
        !           583:                      json_parser_callback callback, void *userdata)
        !           584: {
        !           585:        memset(parser, 0, sizeof(*parser));
        !           586: 
        !           587:        if (config)
        !           588:                memcpy(&parser->config, config, sizeof(json_config));
        !           589:        parser->callback = callback;
        !           590:        parser->userdata = userdata;
        !           591: 
        !           592:        /* initialise parsing stack and state */
        !           593:        parser->stack_offset = 0;
        !           594:        parser->state = STATE_GO;
        !           595: 
        !           596:        /* initialize the parse stack */
        !           597:        parser->stack_size = (parser->config.max_nesting > 0)
        !           598:                ? parser->config.max_nesting
        !           599:                : LIBJSON_DEFAULT_STACK_SIZE;
        !           600: 
        !           601:        parser->stack = parser_malloc(parser, parser->stack_size * sizeof(parser->stack[0]));
        !           602:        if (!parser->stack)
        !           603:                return JSON_ERROR_NO_MEMORY;
        !           604: 
        !           605:        /* initialize the parse buffer */
        !           606:        parser->buffer_size = (parser->config.buffer_initial_size > 0)
        !           607:                ? parser->config.buffer_initial_size
        !           608:                : LIBJSON_DEFAULT_BUFFER_SIZE;
        !           609: 
        !           610:        if (parser->config.max_data > 0 && parser->buffer_size > parser->config.max_data)
        !           611:                parser->buffer_size = parser->config.max_data;
        !           612: 
        !           613:        parser->buffer = parser_malloc(parser, parser->buffer_size * sizeof(char));
        !           614:        if (!parser->buffer) {
        !           615:                parser_free(parser, parser->stack);
        !           616:                return JSON_ERROR_NO_MEMORY;
        !           617:        }
        !           618:        return 0;
        !           619: }
        !           620: 
        !           621: /** json_parser_free freed memory structure allocated by the parser */
        !           622: int json_parser_free(json_parser *parser)
        !           623: {
        !           624:        if (!parser)
        !           625:                return 0;
        !           626:        parser_free(parser, parser->stack);
        !           627:        parser_free(parser, parser->buffer);
        !           628:        parser->stack = NULL;
        !           629:        parser->buffer = NULL;
        !           630:        return 0;
        !           631: }
        !           632: 
        !           633: /** json_parser_is_done return 0 is the parser isn't in a finish state. !0 if it is */
        !           634: int json_parser_is_done(json_parser *parser)
        !           635: {
        !           636:        /* need to compare the state to !GO to not accept empty document */
        !           637:        return parser->stack_offset == 0 && parser->state != STATE_GO;
        !           638: }
        !           639: 
        !           640: /** json_parser_string append a string s with a specific length to the parser
        !           641:  * return 0 if everything went ok, a JSON_ERROR_* otherwise.
        !           642:  * the user can supplied a valid processed pointer that will
        !           643:  * be fill with the number of processed characters before returning */
        !           644: int json_parser_string(json_parser *parser, const char *s,
        !           645:                        uint32_t length, uint32_t *processed)
        !           646: {
        !           647:        int ret;
        !           648:        int next_class, next_state;
        !           649:        int buffer_policy;
        !           650:        uint32_t i;
        !           651: 
        !           652:        ret = 0;
        !           653:        for (i = 0; i < length; i++) {
        !           654:                unsigned char ch = s[i];
        !           655: 
        !           656:                ret = 0;
        !           657:                next_class = (ch >= 128) ? C_OTHER : character_class[ch];
        !           658:                if (next_class == C_ERROR) {
        !           659:                        ret = JSON_ERROR_BAD_CHAR;
        !           660:                        break;
        !           661:                }
        !           662: 
        !           663:                next_state = state_transition_table[parser->state][next_class];
        !           664:                buffer_policy = buffer_policy_table[parser->state][next_class];
        !           665:                TRACING("addchar %d (current-state=%d, next-state=%d, buf-policy=%d)\n",
        !           666:                        ch, parser->state, next_state, buffer_policy);
        !           667:                if (next_state == STATE___) {
        !           668:                        ret = JSON_ERROR_UNEXPECTED_CHAR;
        !           669:                        break;
        !           670:                }
        !           671: 
        !           672:                /* add char to buffer */
        !           673:                if (buffer_policy) {
        !           674:                        ret = (buffer_policy == 2)
        !           675:                                ? buffer_push_escape(parser, ch)
        !           676:                                : buffer_push(parser, ch);
        !           677:                        if (ret)
        !           678:                                break;
        !           679:                }
        !           680: 
        !           681:                /* move to the next level */
        !           682:                if (IS_STATE_ACTION(next_state))
        !           683:                        ret = do_action(parser, next_state);
        !           684:                else
        !           685:                        parser->state = next_state;
        !           686:                if (ret)
        !           687:                        break;
        !           688:        }
        !           689:        if (processed)
        !           690:                *processed = i;
        !           691:        return ret;
        !           692: }
        !           693: 
        !           694: /** json_parser_char append one single char to the parser
        !           695:  * return 0 if everything went ok, a JSON_ERROR_* otherwise */
        !           696: int json_parser_char(json_parser *parser, unsigned char ch)
        !           697: {
        !           698:        return json_parser_string(parser, (char *) &ch, 1, NULL);
        !           699: }

E-mail: