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 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; } } }
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]); } }