Boost Iostreams ライブラリの gzip フィルタを、バッファリングされた自家製のものと組み合わせて使用しているときに、実行の問題に遭遇しました。私のやり方で何が間違っているのか知りたいです。
まず、私のフィルターは一般的な DualFilter です。変換とプット/リターンの前に (16 バイトの) バッファーを使用します。私のフィルタのカテゴリは、closesable と dual_use です。コードの詳細は、このメールの最後に記載されています。
私の問題は ([a/b] は、文字 a と b でケースを分離することを意味します): 書き込みと読み取りの 6 つの可能性を取る場合:
1) io::filtering_[i/o]stream stm;
2) stm.push(io::gzip_[de/]compressor());
3) stm.push(my_[Unt/T]ransFilter);
現時点では、stm.[get/put] を使用して読み取り/書き込みを行います。
1)-2) works perfectly
1)-3) works perfectly
1)-3)-2) works perfectly
1)-2)-3) Stay stuck (obviously it is the one I really need)
実際、最後のケースでは、gzip フィルターは、この無限ループを TransFilter の put に与えます。
31 -117 8 0 0 0 0 0 0 31 -117 8 0 0...
同様のケースが bzip フィルターでも発生します (ループが少し長くても)。
私は何を間違っていますか?誰かが私を助けることができますか?
前もって感謝します
クリストフ
PS:ここでは、私のフィルターの単純化された実装です
template<typename Source>
int get(Source& src)
{
//at the very beginning or if the buffer are fully returned
if (fcurrent_pos == fblkLength)
{
fcurrent_pos =0;
FillThem (src); //fill&transform the buffers with the right number of src.get()
fc=CheckNSolveBufferIsEnd (src); //eventually prepare read the suffix of the file
}
//The effective return
if (fcurrent_pos < fUntrans.size ())
return (int)fUntrans[fcurrent_pos++];
else
return fc;
}
template<typename Sink>
bool put(Sink& dest, int c)
{
if (c==EOF || c ==boost::iostreams::WOULD_BLOCK)
return false;
if (fUntrans.size () < fblkLength - 1)
{
fUntrans.AddData((char*)(&c),1);
return true;
}
fUntrans.AddData((char*)(&c),1);
fenc->TransformThis (fUntrans, fTrans, fKey);
for (int i=0; i<fblkLength; i++)
{
if (!boost::iostreams::put(dest, (int)fTrans[i]))
return false;
}
return true;
}
template<typename Sink>
bool close (Sink &dest, BOOST_IOS::openmode m)
{
if (fFlushed)
return true;
PrepareSuffix ();
for (int i=0; i< fblkLength*2; //suffix length
i++)
{
if (!boost::iostreams::put(dest, (int)fTrans[i]))
return false;
}
return true;
}