2021/03/03

Recent entries from same category

  1. RapidJSON や simdjson よりも速いC言語から使えるJSONライブラリ「yyjson」
  2. C++ で flask ライクなウェブサーバ「clask」書いた。
  3. C++ 用 SQLite3 ORM 「sqlite_orm」が便利。
  4. zsh で PATH に相対パスを含んだ場合にコマンドが補完できないのは意図的かどうか。
  5. mruby-tflite を Coral Edge TPU 対応した。

おなじみC/C++から使えるJSONライブラリを紹介するコーナー。まずは過去のまとめ。

これまで C++ から扱える JSON パーサを数多く紹介してきましたが、いずれもコメントを扱えるものはありませんでした。今回紹介する jsoncpp はコメントも扱えます。

GitHub - open-source-parsers/jsoncpp: A C++ library for interacting with JSON.

JsonCpp JSON is a lightweight data-interchange format. It can represent numbers, strings, ordered se...

https://github.com/open-source-parsers/jsoncpp

特徴は以下の通り。

  • コメントが扱える
  • Amalgamated code を生成できる
  • 古いコンパイラをサポートしている
  • Public Domain

触ってみた感じは json.hpp に近いです。

#include "json/json.h"
#include 

int
main(int argc, char* argv[]) {
  const std::string rawJson = R"(
  {
    "Age": 20,
    "Name": "mattn" // your name
  }
  )";
  Json::Value root;
  Json::CharReaderBuilder builder;
  builder["collectComments"] = true;
  JSONCPP_STRING errs;
  auto reader = builder.newCharReader();
  if (!reader->parse(rawJson.c_str(), rawJson.cend().base(), &root, &errs)) {
    std::cout << errs << std::endl;
    return EXIT_FAILURE;
  }
  std::cout << root["Age"].asInt64() << std::endl;
  std::cout << root["Name"].asString() << std::endl;
  std::cout << root["Name"].getComment(Json::CommentPlacement::commentAfterOnSameLine) << std::endl;
  return EXIT_SUCCESS;
}

collectComments を true にする事でパース時にコメントを収集してくれます。getComment に指定する commentBefore, commentAfterOnSameLine, commentAfter によりノードの前方、同一行または後方、後方、のいずれかのコメントを得られます。

jsoncpp にはこれだけでなく、とても便利な色々なオプションが用意されています。

collectComments: false or true

true でコメントを収集し、シリアライズ時にコメントを戻す

allowComments: false or true

コメントを許可

allowTrailingCommas: false or true

ケツカンマを許可

strictRoot: false or true

ルートノートに配列またはオブジェクトを必須とする

allowDroppedNullPlaceholders: false or true

"null" という文字列をシリアライズ時にドロップする。

allowNumericKeys: false or true

オブジェクトに数値のキーを許可

allowSingleQuotes: false or true

シングルクオートを許可

stackLimit: 数値

階層の限界を指定。オーバーすると例外が発生。

failIfExtra: false or true

余計な空白をエラーとして扱う。

rejectDupKeys: false or true

オブジェクトのキーに重複を許可。

allowSpecialFloats: false or true

NaN や inf の様な特殊な浮動小数点を許可。


これだけあれば多少ユルユル仕様な設定ファイル向けの JSON ファイルも読み込めると思います。

また jsoncpp は通常、ライブラリ形式(.a)が提供されますが、付属の amalgamate.py を使う事で、ヘッダファイル1つとソースファイル1つに纏められた形式にする事もできる為、以下の様に簡単にソースコードをビルドする事ができます。

$ ls -R
.:
json  jsoncpp.cpp  main.cpp

./json:
json.h  json-forwards.h

$ gcc -I. -o app main.cpp jsoncpp.cpp

jsoncpp は基本、パブリックドメインのライセンスで提供されています。しかし地域によってはパブリックドメインは実在しない扱いとなります。jsoncpp ではその様な地域の場合は MIT ライセンスのもと配布されるという事になっています。

ここまで融通の効く C++ 向け JSON パーサは僕が知る限り他には無いと思います。

Posted at by