pficommon v1.3.0 documentation

3.6.2. pfi::text::json

«  3.6.1. pfi::text::csv   ::   Contents

3.6.2. pfi::text::json

3.6.2.1. 概要

JSON(JavaScript Object Notation)を扱うためのライブラリである。 JSONのオブジェクトの操作、文字列への変換、パーザ、pretty printer、 C++ネイティブ型への相互自動変換などを備えている。

JSONの仕様はこちらを参照のこと。

http://www.ietf.org/rfc/rfc4627.txt

3.6.2.2. 使い方

3.6.2.2.1. jsonデータ型の操作

class json_object
class json_array
class json_integer
class json_float
class json_bool
class json_null

それぞれjsonのデータ型を表す (これらを直接扱うことはあまりない)。

class json_value [#j1c13c05]

上の型の基底クラス。

class json

jsonオブジェクトをハンドルするための型 (実際には、これはスマートポインタのような働きをする)。

json::json(json_value *)

ハンドルにオブジェクトをセットする。 セットしたポインタはjsonクラスが管理するようになるので、 外では使用したり、解放したりしてはいけない。

json::operator[](const string &name)

保持しているjson_objectのメンバを参照する。 保持しているものがjson_objectでなければ、bad_cast例外が投げられる。

json::operator[](size_t ix)

保持しているjson_arrayのメンバを参照する。 保持しているものがjson_arrayでなければ、bad_cast例外が投げられる。

json::add(const string &name, const json &js)

保持しているjson_objectに要素を追加する (例外は上と同様)。

json::add(const json &js)

保持しているjson_arrayに要素を追加する (例外は上と同様)。

json::size() const

保持しているjson_arrayのサイズを取得する (例外は上と同様)。

iterator json::begin()

保持しているjson_objectの要素の開始イテレータを取得する。 要素の型はpair<string, json>である (例外は同様)。

iterator json::end()

保持しているjson_objectの要素の終端イテレータを取得する (例外は同様)。

json_value *json::get() const

保持しているjson_valueのポインタを返す。

json::print(ostream &os) const

保持しているjson_valueをストリームに書き出す。 文字数が最小になるように書き出す。

json::pretty(ostream &os) const

保持しているjson_valueをストリームに書き出す。 読みやすい形で出力される。

3.6.2.2.2. 例

  • オブジェクトを組み立てる。
json js(new json_object());
js["abc"]=json(new json_integer(123));
js["bcd"]=json(new json_flaot(3.14));
js["cde"]=json(new json_string("appuppupuepue"));
js["def"]=json(new json_bool(true));
  • 配列を組み立てる。
json js(new json_array());
js.add(json(new json_string("hoge")));
js.add(json(new json_bool(false)));

3.6.2.2.3. 文字列との相互変換

operator<<およびoperator>>がオーバーライドされているので、 それで文字列への相互変換が行える。

json js(new json_array());
js.add(new json_integer(1)):
js.add(new json_integer(2)):
js.add(new json_integer(3)):

stringstream ss;
ss<<js; // [1,2,3]

json ks;
ss>>ks; // js==ks

読み込みに失敗するとpfi::lang::parse_errorが投げられる。 istreamは読まれた分だけ消費されるので注意すること。

pretty printもできる。

json js(new json_array());
js.add(new json_integer(1)):
js.add(new json_integer(2)):
js.add(new json_integer(3)):

cout<<pretty(js);

次のように表示される。

[
  1,
  2,
  3
]

3.6.2.2.4. C++型との相互変換

jsonオブジェクトとC++の型との間で自動的に相互変換ができる。

  • json_integer <=> int
  • json_float <=> double
  • json_string <=> string
  • json_bool <=> bool
  • json_object <=> map<string, T>
  • json_array <=> vector<T>

ユーザ定義型との相互変換もできる(後述)。

3.6.2.2.5. template <class T> json to_json(const T &v)

jsonへ変換可能な型をjsonに変換する。

vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);

json js=to_json(v);
cout<<js; // [1,2,3]

3.6.2.2.6. template <class T> void from_json(const json &js, T &v)

jsonからjsonに変換可能な型に変換する。 jsが型Tに合わないオブジェクトを含む場合、bad_cast例外が投げられる。

json js(new json_array());
js.add(new json_integer(1)):
js.add(new json_integer(2)):
js.add(new json_integer(3)):

vector<int> v;
from_json(js, v); // {1, 2, 3}

3.6.2.2.7. ユーザ定義型との相互変換

ユーザ定義型とjson_objectとを相互変換させることができる。 相互変換できるようにするには、そのクラスをserializableにする必要がある。 ただし、メンバのシリアライズに必ずMEMBERマクロを用いて、 シリアライザにメンバの名前を教えてやる必要がある。

struct foo{
  int a;
  string b;
  struct bar{
    vector<double> x;

    template <class Archive>
    void serialize(Archive &ar){
      ar & MEMBER(x);
    }
  } c;

  template <class Archive>
  void serialize(Archive &ar){
    ar & MEMBER(a) & MEMBER(b) & MEMBER(c);
  }
};

int main(){
  foo f;
  f.a=123;
  f.b="hoge";
  f.c.x.push_back(1.4142):
  f.c.x.push_back(3.1415);

  cout<<to_json(f)<<endl; // {"a":123,"b":"hoge","c":{"x":[1.4142,3.1415]}}
}

3.6.2.2.8. template <class T> T json_cast<T>(const json &js)

jsをそれと変換可能な型Tに変換する。 jsが型に合わない場合はbad_cast例外が投げられる。

json js(new json_integer(123));
cout<<json_cast<int>(js)<<endl; // 123

3.6.2.2.9. via_json

streamからjsonで記述された型Tのオブジェクトをダイレクトに取り出す。

foo f;
cin>>via_json(f);

«  3.6.1. pfi::text::csv   ::   Contents