summaryrefslogtreecommitdiff
path: root/json_curl.c
blob: 1911b0fb42092bf53d7156e79e97f840e225d58e (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
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;
}