예제 #1
0
        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"));
        }
예제 #2
0
        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);
        }
예제 #3
0
        public static void SizeTest(string inputFilePath)
        {
            Console.WriteLine("In size tests");
            for (int blockSize = 1024; blockSize <= 256 * 1024; blockSize *= 2)
            {
                string compressedFilePath = Path.ChangeExtension(inputFilePath, "." + blockSize.ToString() + ".compressed");
                using (Stream compressor = new CompressedWriteStream(File.Create(compressedFilePath), blockSize, false))
                    StreamUtilities.CopyFromFile(inputFilePath, compressor);

                double percent = 100.0 * (new FileInfo(compressedFilePath).Length) / (new FileInfo(inputFilePath).Length);
                Console.WriteLine("Blocksize " + blockSize.ToString().PadLeft(7) +
                                  " compression " + percent.ToString("f2") + "%. Placed in file " + compressedFilePath);
            }
        }
예제 #4
0
        public static void Tests()
        {
            string testOrig       = "text.orig";
            string testCompressed = "text.compressed";

            for (int fileSize = 1023; fileSize <= 1025; fileSize++)
            {
                CreateDataFile(testOrig, fileSize);
                FileStream origData = File.OpenRead(testOrig);

                // Try writing in various block sizes
                // TODO more sizes?
                for (int i = 1; i < 256; i += 37)
                {
                    CompressedWriteStream compressor = new CompressedWriteStream(File.Create(testCompressed), 64, false);
                    origData.Position = 0;
                    CopyInChunks(origData, compressor, i);
                    compressor.Close();

                    CompressedReadStream decompressor = new CompressedReadStream(testCompressed);
                    origData.Position = 0;
                    Debug.Assert(CompareStreams(origData, decompressor, 1024 * 16));
                    decompressor.Close();
                }

                CompressedReadStream lengthTest = new CompressedReadStream(testCompressed);
                Debug.Assert(lengthTest.Length == origData.Length);
                lengthTest.Close();

                // Try reading back in various seek positions.
                for (int blockSize = 20; blockSize < 300; blockSize += 47)
                {
                    CompressedReadStream decompressor = new CompressedReadStream(testCompressed);
                    for (int seekPosition = 0; seekPosition <= 1024; seekPosition += 16 * 3)
                    {
                        CompareStreams(origData, decompressor, blockSize, seekPosition);
                    }
                    decompressor.Close();
                }

                origData.Close();
            }
        }
예제 #5
0
        /// <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"));
        }
예제 #6
0
 public static void CompressFile(string inputFilePath, string compressedFilePath)
 {
     using (Stream compressor = new CompressedWriteStream(compressedFilePath))
         Utilities.StreamUtilities.CopyFromFile(inputFilePath, compressor);
 }
예제 #7
0
 public static void DecompressFile(string compressedFilePath, string outputFilePath)
 {
     using (Stream decompressor = new CompressedWriteStream(compressedFilePath))
         Utilities.StreamUtilities.CopyToFile(decompressor, outputFilePath);
 }