MessagePack の扱えるプリミティブ型まとめ

参考

MessagePack の C/C++ バインディング上で扱うことの出来るデータ構造を調べてみた。エントリが長くなるのも何なので、プリミティブ型とコンテナ型の二種類に分けてエントリにしてある。ここで、コンテナ型は他の型の値を内包することが出来る型、プリミティブ型は他の値を内包できない型という意味合いである。

なお、ここに書いてある内容は MessagePack の現存する実装などから推測したものに過ぎないので、注意が必要である*1

MessagePack の扱えるプリミティブ型たち

cpp/object.hpp の

namespace type {
	static const unsigned char NIL					= 0x01;
	static const unsigned char BOOLEAN				= 0x02;
	static const unsigned char POSITIVE_INTEGER		= 0x03;
	static const unsigned char NEGATIVE_INTEGER		= 0x04;
	static const unsigned char DOUBLE				= 0x05;
	static const unsigned char RAW					= 0x06;
	static const unsigned char ARRAY				= 0x07;
	static const unsigned char MAP					= 0x08;
}

から(ほぼ)読み取れるように、プリミティブ型としては

  • ブール型
    • true か false
  • 整数型
    • 正の整数型
    • 負の整数型
  • 浮動小数
  • 生のバイト列 (raw)型
  • null 値

を扱えるようである。

MessagePack の ブール型

MessagePack では、true, false のどちらかの値(ブール型)を、整数型の値とは区別して扱うことが出来る。

MessagePack の 整数型

MessagePack では、正の整数型と負の整数型を区別して扱っているようだ。
cpp/object.hpp を見ると、上記の POSIIVE/NEGATIVE_INTEGER を区別した上で、値を保持する際にも

struct object {
	union union_type {
		uint64_t u64;
		int64_t  i64;
		// (中略)
	};
	// (中略)
}

のように、正の整数と負の整数の場合とで別々の値の保持方法を取っているようだ。

また、後のエントリで述べる MessagePack のエンコードフォーマットを見ると分かるが、現状では [-264, 264>) の範囲の整数に対応していて、それ以上の大きさの整数やマルチバイト整数の類は対応していないようだ。

MessagePack の 浮動小数

MessagePack では、32bit、64bit の浮動小数値も格納できるようだ。
ただし、これは後の MessagePack のシリアライズフォーマットについてのエントリで述べてある通り、現在の MessagepPack ではポータビリティのなさそうな実装になっているので、利用には注意が必要であろう。

MessagePack の raw 型

MessagePack では、任意長のバイト列を raw 型として扱える。
MessagePack では文字列も raw 扱いである。よって、文字列のエンコーディングや、文字列と文字列以外のバイナリの区別などは MessagePack を使う側でやる必要がある。

実際 cpp/object.hpp では

struct object {
	union union_type {
		// (中略)
		struct {
			const char* ptr;
			uint32_t size;
		} ref;
	};
	// (中略)
}

のように、長さ*2と char* として保持しているようだ。

MessagePack の null(nil) 値

MessagePack では、null(nil) 値を扱うことが出来る。null 型は値が一種類(null)しかないので、特筆することはなさそうだ。

*1:id:viver によると、今のところ正式な仕様のドキュメントといったものはないそうだ。

*2:長さを別に持っている故に、もちろん \0 を含むバイナリも安心して扱えるように意図してあるようだ