Example #1
0
        private async Task <bool> AcquireNextChunkAsync()
        {
            do
            {
                ulong?rawVarint = await TryReadVarIntAsync().ConfigureAwait(false);

                if (rawVarint == null)
                {
                    return(false);
                }

                ulong varint = rawVarint.Value;

                var flags        = (ChunkFlags)varint;
                var isCompressed = (flags & ChunkFlags.Compressed) != 0;

                var originalLength = (int) await ReadVarIntAync().ConfigureAwait(false);

                var compressedLength = isCompressed ? (int) await ReadVarIntAync().ConfigureAwait(false) : originalLength;

                if (compressedLength > originalLength)
                {
                    throw EndOfStream();                                    // corrupted
                }
                var compressed = new byte[compressedLength];
                var chunk      = await ReadBlockAsync(compressed, 0, compressedLength).ConfigureAwait(false);

                if (chunk != compressedLength)
                {
                    throw EndOfStream();                            // corrupted
                }
                if (!isCompressed)
                {
                    _buffer       = compressed; // no compression on this chunk
                    _bufferLength = compressedLength;
                }
                else
                {
                    if (_buffer == null || _buffer.Length < originalLength)
                    {
                        _buffer = new byte[originalLength];
                    }
                    var passes = (int)flags >> 2;
                    if (passes != 0)
                    {
                        throw new NotSupportedException("Chunks with multiple passes are not supported.");
                    }
                    LZ4Codec.Decode(compressed, 0, compressedLength, _buffer, 0, originalLength, true);
                    _bufferLength = originalLength;
                }

                _bufferOffset = 0;
            } while (_bufferLength == 0); // skip empty block (shouldn't happen but...)

            return(true);
        }
Example #2
0
        /// <summary>Flushes current chunk.</summary>
        private void FlushCurrentChunk()
        {
            if (_bufferOffset <= 0)
            {
                return;
            }

            var compressed       = new byte[_bufferOffset];
            var compressedLength = _highCompression
                                ? LZ4Codec.EncodeHC(_buffer, 0, _bufferOffset, compressed, 0, _bufferOffset)
                                : LZ4Codec.Encode(_buffer, 0, _bufferOffset, compressed, 0, _bufferOffset);

            if (compressedLength <= 0 || compressedLength >= _bufferOffset)
            {
                // incompressible block
                compressed       = _buffer;
                compressedLength = _bufferOffset;
            }

            var isCompressed = compressedLength < _bufferOffset;

            if (fileHeaderInfo == null)
            {
                fileHeaderInfo = new LZ4FileHeaderInfo();
                fileHeaderInfo.FrameDescriptor_BD_BlockMaxSize     = BlockMaximumSize.Block64K;
                fileHeaderInfo.FrameDescriptor_FLG_BChecksum       = false;
                fileHeaderInfo.FrameDescriptor_FLG_BIndependence   = true;
                fileHeaderInfo.FrameDescriptor_FLG_ContentChecksum = true;
                fileHeaderInfo.FrameDescriptor_FLG_ContentSize     = false;
                fileHeaderInfo.FrameDescriptor_FLG_Version         = 64;


                //U32 const xxh = XXH32(header, length, 0);
                //return (BYTE)(xxh >> 8);
                //    *dstPtr = LZ4F_headerChecksum(headerStart, dstPtr - headerStart);
                LZ4FileHeaderInfo.WriteHeader(_innerStream, fileHeaderInfo);
            }
            LZ4HeaderChunkInfo chunkInfo = new LZ4HeaderChunkInfo();

            chunkInfo.IsCompressed = true;
            chunkInfo.ChunkSize    = compressedLength;
            LZ4HeaderChunkInfo.WriteHeader(_innerStream, chunkInfo);

            _innerStream.Write(compressed, 0, compressedLength);

            _bufferOffset = 0;
        }
