예제 #1
0
        public override void Write(byte[] buffer, int offset, int count)
        {
            if (_mode != CompressionMode.Compress)
            {
                throw new BrotliException("Can't write on this stream");
            }

            _written    = true;
            totalWrote += count;
            //Console.WriteLine(String.Format("Write {0} bytes,total={1} bytes.", count, totalWrote));

            UInt32 totalOut      = 0;
            int    bytesRemain   = count;
            int    currentOffset = offset;

            Boolean compressOK = true;

            while (bytesRemain > 0)
            {
                int copyLen = bytesRemain > BufferSize ? BufferSize : bytesRemain;
                Marshal.Copy(buffer, currentOffset, _ptrInputBuffer, copyLen);
                bytesRemain   -= copyLen;
                currentOffset += copyLen;
                _availableIn   = (UInt32)copyLen;
                _ptrNextInput  = _ptrInputBuffer;
                while (_availableIn > 0)
                {
                    compressOK = Brolib.BrotliEncoderCompressStream(_state, BrotliEncoderOperation.Process, ref _availableIn, ref _ptrNextInput, ref _availableOut,
                                                                    ref _ptrNextOutput, out totalOut);
                    if (!compressOK)
                    {
                        throw new BrotliException("Unable to compress stream");
                    }
                    if (_availableOut != BufferSize)
                    {
                        var bytesWrote = (int)(BufferSize - _availableOut);
                        //Byte[] localBuffer = new Byte[bytesWrote];
                        Marshal.Copy(_ptrOutputBuffer, _managedBuffer, 0, bytesWrote);
                        _stream.Write(_managedBuffer, 0, bytesWrote);
                        _availableOut  = BufferSize;
                        _ptrNextOutput = _ptrOutputBuffer;
                    }
                }
                if (Brolib.BrotliEncoderIsFinished(_state))
                {
                    break;
                }
            }
        }
예제 #2
0
        protected virtual void FlushBrotliStream(Boolean finished)
        {
            //test if the resource has been freed
            if (_state == IntPtr.Zero)
            {
                return;
            }
            if (Brolib.BrotliEncoderIsFinished(_state))
            {
                return;
            }
            BrotliEncoderOperation op = finished ? BrotliEncoderOperation.Finish : BrotliEncoderOperation.Flush;
            UInt32 totalOut           = 0;

            while (true)
            {
                var compressOK = Brolib.BrotliEncoderCompressStream(_state, op, ref _availableIn, ref _ptrNextInput, ref _availableOut, ref _ptrNextOutput, out totalOut);
                if (!compressOK)
                {
                    throw new BrotliException("Unable to finish encode stream");
                }
                var extraData = _availableOut != BufferSize;
                if (extraData)
                {
                    var bytesWrote = (int)(BufferSize - _availableOut);
                    if (_written)
                    {
                        Marshal.Copy(_ptrOutputBuffer, _managedBuffer, 0, bytesWrote);
                        _stream.Write(_managedBuffer, 0, bytesWrote);
                    }
                    _availableOut  = BufferSize;
                    _ptrNextOutput = _ptrOutputBuffer;
                }
                if (Brolib.BrotliEncoderIsFinished(_state))
                {
                    break;
                }
                if (!extraData)
                {
                    break;
                }
            }
        }
예제 #3
0
        public int Compress(byte[] source, int offset, int count, byte[] destination)
        {
            if (mCompressionMode != CompressionMode.Compress)
            {
                throw new BrotliException(
                          "The BrotliStream instance can not compress the buffer.");
            }

            int destinationLength = 0;

            int remainingBytes = count;
            int currentOffset  = offset;

            #region Process
            while (remainingBytes > 0)
            {
                int bytesToCopy = remainingBytes > BUFFER_SIZE
                    ? BUFFER_SIZE
                    : remainingBytes;

                Marshal.Copy(source, currentOffset, mPtrInputBuffer, bytesToCopy);
                remainingBytes -= bytesToCopy;
                currentOffset  += bytesToCopy;
                mAvailableIn    = (UInt32)bytesToCopy;
                mPtrNextInput   = mPtrInputBuffer;

                while (mAvailableIn > 0)
                {
                    uint totalOut = 0;

                    bool processedOk = Brolib.BrotliEncoderCompressStream(
                        mPtrState,
                        BrotliEncoderOperation.Process,
                        ref mAvailableIn,
                        ref mPtrNextInput,
                        ref mAvailableOut,
                        ref mPtrNextOutput,
                        out totalOut);

                    if (!processedOk)
                    {
                        throw new BrotliException("Could not compress the buffer.");
                    }

                    if (mAvailableOut == BUFFER_SIZE)
                    {
                        continue;
                    }

                    int bytesProcessed = (int)(BUFFER_SIZE - mAvailableOut);
                    Marshal.Copy(
                        mPtrOutputBuffer, destination, destinationLength, bytesProcessed);
                    destinationLength += bytesProcessed;
                    mAvailableOut      = BUFFER_SIZE;
                    mPtrNextOutput     = mPtrOutputBuffer;
                }

                if (Brolib.BrotliEncoderIsFinished(mPtrState))
                {
                    break;
                }
            }
            #endregion

            #region Finish
            while (true)
            {
                UInt32 totalOut     = 0;
                bool   compressedOk = Brolib.BrotliEncoderCompressStream(
                    mPtrState,
                    BrotliEncoderOperation.Finish,
                    ref mAvailableIn,
                    ref mPtrNextInput,
                    ref mAvailableOut,
                    ref mPtrNextOutput,
                    out totalOut);

                if (!compressedOk)
                {
                    throw new BrotliException("Unable to correctly compress the buffer");
                }

                bool extraData = mAvailableOut != BUFFER_SIZE;

                if (extraData)
                {
                    int bytesWritten = (int)(BUFFER_SIZE - mAvailableOut);
                    Marshal.Copy(mPtrOutputBuffer, destination, destinationLength, bytesWritten);
                    destinationLength += bytesWritten;
                    mAvailableOut      = BUFFER_SIZE;
                    mPtrNextOutput     = mPtrOutputBuffer;
                }

                if (Brolib.BrotliEncoderIsFinished(mPtrState) || !extraData)
                {
                    break;
                }
            }
            #endregion

            return(destinationLength);
        }