Exemple #1
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;
        }
Exemple #2
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);
        }
Exemple #3
0
        ///// <summary>Reads the variable length int. Work with assumption that value is in the stream
        ///// and throws exception if it isn't. If you want to check if value is in the stream
        ///// use <see cref="TryReadVarInt"/> instead.</summary>
        ///// <returns></returns>
        //ulong ReadVarInt(Stream stream)
        //{
        //    ulong result;
        //    if (!TryReadVarInt(stream, out result)) throw new EndOfStreamException();
        //    return result;
        //}
        ///// <summary>Tries to read variable length int.</summary>
        ///// <param name="result">The result.</param>
        ///// <returns><c>true</c> if integer has been read, <c>false</c> if end of stream has been
        ///// encountered. If end of stream has been encountered in the middle of value
        ///// <see cref="EndOfStreamException"/> is thrown.</returns>
        //bool TryReadVarInt(Stream stream, out ulong result)
        //{
        //    var buffer = new byte[1];
        //    var count = 0;
        //    result = 0;

        //    while (true)
        //    {
        //        if (stream.Read(buffer, 0, 1) == 0)
        //        {
        //            if (count == 0) return false;
        //            throw new EndOfStreamException();
        //        }
        //        var b = buffer[0];
        //        result = result + ((ulong)(b & 0x7F) << count);
        //        count += 7;
        //        if ((b & 0x80) == 0 || count >= 64) break;
        //    }

        //    return true;
        //}

        public LZ4HeaderChunkInfo ReadChunkHeader(Stream stream)
        {
            var info = new LZ4HeaderChunkInfo(stream);

            return(info);
        }