iso9660_file_sink

iso9660_file_sinkを実装しました。
iso9660_file_sink_impl.hpp
自分で作ったisoファイルをマウントしてエクスプローラで閲覧すると、喜びも一入です。


昨日悩んでいたディレクトリ情報やディレクトリ構造の持ち方ですが、

// ディレクトリエントリの情報
struct directory_record
{
    // ...
};

typedef std::vector<directory_record> directory_records;

// パステーブルのレコード
struct path_table_record
{
    // ...

    // 親ディレクトリの同一階層内のインデックス
    // (出力時には全体での通し番号に振り直す)
    boost::uint16_t parent_index;

    // ディレクトリエントリのベクタ
    boost::shared_ptr<directory_records> records;
};

typedef std::vector<path_table_record> path_table_records;

// ベクタのインデックスはディレクトリ階層のレベル
// 0はルートディレクトリ
boost::ptr_vector<path_table_records> path_table_;

のようにパステーブルを階層ごとに独立して管理することにしました。
パステーブルはファイルを追加するたびに検索する必要があるため、常にソートされた状態を保っています。
パステーブルにレコードを追加すると、その直下の階層内のレコードでparent_indexの値がずれるので、そのたびに調整しています。
階層ごとに分けたのは、このずれの影響を少なくするためです。


また、path_table_recordはソートで頻繁にコピーが発生するため、ディレクトリエントリのベクタはスマートポインタで持つようにしています。


ディレクトリ構造の持ち方も面倒でしたが、出力もかなり面倒でした。
ISO 9660では、ディレクトリのエクステント(ファイルの中身)は、各エントリのディレクトリレコードを連結したものです。
これには「.」や「..」に相当するレコードも含まれるため、ディスクに出力する前に各ディレクトリのサイズを計算し、「.」と「..」も含め適切なオフセットとサイズを重複して設定する必要があります。
実装がややこしかった割にはすんなり動いた気もします。


TODO

  • Joliet対応
  • ボリューム情報(ボリュームラベル等)の設定