using System;
using System.Globalization;
using System.IO;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace Cysharp.Text
{
///
/// A implementation that is backed with .
///
///
/// It's important to make sure the writer is always properly disposed.
///
public sealed class ZStringWriter : TextWriter
{
private Utf16ValueStringBuilder sb;
private bool isOpen;
private UnicodeEncoding? encoding;
///
/// Creates a new instance using as format provider.
///
public ZStringWriter() : this(CultureInfo.CurrentCulture)
{
}
///
/// Creates a new instance with given format provider.
///
public ZStringWriter(IFormatProvider formatProvider) : base(formatProvider)
{
sb = ZString.CreateStringBuilder();
isOpen = true;
}
///
/// Disposes this instance, operations are no longer allowed.
///
public override void Close()
{
Dispose(true);
}
protected override void Dispose(bool disposing)
{
sb.Dispose();
isOpen = false;
base.Dispose(disposing);
}
public override Encoding Encoding => encoding = encoding ?? new UnicodeEncoding(false, false);
public override void Write(char value)
{
AssertNotDisposed();
sb.Append(value);
}
public override void Write(char[] buffer, int index, int count)
{
if (buffer == null)
{
throw new ArgumentNullException(nameof(buffer));
}
if (index < 0)
{
throw new ArgumentOutOfRangeException(nameof(index));
}
if (count < 0)
{
throw new ArgumentOutOfRangeException(nameof(count));
}
if (buffer.Length - index < count)
{
throw new ArgumentException();
}
AssertNotDisposed();
sb.Append(buffer, index, count);
}
public override void Write(string value)
{
AssertNotDisposed();
if (value != null)
{
sb.Append(value);
}
}
public override Task WriteAsync(char value)
{
Write(value);
return Task.CompletedTask;
}
public override Task WriteAsync(string value)
{
Write(value);
return Task.CompletedTask;
}
public override Task WriteAsync(char[] buffer, int index, int count)
{
Write(buffer, index, count);
return Task.CompletedTask;
}
public override Task WriteLineAsync(char value)
{
WriteLine(value);
return Task.CompletedTask;
}
public override Task WriteLineAsync(string value)
{
WriteLine(value);
return Task.CompletedTask;
}
public override Task WriteLineAsync(char[] buffer, int index, int count)
{
WriteLine(buffer, index, count);
return Task.CompletedTask;
}
public override void Write(bool value)
{
AssertNotDisposed();
sb.Append(value);
}
public override void Write(decimal value)
{
AssertNotDisposed();
sb.Append(value);
}
///
/// No-op.
///
public override Task FlushAsync()
{
return Task.CompletedTask;
}
///
/// Materializes the current state from underlying string builder.
///
public override string ToString()
{
return sb.ToString();
}
#if !NETSTANDARD2_0
#if !UNITY_2018_3_OR_NEWER
public override void Write(ReadOnlySpan buffer)
{
AssertNotDisposed();
sb.Append(buffer);
}
public override void WriteLine(ReadOnlySpan buffer)
{
AssertNotDisposed();
sb.Append(buffer);
WriteLine();
}
public override Task WriteAsync(ReadOnlyMemory buffer, CancellationToken cancellationToken = default)
{
if (cancellationToken.IsCancellationRequested)
{
return Task.FromCanceled(cancellationToken);
}
Write(buffer.Span);
return Task.CompletedTask;
}
public override Task WriteLineAsync(ReadOnlyMemory buffer, CancellationToken cancellationToken = default)
{
if (cancellationToken.IsCancellationRequested)
{
return Task.FromCanceled(cancellationToken);
}
WriteLine(buffer.Span);
return Task.CompletedTask;
}
#endif
#endif
private void AssertNotDisposed()
{
if (!isOpen)
{
throw new ObjectDisposedException(nameof(sb));
}
}
}
}