Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
DefaultInterpolatedStringHandler.cs
Go to the documentation of this file.
5
7
8[InterpolatedStringHandler]
10{
11 private readonly IFormatProvider _provider;
12
13 private char[] _arrayToReturnToPool;
14
16
17 private int _pos;
18
19 private readonly bool _hasCustomFormatter;
20
21 internal ReadOnlySpan<char> Text => _chars.Slice(0, _pos);
22
23 public DefaultInterpolatedStringHandler(int literalLength, int formattedCount)
24 {
25 _provider = null;
26 _chars = (_arrayToReturnToPool = ArrayPool<char>.Shared.Rent(GetDefaultLength(literalLength, formattedCount)));
27 _pos = 0;
28 _hasCustomFormatter = false;
29 }
30
31 public DefaultInterpolatedStringHandler(int literalLength, int formattedCount, IFormatProvider? provider)
32 {
33 _provider = provider;
34 _chars = (_arrayToReturnToPool = ArrayPool<char>.Shared.Rent(GetDefaultLength(literalLength, formattedCount)));
35 _pos = 0;
36 _hasCustomFormatter = provider != null && HasCustomFormatter(provider);
37 }
38
39 public DefaultInterpolatedStringHandler(int literalLength, int formattedCount, IFormatProvider? provider, Span<char> initialBuffer)
40 {
41 _provider = provider;
42 _chars = initialBuffer;
44 _pos = 0;
45 _hasCustomFormatter = provider != null && HasCustomFormatter(provider);
46 }
47
48 [MethodImpl(MethodImplOptions.AggressiveInlining)]
49 internal static int GetDefaultLength(int literalLength, int formattedCount)
50 {
51 return Math.Max(256, literalLength + formattedCount * 11);
52 }
53
54 public override string ToString()
55 {
56 return new string(Text);
57 }
58
59 public string ToStringAndClear()
60 {
61 string result = new string(Text);
62 Clear();
63 return result;
64 }
65
66 [MethodImpl(MethodImplOptions.AggressiveInlining)]
67 internal void Clear()
68 {
69 char[] arrayToReturnToPool = _arrayToReturnToPool;
71 if (arrayToReturnToPool != null)
72 {
73 ArrayPool<char>.Shared.Return(arrayToReturnToPool);
74 }
75 }
76
77 [MethodImpl(MethodImplOptions.AggressiveInlining)]
78 public void AppendLiteral(string value)
79 {
80 if (value.Length == 1)
81 {
83 int pos = _pos;
84 if ((uint)pos < (uint)chars.Length)
85 {
86 chars[pos] = value[0];
87 _pos = pos + 1;
88 }
89 else
90 {
92 }
93 }
94 else if (value.Length == 2)
95 {
96 Span<char> chars2 = _chars;
97 int pos2 = _pos;
98 if ((uint)pos2 < chars2.Length - 1)
99 {
100 Unsafe.WriteUnaligned(ref Unsafe.As<char, byte>(ref Unsafe.Add(ref MemoryMarshal.GetReference(chars2), pos2)), Unsafe.ReadUnaligned<int>(ref Unsafe.As<char, byte>(ref value.GetRawStringData())));
101 _pos = pos2 + 2;
102 }
103 else
104 {
106 }
107 }
108 else
109 {
111 }
112 }
113
114 private void AppendStringDirect(string value)
115 {
116 if (value.TryCopyTo(_chars.Slice(_pos)))
117 {
118 _pos += value.Length;
119 }
120 else
121 {
123 }
124 }
125
127 {
129 {
130 AppendCustomFormatter(value, null);
131 return;
132 }
133 string text;
134 if (value is IFormattable)
135 {
136 if (value is ISpanFormattable)
137 {
138 int charsWritten;
139 while (!((ISpanFormattable)(object)value).TryFormat(_chars.Slice(_pos), out charsWritten, default(ReadOnlySpan<char>), _provider))
140 {
141 Grow();
142 }
143 _pos += charsWritten;
144 return;
145 }
146 text = ((IFormattable)(object)value).ToString(null, _provider);
147 }
148 else
149 {
150 text = value?.ToString();
151 }
152 if (text != null)
153 {
155 }
156 }
157
158 public void AppendFormatted<T>(T value, string? format)
159 {
161 {
162 AppendCustomFormatter(value, format);
163 return;
164 }
165 string text;
166 if (value is IFormattable)
167 {
168 if (value is ISpanFormattable)
169 {
170 int charsWritten;
171 while (!((ISpanFormattable)(object)value).TryFormat(_chars.Slice(_pos), out charsWritten, format, _provider))
172 {
173 Grow();
174 }
175 _pos += charsWritten;
176 return;
177 }
179 }
180 else
181 {
182 text = value?.ToString();
183 }
184 if (text != null)
185 {
187 }
188 }
189
190 public void AppendFormatted<T>(T value, int alignment)
191 {
192 int pos = _pos;
194 if (alignment != 0)
195 {
196 AppendOrInsertAlignmentIfNeeded(pos, alignment);
197 }
198 }
199
200 public void AppendFormatted<T>(T value, int alignment, string? format)
201 {
202 int pos = _pos;
204 if (alignment != 0)
205 {
206 AppendOrInsertAlignmentIfNeeded(pos, alignment);
207 }
208 }
209
211 {
212 if (value.TryCopyTo(_chars.Slice(_pos)))
213 {
214 _pos += value.Length;
215 }
216 else
217 {
219 }
220 }
221
222 public void AppendFormatted(ReadOnlySpan<char> value, int alignment = 0, string? format = null)
223 {
224 bool flag = false;
225 if (alignment < 0)
226 {
227 flag = true;
228 alignment = -alignment;
229 }
230 int num = alignment - value.Length;
231 if (num <= 0)
232 {
234 return;
235 }
237 if (flag)
238 {
239 value.CopyTo(_chars.Slice(_pos));
240 _pos += value.Length;
241 _chars.Slice(_pos, num).Fill(' ');
242 _pos += num;
243 }
244 else
245 {
246 _chars.Slice(_pos, num).Fill(' ');
247 _pos += num;
248 value.CopyTo(_chars.Slice(_pos));
249 _pos += value.Length;
250 }
251 }
252
253 public void AppendFormatted(string? value)
254 {
255 if (!_hasCustomFormatter && value != null && value.TryCopyTo(_chars.Slice(_pos)))
256 {
257 _pos += value.Length;
258 }
259 else
260 {
262 }
263 }
264
265 [MethodImpl(MethodImplOptions.NoInlining)]
266 private void AppendFormattedSlow(string value)
267 {
269 {
270 AppendCustomFormatter(value, null);
271 }
272 else if (value != null)
273 {
275 value.CopyTo(_chars.Slice(_pos));
276 _pos += value.Length;
277 }
278 }
279
280 public void AppendFormatted(string? value, int alignment = 0, string? format = null)
281 {
282 this.AppendFormatted<string>(value, alignment, format);
283 }
284
285 public void AppendFormatted(object? value, int alignment = 0, string? format = null)
286 {
287 this.AppendFormatted<object>(value, alignment, format);
288 }
289
290 [MethodImpl(MethodImplOptions.AggressiveInlining)]
291 internal static bool HasCustomFormatter(IFormatProvider provider)
292 {
293 if (provider.GetType() != typeof(CultureInfo))
294 {
295 return provider.GetFormat(typeof(ICustomFormatter)) != null;
296 }
297 return false;
298 }
299
300 [MethodImpl(MethodImplOptions.NoInlining)]
301 private void AppendCustomFormatter<T>(T value, string format)
302 {
304 if (customFormatter != null)
305 {
306 string text = customFormatter.Format(format, value, _provider);
307 if (text != null)
308 {
310 }
311 }
312 }
313
314 private void AppendOrInsertAlignmentIfNeeded(int startingPos, int alignment)
315 {
316 int num = _pos - startingPos;
317 bool flag = false;
318 if (alignment < 0)
319 {
320 flag = true;
321 alignment = -alignment;
322 }
323 int num2 = alignment - num;
324 if (num2 > 0)
325 {
327 if (flag)
328 {
329 _chars.Slice(_pos, num2).Fill(' ');
330 }
331 else
332 {
333 _chars.Slice(startingPos, num).CopyTo(_chars.Slice(startingPos + num2));
334 _chars.Slice(startingPos, num2).Fill(' ');
335 }
336 _pos += num2;
337 }
338 }
339
340 [MethodImpl(MethodImplOptions.AggressiveInlining)]
341 private void EnsureCapacityForAdditionalChars(int additionalChars)
342 {
343 if (_chars.Length - _pos < additionalChars)
344 {
345 Grow(additionalChars);
346 }
347 }
348
349 [MethodImpl(MethodImplOptions.NoInlining)]
350 private void GrowThenCopyString(string value)
351 {
352 Grow(value.Length);
353 value.CopyTo(_chars.Slice(_pos));
354 _pos += value.Length;
355 }
356
357 [MethodImpl(MethodImplOptions.NoInlining)]
359 {
360 Grow(value.Length);
361 value.CopyTo(_chars.Slice(_pos));
362 _pos += value.Length;
363 }
364
365 [MethodImpl(MethodImplOptions.NoInlining)]
366 private void Grow(int additionalChars)
367 {
368 GrowCore((uint)(_pos + additionalChars));
369 }
370
371 [MethodImpl(MethodImplOptions.NoInlining)]
372 private void Grow()
373 {
374 GrowCore((uint)(_chars.Length + 1));
375 }
376
377 [MethodImpl(MethodImplOptions.AggressiveInlining)]
378 private void GrowCore(uint requiredMinCapacity)
379 {
380 uint value = Math.Max(requiredMinCapacity, Math.Min((uint)(_chars.Length * 2), 1073741791u));
381 int minimumLength = (int)Math.Clamp(value, 256u, 2147483647u);
382 char[] array = ArrayPool<char>.Shared.Rent(minimumLength);
383 _chars.Slice(0, _pos).CopyTo(array);
384 char[] arrayToReturnToPool = _arrayToReturnToPool;
386 if (arrayToReturnToPool != null)
387 {
388 ArrayPool<char>.Shared.Return(arrayToReturnToPool);
389 }
390 }
391}
static ArrayPool< T > Shared
Definition ArrayPool.cs:7
static byte Clamp(byte value, byte min, byte max)
Definition Math.cs:435
static byte Min(byte val1, byte val2)
Definition Math.cs:912
static byte Max(byte val1, byte val2)
Definition Math.cs:738
string Format(string? format, object? arg, IFormatProvider? formatProvider)
object? GetFormat(Type? formatType)
DefaultInterpolatedStringHandler(int literalLength, int formattedCount, IFormatProvider? provider)
void AppendFormatted(ReadOnlySpan< char > value, int alignment=0, string? format=null)
void AppendFormatted(string? value, int alignment=0, string? format=null)
DefaultInterpolatedStringHandler(int literalLength, int formattedCount, IFormatProvider? provider, Span< char > initialBuffer)
void AppendFormatted(object? value, int alignment=0, string? format=null)
Span< T > Slice(int start)
Definition Span.cs:271
int Length
Definition Span.cs:70