Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
OptimizedInboxTextEncoder.cs
Go to the documentation of this file.
8
10
11internal sealed class OptimizedInboxTextEncoder
12{
13 [StructLayout(LayoutKind.Explicit)]
15 {
16 [FieldOffset(0)]
17 private unsafe fixed byte AsBytes[16];
18
19 [FieldOffset(0)]
21
22 [MethodImpl(MethodImplOptions.AggressiveInlining)]
23 internal unsafe readonly bool IsAllowedAsciiCodePoint(uint codePoint)
24 {
25 if (codePoint > 127)
26 {
27 return false;
28 }
29 uint num = AsBytes[codePoint & 0xF];
30 if ((num & (uint)(1 << (int)(codePoint >> 4))) == 0)
31 {
32 return false;
33 }
34 return true;
35 }
36
37 internal unsafe void PopulateAllowedCodePoints(in AllowedBmpCodePointsBitmap allowedBmpCodePoints)
38 {
39 this = default(AllowedAsciiCodePoints);
40 for (int i = 32; i < 127; i++)
41 {
42 if (allowedBmpCodePoints.IsCharAllowed((char)i))
43 {
44 ref byte reference = ref AsBytes[i & 0xF];
45 reference |= (byte)(1 << (i >> 4));
46 }
47 }
48 }
49 }
50
51 private struct AsciiPreescapedData
52 {
53 private unsafe fixed ulong Data[128];
54
55 internal unsafe void PopulatePreescapedData(in AllowedBmpCodePointsBitmap allowedCodePointsBmp, ScalarEscaperBase innerEncoder)
56 {
57 this = default(AsciiPreescapedData);
58 byte* intPtr = stackalloc byte[16];
59 // IL initblk instruction
60 Unsafe.InitBlock(intPtr, 0, 16);
61 Span<char> span = new Span<char>(intPtr, 8);
62 Span<char> span2 = span;
63 for (int i = 0; i < 128; i++)
64 {
65 Rune value = new Rune(i);
66 ulong num;
67 int num2;
68 if (!Rune.IsControl(value) && allowedCodePointsBmp.IsCharAllowed((char)i))
69 {
70 num = (uint)i;
71 num2 = 1;
72 }
73 else
74 {
75 num2 = innerEncoder.EncodeUtf16(value, span2.Slice(0, 6));
76 num = 0uL;
77 span2.Slice(num2).Clear();
78 for (int num3 = num2 - 1; num3 >= 0; num3--)
79 {
80 uint num4 = span2[num3];
81 num = (num << 8) | num4;
82 }
83 }
84 Data[i] = num | ((ulong)(uint)num2 << 56);
85 }
86 }
87
88 [MethodImpl(MethodImplOptions.AggressiveInlining)]
89 internal unsafe readonly bool TryGetPreescapedData(uint codePoint, out ulong preescapedData)
90 {
91 if (codePoint <= 127)
92 {
93 preescapedData = Data[codePoint];
94 return true;
95 }
96 preescapedData = 0uL;
97 return false;
98 }
99 }
100
102
104
106
108
109 internal OptimizedInboxTextEncoder(ScalarEscaperBase scalarEscaper, in AllowedBmpCodePointsBitmap allowedCodePointsBmp, bool forbidHtmlSensitiveCharacters = true, ReadOnlySpan<char> extraCharactersToEscape = default(ReadOnlySpan<char>))
110 {
111 _scalarEscaper = scalarEscaper;
112 _allowedBmpCodePoints = allowedCodePointsBmp;
114 if (forbidHtmlSensitiveCharacters)
115 {
117 }
118 ReadOnlySpan<char> readOnlySpan = extraCharactersToEscape;
119 for (int i = 0; i < readOnlySpan.Length; i++)
120 {
121 char value = readOnlySpan[i];
123 }
126 }
127
128 [MethodImpl(MethodImplOptions.AggressiveInlining)]
129 [Obsolete("FindFirstCharacterToEncode has been deprecated. It should only be used by the TextEncoder adapter.")]
130 public unsafe int FindFirstCharacterToEncode(char* text, int textLength)
131 {
132 return GetIndexOfFirstCharToEncode(new ReadOnlySpan<char>(text, textLength));
133 }
134
135 [Obsolete("TryEncodeUnicodeScalar has been deprecated. It should only be used by the TextEncoder adapter.")]
136 public unsafe bool TryEncodeUnicodeScalar(int unicodeScalar, char* buffer, int bufferLength, out int numberOfCharactersWritten)
137 {
138 Span<char> destination = new Span<char>(buffer, bufferLength);
139 if (_allowedBmpCodePoints.IsCodePointAllowed((uint)unicodeScalar))
140 {
141 if (!destination.IsEmpty)
142 {
143 destination[0] = (char)unicodeScalar;
144 numberOfCharactersWritten = 1;
145 return true;
146 }
147 }
148 else
149 {
150 int num = _scalarEscaper.EncodeUtf16(new Rune(unicodeScalar), destination);
151 if (num >= 0)
152 {
153 numberOfCharactersWritten = num;
154 return true;
155 }
156 }
157 numberOfCharactersWritten = 0;
158 return false;
159 }
160
161 public OperationStatus Encode(ReadOnlySpan<char> source, Span<char> destination, out int charsConsumed, out int charsWritten, bool isFinalBlock)
162 {
164 int num = 0;
165 int num2 = 0;
166 OperationStatus result2;
167 while (true)
168 {
169 int num3;
170 Rune result;
171 if (SpanUtility.IsValidIndex(source, num))
172 {
173 char c = source[num];
174 if (_asciiPreescapedData.TryGetPreescapedData(c, out var preescapedData))
175 {
176 if (SpanUtility.IsValidIndex(destination, num2))
177 {
178 destination[num2] = (char)(byte)preescapedData;
179 if (((int)preescapedData & 0xFF00) == 0)
180 {
181 num2++;
182 num++;
183 continue;
184 }
185 preescapedData >>= 8;
186 num3 = num2 + 1;
187 while (SpanUtility.IsValidIndex(destination, num3))
188 {
189 destination[num3++] = (char)(byte)preescapedData;
190 if ((byte)(preescapedData >>= 8) != 0)
191 {
192 continue;
193 }
194 goto IL_0091;
195 }
196 }
197 goto IL_0148;
198 }
199 if (Rune.TryCreate(c, out result))
200 {
201 goto IL_00e1;
202 }
203 int index = num + 1;
204 if (SpanUtility.IsValidIndex(source, index))
205 {
206 if (Rune.TryCreate(c, source[index], out result))
207 {
208 goto IL_00e1;
209 }
210 }
211 else if (!isFinalBlock && char.IsHighSurrogate(c))
212 {
213 result2 = OperationStatus.NeedMoreData;
214 break;
215 }
216 result = Rune.ReplacementChar;
217 goto IL_010d;
218 }
219 result2 = OperationStatus.Done;
220 break;
221 IL_0148:
222 result2 = OperationStatus.DestinationTooSmall;
223 break;
224 IL_0091:
225 num2 = num3;
226 num++;
227 continue;
228 IL_010d:
229 int num4 = _scalarEscaper.EncodeUtf16(result, destination.Slice(num2));
230 if (num4 >= 0)
231 {
232 num2 += num4;
233 num += result.Utf16SequenceLength;
234 continue;
235 }
236 goto IL_0148;
237 IL_00e1:
238 if (!IsScalarValueAllowed(result))
239 {
240 goto IL_010d;
241 }
242 if (result.TryEncodeToUtf16(destination.Slice(num2), out var charsWritten2))
243 {
244 num2 += charsWritten2;
245 num += charsWritten2;
246 continue;
247 }
248 goto IL_0148;
249 }
250 charsConsumed = num;
251 charsWritten = num2;
252 return result2;
253 }
254
255 public OperationStatus EncodeUtf8(ReadOnlySpan<byte> source, Span<byte> destination, out int bytesConsumed, out int bytesWritten, bool isFinalBlock)
256 {
258 int num = 0;
259 int num2 = 0;
260 OperationStatus result2;
261 while (true)
262 {
263 int num3;
264 if (SpanUtility.IsValidIndex(source, num))
265 {
266 uint codePoint = source[num];
267 if (_asciiPreescapedData.TryGetPreescapedData(codePoint, out var preescapedData))
268 {
269 if (SpanUtility.TryWriteUInt64LittleEndian(destination, num2, preescapedData))
270 {
271 num2 += (int)(preescapedData >> 56);
272 num++;
273 continue;
274 }
275 num3 = num2;
276 while (SpanUtility.IsValidIndex(destination, num3))
277 {
278 destination[num3++] = (byte)preescapedData;
279 if ((byte)(preescapedData >>= 8) != 0)
280 {
281 continue;
282 }
283 goto IL_0076;
284 }
285 }
286 else
287 {
288 Rune result;
289 int bytesConsumed2;
290 OperationStatus operationStatus = Rune.DecodeFromUtf8(source.Slice(num), out result, out bytesConsumed2);
291 if (operationStatus != 0)
292 {
293 if (!isFinalBlock && operationStatus == OperationStatus.NeedMoreData)
294 {
295 result2 = OperationStatus.NeedMoreData;
296 break;
297 }
298 }
299 else if (IsScalarValueAllowed(result))
300 {
301 if (result.TryEncodeToUtf8(destination.Slice(num2), out var bytesWritten2))
302 {
303 num2 += bytesWritten2;
304 num += bytesWritten2;
305 continue;
306 }
307 goto IL_0103;
308 }
309 int num4 = _scalarEscaper.EncodeUtf8(result, destination.Slice(num2));
310 if (num4 >= 0)
311 {
312 num2 += num4;
313 num += bytesConsumed2;
314 continue;
315 }
316 }
317 goto IL_0103;
318 }
319 result2 = OperationStatus.Done;
320 break;
321 IL_0076:
322 num2 = num3;
323 num++;
324 continue;
325 IL_0103:
326 result2 = OperationStatus.DestinationTooSmall;
327 break;
328 }
329 bytesConsumed = num;
330 bytesWritten = num2;
331 return result2;
332 }
333
335 {
336 int length = data.Length;
338 {
339 int num;
340 fixed (byte* pData = data)
341 {
342 UIntPtr uIntPtr = ((!AdvSimd.Arm64.IsSupported || !BitConverter.IsLittleEndian) ? GetIndexOfFirstByteToEncodeSsse3(pData, (uint)length) : GetIndexOfFirstByteToEncodeAdvSimd64(pData, (uint)length));
343 num = (int)(nuint)uIntPtr;
344 }
345 if (!SpanUtility.IsValidIndex(data, num))
346 {
347 return -1;
348 }
350 {
351 return num;
352 }
353 data = data.Slice(num);
354 }
355 Rune result;
356 int bytesConsumed;
357 while (!data.IsEmpty && Rune.DecodeFromUtf8(data, out result, out bytesConsumed) == OperationStatus.Done && bytesConsumed < 4 && _allowedBmpCodePoints.IsCharAllowed((char)result.Value))
358 {
359 data = data.Slice(bytesConsumed);
360 }
361 if (!data.IsEmpty)
362 {
363 return length - data.Length;
364 }
365 return -1;
366 }
367
369 {
370 fixed (char* ptr = data)
371 {
372 nuint num = (uint)data.Length;
373 nuint num2 = 0u;
374 if (Ssse3.IsSupported)
375 {
376 num2 = GetIndexOfFirstCharToEncodeSsse3(ptr, num);
377 }
379 {
381 }
382 if (num2 < num)
383 {
385 nint num3 = 0;
386 while (true)
387 {
388 if (num - num2 >= 8)
389 {
390 num3 = -1;
391 if (_allowedBmpCodePoints.IsCharAllowed(ptr[(nuint)((nint)num2 + ++num3)]) && _allowedBmpCodePoints.IsCharAllowed(ptr[(nuint)((nint)num2 + ++num3)]) && _allowedBmpCodePoints.IsCharAllowed(ptr[(nuint)((nint)num2 + ++num3)]) && _allowedBmpCodePoints.IsCharAllowed(ptr[(nuint)((nint)num2 + ++num3)]) && _allowedBmpCodePoints.IsCharAllowed(ptr[(nuint)((nint)num2 + ++num3)]) && _allowedBmpCodePoints.IsCharAllowed(ptr[(nuint)((nint)num2 + ++num3)]) && _allowedBmpCodePoints.IsCharAllowed(ptr[(nuint)((nint)num2 + ++num3)]) && _allowedBmpCodePoints.IsCharAllowed(ptr[(nuint)((nint)num2 + ++num3)]))
392 {
393 num2 += 8;
394 continue;
395 }
396 num2 += (nuint)num3;
397 break;
398 }
399 for (; num2 < num && _allowedBmpCodePoints.IsCharAllowed(ptr[num2]); num2++)
400 {
401 }
402 break;
403 }
404 }
405 int num4 = (int)num2;
406 if (num4 == (int)num)
407 {
408 num4 = -1;
409 }
410 return num4;
411 }
412 }
413
414 [MethodImpl(MethodImplOptions.AggressiveInlining)]
416 {
418 }
419
420 [MethodImpl(MethodImplOptions.AggressiveInlining)]
421 private void _AssertThisNotNull()
422 {
423 _ = GetType() == typeof(OptimizedInboxTextEncoder);
424 }
425
426 private unsafe nuint GetIndexOfFirstByteToEncodeSsse3(byte* pData, nuint lengthInBytes)
427 {
429 Vector128<byte> right = Vector128.Create((byte)7);
430 Vector128<byte> value = Vector128.Create(1, 2, 4, 8, 16, 32, 64, 128, 0, 0, 0, 0, 0, 0, 0, 0);
432 nuint num = 0u;
433 if (lengthInBytes < 16)
434 {
435 goto IL_00b3;
436 }
437 nuint num2 = lengthInBytes & unchecked((nuint)(-16));
438 int num3;
439 while (true)
440 {
441 Vector128<byte> vector = Sse2.LoadVector128(pData + num);
442 Vector128<byte> left = Ssse3.Shuffle(asVector, vector);
443 Vector128<byte> right2 = Ssse3.Shuffle(value, Sse2.And(Sse2.ShiftRightLogical(vector.AsUInt32(), 4).AsByte(), right));
444 Vector128<byte> left2 = Sse2.And(left, right2);
445 num3 = Sse2.MoveMask(Sse2.CompareEqual(left2, zero));
446 if (((uint)num3 & 0xFFFFu) != 0)
447 {
448 break;
449 }
450 if ((num += 16) < num2)
451 {
452 continue;
453 }
454 goto IL_00b3;
455 }
456 goto IL_01af;
457 IL_00b3:
458 if ((lengthInBytes & 8) != 0)
459 {
460 Vector128<byte> vector2 = Sse2.LoadScalarVector128((ulong*)(pData + num)).AsByte();
461 Vector128<byte> left3 = Ssse3.Shuffle(asVector, vector2);
462 Vector128<byte> right3 = Ssse3.Shuffle(value, Sse2.And(Sse2.ShiftRightLogical(vector2.AsUInt32(), 4).AsByte(), right));
463 Vector128<byte> left4 = Sse2.And(left3, right3);
464 num3 = Sse2.MoveMask(Sse2.CompareEqual(left4, zero));
465 if ((byte)num3 != 0)
466 {
467 goto IL_01af;
468 }
469 num += 8;
470 }
471 if ((lengthInBytes & 4) != 0)
472 {
473 Vector128<byte> vector3 = Sse2.LoadScalarVector128((uint*)(pData + num)).AsByte();
474 Vector128<byte> left5 = Ssse3.Shuffle(asVector, vector3);
475 Vector128<byte> right4 = Ssse3.Shuffle(value, Sse2.And(Sse2.ShiftRightLogical(vector3.AsUInt32(), 4).AsByte(), right));
476 Vector128<byte> left6 = Sse2.And(left5, right4);
477 num3 = Sse2.MoveMask(Sse2.CompareEqual(left6, zero));
478 if (((uint)num3 & 0xFu) != 0)
479 {
480 goto IL_01af;
481 }
482 num += 4;
483 }
484 if ((lengthInBytes & 3) != 0)
485 {
486 while (_allowedAsciiCodePoints.IsAllowedAsciiCodePoint(pData[num]) && ++num != lengthInBytes)
487 {
488 }
489 }
490 goto IL_01ac;
491 IL_01af:
492 num += (uint)BitOperations.TrailingZeroCount(num3);
493 goto IL_01ac;
494 IL_01ac:
495 return num;
496 }
497
498 private unsafe nuint GetIndexOfFirstCharToEncodeSsse3(char* pData, nuint lengthInChars)
499 {
501 Vector128<byte> right = Vector128.Create((byte)7);
502 Vector128<byte> value = Vector128.Create(1, 2, 4, 8, 16, 32, 64, 128, 0, 0, 0, 0, 0, 0, 0, 0);
504 nuint num = 0u;
505 if (lengthInChars < 16)
506 {
507 goto IL_00d4;
508 }
509 nuint num2 = lengthInChars & unchecked((nuint)(-16));
510 int num3;
511 while (true)
512 {
513 Vector128<byte> vector = Sse2.PackUnsignedSaturate(Sse2.LoadVector128((short*)(pData + num)), Sse2.LoadVector128((short*)(pData + 8 + num)));
514 Vector128<byte> left = Ssse3.Shuffle(asVector, vector);
515 Vector128<byte> right2 = Ssse3.Shuffle(value, Sse2.And(Sse2.ShiftRightLogical(vector.AsUInt32(), 4).AsByte(), right));
516 Vector128<byte> left2 = Sse2.And(left, right2);
517 num3 = Sse2.MoveMask(Sse2.CompareEqual(left2, zero));
518 if (((uint)num3 & 0xFFFFu) != 0)
519 {
520 break;
521 }
522 if ((num += 16) < num2)
523 {
524 continue;
525 }
526 goto IL_00d4;
527 }
528 goto IL_01ea;
529 IL_00d4:
530 if ((lengthInChars & 8) != 0)
531 {
532 Vector128<byte> vector2 = Sse2.PackUnsignedSaturate(Sse2.LoadVector128((short*)(pData + num)), zero.AsInt16());
533 Vector128<byte> left3 = Ssse3.Shuffle(asVector, vector2);
534 Vector128<byte> right3 = Ssse3.Shuffle(value, Sse2.And(Sse2.ShiftRightLogical(vector2.AsUInt32(), 4).AsByte(), right));
535 Vector128<byte> left4 = Sse2.And(left3, right3);
536 num3 = Sse2.MoveMask(Sse2.CompareEqual(left4, zero));
537 if ((byte)num3 != 0)
538 {
539 goto IL_01ea;
540 }
541 num += 8;
542 }
543 if ((lengthInChars & 4) != 0)
544 {
545 Vector128<byte> vector3 = Sse2.PackUnsignedSaturate(Sse2.LoadScalarVector128((ulong*)(pData + num)).AsInt16(), zero.AsInt16());
546 Vector128<byte> left5 = Ssse3.Shuffle(asVector, vector3);
547 Vector128<byte> right4 = Ssse3.Shuffle(value, Sse2.And(Sse2.ShiftRightLogical(vector3.AsUInt32(), 4).AsByte(), right));
548 Vector128<byte> left6 = Sse2.And(left5, right4);
549 num3 = Sse2.MoveMask(Sse2.CompareEqual(left6, zero));
550 if (((uint)num3 & 0xFu) != 0)
551 {
552 goto IL_01ea;
553 }
554 num += 4;
555 }
556 if ((lengthInChars & 3) != 0)
557 {
558 while (_allowedAsciiCodePoints.IsAllowedAsciiCodePoint(pData[num]) && ++num != lengthInChars)
559 {
560 }
561 }
562 goto IL_01e7;
563 IL_01ea:
564 num += (uint)BitOperations.TrailingZeroCount(num3);
565 goto IL_01e7;
566 IL_01e7:
567 return num;
568 }
569
570 private unsafe nuint GetIndexOfFirstByteToEncodeAdvSimd64(byte* pData, nuint lengthInBytes)
571 {
572 Vector128<byte> right = Vector128.Create((byte)15);
573 Vector128<byte> table = Vector128.Create(1, 2, 4, 8, 16, 32, 64, 128, 0, 0, 0, 0, 0, 0, 0, 0);
574 Vector128<byte> right2 = Vector128.Create((ushort)61455).AsByte();
576 nuint num = 0u;
577 if (lengthInBytes < 16)
578 {
579 goto IL_00ca;
580 }
581 nuint num2 = lengthInBytes & unchecked((nuint)(-16));
582 ulong num3;
583 while (true)
584 {
585 Vector128<byte> vector = AdvSimd.LoadVector128(pData + num);
586 Vector128<byte> left = AdvSimd.Arm64.VectorTableLookup(asVector, AdvSimd.And(vector, right));
587 Vector128<byte> right3 = AdvSimd.Arm64.VectorTableLookup(table, AdvSimd.ShiftRightArithmetic(vector.AsSByte(), 4).AsByte());
588 Vector128<byte> left2 = AdvSimd.CompareTest(left, right3);
589 Vector128<byte> vector2 = AdvSimd.And(left2, right2);
590 num3 = AdvSimd.Arm64.AddPairwise(vector2, vector2).AsUInt64().ToScalar();
591 if (num3 != ulong.MaxValue)
592 {
593 break;
594 }
595 if ((num += 16) < num2)
596 {
597 continue;
598 }
599 goto IL_00ca;
600 }
601 num += (uint)(BitOperations.TrailingZeroCount(~num3) >>> 2);
602 goto IL_01c7;
603 IL_01c7:
604 return num;
605 IL_00ca:
606 if ((lengthInBytes & 8) != 0)
607 {
608 Vector128<byte> vector3 = AdvSimd.LoadVector64(pData + num).ToVector128Unsafe();
609 Vector128<byte> left3 = AdvSimd.Arm64.VectorTableLookup(asVector, AdvSimd.And(vector3, right));
610 Vector128<byte> right4 = AdvSimd.Arm64.VectorTableLookup(table, AdvSimd.ShiftRightArithmetic(vector3.AsSByte(), 4).AsByte());
611 Vector128<byte> vector4 = AdvSimd.CompareTest(left3, right4);
612 num3 = vector4.AsUInt64().ToScalar();
613 if (num3 != ulong.MaxValue)
614 {
615 goto IL_01dc;
616 }
617 num += 8;
618 }
619 if ((lengthInBytes & 4) != 0)
620 {
621 Vector128<byte> vector5 = Vector128.CreateScalarUnsafe(Unsafe.ReadUnaligned<uint>(pData + num)).AsByte();
622 Vector128<byte> left4 = AdvSimd.Arm64.VectorTableLookup(asVector, AdvSimd.And(vector5, right));
623 Vector128<byte> right5 = AdvSimd.Arm64.VectorTableLookup(table, AdvSimd.ShiftRightArithmetic(vector5.AsSByte(), 4).AsByte());
624 Vector128<byte> vector6 = AdvSimd.CompareTest(left4, right5);
625 num3 = vector6.AsUInt32().ToScalar();
626 if (num3 != uint.MaxValue)
627 {
628 goto IL_01dc;
629 }
630 num += 4;
631 }
632 if ((lengthInBytes & 3) != 0)
633 {
634 while (_allowedAsciiCodePoints.IsAllowedAsciiCodePoint(pData[num]) && ++num != lengthInBytes)
635 {
636 }
637 }
638 goto IL_01c7;
639 IL_01dc:
640 num += (uint)(BitOperations.TrailingZeroCount(~num3) >>> 3);
641 goto IL_01c7;
642 }
643
644 private unsafe nuint GetIndexOfFirstCharToEncodeAdvSimd64(char* pData, nuint lengthInChars)
645 {
646 Vector128<byte> right = Vector128.Create((byte)15);
647 Vector128<byte> table = Vector128.Create(1, 2, 4, 8, 16, 32, 64, 128, 0, 0, 0, 0, 0, 0, 0, 0);
648 Vector128<byte> right2 = Vector128.Create((ushort)61455).AsByte();
650 nuint num = 0u;
651 if (lengthInChars < 16)
652 {
653 goto IL_00f0;
654 }
655 nuint num2 = lengthInChars & unchecked((nuint)(-16));
656 ulong num3;
657 while (true)
658 {
660 Vector128<byte> left = AdvSimd.Arm64.VectorTableLookup(asVector, AdvSimd.And(vector, right));
661 Vector128<byte> right3 = AdvSimd.Arm64.VectorTableLookup(table, AdvSimd.ShiftRightArithmetic(vector.AsSByte(), 4).AsByte());
662 Vector128<byte> left2 = AdvSimd.CompareTest(left, right3);
663 Vector128<byte> vector2 = AdvSimd.And(left2, right2);
664 num3 = AdvSimd.Arm64.AddPairwise(vector2, vector2).AsUInt64().ToScalar();
665 if (num3 != ulong.MaxValue)
666 {
667 break;
668 }
669 if ((num += 16) < num2)
670 {
671 continue;
672 }
673 goto IL_00f0;
674 }
675 num += (uint)(BitOperations.TrailingZeroCount(~num3) >>> 2);
676 goto IL_0205;
677 IL_0205:
678 return num;
679 IL_00f0:
680 if ((lengthInChars & 8) != 0)
681 {
682 Vector128<byte> vector3 = AdvSimd.ExtractNarrowingSaturateUnsignedLower(AdvSimd.LoadVector128((short*)(pData + num))).AsByte().ToVector128Unsafe();
683 Vector128<byte> left3 = AdvSimd.Arm64.VectorTableLookup(asVector, AdvSimd.And(vector3, right));
684 Vector128<byte> right4 = AdvSimd.Arm64.VectorTableLookup(table, AdvSimd.ShiftRightArithmetic(vector3.AsSByte(), 4).AsByte());
685 Vector128<byte> vector4 = AdvSimd.CompareTest(left3, right4);
686 num3 = vector4.AsUInt64().ToScalar();
687 if (num3 != ulong.MaxValue)
688 {
689 goto IL_021a;
690 }
691 num += 8;
692 }
693 if ((lengthInChars & 4) != 0)
694 {
695 Vector128<byte> vector5 = AdvSimd.ExtractNarrowingSaturateUnsignedLower(AdvSimd.LoadVector64((short*)(pData + num)).ToVector128Unsafe()).ToVector128Unsafe();
696 Vector128<byte> left4 = AdvSimd.Arm64.VectorTableLookup(asVector, AdvSimd.And(vector5, right));
697 Vector128<byte> right5 = AdvSimd.Arm64.VectorTableLookup(table, AdvSimd.ShiftRightArithmetic(vector5.AsSByte(), 4).AsByte());
698 Vector128<byte> vector6 = AdvSimd.CompareTest(left4, right5);
699 num3 = vector6.AsUInt32().ToScalar();
700 if (num3 != uint.MaxValue)
701 {
702 goto IL_021a;
703 }
704 num += 4;
705 }
706 if ((lengthInChars & 3) != 0)
707 {
708 while (_allowedAsciiCodePoints.IsAllowedAsciiCodePoint(pData[num]) && ++num != lengthInChars)
709 {
710 }
711 }
712 goto IL_0205;
713 IL_021a:
714 num += (uint)(BitOperations.TrailingZeroCount(~num3) >>> 3);
715 goto IL_0205;
716 }
717}
static readonly bool IsLittleEndian
static int TrailingZeroCount(int value)
static unsafe void InitBlock(void *startAddress, byte value, uint byteCount)
Definition Unsafe.cs:117
static Vector128< byte > VectorTableLookup(Vector128< byte > table, Vector128< byte > byteIndexes)
Definition AdvSimd.cs:2774
static Vector128< byte > AddPairwise(Vector128< byte > left, Vector128< byte > right)
Definition AdvSimd.cs:239
static unsafe Vector128< byte > LoadVector128(byte *address)
Definition AdvSimd.cs:6034
static Vector64< byte > And(Vector64< byte > left, Vector64< byte > right)
Definition AdvSimd.cs:3919
static Vector64< short > ShiftRightArithmetic(Vector64< short > value, byte count)
Definition AdvSimd.cs:9369
static Vector64< byte > ExtractNarrowingSaturateUnsignedLower(Vector128< short > value)
Definition AdvSimd.cs:5204
static unsafe Vector64< byte > LoadVector64(byte *address)
Definition AdvSimd.cs:5984
static Vector128< byte > ExtractNarrowingSaturateUnsignedUpper(Vector64< byte > lower, Vector128< short > value)
Definition AdvSimd.cs:5219
static Vector64< byte > CompareTest(Vector64< byte > left, Vector64< byte > right)
Definition AdvSimd.cs:4589
static Vector128< byte > Create(byte value)
Definition Vector128.cs:138
static unsafe Vector128< byte > CreateScalarUnsafe(byte value)
Definition Vector128.cs:829
static unsafe Vector128< sbyte > LoadVector128(sbyte *address)
Definition Sse2.cs:582
static unsafe Vector128< double > LoadScalarVector128(double *address)
Definition Sse2.cs:627
static int MoveMask(Vector128< sbyte > value)
Definition Sse2.cs:772
static Vector128< sbyte > CompareEqual(Vector128< sbyte > left, Vector128< sbyte > right)
Definition Sse2.cs:232
static Vector128< byte > PackUnsignedSaturate(Vector128< short > left, Vector128< short > right)
Definition Sse2.cs:892
static Vector128< byte > And(Vector128< byte > left, Vector128< byte > right)
Definition Sse2.cs:132
static Vector128< short > ShiftRightLogical(Vector128< short > value, Vector128< short > count)
Definition Sse2.cs:1057
static Vector128< sbyte > Shuffle(Vector128< sbyte > value, Vector128< sbyte > mask)
Definition Ssse3.cs:112
OperationStatus Encode(ReadOnlySpan< char > source, Span< char > destination, out int charsConsumed, out int charsWritten, bool isFinalBlock)
unsafe bool TryEncodeUnicodeScalar(int unicodeScalar, char *buffer, int bufferLength, out int numberOfCharactersWritten)
unsafe nuint GetIndexOfFirstCharToEncodeSsse3(char *pData, nuint lengthInChars)
unsafe nuint GetIndexOfFirstByteToEncodeAdvSimd64(byte *pData, nuint lengthInBytes)
unsafe int GetIndexOfFirstByteToEncode(ReadOnlySpan< byte > data)
unsafe int GetIndexOfFirstCharToEncode(ReadOnlySpan< char > data)
unsafe int FindFirstCharacterToEncode(char *text, int textLength)
OperationStatus EncodeUtf8(ReadOnlySpan< byte > source, Span< byte > destination, out int bytesConsumed, out int bytesWritten, bool isFinalBlock)
OptimizedInboxTextEncoder(ScalarEscaperBase scalarEscaper, in AllowedBmpCodePointsBitmap allowedCodePointsBmp, bool forbidHtmlSensitiveCharacters=true, ReadOnlySpan< char > extraCharactersToEscape=default(ReadOnlySpan< char >))
unsafe nuint GetIndexOfFirstByteToEncodeSsse3(byte *pData, nuint lengthInBytes)
unsafe nuint GetIndexOfFirstCharToEncodeAdvSimd64(char *pData, nuint lengthInChars)
int EncodeUtf16(Rune value, Span< char > destination)
int EncodeUtf8(Rune value, Span< byte > destination)
static bool TryWriteUInt64LittleEndian(Span< byte > span, int offset, ulong value)
static bool IsAsciiCodePoint(uint value)
ReadOnlySpan< T > Slice(int start)
Span< T > Slice(int start)
Definition Span.cs:271
unsafe void PopulateAllowedCodePoints(in AllowedBmpCodePointsBitmap allowedBmpCodePoints)
unsafe void PopulatePreescapedData(in AllowedBmpCodePointsBitmap allowedCodePointsBmp, ScalarEscaperBase innerEncoder)
unsafe readonly bool TryGetPreescapedData(uint codePoint, out ulong preescapedData)
static bool IsControl(Rune value)
Definition Rune.cs:710
int Utf16SequenceLength
Definition Rune.cs:55
static OperationStatus DecodeFromUtf8(ReadOnlySpan< byte > source, out Rune result, out int bytesConsumed)
Definition Rune.cs:202
static Rune ReplacementChar
Definition Rune.cs:53
static bool TryCreate(char ch, out Rune result)
Definition Rune.cs:511
bool TryEncodeToUtf8(Span< byte > destination, out int bytesWritten)
Definition Rune.cs:580
bool TryEncodeToUtf16(Span< char > destination, out int charsWritten)
Definition Rune.cs:553