From cbaad9af8fea82cde8684f423c750e233efdc27d Mon Sep 17 00:00:00 2001 From: Vance Morrison Date: Thu, 14 Jun 2018 09:06:08 -0700 Subject: [PATCH] Write and WriteAsync overloads for StringBuilder. (dotnet/coreclr#18281) * Write and WriteAsync overloads for StringBuilder. Addresses issue https://github.com/dotnet/corefx/issues/30048 Note that tests will come as a separate checking as part of the coreFX repo. * Review feedback * Review feedback * Added WriteLine(StringBuilder overloads (review feedback) * review feedback * Fix configureAwait * bug fix * Bug fix * review feedback Commit migrated from https://github.com/dotnet/coreclr/commit/fb8d7b863365457a11da270d6950c16c082635df --- .../src/System/IO/TextWriter.cs | 78 ++++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/src/libraries/System.Private.CoreLib/src/System/IO/TextWriter.cs b/src/libraries/System.Private.CoreLib/src/System/IO/TextWriter.cs index 2afe907..22a8cd6 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IO/TextWriter.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IO/TextWriter.cs @@ -283,6 +283,21 @@ namespace System.IO } } + /// + /// Equivalent to Write(stringBuilder.ToString()) however it uses the + /// StringBuilder.GetChunks() method to avoid creating the intermediate string + /// + /// The string (as a StringBuilder) to write to the stream + public virtual void Write(StringBuilder value) + { + if (value == null) + { + throw new ArgumentNullException(nameof(value)); + } + foreach (ReadOnlyMemory chunk in value.GetChunks()) + Write(chunk); + } + // Writes out a formatted string. Uses the same semantics as // String.Format. // @@ -447,6 +462,16 @@ namespace System.IO Write(CoreNewLineStr); } + /// + /// Equivalent to WriteLine(stringBuilder.ToString()) however it uses the + /// StringBuilder.GetChunks() method to avoid creating the intermediate string + /// + public virtual void WriteLine(StringBuilder value) + { + Write(value); + WriteLine(); + } + // Writes the text representation of an object followed by a line // terminator to the text stream. // @@ -527,6 +552,28 @@ namespace System.IO tuple, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default); } + /// + /// Equivalent to WriteAsync(stringBuilder.ToString()) however it uses the + /// StringBuilder.GetChunks() method to avoid creating the intermediate string + /// + /// The string (as a StringBuilder) to write to the stream + public virtual Task WriteAsync(StringBuilder value, CancellationToken cancellationToken = default) + { + // Do the agument checking before 'going async' so you get it early + if (value == null) + { + throw new ArgumentNullException(nameof(value)); + } + // Then do the rest which may be deferred (done in the returned Task) + return WriteAsyncCore(value, cancellationToken); + + async Task WriteAsyncCore(StringBuilder sb, CancellationToken ct) + { + foreach (ReadOnlyMemory chunk in sb.GetChunks()) + await WriteAsync(chunk, ct).ConfigureAwait(false); + } + } + public Task WriteAsync(char[] buffer) { if (buffer == null) @@ -579,6 +626,17 @@ namespace System.IO tuple, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default); } + /// + /// Equivalent to WriteLineAsync(stringBuilder.ToString()) however it uses the + /// StringBuilder.GetChunks() method to avoid creating the intermediate string + /// + /// The string (as a StringBuilder) to write to the stream + public async virtual Task WriteLineAsync(StringBuilder value, CancellationToken cancellationToken = default) + { + await WriteAsync(value, cancellationToken).ConfigureAwait(false); + await WriteAsync(CoreNewLine, cancellationToken).ConfigureAwait(false); + } + public Task WriteLineAsync(char[] buffer) { if (buffer == null) @@ -745,6 +803,9 @@ namespace System.IO public override void Write(string value) => _out.Write(value); [MethodImpl(MethodImplOptions.Synchronized)] + public override void Write(StringBuilder value) => _out.Write(value); + + [MethodImpl(MethodImplOptions.Synchronized)] public override void Write(object value) => _out.Write(value); [MethodImpl(MethodImplOptions.Synchronized)] @@ -799,6 +860,9 @@ namespace System.IO public override void WriteLine(string value) => _out.WriteLine(value); [MethodImpl(MethodImplOptions.Synchronized)] + public override void WriteLine(StringBuilder value) => _out.WriteLine(value); + + [MethodImpl(MethodImplOptions.Synchronized)] public override void WriteLine(object value) => _out.WriteLine(value); [MethodImpl(MethodImplOptions.Synchronized)] @@ -832,6 +896,13 @@ namespace System.IO } [MethodImpl(MethodImplOptions.Synchronized)] + public override Task WriteAsync(StringBuilder value, CancellationToken cancellationToken = default) + { + Write(value); + return Task.CompletedTask; + } + + [MethodImpl(MethodImplOptions.Synchronized)] public override Task WriteAsync(char[] buffer, int index, int count) { Write(buffer, index, count); @@ -853,6 +924,13 @@ namespace System.IO } [MethodImpl(MethodImplOptions.Synchronized)] + public override Task WriteLineAsync(StringBuilder value, CancellationToken cancellationToken = default) + { + WriteLine(value); + return Task.CompletedTask; + } + + [MethodImpl(MethodImplOptions.Synchronized)] public override Task WriteLineAsync(char[] buffer, int index, int count) { WriteLine(buffer, index, count); -- 2.7.4