概要:
- 現行のRaw型をString型として読み替える。
- Binary型を新設する。
- 明らかなバイナリはデフォルトでBinary型(新設型)で保存
- Binary: バイト列
- 「明らかにバイト列である」と言うヒントが付いたStringである
- String: UTF-8でエンコードされた文字列、もしくはバイト列
- 明らかにバイト列であると区別できる場合、それはString型で保存されるべきではない(SHOULD NOT)
- それ以外、すなわちバイト列と文字列の区別が曖昧な場合も、すべてString型で保存する
Stringがバイナリデータを含むかもしれない(UTF-8として不正なバイト列を含み得る)とした理由は、区別が曖昧な環境において、すべてのバイト列(もしくはすべての文字列)にマーカーを付ける作業が非現実的であるから、という根拠に基づく。
ただし、Stringを受け取ったときに、UTF-8としてinvalidなバイトシーケンスを含むデータだった場合に、これを弾く実装を行っても良い(MAY)。この実装はオプションとして提供され、UTF-8としてinvalidなバイトシーケンスを含むString型オブジェクトを取り出せるようにする手段も提供することが強く推奨される(SHOULD)。
0xa0-0xbf FixString (0bytes - 31bytes String type) // changed
0xd5 binary 8 (0bytes - 255bytes Raw type) // new
0xd6 binary 16 (256bytes - 65535bytes Raw type) // new
0xd7 binary 32 (65536bytes - 4294967295bytes Raw type) // new
0xd8 reserved
0xd9 string 8 (32bytes - 255bytes String type) // new
0xda string 16 (256bytes - 65535bytes String type) // changed from raw 16
0xdb string 32 (65536bytes - 4294967295bytes String type) // changed from raw 32
- シリアライザ:
- 基本的に、文字列に見える物はすべてString型として保存する。invalidなエンコーディングが入っても良い
- UTF-8のvalidationは行わない
- 明示的に「これはバイト列だ」とヒントが付けられたオブジェクトを受け取った場合、それはBinary型として保存する(SHOULD)
- デシリアライザ:
- すべて文字列型やバイト列を格納する型にデコードする
- String型でvalidationは行わない(SHOULD NOT)。invalidなバイトシーケンスを含むStringを受け取っても、そのまま格納する
- String型でvalidationを行うオプションを実装をしてもよい(MAY)
- Binary型を受け取った場合、何らかのフラグが立ったオブジェクトを返すのは良いアイディアだが、そうでなくても良いし、提供方法はオプションでも良い(MAY)
- この挙動は、MessagePackを入力として、MessagePackを出力するような、中間処理を行うツールで、出力先でも型情報を維持しなければならないケースで必要になる
- この機能が必要なケースは稀である
- 実装の方法は、binary_as_classオプションがonであったら、Binary型を受け取った場合に、バイト列をフィールドとして所有するMessagePackBinaryクラスのインスタンスを返す方法ある。
-
シリアライザ:
- all_stringオプションがoff(デフォルト=off)
- バイト列はBinary型として保存する
- 文字列はString型として保存する
- all_stringオプションがon
- バイト列も文字列もRaw型として保存する
- all_stringオプションがoff(デフォルト=off)
-
デシリアライザ:
- all_rawオプションがon(デフォルト値、多言語間の互換性を高めるためにONであることが推奨される)
- String型もBinary型もバイナリデータとして復元する
- String型を受け取った場合、何かフラグが立ったバイト列型を返すのは良いアイディアだが、そうでなくても良い(MAY)
- all_rawオプションがoff
- Binary型を受け取ったら、バイト列を返す
- String型を受け取ったら、文字列を返す
- String型は、デシリアライズを行う段階で文字列のvalidationをしなくてもよい。してもよい。(←ここどうする?)
- all_rawオプションの存在意義:
- String型にUTF-8としてinvalidなバイトシーケンスが含まれていた場合に、アプリケーションがそれらをハンドリングできるようにする機能を提供するべきである(SHOULD)
- all_rawオプションがon(デフォルト値、多言語間の互換性を高めるためにONであることが推奨される)
- マイナーバージョンアップで、新設される型をバイト列として返す実装をリリースする
- メジャーバージョンアップで、明らかなバイト列を新設Binary型でシリアライズする実装をリリースする(ソース互換性が失われることを明示)
区別が曖昧な言語において、String型でvalidationするオプションを実装するのは、マイナーバージョンでも良い。いずれにしても、デフォルトではvalidationしないことが推奨される(SHOULD NOT)
区別が厳格な環境において、メジャーバージョンアップでバイト列を新設Raw型でシリアライズする実装を行ったとき、all_stringオプションを同時に提供するべき。
"区別が曖昧な環境" とは、文字列とバイト列を区別する型がそもそも無いか(PHP, C++, Erlang)、文字列を表すためにフラグ等の付加情報が使われるが、文字列なのに付加情報が付与されていないケースが一般的に存在する言語か(Perl, Ruby)、文字列をバイト列を格納クラスで扱うことが一般的に行われているか(?)、いずれかに該当する言語で書かれたプログラムを指す。
「用語」で触れられている言語の種類を増やしたい。コメント求む。
この変更後のMessagePackの呼び方。
- 案1:現行の仕様をMessagePack 0.9 と呼び、新しい仕様を MessagePack 1.0 と呼ぶ
- 案2:現行の仕様をMessagePack 1.0 と呼び、新しい仕様を MessagePack 1.1 と呼ぶ
twitter でも返信しましたが、ここに書いた方が共有しやすいのでこちらにも(msgpack-cli、つまり C#、VB あたりの場合):