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

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

E-mail: