2009-05-15 3 views
1

Я использую слегка модифицированную версию DotZlib, которая является частью каталога contrib с исходным кодом zlib, чтобы раздуть поток данных в реальном времени.DotZlib - код обработки ошибки Inflate 1 Z_STREAM_END

Вместо обычного inflateInit мне нужно использовать InflateInit2 - но это единственное отличие от предоставленной библиотеки.

Пустота после нескольких чтений Я получаю код ошибки 1 из zlib и не могу восстановить при добавлении байтов.

Исходный код из каталога CONTRIB ZLIB является:

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); 
     } 

КСТАТИ Кто-нибудь знает, как внести свой вклад улучшенный код? Реализация хорошо разработана, но неполна с моей точки зрения.

+1

FYI, есть 100% управляемый ZlibStream в DotNetZip - http://dotnetzip.codeplex.com. – Cheeso

+0

Да - но мне нужно добавить поддержку сжатия в приложение реального времени - таким образом, мне нужно иметь максимальную производительность. – weismat

ответ

1

Я думаю, что

  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(); 
      } 

Есть две проблемы, которые я вижу с первой версией кода:

  1. если надуйте() производит данные, но не дает достаточного количества данных, чтобы сделать avail_out равным 0, вы не будете вызывать OnDataAvailable, даже если данные доступны.
  2. вы можете назвать inflate(), хотя avail_in равно 0, что я легко мог представить, может привести к ошибке потока.

(NB:.. Я подозреваю, что вы знаете меня в профессиональном качестве Этот ответ дается в личном качестве и не имеет отношения к моей работе для моего работодателя)

+0

Я думаю, что это может быть так. Я проверю его - он соответствует тому, что я видел на http://www.koders.com/csharp/fidB377599DB0D658DEA5BD81F67CA407C4FE12E93B.aspx?s=login. – weismat

+0

Этот случай обрабатывается отлично, но как я могу восстановить из ошибки памяти правильно - должен ли я освободить и выделить буфер? Документация на inflateReset не так понятна. – weismat

+0

О какой ошибке памяти мы говорим? надуть возвращения Z_MEM_ERROR? Или что-то другое? –

Смежные вопросы