Ejemplo n.º 1
0
        /// <exception cref="NotSupportedException">The stream must be in decompress mode to read from.</exception>
        /// <exception cref="ArgumentNullException"><paramref name="p"/> is <see langword="null" />.</exception>
        /// <exception cref="ArgumentOutOfRangeException">length cannot be negative.</exception>
        /// <exception cref="ObjectDisposedException">The method cannot be called after the object has been disposed.</exception>
        public unsafe int Read(byte *p, int length)
        {
            if (!CanRead)
            {
                throw new NotSupportedException($"{nameof(GZipStream)} must be in decompress mode to read from");
            }
            if (p == null)
            {
                throw new ArgumentNullException(nameof(p));
            }
            if (length < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(length), "length cannot be negative");
            }
            if (_isDisposed)
            {
                throw new ObjectDisposedException(nameof(GZipStream));
            }
            Contract.EndContractBlock();

            var exitLoop = false;

            _zstream.next_out  = p;
            _zstream.avail_out = (uint)length;

            while (_zstream.avail_out > 0 && exitLoop == false)
            {
                if (_zstream.avail_in == 0)
                {
                    var readLength = _stream.Read(_tmpBuffer, 0, _tmpBuffer.Length);
                    _zstream.avail_in = (uint)readLength;
                    _zstream.next_in  = (byte *)_tmpBufferPtr;
                }
                var result = ZLibNative.inflate(ref _zstream, ZLibFlush.NoFlush);
                switch (result)
                {
                case ZLibReturnCode.StreamEnd:
                    exitLoop = true;
                    break;

                case ZLibReturnCode.Ok:
                    break;

                case ZLibReturnCode.MemError:
                    throw new OutOfMemoryException($"ZLib return code: {result}");

                default:
                    throw new Exception($"ZLib return code: {result}");
                }
            }

            return(length - (int)_zstream.avail_out);
        }