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

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: 
1.15      moko      124: /* some compilers have the following names defined */
                    125: #undef _C2
                    126: #undef ST_
                    127: #undef PT_
                    128: 
1.1       moko      129: /* error state */
                    130: #define STATE___       0xff
                    131: 
                    132: #define NR_STATES      (STATE_D2 + 1)
                    133: #define NR_CLASSES     (C_HASH + 1)
                    134: 
                    135: #define IS_STATE_ACTION(s) ((s) & 0x80)
1.14      moko      136: #define ST_(x) STATE##x
                    137: #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)                               \
                    138:        { ST_(a),ST_(b),ST_(c),ST_(d),ST_(e),ST_(f),ST_(g),ST_(h),ST_(i),ST_(j),ST_(k),ST_(l),ST_(m),ST_(n),            \
                    139:          ST_(o),ST_(p),ST_(q),ST_(r),ST_(s),ST_(t),ST_(u),ST_(v),ST_(w),ST_(x),ST_(y),ST_(z),ST_(a1),ST_(b1),          \
                    140:          ST_(c1),ST_(d1),ST_(e1),ST_(f1),ST_(g1),ST_(h1) }
1.1       moko      141: 
                    142: /* map from the (previous state+new character class) to the next parser transition */
                    143: static const uint8_t state_transition_table[NR_STATES][NR_CLASSES] = {
                    144: /*             white                                                                            ABCDF  other    */
1.14      moko      145: /*          sp  nl  |   {   }   [   ]   :   ,   "   \   /   +   -   .   0   19  a   b   c   d   e   f   l   n   r   s   t   u   |   E   |   *   # */
                    146: /*GO*/ PT_(_GO,_GO,_GO,_OB,___,_AB,___,___,___,___,___,_CB,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,_YB),
                    147: /*OK*/ PT_(_OK,_OK,_OK,___,_OE,___,_AE,___,_SP,___,___,_CB,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,_YB),
                    148: /*OO*/ PT_(_OO,_OO,_OO,___,_OE,___,___,___,___,_SS,___,_CB,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,_YB),
                    149: /*KK*/ PT_(_KK,_KK,_KK,___,___,___,___,___,___,_SS,___,_CB,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,_YB),
                    150: /*CO*/ PT_(_CO,_CO,_CO,___,___,___,___,_KS,___,___,___,_CB,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,_YB),
                    151: /*VV*/ PT_(_VV,_VV,_VV,_OB,___,_AB,___,___,___,_SS,___,_CB,___,_MX,___,_ZX,_IX,___,___,___,___,___,_F1,___,_N1,___,___,_T1,___,___,___,___,___,_YB),
                    152: /*AA*/ PT_(_AA,_AA,_AA,_OB,___,_AB,_AE,___,___,_SS,___,_CB,___,_MX,___,_ZX,_IX,___,___,___,___,___,_F1,___,_N1,___,___,_T1,___,___,___,___,___,_YB),
                    153: /**************************************************************************************************************************************************/
                    154: /*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),
                    155: /*E0*/ PT_(___,___,___,___,___,___,___,___,___,_SS,_SS,_SS,___,___,___,___,___,___,_SS,___,___,___,_SS,___,_SS,_SS,___,_SS,_U1,___,___,___,___,___),
                    156: /*U1*/ PT_(___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,_U2,_U2,_U2,_U2,_U2,_U2,_U2,_U2,___,___,___,___,___,___,_U2,_U2,___,___,___),
                    157: /*U2*/ PT_(___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,_U3,_U3,_U3,_U3,_U3,_U3,_U3,_U3,___,___,___,___,___,___,_U3,_U3,___,___,___),
                    158: /*U3*/ PT_(___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,_U4,_U4,_U4,_U4,_U4,_U4,_U4,_U4,___,___,___,___,___,___,_U4,_U4,___,___,___),
                    159: /*U4*/ PT_(___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,_UC,_UC,_UC,_UC,_UC,_UC,_UC,_UC,___,___,___,___,___,___,_UC,_UC,___,___,___),
                    160: /**************************************************************************************************************************************************/
                    161: /*M0*/ PT_(___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,_Z0,_I0,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___),
                    162: /*Z0*/ PT_(_OK,_OK,_OK,___,_OE,___,_AE,___,_SP,___,___,_CB,___,___,_DF,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,_YB),
                    163: /*I0*/ PT_(_OK,_OK,_OK,___,_OE,___,_AE,___,_SP,___,___,_CB,___,___,_DF,_I0,_I0,___,___,___,___,_DE,___,___,___,___,___,___,___,___,_DE,___,___,_YB),
                    164: /*R1*/ PT_(___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,_R2,_R2,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___),
                    165: /*R2*/ PT_(_OK,_OK,_OK,___,_OE,___,_AE,___,_SP,___,___,_CB,___,___,___,_R2,_R2,___,___,___,___,_X1,___,___,___,___,___,___,___,___,_X1,___,___,_YB),
                    166: /*X1*/ PT_(___,___,___,___,___,___,___,___,___,___,___,___,_X2,_X2,___,_X3,_X3,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___),
                    167: /*X2*/ PT_(___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,_X3,_X3,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___),
                    168: /*X3*/ PT_(_OK,_OK,_OK,___,_OE,___,_AE,___,_SP,___,___,___,___,___,___,_X3,_X3,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___),
                    169: /**************************************************************************************************************************************************/
                    170: /*T1*/ PT_(___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,_T2,___,___,___,___,___,___,___,___),
                    171: /*T2*/ PT_(___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,_T3,___,___,___,___,___),
                    172: /*T3*/ PT_(___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,_TR,___,___,___,___,___,___,___,___,___,___,___,___),
                    173: /*F1*/ PT_(___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,_F2,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___),
                    174: /*F2*/ PT_(___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,_F3,___,___,___,___,___,___,___,___,___,___),
                    175: /*F3*/ PT_(___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,_F4,___,___,___,___,___,___,___),
                    176: /*F4*/ PT_(___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,_FA,___,___,___,___,___,___,___,___,___,___,___,___),
                    177: /*N1*/ PT_(___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,_N2,___,___,___,___,___),
                    178: /*N2*/ PT_(___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,_N3,___,___,___,___,___,___,___,___,___,___),
                    179: /*N3*/ PT_(___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,_NU,___,___,___,___,___,___,___,___,___,___),
                    180: /**************************************************************************************************************************************************/
                    181: /*C1*/ PT_(___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,_C2,___),
                    182: /*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),
                    183: /*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),
                    184: /*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),
                    185: /*D1*/ PT_(___,___,___,___,___,___,___,___,___,___,_D2,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___),
                    186: /*D2*/ PT_(___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,_U1,___,___,___,___,___),
1.1       moko      187: };
                    188: /* map from (previous state+new character class) to the buffer policy. ignore=0/append=1/escape=2 */
                    189: static const uint8_t buffer_policy_table[NR_STATES][NR_CLASSES] = {
                    190: /*          white                                                                            ABCDF  other     */
                    191: /*      sp nl  |  {  }  [  ]  :  ,  "  \  /  +  -  .  0  19 a  b  c  d  e  f  l  n  r  s  t  u  |  E  |  *  # */
                    192: /*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 },
                    193: /*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      194: /*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 },
                    195: /*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      196: /*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      197: /*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 },
                    198: /*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      199: /**************************************************************************************************************/
1.11      moko      200: /*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      201: /*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 },
                    202: /*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 },
                    203: /*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 },
                    204: /*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 },
                    205: /*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 },
                    206: /**************************************************************************************************************/
                    207: /*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 },
                    208: /*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 },
                    209: /*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 },
                    210: /*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 },
                    211: /*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 },
                    212: /*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 },
                    213: /*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 },
                    214: /*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 },
                    215: /**************************************************************************************************************/
                    216: /*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 },
                    217: /*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 },
                    218: /*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 },
                    219: /*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 },
                    220: /*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 },
                    221: /*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 },
                    222: /*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 },
                    223: /*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 },
                    224: /*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 },
                    225: /*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 },
                    226: /**************************************************************************************************************/
                    227: /*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 },
                    228: /*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 },
                    229: /*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 },
                    230: /*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 },
                    231: /*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 },
                    232: /*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 },
                    233: };
                    234: 
                    235: #define MODE_ARRAY 0
                    236: #define MODE_OBJECT 1
                    237: 
                    238: #define parser_malloc(parser, s) parser->config.user_malloc(s)
                    239: #define parser_realloc(parser, p, s) parser->config.user_realloc(p, s)
                    240: #define parser_free(parser, p) parser->config.user_free(p)
                    241: 
                    242: static int state_grow(json_parser *parser)
                    243: {
                    244:        uint32_t newsize = parser->stack_size * 2;
                    245:        void *ptr;
                    246: 
                    247:        if (parser->config.max_nesting != 0)
                    248:                return JSON_ERROR_NESTING_LIMIT;
                    249: 
                    250:        ptr = parser_realloc(parser, parser->stack, newsize * sizeof(uint8_t));
                    251:        if (!ptr)
                    252:                return JSON_ERROR_NO_MEMORY;
1.13      moko      253:        parser->stack = (uint8_t *)ptr;
1.1       moko      254:        parser->stack_size = newsize;
                    255:        return 0;
                    256: }
                    257: 
1.2       moko      258: static int state_push(json_parser *parser, uint8_t mode)
1.1       moko      259: {
                    260:        if (parser->stack_offset >= parser->stack_size) {
                    261:                int ret = state_grow(parser);
                    262:                if (ret)
                    263:                        return ret;
                    264:        }
                    265:        parser->stack[parser->stack_offset++] = mode;
                    266:        return 0;
                    267: }
                    268: 
1.2       moko      269: static int state_pop(json_parser *parser, uint8_t mode)
1.1       moko      270: {
                    271:        if (parser->stack_offset == 0)
                    272:                return JSON_ERROR_POP_EMPTY;
                    273:        parser->stack_offset--;
                    274:        if (parser->stack[parser->stack_offset] != mode)
                    275:                return JSON_ERROR_POP_UNEXPECTED_MODE;
                    276:        return 0;
                    277: }
                    278: 
                    279: static int buffer_grow(json_parser *parser)
                    280: {
                    281:        uint32_t newsize;
                    282:        void *ptr;
1.2       moko      283:        uint32_t max = parser->config.max_data;
1.1       moko      284: 
                    285:        if (max > 0 && parser->buffer_size == max)
                    286:                return JSON_ERROR_DATA_LIMIT;
                    287:        newsize = parser->buffer_size * 2;
                    288:        if (max > 0 && newsize > max)
                    289:                newsize = max;
                    290: 
                    291:        ptr = parser_realloc(parser, parser->buffer, newsize * sizeof(char));
                    292:        if (!ptr)
                    293:                return JSON_ERROR_NO_MEMORY;
1.13      moko      294:        parser->buffer = (char *)ptr;
1.1       moko      295:        parser->buffer_size = newsize;
                    296:        return 0;
                    297: }
                    298: 
                    299: static int buffer_push(json_parser *parser, unsigned char c)
                    300: {
                    301:        int ret;
                    302: 
                    303:        if (parser->buffer_offset + 1 >= parser->buffer_size) {
                    304:                ret = buffer_grow(parser);
                    305:                if (ret)
                    306:                        return ret;
                    307:        }
                    308:        parser->buffer[parser->buffer_offset++] = c;
                    309:        return 0;
                    310: }
                    311: 
                    312: static int do_callback_withbuf(json_parser *parser, int type)
                    313: {
                    314:        if (!parser->callback)
                    315:                return 0;
                    316:        parser->buffer[parser->buffer_offset] = '\0';
                    317:        return (*parser->callback)(parser->userdata, type, parser->buffer, parser->buffer_offset);
                    318: }
                    319: 
                    320: static int do_callback(json_parser *parser, int type)
                    321: {
                    322:        if (!parser->callback)
                    323:                return 0;
                    324:        return (*parser->callback)(parser->userdata, type, NULL, 0);
                    325: }
                    326: 
                    327: static int do_buffer(json_parser *parser)
                    328: {
                    329:        int ret = 0;
                    330: 
                    331:        switch (parser->type) {
                    332:        case JSON_KEY: case JSON_STRING:
                    333:        case JSON_FLOAT: case JSON_INT:
                    334:        case JSON_NULL: case JSON_TRUE: case JSON_FALSE:
                    335:                ret = do_callback_withbuf(parser, parser->type);
                    336:                if (ret)
                    337:                        return ret;
                    338:                break;
                    339:        default:
                    340:                break;
                    341:        }
                    342:        parser->buffer_offset = 0;
                    343:        return ret;
                    344: }
                    345: 
                    346: static const uint8_t hextable[] = {
1.2       moko      347:        255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
                    348:        255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
                    349:        255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
                    350:          0,  1,  2,  3,  4,  5,  6,  7,  8,  9,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,
                    353:        255, 10, 11, 12, 13, 14, 15,255,255,255,255,255,255,255,255,255,
                    354:        255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
1.1       moko      355: };
                    356: 
                    357: #define hex(c) (hextable[(uint8_t) c])
                    358: 
                    359: /* high surrogate range from d800 to dbff */
                    360: /* low surrogate range dc00 to dfff */
                    361: #define IS_HIGH_SURROGATE(uc) (((uc) & 0xfc00) == 0xd800)
                    362: #define IS_LOW_SURROGATE(uc)  (((uc) & 0xfc00) == 0xdc00)
                    363: 
                    364: /* transform an unicode [0-9A-Fa-f]{4} sequence into a proper value */
                    365: static int decode_unicode_char(json_parser *parser)
                    366: {
                    367:        uint32_t uval;
                    368:        char *b = parser->buffer;
1.3       moko      369:        uint32_t offset = parser->buffer_offset;
1.1       moko      370: 
                    371:        uval = (hex(b[offset - 4]) << 12) | (hex(b[offset - 3]) << 8)
                    372:             | (hex(b[offset - 2]) << 4) | hex(b[offset - 1]);
                    373: 
                    374:        parser->buffer_offset -= 4;
                    375: 
                    376:        /* fast case */
                    377:        if (!parser->unicode_multi && uval < 0x80) {
                    378:                b[parser->buffer_offset++] = (char) uval;
                    379:                return 0;
                    380:        }
                    381: 
                    382:        if (parser->unicode_multi) {
                    383:                if (!IS_LOW_SURROGATE(uval))
                    384:                        return JSON_ERROR_UNICODE_MISSING_LOW_SURROGATE;
                    385: 
                    386:                uval = 0x10000 + ((parser->unicode_multi & 0x3ff) << 10) + (uval & 0x3ff);
                    387:                b[parser->buffer_offset++] = (char) ((uval >> 18) | 0xf0);
                    388:                b[parser->buffer_offset++] = (char) (((uval >> 12) & 0x3f) | 0x80);
                    389:                b[parser->buffer_offset++] = (char) (((uval >> 6) & 0x3f) | 0x80);
                    390:                b[parser->buffer_offset++] = (char) ((uval & 0x3f) | 0x80);
                    391:                parser->unicode_multi = 0;
                    392:                return 0;
                    393:        }
                    394: 
                    395:        if (IS_LOW_SURROGATE(uval))
                    396:                return JSON_ERROR_UNICODE_UNEXPECTED_LOW_SURROGATE;
                    397:        if (IS_HIGH_SURROGATE(uval)) {
1.3       moko      398:                parser->unicode_multi = (uint16_t)uval;
1.1       moko      399:                return 0;
                    400:        }
                    401: 
                    402:        if (uval < 0x800) {
                    403:                b[parser->buffer_offset++] = (char) ((uval >> 6) | 0xc0);
                    404:                b[parser->buffer_offset++] = (char) ((uval & 0x3f) | 0x80);
                    405:        } else {
                    406:                b[parser->buffer_offset++] = (char) ((uval >> 12) | 0xe0);
                    407:                b[parser->buffer_offset++] = (char) (((uval >> 6) & 0x3f) | 0x80);
                    408:                b[parser->buffer_offset++] = (char) (((uval >> 0) & 0x3f) | 0x80);
                    409:        }
                    410:        return 0;
                    411: }
                    412: 
                    413: static int buffer_push_escape(json_parser *parser, unsigned char next)
                    414: {
                    415:        char c = '\0';
                    416: 
                    417:        switch (next) {
                    418:        case 'b': c = '\b'; break;
                    419:        case 'f': c = '\f'; break;
                    420:        case 'n': c = '\n'; break;
                    421:        case 'r': c = '\r'; break;
                    422:        case 't': c = '\t'; break;
                    423:        case '"': c = '"'; break;
                    424:        case '/': c = '/'; break;
                    425:        case '\\': c = '\\'; break;
                    426:        }
                    427:        /* push the escaped character */
                    428:        return buffer_push(parser, c);
                    429: }
                    430: 
1.5       moko      431: #define CHK(f) { ret = f; if (ret) return ret; }
1.1       moko      432: 
1.8       moko      433: static int act_uc(json_parser *parser)
1.1       moko      434: {
                    435:        int ret;
                    436:        CHK(decode_unicode_char(parser));
1.11      moko      437:        parser->state = (uint8_t)((parser->unicode_multi) ? STATE_D1 : STATE_SS);
1.1       moko      438:        return 0;
                    439: }
                    440: 
1.8       moko      441: static int act_yb(json_parser *parser)
1.1       moko      442: {
                    443:        if (!parser->config.allow_yaml_comments)
                    444:                return JSON_ERROR_COMMENT_NOT_ALLOWED;
                    445:        parser->save_state = parser->state;
                    446:        return 0;
                    447: }
                    448: 
1.8       moko      449: static int act_cb(json_parser *parser)
1.1       moko      450: {
                    451:        if (!parser->config.allow_c_comments)
                    452:                return JSON_ERROR_COMMENT_NOT_ALLOWED;
                    453:        parser->save_state = parser->state;
                    454:        return 0;
                    455: }
                    456: 
1.8       moko      457: static int act_ce(json_parser *parser)
1.1       moko      458: {
1.16    ! moko      459:        parser->state = (parser->save_state > STATE_AA) ? (uint8_t)(STATE_OK) : (uint8_t)(parser->save_state);
1.1       moko      460:        return 0;
                    461: }
                    462: 
1.8       moko      463: static int act_ob(json_parser *parser)
1.1       moko      464: {
                    465:        int ret;
                    466:        CHK(do_callback(parser, JSON_OBJECT_BEGIN));
                    467:        CHK(state_push(parser, MODE_OBJECT));
                    468:        parser->expecting_key = 1;
                    469:        return 0;
                    470: }
                    471: 
1.8       moko      472: static int act_oe(json_parser *parser)
1.1       moko      473: {
                    474:        int ret;
1.8       moko      475:        CHK(state_pop(parser, MODE_OBJECT));
1.1       moko      476:        CHK(do_callback(parser, JSON_OBJECT_END));
                    477:        parser->expecting_key = 0;
                    478:        return 0;
                    479: }
                    480: 
1.8       moko      481: static int act_ab(json_parser *parser)
1.1       moko      482: {
                    483:        int ret;
                    484:        CHK(do_callback(parser, JSON_ARRAY_BEGIN));
                    485:        CHK(state_push(parser, MODE_ARRAY));
                    486:        return 0;
                    487: }
1.8       moko      488: static int act_ae(json_parser *parser)
1.1       moko      489: {
                    490:        int ret;
1.8       moko      491:        CHK(state_pop(parser, MODE_ARRAY));
1.1       moko      492:        CHK(do_callback(parser, JSON_ARRAY_END));
                    493:        return 0;
                    494: }
                    495: 
1.8       moko      496: static int act_se(json_parser *parser)
1.1       moko      497: {
                    498:        int ret;
                    499:        CHK(do_callback_withbuf(parser, (parser->expecting_key) ? JSON_KEY : JSON_STRING));
                    500:        parser->buffer_offset = 0;
1.10      moko      501:        parser->state = (uint8_t)((parser->expecting_key) ? STATE_CO : STATE_OK);
1.1       moko      502:        parser->expecting_key = 0;
                    503:        return 0;
                    504: }
                    505: 
1.8       moko      506: static int act_sp(json_parser *parser)
1.1       moko      507: {
                    508:        if (parser->stack_offset == 0)
                    509:                return JSON_ERROR_COMMA_OUT_OF_STRUCTURE;
                    510:        if (parser->stack[parser->stack_offset - 1] == MODE_OBJECT) {
                    511:                parser->expecting_key = 1;
1.11      moko      512:                parser->state = STATE_KK;
1.1       moko      513:        } else
1.11      moko      514:                parser->state = STATE_VV;
1.1       moko      515:        return 0;
                    516: }
                    517: 
                    518: struct action_descr
                    519: {
                    520:        int (*call)(json_parser *parser);
1.13      moko      521:        json_type type;
1.1       moko      522:        uint8_t state; /* 0 if we let the callback set the value it want */
                    523:        uint8_t dobuffer;
                    524: };
                    525: 
                    526: static struct action_descr actions_map[] = {
1.11      moko      527:        { NULL,   JSON_NONE,  STATE_VV, 0 }, /* KS */
1.8       moko      528:        { act_sp, JSON_NONE,  0,        1 }, /* SP */
1.11      moko      529:        { act_ab, JSON_NONE,  STATE_AA, 0 }, /* AB */
1.8       moko      530:        { act_ae, JSON_NONE,  STATE_OK, 1 }, /* AE */
1.11      moko      531:        { act_ob, JSON_NONE,  STATE_OO, 0 }, /* OB */
1.8       moko      532:        { act_oe, JSON_NONE,  STATE_OK, 1 }, /* OE */
                    533:        { act_cb, JSON_NONE,  STATE_C1, 1 }, /* CB */
                    534:        { act_yb, JSON_NONE,  STATE_Y1, 1 }, /* YB */
                    535:        { act_ce, JSON_NONE,  0,        0 }, /* CE */
                    536:        { NULL,   JSON_FALSE, STATE_OK, 0 }, /* FA */
                    537:        { NULL,   JSON_TRUE,  STATE_OK, 0 }, /* TR */
                    538:        { NULL,   JSON_NULL,  STATE_OK, 0 }, /* NU */
                    539:        { NULL,   JSON_FLOAT, STATE_X1, 0 }, /* DE */
                    540:        { NULL,   JSON_FLOAT, STATE_R1, 0 }, /* DF */
                    541:        { act_se, JSON_NONE,  0,        0 }, /* SE */
                    542:        { NULL,   JSON_INT,   STATE_M0, 0 }, /* MX */
                    543:        { NULL,   JSON_INT,   STATE_Z0, 0 }, /* ZX */
                    544:        { NULL,   JSON_INT,   STATE_I0, 0 }, /* IX */
                    545:        { act_uc, JSON_NONE,  0,        0 }, /* UC */
1.1       moko      546: };
                    547: 
1.4       moko      548: static int do_action(json_parser *parser, uint8_t next_state)
1.1       moko      549: {
                    550:        struct action_descr *descr = &actions_map[next_state & ~0x80];
                    551: 
                    552:        if (descr->call) {
                    553:                int ret;
                    554:                if (descr->dobuffer)
                    555:                        CHK(do_buffer(parser));
                    556:                CHK((descr->call)(parser));
                    557:        }
                    558:        if (descr->state)
                    559:                parser->state = descr->state;
                    560:        parser->type = descr->type;
                    561:        return 0;
                    562: }
                    563: 
                    564: /** json_parser_init initialize a parser structure taking a config,
                    565:  * a config and its userdata.
                    566:  * return JSON_ERROR_NO_MEMORY if memory allocation failed or SUCCESS.
                    567:  */
                    568: int json_parser_init(json_parser *parser, json_config *config,
                    569:                      json_parser_callback callback, void *userdata)
                    570: {
                    571:        memset(parser, 0, sizeof(*parser));
                    572: 
                    573:        if (config)
                    574:                memcpy(&parser->config, config, sizeof(json_config));
                    575:        parser->callback = callback;
                    576:        parser->userdata = userdata;
                    577: 
                    578:        /* initialise parsing stack and state */
                    579:        parser->stack_offset = 0;
                    580:        parser->state = STATE_GO;
                    581: 
                    582:        /* initialize the parse stack */
                    583:        parser->stack_size = (parser->config.max_nesting > 0)
                    584:                ? parser->config.max_nesting
                    585:                : LIBJSON_DEFAULT_STACK_SIZE;
                    586: 
1.13      moko      587:        parser->stack = (uint8_t *)parser_malloc(parser, parser->stack_size * sizeof(parser->stack[0]));
1.1       moko      588:        if (!parser->stack)
                    589:                return JSON_ERROR_NO_MEMORY;
                    590: 
                    591:        /* initialize the parse buffer */
                    592:        parser->buffer_size = (parser->config.buffer_initial_size > 0)
                    593:                ? parser->config.buffer_initial_size
                    594:                : LIBJSON_DEFAULT_BUFFER_SIZE;
                    595: 
                    596:        if (parser->config.max_data > 0 && parser->buffer_size > parser->config.max_data)
                    597:                parser->buffer_size = parser->config.max_data;
                    598: 
1.13      moko      599:        parser->buffer = (char *)parser_malloc(parser, parser->buffer_size * sizeof(char));
1.1       moko      600:        if (!parser->buffer) {
                    601:                parser_free(parser, parser->stack);
                    602:                return JSON_ERROR_NO_MEMORY;
                    603:        }
                    604:        return 0;
                    605: }
                    606: 
                    607: /** json_parser_free freed memory structure allocated by the parser */
                    608: int json_parser_free(json_parser *parser)
                    609: {
                    610:        if (!parser)
                    611:                return 0;
                    612:        parser_free(parser, parser->stack);
                    613:        parser_free(parser, parser->buffer);
                    614:        parser->stack = NULL;
                    615:        parser->buffer = NULL;
                    616:        return 0;
                    617: }
                    618: 
                    619: /** json_parser_is_done return 0 is the parser isn't in a finish state. !0 if it is */
                    620: int json_parser_is_done(json_parser *parser)
                    621: {
                    622:        /* need to compare the state to !GO to not accept empty document */
                    623:        return parser->stack_offset == 0 && parser->state != STATE_GO;
                    624: }
                    625: 
                    626: /** json_parser_string append a string s with a specific length to the parser
                    627:  * return 0 if everything went ok, a JSON_ERROR_* otherwise.
                    628:  * the user can supplied a valid processed pointer that will
                    629:  * be fill with the number of processed characters before returning */
                    630: int json_parser_string(json_parser *parser, const char *s,
                    631:                        uint32_t length, uint32_t *processed)
                    632: {
                    633:        int ret;
1.4       moko      634:        uint8_t next_class, next_state;
1.3       moko      635:        uint32_t buffer_policy;
1.1       moko      636:        uint32_t i;
                    637: 
                    638:        ret = 0;
                    639:        for (i = 0; i < length; i++) {
                    640:                unsigned char ch = s[i];
                    641: 
                    642:                ret = 0;
1.16    ! moko      643:                next_class = (ch >= 128) ? (uint8_t)(C_OTHER) : (uint8_t)(character_class[ch]);
1.1       moko      644:                if (next_class == C_ERROR) {
                    645:                        ret = JSON_ERROR_BAD_CHAR;
                    646:                        break;
                    647:                }
                    648: 
                    649:                next_state = state_transition_table[parser->state][next_class];
                    650:                buffer_policy = buffer_policy_table[parser->state][next_class];
                    651:                if (next_state == STATE___) {
                    652:                        ret = JSON_ERROR_UNEXPECTED_CHAR;
                    653:                        break;
                    654:                }
                    655: 
                    656:                /* add char to buffer */
                    657:                if (buffer_policy) {
                    658:                        ret = (buffer_policy == 2)
                    659:                                ? buffer_push_escape(parser, ch)
                    660:                                : buffer_push(parser, ch);
                    661:                        if (ret)
                    662:                                break;
                    663:                }
                    664: 
                    665:                /* move to the next level */
                    666:                if (IS_STATE_ACTION(next_state))
                    667:                        ret = do_action(parser, next_state);
                    668:                else
                    669:                        parser->state = next_state;
                    670:                if (ret)
                    671:                        break;
                    672:        }
                    673:        if (processed)
                    674:                *processed = i;
                    675:        return ret;
                    676: }
                    677: 
                    678: /** json_parser_char append one single char to the parser
                    679:  * return 0 if everything went ok, a JSON_ERROR_* otherwise */
                    680: int json_parser_char(json_parser *parser, unsigned char ch)
                    681: {
                    682:        return json_parser_string(parser, (char *) &ch, 1, NULL);
                    683: }

E-mail: