latest log

酩酊状態で書いたエンジニアポエムです。酩酊状態で読んでください。

new msgpack.js with ArrayBuffer

リクエストを頂いたので、 ArrayBuffer を使った msgpack.js を書きました。

とりあえずコードを書いた段階で、識者の意見を取り入れて I/F の改善や、妥当性のチェックとテストケースの作成、ベンチマークなどはこれからの作業になります。

https://gist.github.com/4106426

MobileSafari と Android 4.0 での DataView のサポート具合が良くわからなかったので、ArrayBuffer + Uint8Array だけで実装しています。

// encode
a = msgpack.pack({ a: [1,2,3, { b: 4, c: "hoge" }, "abc"] });
      // -> [129, 161, 97, 149, 1, 2, 3, 130, 161,
      //       98, 4, 161, 99, 164, 104, 111, 103, 101, 163, 97, 98, 99]

// decode
msgpack.unpack(a); // -> { a: [1,2,3, { b: 4, c: "hoge" }, "abc"] }


今時の XHR Lv2 で ArrayBuffer を送受信するには、以下のようにすると良いらしいですよ。

function getArrayBuffer(url, callback) {
    var xhr = new XMLHttpRequest();

    xhr.open("GET", url);
    xhr.responseType = "arraybuffer";

    xhr.onreadystatechange = function () {
        if (xhr.readyState === 4) {

            var view = new Uint8Array(xhr.response);
            var rv = [];

            Array.prototype.push.apply(rv, view); // 一度 Array に変換する場合はこうします
            callback(rv);
        }
    };
    xhr.send();
}

function postArrayBuffer(url, arrayBuffer) {
    var xhr = new XMLHttpRequest();
    xhr.open("POST", url, true);

    var view = new Uint8Array(arrayBuffer);

    xhr.send(view.buffer);
}

参考リンク:


今回書いたコードには、解決すべき2つの問題があります。

  • https://github.com/uupaa/msgpack.js に上がっている現行コードとは I/F の互換性がありません。
  • TypedArray をサポートしていない、古いブラウザ(IE8, IE9, Android 2.3 など)で動作しません。

これらの問題については別途検討します。