Data descriptor を使わないように書き換えてみた

圧縮ファイル変換が欲しい

手元に沢山のrar形式のファイルが増えてきたけど、個人的にはzip形式の方が嬉しい。
だって、rar形式は展開遅いし、linuxだと圧縮するライブラリがまず無い。(あるようだけど・・・)
そういう背景で、libarchiveに手を出してみた。

libarchive - C library and command-line tools for reading and writing tar, cpio, zip, ISO, and other archive formats @ GitHub

libarchiveの問題点

libarchive は Data descriptor を使用する

現在(2014/03/30)の時点で、libarchiveのstable版は3.1.2である。
ただ、libarchiveのgithubを見ると、だいぶ進んでいるので、そっちをautomakeで使うことにした。

んで、ここで問題発生。
libarchiveでzip形式を作成すると、Local file header領域の crc-32, compressed/uncompressed size が 0 になってしまった。
zip形式の仕様では、Local file headerのあとに圧縮データが書き込まれるが、その場合、ヘッダーを書く時点では圧縮データの情報が不足する可能性がある。
それを補完する目的で、圧縮データのあとに Data descriptor 領域を設けて、そこに書けば OK だよ!という仕様になっている。

そう、libarchiveのzip形式は「必ず Data descriptor 領域を使用する」実装になっていて、これが原因でヘッダーの要素が 0 になっていたのだ。

個人的理由で、Data descriptor は使いたくない

まぁ、仕様だから仕方ないんだけど。
自分が仕様するsusie32プラグインが Data descriptor に対応していないため、 Local file header の情報に不備があるとzip形式を開くことができない。
あと、個人的に、こんな逃げな仕様は認めたくない。 (おい

ということで、libarchive を Data descriptor を使わないように書き換えてみた。

Data descriptor を使わないように書き換えてみた

コードはこちら。
Comparing libarchive:master...hidez8891:zip_without_data_descriptor · hidez8891/libarchive · GitHub

既存の Data descriptor 処理を殺しているため、zip64でちゃんと動くかは不明・・・

既存の仕様よりデグレしてるし、temporary file を使うから処理も遅くなっている。
だから、プルリクは(現時点では)送らない予定。

これで要求は満たされたので、 バリバリ変換していこうー!