diff options
| author | Timothy J. Wood <tjw@omnigroup.com> | 2009-02-26 13:41:46 -0800 |
|---|---|---|
| committer | Timothy J. Wood <tjw@omnigroup.com> | 2009-02-26 13:41:46 -0800 |
| commit | 1a7a73039abf621af36f73adf4a4ca77c2c94bd9 (patch) | |
| tree | e7ea2f80377f3dcb2c80bfc2a9b53c5332ec29b6 | |
| parent | d4d5f5af2cc52d7b8c92fc2a57f18e38d1f6f5d2 (diff) | |
| download | yajl-1a7a73039abf621af36f73adf4a4ca77c2c94bd9.tar.gz | |
A simple fix for lonely_number.json
- Add new parser function, yajl_parse_complete(). This is defined
to parse any buffered data assuming that there is no more input
forthcoming and may issue callbacks based on that parse.
- Implement this as parsing a single space character. This is
sufficient to handle the problem case, a number at the end
of the stream.
- Updated yagl_test.c to call this when the stream ends.
| -rw-r--r-- | src/api/yajl_parse.h | 11 | ||||
| -rw-r--r-- | src/yajl.c | 12 | ||||
| -rw-r--r-- | test/yajl_test.c | 31 |
3 files changed, 42 insertions, 12 deletions
diff --git a/src/api/yajl_parse.h b/src/api/yajl_parse.h index a6d5b1a..6f6dba3 100644 --- a/src/api/yajl_parse.h +++ b/src/api/yajl_parse.h @@ -143,6 +143,17 @@ extern "C" { const unsigned char * jsonText, unsigned int jsonTextLength); + /** Parse any remaining buffered json. + * Since yajl is a stream-based parser, without an explicit end of + * input, yajl sometimes can't decide if content at the end of the + * stream is valid or not. For example, if "1" has been fed in, + * yajl can't know whether another digit is next or some character + * that would terminate the integer token. + * + * \param hand - a handle to the json parser allocated with yajl_alloc + */ + yajl_status yajl_parse_complete(yajl_handle hand); + /** get an error string describing the state of the * parse. * @@ -104,6 +104,18 @@ yajl_parse(yajl_handle hand, const unsigned char * jsonText, return status; } +yajl_status +yajl_parse_complete(yajl_handle hand) +{ + /* The particular case we want to handle is a trailing number. + * Further input consisting of digits could cause our interpretation + * of the number to change (buffered "1" but "2" comes in). + * A very simple approach to this is to inject whitespace to terminate + * any number in the lex buffer. + */ + return yajl_parse(hand, (const unsigned char *)" ", 1); +} + unsigned char * yajl_get_error(yajl_handle hand, int verbose, const unsigned char * jsonText, unsigned int jsonTextLen) diff --git a/test/yajl_test.c b/test/yajl_test.c index 35bcc9d..5f1dd31 100644 --- a/test/yajl_test.c +++ b/test/yajl_test.c @@ -185,26 +185,33 @@ main(int argc, char ** argv) /* ok. open file. let's read and parse */ hand = yajl_alloc(&callbacks, &cfg, NULL); - for(;;) { + int done = 0; + while (!done) { rd = fread((void *) fileData, 1, bufSize, stdin); if (rd == 0) { if (!feof(stdin)) { fprintf(stderr, "error reading from '%s'\n", fileName); + break; } - break; - } else { + done = 1; + } + + if (done) + /* parse any remaining buffered data */ + stat = yajl_parse_complete(hand); + else /* read file data, pass to parser */ stat = yajl_parse(hand, fileData, rd); - if (stat != yajl_status_insufficient_data && - stat != yajl_status_ok) - { - unsigned char * str = yajl_get_error(hand, 0, fileData, rd); - fflush(stdout); - fprintf(stderr, (char *) str); - yajl_free_error(str); - break; - } + + if (stat != yajl_status_insufficient_data && + stat != yajl_status_ok) + { + unsigned char * str = yajl_get_error(hand, 0, fileData, rd); + fflush(stdout); + fprintf(stderr, (char *) str); + yajl_free_error(str); + break; } } |
