PIYO - Tech & Life -

binary plist parser for Javascript (non-Node)

Node.jsベースであればJavascriptでバイナリplistをパースする処理を書けるということがわかったというのがこちら↓

バイナリ形式のplistファイル - ぴよログ

でも本当にやりたかったのはブラウザでipaファイルを指定して展開し、中にあるInfo.plistを解析するというものでした。上の記事で紹介しているnode-bplist-parserのコードはそのままではブラウザで動きませんでした。

bplist-parserを流用する

browserifyする

Node.jsではCommonJS的にモジュールを書けるようになっていますが、ブラウザのJavascriptでは通常はそのようなことはできません。それを実現するためにbrowserifyというnpmモジュールがあります。

BrowserifyBrowserifyはてなブックマーク - Browserify

browserifyを使って吐き出したjsファイルをHTMLファイル中のscriptタグで指定しておくと、require(“”)でロードできるようになるということでした。実装はよくわからんけど、とりあえず使ってみました。

% browserify -r ./bplistParser.js -o xoyip-bplist-parser.js

このようにコマンドラインでファイルを変換できます。変換後のファイルを使います。

<script type="text/javascript" src="./xoyip-bplist-parser.js"></script>
var bplist = require("bplistParser.js");
bplist.parseFile( ... );

Bufferもbrowserifyする

上のサンプルコードにも書いたparseFileが今回使いたい関数です。Node.js版で想定されているこの関数の本来の引数はファイルパスかBufferオブジェクトというもので、パース部分ではBufferオブジェクトから少しずつ読み出しを行っています。このBufferもブラウザには存在しないため同じくbrowserifyしたものをrequireして使いました。

% npm install buffer
% browserify -r path/to/buffer.js -o buffer.js

そして、解析したい内容をBufferオブジェクトにしてparseFileに渡せば…

できませんでした

Node.jsで動かしたときは正常にパースできていたので、デバッグしながらブラウザ版と比較して動かしてみたとことろ、Bufferオブジェクトのサイズが全然違う!ということがわかりました。

bplist-parserをそのまま流用するのは諦めました。

パース部分を書き換える

bplist-parser内部ではBufferが来ることを想定していますが、Bufferを渡しても動かないというのがここまででわかったことです。

仕方がないので、基本ロジックはそのままに別のバイナリデータライブラリを導入し、Bufferと置き換えることにしました。そのときに用いたのがjDataView.jsです。

jDataView/jDataView

こちらもNode.jsのモジュールなのでbrowserifyをかけて使っています。

bplist-parserを書き換える

parseFileにBufferのオブジェクトを渡すのではなく、jDataViewのオブジェクトを渡せばいい、という風に変更します。

bplist-parserの内部ではBufferオブジェクトのbufferに対して色々なアクセスをします。

// 元のbplist-parser
// bufferはBufferのオブジェクト
buffer.length
buffer.readUInt(6)
buffer[i]

↑を↓のように書き換えました。幸いというか、目的が同じなので当たり前かもしれませんが、似たようなメソッドが提供されているので整合性がとれるように置き換えれば問題ありませんでした。

// 書き換え後のbplist-parser
// bufferはjDataViewのオブジェクト
buffer.byteLength
buffer.getUint8(6)
buffer.getUint8(i)

完成したものがこちら

pi-chan/bplist-parser