コード例 #1
0
        public override int Read(byte[] buffer, int offset, int count)
        {
            if (_mode != CompressionMode.Decompress)
            {
                throw new BrotliException("Can't read on this stream");
            }


            int     bytesRead     = (int)(_intermediateStream.Length - _readOffset);
            uint    totalCount    = 0;
            Boolean endOfStream   = false;
            Boolean errorDetected = false;

            while (bytesRead < count)
            {
                while (true)
                {
                    if (_lastDecodeResult == BrotliDecoderResult.NeedsMoreInput)
                    {
                        _availableIn  = (UInt32)_stream.Read(_managedBuffer, 0, (int)BufferSize);
                        _ptrNextInput = _ptrInputBuffer;
                        if (_availableIn <= 0)
                        {
                            endOfStream = true;
                            break;
                        }
                        Marshal.Copy(_managedBuffer, 0, _ptrInputBuffer, (int)_availableIn);
                    }
                    else if (_lastDecodeResult == BrotliDecoderResult.NeedsMoreOutput)
                    {
                        Marshal.Copy(_ptrOutputBuffer, _managedBuffer, 0, BufferSize);
                        _intermediateStream.Write(_managedBuffer, 0, BufferSize);
                        bytesRead     += BufferSize;
                        _availableOut  = BufferSize;
                        _ptrNextOutput = _ptrOutputBuffer;
                    }
                    else
                    {
                        //Error or OK
                        endOfStream = true;
                        break;
                    }
                    _lastDecodeResult = Brolib.BrotliDecoderDecompressStream(_state, ref _availableIn, ref _ptrNextInput,
                                                                             ref _availableOut, ref _ptrNextOutput, out totalCount);
                    if (bytesRead >= count)
                    {
                        break;
                    }
                }

                if (endOfStream && !Brolib.BrotliDecoderIsFinished(_state))
                {
                    errorDetected = true;
                }

                if (_lastDecodeResult == BrotliDecoderResult.Error || errorDetected)
                {
                    var error = Brolib.BrotliDecoderGetErrorCode(_state);
                    var text  = Brolib.BrotliDecoderErrorString(error);
                    throw new BrotliDecodeException(String.Format("Unable to decode stream,possibly corrupt data.Code={0}({1})", error, text), error, text);
                }

                if (endOfStream && !Brolib.BrotliDecoderIsFinished(_state) && _lastDecodeResult == BrotliDecoderResult.NeedsMoreInput)
                {
                    throw new BrotliException("Unable to decode stream,unexpected EOF");
                }

                if (endOfStream && _ptrNextOutput != _ptrOutputBuffer)
                {
                    int remainBytes = (int)(_ptrNextOutput.ToInt64() - _ptrOutputBuffer.ToInt64());
                    bytesRead += remainBytes;
                    Marshal.Copy(_ptrOutputBuffer, _managedBuffer, 0, remainBytes);
                    _intermediateStream.Write(_managedBuffer, 0, remainBytes);
                    _ptrNextOutput = _ptrOutputBuffer;
                }
                if (endOfStream)
                {
                    break;
                }
            }

            if (_intermediateStream.Length - _readOffset >= count || endOfStream)
            {
                _intermediateStream.Seek(_readOffset, SeekOrigin.Begin);
                var bytesToRead = (int)(_intermediateStream.Length - _readOffset);
                if (bytesToRead > count)
                {
                    bytesToRead = count;
                }
                _intermediateStream.Read(buffer, offset, bytesToRead);
                TruncateBeginning(_intermediateStream, _readOffset + bytesToRead);
                _readOffset = 0;
                return(bytesToRead);
            }

            return(0);
        }
コード例 #2
0
 private static TransformationStatus GetTransformationStatusFromBrotliDecoderResult(BrotliDecoderResult result)
 {
     if (result == BrotliDecoderResult.Success)
     {
         return(TransformationStatus.Done);
     }
     if (result == BrotliDecoderResult.NeedsMoreOutput)
     {
         return(TransformationStatus.DestinationTooSmall);
     }
     if (result == BrotliDecoderResult.NeedsMoreInput)
     {
         return(TransformationStatus.NeedMoreSourceData);
     }
     return(TransformationStatus.InvalidData);
 }
