2011年2月28日月曜日

[LabVIEW]『統合アーカイバ』DLLライブラリの更新と解説

一晩寝て、ちょっとすっきりしたので前回エントリでアップした『統合アーカイバ』DLL用ライブラリの更新と解説を少しだけ。

更新したライブラリ『CommonArchiver_for_LabVIEW_20110228b』のダウンロードはココ


変更点は、
  • CAB形式への対応
  • TAR形式の書庫ファイルでプレビューが取得できなかったのを修正
です。
また、注意点として、
  • ARJ形式の展開を行なう「UNARJ32J.DLL」をロードすると、以降DLLのロードに不具合が出る。
という問題点があります。現状では「UNARJ32J.DLL」はロードしないのが懸命です(使ったことないし、今後も使わないと思うので多分対応しません)。

以下、自分用メモとしての解説w


■ライブラリが提供する機能について

このライブラリでは、高レベルな機能として、
  1. 書庫ファイルへの単一ファイルの格納 (comarc_AddFileToArchive.vi)
  2. 書庫ファイルへのディレクトリ以下全ファイルの格納 (comarc_AddDirToArchive.vi)
  3. 書庫ファイルの格納ファイル一覧の取得 (comarc_ExtractAllFromArchive.vi)
  4. 書庫ファイルの全格納ファイルのディスクへの展開 (comarc_ExtractAllFromArchive.vi)
という4つの機能を実装しています。
上記1.および2.はさらに、「既存書庫ファイルへの追加」も加えることができます。

ただし、ロードしたDLLの全てで上記全機能が使えるわけではありません。
例えば、「UNZIP32.DLL」や「UNRAR32.DLL」は、そもそもDLLに格納機能がありませんし、
CAB32.DLL」や「TAR32.DLL」は既存書庫ファイルへの追加ができません。

■DLLコマンド・スイッチの相違を吸収する方法

実際に格納・展開を行っているのはDLL固有名を持つ関数で、API経由でこの関数にコマンド・スイッチ文字列を送って実行させています。
ところが、このコマンド・スイッチ文字列がDLL毎に異なっています。
例えば、圧縮・格納を行わせるコマンドは、「UNLHA32.DLL」では【a -d …】ですし、「TAR32.DLL」では【-c …】です。

このライブラリではそうした相違を吸収するために、『成功するまで異なったコマンド文字列を送り続ける』という力技を使っています。

ファイルおよびディレクトリの格納を行なうcomarc_AddFileToArchive.viでは、
  1. 最初に【a -d …】コマンド・スイッチを送ります。「UNLHA32.DLL」ではここで成功するのですが、「7-ZIP32.DLL」だと【-d】スイッチがないのでエラーになります。
  2. 次に【a -r …】コマンド・スイッチを送ります。これで「7-ZIP32.DLL」は成功します。しかし「CAB32.DLL」「TAR32.DLL」では【コマンドは全てマイナス記号始まり】なので、ここまで全部エラーです。
  3. 次に【-a -r …】コマンド・スイッチを送り、「CAB32.DLL」が成功します。しかしまだ「TAR32.DLL」では【-a】コマンドがないのでエラーです。
  4. 最後に【-c …】コマンドを送って「TAR32.DLL」が成功します。ここまでで成功しなかったら、そのDLLでは機能未対応としてエラーとします。
という順序でコマンド・スイッチを試しています。

書庫ファイル一覧取得では、【v …】→【-v …】→【l …】→【-l …】の順で、
書庫ファイル展開では、 【x …】→【-x …】の順でコマンドを試しています。

このことは「試すコマンドをさらに増やせば対応DLLも増える」ということになるのですが、動作確認が面倒くさいですw

■書庫ファイルの格納ファイル一覧取得について

上記のように、書庫ファイルの格納ファイル一覧取得は、DLLに【l …】コマンドを送信し、そのログ出力から行っています。
このログ出力は、呼び出し側で確保したメモリ領域に出力させる方式ですので、確保した領域をログがハミでる場合には、確保した分までしか出力されません(まぁ当然ですが)。
そのため、ちょっと長いファイルリストなんかだと、全部が収まらないことが多々あります。

