From: Stephen Toub Date: Thu, 5 Nov 2020 18:32:44 +0000 (-0500) Subject: Add stream conformance tests for TranscodingStream (#44248) X-Git-Tag: submit/tizen/20210909.063632~4754 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=82e503959082a0d5be4da9aa2d19d97101ddce0d;p=platform%2Fupstream%2Fdotnet%2Fruntime.git Add stream conformance tests for TranscodingStream (#44248) * Add stream conformance tests for TranscodingStream * Special-case 0-length input buffers to TranscodingStream.Write{Async} The base implementation of Encoder.Convert doesn't like empty inputs. Regardless, if the input is empty, we can avoid a whole bunch of unnecessary work. --- diff --git a/src/libraries/System.Private.CoreLib/src/System/Text/TranscodingStream.cs b/src/libraries/System.Private.CoreLib/src/System/Text/TranscodingStream.cs index 4bc5f5f..71a8d4b 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Text/TranscodingStream.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Text/TranscodingStream.cs @@ -459,6 +459,11 @@ namespace System.Text { EnsurePreWriteConditions(); + if (buffer.IsEmpty) + { + return; + } + int rentalLength = Math.Clamp(buffer.Length, MinWriteRentedArraySize, MaxWriteRentedArraySize); char[] scratchChars = ArrayPool.Shared.Rent(rentalLength); @@ -527,6 +532,11 @@ namespace System.Text return ValueTask.FromCanceled(cancellationToken); } + if (buffer.IsEmpty) + { + return ValueTask.CompletedTask; + } + return WriteAsyncCore(buffer, cancellationToken); async ValueTask WriteAsyncCore(ReadOnlyMemory remainingOuterEncodedBytes, CancellationToken cancellationToken) { diff --git a/src/libraries/System.Text.Encoding/tests/Encoding/TranscodingStreamTests.cs b/src/libraries/System.Text.Encoding/tests/Encoding/TranscodingStreamTests.cs index 5eb16c1..c937793 100644 --- a/src/libraries/System.Text.Encoding/tests/Encoding/TranscodingStreamTests.cs +++ b/src/libraries/System.Text.Encoding/tests/Encoding/TranscodingStreamTests.cs @@ -2,7 +2,9 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Generic; +using System.Diagnostics; using System.IO; +using System.IO.Tests; using System.Threading; using System.Threading.Tasks; using Moq; @@ -10,8 +12,20 @@ using Xunit; namespace System.Text.Tests { - public class TranscodingStreamTests + public class TranscodingStreamTests : ConnectedStreamConformanceTests { + protected override bool FlushRequiredToWriteData => true; + protected override bool FlushGuaranteesAllDataWritten => false; + protected override bool BlocksOnZeroByteReads => true; + + protected override Task CreateConnectedStreamsAsync() + { + (Stream stream1, Stream stream2) = ConnectedStreams.CreateBidirectional(); + return Task.FromResult( + (Encoding.CreateTranscodingStream(stream1, new IdentityEncoding(), new IdentityEncoding()), + Encoding.CreateTranscodingStream(stream2, new IdentityEncoding(), new IdentityEncoding()))); + } + public static IEnumerable ReadWriteTestBufferLengths { get @@ -668,7 +682,7 @@ namespace System.Text.Tests } [Fact] - public async Task WriteAsync() + public async Task WriteAsync_WithFullData() { MemoryStream sink = new MemoryStream(); CancellationToken expectedFlushAsyncCancellationToken = new CancellationTokenSource().Token; @@ -892,5 +906,41 @@ namespace System.Text.Tests } } } + + /// A custom encoding that's used to roundtrip from bytes to bytes through a string. + private sealed class IdentityEncoding : Encoding + { + public override int GetByteCount(char[] chars, int index, int count) => count; + + public override int GetBytes(char[] chars, int charIndex, int charCount, byte[] bytes, int byteIndex) + { + Span span = chars.AsSpan(charIndex, charCount); + for (int i = 0; i < span.Length; i++) + { + Debug.Assert(span[i] <= 0xFF); + bytes[byteIndex + i] = (byte)span[i]; + } + return charCount; + } + + public override int GetCharCount(byte[] bytes, int index, int count) => count; + + public override int GetChars(byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex) + { + Span span = bytes.AsSpan(byteIndex, byteCount); + for (int i = 0; i < span.Length; i++) + { + Debug.Assert(span[i] <= 0xFF); + chars[charIndex + i] = (char)span[i]; + } + return byteCount; + } + + public override int GetMaxByteCount(int charCount) => charCount; + + public override int GetMaxCharCount(int byteCount) => byteCount; + + public override byte[] GetPreamble() => Array.Empty(); + } } } diff --git a/src/libraries/System.Text.Encoding/tests/System.Text.Encoding.Tests.csproj b/src/libraries/System.Text.Encoding/tests/System.Text.Encoding.Tests.csproj index 78c22e0..74bcfdc 100644 --- a/src/libraries/System.Text.Encoding/tests/System.Text.Encoding.Tests.csproj +++ b/src/libraries/System.Text.Encoding/tests/System.Text.Encoding.Tests.csproj @@ -79,6 +79,12 @@ + + + + + +