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: