DotZlib - inflar código de manipulação de erro 1 Z_STREAM_END
Pergunta
Eu estou usando uma versão ligeiramente modificada do DotZlib que faz parte do diretório contrib com o código fonte zlib para inflar um fluxo de dados em tempo real.
Em vez do inflateInit regular, eu preciso usar InflateInit2 -. Mas isso a única diferença para a biblioteca fornecido
Netherlesse depois de um par de lê Eu receber código de erro 1 do zlib e não conseguem recuperar quando a adição de bytes.
O código original do diretório 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 );
}
BTW Alguém sabe como contribuir código melhorado? A implementação é muito bem concebido, mas incompleta, do meu ponto de vista.
Solução
Eu acho que
err = inflate(ref _ztream, (int)FlushTypes.None);
if (err == 0)
while (_ztream.avail_out == 0)
{
OnDataAvailable();
err = inflate(ref _ztream, (int)FlushTypes.None);
}
deve ser
while (_ztream.avail_in > 0)
{
err = inflate(ref _ztream, (int)FlushTypes.None);
if (err!=0)
break;
OnDataAvailable();
}
Existem dois problemas que vejo com a primeira versão do código:
- se inflar () produz dados, mas não produz dados suficientes para fazer avail_out ser 0, você não vai chamar OnDataAvailable, apesar de está disponível de dados.
- você pode chamar inflar () embora avail_in é 0, o que eu poderia facilmente imaginar pode produzir um erro de fluxo de-final.
(NB:.. Eu suspeito que você me conhece em uma capacidade profissional Esta resposta é dada a título privado e não está relacionado ao meu trabalho para o meu empregador)