DotZlib - раздувать код обработки ошибок 1 Z_STREAM_END - PullRequest
1 голос
/ 15 мая 2009

Я использую слегка измененную версию DotZlib, которая является частью каталога contrib с исходным кодом zlib, для раздувания потока данных в реальном времени.

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

Netherlesse после пары чтений, я получаю код ошибки 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 Ответ

1 голос
/ 18 мая 2009

Я думаю, что

            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. если inflate () выдает данные, но не выдает достаточно данных, чтобы сделать vend_out равным 0, вы не вызовете OnDataAvailable, даже если данные доступны.
  2. Вы могли бы вызвать inflate (), даже если в качестве значения 0 в качестве значения_подключения можно было бы предположить, что это может привести к ошибке завершения потока.

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

...