示例#1
0
        public DecompressedData Decompress(byte[] data, int offset, int count, bool forceDecompress = false, bool dataCanBeLarger = false)
        {
            if (decompressorInputStream == null)
            {
                decompressorInputStream = new BufferPoolMemoryStream(count);
            }

            if (data != null)
            {
                decompressorInputStream.Write(data, offset, count);
            }

            if (!forceDecompress && decompressorInputStream.Length < MinLengthToDecompress)
            {
                return(new DecompressedData(null, 0));
            }

            decompressorInputStream.Position = 0;

            if (decompressorGZipStream == null)
            {
                decompressorGZipStream = new Zlib.GZipStream(decompressorInputStream,
                                                             Zlib.CompressionMode.Decompress,
                                                             Zlib.CompressionLevel.Default,
                                                             true);
                decompressorGZipStream.FlushMode = Zlib.FlushType.Sync;
            }

            if (decompressorOutputStream == null)
            {
                decompressorOutputStream = new BufferPoolMemoryStream();
            }
            decompressorOutputStream.SetLength(0);

            byte[] copyBuffer = BufferPool.Get(1024, true);

            int readCount;
            int sumReadCount = 0;

            while ((readCount = decompressorGZipStream.Read(copyBuffer, 0, copyBuffer.Length)) != 0)
            {
                decompressorOutputStream.Write(copyBuffer, 0, readCount);
                sumReadCount += readCount;
            }

            BufferPool.Release(copyBuffer);

            // If no read is done (returned with any data) don't zero out the input stream, as it would delete any not yet used data.
            if (sumReadCount > 0)
            {
                decompressorGZipStream.SetLength(0);
            }

            byte[] result = decompressorOutputStream.ToArray(dataCanBeLarger);

            return(new DecompressedData(result, dataCanBeLarger ? (int)decompressorOutputStream.Length : result.Length));
        }
        private byte[] Decompress(byte[] data, int offset, int count, bool forceDecompress = false)
        {
            if (decompressorInputStream == null)
            {
                decompressorInputStream = new BufferPoolMemoryStream(count);
            }

            if (data != null)
            {
                decompressorInputStream.Write(data, offset, count);
            }

            if (!forceDecompress && decompressorInputStream.Length < MinLengthToDecompress)
            {
                return(null);
            }

            decompressorInputStream.Position = 0;

            if (decompressorGZipStream == null)
            {
                decompressorGZipStream = new Decompression.Zlib.GZipStream(decompressorInputStream,
                                                                           Decompression.Zlib.CompressionMode.Decompress,
                                                                           Decompression.Zlib.CompressionLevel.Default,
                                                                           true);
                decompressorGZipStream.FlushMode = Decompression.Zlib.FlushType.Sync;
            }

            if (decompressorOutputStream == null)
            {
                decompressorOutputStream = new BufferPoolMemoryStream();
            }
            decompressorOutputStream.SetLength(0);

            byte[] copyBuffer = VariableSizedBufferPool.Get(1024, true);

            int readCount;

            while ((readCount = decompressorGZipStream.Read(copyBuffer, 0, copyBuffer.Length)) != 0)
            {
                decompressorOutputStream.Write(copyBuffer, 0, readCount);
            }

            VariableSizedBufferPool.Release(copyBuffer);

            decompressorGZipStream.SetLength(0);

            // TODO: be able to use a larger array
            byte[] result = decompressorOutputStream.ToArray();

            return(result);
        }
示例#3
0
        /// <summary>
        /// A function to compress and return the data parameter with possible context takeover support (reusing the DeflateStream).
        /// </summary>
        private byte[] Compress(byte[] data, int length)
        {
            if (compressorOutputStream == null)
            {
                compressorOutputStream = new BufferPoolMemoryStream();
            }
            compressorOutputStream.SetLength(0);

            if (compressorDeflateStream == null)
            {
                compressorDeflateStream           = new DeflateStream(compressorOutputStream, CompressionMode.Compress, this.Level, true, this.ClientMaxWindowBits);
                compressorDeflateStream.FlushMode = FlushType.Sync;
            }

            byte[] result = null;
            try
            {
                compressorDeflateStream.Write(data, 0, length);
                compressorDeflateStream.Flush();

                compressorOutputStream.Position = 0;

                // http://tools.ietf.org/html/rfc7692#section-7.2.1
                // Remove 4 octets (that are 0x00 0x00 0xff 0xff) from the tail end. After this step, the last octet of the compressed data contains (possibly part of) the DEFLATE header bits with the "BTYPE" bits set to 00.
                compressorOutputStream.SetLength(compressorOutputStream.Length - 4);

                result = compressorOutputStream.ToArray();
            }
            finally
            {
                if (this.ClientNoContextTakeover)
                {
                    compressorDeflateStream.Dispose();
                    compressorDeflateStream = null;
                }
            }

            return(result);
        }
示例#4
0
        /// <summary>
        /// A function to decompress and return the data parameter with possible context takeover support (reusing the DeflateStream).
        /// </summary>
        private byte[] Decompress(byte[] data, int length)
        {
            if (decompressorInputStream == null)
            {
                decompressorInputStream = new BufferPoolMemoryStream(length + 4);
            }

            decompressorInputStream.Write(data, 0, length);

            // http://tools.ietf.org/html/rfc7692#section-7.2.2
            // Append 4 octets of 0x00 0x00 0xff 0xff to the tail end of the payload of the message.
            decompressorInputStream.Write(PerMessageCompression.Trailer, 0, PerMessageCompression.Trailer.Length);

            decompressorInputStream.Position = 0;

            if (decompressorDeflateStream == null)
            {
                decompressorDeflateStream           = new DeflateStream(decompressorInputStream, CompressionMode.Decompress, CompressionLevel.Default, true, this.ServerMaxWindowBits);
                decompressorDeflateStream.FlushMode = FlushType.Sync;
            }

            if (decompressorOutputStream == null)
            {
                decompressorOutputStream = new BufferPoolMemoryStream();
            }
            decompressorOutputStream.SetLength(0);

            byte[] copyBuffer = BufferPool.Get(1024, true);
            int    readCount;

            while ((readCount = decompressorDeflateStream.Read(copyBuffer, 0, copyBuffer.Length)) != 0)
            {
                decompressorOutputStream.Write(copyBuffer, 0, readCount);
            }

            BufferPool.Release(copyBuffer);

            decompressorDeflateStream.SetLength(0);

            byte[] result = decompressorOutputStream.ToArray();

            if (this.ServerNoContextTakeover)
            {
                decompressorDeflateStream.Dispose();
                decompressorDeflateStream = null;
            }

            return(result);
        }