私はブーストとそのiostreamsパッケージを新しくして、ドキュメントを少し薄くしています。私は、私は圧縮されたストリームを読み込むために書き込んだC#ストリームコードの小さな部分を変換しようとしています。boost :: iostreamsはリソースを管理しています
byte[] data = new byte[length - 1];
file.Read(data, 0, data.Length);
Stream ret = new ZlibStream(new MemoryStream(data), CompressionMode.Decompress, true);
return ret;
ファイルの一部からのデータは、zlibデコンプレッサに供給するメモリバッファに読み込まれます。ストリームの消費者は時間がたつにつれてそれを取り除き、終了するとClose()
と呼ばれ、ガベージコレクタと組み合わされてすべてのリソースがクリーンアップされます。 注::重要な違いは、ファイル全体を解凍しようとしていないことです。ファイルは既に内部の場所にシークされており、ファイルのフルサイズに比べて長さが短くなっています。
私はBoostのC++コードでこれに匹敵する最高のものを考え出しています。これまでのところ、私はこの道徳的上記(未テスト)に相当します:私は、ストリームの削除を気にすることから、消費者を救うshared_ptr
に包まれfiltering_streamを返すことができると仮定し
char * data = new char[length - 1];
_file.read(data, length - 1);
io::stream_buffer<io::basic_array_source<char> > buffer(data, length - 1);
io::filtering_stream<io::input> * in = new io::filtering_stream<io::input>;
in->push(io::zlib_decompressor());
in->push(buffer);
return in;
を、私も持っていますそのデータバッファーはそこに新しいものがあります。理想的には、消費者がストリーム上でclose()
と呼ぶようにしたいと思っています。そして、ある種のメカニズム(コールバックなど)がフィルタの基礎となるリソースをクリーンアップします。消費者がストリームを明示的なリリース関数に渡すように要求することも許容されますが、最初の場所で元のデータバッファを戻す方法はまだ完全にはわかりません。
クリーナーの代替ソリューションも歓迎します。
私がのstd ::ベクトル担保ドライバに関するキャットプラスプラスすることによってコメントに押収緩く試してみた1
更新。それは私がやったことではありませんが、これはこれまで私が思いついたことです。次のコードでは、boostドライバの例に基づいて、boost :: shared_arrayでバックアップされたドライバがあります。
namespace io = boost::iostreams;
class shared_array_source
{
public:
typedef char char_type;
typedef io::source_tag category;
shared_array_source (boost::shared_array<char> s, std::streamsize n)
: _data(s), _pos(0), _len(n)
{ }
std::streamsize read (char * s, std::streamsize n)
{
std::streamsize amt = _len - _pos;
std::streamsize result = (std::min)(amt, n);
if (result != 0) {
std::copy(_data.get() + _pos, _data.get() + _pos + result, s);
return result;
}
else {
return -1;
}
}
private:
boost::shared_array<char> _data;
std::streamsize _pos;
std::streamsize _len;
};
その後、私はストリーム
io::filtering_istream * GetInputStream (...)
{
// ... manipulations on _file, etc.
boost::shared_array<char> data(new char[length - 1]);
_file.read(data.get(), length - 1);
shared_array_source src(data, length - 1);
io::stream<shared_array_source> buffer(src);
io::filtering_istream * in = new io::filtering_istream;
in->push(io::zlib_decompressor());
in->push(buffer);
// Exhibit A
// uint32_t ui;
// rstr->read((char *)&ui, 4);
return in;
}
そして、テストプログラムの私の主な機能でを返す私の機能を持っている:
int main() {
boost::iostreams::filtering_istream * istr = GetInputStream();
// Exhibit B
uint32_t ui;
rstr->read((char *)&ui, 4);
return 0;
}
は私がポインタを返すてるという事実を無視それは決して解放されません - 私はこれを可能な限りシンプルに保っています。これを実行するとどうなりますか? Exhibit Aのコードのコメントを外すと、ui
に適切な情報が得られます。しかし、私がExhibit Bを打ったとき、私はBoost(時には)で深く、深く、深く墜落します。うんざり、私は範囲外に出て、物事が壊れた、いくつかのローカルは、すべてを解体し、混乱させる必要があります。 data
はshared_arrayにあり、in
はヒープ上にあり、コンプレッサーはドキュメントに従って構築されています。
ブーストコンストラクタまたは関数の1つは、スタック上のオブジェクトへの参照(つまり、io :: streamまたはfiltering_streamのプッシュ)を取得していますか?その場合、ヒープ上の管理されていないオブジェクトを持つ正方形に戻っています。
常にゼロに等しいか? これは決して価値がありません。 –