aboutsummaryrefslogtreecommitdiffstats
path: root/src/json/load.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/json/load.c')
-rw-r--r--src/json/load.c58
1 files changed, 58 insertions, 0 deletions
diff --git a/src/json/load.c b/src/json/load.c
index 07d0b9f8b..0f0968e9e 100644
--- a/src/json/load.c
+++ b/src/json/load.c
@@ -856,3 +856,61 @@ json_load_file (const char *path, json_error_t * error)
fclose (fp);
return result;
}
+
+
+typedef struct evbuffer_data_s {
+ const char *data;
+ gsize len;
+ guint pos;
+} evbuffer_data_t;
+
+
+static int
+evbuffer_get (void *data)
+{
+ evbuffer_data_t *stream = (evbuffer_data_t *) data;
+
+ if (stream->pos >= stream->len) {
+ return EOF;
+ }
+
+ return *(stream->data + stream->pos++);
+}
+
+static int
+evbuffer_eof (void *data)
+{
+ evbuffer_data_t *stream = (evbuffer_data_t *) data;
+
+ return stream->pos >= stream->len;
+}
+
+json_t *
+json_load_evbuffer (struct evbuffer *evb, json_error_t *error)
+{
+ evbuffer_data_t stream_data;
+ lex_t lex;
+ json_t *result;
+
+ stream_data.data = EVBUFFER_DATA (evb);
+ stream_data.pos = 0;
+ stream_data.len = EVBUFFER_LENGTH (evb);
+
+ if (lex_init (&lex, evbuffer_get, evbuffer_eof, (void *)&stream_data))
+ return NULL;
+
+ result = parse_json (&lex, error);
+ if (!result)
+ goto out;
+
+ lex_scan (&lex, error);
+ if (lex.token != TOKEN_EOF) {
+ error_set (error, &lex, "end of file expected");
+ json_decref (result);
+ result = NULL;
+ }
+
+ out:
+ lex_close (&lex);
+ return result;
+}