Example #3
0
        /// <summary>Reads the next chunk from stream.</summary>
        /// <returns><c>true</c> if next has been read, or <c>false</c> if it is legitimate end of file.
        /// Throws <see cref="EndOfStreamException"/> if end of stream was unexpected.</returns>
        private bool AcquireNextChunk()
        {
            do
            {
                if (fileHeaderInfo == null)
                {
                    fileHeaderInfo = _formatReader.ReadHeader(_innerStream);
                }
                if (blockInfo != null && blockInfo.ChunkSize <= 0)
                {
                    return(false);
                }
                blockInfo = _formatReader.ReadChunkHeader(_innerStream);
                int compressedLength = blockInfo.ChunkSize;
                if (compressedLength <= 0 || compressedLength > GetBufferSize(fileHeaderInfo.FrameDescriptor_BD_BlockMaxSize))
                {
                    return(false);
                }
                bool isCompressed = blockInfo.IsCompressed;
                var  compressed   = new byte[compressedLength];
                var  chunk        = ReadBlock(compressed, 0, compressedLength);
                if (chunk != compressedLength)
                {
                    throw EndOfStream();                            // corrupted
                }
                if (!isCompressed)
                {
                    _buffer       = compressed; // no compression on this chunk
                    _bufferLength = compressedLength;
                }
                else
                {
                    int bSize = GetBufferSize(fileHeaderInfo.FrameDescriptor_BD_BlockMaxSize);
                    if (_buffer == null)
                    {
                        _buffer = new byte[bSize];
                    }
                    _bufferLength = LZ4Codec.Decode(compressed, 0, compressedLength, _buffer, 0, bSize, false);
                }

                _bufferOffset = 0;
            } while (_bufferLength == 0); // skip empty block (shouldn't happen but...)

            return(true);
        }
Example #4
0
        private async Task FlushCurrentChunkAsync()
        {
            if (_bufferOffset <= 0)
            {
                return;
            }

            var compressed       = new byte[_bufferOffset];
            var compressedLength = _highCompression
                ? LZ4Codec.EncodeHC(_buffer, 0, _bufferOffset, compressed, 0, _bufferOffset)
                : LZ4Codec.Encode(_buffer, 0, _bufferOffset, compressed, 0, _bufferOffset);

            if (compressedLength <= 0 || compressedLength >= _bufferOffset)
            {
                // incompressible block
                compressed       = _buffer;
                compressedLength = _bufferOffset;
            }

            var isCompressed = compressedLength < _bufferOffset;

            var flags = ChunkFlags.None;

            if (isCompressed)
            {
                flags |= ChunkFlags.Compressed;
            }
            if (_highCompression)
            {
                flags |= ChunkFlags.HighCompression;
            }

            await WriteVarIntAsync((ulong)flags).ConfigureAwait(false);
            await WriteVarIntAsync((ulong)_bufferOffset).ConfigureAwait(false);

            if (isCompressed)
            {
                await WriteVarIntAsync((ulong)compressedLength).ConfigureAwait(false);
            }

            await _innerStream.WriteAsync(compressed, 0, compressedLength).ConfigureAwait(false);

            _bufferOffset = 0;
        }
Example #5
0
        /// <summary>Flushes current chunk.</summary>
        private void FlushCurrentChunk()
        {
            if (_bufferOffset <= 0)
            {
                return;
            }

            var compressed       = new byte[_bufferOffset];
            var compressedLength = _highCompression
                                ? LZ4Codec.EncodeHC(_buffer, 0, _bufferOffset, compressed, 0, _bufferOffset)
                                : LZ4Codec.Encode(_buffer, 0, _bufferOffset, compressed, 0, _bufferOffset);

            if (compressedLength <= 0 || compressedLength >= _bufferOffset)
            {
                // incompressible block
                compressed       = _buffer;
                compressedLength = _bufferOffset;
            }

            var isCompressed = compressedLength < _bufferOffset;

            var flags = ChunkFlags.None;

            if (isCompressed)
            {
                flags |= ChunkFlags.Compressed;
            }
            if (_highCompression)
            {
                flags |= ChunkFlags.HighCompression;
            }

            WriteVarInt((ulong)flags);
            WriteVarInt((ulong)_bufferOffset);
            if (isCompressed)
            {
                WriteVarInt((ulong)compressedLength);
            }

            _innerStream.Write(compressed, 0, compressedLength);

            _bufferOffset = 0;
        }