summaryrefslogtreecommitdiff
path: root/json_curl.c
diff options
context:
space:
mode:
Diffstat (limited to 'json_curl.c')
-rw-r--r--json_curl.c42
1 files changed, 42 insertions, 0 deletions
diff --git a/json_curl.c b/json_curl.c
new file mode 100644
index 0000000..1911b0f
--- /dev/null
+++ b/json_curl.c
@@ -0,0 +1,42 @@
+#include "json_curl.h"
+
+#include <stdlib.h>
+#include <curl/curl.h>
+#include <json-c/json.h>
+
+struct json_builder {
+ json_object *obj;
+ json_tokener *tok;
+};
+
+static size_t parse_cb(char *data, size_t size, size_t nmemb, void *userdata)
+{
+ size_t rsize = size * nmemb;
+ struct json_builder *jb = userdata;
+
+ // extra data after the first valid object is ignored.
+ if (!jb->obj) {
+ json_object *tmp = json_tokener_parse_ex(jb->tok, data, rsize);
+ if (tmp)
+ jb->obj = tmp;
+ else if (json_tokener_get_error(jb->tok) != json_tokener_continue)
+ return 0;
+ }
+
+ return rsize;
+}
+
+json_object *json_curl_perform(CURL *curl, const char *uri)
+{
+ struct json_builder jb = { NULL, json_tokener_new() };
+
+ if (uri) curl_easy_setopt(curl, CURLOPT_URL, uri);
+ curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, parse_cb);
+ curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&jb);
+
+ CURLcode res = curl_easy_perform(curl);
+ json_tokener_free(jb.tok);
+ if (res != CURLE_OK) return NULL;
+
+ return jb.obj;
+}