@@ -283,6 +283,21 @@ public virtual void Write(object value)
283283 }
284284 }
285285
286+ /// <summary>
287+ /// Equivalent to Write(stringBuilder.ToString()) however it uses the
288+ /// StringBuilder.GetChunks() method to avoid creating the intermediate string
289+ /// </summary>
290+ /// <param name="value">The string (as a StringBuilder) to write to the stream</param>
291+ public virtual void Write ( StringBuilder value )
292+ {
293+ if ( value == null )
294+ {
295+ throw new ArgumentNullException ( nameof ( value ) ) ;
296+ }
297+ foreach ( ReadOnlyMemory < char > chunk in value . GetChunks ( ) )
298+ Write ( chunk ) ;
299+ }
300+
286301 // Writes out a formatted string. Uses the same semantics as
287302 // String.Format.
288303 //
@@ -447,6 +462,16 @@ public virtual void WriteLine(string value)
447462 Write ( CoreNewLineStr ) ;
448463 }
449464
465+ /// <summary>
466+ /// Equivalent to WriteLine(stringBuilder.ToString()) however it uses the
467+ /// StringBuilder.GetChunks() method to avoid creating the intermediate string
468+ /// </summary>
469+ public virtual void WriteLine ( StringBuilder value )
470+ {
471+ Write ( value ) ;
472+ WriteLine ( ) ;
473+ }
474+
450475 // Writes the text representation of an object followed by a line
451476 // terminator to the text stream.
452477 //
@@ -527,6 +552,28 @@ public virtual Task WriteAsync(string value)
527552 tuple , CancellationToken . None , TaskCreationOptions . DenyChildAttach , TaskScheduler . Default ) ;
528553 }
529554
555+ /// <summary>
556+ /// Equivalent to WriteAsync(stringBuilder.ToString()) however it uses the
557+ /// StringBuilder.GetChunks() method to avoid creating the intermediate string
558+ /// </summary>
559+ /// <param name="value">The string (as a StringBuilder) to write to the stream</param>
560+ public virtual Task WriteAsync ( StringBuilder value , CancellationToken cancellationToken = default )
561+ {
562+ // Do the agument checking before 'going async' so you get it early
563+ if ( value == null )
564+ {
565+ throw new ArgumentNullException ( nameof ( value ) ) ;
566+ }
567+ // Then do the rest which may be deferred (done in the returned Task)
568+ return WriteAsyncCore ( value , cancellationToken ) ;
569+
570+ async Task WriteAsyncCore ( StringBuilder sb , CancellationToken ct )
571+ {
572+ foreach ( ReadOnlyMemory < char > chunk in sb . GetChunks ( ) )
573+ await WriteAsync ( chunk , ct ) . ConfigureAwait ( false ) ;
574+ }
575+ }
576+
530577 public Task WriteAsync ( char [ ] buffer )
531578 {
532579 if ( buffer == null )
@@ -579,6 +626,17 @@ public virtual Task WriteLineAsync(string value)
579626 tuple , CancellationToken . None , TaskCreationOptions . DenyChildAttach , TaskScheduler . Default ) ;
580627 }
581628
629+ /// <summary>
630+ /// Equivalent to WriteLineAsync(stringBuilder.ToString()) however it uses the
631+ /// StringBuilder.GetChunks() method to avoid creating the intermediate string
632+ /// </summary>
633+ /// <param name="value">The string (as a StringBuilder) to write to the stream</param>
634+ public async virtual Task WriteLineAsync ( StringBuilder value , CancellationToken cancellationToken = default )
635+ {
636+ await WriteAsync ( value , cancellationToken ) . ConfigureAwait ( false ) ;
637+ await WriteAsync ( CoreNewLine , cancellationToken ) . ConfigureAwait ( false ) ;
638+ }
639+
582640 public Task WriteLineAsync ( char [ ] buffer )
583641 {
584642 if ( buffer == null )
@@ -744,6 +802,9 @@ protected override void Dispose(bool disposing)
744802 [ MethodImpl ( MethodImplOptions . Synchronized ) ]
745803 public override void Write ( string value ) => _out . Write ( value ) ;
746804
805+ [ MethodImpl ( MethodImplOptions . Synchronized ) ]
806+ public override void Write ( StringBuilder value ) => _out . Write ( value ) ;
807+
747808 [ MethodImpl ( MethodImplOptions . Synchronized ) ]
748809 public override void Write ( object value ) => _out . Write ( value ) ;
749810
@@ -798,6 +859,9 @@ protected override void Dispose(bool disposing)
798859 [ MethodImpl ( MethodImplOptions . Synchronized ) ]
799860 public override void WriteLine ( string value ) => _out . WriteLine ( value ) ;
800861
862+ [ MethodImpl ( MethodImplOptions . Synchronized ) ]
863+ public override void WriteLine ( StringBuilder value ) => _out . WriteLine ( value ) ;
864+
801865 [ MethodImpl ( MethodImplOptions . Synchronized ) ]
802866 public override void WriteLine ( object value ) => _out . WriteLine ( value ) ;
803867
@@ -831,6 +895,13 @@ public override Task WriteAsync(string value)
831895 return Task . CompletedTask ;
832896 }
833897
898+ [ MethodImpl ( MethodImplOptions . Synchronized ) ]
899+ public override Task WriteAsync ( StringBuilder value , CancellationToken cancellationToken = default )
900+ {
901+ Write ( value ) ;
902+ return Task . CompletedTask ;
903+ }
904+
834905 [ MethodImpl ( MethodImplOptions . Synchronized ) ]
835906 public override Task WriteAsync ( char [ ] buffer , int index , int count )
836907 {
@@ -852,6 +923,13 @@ public override Task WriteLineAsync(string value)
852923 return Task . CompletedTask ;
853924 }
854925
926+ [ MethodImpl ( MethodImplOptions . Synchronized ) ]
927+ public override Task WriteLineAsync ( StringBuilder value , CancellationToken cancellationToken = default )
928+ {
929+ WriteLine ( value ) ;
930+ return Task . CompletedTask ;
931+ }
932+
855933 [ MethodImpl ( MethodImplOptions . Synchronized ) ]
856934 public override Task WriteLineAsync ( char [ ] buffer , int index , int count )
857935 {
0 commit comments