public void Write() { MemoryStream innerStream = new MemoryStream(); Stream transcodingStream = Encoding.CreateTranscodingStream( innerStream, innerStreamEncoding: ErrorCheckingUnicodeEncoding /* throws on error */, outerStreamEncoding: Encoding.UTF8 /* performs substition */, leaveOpen: true); // First, test Write(byte[], int, int) transcodingStream.Write(Encoding.UTF8.GetBytes("abcdefg"), 2, 3); Assert.Equal("cde", ErrorCheckingUnicodeEncoding.GetString(innerStream.ToArray())); // Then test WriteByte(byte) transcodingStream.WriteByte((byte)'z'); Assert.Equal("cdez", ErrorCheckingUnicodeEncoding.GetString(innerStream.ToArray())); // We'll write U+00E0 (utf-8: [C3 A0]) byte-by-byte. // We shouldn't flush any intermediate bytes. transcodingStream.WriteByte((byte)0xC3); Assert.Equal("cdez", ErrorCheckingUnicodeEncoding.GetString(innerStream.ToArray())); transcodingStream.WriteByte((byte)0xA0); Assert.Equal("cdez\u00E0", ErrorCheckingUnicodeEncoding.GetString(innerStream.ToArray())); innerStream.SetLength(0); // reset inner stream // Then test Write(ROS<byte>), once with a short string and once with a long string string asciiString = GetVeryLongAsciiString(128); byte[] asciiBytesAsUtf8 = Encoding.UTF8.GetBytes(asciiString); transcodingStream.Write(asciiBytesAsUtf8.AsSpan()); Assert.Equal(asciiString, ErrorCheckingUnicodeEncoding.GetString(innerStream.ToArray())); innerStream.SetLength(0); // reset inner stream asciiString = GetVeryLongAsciiString(16 * 1024 * 1024); asciiBytesAsUtf8 = Encoding.UTF8.GetBytes(asciiString); transcodingStream.Write(asciiBytesAsUtf8.AsSpan()); Assert.Equal(asciiString, ErrorCheckingUnicodeEncoding.GetString(innerStream.ToArray())); innerStream.SetLength(0); // reset inner stream // Close the outer stream and ensure no leftover data was written to the inner stream transcodingStream.Close(); Assert.Equal(0, innerStream.Position); }
public async Task WriteAsync() { MemoryStream sink = new MemoryStream(); CancellationToken expectedFlushAsyncCancellationToken = new CancellationTokenSource().Token; CancellationToken expectedWriteAsyncCancellationToken = new CancellationTokenSource().Token; var innerStreamMock = new Mock <Stream>(MockBehavior.Strict); innerStreamMock.Setup(o => o.CanWrite).Returns(true); innerStreamMock.Setup(o => o.WriteAsync(It.IsAny <ReadOnlyMemory <byte> >(), expectedWriteAsyncCancellationToken)) .Returns <ReadOnlyMemory <byte>, CancellationToken>(sink.WriteAsync); innerStreamMock.Setup(o => o.FlushAsync(expectedFlushAsyncCancellationToken)).Returns(Task.CompletedTask); Stream transcodingStream = Encoding.CreateTranscodingStream( innerStreamMock.Object, innerStreamEncoding: ErrorCheckingUnicodeEncoding, outerStreamEncoding: Encoding.UTF8 /* performs U+FFFD substition */, leaveOpen: true); // First, test WriteAsync(byte[], int, int, CancellationToken) await transcodingStream.WriteAsync(Encoding.UTF8.GetBytes("abcdefg"), 2, 3, expectedWriteAsyncCancellationToken); Assert.Equal("cde", ErrorCheckingUnicodeEncoding.GetString(sink.ToArray())); // We'll write U+00E0 (utf-8: [C3 A0]) byte-by-byte. // We shouldn't flush any intermediate bytes. await transcodingStream.WriteAsync(new byte[] { 0xC3, 0xA0 }, 0, 1, expectedWriteAsyncCancellationToken); await transcodingStream.FlushAsync(expectedFlushAsyncCancellationToken); Assert.Equal("cde", ErrorCheckingUnicodeEncoding.GetString(sink.ToArray())); await transcodingStream.WriteAsync(new byte[] { 0xC3, 0xA0 }, 1, 1, expectedWriteAsyncCancellationToken); Assert.Equal("cde\u00E0", ErrorCheckingUnicodeEncoding.GetString(sink.ToArray())); sink.SetLength(0); // reset sink // Then test WriteAsync(ROM<byte>, CancellationToken), once with a short string and once with a long string string asciiString = GetVeryLongAsciiString(128); byte[] asciiBytesAsUtf8 = Encoding.UTF8.GetBytes(asciiString); await transcodingStream.WriteAsync(asciiBytesAsUtf8.AsMemory(), expectedWriteAsyncCancellationToken); Assert.Equal(asciiString, ErrorCheckingUnicodeEncoding.GetString(sink.ToArray())); sink.SetLength(0); // reset sink asciiString = GetVeryLongAsciiString(16 * 1024 * 1024); asciiBytesAsUtf8 = Encoding.UTF8.GetBytes(asciiString); await transcodingStream.WriteAsync(asciiBytesAsUtf8.AsMemory(), expectedWriteAsyncCancellationToken); Assert.Equal(asciiString, ErrorCheckingUnicodeEncoding.GetString(sink.ToArray())); sink.SetLength(0); // reset sink // Close the outer stream and ensure no leftover data was written to the inner stream ValueTask actualDisposeTask = transcodingStream.DisposeAsync(); Assert.Equal(default(ValueTask), actualDisposeTask); // should've completed synchronously Assert.Equal(0, sink.Position); }