aboutsummaryrefslogtreecommitdiff
path: root/src/load.c
diff options
context:
space:
mode:
authorRogerz Zhang <rogerz.zhang@gmail.com>2012-03-21 16:34:14 +0800
committerrogerz <rogerz.zhang@gmail.com>2012-03-22 14:52:57 +0800
commit040bd7b0fafaf7bf8660b77ea0392f49d0d649b6 (patch)
tree01a20c5f9f8b46555776a59df757ef6ffedbd2fb /src/load.c
parent952e1d4ba953241f0617d28c45f1765fa777dbb2 (diff)
downloadjansson-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.c55
1 files changed, 55 insertions, 0 deletions
diff --git a/src/load.c b/src/load.c
index 70a1ac2..32d7901 100644
--- a/src/load.c
+++ b/src/load.c
@@ -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;
+}