コード例 #3
0
        public int Decompress(byte[] source, int offset, int count, byte[] destination)
        {
            if (mCompressionMode != CompressionMode.Decompress)
            {
                throw new BrotliException(
                          "The BrotliStream instance can not decompress the buffer.");
            }

            BrotliDecoderResult lastDecodeResult =
                BrotliDecoderResult.NeedsMoreInput;

            int  bytesProcessed    = 0;
            bool endOfSource       = false;
            bool errorDetected     = false;
            int  destinationLength = 0;

            while (bytesProcessed < count)
            {
                while (true)
                {
                    if (lastDecodeResult == BrotliDecoderResult.NeedsMoreInput)
                    {
                        mAvailableIn = (count - bytesProcessed) > BUFFER_SIZE
                            ? BUFFER_SIZE
                            : (uint)(count - bytesProcessed);

                        mPtrNextInput = mPtrInputBuffer;

                        if (mAvailableIn <= 0)
                        {
                            endOfSource = true;
                            break;
                        }

                        Marshal.Copy(
                            source,
                            offset + bytesProcessed,
                            mPtrInputBuffer,
                            (int)mAvailableIn);
                    }
                    else if (lastDecodeResult == BrotliDecoderResult.NeedsMoreOutput)
                    {
                        Marshal.Copy(
                            mPtrOutputBuffer,
                            destination,
                            destinationLength,
                            BUFFER_SIZE);

                        destinationLength += BUFFER_SIZE;
                        bytesProcessed    += BUFFER_SIZE;
                        mAvailableOut      = BUFFER_SIZE;
                        mPtrNextOutput     = mPtrOutputBuffer;
                    }
                    else
                    {
                        // Error or OK
                        endOfSource = true;
                        break;
                    }

                    uint totalCount = 0;
                    lastDecodeResult = Brolib.BrotliDecoderDecompressStream(
                        mPtrState,
                        ref mAvailableIn,
                        ref mPtrNextInput,
                        ref mAvailableOut,
                        ref mPtrNextOutput,
                        out totalCount);

                    if (bytesProcessed >= destination.Length)
                    {
                        break;
                    }
                }

                if (endOfSource && !Brolib.BrotliDecoderIsFinished(mPtrState))
                {
                    errorDetected = true;
                }

                if (lastDecodeResult == BrotliDecoderResult.Error || errorDetected)
                {
                    int    errorCode    = Brolib.BrotliDecoderGetErrorCode(mPtrState);
                    string errorMessage = Brolib.BrotliDecoderErrorString(errorCode);

                    throw new BrotliException(string.Format(
                                                  "Unable to decompress the buffer. Error {0} - {1}",
                                                  errorCode, errorMessage));
                }

                if (endOfSource && Brolib.BrotliDecoderIsFinished(mPtrState) &&
                    lastDecodeResult == BrotliDecoderResult.NeedsMoreInput)
                {
                    throw new Exception("Unable to decompress the buffer. Unexpected EOF.");
                }

                if (endOfSource && mPtrNextOutput != mPtrOutputBuffer)
                {
                    int remainingBytes = (int)(mPtrNextOutput.ToInt64() - mPtrOutputBuffer.ToInt64());
                    bytesProcessed += remainingBytes;

                    if (destinationLength + remainingBytes > destination.Length)
                    {
                        throw new BrotliException(
                                  "The destination buffer is smaller than the decompressed source buffer");
                    }

                    Marshal.Copy(mPtrOutputBuffer, destination, destinationLength, remainingBytes);
                    destinationLength += remainingBytes;
                    mPtrNextOutput     = mPtrOutputBuffer;
                }

                if (endOfSource)
                {
                    break;
                }
            }

            return(destinationLength);
        }