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も残していますが、多分いらなくなります。