DotZlib - エラー処理コード 1 Z_STREAM_END をインフレートします。
質問
私は、リアルタイム データ ストリームをインフレートするために、zlib ソース コードを含む contrib ディレクトリの一部である DotZlib のわずかに変更されたバージョンを使用しています。
通常の inflateInit の代わりに InflateInit2 を使用する必要がありますが、提供されているライブラリとの唯一の違いはこれです。
それでも、数回の読み取りの後、zlib からエラー コード 1 を受け取り、バイトを追加するときに回復できません。
zlib contrib ディレクトリの元のコードは次のとおりです。
public override void Add(byte[] data, int offset, int count)
{
if (data == null) throw new ArgumentNullException();
if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException()
;
if ((offset+count) > data.Length) throw new ArgumentException();
int total = count;
int inputIndex = offset;
int err = 0;
while (err >= 0 && inputIndex < total)
{
copyInput(data, inputIndex, Math.Min(total - inputIndex, kBufferSize));
err = inflate(ref _ztream, (int)FlushTypes.None);
if (err == 0)
while (_ztream.avail_out == 0)
{
OnDataAvailable();
err = inflate(ref _ztream, (int)FlushTypes.None);
}
inputIndex += (int)_ztream.total_in;
}
setChecksum( _ztream.adler );
}
ところで、コードを改善する方法を知っている人はいますか?実装はうまく設計されていますが、私の観点からは不完全です。
解決
私はそう思います
err = inflate(ref _ztream, (int)FlushTypes.None);
if (err == 0)
while (_ztream.avail_out == 0)
{
OnDataAvailable();
err = inflate(ref _ztream, (int)FlushTypes.None);
}
あるべきです
while (_ztream.avail_in > 0)
{
err = inflate(ref _ztream, (int)FlushTypes.None);
if (err!=0)
break;
OnDataAvailable();
}
コードの最初のバージョンには 2 つの問題があります。
- inflate() がデータを生成しても、avail_out を 0 にするのに十分なデータが生成されない場合は、データが利用可能であっても、OnDataAvailable は呼び出されません。
- avail_in が 0 であっても inflate() を呼び出す可能性があります。これにより、ストリーム終了エラーが発生する可能性があることが容易に想像できます。
(注意:あなたは私のことを専門的な立場で知っていると思います。この回答は個人的な立場で行われたものであり、雇用主としての私の仕事とは関係ありません。)
所属していません StackOverflow