| 186 if (ttype != CX_JSON_TOKEN_STRING) { |
186 if (ttype != CX_JSON_TOKEN_STRING) { |
| 187 // currently non-string token |
187 // currently non-string token |
| 188 CxJsonTokenType ctype = char2ttype(c); // start of new token? |
188 CxJsonTokenType ctype = char2ttype(c); // start of new token? |
| 189 if (ttype == CX_JSON_NO_TOKEN) { |
189 if (ttype == CX_JSON_NO_TOKEN) { |
| 190 if (ctype == CX_JSON_TOKEN_SPACE) { |
190 if (ctype == CX_JSON_TOKEN_SPACE) { |
| |
191 json->buffer.pos++; |
| 191 continue; |
192 continue; |
| 192 } else if (ctype == CX_JSON_TOKEN_STRING) { |
193 } else if (ctype == CX_JSON_TOKEN_STRING) { |
| 193 // begin string |
194 // begin string |
| 194 ttype = CX_JSON_TOKEN_STRING; |
195 ttype = CX_JSON_TOKEN_STRING; |
| 195 token_start = i; |
196 token_start = i; |
| 235 } |
236 } |
| 236 } |
237 } |
| 237 |
238 |
| 238 if (ttype != CX_JSON_NO_TOKEN) { |
239 if (ttype != CX_JSON_NO_TOKEN) { |
| 239 // uncompleted token |
240 // uncompleted token |
| 240 size_t uncompeted_len = json->buffer.size - token_start; |
241 size_t uncompleted_len = json->buffer.size - token_start; |
| 241 if (json->uncompleted.tokentype == CX_JSON_NO_TOKEN) { |
242 if (json->uncompleted.tokentype == CX_JSON_NO_TOKEN) { |
| 242 // current token is uncompleted |
243 // current token is uncompleted |
| 243 // save current token content |
244 // save current token content |
| 244 CxJsonToken uncompleted = { |
245 CxJsonToken uncompleted = { |
| 245 ttype, true, |
246 ttype, true, |
| 246 cx_strdup(cx_strn(json->buffer.space + token_start, uncompeted_len)) |
247 cx_strdup(cx_strn(json->buffer.space + token_start, uncompleted_len)) |
| 247 }; |
248 }; |
| 248 if (uncompleted.content.ptr == NULL) { |
249 if (uncompleted.content.ptr == NULL) { |
| 249 return CX_JSON_BUFFER_ALLOC_FAILED; |
250 return CX_JSON_BUFFER_ALLOC_FAILED; |
| 250 } |
251 } |
| 251 json->uncompleted = uncompleted; |
252 json->uncompleted = uncompleted; |
| 252 } else { |
253 } else { |
| 253 // previously we also had an uncompleted token |
254 // previously we also had an uncompleted token |
| 254 // combine the uncompleted token with the current token |
255 // combine the uncompleted token with the current token |
| 255 assert(json->uncompleted.allocated); |
256 assert(json->uncompleted.allocated); |
| 256 cxmutstr str = cx_strcat_m(json->uncompleted.content, 1, |
257 cxmutstr str = cx_strcat_m(json->uncompleted.content, 1, |
| 257 cx_strn(json->buffer.space + token_start, uncompeted_len)); |
258 cx_strn(json->buffer.space + token_start, uncompleted_len)); |
| 258 if (str.ptr == NULL) { |
259 if (str.ptr == NULL) { |
| 259 return CX_JSON_BUFFER_ALLOC_FAILED; |
260 return CX_JSON_BUFFER_ALLOC_FAILED; |
| 260 } |
261 } |
| 261 json->uncompleted.content = str; |
262 json->uncompleted.content = str; |
| 262 } |
263 } |
| |
264 // advance the buffer position - we saved the stuff in the uncompleted token |
| |
265 json->buffer.pos += uncompleted_len; |
| 263 } |
266 } |
| 264 |
267 |
| 265 return CX_JSON_INCOMPLETE_DATA; |
268 return CX_JSON_INCOMPLETE_DATA; |
| 266 } |
269 } |
| 267 |
270 |
| 612 |
615 |
| 613 // parse data |
616 // parse data |
| 614 CxJsonStatus result; |
617 CxJsonStatus result; |
| 615 do { |
618 do { |
| 616 result = json_parse(json); |
619 result = json_parse(json); |
| |
620 cxBufferShiftLeft(&json->buffer, json->buffer.pos); |
| 617 if (result == CX_JSON_NO_ERROR && json->states_size == 1) { |
621 if (result == CX_JSON_NO_ERROR && json->states_size == 1) { |
| 618 // final state reached |
622 // final state reached |
| 619 assert(json->states[0] == JP_STATE_VALUE_END); |
623 assert(json->states[0] == JP_STATE_VALUE_END); |
| 620 assert(json->vbuf_size == 0); |
624 assert(json->vbuf_size == 0); |
| 621 |
625 |