private void FlushBlock(bool lastBlock) { compressor.Dispose(); int compressedBlockSize = (int)outputBuffer.Length; Debug.Assert(spaceLeftInBlock == 0 || lastBlock); CompressedWriteStream.LogLine("FlushBlock: lastBlock " + lastBlock + " compressedBlockSize = 0x" + compressedBlockSize.ToString("x") + " uncompresseSize=0x" + (blockSize - spaceLeftInBlock).ToString("x")); CompressedWriteStream.LogLine("Block header placed at filePosition=0x" + outputStream.Position.ToString("x")); // Write the block out prepended with its blockSize if (lastBlock) { WriteInt(outputStream, -compressedBlockSize); WriteInt(outputStream, blockSize - spaceLeftInBlock); // write the uncompressed blockSize too. } else { compressedBlockSizes.Add(compressedBlockSize); WriteInt(outputStream, compressedBlockSize); } outputStream.Write(outputBuffer.GetBuffer(), 0, compressedBlockSize); // TODO remove outputStream.Write(new byte[compressedBlockSize], 0, compressedBlockSize); CompressedWriteStream.LogLine("After write, filePosition=0x" + outputStream.Position.ToString("x")); }
protected override void Dispose(bool disposing) { if (!disposing) { int lastBlockByteCount = blockSize - spaceLeftInBlock; // Write out the last block FlushBlock(true); // Write out the table of block sizes (to allow for efficient arbitrary seeking). CompressedWriteStream.LogLine("Writing offset table starting at 0x" + outputStream.Position.ToString("x")); long blockOffset = positionOfFirstBlock; foreach (int compressedBlockSize in compressedBlockSizes) { WriteLong(outputStream, blockOffset); blockOffset += (compressedBlockSize + 4); // Add the total blockSize (with header) of the previous block } WriteLong(outputStream, blockOffset); CompressedWriteStream.LogLine("Writing offset table count " + (compressedBlockSizes.Count + 1) + " uncompressed Left = 0x" + lastBlockByteCount.ToString("x")); // remember the count of the table. WriteInt(outputStream, compressedBlockSizes.Count + 1); // and the number of uncompressed bytes in the last block WriteInt(outputStream, lastBlockByteCount); if (!leaveOpen) { outputStream.Dispose(); } } base.Dispose(disposing); }
/// <summary> /// Initializes the current block to point at the begining of the block (a block is the length as /// well as the data) that starts at the uncompressed location 'uncompressedBlockStart' which as the /// cooresponding compressed location 'compressedBlockStart'. /// </summary> private void FillBlock(long uncompressedBlockStart, long compressedBlockStart) { CompressedWriteStream.LogLine("FillBlock: uncompressedBlockStart 0x" + uncompressedBlockStart.ToString("x") + " compressedBlockStart 0x" + compressedBlockStart.ToString("x")); // Advance the uncompressed position uncompressedBlockStartPosition = uncompressedBlockStart; // and set the compressed stream to just past this block's data compressedData.Position = compressedBlockStart; // Read in the next block' blockSize (both compressed and uncompressed) uncompressedBlockSize = maxUncompressedBlockSize; int compressedBlockSize = ReadInt(compressedData); lastBlock = false; if (compressedBlockSize < 0) { compressedBlockSize = -compressedBlockSize; uncompressedBlockSize = ReadInt(compressedData); lastBlock = true; } Debug.Assert(compressedBlockSize <= maxUncompressedBlockSize * 3); // I have never seen expansion more than 2X Debug.Assert(uncompressedBlockSize <= maxUncompressedBlockSize); if (decompressor != null) { decompressor.Dispose(); } // Get next clump of data. decompressor = new DeflateStream(compressedData, CompressionMode.Decompress, true); // Set the uncompressed and compressed data pointers. uncompressedDataLeft = uncompressedBlockSize; nextCompressedBlockStartPosition = compressedData.Position + compressedBlockSize; CompressedWriteStream.LogLine("FillBlock compressedBlockSize = 0x" + compressedBlockSize.ToString("x") + " lastblock = " + lastBlock); CompressedWriteStream.LogLine("FillBlock: DONE: uncompressedDataLeft 0x" + uncompressedDataLeft.ToString("x") + " nextCompressedBlockStartPosition 0x" + nextCompressedBlockStartPosition.ToString("x")); }