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: