private void WriteBlockEntries(BinaryWriter writer, MemoryStream blockStream, bool flushAllData, byte[] compressorBufferCache) { int dataRemainder = 0; int readPosition = 0; while (true) { dataRemainder = (int)Math.Min(blockStream.Length - readPosition, WriterBlockSizeThreshold); if (dataRemainder == 0 || (dataRemainder < WriterBlockSizeThreshold && !flushAllData)) { break; } var blockEntry = new BlockEntry() { DecompressedOffset = WriterDecompressedBlockOffset, DecompressedSize = (uint)dataRemainder, Offset = (ulong)writer.BaseStream.Position, }; // Compress long compressedSize = Utility.OodleLZ.Compress(blockStream.GetBuffer().AsSpan().Slice(readPosition, dataRemainder), compressorBufferCache); if (compressedSize == -1) { throw new Exception("Buffer compression failed"); } blockEntry.Size = (uint)compressedSize; // Encrypt if (Header.IsEncrypted) { blockEntry.XorDataBuffer(compressorBufferCache); } // Write to disk writer.Write(compressorBufferCache, 0, (int)blockEntry.Size); WriterDecompressedBlockOffset += blockEntry.DecompressedSize; readPosition += dataRemainder; BlockEntries.Add(blockEntry); } // Free MemoryStream data that was already written to prevent excessive memory consumption if (readPosition > 0 && dataRemainder > 0) { Buffer.BlockCopy(blockStream.GetBuffer(), readPosition, blockStream.GetBuffer(), 0, dataRemainder); blockStream.SetLength(blockStream.Length - readPosition); } }
private void WriteBlockEntries(BinaryWriter writer, ConcurrentBag <CompressBlock> blocks) { foreach (var block in blocks.OrderBy(x => x.DecompressedOffset)) { var blockEntry = new BlockEntry() { DecompressedOffset = block.DecompressedOffset, DecompressedSize = block.DecompressedSize, Offset = (ulong)writer.BaseStream.Position, Size = block.Size }; // Encrypt if (Header.IsEncrypted) { blockEntry.XorDataBuffer(block.CompressBuffer); } // Write to disk writer.Write(block.CompressBuffer, 0, (int)blockEntry.Size); BlockEntries.Add(blockEntry); } }