public void DecoderSinkShouldRejectExcessivelyLargeInput() { var input = new byte[] { 0, 1, 2, 3, 4, 5 }; var decoder = new HeatshrinkDecoder(1, Constants.MinWindowBits, Constants.MinWindowBits - 1); // Sink as much as will fit var res = decoder.Sink(input, out var count); Assert.AreEqual(DecoderSinkResult.Ok, res); Assert.AreEqual(1, count); // And now, no more should fit. res = decoder.Sink(input, count, input.Length - count, out count); Assert.AreEqual(DecoderSinkResult.Full, res); Assert.AreEqual(0, count); }
public void DecoderFinishShouldNoteWhenDoen() { var input = new byte[] { 0xb3, 0x5b, 0xed, 0xe0, 0x41, 0x00 }; // "foofoo" var output = new byte[7]; var decoder = new HeatshrinkDecoder(256, 7, 6); var sres = decoder.Sink(input, out var count); Assert.AreEqual(DecoderSinkResult.Ok, sres); var pres = decoder.Poll(output, out var outSz); Assert.AreEqual(DecoderPollResult.Empty, pres); Assert.AreEqual(6, outSz); Assert.AreEqual((byte)'f', output[0]); Assert.AreEqual((byte)'o', output[1]); Assert.AreEqual((byte)'o', output[2]); Assert.AreEqual((byte)'f', output[3]); Assert.AreEqual((byte)'o', output[4]); Assert.AreEqual((byte)'o', output[5]); var fres = decoder.Finish(); Assert.AreEqual(DecoderFinishResult.Done, fres); }
public void DataWithSimpleRepetitionShouldMatchWithAbsurdlyTinyBuffers() { var encoder = new HeatshrinkEncoder(8, 3); var decoder = new HeatshrinkDecoder(256, 8, 3); var input = Encoding.UTF8.GetBytes("abcabcdabcdeabcdefabcdefgabcdefgh"); var comp = new byte[60]; var decomp = new byte[60]; var log = false; if (log) { Helper.DumpBuf("input", input); } for (var i = 0; i < input.Length; ++i) { Assert.IsTrue(encoder.Sink(input, i, 1, out var count) >= 0); } Assert.AreEqual(EncoderFinishResult.More, encoder.Finish()); var packedCount = 0; do { Assert.IsTrue(encoder.Poll(comp, packedCount, 1, out var count) >= 0); packedCount += count; } while (encoder.Finish() == EncoderFinishResult.More); if (log) { Helper.DumpBuf("comp", comp, packedCount); } for (var i = 0; i < packedCount; ++i) { Assert.IsTrue(decoder.Sink(comp, i, 1, out var count) >= 0); } for (var i = 0; i < input.Length; ++i) { Assert.IsTrue(decoder.Poll(decomp, i, 1, out var count) >= 0); } if (log) { Helper.DumpBuf("decomp", decomp, input.Length); } for (var i = 0; i < input.Length; ++i) { Assert.AreEqual(input[i], decomp[i]); } }
public void DataWithoutDuplicationShouldMatchWithAbsurdlyTinyBuffer() { var encoder = new HeatshrinkEncoder(8, 3); var decoder = new HeatshrinkDecoder(256, 8, 3); var input = Enumerable.Range('a', 'z' - 'a' + 1).Select(c => (byte)c).ToArray(); var comp = new byte[60]; var decomp = new byte[60]; var log = false; if (log) { Helper.DumpBuf("input", input); } for (var i = 0; i < input.Length; ++i) { Assert.IsTrue(encoder.Sink(input, i, 1, out var count) >= 0); } Assert.AreEqual(EncoderFinishResult.More, encoder.Finish()); var packedCount = 0; do { Assert.IsTrue(encoder.Poll(comp, packedCount, 1, out var count) >= 0); packedCount += count; } while (encoder.Finish() == EncoderFinishResult.More); if (log) { Helper.DumpBuf("comp", comp, packedCount); } for (var i = 0; i < packedCount; ++i) { Assert.IsTrue(decoder.Sink(comp, i, 1, out var count) >= 0); } for (var i = 0; i < input.Length; ++i) { Assert.IsTrue(decoder.Poll(decomp, i, 1, out var count) >= 0); } if (log) { Helper.DumpBuf("decomp", decomp, input.Length); } for (var i = 0; i < input.Length; ++i) { Assert.AreEqual(input[i], decomp[i]); } }
public void DecoderPollShouldSuspendIfOutOfSpaceInOutputBufferDuringLiteralExpansion() { var input = new byte[] { 0xb3, 0x5b, 0xed, 0xe0, 0x40, 0x80 }; var output = new byte[1]; var decoder = new HeatshrinkDecoder(256, 7, 6); var sres = decoder.Sink(input, out var count); Assert.AreEqual(DecoderSinkResult.Ok, sres); var pres = decoder.Poll(output, out var outSz); Assert.AreEqual(DecoderPollResult.More, pres); Assert.AreEqual(1, outSz); Assert.AreEqual((byte)'f', output[0]); }
public void DecoderPollShouldExpandShortLiteral() { var input = new byte[] { 0xb3, 0x5b, 0xed, 0xe0 }; var output = new byte[4]; var decoder = new HeatshrinkDecoder(256, 7, 3); var sres = decoder.Sink(input, out var count); Assert.AreEqual(DecoderSinkResult.Ok, sres); var pres = decoder.Poll(output, out var outSz); Assert.AreEqual(DecoderPollResult.Empty, pres); Assert.AreEqual(3, outSz); Assert.AreEqual((byte)'f', output[0]); Assert.AreEqual((byte)'o', output[1]); Assert.AreEqual((byte)'o', output[2]); }
public void DecoderPollShouldSuspendIfOutOfSpaceInOutputBufferDuringBackrefExpansion() { var input = new byte[] { 0xb3, 0x5b, 0xed, 0xe0, 0x41, 0x00 }; // "foofoo" var output = new byte[4]; var decoder = new HeatshrinkDecoder(256, 7, 6); var sres = decoder.Sink(input, out var count); Assert.AreEqual(DecoderSinkResult.Ok, sres); var pres = decoder.Poll(output, out var outSz); Assert.AreEqual(DecoderPollResult.More, pres); Assert.AreEqual(4, outSz); Assert.AreEqual((byte)'f', output[0]); Assert.AreEqual((byte)'o', output[1]); Assert.AreEqual((byte)'o', output[2]); Assert.AreEqual((byte)'f', output[3]); }
public void DecoderPollShouldExpandShortSelfOverlappingBackref() { // "aaaaa" == (literal, 1), ('a'), (backref, 1 back, 4 bytes) var input = new byte[] { 0xb0, 0x80, 0x01, 0x80 }; var output = new byte[6]; var expected = new byte[] { (byte)'a', (byte)'a', (byte)'a', (byte)'a', (byte)'a' }; var decoder = new HeatshrinkDecoder(256, 8, 7); var sres = decoder.Sink(input, out var count); Assert.AreEqual(DecoderSinkResult.Ok, sres); decoder.Poll(output, out var outSz); Assert.AreEqual(expected.Length, outSz); for (int i = 0; i < expected.Length; ++i) { Assert.AreEqual(expected[i], output[i]); } }
public void DecoderPollShouldExpandShortLiteralAndBackref() { var input = new byte[] { 0xb3, 0x5b, 0xed, 0xe0, 0x41, 0x00 }; // "foofoo" var output = new byte[6]; var decoder = new HeatshrinkDecoder(256, 7, 6); var sres = decoder.Sink(input, out var count); Assert.AreEqual(DecoderSinkResult.Ok, sres); decoder.Poll(output, out var outSz); Assert.AreEqual(6, outSz); Assert.AreEqual((byte)'f', output[0]); Assert.AreEqual((byte)'o', output[1]); Assert.AreEqual((byte)'o', output[2]); Assert.AreEqual((byte)'f', output[3]); Assert.AreEqual((byte)'o', output[4]); Assert.AreEqual((byte)'o', output[5]); }
public void DecoderShouldNotGetStuckWithFinishYieldingMoreButZeroBytesOutputFromPoll() { var input = new byte[512]; for (var i = 0; i < 256; ++i) { input[i] = 0xff; } var decoder = new HeatshrinkDecoder(256, 8, 4); /* Confirm that no byte of trailing context can lead to * heatshrink_decoder_finish erroneously returning HSDR_FINISH_MORE * when heatshrink_decoder_poll will yield 0 bytes. * * Before 0.3.1, a final byte of 0xFF could potentially cause * this to happen, if at exactly the byte boundary. */ for (int b = 0; b < 256; ++b) { for (int i = 1; i < 512; ++i) { input[i] = (byte)b; decoder.Reset(); var output = new byte[1024]; var sres = decoder.Sink(input, out var count); Assert.AreEqual(DecoderSinkResult.Ok, sres); var pres = decoder.Poll(output, out var outSz); Assert.AreEqual(DecoderPollResult.Empty, pres); var fres = decoder.Finish(); Assert.AreEqual(DecoderFinishResult.Done, fres); input[i] = 0xff; } } }
public void DecoderPollShouldExpandShortLiteralAndBackrefWhenFedInputByteByByte() { var input = new byte[] { 0xb3, 0x5b, 0xed, 0xe0, 0x41, 0x00 }; // "foofoo" var output = new byte[7]; var decoder = new HeatshrinkDecoder(256, 7, 6); for (var i = 0; i < 6; ++i) { var sres = decoder.Sink(input, i, 1, out var count); Assert.AreEqual(DecoderSinkResult.Ok, sres); } var pres = decoder.Poll(output, out var outSz); Assert.AreEqual(DecoderPollResult.Empty, pres); Assert.AreEqual(6, outSz); Assert.AreEqual((byte)'f', output[0]); Assert.AreEqual((byte)'o', output[1]); Assert.AreEqual((byte)'o', output[2]); Assert.AreEqual((byte)'f', output[3]); Assert.AreEqual((byte)'o', output[4]); Assert.AreEqual((byte)'o', output[5]); }
internal static void CompressAndExpandAndCheck(byte[] input, ConfigInfo cfg) { var encoder = new HeatshrinkEncoder(cfg.WindowSz, cfg.LookaheadSz); var decoder = new HeatshrinkDecoder(cfg.DecoderInputBufferSize, cfg.WindowSz, cfg.LookaheadSz); var inputSize = input.Length; var compSz = inputSize + (inputSize / 2) + 4; var decompSz = inputSize + (inputSize / 2) + 4; var comp = new byte[compSz]; var decomp = new byte[decompSz]; if (cfg.LogLevel > 1) { Console.WriteLine("\n^^ COMPRESSING\n"); DumpBuf("input", input); } var sunk = 0; var polled = 0; while (sunk < inputSize) { var esres = encoder.Sink(input, sunk, inputSize - sunk, out var count); Assert.IsTrue(esres >= 0); sunk += count; if (cfg.LogLevel > 1) { Console.WriteLine($"^^ sunk {count}"); } if (sunk == inputSize) { Assert.AreEqual(EncoderFinishResult.More, encoder.Finish()); } EncoderPollResult pres; do { pres = encoder.Poll(comp, polled, compSz - polled, out count); Assert.IsTrue(pres >= 0); polled += count; if (cfg.LogLevel > 1) { Console.WriteLine($"^^ polled {count}"); } } while (pres == EncoderPollResult.More); Assert.AreEqual(EncoderPollResult.Empty, pres); if (polled >= compSz) { Assert.Fail("compression should never expand that much"); } if (sunk == inputSize) { Assert.AreEqual(EncoderFinishResult.Done, encoder.Finish()); } } if (cfg.LogLevel > 0) { Console.Write($"in: {inputSize}, compressed: {polled} "); } var compressedSize = polled; sunk = 0; polled = 0; if (cfg.LogLevel > 1) { Console.WriteLine("\n^^ DECOMPRESSING\n"); DumpBuf("comp", comp, compressedSize); } while (sunk < compressedSize) { Assert.IsTrue(decoder.Sink(comp, sunk, compressedSize - sunk, out var count) >= 0); sunk += count; if (cfg.LogLevel > 1) { Console.WriteLine($"^^ sunk {count}"); } if (sunk == compressedSize) { Assert.AreEqual(DecoderFinishResult.More, decoder.Finish()); } DecoderPollResult pres; do { pres = decoder.Poll(decomp, polled, decompSz - polled, out count); Assert.IsTrue(pres >= 0); Assert.IsTrue(count > 0); polled += count; if (cfg.LogLevel > 1) { Console.WriteLine($"^^ polled: {count}"); } } while (pres == DecoderPollResult.More); Assert.AreEqual(DecoderPollResult.Empty, pres); if (sunk == compressedSize) { var fres = decoder.Finish(); Assert.AreEqual(DecoderFinishResult.Done, fres); } if (polled > inputSize) { Console.WriteLine($"\nExpected: {inputSize}, got {polled}\n"); Assert.Fail("Decompressed data is larger than original input"); } } if (cfg.LogLevel > 0) { Console.WriteLine($"decompressed: {polled}"); } if (polled != inputSize) { Assert.Fail("Decompressed length does not match original input length"); } if (cfg.LogLevel > 1) { DumpBuf("decomp", decomp, polled); } for (var i = 0; i < inputSize; ++i) { if (input[i] != decomp[i]) { Console.WriteLine($"*** mismatch at {i}"); } Assert.AreEqual(input[i], decomp[i]); } }