root / json-lexer.c @ 9f107513
History | View | Annotate | Download (7.4 kB)
1 | 5ab8558d | Anthony Liguori | /*
|
---|---|---|---|
2 | 5ab8558d | Anthony Liguori | * JSON lexer
|
3 | 5ab8558d | Anthony Liguori | *
|
4 | 5ab8558d | Anthony Liguori | * Copyright IBM, Corp. 2009
|
5 | 5ab8558d | Anthony Liguori | *
|
6 | 5ab8558d | Anthony Liguori | * Authors:
|
7 | 5ab8558d | Anthony Liguori | * Anthony Liguori <aliguori@us.ibm.com>
|
8 | 5ab8558d | Anthony Liguori | *
|
9 | 5ab8558d | Anthony Liguori | * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
|
10 | 5ab8558d | Anthony Liguori | * See the COPYING.LIB file in the top-level directory.
|
11 | 5ab8558d | Anthony Liguori | *
|
12 | 5ab8558d | Anthony Liguori | */
|
13 | 5ab8558d | Anthony Liguori | |
14 | 5ab8558d | Anthony Liguori | #include "qstring.h" |
15 | 5ab8558d | Anthony Liguori | #include "qlist.h" |
16 | 5ab8558d | Anthony Liguori | #include "qdict.h" |
17 | 5ab8558d | Anthony Liguori | #include "qint.h" |
18 | 5ab8558d | Anthony Liguori | #include "qemu-common.h" |
19 | 5ab8558d | Anthony Liguori | #include "json-lexer.h" |
20 | 5ab8558d | Anthony Liguori | |
21 | 5ab8558d | Anthony Liguori | /*
|
22 | 5ab8558d | Anthony Liguori | * \"([^\\\"]|(\\\"\\'\\\\\\/\\b\\f\\n\\r\\t\\u[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]))*\"
|
23 | 5ab8558d | Anthony Liguori | * '([^\\']|(\\\"\\'\\\\\\/\\b\\f\\n\\r\\t\\u[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]))*'
|
24 | 5ab8558d | Anthony Liguori | * 0|([1-9][0-9]*(.[0-9]+)?([eE]([-+])?[0-9]+))
|
25 | 5ab8558d | Anthony Liguori | * [{}\[\],:]
|
26 | 5ab8558d | Anthony Liguori | * [a-z]+
|
27 | 5ab8558d | Anthony Liguori | *
|
28 | 5ab8558d | Anthony Liguori | */
|
29 | 5ab8558d | Anthony Liguori | |
30 | 5ab8558d | Anthony Liguori | enum json_lexer_state {
|
31 | 5ab8558d | Anthony Liguori | ERROR = 0,
|
32 | 5ab8558d | Anthony Liguori | IN_DONE_STRING, |
33 | 5ab8558d | Anthony Liguori | IN_DQ_UCODE3, |
34 | 5ab8558d | Anthony Liguori | IN_DQ_UCODE2, |
35 | 5ab8558d | Anthony Liguori | IN_DQ_UCODE1, |
36 | 5ab8558d | Anthony Liguori | IN_DQ_UCODE0, |
37 | 5ab8558d | Anthony Liguori | IN_DQ_STRING_ESCAPE, |
38 | 5ab8558d | Anthony Liguori | IN_DQ_STRING, |
39 | 5ab8558d | Anthony Liguori | IN_SQ_UCODE3, |
40 | 5ab8558d | Anthony Liguori | IN_SQ_UCODE2, |
41 | 5ab8558d | Anthony Liguori | IN_SQ_UCODE1, |
42 | 5ab8558d | Anthony Liguori | IN_SQ_UCODE0, |
43 | 5ab8558d | Anthony Liguori | IN_SQ_STRING_ESCAPE, |
44 | 5ab8558d | Anthony Liguori | IN_SQ_STRING, |
45 | 5ab8558d | Anthony Liguori | IN_ZERO, |
46 | 5ab8558d | Anthony Liguori | IN_DIGITS, |
47 | 5ab8558d | Anthony Liguori | IN_DIGIT, |
48 | 5ab8558d | Anthony Liguori | IN_EXP_E, |
49 | 5ab8558d | Anthony Liguori | IN_MANTISSA, |
50 | 5ab8558d | Anthony Liguori | IN_MANTISSA_DIGITS, |
51 | 5ab8558d | Anthony Liguori | IN_NONZERO_NUMBER, |
52 | 5ab8558d | Anthony Liguori | IN_NEG_NONZERO_NUMBER, |
53 | 5ab8558d | Anthony Liguori | IN_KEYWORD, |
54 | 5ab8558d | Anthony Liguori | IN_ESCAPE, |
55 | 5ab8558d | Anthony Liguori | IN_ESCAPE_L, |
56 | 5ab8558d | Anthony Liguori | IN_ESCAPE_LL, |
57 | 2c0d4b36 | Roy Tam | IN_ESCAPE_I, |
58 | 2c0d4b36 | Roy Tam | IN_ESCAPE_I6, |
59 | 2c0d4b36 | Roy Tam | IN_ESCAPE_I64, |
60 | 5ab8558d | Anthony Liguori | IN_ESCAPE_DONE, |
61 | 5ab8558d | Anthony Liguori | IN_WHITESPACE, |
62 | 5ab8558d | Anthony Liguori | IN_OPERATOR_DONE, |
63 | 5ab8558d | Anthony Liguori | IN_START, |
64 | 5ab8558d | Anthony Liguori | }; |
65 | 5ab8558d | Anthony Liguori | |
66 | 5ab8558d | Anthony Liguori | #define TERMINAL(state) [0 ... 0x7F] = (state) |
67 | 5ab8558d | Anthony Liguori | |
68 | 5ab8558d | Anthony Liguori | static const uint8_t json_lexer[][256] = { |
69 | 5ab8558d | Anthony Liguori | [IN_DONE_STRING] = { |
70 | 5ab8558d | Anthony Liguori | TERMINAL(JSON_STRING), |
71 | 5ab8558d | Anthony Liguori | }, |
72 | 5ab8558d | Anthony Liguori | |
73 | 5ab8558d | Anthony Liguori | /* double quote string */
|
74 | 5ab8558d | Anthony Liguori | [IN_DQ_UCODE3] = { |
75 | 5ab8558d | Anthony Liguori | ['0' ... '9'] = IN_DQ_STRING, |
76 | 5ab8558d | Anthony Liguori | ['a' ... 'f'] = IN_DQ_STRING, |
77 | 5ab8558d | Anthony Liguori | ['A' ... 'F'] = IN_DQ_STRING, |
78 | 5ab8558d | Anthony Liguori | }, |
79 | 5ab8558d | Anthony Liguori | [IN_DQ_UCODE2] = { |
80 | 5ab8558d | Anthony Liguori | ['0' ... '9'] = IN_DQ_UCODE3, |
81 | 5ab8558d | Anthony Liguori | ['a' ... 'f'] = IN_DQ_UCODE3, |
82 | 5ab8558d | Anthony Liguori | ['A' ... 'F'] = IN_DQ_UCODE3, |
83 | 5ab8558d | Anthony Liguori | }, |
84 | 5ab8558d | Anthony Liguori | [IN_DQ_UCODE1] = { |
85 | 5ab8558d | Anthony Liguori | ['0' ... '9'] = IN_DQ_UCODE2, |
86 | 5ab8558d | Anthony Liguori | ['a' ... 'f'] = IN_DQ_UCODE2, |
87 | 5ab8558d | Anthony Liguori | ['A' ... 'F'] = IN_DQ_UCODE2, |
88 | 5ab8558d | Anthony Liguori | }, |
89 | 5ab8558d | Anthony Liguori | [IN_DQ_UCODE0] = { |
90 | 5ab8558d | Anthony Liguori | ['0' ... '9'] = IN_DQ_UCODE1, |
91 | 5ab8558d | Anthony Liguori | ['a' ... 'f'] = IN_DQ_UCODE1, |
92 | 5ab8558d | Anthony Liguori | ['A' ... 'F'] = IN_DQ_UCODE1, |
93 | 5ab8558d | Anthony Liguori | }, |
94 | 5ab8558d | Anthony Liguori | [IN_DQ_STRING_ESCAPE] = { |
95 | 5ab8558d | Anthony Liguori | ['b'] = IN_DQ_STRING,
|
96 | 5ab8558d | Anthony Liguori | ['f'] = IN_DQ_STRING,
|
97 | 5ab8558d | Anthony Liguori | ['n'] = IN_DQ_STRING,
|
98 | 5ab8558d | Anthony Liguori | ['r'] = IN_DQ_STRING,
|
99 | 5ab8558d | Anthony Liguori | ['t'] = IN_DQ_STRING,
|
100 | 5ab8558d | Anthony Liguori | ['\''] = IN_DQ_STRING,
|
101 | 5ab8558d | Anthony Liguori | ['\"'] = IN_DQ_STRING,
|
102 | 5ab8558d | Anthony Liguori | ['u'] = IN_DQ_UCODE0,
|
103 | 5ab8558d | Anthony Liguori | }, |
104 | 5ab8558d | Anthony Liguori | [IN_DQ_STRING] = { |
105 | 5ab8558d | Anthony Liguori | [1 ... 0xFF] = IN_DQ_STRING, |
106 | 5ab8558d | Anthony Liguori | ['\\'] = IN_DQ_STRING_ESCAPE,
|
107 | 5ab8558d | Anthony Liguori | ['"'] = IN_DONE_STRING,
|
108 | 5ab8558d | Anthony Liguori | }, |
109 | 5ab8558d | Anthony Liguori | |
110 | 5ab8558d | Anthony Liguori | /* single quote string */
|
111 | 5ab8558d | Anthony Liguori | [IN_SQ_UCODE3] = { |
112 | 5ab8558d | Anthony Liguori | ['0' ... '9'] = IN_SQ_STRING, |
113 | 5ab8558d | Anthony Liguori | ['a' ... 'f'] = IN_SQ_STRING, |
114 | 5ab8558d | Anthony Liguori | ['A' ... 'F'] = IN_SQ_STRING, |
115 | 5ab8558d | Anthony Liguori | }, |
116 | 5ab8558d | Anthony Liguori | [IN_SQ_UCODE2] = { |
117 | 5ab8558d | Anthony Liguori | ['0' ... '9'] = IN_SQ_UCODE3, |
118 | 5ab8558d | Anthony Liguori | ['a' ... 'f'] = IN_SQ_UCODE3, |
119 | 5ab8558d | Anthony Liguori | ['A' ... 'F'] = IN_SQ_UCODE3, |
120 | 5ab8558d | Anthony Liguori | }, |
121 | 5ab8558d | Anthony Liguori | [IN_SQ_UCODE1] = { |
122 | 5ab8558d | Anthony Liguori | ['0' ... '9'] = IN_SQ_UCODE2, |
123 | 5ab8558d | Anthony Liguori | ['a' ... 'f'] = IN_SQ_UCODE2, |
124 | 5ab8558d | Anthony Liguori | ['A' ... 'F'] = IN_SQ_UCODE2, |
125 | 5ab8558d | Anthony Liguori | }, |
126 | 5ab8558d | Anthony Liguori | [IN_SQ_UCODE0] = { |
127 | 5ab8558d | Anthony Liguori | ['0' ... '9'] = IN_SQ_UCODE1, |
128 | 5ab8558d | Anthony Liguori | ['a' ... 'f'] = IN_SQ_UCODE1, |
129 | 5ab8558d | Anthony Liguori | ['A' ... 'F'] = IN_SQ_UCODE1, |
130 | 5ab8558d | Anthony Liguori | }, |
131 | 5ab8558d | Anthony Liguori | [IN_SQ_STRING_ESCAPE] = { |
132 | 5ab8558d | Anthony Liguori | ['b'] = IN_SQ_STRING,
|
133 | 5ab8558d | Anthony Liguori | ['f'] = IN_SQ_STRING,
|
134 | 5ab8558d | Anthony Liguori | ['n'] = IN_SQ_STRING,
|
135 | 5ab8558d | Anthony Liguori | ['r'] = IN_SQ_STRING,
|
136 | 5ab8558d | Anthony Liguori | ['t'] = IN_SQ_STRING,
|
137 | 5ab8558d | Anthony Liguori | ['\''] = IN_SQ_STRING,
|
138 | 5ab8558d | Anthony Liguori | ['\"'] = IN_SQ_STRING,
|
139 | 5ab8558d | Anthony Liguori | ['u'] = IN_SQ_UCODE0,
|
140 | 5ab8558d | Anthony Liguori | }, |
141 | 5ab8558d | Anthony Liguori | [IN_SQ_STRING] = { |
142 | 5ab8558d | Anthony Liguori | [1 ... 0xFF] = IN_SQ_STRING, |
143 | 5ab8558d | Anthony Liguori | ['\\'] = IN_SQ_STRING_ESCAPE,
|
144 | 5ab8558d | Anthony Liguori | ['\''] = IN_DONE_STRING,
|
145 | 5ab8558d | Anthony Liguori | }, |
146 | 5ab8558d | Anthony Liguori | |
147 | 5ab8558d | Anthony Liguori | /* Zero */
|
148 | 5ab8558d | Anthony Liguori | [IN_ZERO] = { |
149 | 5ab8558d | Anthony Liguori | TERMINAL(JSON_INTEGER), |
150 | 5ab8558d | Anthony Liguori | ['0' ... '9'] = ERROR, |
151 | 5ab8558d | Anthony Liguori | ['.'] = IN_MANTISSA,
|
152 | 5ab8558d | Anthony Liguori | }, |
153 | 5ab8558d | Anthony Liguori | |
154 | 5ab8558d | Anthony Liguori | /* Float */
|
155 | 5ab8558d | Anthony Liguori | [IN_DIGITS] = { |
156 | 5ab8558d | Anthony Liguori | TERMINAL(JSON_FLOAT), |
157 | 5ab8558d | Anthony Liguori | ['0' ... '9'] = IN_DIGITS, |
158 | 5ab8558d | Anthony Liguori | }, |
159 | 5ab8558d | Anthony Liguori | |
160 | 5ab8558d | Anthony Liguori | [IN_DIGIT] = { |
161 | 5ab8558d | Anthony Liguori | ['0' ... '9'] = IN_DIGITS, |
162 | 5ab8558d | Anthony Liguori | }, |
163 | 5ab8558d | Anthony Liguori | |
164 | 5ab8558d | Anthony Liguori | [IN_EXP_E] = { |
165 | 5ab8558d | Anthony Liguori | ['-'] = IN_DIGIT,
|
166 | 5ab8558d | Anthony Liguori | ['+'] = IN_DIGIT,
|
167 | 5ab8558d | Anthony Liguori | ['0' ... '9'] = IN_DIGITS, |
168 | 5ab8558d | Anthony Liguori | }, |
169 | 5ab8558d | Anthony Liguori | |
170 | 5ab8558d | Anthony Liguori | [IN_MANTISSA_DIGITS] = { |
171 | 5ab8558d | Anthony Liguori | TERMINAL(JSON_FLOAT), |
172 | 5ab8558d | Anthony Liguori | ['0' ... '9'] = IN_MANTISSA_DIGITS, |
173 | 5ab8558d | Anthony Liguori | ['e'] = IN_EXP_E,
|
174 | 5ab8558d | Anthony Liguori | ['E'] = IN_EXP_E,
|
175 | 5ab8558d | Anthony Liguori | }, |
176 | 5ab8558d | Anthony Liguori | |
177 | 5ab8558d | Anthony Liguori | [IN_MANTISSA] = { |
178 | 5ab8558d | Anthony Liguori | ['0' ... '9'] = IN_MANTISSA_DIGITS, |
179 | 5ab8558d | Anthony Liguori | }, |
180 | 5ab8558d | Anthony Liguori | |
181 | 5ab8558d | Anthony Liguori | /* Number */
|
182 | 5ab8558d | Anthony Liguori | [IN_NONZERO_NUMBER] = { |
183 | 5ab8558d | Anthony Liguori | TERMINAL(JSON_INTEGER), |
184 | 5ab8558d | Anthony Liguori | ['0' ... '9'] = IN_NONZERO_NUMBER, |
185 | 5ab8558d | Anthony Liguori | ['e'] = IN_EXP_E,
|
186 | 5ab8558d | Anthony Liguori | ['E'] = IN_EXP_E,
|
187 | 5ab8558d | Anthony Liguori | ['.'] = IN_MANTISSA,
|
188 | 5ab8558d | Anthony Liguori | }, |
189 | 5ab8558d | Anthony Liguori | |
190 | 5ab8558d | Anthony Liguori | [IN_NEG_NONZERO_NUMBER] = { |
191 | 5ab8558d | Anthony Liguori | ['0'] = IN_ZERO,
|
192 | 5ab8558d | Anthony Liguori | ['1' ... '9'] = IN_NONZERO_NUMBER, |
193 | 5ab8558d | Anthony Liguori | }, |
194 | 5ab8558d | Anthony Liguori | |
195 | 5ab8558d | Anthony Liguori | /* keywords */
|
196 | 5ab8558d | Anthony Liguori | [IN_KEYWORD] = { |
197 | 5ab8558d | Anthony Liguori | TERMINAL(JSON_KEYWORD), |
198 | 5ab8558d | Anthony Liguori | ['a' ... 'z'] = IN_KEYWORD, |
199 | 5ab8558d | Anthony Liguori | }, |
200 | 5ab8558d | Anthony Liguori | |
201 | 5ab8558d | Anthony Liguori | /* whitespace */
|
202 | 5ab8558d | Anthony Liguori | [IN_WHITESPACE] = { |
203 | 5ab8558d | Anthony Liguori | TERMINAL(JSON_SKIP), |
204 | 5ab8558d | Anthony Liguori | [' '] = IN_WHITESPACE,
|
205 | 5ab8558d | Anthony Liguori | ['\t'] = IN_WHITESPACE,
|
206 | 5ab8558d | Anthony Liguori | ['\r'] = IN_WHITESPACE,
|
207 | 5ab8558d | Anthony Liguori | ['\n'] = IN_WHITESPACE,
|
208 | 5ab8558d | Anthony Liguori | }, |
209 | 5ab8558d | Anthony Liguori | |
210 | 5ab8558d | Anthony Liguori | /* operator */
|
211 | 5ab8558d | Anthony Liguori | [IN_OPERATOR_DONE] = { |
212 | 5ab8558d | Anthony Liguori | TERMINAL(JSON_OPERATOR), |
213 | 5ab8558d | Anthony Liguori | }, |
214 | 5ab8558d | Anthony Liguori | |
215 | 5ab8558d | Anthony Liguori | /* escape */
|
216 | 5ab8558d | Anthony Liguori | [IN_ESCAPE_DONE] = { |
217 | 5ab8558d | Anthony Liguori | TERMINAL(JSON_ESCAPE), |
218 | 5ab8558d | Anthony Liguori | }, |
219 | 5ab8558d | Anthony Liguori | |
220 | 5ab8558d | Anthony Liguori | [IN_ESCAPE_LL] = { |
221 | 5ab8558d | Anthony Liguori | ['d'] = IN_ESCAPE_DONE,
|
222 | 5ab8558d | Anthony Liguori | }, |
223 | 5ab8558d | Anthony Liguori | |
224 | 5ab8558d | Anthony Liguori | [IN_ESCAPE_L] = { |
225 | 5ab8558d | Anthony Liguori | ['d'] = IN_ESCAPE_DONE,
|
226 | 5ab8558d | Anthony Liguori | ['l'] = IN_ESCAPE_LL,
|
227 | 5ab8558d | Anthony Liguori | }, |
228 | 5ab8558d | Anthony Liguori | |
229 | 2c0d4b36 | Roy Tam | [IN_ESCAPE_I64] = { |
230 | 2c0d4b36 | Roy Tam | ['d'] = IN_ESCAPE_DONE,
|
231 | 2c0d4b36 | Roy Tam | }, |
232 | 2c0d4b36 | Roy Tam | |
233 | 2c0d4b36 | Roy Tam | [IN_ESCAPE_I6] = { |
234 | 2c0d4b36 | Roy Tam | ['4'] = IN_ESCAPE_I64,
|
235 | 2c0d4b36 | Roy Tam | }, |
236 | 2c0d4b36 | Roy Tam | |
237 | 2c0d4b36 | Roy Tam | [IN_ESCAPE_I] = { |
238 | 2c0d4b36 | Roy Tam | ['6'] = IN_ESCAPE_I6,
|
239 | 2c0d4b36 | Roy Tam | }, |
240 | 2c0d4b36 | Roy Tam | |
241 | 5ab8558d | Anthony Liguori | [IN_ESCAPE] = { |
242 | 5ab8558d | Anthony Liguori | ['d'] = IN_ESCAPE_DONE,
|
243 | 5ab8558d | Anthony Liguori | ['i'] = IN_ESCAPE_DONE,
|
244 | 5ab8558d | Anthony Liguori | ['p'] = IN_ESCAPE_DONE,
|
245 | 5ab8558d | Anthony Liguori | ['s'] = IN_ESCAPE_DONE,
|
246 | 5ab8558d | Anthony Liguori | ['f'] = IN_ESCAPE_DONE,
|
247 | 5ab8558d | Anthony Liguori | ['l'] = IN_ESCAPE_L,
|
248 | 2c0d4b36 | Roy Tam | ['I'] = IN_ESCAPE_I,
|
249 | 5ab8558d | Anthony Liguori | }, |
250 | 5ab8558d | Anthony Liguori | |
251 | 5ab8558d | Anthony Liguori | /* top level rule */
|
252 | 5ab8558d | Anthony Liguori | [IN_START] = { |
253 | 5ab8558d | Anthony Liguori | ['"'] = IN_DQ_STRING,
|
254 | 5ab8558d | Anthony Liguori | ['\''] = IN_SQ_STRING,
|
255 | 5ab8558d | Anthony Liguori | ['0'] = IN_ZERO,
|
256 | 5ab8558d | Anthony Liguori | ['1' ... '9'] = IN_NONZERO_NUMBER, |
257 | 5ab8558d | Anthony Liguori | ['-'] = IN_NEG_NONZERO_NUMBER,
|
258 | 5ab8558d | Anthony Liguori | ['{'] = IN_OPERATOR_DONE,
|
259 | 5ab8558d | Anthony Liguori | ['}'] = IN_OPERATOR_DONE,
|
260 | 5ab8558d | Anthony Liguori | ['['] = IN_OPERATOR_DONE,
|
261 | 5ab8558d | Anthony Liguori | [']'] = IN_OPERATOR_DONE,
|
262 | 5ab8558d | Anthony Liguori | [','] = IN_OPERATOR_DONE,
|
263 | 5ab8558d | Anthony Liguori | [':'] = IN_OPERATOR_DONE,
|
264 | 5ab8558d | Anthony Liguori | ['a' ... 'z'] = IN_KEYWORD, |
265 | 5ab8558d | Anthony Liguori | ['%'] = IN_ESCAPE,
|
266 | 5ab8558d | Anthony Liguori | [' '] = IN_WHITESPACE,
|
267 | 5ab8558d | Anthony Liguori | ['\t'] = IN_WHITESPACE,
|
268 | 5ab8558d | Anthony Liguori | ['\r'] = IN_WHITESPACE,
|
269 | 5ab8558d | Anthony Liguori | ['\n'] = IN_WHITESPACE,
|
270 | 5ab8558d | Anthony Liguori | }, |
271 | 5ab8558d | Anthony Liguori | }; |
272 | 5ab8558d | Anthony Liguori | |
273 | 5ab8558d | Anthony Liguori | void json_lexer_init(JSONLexer *lexer, JSONLexerEmitter func)
|
274 | 5ab8558d | Anthony Liguori | { |
275 | 5ab8558d | Anthony Liguori | lexer->emit = func; |
276 | 5ab8558d | Anthony Liguori | lexer->state = IN_START; |
277 | 5ab8558d | Anthony Liguori | lexer->token = qstring_new(); |
278 | 5ab8558d | Anthony Liguori | } |
279 | 5ab8558d | Anthony Liguori | |
280 | 5ab8558d | Anthony Liguori | static int json_lexer_feed_char(JSONLexer *lexer, char ch) |
281 | 5ab8558d | Anthony Liguori | { |
282 | 5ab8558d | Anthony Liguori | char buf[2]; |
283 | 5ab8558d | Anthony Liguori | |
284 | 5ab8558d | Anthony Liguori | lexer->x++; |
285 | 5ab8558d | Anthony Liguori | if (ch == '\n') { |
286 | 5ab8558d | Anthony Liguori | lexer->x = 0;
|
287 | 5ab8558d | Anthony Liguori | lexer->y++; |
288 | 5ab8558d | Anthony Liguori | } |
289 | 5ab8558d | Anthony Liguori | |
290 | 5ab8558d | Anthony Liguori | lexer->state = json_lexer[lexer->state][(uint8_t)ch]; |
291 | 5ab8558d | Anthony Liguori | |
292 | 5ab8558d | Anthony Liguori | switch (lexer->state) {
|
293 | 5ab8558d | Anthony Liguori | case JSON_OPERATOR:
|
294 | 5ab8558d | Anthony Liguori | case JSON_ESCAPE:
|
295 | 5ab8558d | Anthony Liguori | case JSON_INTEGER:
|
296 | 5ab8558d | Anthony Liguori | case JSON_FLOAT:
|
297 | 5ab8558d | Anthony Liguori | case JSON_KEYWORD:
|
298 | 5ab8558d | Anthony Liguori | case JSON_STRING:
|
299 | 5ab8558d | Anthony Liguori | lexer->emit(lexer, lexer->token, lexer->state, lexer->x, lexer->y); |
300 | 5ab8558d | Anthony Liguori | case JSON_SKIP:
|
301 | 5ab8558d | Anthony Liguori | lexer->state = json_lexer[IN_START][(uint8_t)ch]; |
302 | 5ab8558d | Anthony Liguori | QDECREF(lexer->token); |
303 | 5ab8558d | Anthony Liguori | lexer->token = qstring_new(); |
304 | 5ab8558d | Anthony Liguori | break;
|
305 | 5ab8558d | Anthony Liguori | case ERROR:
|
306 | 5ab8558d | Anthony Liguori | return -EINVAL;
|
307 | 5ab8558d | Anthony Liguori | default:
|
308 | 5ab8558d | Anthony Liguori | break;
|
309 | 5ab8558d | Anthony Liguori | } |
310 | 5ab8558d | Anthony Liguori | |
311 | 5ab8558d | Anthony Liguori | buf[0] = ch;
|
312 | 5ab8558d | Anthony Liguori | buf[1] = 0; |
313 | 5ab8558d | Anthony Liguori | |
314 | 5ab8558d | Anthony Liguori | qstring_append(lexer->token, buf); |
315 | 5ab8558d | Anthony Liguori | |
316 | 5ab8558d | Anthony Liguori | return 0; |
317 | 5ab8558d | Anthony Liguori | } |
318 | 5ab8558d | Anthony Liguori | |
319 | 5ab8558d | Anthony Liguori | int json_lexer_feed(JSONLexer *lexer, const char *buffer, size_t size) |
320 | 5ab8558d | Anthony Liguori | { |
321 | 5ab8558d | Anthony Liguori | size_t i; |
322 | 5ab8558d | Anthony Liguori | |
323 | 5ab8558d | Anthony Liguori | for (i = 0; i < size; i++) { |
324 | 5ab8558d | Anthony Liguori | int err;
|
325 | 5ab8558d | Anthony Liguori | |
326 | 5ab8558d | Anthony Liguori | err = json_lexer_feed_char(lexer, buffer[i]); |
327 | 5ab8558d | Anthony Liguori | if (err < 0) { |
328 | 5ab8558d | Anthony Liguori | return err;
|
329 | 5ab8558d | Anthony Liguori | } |
330 | 5ab8558d | Anthony Liguori | } |
331 | 5ab8558d | Anthony Liguori | |
332 | 5ab8558d | Anthony Liguori | return 0; |
333 | 5ab8558d | Anthony Liguori | } |
334 | 5ab8558d | Anthony Liguori | |
335 | 5ab8558d | Anthony Liguori | int json_lexer_flush(JSONLexer *lexer)
|
336 | 5ab8558d | Anthony Liguori | { |
337 | 5ab8558d | Anthony Liguori | return json_lexer_feed_char(lexer, 0); |
338 | 5ab8558d | Anthony Liguori | } |
339 | 5ab8558d | Anthony Liguori | |
340 | 5ab8558d | Anthony Liguori | void json_lexer_destroy(JSONLexer *lexer)
|
341 | 5ab8558d | Anthony Liguori | { |
342 | 5ab8558d | Anthony Liguori | QDECREF(lexer->token); |
343 | 5ab8558d | Anthony Liguori | } |