Node.jsベースであればJavascriptでバイナリplistをパースする処理を書けるということがわかったというのがこちら↓
でも本当にやりたかったのはブラウザでipaファイルを指定して展開し、中にあるInfo.plistを解析するというものでした。上の記事で紹介しているnode-bplist-parser
のコードはそのままではブラウザで動きませんでした。
bplist-parserを流用する
browserifyする
Node.jsではCommonJS的にモジュールを書けるようになっていますが、ブラウザのJavascriptでは通常はそのようなことはできません。それを実現するためにbrowserify
というnpmモジュールがあります。
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
です。
こちらも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)