もともと、本職はc++プログラムがほとんどなんで、いつも入出力のGUIに悩まされていました。それをCouchDBで楽したいというところで、色々調べていましたがだいたい目処がついてきたので、さてそれをc++プログラムでどうやってハンドリングしたらいいのか?というところまできました。
c++でJSONのパーサはいくつか見つかりましたが、picojsonがヘッダファイル一つというシンプルさでなかなか秀逸です。早速これを試してみました。
まず試験データとしてのJSONファイル(test3.json)です。
- {"message":"success",
- "number":[1, 2],
- "person":{"name":"hoge", "age":38},
- "follow":[
- {"name":"hoge", "age":38},
- {"name":"huga", "age":42}
- ],
- "returnCode":0}
わざと複雑な階層構造を持たせています。このファイル名を引数として動くサンプルが以下です。
- #include
#include
実行すると以下の様な出力をだしてきます。
- ---- dump input ----
- {"follow":[{"age":38,"name":"hoge"},{"age":42,"name":"huga"}],"message":"success","nu\
- mber":[1,2],"person":{"age":38,"name":"hoge"},"returnCode":0}
- ---- analyzing input ----
- input is an object
- follow [{"age":38,"name":"hoge"},{"age":42,"name":"huga"}]
- message "success"
- number [1,2]
- person {"age":38,"name":"hoge"}
- returnCode 0
- success
- follow [{"age":38,"name":"hoge"},{"age":42,"name":"huga"}]
- message "fail"
- number [1,2]
- person {"age":38,"name":"hoge"}
- piyopiyo 10
- returnCode 0
- hoge 38
- huga 42
- {"follow":[{"age":38,"name":"hoge"},{"age":42,"name":"huga"}],"message":"fail","numbe\
- r":[1,2],"person":{"age":42,"name":"huga"},"piyopiyo":10,"returnCode":0}
うまく動いていますね。階層構造の扱いも、値の変更も思い通りになります。
ちょっと面倒くさいのが、いちいちpicojson::value形式で読みこんだ後、データの操作のためにpicojson::object形式にしないといけないこと。JavaScriptでも同じような考え方でしたが何でですかね?picojsonの実装はヘッダファイル一つなので、少し読んでみると、picojson::valueではvector形式で読み込んでいるようですが、すぐにmap形式にしてしまいます。確かにこれならアクセスするのが簡単で、処理速度も早いんですがデータ項目の順番がkeyでソートされてしまい順番が変わってしまいます。JSONとしては問題ないんですが、デバッグ時に少し悩みそうです。
後、このサンプルではparse()関数を使っていますが、picojson::valueは、>>を使って直接読み込むことができます。わざわざサンプル用に、stringでファイルを読み込み、parse()関数を使うように変更しました。こっちの方がエラーの扱いがわかりやすいからなんですがね。
picojsonなかなかいいんですが、一つ難点を言えば、c++のtemplate機能を使い倒しているため、エラーが出てくると、わけのわからないエラーメッセージを出してくるのがつらいです。c++の機能なんで、しかたないんですが。
0 件のコメント:
コメントを投稿