public void EncoderPollShouldDetectRepeatedSubstringAndPreserveTrailingLiteral() { var encoder = new HeatshrinkEncoder(8, 3); var input = new byte[] { (byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e' }; var output = new byte[1024]; var expected = new byte[] { 0xb0, 0xd8, 0xac, 0x76, 0x40, 0x1b, 0xb2, 0x80 }; var sres = encoder.Sink(input, out var copied); Assert.AreEqual(EncoderSinkResult.Ok, sres); Assert.AreEqual(input.Length, copied); var fres = encoder.Finish(); Assert.AreEqual(EncoderFinishResult.More, fres); Assert.AreEqual(EncoderPollResult.Empty, encoder.Poll(output, out copied)); fres = encoder.Finish(); Assert.AreEqual(EncoderFinishResult.Done, fres); Assert.AreEqual(expected.Length, copied); for (int i = 0; i < expected.Length; ++i) { Assert.AreEqual(expected[i], output[i]); } }
public void EncoderSinkShouldAcceptPartialInputWhenSomeWillFit() { var encoder = new HeatshrinkEncoder(8, 7); var input = Enumerable.Repeat('*', 512).Select(c => (byte)c).ToArray(); Assert.AreEqual(EncoderSinkResult.Ok, encoder.Sink(input, out var bytesCopied)); Assert.AreEqual(256, bytesCopied); }
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 Gen() { var encoder = new HeatshrinkEncoder(8, 7); var input = new byte[] { (byte)'a', (byte)'a', (byte)'a', (byte)'a', (byte)'a' }; var output = new byte[1024]; var sres = encoder.Sink(input, out var copied); Assert.AreEqual(EncoderSinkResult.Ok, sres); Assert.AreEqual(input.Length, copied); var fres = encoder.Finish(); Assert.AreEqual(EncoderFinishResult.More, fres); Assert.AreEqual(EncoderPollResult.Empty, encoder.Poll(output, out copied)); fres = encoder.Finish(); Assert.AreEqual(EncoderFinishResult.Done, fres); }
public void EncoderShouldEmitDataWithoutRepetitionsAsLiteralSequence() { var encoder = new HeatshrinkEncoder(8, 7); var input = new byte[5]; var output = new byte[1024]; var expected = new byte[] { 0x80, 0x40, 0x60, 0x50, 0x38, 0x20 }; for (int i = 0; i < 5; ++i) { input[i] = (byte)i; } Assert.AreEqual(EncoderSinkResult.Ok, encoder.Sink(input, out var copied)); Assert.AreEqual(5, copied); // Should get no output yet, since encoder doesn't know input is complete. var pres = encoder.Poll(output, out copied); Assert.AreEqual(EncoderPollResult.Empty, pres); Assert.AreEqual(0, copied); // Mark input stream as done, to force small input to be processed. var fres = encoder.Finish(); Assert.AreEqual(EncoderFinishResult.More, fres); pres = encoder.Poll(output, out copied); Assert.AreEqual(EncoderPollResult.Empty, pres); for (int i = 0; i < expected.Length; ++i) { Assert.AreEqual(expected[i], output[i]); } Assert.AreEqual(EncoderFinishResult.Done, encoder.Finish()); }
public void EncoderShouldEmitSeriesOfSameByteAsLiteralThenBackRef() { var encoder = new HeatshrinkEncoder(8, 7); var input = new byte[5]; var output = new byte[1024]; var expected = new byte[] { 0xb0, 0x80, 0x01, 0x80 }; for (int i = 0; i < 5; ++i) { input[i] = (byte)'a'; // "aaaaa"; } Assert.AreEqual(EncoderSinkResult.Ok, encoder.Sink(input, out var copied)); Assert.AreEqual(5, copied); // Should get no output yet, since encoder doesn't know input is complete. var pres = encoder.Poll(output, out copied); Assert.AreEqual(EncoderPollResult.Empty, pres); Assert.AreEqual(0, copied); // Mark input stream as done, to force small input to be processed. var fres = encoder.Finish(); Assert.AreEqual(EncoderFinishResult.More, fres); pres = encoder.Poll(output, out copied); Assert.AreEqual(EncoderPollResult.Empty, pres); Assert.AreEqual(4, copied); for (int i = 0; i < copied; ++i) { Assert.AreEqual(expected[i], output[i]); } Assert.AreEqual(EncoderFinishResult.Done, encoder.Finish()); }
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]); } }