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 |