JavaScript で MessagePack を実装してみた

140文字を超えちゃうので、こちらで。

id:viver さんの MessagePackJavaScript で実装してみました。

HOT TO USE

<script src="misc/msgpack.js"></script>
<script src="misc/utf8.js"></script>
<script>
var pack = msgpack.pack("こんにちはこんにちは");

alert(msgpack.unpack(pack)); // こんにちはこんにちは
</script>

現時点の仕様 / 制限事項

仕様
  • msgpack.pack(data:Mix):ByteArray で、data に指定されたオブジェクトをエンコードし、ByteArray( [数値, ...] ) を返します。
    • 文字列は UTF8 な raw data として数値化します。
    • エンコードに失敗すると、throw Error("OVERFLOW") な例外が発生します。
  • msgpack.unpack(data:String/ByteArray):Mix で、data に指定された文字列またはByteArray から、元のデータを復元します。
    • raw data は UTF8 でエンコードされている文字列としてデコードします。
  • undefined は nilエンコードします。
  • msgpack.pack に String, Number, Array, Boolean, null, undefined 以外のオブジェクトを渡すと、map にエンコードします。
制限事項
  • JavaScriptのNumber型の内部表現が IEEE754-1985 なため、0x20000000000000 を超える値(int64, uint64 の上位14bitを利用している値)は、たとえ整数であっても正しく表現できません。これは JavaScript の制限です。
  • 私が作成したテストケースの28, 30, 52番が失敗します(52番は未解決です)。
  • IEEE754 の変換処理が坊主の手習い状態です。浮動小数点数の丸めも実装していないため、計算誤差が発生するケースがあると思います。
  • 現状では NaN や Infinity をサポートしていません。サポートしました。

反省会

  • JavaScript の ビット演算子が 31bit以上の数値に適用できないため、IEEE754 を数値として処理せず文字列として処理してる
  • まだ最適化を行っていませんが、興味がある方はベンチマークを試してみてください。
  • 間違っている箇所や、問題があれば教えてください。

つかれた。ぱたり。

ソースコードは単体でも使えます

msgpack.js や utf8.js などは、uupaa.js の一部ですが、単体でも利用可能です。

<script src="http://uupaa-js.googlecode.com/svn/trunk/0.8/src/misc/msgpack.js"></script>
<script src="http://uupaa-js.googlecode.com/svn/trunk/0.8/src/misc/utf8.js"></script>