diff options
author | Rogerz Zhang <rogerz.zhang@gmail.com> | 2012-03-21 16:34:14 +0800 |
---|---|---|
committer | rogerz <rogerz.zhang@gmail.com> | 2012-03-22 14:52:57 +0800 |
commit | 040bd7b0fafaf7bf8660b77ea0392f49d0d649b6 (patch) | |
tree | 01a20c5f9f8b46555776a59df757ef6ffedbd2fb /src/load.c | |
parent | 952e1d4ba953241f0617d28c45f1765fa777dbb2 (diff) | |
download | jansson-040bd7b0fafaf7bf8660b77ea0392f49d0d649b6.zip jansson-040bd7b0fafaf7bf8660b77ea0392f49d0d649b6.tar.gz jansson-040bd7b0fafaf7bf8660b77ea0392f49d0d649b6.tar.bz2 |
Add json_load_callback()
Diffstat (limited to 'src/load.c')
-rw-r--r-- | src/load.c | 55 |
1 files changed, 55 insertions, 0 deletions
@@ -990,3 +990,58 @@ json_t *json_load_file(const char *path, size_t flags, json_error_t *error) fclose(fp); return result; } + +#define MAX_BUF_LEN 1024 + +typedef struct +{ + char data[MAX_BUF_LEN]; + size_t len; + size_t pos; + json_load_callback_t callback; + void *arg; +} callback_data_t; + +static int callback_get(void *data) +{ + char c; + callback_data_t *stream = data; + + if(stream->pos >= stream->len) { + stream->pos = 0; + stream->len = stream->callback(stream->data, MAX_BUF_LEN, stream->arg); + if (stream->len <=0) + return EOF; + } + + c = stream->data[stream->pos]; + stream->pos++; + return (unsigned char)c; +} + +json_t *json_load_callback(json_load_callback_t callback, void *arg, size_t flags, json_error_t *error) +{ + lex_t lex; + json_t *result; + + callback_data_t stream_data; + + memset(&stream_data, 0, sizeof(stream_data)); + stream_data.callback = callback; + stream_data.arg = arg; + + jsonp_error_init(error, "<callback>"); + + if (callback == NULL) { + error_set(error, NULL, "wrong arguments"); + return NULL; + } + + if(lex_init(&lex, (get_func)callback_get, &stream_data)) + return NULL; + + result = parse_json(&lex, flags, error); + + lex_close(&lex); + return result; +} |