public void DestinationLength_too_small_but_retry___OK(bool isFinalBlock) { const int dataLength = 300; const int destLength = 350; var sut = new Base64Encoder(); Span <byte> data = new byte[dataLength]; Span <T> encoded = new T[destLength]; int requitedSize = sut.GetEncodedLength(dataLength); OperationStatus status = sut.EncodeCore(data, encoded, out int consumed, out int written, isFinalBlock); Assert.Multiple(() => { const int expectedConsumed = destLength / 4 * 3; const int expectedWritten = expectedConsumed / 3 * 4; Assert.AreEqual(OperationStatus.DestinationTooSmall, status); Assert.AreEqual(expectedConsumed, consumed); Assert.AreEqual(expectedWritten, written); }); data = data.Slice(consumed); encoded = new T[sut.GetEncodedLength(data.Length)]; status = sut.EncodeCore(data, encoded, out consumed, out written, isFinalBlock); Assert.AreEqual(OperationStatus.Done, status); Assert.AreEqual(data.Length, consumed); Assert.AreEqual(encoded.Length, written); }
public void SourceLength_is_0___0() { var sut = new Base64Encoder(); int actual = sut.GetEncodedLength(0); Assert.AreEqual(0, actual); }
public void Buffer_chain_various_length_encode() { var sut = new Base64Encoder(); var rnd = new Random(0); for (int i = 2; i < 200; ++i) { var data = new byte[i]; rnd.NextBytes(data); int encodedLength = sut.GetEncodedLength(data.Length); Span <T> encoded = new T[encodedLength]; int partialLength = data.Length / 2; OperationStatus status = sut.EncodeCore(data.AsSpan(0, partialLength), encoded, out int consumed, out int written1, isFinalBlock: false); Assert.AreEqual(partialLength % 3 == 0 ? OperationStatus.Done : OperationStatus.NeedMoreData, status, "fail at i = {0}", i); status = sut.EncodeCore(data.AsSpan(consumed), encoded.Slice(written1), out consumed, out int written2, isFinalBlock: true); Assert.AreEqual(OperationStatus.Done, status, "fail at i = {0}", i); Assert.AreEqual(encodedLength, written1 + written2, "fail at i = {0}", i); Span <T> expected = new T[encodedLength]; sut.EncodeCore(data, expected, out int _, out int _); string encodedText; string expectedText; if (typeof(T) == typeof(byte)) { Span <byte> encodedBytes = MemoryMarshal.AsBytes(encoded); Span <byte> expectedBytes = MemoryMarshal.AsBytes(expected); #if NETCOREAPP encodedText = Encoding.ASCII.GetString(encodedBytes); expectedText = Encoding.ASCII.GetString(expectedBytes); #else encodedText = Encoding.ASCII.GetString(encodedBytes.ToArray()); expectedText = Encoding.ASCII.GetString(expectedBytes.ToArray()); #endif } else if (typeof(T) == typeof(char)) { #if NETCOREAPP encodedText = new string(MemoryMarshal.Cast <T, char>(encoded)); expectedText = new string(MemoryMarshal.Cast <T, char>(expected)); #else encodedText = new string(MemoryMarshal.Cast <T, char>(encoded).ToArray()); expectedText = new string(MemoryMarshal.Cast <T, char>(expected).ToArray()); #endif } else { throw new NotSupportedException(); // just in case new types are introduced in the future } Assert.AreEqual(expectedText, encodedText, "fail at i = {0}", i); } }
public void Data_of_various_length_isFinalBlock_false() { var sut = new Base64Encoder(); var bytes = new byte[byte.MaxValue + 1]; for (int i = 0; i < bytes.Length; ++i) { bytes[i] = (byte)(255 - i); } for (int i = 0; i < 256; ++i) { Span <byte> source = bytes.AsSpan(0, i + 1); Span <T> encoded = new T[sut.GetEncodedLength(source.Length)]; OperationStatus status = sut.EncodeCore(source, encoded, out int consumed, out int written, isFinalBlock: false); OperationStatus expectedStatus = source.Length % 3 == 0 ? OperationStatus.Done : OperationStatus.NeedMoreData; int expectedConsumed = source.Length / 3 * 3; int expectedWritten = expectedConsumed / 3 * 4; Assert.AreEqual(expectedStatus, status, "fail at length = {0}", i + 1); Assert.AreEqual(expectedConsumed, consumed); Assert.AreEqual(expectedWritten, written); string encodedText; source = source.Slice(0, consumed); encoded = encoded.Slice(0, written); if (typeof(T) == typeof(byte)) { Span <byte> encodedBytes = MemoryMarshal.AsBytes(encoded); #if NETCOREAPP encodedText = Encoding.ASCII.GetString(encodedBytes); #else encodedText = Encoding.ASCII.GetString(encodedBytes.ToArray()); #endif } else if (typeof(T) == typeof(char)) { #if NETCOREAPP encodedText = new string(MemoryMarshal.Cast <T, char>(encoded)); #else encodedText = new string(MemoryMarshal.Cast <T, char>(encoded).ToArray()); #endif } else { throw new NotSupportedException(); // just in case new types are introduced in the future } #if NETCOREAPP string expected = Convert.ToBase64String(source); #else string expected = Convert.ToBase64String(source.ToArray()); #endif Assert.AreEqual(expected, encodedText); } }
public void Invalid_data_various_length___status_InvalidData() { var sut = new Base64Encoder(); var rnd = new Random(0); for (int i = 4; i < 200; ++i) { var data = new byte[i]; rnd.NextBytes(data); int encodedLength = sut.GetEncodedLength(data.Length); Span <T> encoded = new T[encodedLength]; OperationStatus status = sut.EncodeCore(data, encoded, out int consumed, out int written); Assume.That(status, Is.EqualTo(OperationStatus.Done)); Assume.That(consumed, Is.EqualTo(data.Length)); Assume.That(written, Is.EqualTo(encodedLength)); int decodedLength; if (typeof(T) == typeof(byte)) { Span <byte> tmp = MemoryMarshal.AsBytes(encoded); decodedLength = sut.GetDecodedLength(tmp); // Insert invalid data, just before eventual padding tmp[tmp.Length - 3] = (byte)'~'; } else if (typeof(T) == typeof(char)) { Span <char> tmp = MemoryMarshal.Cast <T, char>(encoded); decodedLength = sut.GetDecodedLength(tmp); // Insert invalid data, just before eventual padding tmp[tmp.Length - 3] = '~'; } else { throw new NotSupportedException(); // just in case new types are introduced in the future } Span <byte> decoded = new byte[decodedLength]; status = sut.DecodeCore <T>(encoded, decoded, out consumed, out written); // Invalid data is in the last 4 bytes, so everyting up to the last multiple of 4 is read. int expectedConsumed = (encoded.Length - 3) / 4 * 4; int expectedWritten = expectedConsumed / 4 * 3; Assert.Multiple(() => { Assert.AreEqual(OperationStatus.InvalidData, status); Assert.AreEqual(expectedConsumed, consumed, "Fail at i = {0}", i); Assert.AreEqual(expectedWritten, written, "Fail at i = {0}", i); }); } }
public void Basic_encoding_with_known_input_isFinalBlock_false(int numBytes, string expectedText, int expectedConsumed, int expectedWritten) { var sut = new Base64Encoder(); Span <byte> source = new byte[numBytes]; for (int i = 0; i < source.Length; ++i) { source[i] = (byte)(i + 1); } Span <T> encoded = new T[sut.GetEncodedLength(source.Length)]; OperationStatus status = sut.EncodeCore(source, encoded, out int consumed, out int written, isFinalBlock: false); OperationStatus expectedStatus = source.Length % 3 == 0 ? OperationStatus.Done : OperationStatus.NeedMoreData; Assert.Multiple(() => { Assert.AreEqual(expectedStatus, status); Assert.AreEqual(expectedConsumed, consumed); Assert.AreEqual(expectedWritten, written); }); string encodedText; source = source.Slice(0, consumed); encoded = encoded.Slice(0, written); if (typeof(T) == typeof(byte)) { Span <byte> encodedBytes = MemoryMarshal.AsBytes(encoded); #if NETCOREAPP encodedText = Encoding.ASCII.GetString(encodedBytes); #else encodedText = Encoding.ASCII.GetString(encodedBytes.ToArray()); #endif } else if (typeof(T) == typeof(char)) { #if NETCOREAPP encodedText = new string(MemoryMarshal.Cast <T, char>(encoded)); #else encodedText = new string(MemoryMarshal.Cast <T, char>(encoded).ToArray()); #endif } else { throw new NotSupportedException(); // just in case new types are introduced in the future } Assert.AreEqual(expectedText, encodedText); }
public void Empty_input() { var sut = new Base64Encoder(); ReadOnlySpan <byte> source = ReadOnlySpan <byte> .Empty; Span <T> encoded = new T[sut.GetEncodedLength(source.Length)]; OperationStatus status = sut.EncodeCore(source, encoded, out int consumed, out int written); Assert.AreEqual(OperationStatus.Done, status); Assert.AreEqual(0, consumed); Assert.AreEqual(0, written); Assert.IsTrue(encoded.IsEmpty); }
public void Guid___ssse3_event_fired() { var sut = new Base64Encoder(); var data = Guid.NewGuid().ToByteArray(); int encodedLength = sut.GetEncodedLength(data.Length); Span <T> encoded = new T[encodedLength]; bool ssse3Executed = false; Base64Encoder.Ssse3Encoded += (s, e) => ssse3Executed = true; OperationStatus status = sut.EncodeCore(data, encoded, out int consumed, out int written); Assert.IsTrue(ssse3Executed); }
public void Invalid_data_various_length___status_InvalidData() { var sut = new Base64Encoder(); var rnd = new Random(0); for (int i = 2; i < 200; ++i) { var data = new byte[i]; rnd.NextBytes(data); int encodedLength = sut.GetEncodedLength(data.Length); Span <T> encoded = new T[encodedLength]; OperationStatus status = sut.EncodeCore(data, encoded, out int consumed, out int written); Assume.That(status, Is.EqualTo(OperationStatus.Done)); Assume.That(consumed, Is.EqualTo(data.Length)); Assume.That(written, Is.EqualTo(encodedLength)); int decodedLength; if (typeof(T) == typeof(byte)) { Span <byte> tmp = MemoryMarshal.AsBytes(encoded); decodedLength = sut.GetDecodedLength(tmp); // Insert invalid data tmp[0] = (byte)'~'; } else if (typeof(T) == typeof(char)) { Span <char> tmp = MemoryMarshal.Cast <T, char>(encoded); decodedLength = sut.GetDecodedLength(tmp); // Insert invalid data tmp[0] = '~'; } else { throw new NotSupportedException(); // just in case new types are introduced in the future } Span <byte> decoded = new byte[decodedLength]; status = sut.DecodeCore <T>(encoded, decoded, out int _, out int _); Assert.AreEqual(OperationStatus.InvalidData, status); } }
public void SourceLength_1_to_50___correct_encoded_len() { var sut = new Base64Encoder(); Assert.Multiple(() => { for (int i = 1; i < 50; ++i) { var data = new byte[i]; string base64 = Convert.ToBase64String(data); int actual = sut.GetEncodedLength(i); Assert.AreEqual(base64.Length, actual); } }); }
public void Buffer_chain_various_length_decode() { var sut = new Base64Encoder(); var rnd = new Random(0); for (int i = 2; i < 200; ++i) { var data = new byte[i]; rnd.NextBytes(data); int encodedLength = sut.GetEncodedLength(data.Length); Span <T> encoded = new T[encodedLength]; OperationStatus status = sut.EncodeCore(data, encoded, out int consumed, out int written); Assume.That(status, Is.EqualTo(OperationStatus.Done), "fail at i = {0}", i); Assume.That(consumed, Is.EqualTo(data.Length), "fail at i = {0}", i); Assume.That(written, Is.EqualTo(encodedLength), "fail at i = {0}", i); int decodedLength; if (typeof(T) == typeof(byte)) { decodedLength = sut.GetDecodedLength(MemoryMarshal.AsBytes(encoded)); } else if (typeof(T) == typeof(char)) { decodedLength = sut.GetDecodedLength(MemoryMarshal.Cast <T, char>(encoded)); } else { throw new NotSupportedException(); // just in case new types are introduced in the future } Span <byte> decoded = new byte[decodedLength]; int partialLength = encoded.Length / 2; status = sut.DecodeCore <T>(encoded.Slice(0, partialLength), decoded, out consumed, out int written1, isFinalBlock: false); Assert.AreEqual(partialLength % 4 == 0 ? OperationStatus.Done : OperationStatus.NeedMoreData, status, "fail at i = {0}", i); status = sut.DecodeCore <T>(encoded.Slice(consumed), decoded.Slice(written1), out consumed, out int written2, isFinalBlock: true); Assert.AreEqual(OperationStatus.Done, status, "fail at i = {0}", i); Assert.AreEqual(decodedLength, written1 + written2, "fail at i = {0}", i); CollectionAssert.AreEqual(data, decoded.ToArray(), "fail at i = {0}", i); } }
public void Large_data___avx2_event_fired() { Assume.That(Avx2.IsSupported); var sut = new Base64Encoder(); var data = new byte[50]; var rnd = new Random(0); rnd.NextBytes(data); int encodedLength = sut.GetEncodedLength(data.Length); Span <T> encoded = new T[encodedLength]; OperationStatus status = sut.EncodeCore(data, encoded, out int consumed, out int written); Assume.That(status, Is.EqualTo(OperationStatus.Done)); Assume.That(consumed, Is.EqualTo(data.Length)); Assume.That(written, Is.EqualTo(encodedLength)); int decodedLength; if (typeof(T) == typeof(byte)) { decodedLength = sut.GetDecodedLength(MemoryMarshal.AsBytes(encoded)); } else if (typeof(T) == typeof(char)) { decodedLength = sut.GetDecodedLength(MemoryMarshal.Cast <T, char>(encoded)); } else { throw new NotSupportedException(); // just in case new types are introduced in the future } Span <byte> decoded = new byte[decodedLength]; bool avxExecuted = false; Base64Encoder.Avx2Decoded += (s, e) => avxExecuted = true; status = sut.DecodeCore <T>(encoded, decoded, out int _, out int _); Assume.That(status, Is.EqualTo(OperationStatus.Done)); Assert.IsTrue(avxExecuted); }
public void Large_data___avx2_event_fired() { Assume.That(Avx2.IsSupported); var sut = new Base64Encoder(); var data = new byte[50]; var rnd = new Random(); rnd.NextBytes(data); int encodedLength = sut.GetEncodedLength(data.Length); Span <T> encoded = new T[encodedLength]; bool avx2Executed = false; Base64Encoder.Avx2Encoded += (s, e) => avx2Executed = true; OperationStatus status = sut.EncodeCore(data, encoded, out int consumed, out int written); Assert.IsTrue(avx2Executed); }
public void Guid___ssse3_event_fired() { var sut = new Base64Encoder(); var data = Guid.NewGuid().ToByteArray(); int encodedLength = sut.GetEncodedLength(data.Length); Span <T> encoded = new T[encodedLength]; OperationStatus status = sut.EncodeCore(data, encoded, out int consumed, out int written); Assume.That(status, Is.EqualTo(OperationStatus.Done)); Assume.That(consumed, Is.EqualTo(data.Length)); Assume.That(written, Is.EqualTo(encodedLength)); int decodedLength; if (typeof(T) == typeof(byte)) { decodedLength = sut.GetDecodedLength(MemoryMarshal.AsBytes(encoded)); } else if (typeof(T) == typeof(char)) { decodedLength = sut.GetDecodedLength(MemoryMarshal.Cast <T, char>(encoded)); } else { throw new NotSupportedException(); // just in case new types are introduced in the future } Span <byte> decoded = new byte[decodedLength]; bool ssse3Executed = false; Base64Encoder.Ssse3Decoded += (s, e) => ssse3Executed = true; status = sut.DecodeCore <T>(encoded, decoded, out int _, out int _); Assume.That(status, Is.EqualTo(OperationStatus.Done)); Assert.IsTrue(ssse3Executed); }
public void Data_of_various_length___roundtrips_correclty() { var sut = new Base64Encoder(); var bytes = new byte[byte.MaxValue + 1]; for (int i = 0; i < bytes.Length; ++i) { bytes[i] = (byte)(255 - i); } for (int i = 0; i < 256; ++i) { Span <byte> source = bytes.AsSpan(0, i + 1); Span <T> encoded = new T[sut.GetEncodedLength(source.Length)]; OperationStatus status = sut.EncodeCore(source, encoded, out int consumed, out int written); Assert.AreEqual(OperationStatus.Done, status, nameof(status) + $" at i = {i}"); Assert.AreEqual(source.Length, consumed, nameof(consumed) + $" at i = {i}"); Assert.AreEqual(encoded.Length, written, nameof(written) + $" at i = {i}"); string encodedText; int decodedLength; if (typeof(T) == typeof(byte)) { Span <byte> encodedBytes = MemoryMarshal.AsBytes(encoded); #if NETCOREAPP encodedText = Encoding.ASCII.GetString(encodedBytes); #else encodedText = Encoding.ASCII.GetString(encodedBytes.ToArray()); #endif decodedLength = sut.GetDecodedLength(encodedBytes); } else if (typeof(T) == typeof(char)) { #if NETCOREAPP encodedText = new string(MemoryMarshal.Cast <T, char>(encoded)); #else encodedText = new string(MemoryMarshal.Cast <T, char>(encoded).ToArray()); #endif decodedLength = sut.GetDecodedLength(encodedText.AsSpan()); } else { throw new NotSupportedException(); // just in case new types are introduced in the future } #if NETCOREAPP string expectedText = Convert.ToBase64String(source); #else string expectedText = Convert.ToBase64String(source.ToArray()); #endif Assert.AreEqual(expectedText, encodedText); Span <byte> decoded = new byte[decodedLength]; status = sut.DecodeCore <T>(encoded, decoded, out consumed, out written); Assert.AreEqual(OperationStatus.Done, status); Assert.AreEqual(encoded.Length, consumed); Assert.AreEqual(decodedLength, written); CollectionAssert.AreEqual(source.ToArray(), decoded.ToArray()); } }
public void SourceLength_gt_MaximumEncodeLength___throws_ArgumentOutOfRange() { var sut = new Base64Encoder(); Assert.Throws <ArgumentOutOfRangeException>(() => sut.GetEncodedLength(Base64Encoder.MaximumEncodeLength + 1)); }
public void SourceLength_is_negative___throws_ArgumentOutOfRange() { var sut = new Base64Encoder(); Assert.Throws <ArgumentOutOfRangeException>(() => sut.GetEncodedLength(-1)); }
public int SourceLength_given___correct_encoded_length(int sourceLength) { var sut = new Base64Encoder(); return(sut.GetEncodedLength(sourceLength)); }