lzh_file_sink

予定通りlzh_file_sinkが出来ました。
lzh_file.hppの差分
Level2ヘッダ固定で、まだ必要最低限の拡張ヘッダしかサポートしていません。


使い方はこんな感じです。

#include <hamigaki/iostreams/device/lzh_file.hpp>
#include <boost/filesystem/convenience.hpp>
#include <boost/filesystem/operations.hpp>
#include <boost/iostreams/copy.hpp>
#include <clocale>

namespace io_ex = hamigaki::iostreams;
namespace fs = boost::filesystem;
namespace io = boost::iostreams;

int main(int argc, char* argv[])
{
    if (argc < 3)
        return 1;

    std::setlocale(LC_ALL, "");
    fs::path::default_name_check(fs::no_check);

    // コマンドラインの第一引数がLZHファイル名
    io_ex::lzh_file_sink lzh(argv[1]);

    // 残りのコマンドライン引数が圧縮するファイル名
    for (int i = 2; i < argc; ++i)
    {
        io_ex::lha::header head;
        head.path = fs::path(argv[i], fs::native);

        // ディレクトリの場合はファイル属性を設定
        if (fs::is_directory(head.path))
            head.attributes = io_ex::lha::attributes::directory;

        // 最終更新日時を設定
        head.update_time = fs::last_write_time(head.path);

        // 新しいエントリを作成
        lzh.create_entry(head);

        // ファイルの場合は内容をコピー(圧縮)
        if (!fs::is_directory(head.path))
        {
            io::copy(
                io_ex::file_source(
                    head.path.native_file_string(),
                    std::ios_base::binary
                ),
                lzh
            );
        }
    }

    // LZHのエンドマークを書き込む
    lzh.write_end_mark();
}

本当は圧縮結果が元のファイルサイズを超えたら、非圧縮で書き直す必要があります。
そのインタフェースは考え中です。


あと、どうでもいいことですが、LHAのアルゴリズムは「LZHUFF」でなく「LZHUF」なので、lzhuff_compressorはlzhuf_compressorの間違いです。
後で直しておきます。