public override void Flush() { var maxCompressedSize = LZ4Codec.MaximumOutputLength(_uncompressedBuffer.Length); if (_compressedBuffer == null || _compressedBuffer.Length < maxCompressedSize) { _compressedBuffer = new byte[maxCompressedSize]; } var compressedSize = LZ4Codec.Encode(_uncompressedBuffer, 0, _bufferLen, _compressedBuffer, 0, _compressedBuffer.Length); if (compressedSize >= _bufferLen) { // Lz4 allows to write non-compressed block. // Reuse _ncompressedBuffer which is not needed anymore to serialize block size LittleEndianConverter.Write((uint)(_bufferLen | 1 << 31), _compressedBuffer, 0); // highest bit set indicates no compression _base.Write(_compressedBuffer, 0, 4); _base.Write(_uncompressedBuffer, 0, _bufferLen); } else { LittleEndianConverter.Write((uint)compressedSize, _uncompressedBuffer, 0); _base.Write(_uncompressedBuffer, 0, 4); _base.Write(_compressedBuffer, 0, compressedSize); } _bufferLen = 0; }
// TODO: for optimization, hardcode the whole header as static array static byte[] CreateHeader() { var buff = new byte[4 + 3]; LittleEndianConverter.Write(MAGIC, buff, 0); // Version 1; Block Independence var flags = 1 << 6 | 1 << 5; //96; // TODO: make lz4 block size configurable // Block size 64Kb var bd = 1 << 6; //64; buff[4] = (byte)flags; buff[5] = (byte)bd; var hasher = new xxHash(); hasher.Init(); hasher.Update(buff, 6); var checksum = hasher.Digest() >> 8 & 0xff; // 26 buff[6] = (byte)checksum; return(buff); }