public void Zlib_Codec_TestLargeDeflateInflate() { int rc; int j; int bufferSize = 80000; byte[] compressedBytes = new byte[bufferSize]; byte[] workBuffer = new byte[bufferSize / 4]; ZlibCodec compressingStream = new ZlibCodec(); rc = compressingStream.InitializeDeflate(CompressionLevel.Level1); Assert.AreEqual<int>(ZlibConstants.Z_OK, rc, String.Format("at InitializeDeflate() [{0}]", compressingStream.Message)); compressingStream.OutputBuffer = compressedBytes; compressingStream.AvailableBytesOut = compressedBytes.Length; compressingStream.NextOut = 0; System.Random rnd = new Random(); for (int k = 0; k < 4; k++) { switch (k) { case 0: // At this point, workBuffer is all zeroes, so it should compress very well. break; case 1: // switch to no compression, keep same workBuffer (all zeroes): compressingStream.SetDeflateParams(CompressionLevel.None, CompressionStrategy.Default); break; case 2: // Insert data into workBuffer, and switch back to compressing mode. // we'll use lengths of the same random byte: for (int i = 0; i < workBuffer.Length / 1000; i++) { byte b = (byte)rnd.Next(); int n = 500 + rnd.Next(500); for (j = 0; j < n; j++) workBuffer[j + i] = b; i += j - 1; } compressingStream.SetDeflateParams(CompressionLevel.BestCompression, CompressionStrategy.Filtered); break; case 3: // insert totally random data into the workBuffer rnd.NextBytes(workBuffer); break; } compressingStream.InputBuffer = workBuffer; compressingStream.NextIn = 0; compressingStream.AvailableBytesIn = workBuffer.Length; rc = compressingStream.Deflate(FlushType.None); Assert.AreEqual<int>(ZlibConstants.Z_OK, rc, String.Format("at Deflate({0}) [{1}]", k, compressingStream.Message)); if (k == 0) Assert.AreEqual<int>(0, compressingStream.AvailableBytesIn, "Deflate should be greedy."); TestContext.WriteLine("Stage {0}: uncompressed/compresssed bytes so far: ({1,6}/{2,6})", k, compressingStream.TotalBytesIn, compressingStream.TotalBytesOut); } rc = compressingStream.Deflate(FlushType.Finish); Assert.AreEqual<int>(ZlibConstants.Z_STREAM_END, rc, String.Format("at Deflate() [{0}]", compressingStream.Message)); rc = compressingStream.EndDeflate(); Assert.AreEqual<int>(ZlibConstants.Z_OK, rc, String.Format("at EndDeflate() [{0}]", compressingStream.Message)); TestContext.WriteLine("Final: uncompressed/compressed bytes: ({0,6},{1,6})", compressingStream.TotalBytesIn, compressingStream.TotalBytesOut); ZlibCodec decompressingStream = new ZlibCodec(CompressionMode.Decompress); decompressingStream.InputBuffer = compressedBytes; decompressingStream.NextIn = 0; decompressingStream.AvailableBytesIn = bufferSize; // upon inflating, we overwrite the decompressedBytes buffer repeatedly int nCycles = 0; while (true) { decompressingStream.OutputBuffer = workBuffer; decompressingStream.NextOut = 0; decompressingStream.AvailableBytesOut = workBuffer.Length; rc = decompressingStream.Inflate(FlushType.None); nCycles++; if (rc == ZlibConstants.Z_STREAM_END) break; Assert.AreEqual<int>(ZlibConstants.Z_OK, rc, String.Format("at Inflate() [{0}] TotalBytesOut={1}", decompressingStream.Message, decompressingStream.TotalBytesOut)); } rc = decompressingStream.EndInflate(); Assert.AreEqual<int>(ZlibConstants.Z_OK, rc, String.Format("at EndInflate() [{0}]", decompressingStream.Message)); Assert.AreEqual<int>(4 * workBuffer.Length, (int)decompressingStream.TotalBytesOut); TestContext.WriteLine("compressed length: {0}", compressingStream.TotalBytesOut); TestContext.WriteLine("decompressed length (expected): {0}", 4 * workBuffer.Length); TestContext.WriteLine("decompressed length (actual) : {0}", decompressingStream.TotalBytesOut); TestContext.WriteLine("decompression cycles: {0}", nCycles); }