呼び出し前にAPIのGetFileCount関数で必要領域の見当がつけば良かったんですが、DLLによって出力するログ形式(ファイル1つ当たりに使うログのバイト数)が違うので、これも無理があります。

そこで、このライブラリでは、最初に512バイトだけ領域を確保してログを取得し、そのログ中にヌル文字が見つからなかった場合は、領域不足でログが途中で切られたと見做し、確保領域を倍の1024バイトに増やして、もう一度コマンドを実行しています。

この「ログ取得→ヌル文字なければ領域倍増→ログ再取得」のサイクルを10回まで行い、そこまでにヌル文字を見つけられなければエラーを返すようにしています。ヌル文字が見つかれば、後述するログの解析に移行します。

出力されるログの形式は、DLL毎にかなり異なっています。
「UNLHA32.DLL」では、1ファイルにつき、パス付きの名前で1行、サイズ等情報で1行の計2行使っていますし、
「7-ZIP32.DLL」などでは、パス付き名前・サイズ等全て1行に含まれています。
また、ログヘッダーもDLLごとにその行数が異なっています。

このライブラリでは、先ず「行頭が3文字以上のマイナス記号」で始まる行を全て検索し、それらをログヘッダー・フッターとファイル情報との境目である、と認識し、解析ています。
このとき、「CAB32.DLL」ではログフッターがなく、ファイル情報の終わりに「行頭が3文字以上のマイナス記号」の行が無いので、全てのDLLからのログ出力には末尾に「行頭が3文字以上のマイナス記号」の行を付加しています。
また、「TAR32.DLL」では、このようなログヘッダー・フッター自体がありませんので、単純に全文をファイル情報と見なして解析しています。


■各アーカイバDLLの対応状況

20110228b版における各アーカイバDLLの機能対応状況は以下のとおりです。


○UNLHA32.DLL
  • 新規書庫ファイルへの単一ファイル・ディレクトリ格納 -----
  • 既存書庫ファイルへの単一ファイル・ディレクトリ追加 -----
  • 書庫ファイルの格納ファイル一覧取得 -----
  • 書庫ファイルの全格納ファイル展開 -----
○UNARJ32J..DLL

※DLLのロードに不具合あり

○UNZIP32.DLL
  • 新規書庫ファイルへの単一ファイル・ディレクトリ格納 -----
  • 既存書庫ファイルへの単一ファイル・ディレクトリ追加 -----
  • 書庫ファイルの格納ファイル一覧取得 -----
  • 書庫ファイルの全格納ファイル展開 -----

○TAR32.DLL
  • 新規書庫ファイルへの単一ファイル・ディレクトリ格納 -----
  • 既存書庫ファイルへの単一ファイル・ディレクトリ追加 -----
  • 書庫ファイルの格納ファイル一覧取得 -----
  • 書庫ファイルの全格納ファイル展開 -----
○CAB32.DLL
  • 新規書庫ファイルへの単一ファイル・ディレクトリ格納 -----
  • 既存書庫ファイルへの単一ファイル・ディレクトリ追加 -----
  • 書庫ファイルの格納ファイル一覧取得 -----
  • 書庫ファイルの全格納ファイル展開 -----
○UNRAR32.DLL
  • 新規書庫ファイルへの単一ファイル・ディレクトリ格納 -----
  • 既存書庫ファイルへの単一ファイル・ディレクトリ追加 -----
  • 書庫ファイルの格納ファイル一覧取得 -----
  • 書庫ファイルの全格納ファイル展開 -----
○BGA32.DLL
  • 新規書庫ファイルへの単一ファイル・ディレクトリ格納 -----
  • 既存書庫ファイルへの単一ファイル・ディレクトリ追加 -----
  • 書庫ファイルの格納ファイル一覧取得 -----
  • 書庫ファイルの全格納ファイル展開 -----
○7-ZIP32.DLL
  • 新規書庫ファイルへの単一ファイル・ディレクトリ格納 -----
  • 既存書庫ファイルへの単一ファイル・ディレクトリ追加 -----
  • 書庫ファイルの格納ファイル一覧取得 -----
  • 書庫ファイルの全格納ファイル展開 -----
上記以外のDLLについては未確認です。

以上

0 件のコメント:

コメントを投稿