Skip to content

Commit 6780644

Browse files
committed
ZStringWriter for Unity
1 parent 7bf1a46 commit 6780644

File tree

5 files changed

+228
-1
lines changed

5 files changed

+228
-1
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,209 @@
1+
using System;
2+
using System.Globalization;
3+
using System.IO;
4+
using System.Text;
5+
using System.Threading;
6+
using System.Threading.Tasks;
7+
8+
namespace Cysharp.Text
9+
{
10+
/// <summary>
11+
/// A <see cref="TextWriter"/> implementation that is backed with <see cref="Utf16ValueStringBuilder"/>.
12+
/// </summary>
13+
/// <remarks>
14+
/// It's important to make sure the writer is always properly disposed.
15+
/// </remarks>
16+
public sealed class ZStringWriter : TextWriter
17+
{
18+
private Utf16ValueStringBuilder sb;
19+
private bool isOpen;
20+
private UnicodeEncoding encoding;
21+
22+
/// <summary>
23+
/// Creates a new instance using <see cref="CultureInfo.CurrentCulture"/> as format provider.
24+
/// </summary>
25+
public ZStringWriter() : this(CultureInfo.CurrentCulture)
26+
{
27+
}
28+
29+
/// <summary>
30+
/// Creates a new instance with given format provider.
31+
/// </summary>
32+
public ZStringWriter(IFormatProvider formatProvider) : base(formatProvider)
33+
{
34+
sb = ZString.CreateStringBuilder();
35+
isOpen = true;
36+
}
37+
38+
/// <summary>
39+
/// Disposes this instance, operations are no longer allowed.
40+
/// </summary>
41+
public override void Close()
42+
{
43+
Dispose(true);
44+
}
45+
46+
protected override void Dispose(bool disposing)
47+
{
48+
sb.Dispose();
49+
isOpen = false;
50+
base.Dispose(disposing);
51+
}
52+
53+
public override Encoding Encoding => encoding = encoding ?? new UnicodeEncoding(false, false);
54+
55+
public override void Write(char value)
56+
{
57+
AssertNotDisposed();
58+
59+
sb.Append(value);
60+
}
61+
62+
public override void Write(char[] buffer, int index, int count)
63+
{
64+
if (buffer == null)
65+
{
66+
throw new ArgumentNullException(nameof(buffer));
67+
}
68+
if (index < 0)
69+
{
70+
throw new ArgumentOutOfRangeException(nameof(index));
71+
}
72+
if (count < 0)
73+
{
74+
throw new ArgumentOutOfRangeException(nameof(count));
75+
}
76+
if (buffer.Length - index < count)
77+
{
78+
throw new ArgumentException();
79+
}
80+
AssertNotDisposed();
81+
82+
sb.Append(buffer.AsSpan(index, count));
83+
}
84+
85+
public override void Write(string value)
86+
{
87+
AssertNotDisposed();
88+
89+
if (value != null)
90+
{
91+
sb.Append(value);
92+
}
93+
}
94+
95+
public override Task WriteAsync(char value)
96+
{
97+
Write(value);
98+
return Task.CompletedTask;
99+
}
100+
101+
public override Task WriteAsync(string value)
102+
{
103+
Write(value);
104+
return Task.CompletedTask;
105+
}
106+
107+
public override Task WriteAsync(char[] buffer, int index, int count)
108+
{
109+
Write(buffer, index, count);
110+
return Task.CompletedTask;
111+
}
112+
113+
public override Task WriteLineAsync(char value)
114+
{
115+
WriteLine(value);
116+
return Task.CompletedTask;
117+
}
118+
119+
public override Task WriteLineAsync(string value)
120+
{
121+
WriteLine(value);
122+
return Task.CompletedTask;
123+
}
124+
125+
public override Task WriteLineAsync(char[] buffer, int index, int count)
126+
{
127+
WriteLine(buffer, index, count);
128+
return Task.CompletedTask;
129+
}
130+
131+
public override void Write(bool value)
132+
{
133+
AssertNotDisposed();
134+
sb.Append(value);
135+
}
136+
137+
public override void Write(decimal value)
138+
{
139+
AssertNotDisposed();
140+
sb.Append(value);
141+
}
142+
143+
/// <summary>
144+
/// No-op.
145+
/// </summary>
146+
public override Task FlushAsync()
147+
{
148+
return Task.CompletedTask;
149+
}
150+
151+
/// <summary>
152+
/// Materializes the current state from underlying string builder.
153+
/// </summary>
154+
public override string ToString()
155+
{
156+
return sb.ToString();
157+
}
158+
159+
#if !NETSTANDARD2_0
160+
#if !UNITY_2018_3_OR_NEWER
161+
162+
public override void Write(ReadOnlySpan<char> buffer)
163+
{
164+
AssertNotDisposed();
165+
166+
sb.Append(buffer);
167+
}
168+
169+
public override void WriteLine(ReadOnlySpan<char> buffer)
170+
{
171+
AssertNotDisposed();
172+
173+
sb.Append(buffer);
174+
WriteLine();
175+
}
176+
177+
public override Task WriteAsync(ReadOnlyMemory<char> buffer, CancellationToken cancellationToken = default)
178+
{
179+
if (cancellationToken.IsCancellationRequested)
180+
{
181+
return Task.FromCanceled(cancellationToken);
182+
}
183+
184+
Write(buffer.Span);
185+
return Task.CompletedTask;
186+
}
187+
188+
public override Task WriteLineAsync(ReadOnlyMemory<char> buffer, CancellationToken cancellationToken = default)
189+
{
190+
if (cancellationToken.IsCancellationRequested)
191+
{
192+
return Task.FromCanceled(cancellationToken);
193+
}
194+
195+
WriteLine(buffer.Span);
196+
return Task.CompletedTask;
197+
}
198+
#endif
199+
#endif
200+
201+
private void AssertNotDisposed()
202+
{
203+
if (!isOpen)
204+
{
205+
throw new ObjectDisposedException(nameof(sb));
206+
}
207+
}
208+
}
209+
}

src/ZString.Unity/Assets/Scripts/ZString/ZStringWriter.cs.meta

+11
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/ZString/Icon.png

3.11 KB
Loading

src/ZString/ZString.csproj

+5
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,13 @@
2020
<PackageLicenseExpression>MIT</PackageLicenseExpression>
2121
<SignAssembly>true</SignAssembly>
2222
<AssemblyOriginatorKeyFile>../../opensource.snk</AssemblyOriginatorKeyFile>
23+
<PackageIcon>Icon.png</PackageIcon>
2324
</PropertyGroup>
2425

26+
<ItemGroup>
27+
<None Include="Icon.png" Pack="true" PackagePath="/" />
28+
</ItemGroup>
29+
2530
<ItemGroup>
2631
<PackageReference Include="System.Memory" Version="4.5.3" />
2732
</ItemGroup>

src/ZString/ZStringWriter.cs

+3-1
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@ public override string ToString()
157157
}
158158

159159
#if !NETSTANDARD2_0
160+
#if !UNITY_2018_3_OR_NEWER
160161

161162
public override void Write(ReadOnlySpan<char> buffer)
162163
{
@@ -195,7 +196,8 @@ public override Task WriteLineAsync(ReadOnlyMemory<char> buffer, CancellationTok
195196
return Task.CompletedTask;
196197
}
197198
#endif
198-
199+
#endif
200+
199201
private void AssertNotDisposed()
200202
{
201203
if (!isOpen)

0 commit comments

Comments
 (0)