Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
ValueStringBuilder.cs
Go to the documentation of this file.
4
5namespace System.Text;
6
7internal ref struct ValueStringBuilder
8{
9 private char[] _arrayToReturnToPool;
10
11 private Span<char> _chars;
12
13 private int _pos;
14
15 public int Length
16 {
17 get
18 {
19 return _pos;
20 }
21 set
22 {
23 _pos = value;
24 }
25 }
26
27 public int Capacity => _chars.Length;
28
29 public ref char this[int index] => ref _chars[index];
30
32
33 internal void AppendSpanFormattable<T>(T value, string format, IFormatProvider provider) where T : ISpanFormattable
34 {
35 if (value.TryFormat(_chars.Slice(_pos), out var charsWritten, format, provider))
36 {
37 _pos += charsWritten;
38 }
39 else
40 {
41 Append(value.ToString(format, provider));
42 }
43 }
44
45 internal void AppendFormatHelper(IFormatProvider provider, string format, ParamsArray args)
46 {
47 if (format == null)
48 {
49 throw new ArgumentNullException("format");
50 }
51 int num = 0;
52 int length = format.Length;
53 char c = '\0';
54 ICustomFormatter customFormatter = (ICustomFormatter)(provider?.GetFormat(typeof(ICustomFormatter)));
55 while (true)
56 {
57 if (num < length)
58 {
59 c = format[num];
60 num++;
61 if (c == '}')
62 {
63 if (num < length && format[num] == '}')
64 {
65 num++;
66 }
67 else
68 {
70 }
71 }
72 else if (c == '{')
73 {
74 if (num >= length || format[num] != '{')
75 {
76 num--;
77 goto IL_008f;
78 }
79 num++;
80 }
81 Append(c);
82 continue;
83 }
84 goto IL_008f;
85 IL_008f:
86 if (num == length)
87 {
88 break;
89 }
90 num++;
91 if (num == length || (c = format[num]) < '0' || c > '9')
92 {
94 }
95 int num2 = 0;
96 do
97 {
98 num2 = num2 * 10 + c - 48;
99 num++;
100 if (num == length)
101 {
103 }
104 c = format[num];
105 }
106 while (c >= '0' && c <= '9' && num2 < 1000000);
107 if (num2 >= args.Length)
108 {
110 }
111 for (; num < length; num++)
112 {
113 if ((c = format[num]) != ' ')
114 {
115 break;
116 }
117 }
118 bool flag = false;
119 int num3 = 0;
120 if (c == ',')
121 {
122 for (num++; num < length && format[num] == ' '; num++)
123 {
124 }
125 if (num == length)
126 {
128 }
129 c = format[num];
130 if (c == '-')
131 {
132 flag = true;
133 num++;
134 if (num == length)
135 {
137 }
138 c = format[num];
139 }
140 if (c < '0' || c > '9')
141 {
143 }
144 do
145 {
146 num3 = num3 * 10 + c - 48;
147 num++;
148 if (num == length)
149 {
151 }
152 c = format[num];
153 }
154 while (c >= '0' && c <= '9' && num3 < 1000000);
155 }
156 for (; num < length; num++)
157 {
158 if ((c = format[num]) != ' ')
159 {
160 break;
161 }
162 }
163 object obj = args[num2];
164 ReadOnlySpan<char> readOnlySpan = default(ReadOnlySpan<char>);
165 switch (c)
166 {
167 case ':':
168 {
169 num++;
170 int num4 = num;
171 while (true)
172 {
173 if (num == length)
174 {
176 }
177 c = format[num];
178 switch (c)
179 {
180 case '{':
182 goto IL_0205;
183 default:
184 goto IL_0205;
185 case '}':
186 break;
187 }
188 break;
189 IL_0205:
190 num++;
191 }
192 if (num > num4)
193 {
194 readOnlySpan = format.AsSpan(num4, num - num4);
195 }
196 break;
197 }
198 default:
200 break;
201 case '}':
202 break;
203 }
204 num++;
205 string text = null;
206 string text2 = null;
207 if (customFormatter != null)
208 {
209 if (readOnlySpan.Length != 0)
210 {
211 text2 = new string(readOnlySpan);
212 }
213 text = customFormatter.Format(text2, obj, provider);
214 }
215 if (text == null)
216 {
217 if (obj is ISpanFormattable spanFormattable && (flag || num3 == 0) && spanFormattable.TryFormat(_chars.Slice(_pos), out var charsWritten, readOnlySpan, provider))
218 {
219 _pos += charsWritten;
220 int num5 = num3 - charsWritten;
221 if (flag && num5 > 0)
222 {
223 Append(' ', num5);
224 }
225 continue;
226 }
227 if (obj is IFormattable formattable)
228 {
229 if (readOnlySpan.Length != 0 && text2 == null)
230 {
231 text2 = new string(readOnlySpan);
232 }
233 text = formattable.ToString(text2, provider);
234 }
235 else if (obj != null)
236 {
237 text = obj.ToString();
238 }
239 }
240 if (text == null)
241 {
242 text = string.Empty;
243 }
244 int num6 = num3 - text.Length;
245 if (!flag && num6 > 0)
246 {
247 Append(' ', num6);
248 }
249 Append(text);
250 if (flag && num6 > 0)
251 {
252 Append(' ', num6);
253 }
254 }
255 }
256
257 private static void ThrowFormatError()
258 {
260 }
261
262 public ValueStringBuilder(Span<char> initialBuffer)
263 {
265 _chars = initialBuffer;
266 _pos = 0;
267 }
268
269 public ValueStringBuilder(int initialCapacity)
270 {
271 _arrayToReturnToPool = ArrayPool<char>.Shared.Rent(initialCapacity);
273 _pos = 0;
274 }
275
276 public void EnsureCapacity(int capacity)
277 {
278 if ((uint)capacity > (uint)_chars.Length)
279 {
280 Grow(capacity - _pos);
281 }
282 }
283
284 public ref char GetPinnableReference()
285 {
286 return ref MemoryMarshal.GetReference(_chars);
287 }
288
289 public ref char GetPinnableReference(bool terminate)
290 {
291 if (terminate)
292 {
294 _chars[Length] = '\0';
295 }
296 return ref MemoryMarshal.GetReference(_chars);
297 }
298
299 public override string ToString()
300 {
301 string result = _chars.Slice(0, _pos).ToString();
302 Dispose();
303 return result;
304 }
305
306 public ReadOnlySpan<char> AsSpan(bool terminate)
307 {
308 if (terminate)
309 {
311 _chars[Length] = '\0';
312 }
313 return _chars.Slice(0, _pos);
314 }
315
317 {
318 return _chars.Slice(0, _pos);
319 }
320
322 {
323 return _chars.Slice(start, _pos - start);
324 }
325
327 {
328 return _chars.Slice(start, length);
329 }
330
331 public bool TryCopyTo(Span<char> destination, out int charsWritten)
332 {
333 if (_chars.Slice(0, _pos).TryCopyTo(destination))
334 {
335 charsWritten = _pos;
336 Dispose();
337 return true;
338 }
339 charsWritten = 0;
340 Dispose();
341 return false;
342 }
343
344 public void Insert(int index, string s)
345 {
346 if (s != null)
347 {
348 int length = s.Length;
349 if (_pos > _chars.Length - length)
350 {
351 Grow(length);
352 }
353 int length2 = _pos - index;
355 s.CopyTo(_chars.Slice(index));
356 _pos += length;
357 }
358 }
359
360 [MethodImpl(MethodImplOptions.AggressiveInlining)]
361 public void Append(char c)
362 {
363 int pos = _pos;
364 if ((uint)pos < (uint)_chars.Length)
365 {
366 _chars[pos] = c;
367 _pos = pos + 1;
368 }
369 else
370 {
371 GrowAndAppend(c);
372 }
373 }
374
375 [MethodImpl(MethodImplOptions.AggressiveInlining)]
376 public void Append(string s)
377 {
378 if (s != null)
379 {
380 int pos = _pos;
381 if (s.Length == 1 && (uint)pos < (uint)_chars.Length)
382 {
383 _chars[pos] = s[0];
384 _pos = pos + 1;
385 }
386 else
387 {
388 AppendSlow(s);
389 }
390 }
391 }
392
393 private void AppendSlow(string s)
394 {
395 int pos = _pos;
396 if (pos > _chars.Length - s.Length)
397 {
398 Grow(s.Length);
399 }
400 s.CopyTo(_chars.Slice(pos));
401 _pos += s.Length;
402 }
403
404 public void Append(char c, int count)
405 {
406 if (_pos > _chars.Length - count)
407 {
408 Grow(count);
409 }
411 for (int i = 0; i < span.Length; i++)
412 {
413 span[i] = c;
414 }
415 _pos += count;
416 }
417
418 public unsafe void Append(char* value, int length)
419 {
420 int pos = _pos;
421 if (pos > _chars.Length - length)
422 {
423 Grow(length);
424 }
426 for (int i = 0; i < span.Length; i++)
427 {
428 span[i] = *(value++);
429 }
430 _pos += length;
431 }
432
434 {
435 int pos = _pos;
436 if (pos > _chars.Length - value.Length)
437 {
438 Grow(value.Length);
439 }
440 value.CopyTo(_chars.Slice(_pos));
441 _pos += value.Length;
442 }
443
444 [MethodImpl(MethodImplOptions.AggressiveInlining)]
446 {
447 int pos = _pos;
448 if (pos > _chars.Length - length)
449 {
450 Grow(length);
451 }
452 _pos = pos + length;
453 return _chars.Slice(pos, length);
454 }
455
456 [MethodImpl(MethodImplOptions.NoInlining)]
457 private void GrowAndAppend(char c)
458 {
459 Grow(1);
460 Append(c);
461 }
462
463 [MethodImpl(MethodImplOptions.NoInlining)]
464 private void Grow(int additionalCapacityBeyondPos)
465 {
466 char[] array = ArrayPool<char>.Shared.Rent((int)Math.Max((uint)(_pos + additionalCapacityBeyondPos), (uint)(_chars.Length * 2)));
467 _chars.Slice(0, _pos).CopyTo(array);
468 char[] arrayToReturnToPool = _arrayToReturnToPool;
470 if (arrayToReturnToPool != null)
471 {
472 ArrayPool<char>.Shared.Return(arrayToReturnToPool);
473 }
474 }
475
476 [MethodImpl(MethodImplOptions.AggressiveInlining)]
477 public void Dispose()
478 {
479 char[] arrayToReturnToPool = _arrayToReturnToPool;
480 this = default(ValueStringBuilder);
481 if (arrayToReturnToPool != null)
482 {
483 ArrayPool<char>.Shared.Return(arrayToReturnToPool);
484 }
485 }
486}
static ArrayPool< T > Shared
Definition ArrayPool.cs:7
static byte Max(byte val1, byte val2)
Definition Math.cs:738
static string Format_IndexOutOfRange
Definition SR.cs:1348
static string Format_InvalidString
Definition SR.cs:1354
Definition SR.cs:7
string Format(string? format, object? arg, IFormatProvider? formatProvider)
bool TryFormat(Span< char > destination, out int charsWritten, ReadOnlySpan< char > format, IFormatProvider? provider)
Span< T > Slice(int start)
Definition Span.cs:271
int Length
Definition Span.cs:70
void Insert(int index, string s)
ValueStringBuilder(Span< char > initialBuffer)
ReadOnlySpan< char > AsSpan(bool terminate)
void AppendFormatHelper(IFormatProvider provider, string format, ParamsArray args)
bool TryCopyTo(Span< char > destination, out int charsWritten)
unsafe void Append(char *value, int length)
ref char GetPinnableReference(bool terminate)
Span< char > AppendSpan(int length)
ReadOnlySpan< char > AsSpan(int start, int length)
void Append(ReadOnlySpan< char > value)
void AppendSpanFormattable< T >(T value, string format, IFormatProvider provider)
void Grow(int additionalCapacityBeyondPos)
ReadOnlySpan< char > AsSpan(int start)
ValueStringBuilder(int initialCapacity)