blocking_read

整数型のバイナリ読み書きが煩雑だったのでbinary_io.hppに追加しました。
binary_io.hppの差分


ついでにブロッキングI/Oの関数を追加しました。
<hamigaki/iostreams/blocking.hpp>
基本の処理として、

template<class Source>
struct blocking_reader
{
    typedef typename boost::iostreams::char_type_of<Source>::type char_type;

    static char_type* read(Source& src, char_type* s, std::streamsize n)
    {
        boost::iostreams::non_blocking_adapter<Source> nb(src);
        if (boost::iostreams::read(nb, s, n) != n)
            throw boost::iostreams::detail::bad_read();
        return s;
    }
};

を用意し、これを使って3つのインタフェース、

// 1文字読む
template<class Source>
inline char blocking_get(Source& src);

// ちょうどn文字読む
template<class Source>
inline char* blocking_read(Source& src, char* s, std::streamsize n);

// 上記の配列版
template<class Source, std::size_t Size>
inline char* blocking_read(Source& src, char (&s)[Size]);

を実装しています。
なお、non_blocking_adapterを二重に被せるのは無駄なので、blocking_readerを特殊化することで無駄を省いています。

// マクロHAMIGAKI_IOSTREAMS_BLOCKING_SOURCEは
// ブロッキングデバイス用に単純なread呼び出しをする特別バージョンを定義する
HAMIGAKI_IOSTREAMS_BLOCKING_SOURCE(boost::iostreams::non_blocking_adapter, 1);


writeの場合も考え方は同じで、writeの場合はblocking_writerを使います。
blocking_readerとblocking_writerを分けたのは、特殊化用のマクロ内でread()とwrite()を実装してしまうと、非テンプレートで特殊化した場合に不要な関数(Sinkに対するreadなど)まで要求されてしまうからです。
以前作ったHAMIGAKI_IOSTREAMS_BLOCKINGはこの問題のため放置状態でした。
まだHAMIGAKI_IOSTREAMS_BLOCKINGも残していますが、多分いらなくなります。