Vim でバイナリデータを扱う

Vim Advent Calendar 2013 の 128 日目の記事です。
Vim でバイナリデータを扱う方法についてのまとめです。

基礎知識

Vim script で扱える文字列は、C 言語の文字列と同じです。すなわち、'\0' 文字終端のバイト列です。これはつまり、NUL 文字が扱えないことを意味します。文字列でバイナリデータを扱おうとすると、ここでつまづきます。

文字列の配列

NUL 文字が扱えないなら、それを区切りとする文字列の配列で扱えばいいじゃない、ってことで、文字列の配列です。
Vim 本体組み込みの readfile() と writefile() 関数では、これに少し手を加えて、改行文字区切りで配列にして、各文字列内の NUL 文字を改行文字にする形式が使われています。ちょっとややこしいですが、普段文字列は改行区切りで扱うことの方が多いので、こちらの方が都合が良いです。また、最近だと、system({expr} [, {input}]) の {input} にこの形式が使えたり、systemlist() と言う、この形式で結果を返す関数が追加されたりしました。

数値の配列

バイナリってのはつまり数値の列なので、そのまんま、0〜255 の値で構成された配列で表現する方法です。Vim のリストはリンクリストなのでメモリは食いますが、直感的でわかりやすいです。

文字列

任意の方法でバイナリを文字列に符号化してしまう方法です。16進数の羅列、urlencode、base64…もはやバイナリなのかわかりませんが、保持する手段としてはアリです。

番外: 各種言語インターフェース

Vim には RubyPython などの言語インターフェースがあるので、その中でデータを保持する方法です。もはや Vim ではないので、バイナリデータだろうがなんだろうがなんでもござれです。Vim 側で表示する時に、表示に都合のよい形式にしてしまえば良いです。vinarise はこの形式です。

まとめ

方法は色々ありますが、重要なのはバイナリデータを扱って何がしたいか、です。それによってどの方法を取るべきかが変わってきます。消費メモリが重要なら、文字列の配列でしょうし、各値を細かく操作したいなら数値の配列でしょう。目的をしっかり考えて選びましょう。