Rock Ridge 再検討

Rock Ridgeのコードを眺めていたところ、ディレクトリのトラバースに関する処理もディレクトリレコードの修正だけで対応できることに気が付きました。


"CL" System Use Entry (子ディレクトリの位置)
"PL" System Use Entry (親ディレクトリの位置)
→そのディレクトリのエクステント位置を上書きする


"RE" System Use Entry (再配置済みフラグ)
ディレクトリレコードの配列からそのディレクトリを削除する


その他のSystem Use Entryはディレクトリやファイルに関する属性を追加するだけのものですから、これでRock Ridgeに関する処理はすべて、ISO 9660/Jolietのパース処理の上にラッパーをかぶせるだけで実装できることになります。


ISO 9660、Joliet用のパーサーに加え、それぞれにRock Ridge拡張を施したものの合わせて4つを用意する必要がありますが、Sourceを実装する際に多相化する必要があるので、初めから多相化しておくのが簡単です。

// ディレクトリパーサーの基底クラス
template<class Source>
class iso_directory_parser
{
public:
    virtual ~iso_directory_parser(){}

    void parse(Source& src, std::vector<directory_record>& records)
    {
        this->do_parse(src, records);
    }

private:
    virtual void do_parse(Source& src, std::vector<directory_record>& records) = 0;
};

// ISO 9660用の実装
template<class Source>
class iso9660_directory_parser : public iso_directory_parser<Source>
{
    // ...
};

// Joliet用の実装
template<class Source>
class joliet_directory_parser : public iso_directory_parser<Source>
{
    // ...
};

// Rock Ridge用の実装
template<class Source>
class rock_ridge_directory_parser : public iso_directory_parser<Source>
{
public:
    typedef iso_directory_parser<Source> impl_type;

    explicit rock_ridge_directory_parser(impl_type* pimpl)
        : pimpl_(pimpl)
    {
    }

private:
    std::auto_ptr<impl_type> pimpl_;

    void do_parse(Source& src, std::vector<directory_record>& records) // virtual
    {
        pimpl_->parse(src, records);

        // ここでRock Ridgeをパースして、recordsを修正する
    }
};

rock_ridge_directory_parserはiso9660_directory_parserでもjoliet_directory_parserでもないので継承関係はありません。
継承でなく包含で済むので、仮想関数はprotectedでなくprivateになっています。


考えもまとまったので、明日は実際に実装して見ます。