Add and apply nullable attributes (dotnet/coreclr#24679)
[mono-project.git] / netcore / System.Private.CoreLib / shared / System / IO / TextWriter.cs
blob9dfb1405a943c50bf3f3207e8d58b7c553248793
1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
5 using System.Text;
6 using System.Threading;
7 using System.Globalization;
8 using System.Threading.Tasks;
9 using System.Runtime.CompilerServices;
10 using System.Runtime.InteropServices;
11 using System.Buffers;
12 using System.Diagnostics.CodeAnalysis;
14 namespace System.IO
16 // This abstract base class represents a writer that can write a sequential
17 // stream of characters. A subclass must minimally implement the
18 // Write(char) method.
20 // This class is intended for character output, not bytes.
21 // There are methods on the Stream class for writing bytes.
22 public abstract partial class TextWriter : MarshalByRefObject, IDisposable, IAsyncDisposable
24 public static readonly TextWriter Null = new NullTextWriter();
26 // We don't want to allocate on every TextWriter creation, so cache the char array.
27 private static readonly char[] s_coreNewLine = Environment.NewLine.ToCharArray();
29 /// <summary>
30 /// This is the 'NewLine' property expressed as a char[].
31 /// It is exposed to subclasses as a protected field for read-only
32 /// purposes. You should only modify it by using the 'NewLine' property.
33 /// In particular you should never modify the elements of the array
34 /// as they are shared among many instances of TextWriter.
35 /// </summary>
36 protected char[] CoreNewLine = s_coreNewLine;
37 private string CoreNewLineStr = Environment.NewLine;
39 // Can be null - if so, ask for the Thread's CurrentCulture every time.
40 private IFormatProvider? _internalFormatProvider;
42 protected TextWriter()
44 _internalFormatProvider = null; // Ask for CurrentCulture all the time.
47 protected TextWriter(IFormatProvider? formatProvider)
49 _internalFormatProvider = formatProvider;
52 public virtual IFormatProvider FormatProvider
54 get
56 if (_internalFormatProvider == null)
58 return CultureInfo.CurrentCulture;
60 else
62 return _internalFormatProvider;
67 public virtual void Close()
69 Dispose(true);
70 GC.SuppressFinalize(this);
73 protected virtual void Dispose(bool disposing)
77 public void Dispose()
79 Dispose(true);
80 GC.SuppressFinalize(this);
83 public virtual ValueTask DisposeAsync()
85 try
87 Dispose();
88 return default;
90 catch (Exception exc)
92 return new ValueTask(Task.FromException(exc));
96 // Clears all buffers for this TextWriter and causes any buffered data to be
97 // written to the underlying device. This default method is empty, but
98 // descendant classes can override the method to provide the appropriate
99 // functionality.
100 public virtual void Flush()
104 public abstract Encoding Encoding
106 get;
109 /// <summary>
110 /// Returns the line terminator string used by this TextWriter. The default line
111 /// terminator string is Environment.NewLine, which is platform specific.
112 /// On Windows this is a carriage return followed by a line feed ("\r\n").
113 /// On OSX and Linux this is a line feed ("\n").
114 /// </summary>
115 /// <remarks>
116 /// The line terminator string is written to the text stream whenever one of the
117 /// WriteLine methods are called. In order for text written by
118 /// the TextWriter to be readable by a TextReader, only one of the following line
119 /// terminator strings should be used: "\r", "\n", or "\r\n".
120 /// </remarks>
121 [AllowNull]
122 public virtual string NewLine
124 get { return CoreNewLineStr; }
127 if (value == null)
129 value = Environment.NewLine;
132 CoreNewLineStr = value;
133 CoreNewLine = value.ToCharArray();
138 // Writes a character to the text stream. This default method is empty,
139 // but descendant classes can override the method to provide the
140 // appropriate functionality.
142 public virtual void Write(char value)
146 // Writes a character array to the text stream. This default method calls
147 // Write(char) for each of the characters in the character array.
148 // If the character array is null, nothing is written.
150 public virtual void Write(char[]? buffer)
152 if (buffer != null)
154 Write(buffer, 0, buffer.Length);
158 // Writes a range of a character array to the text stream. This method will
159 // write count characters of data into this TextWriter from the
160 // buffer character array starting at position index.
162 public virtual void Write(char[] buffer, int index, int count)
164 if (buffer == null)
166 throw new ArgumentNullException(nameof(buffer), SR.ArgumentNull_Buffer);
168 if (index < 0)
170 throw new ArgumentOutOfRangeException(nameof(index), SR.ArgumentOutOfRange_NeedNonNegNum);
172 if (count < 0)
174 throw new ArgumentOutOfRangeException(nameof(count), SR.ArgumentOutOfRange_NeedNonNegNum);
176 if (buffer.Length - index < count)
178 throw new ArgumentException(SR.Argument_InvalidOffLen);
181 for (int i = 0; i < count; i++) Write(buffer[index + i]);
184 // Writes a span of characters to the text stream.
186 public virtual void Write(ReadOnlySpan<char> buffer)
188 char[] array = ArrayPool<char>.Shared.Rent(buffer.Length);
192 buffer.CopyTo(new Span<char>(array));
193 Write(array, 0, buffer.Length);
195 finally
197 ArrayPool<char>.Shared.Return(array);
201 // Writes the text representation of a boolean to the text stream. This
202 // method outputs either bool.TrueString or bool.FalseString.
204 public virtual void Write(bool value)
206 Write(value ? "True" : "False");
209 // Writes the text representation of an integer to the text stream. The
210 // text representation of the given value is produced by calling the
211 // int.ToString() method.
213 public virtual void Write(int value)
215 Write(value.ToString(FormatProvider));
218 // Writes the text representation of an integer to the text stream. The
219 // text representation of the given value is produced by calling the
220 // uint.ToString() method.
222 [CLSCompliant(false)]
223 public virtual void Write(uint value)
225 Write(value.ToString(FormatProvider));
228 // Writes the text representation of a long to the text stream. The
229 // text representation of the given value is produced by calling the
230 // long.ToString() method.
232 public virtual void Write(long value)
234 Write(value.ToString(FormatProvider));
237 // Writes the text representation of an unsigned long to the text
238 // stream. The text representation of the given value is produced
239 // by calling the ulong.ToString() method.
241 [CLSCompliant(false)]
242 public virtual void Write(ulong value)
244 Write(value.ToString(FormatProvider));
247 // Writes the text representation of a float to the text stream. The
248 // text representation of the given value is produced by calling the
249 // float.ToString(float) method.
251 public virtual void Write(float value)
253 Write(value.ToString(FormatProvider));
256 // Writes the text representation of a double to the text stream. The
257 // text representation of the given value is produced by calling the
258 // double.ToString(double) method.
260 public virtual void Write(double value)
262 Write(value.ToString(FormatProvider));
265 public virtual void Write(decimal value)
267 Write(value.ToString(FormatProvider));
270 // Writes a string to the text stream. If the given string is null, nothing
271 // is written to the text stream.
273 public virtual void Write(string? value)
275 if (value != null)
277 Write(value.ToCharArray());
281 // Writes the text representation of an object to the text stream. If the
282 // given object is null, nothing is written to the text stream.
283 // Otherwise, the object's ToString method is called to produce the
284 // string representation, and the resulting string is then written to the
285 // output stream.
287 public virtual void Write(object? value)
289 if (value != null)
291 if (value is IFormattable f)
293 Write(f.ToString(null, FormatProvider));
295 else
296 Write(value.ToString());
300 /// <summary>
301 /// Equivalent to Write(stringBuilder.ToString()) however it uses the
302 /// StringBuilder.GetChunks() method to avoid creating the intermediate string
303 /// </summary>
304 /// <param name="value">The string (as a StringBuilder) to write to the stream</param>
305 public virtual void Write(StringBuilder? value)
307 if (value != null)
309 foreach (ReadOnlyMemory<char> chunk in value.GetChunks())
310 Write(chunk.Span);
314 // Writes out a formatted string. Uses the same semantics as
315 // string.Format.
317 public virtual void Write(string format, object? arg0)
319 Write(string.Format(FormatProvider, format, arg0));
322 // Writes out a formatted string. Uses the same semantics as
323 // string.Format.
325 public virtual void Write(string format, object? arg0, object? arg1)
327 Write(string.Format(FormatProvider, format, arg0, arg1));
330 // Writes out a formatted string. Uses the same semantics as
331 // string.Format.
333 public virtual void Write(string format, object? arg0, object? arg1, object? arg2)
335 Write(string.Format(FormatProvider, format, arg0, arg1, arg2));
338 // Writes out a formatted string. Uses the same semantics as
339 // string.Format.
341 public virtual void Write(string format, params object?[] arg)
343 Write(string.Format(FormatProvider, format, arg));
347 // Writes a line terminator to the text stream. The default line terminator
348 // is Environment.NewLine, but this value can be changed by setting the NewLine property.
350 public virtual void WriteLine()
352 Write(CoreNewLine);
355 // Writes a character followed by a line terminator to the text stream.
357 public virtual void WriteLine(char value)
359 Write(value);
360 WriteLine();
363 // Writes an array of characters followed by a line terminator to the text
364 // stream.
366 public virtual void WriteLine(char[]? buffer)
368 Write(buffer);
369 WriteLine();
372 // Writes a range of a character array followed by a line terminator to the
373 // text stream.
375 public virtual void WriteLine(char[] buffer, int index, int count)
377 Write(buffer, index, count);
378 WriteLine();
381 public virtual void WriteLine(ReadOnlySpan<char> buffer)
383 char[] array = ArrayPool<char>.Shared.Rent(buffer.Length);
387 buffer.CopyTo(new Span<char>(array));
388 WriteLine(array, 0, buffer.Length);
390 finally
392 ArrayPool<char>.Shared.Return(array);
396 // Writes the text representation of a boolean followed by a line
397 // terminator to the text stream.
399 public virtual void WriteLine(bool value)
401 Write(value);
402 WriteLine();
405 // Writes the text representation of an integer followed by a line
406 // terminator to the text stream.
408 public virtual void WriteLine(int value)
410 Write(value);
411 WriteLine();
414 // Writes the text representation of an unsigned integer followed by
415 // a line terminator to the text stream.
417 [CLSCompliant(false)]
418 public virtual void WriteLine(uint value)
420 Write(value);
421 WriteLine();
424 // Writes the text representation of a long followed by a line terminator
425 // to the text stream.
427 public virtual void WriteLine(long value)
429 Write(value);
430 WriteLine();
433 // Writes the text representation of an unsigned long followed by
434 // a line terminator to the text stream.
436 [CLSCompliant(false)]
437 public virtual void WriteLine(ulong value)
439 Write(value);
440 WriteLine();
443 // Writes the text representation of a float followed by a line terminator
444 // to the text stream.
446 public virtual void WriteLine(float value)
448 Write(value);
449 WriteLine();
452 // Writes the text representation of a double followed by a line terminator
453 // to the text stream.
455 public virtual void WriteLine(double value)
457 Write(value);
458 WriteLine();
461 public virtual void WriteLine(decimal value)
463 Write(value);
464 WriteLine();
467 // Writes a string followed by a line terminator to the text stream.
469 public virtual void WriteLine(string? value)
471 if (value != null)
473 Write(value);
475 Write(CoreNewLineStr);
478 /// <summary>
479 /// Equivalent to WriteLine(stringBuilder.ToString()) however it uses the
480 /// StringBuilder.GetChunks() method to avoid creating the intermediate string
481 /// </summary>
482 public virtual void WriteLine(StringBuilder? value)
484 Write(value);
485 WriteLine();
488 // Writes the text representation of an object followed by a line
489 // terminator to the text stream.
491 public virtual void WriteLine(object? value)
493 if (value == null)
495 WriteLine();
497 else
499 // Call WriteLine(value.ToString), not Write(Object), WriteLine().
500 // This makes calls to WriteLine(Object) atomic.
501 if (value is IFormattable f)
503 WriteLine(f.ToString(null, FormatProvider));
505 else
507 WriteLine(value.ToString());
512 // Writes out a formatted string and a new line. Uses the same
513 // semantics as string.Format.
515 public virtual void WriteLine(string format, object? arg0)
517 WriteLine(string.Format(FormatProvider, format, arg0));
520 // Writes out a formatted string and a new line. Uses the same
521 // semantics as string.Format.
523 public virtual void WriteLine(string format, object? arg0, object? arg1)
525 WriteLine(string.Format(FormatProvider, format, arg0, arg1));
528 // Writes out a formatted string and a new line. Uses the same
529 // semantics as string.Format.
531 public virtual void WriteLine(string format, object? arg0, object? arg1, object? arg2)
533 WriteLine(string.Format(FormatProvider, format, arg0, arg1, arg2));
536 // Writes out a formatted string and a new line. Uses the same
537 // semantics as string.Format.
539 public virtual void WriteLine(string format, params object?[] arg)
541 WriteLine(string.Format(FormatProvider, format, arg));
544 #region Task based Async APIs
545 public virtual Task WriteAsync(char value)
547 var tuple = new Tuple<TextWriter, char>(this, value);
548 return Task.Factory.StartNew(state =>
550 var t = (Tuple<TextWriter, char>)state!;
551 t.Item1.Write(t.Item2);
553 tuple, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default);
556 public virtual Task WriteAsync(string? value)
558 var tuple = new Tuple<TextWriter, string?>(this, value);
559 return Task.Factory.StartNew(state =>
561 var t = (Tuple<TextWriter, string?>)state!;
562 t.Item1.Write(t.Item2);
564 tuple, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default);
567 /// <summary>
568 /// Equivalent to WriteAsync(stringBuilder.ToString()) however it uses the
569 /// StringBuilder.GetChunks() method to avoid creating the intermediate string
570 /// </summary>
571 /// <param name="value">The string (as a StringBuilder) to write to the stream</param>
572 public virtual Task WriteAsync(StringBuilder? value, CancellationToken cancellationToken = default)
574 return
575 cancellationToken.IsCancellationRequested ? Task.FromCanceled(cancellationToken) :
576 value == null ? Task.CompletedTask :
577 WriteAsyncCore(value, cancellationToken);
579 async Task WriteAsyncCore(StringBuilder sb, CancellationToken ct)
581 foreach (ReadOnlyMemory<char> chunk in sb.GetChunks())
583 await WriteAsync(chunk, ct).ConfigureAwait(false);
588 public Task WriteAsync(char[]? buffer)
590 if (buffer == null)
592 return Task.CompletedTask;
595 return WriteAsync(buffer, 0, buffer.Length);
598 public virtual Task WriteAsync(char[] buffer, int index, int count)
600 var tuple = new Tuple<TextWriter, char[], int, int>(this, buffer, index, count);
601 return Task.Factory.StartNew(state =>
603 var t = (Tuple<TextWriter, char[], int, int>)state!;
604 t.Item1.Write(t.Item2, t.Item3, t.Item4);
606 tuple, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default);
609 public virtual Task WriteAsync(ReadOnlyMemory<char> buffer, CancellationToken cancellationToken = default) =>
610 cancellationToken.IsCancellationRequested ? Task.FromCanceled(cancellationToken) :
611 MemoryMarshal.TryGetArray(buffer, out ArraySegment<char> array) ?
612 WriteAsync(array.Array!, array.Offset, array.Count) :
613 Task.Factory.StartNew(state =>
615 var t = (Tuple<TextWriter, ReadOnlyMemory<char>>)state!;
616 t.Item1.Write(t.Item2.Span);
617 }, Tuple.Create(this, buffer), cancellationToken, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default);
619 public virtual Task WriteLineAsync(char value)
621 var tuple = new Tuple<TextWriter, char>(this, value);
622 return Task.Factory.StartNew(state =>
624 var t = (Tuple<TextWriter, char>)state!;
625 t.Item1.WriteLine(t.Item2);
627 tuple, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default);
630 public virtual Task WriteLineAsync(string? value)
632 var tuple = new Tuple<TextWriter, string?>(this, value);
633 return Task.Factory.StartNew(state =>
635 var t = (Tuple<TextWriter, string?>)state!;
636 t.Item1.WriteLine(t.Item2);
638 tuple, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default);
641 /// <summary>
642 /// Equivalent to WriteLineAsync(stringBuilder.ToString()) however it uses the
643 /// StringBuilder.GetChunks() method to avoid creating the intermediate string
644 /// </summary>
645 /// <param name="value">The string (as a StringBuilder) to write to the stream</param>
646 public virtual Task WriteLineAsync(StringBuilder? value, CancellationToken cancellationToken = default)
648 return
649 cancellationToken.IsCancellationRequested ? Task.FromCanceled(cancellationToken) :
650 value == null ? WriteAsync(CoreNewLine, cancellationToken) :
651 WriteLineAsyncCore(value, cancellationToken);
653 async Task WriteLineAsyncCore(StringBuilder sb, CancellationToken ct)
655 foreach (ReadOnlyMemory<char> chunk in sb.GetChunks())
657 await WriteAsync(chunk, ct).ConfigureAwait(false);
659 await WriteAsync(CoreNewLine, ct).ConfigureAwait(false);
663 public Task WriteLineAsync(char[]? buffer)
665 if (buffer == null)
667 return WriteLineAsync();
670 return WriteLineAsync(buffer, 0, buffer.Length);
673 public virtual Task WriteLineAsync(char[] buffer, int index, int count)
675 var tuple = new Tuple<TextWriter, char[], int, int>(this, buffer, index, count);
676 return Task.Factory.StartNew(state =>
678 var t = (Tuple<TextWriter, char[], int, int>)state!;
679 t.Item1.WriteLine(t.Item2, t.Item3, t.Item4);
681 tuple, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default);
684 public virtual Task WriteLineAsync(ReadOnlyMemory<char> buffer, CancellationToken cancellationToken = default) =>
685 cancellationToken.IsCancellationRequested ? Task.FromCanceled(cancellationToken) :
686 MemoryMarshal.TryGetArray(buffer, out ArraySegment<char> array) ?
687 WriteLineAsync(array.Array!, array.Offset, array.Count) :
688 Task.Factory.StartNew(state =>
690 var t = (Tuple<TextWriter, ReadOnlyMemory<char>>)state!;
691 t.Item1.WriteLine(t.Item2.Span);
692 }, Tuple.Create(this, buffer), cancellationToken, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default);
694 public virtual Task WriteLineAsync()
696 return WriteAsync(CoreNewLine);
699 public virtual Task FlushAsync()
701 return Task.Factory.StartNew(state =>
703 ((TextWriter)state!).Flush();
705 this, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default);
707 #endregion
709 private sealed class NullTextWriter : TextWriter
711 internal NullTextWriter() : base(CultureInfo.InvariantCulture)
715 public override Encoding Encoding
719 return Encoding.Unicode;
723 public override void Write(char[] buffer, int index, int count)
727 public override void Write(string? value)
731 // Not strictly necessary, but for perf reasons
732 public override void WriteLine()
736 // Not strictly necessary, but for perf reasons
737 public override void WriteLine(string? value)
741 public override void WriteLine(object? value)
745 public override void Write(char value)
750 public static TextWriter Synchronized(TextWriter writer)
752 if (writer == null)
753 throw new ArgumentNullException(nameof(writer));
755 return writer is SyncTextWriter ? writer : new SyncTextWriter(writer);
758 internal sealed class SyncTextWriter : TextWriter, IDisposable
760 private readonly TextWriter _out;
762 internal SyncTextWriter(TextWriter t) : base(t.FormatProvider)
764 _out = t;
767 public override Encoding Encoding => _out.Encoding;
769 public override IFormatProvider FormatProvider => _out.FormatProvider;
771 [AllowNull]
772 public override string NewLine
774 [MethodImpl(MethodImplOptions.Synchronized)]
775 get { return _out.NewLine; }
776 [MethodImpl(MethodImplOptions.Synchronized)]
777 set { _out.NewLine = value; }
780 [MethodImpl(MethodImplOptions.Synchronized)]
781 public override void Close() => _out.Close();
783 [MethodImpl(MethodImplOptions.Synchronized)]
784 protected override void Dispose(bool disposing)
786 // Explicitly pick up a potentially methodimpl'ed Dispose
787 if (disposing)
788 ((IDisposable)_out).Dispose();
791 [MethodImpl(MethodImplOptions.Synchronized)]
792 public override void Flush() => _out.Flush();
794 [MethodImpl(MethodImplOptions.Synchronized)]
795 public override void Write(char value) => _out.Write(value);
797 [MethodImpl(MethodImplOptions.Synchronized)]
798 public override void Write(char[]? buffer) => _out.Write(buffer);
800 [MethodImpl(MethodImplOptions.Synchronized)]
801 public override void Write(char[] buffer, int index, int count) => _out.Write(buffer, index, count);
803 [MethodImpl(MethodImplOptions.Synchronized)]
804 public override void Write(ReadOnlySpan<char> buffer) => _out.Write(buffer);
806 [MethodImpl(MethodImplOptions.Synchronized)]
807 public override void Write(bool value) => _out.Write(value);
809 [MethodImpl(MethodImplOptions.Synchronized)]
810 public override void Write(int value) => _out.Write(value);
812 [MethodImpl(MethodImplOptions.Synchronized)]
813 public override void Write(uint value) => _out.Write(value);
815 [MethodImpl(MethodImplOptions.Synchronized)]
816 public override void Write(long value) => _out.Write(value);
818 [MethodImpl(MethodImplOptions.Synchronized)]
819 public override void Write(ulong value) => _out.Write(value);
821 [MethodImpl(MethodImplOptions.Synchronized)]
822 public override void Write(float value) => _out.Write(value);
824 [MethodImpl(MethodImplOptions.Synchronized)]
825 public override void Write(double value) => _out.Write(value);
827 [MethodImpl(MethodImplOptions.Synchronized)]
828 public override void Write(decimal value) => _out.Write(value);
830 [MethodImpl(MethodImplOptions.Synchronized)]
831 public override void Write(string? value) => _out.Write(value);
833 [MethodImpl(MethodImplOptions.Synchronized)]
834 public override void Write(StringBuilder? value) => _out.Write(value);
836 [MethodImpl(MethodImplOptions.Synchronized)]
837 public override void Write(object? value) => _out.Write(value);
839 [MethodImpl(MethodImplOptions.Synchronized)]
840 public override void Write(string format, object? arg0) => _out.Write(format, arg0);
842 [MethodImpl(MethodImplOptions.Synchronized)]
843 public override void Write(string format, object? arg0, object? arg1) => _out.Write(format, arg0, arg1);
845 [MethodImpl(MethodImplOptions.Synchronized)]
846 public override void Write(string format, object? arg0, object? arg1, object? arg2) => _out.Write(format, arg0, arg1, arg2);
848 [MethodImpl(MethodImplOptions.Synchronized)]
849 public override void Write(string format, object?[] arg) => _out.Write(format, arg);
851 [MethodImpl(MethodImplOptions.Synchronized)]
852 public override void WriteLine() => _out.WriteLine();
854 [MethodImpl(MethodImplOptions.Synchronized)]
855 public override void WriteLine(char value) => _out.WriteLine(value);
857 [MethodImpl(MethodImplOptions.Synchronized)]
858 public override void WriteLine(decimal value) => _out.WriteLine(value);
860 [MethodImpl(MethodImplOptions.Synchronized)]
861 public override void WriteLine(char[]? buffer) => _out.WriteLine(buffer);
863 [MethodImpl(MethodImplOptions.Synchronized)]
864 public override void WriteLine(char[] buffer, int index, int count) => _out.WriteLine(buffer, index, count);
866 [MethodImpl(MethodImplOptions.Synchronized)]
867 public override void WriteLine(ReadOnlySpan<char> buffer) => _out.WriteLine(buffer);
869 [MethodImpl(MethodImplOptions.Synchronized)]
870 public override void WriteLine(bool value) => _out.WriteLine(value);
872 [MethodImpl(MethodImplOptions.Synchronized)]
873 public override void WriteLine(int value) => _out.WriteLine(value);
875 [MethodImpl(MethodImplOptions.Synchronized)]
876 public override void WriteLine(uint value) => _out.WriteLine(value);
878 [MethodImpl(MethodImplOptions.Synchronized)]
879 public override void WriteLine(long value) => _out.WriteLine(value);
881 [MethodImpl(MethodImplOptions.Synchronized)]
882 public override void WriteLine(ulong value) => _out.WriteLine(value);
884 [MethodImpl(MethodImplOptions.Synchronized)]
885 public override void WriteLine(float value) => _out.WriteLine(value);
887 [MethodImpl(MethodImplOptions.Synchronized)]
888 public override void WriteLine(double value) => _out.WriteLine(value);
890 [MethodImpl(MethodImplOptions.Synchronized)]
891 public override void WriteLine(string? value) => _out.WriteLine(value);
893 [MethodImpl(MethodImplOptions.Synchronized)]
894 public override void WriteLine(StringBuilder? value) => _out.WriteLine(value);
896 [MethodImpl(MethodImplOptions.Synchronized)]
897 public override void WriteLine(object? value) => _out.WriteLine(value);
899 [MethodImpl(MethodImplOptions.Synchronized)]
900 public override void WriteLine(string format, object? arg0) => _out.WriteLine(format, arg0);
902 [MethodImpl(MethodImplOptions.Synchronized)]
903 public override void WriteLine(string format, object? arg0, object? arg1) => _out.WriteLine(format, arg0, arg1);
905 [MethodImpl(MethodImplOptions.Synchronized)]
906 public override void WriteLine(string format, object? arg0, object? arg1, object? arg2) => _out.WriteLine(format, arg0, arg1, arg2);
908 [MethodImpl(MethodImplOptions.Synchronized)]
909 public override void WriteLine(string format, object?[] arg) => _out.WriteLine(format, arg);
912 // On SyncTextWriter all APIs should run synchronously, even the async ones.
915 [MethodImpl(MethodImplOptions.Synchronized)]
916 public override ValueTask DisposeAsync()
918 Dispose();
919 return default;
922 [MethodImpl(MethodImplOptions.Synchronized)]
923 public override Task WriteAsync(char value)
925 Write(value);
926 return Task.CompletedTask;
929 [MethodImpl(MethodImplOptions.Synchronized)]
930 public override Task WriteAsync(string? value)
932 Write(value);
933 return Task.CompletedTask;
936 [MethodImpl(MethodImplOptions.Synchronized)]
937 public override Task WriteAsync(StringBuilder? value, CancellationToken cancellationToken = default)
939 if (cancellationToken.IsCancellationRequested)
941 return Task.FromCanceled(cancellationToken);
944 Write(value);
945 return Task.CompletedTask;
948 [MethodImpl(MethodImplOptions.Synchronized)]
949 public override Task WriteAsync(char[] buffer, int index, int count)
951 Write(buffer, index, count);
952 return Task.CompletedTask;
955 [MethodImpl(MethodImplOptions.Synchronized)]
956 public override Task WriteAsync(ReadOnlyMemory<char> buffer, CancellationToken cancellationToken = default)
958 if (cancellationToken.IsCancellationRequested)
960 return Task.FromCanceled(cancellationToken);
963 Write(buffer.Span);
964 return Task.CompletedTask;
967 [MethodImpl(MethodImplOptions.Synchronized)]
968 public override Task WriteLineAsync(ReadOnlyMemory<char> buffer, CancellationToken cancellationToken = default)
970 if (cancellationToken.IsCancellationRequested)
972 return Task.FromCanceled(cancellationToken);
975 WriteLine(buffer.Span);
976 return Task.CompletedTask;
979 [MethodImpl(MethodImplOptions.Synchronized)]
980 public override Task WriteLineAsync(char value)
982 WriteLine(value);
983 return Task.CompletedTask;
986 [MethodImpl(MethodImplOptions.Synchronized)]
987 public override Task WriteLineAsync()
989 WriteLine();
990 return Task.CompletedTask;
993 [MethodImpl(MethodImplOptions.Synchronized)]
994 public override Task WriteLineAsync(string? value)
996 WriteLine(value);
997 return Task.CompletedTask;
1000 [MethodImpl(MethodImplOptions.Synchronized)]
1001 public override Task WriteLineAsync(StringBuilder? value, CancellationToken cancellationToken = default)
1003 if (cancellationToken.IsCancellationRequested)
1005 return Task.FromCanceled(cancellationToken);
1008 WriteLine(value);
1009 return Task.CompletedTask;
1012 [MethodImpl(MethodImplOptions.Synchronized)]
1013 public override Task WriteLineAsync(char[] buffer, int index, int count)
1015 WriteLine(buffer, index, count);
1016 return Task.CompletedTask;
1019 [MethodImpl(MethodImplOptions.Synchronized)]
1020 public override Task FlushAsync()
1022 Flush();
1023 return Task.CompletedTask;