parson特徴は
Lightweight json parser and reader written in C.
http://kgabis.github.com/parson/
- 軽い (2ファイルだけ)
- 単純なAPI
- ドット記法による json 値のアドレッシング (C言語の構造体やOO言語のオブジェクトに似た感じ。例:
"objectA.objectB.value"
) - C89 コンパティブル
- テストスーツ
今回もtwitterのタイムラインをパースしよう。
#include <assert.h>
#include <string.h>
#include <memory.h>
#include <curl/curl.h>
#include "parson.h"
typedef struct {
char* data; // response data from server
size_t size; // response size of data
} MEMFILE;
MEMFILE*
memfopen() {
MEMFILE* mf = (MEMFILE*) malloc(sizeof(MEMFILE));
if (mf) {
mf->data = NULL;
mf->size = 0;
}
return mf;
}
void
memfclose(MEMFILE* mf) {
if (mf->data) free(mf->data);
free(mf);
}
size_t
memfwrite(char* ptr, size_t size, size_t nmemb, void* stream) {
MEMFILE* mf = (MEMFILE*) stream;
int block = size * nmemb;
if (!mf) return block; // through
if (!mf->data)
mf->data = (char*) malloc(block);
else
mf->data = (char*) realloc(mf->data, mf->size + block);
if (mf->data) {
memcpy(mf->data + mf->size, ptr, block);
mf->size += block;
}
return block;
}
char*
memfstrdup(MEMFILE* mf) {
char* buf;
if (mf->size == 0) return NULL;
buf = (char*) malloc(mf->size + 1);
memcpy(buf, mf->data, mf->size);
buf[mf->size] = 0;
return buf;
}
int
main() {
CURL* curl;
MEMFILE* mf = NULL;
char* js = NULL;
int i;
mf = memfopen();
curl = curl_easy_init();
curl_easy_setopt(curl, CURLOPT_URL, "http://api.twitter.com/1/statuses/user_timeline.json?screen_name=otsune");
curl_easy_setopt(curl, CURLOPT_WRITEDATA, mf);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, memfwrite);
curl_easy_perform(curl);
curl_easy_cleanup(curl);
js = memfstrdup(mf);
memfclose(mf);
JSON_Value *root_value = json_parse_string(js);
JSON_Array *tweets = json_value_get_array(root_value);
for (i = 0; i < json_array_get_count(tweets); i++) {
JSON_Object *tweet = json_array_get_object(tweets, i);
printf("%s: %s\n",
json_object_dotget_string(tweet, "user.screen_name"),
json_object_dotget_string(tweet, "text"));
}
json_value_free(root_value);
free(js);
}
なにこれ!めちゃ簡単。しかもソースを見たところユニコードに対応してる。そしてドット演算子、良いすね。JSON XPath の様ですね。ただ残念ながら JSON XPath の様に ..
でスキップする機能は無かったですが。しかしながらこれC言語の JSON パーサの中では、私が知る限り一番扱いやすいと思いますね。(C++は別です)
MIT ライセンスなのでプロジェクトでも使って行きたいと思います。