Skip to content

Instantly share code, notes, and snippets.

@frsyuki
Last active December 16, 2015 13:18
Show Gist options
  • Save frsyuki/5440323 to your computer and use it in GitHub Desktop.
Save frsyuki/5440323 to your computer and use it in GitHub Desktop.

他言語版の実装に見られる傾向

pack_template.h や unpack_template.h を使わない

これらのヘッダは、各言語版が同じgitリポジトリを共有していた時代に実装を簡略化する意図で提供されていたが、現在ではリポジトリが分離されたため、あまり共有する意味がない。 Python版やRuby版では既に使っておらず、逆に使わないことで実装を簡略化&最適化している。

Buffer API の提供

Ruby版やJava版では、Unpacker, Packer クラスに加えて Buffer クラスを抽象化レイヤーとして持っている。 Bufferは、末尾へのデータの追記と、先頭からのデータの読み出しの2つをサポートする可変長のバイト列。

(バッファへのシリアライズでは無く)IOストリームへのシリアライズは、Packer ではなく Buffer がサポートする。つまりBufferは、ある程度データが溜まったら、Bufferのコンストラクタに渡されたIOストリームにデータを書き出す。デシリアライズも同様に、データが無ければコンストラクタに渡されたIOストリームからデータを読み出す。

Ruby版実装のドキュメント:http://ruby.msgpack.org/MessagePack/Buffer.html

Value API

C++版やJava版では、MessagePack の型システムを実装したクラスを提供している。C++版が一番最初に msgpack::object クラスとして実装した。Java版の実装(interface Value)は、hashCode や equals、 toString などの便利なメソッドが実装されていて、頻繁に使われている(※特にValue#toStringがJSONを返すのが大変便利)。

具体的には、静的型付け言語の内部で動的型付けオブジェクトを扱えるようになる利点がある。デシリアライズされたオブジェクトを必ずしも静的な型に当てはめずに、「型不明」な状態のまま変数に入れて持ち運んだりできる。

Java版実装のドキュメント:http://msgpack.org/javadoc/current/org/msgpack/type/Value.html

C++実装では、残念ながらメモリの管理方法が怪しいために正しく使いこなすのが難しい実装なっていて、使っている人はほとんどいない気がする。

objectをラップする型変換用Unpacker

"型変換テンプレート" は、C++で最初に実装され、Java版、C#版、Go版などにも広く移植されている。C++版の型変換テンプレートの宣言は、

// object.hpp
template <typename Stream, typename T>
inline packer<Stream>& operator<< (packer<Stream>& o, const T& v)

template <typename T>
inline T& operator>> (object o, T& v)

となっており、シリアライズ時には msgpack::packer が渡されるが、デシリアライズ時には msgpack::unpacker ではなく msgpack::object が渡される。このため、シリアライズ時にはオブジェクトTを直接シリアライズできる一方で、デシリアライズ時には一度 msgpack::object (Value APIで提供されるクラス)を作る必要がある。

Java版ではこのオーバーヘッドが無視できないほど大きかったので、Unpacker が渡されるようになっている。一度 msgpack::object (に相当するorg.msgpack.type.Valueクラス)を作ってから型変換テンプレートを適用したい場合は、そのオブジェクトをラップする特殊なUnpackerを使う。

Java版 class Converter implements Unpacker のドキュメント:http://msgpack.org/javadoc/current/org/msgpack/unpacker/Converter.html

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment