Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
IdnMapping.cs
Go to the documentation of this file.
4using System.Text;
5
7
8public sealed class IdnMapping
9{
10 private bool _allowUnassigned;
11
12 private bool _useStd3AsciiRules;
13
14 private static readonly char[] s_dotSeparators = new char[4] { '.', '。', '.', '。' };
15
16 public bool AllowUnassigned
17 {
18 get
19 {
20 return _allowUnassigned;
21 }
22 set
23 {
25 }
26 }
27
29 {
30 get
31 {
32 return _useStd3AsciiRules;
33 }
34 set
35 {
37 }
38 }
39
40 private uint IcuFlags => (AllowUnassigned ? 1u : 0u) | (UseStd3AsciiRules ? 2u : 0u);
41
42 private uint NlsFlags => (AllowUnassigned ? 1u : 0u) | (UseStd3AsciiRules ? 2u : 0u);
43
44 public string GetAscii(string unicode)
45 {
46 return GetAscii(unicode, 0);
47 }
48
49 public string GetAscii(string unicode, int index)
50 {
51 if (unicode == null)
52 {
53 throw new ArgumentNullException("unicode");
54 }
55 return GetAscii(unicode, index, unicode.Length - index);
56 }
57
58 public unsafe string GetAscii(string unicode, int index, int count)
59 {
60 if (unicode == null)
61 {
62 throw new ArgumentNullException("unicode");
63 }
64 if (index < 0 || count < 0)
65 {
66 throw new ArgumentOutOfRangeException((index < 0) ? "index" : "count", SR.ArgumentOutOfRange_NeedNonNegNum);
67 }
68 if (index > unicode.Length)
69 {
71 }
72 if (index > unicode.Length - count)
73 {
75 }
76 if (count == 0)
77 {
78 throw new ArgumentException(SR.Argument_IdnBadLabelSize, "unicode");
79 }
80 if (unicode[index + count - 1] == '\0')
81 {
83 }
85 {
86 return GetAsciiInvariant(unicode, index, count);
87 }
88 fixed (char* ptr = unicode)
89 {
91 {
92 return IcuGetAsciiCore(unicode, ptr + index, count);
93 }
94 return NlsGetAsciiCore(unicode, ptr + index, count);
95 }
96 }
97
98 public string GetUnicode(string ascii)
99 {
100 return GetUnicode(ascii, 0);
101 }
102
103 public string GetUnicode(string ascii, int index)
104 {
105 if (ascii == null)
106 {
107 throw new ArgumentNullException("ascii");
108 }
109 return GetUnicode(ascii, index, ascii.Length - index);
110 }
111
112 public unsafe string GetUnicode(string ascii, int index, int count)
113 {
114 if (ascii == null)
115 {
116 throw new ArgumentNullException("ascii");
117 }
118 if (index < 0 || count < 0)
119 {
120 throw new ArgumentOutOfRangeException((index < 0) ? "index" : "count", SR.ArgumentOutOfRange_NeedNonNegNum);
121 }
122 if (index > ascii.Length)
123 {
125 }
126 if (index > ascii.Length - count)
127 {
129 }
130 if (count > 0 && ascii[index + count - 1] == '\0')
131 {
132 throw new ArgumentException(SR.Argument_IdnBadPunycode, "ascii");
133 }
135 {
136 return GetUnicodeInvariant(ascii, index, count);
137 }
138 fixed (char* ptr = ascii)
139 {
141 {
142 return IcuGetUnicodeCore(ascii, ptr + index, count);
143 }
144 return NlsGetUnicodeCore(ascii, ptr + index, count);
145 }
146 }
147
148 public override bool Equals([NotNullWhen(true)] object? obj)
149 {
150 if (obj is IdnMapping idnMapping && _allowUnassigned == idnMapping._allowUnassigned)
151 {
152 return _useStd3AsciiRules == idnMapping._useStd3AsciiRules;
153 }
154 return false;
155 }
156
157 public override int GetHashCode()
158 {
159 return (_allowUnassigned ? 100 : 200) + (_useStd3AsciiRules ? 1000 : 2000);
160 }
161
162 [MethodImpl(MethodImplOptions.AggressiveInlining)]
163 private unsafe static string GetStringForOutput(string originalString, char* input, int inputLength, char* output, int outputLength)
164 {
165 if (originalString.Length == inputLength && inputLength == outputLength && Ordinal.EqualsIgnoreCase(ref *input, ref *output, inputLength))
166 {
167 return originalString;
168 }
169 return new string(output, 0, outputLength);
170 }
171
172 private string GetAsciiInvariant(string unicode, int index, int count)
173 {
174 if (index > 0 || count < unicode.Length)
175 {
176 unicode = unicode.Substring(index, count);
177 }
178 if (ValidateStd3AndAscii(unicode, UseStd3AsciiRules, bCheckAscii: true))
179 {
180 return unicode;
181 }
182 if (unicode[^1] <= '\u001f')
183 {
184 throw new ArgumentException(SR.Format(SR.Argument_InvalidCharSequence, unicode.Length - 1), "unicode");
185 }
187 {
188 ValidateStd3AndAscii(unicode, bUseStd3: true, bCheckAscii: false);
189 }
190 return PunycodeEncode(unicode);
191 }
192
193 private static bool ValidateStd3AndAscii(string unicode, bool bUseStd3, bool bCheckAscii)
194 {
195 if (unicode.Length == 0)
196 {
197 throw new ArgumentException(SR.Argument_IdnBadLabelSize, "unicode");
198 }
199 int num = -1;
200 for (int i = 0; i < unicode.Length; i++)
201 {
202 if (unicode[i] <= '\u001f')
203 {
205 }
206 if (bCheckAscii && unicode[i] >= '\u007f')
207 {
208 return false;
209 }
210 if (IsDot(unicode[i]))
211 {
212 if (i == num + 1)
213 {
214 throw new ArgumentException(SR.Argument_IdnBadLabelSize, "unicode");
215 }
216 if (i - num > 64)
217 {
218 throw new ArgumentException(SR.Argument_IdnBadLabelSize, "unicode");
219 }
220 if (bUseStd3 && i > 0)
221 {
222 ValidateStd3(unicode[i - 1], bNextToDot: true);
223 }
224 num = i;
225 }
226 else if (bUseStd3)
227 {
228 ValidateStd3(unicode[i], i == num + 1);
229 }
230 }
231 if (num == -1 && unicode.Length > 63)
232 {
233 throw new ArgumentException(SR.Argument_IdnBadLabelSize, "unicode");
234 }
235 if (unicode.Length > 255 - ((!IsDot(unicode[^1])) ? 1 : 0))
236 {
237 throw new ArgumentException(SR.Format(SR.Argument_IdnBadNameSize, 255 - ((!IsDot(unicode[^1])) ? 1 : 0)), "unicode");
238 }
239 if (bUseStd3 && !IsDot(unicode[^1]))
240 {
241 ValidateStd3(unicode[^1], bNextToDot: true);
242 }
243 return true;
244 }
245
246 private static string PunycodeEncode(string unicode)
247 {
248 if (unicode.Length == 0)
249 {
250 throw new ArgumentException(SR.Argument_IdnBadLabelSize, "unicode");
251 }
252 StringBuilder stringBuilder = new StringBuilder(unicode.Length);
253 int num = 0;
254 int num2 = 0;
255 int num3 = 0;
256 while (num < unicode.Length)
257 {
258 num = unicode.IndexOfAny(s_dotSeparators, num2);
259 if (num < 0)
260 {
261 num = unicode.Length;
262 }
263 if (num == num2)
264 {
265 if (num == unicode.Length)
266 {
267 break;
268 }
269 throw new ArgumentException(SR.Argument_IdnBadLabelSize, "unicode");
270 }
271 stringBuilder.Append("xn--");
272 bool flag = false;
273 StrongBidiCategory bidiCategory = CharUnicodeInfo.GetBidiCategory(unicode, num2);
274 if (bidiCategory == StrongBidiCategory.StrongRightToLeft)
275 {
276 flag = true;
277 int num4 = num - 1;
278 if (char.IsLowSurrogate(unicode, num4))
279 {
280 num4--;
281 }
282 bidiCategory = CharUnicodeInfo.GetBidiCategory(unicode, num4);
283 if (bidiCategory != StrongBidiCategory.StrongRightToLeft)
284 {
285 throw new ArgumentException(SR.Argument_IdnBadBidi, "unicode");
286 }
287 }
288 int num5 = 0;
289 for (int i = num2; i < num; i++)
290 {
291 StrongBidiCategory bidiCategory2 = CharUnicodeInfo.GetBidiCategory(unicode, i);
292 if (flag && bidiCategory2 == StrongBidiCategory.StrongLeftToRight)
293 {
294 throw new ArgumentException(SR.Argument_IdnBadBidi, "unicode");
295 }
296 if (!flag && bidiCategory2 == StrongBidiCategory.StrongRightToLeft)
297 {
298 throw new ArgumentException(SR.Argument_IdnBadBidi, "unicode");
299 }
300 if (Basic(unicode[i]))
301 {
302 stringBuilder.Append(EncodeBasic(unicode[i]));
303 num5++;
304 }
305 else if (char.IsSurrogatePair(unicode, i))
306 {
307 i++;
308 }
309 }
310 int num6 = num5;
311 if (num6 == num - num2)
312 {
313 stringBuilder.Remove(num3, "xn--".Length);
314 }
315 else
316 {
317 if (unicode.Length - num2 >= "xn--".Length && unicode.Substring(num2, "xn--".Length).Equals("xn--", StringComparison.OrdinalIgnoreCase))
318 {
319 throw new ArgumentException(SR.Argument_IdnBadPunycode, "unicode");
320 }
321 int num7 = 0;
322 if (num6 > 0)
323 {
324 stringBuilder.Append('-');
325 }
326 int num8 = 128;
327 int num9 = 0;
328 int num10 = 72;
329 while (num5 < num - num2)
330 {
331 int num11 = 0;
332 int num12 = 134217727;
333 for (int j = num2; j < num; j += ((!IsSupplementary(num11)) ? 1 : 2))
334 {
335 num11 = char.ConvertToUtf32(unicode, j);
336 if (num11 >= num8 && num11 < num12)
337 {
338 num12 = num11;
339 }
340 }
341 num9 += (num12 - num8) * (num5 - num7 + 1);
342 num8 = num12;
343 for (int j = num2; j < num; j += ((!IsSupplementary(num11)) ? 1 : 2))
344 {
345 num11 = char.ConvertToUtf32(unicode, j);
346 if (num11 < num8)
347 {
348 num9++;
349 }
350 if (num11 != num8)
351 {
352 continue;
353 }
354 int num13 = num9;
355 int num14 = 36;
356 while (true)
357 {
358 int num15 = ((num14 <= num10) ? 1 : ((num14 >= num10 + 26) ? 26 : (num14 - num10)));
359 if (num13 < num15)
360 {
361 break;
362 }
363 stringBuilder.Append(EncodeDigit(num15 + (num13 - num15) % (36 - num15)));
364 num13 = (num13 - num15) / (36 - num15);
365 num14 += 36;
366 }
367 stringBuilder.Append(EncodeDigit(num13));
368 num10 = Adapt(num9, num5 - num7 + 1, num5 == num6);
369 num9 = 0;
370 num5++;
371 if (IsSupplementary(num12))
372 {
373 num5++;
374 num7++;
375 }
376 }
377 num9++;
378 num8++;
379 }
380 }
381 if (stringBuilder.Length - num3 > 63)
382 {
383 throw new ArgumentException(SR.Argument_IdnBadLabelSize, "unicode");
384 }
385 if (num != unicode.Length)
386 {
387 stringBuilder.Append('.');
388 }
389 num2 = num + 1;
390 num3 = stringBuilder.Length;
391 }
392 if (stringBuilder.Length > 255 - ((!IsDot(unicode[^1])) ? 1 : 0))
393 {
394 throw new ArgumentException(SR.Format(SR.Argument_IdnBadNameSize, 255 - ((!IsDot(unicode[^1])) ? 1 : 0)), "unicode");
395 }
396 return stringBuilder.ToString();
397 }
398
399 private static bool IsDot(char c)
400 {
401 if (c != '.' && c != '。' && c != '.')
402 {
403 return c == '。';
404 }
405 return true;
406 }
407
408 private static bool IsSupplementary(int cTest)
409 {
410 return cTest >= 65536;
411 }
412
413 private static bool Basic(uint cp)
414 {
415 return cp < 128;
416 }
417
418 private static void ValidateStd3(char c, bool bNextToDot)
419 {
420 if (c > ',')
421 {
422 switch (c)
423 {
424 default:
425 if ((c < '[' || c > '`') && (c < '{' || c > '\u007f') && !(c == '-' && bNextToDot))
426 {
427 return;
428 }
429 break;
430 case '/':
431 case ':':
432 case ';':
433 case '<':
434 case '=':
435 case '>':
436 case '?':
437 case '@':
438 break;
439 }
440 }
442 }
443
444 private string GetUnicodeInvariant(string ascii, int index, int count)
445 {
446 if (index > 0 || count < ascii.Length)
447 {
448 ascii = ascii.Substring(index, count);
449 }
450 string text = PunycodeDecode(ascii);
451 if (!ascii.Equals(GetAscii(text), StringComparison.OrdinalIgnoreCase))
452 {
453 throw new ArgumentException(SR.Argument_IdnIllegalName, "ascii");
454 }
455 return text;
456 }
457
458 private static string PunycodeDecode(string ascii)
459 {
460 if (ascii.Length == 0)
461 {
463 }
464 if (ascii.Length > 255 - ((!IsDot(ascii[^1])) ? 1 : 0))
465 {
466 throw new ArgumentException(SR.Format(SR.Argument_IdnBadNameSize, 255 - ((!IsDot(ascii[^1])) ? 1 : 0)), "ascii");
467 }
468 StringBuilder stringBuilder = new StringBuilder(ascii.Length);
469 int num = 0;
470 int num2 = 0;
471 int num3 = 0;
472 while (num < ascii.Length)
473 {
474 num = ascii.IndexOf('.', num2);
475 if (num < 0 || num > ascii.Length)
476 {
477 num = ascii.Length;
478 }
479 if (num == num2)
480 {
481 if (num == ascii.Length)
482 {
483 break;
484 }
486 }
487 if (num - num2 > 63)
488 {
490 }
491 if (ascii.Length < "xn--".Length + num2 || string.Compare(ascii, num2, "xn--", 0, "xn--".Length, StringComparison.OrdinalIgnoreCase) != 0)
492 {
493 stringBuilder.Append(ascii, num2, num - num2);
494 }
495 else
496 {
497 num2 += "xn--".Length;
498 int num4 = ascii.LastIndexOf('-', num - 1);
499 if (num4 == num - 1)
500 {
501 throw new ArgumentException(SR.Argument_IdnBadPunycode, "ascii");
502 }
503 int num5;
504 if (num4 <= num2)
505 {
506 num5 = 0;
507 }
508 else
509 {
510 num5 = num4 - num2;
511 for (int i = num2; i < num2 + num5; i++)
512 {
513 if (ascii[i] > '\u007f')
514 {
515 throw new ArgumentException(SR.Argument_IdnBadPunycode, "ascii");
516 }
517 stringBuilder.Append((char)((ascii[i] >= 'A' && ascii[i] <= 'Z') ? (ascii[i] - 65 + 97) : ascii[i]));
518 }
519 }
520 int num6 = num2 + ((num5 > 0) ? (num5 + 1) : 0);
521 int num7 = 128;
522 int num8 = 72;
523 int num9 = 0;
524 int num10 = 0;
525 while (num6 < num)
526 {
527 int num11 = num9;
528 int num12 = 1;
529 int num13 = 36;
530 while (true)
531 {
532 if (num6 >= num)
533 {
534 throw new ArgumentException(SR.Argument_IdnBadPunycode, "ascii");
535 }
536 int num14 = DecodeDigit(ascii[num6++]);
537 if (num14 > (134217727 - num9) / num12)
538 {
539 throw new ArgumentException(SR.Argument_IdnBadPunycode, "ascii");
540 }
541 num9 += num14 * num12;
542 int num15 = ((num13 <= num8) ? 1 : ((num13 >= num8 + 26) ? 26 : (num13 - num8)));
543 if (num14 < num15)
544 {
545 break;
546 }
547 if (num12 > 134217727 / (36 - num15))
548 {
549 throw new ArgumentException(SR.Argument_IdnBadPunycode, "ascii");
550 }
551 num12 *= 36 - num15;
552 num13 += 36;
553 }
554 num8 = Adapt(num9 - num11, stringBuilder.Length - num3 - num10 + 1, num11 == 0);
555 if (num9 / (stringBuilder.Length - num3 - num10 + 1) > 134217727 - num7)
556 {
557 throw new ArgumentException(SR.Argument_IdnBadPunycode, "ascii");
558 }
559 num7 += num9 / (stringBuilder.Length - num3 - num10 + 1);
560 num9 %= stringBuilder.Length - num3 - num10 + 1;
561 if (num7 < 0 || num7 > 1114111 || (num7 >= 55296 && num7 <= 57343))
562 {
563 throw new ArgumentException(SR.Argument_IdnBadPunycode, "ascii");
564 }
565 string value = char.ConvertFromUtf32(num7);
566 int num17;
567 if (num10 > 0)
568 {
569 int num16 = num9;
570 num17 = num3;
571 while (num16 > 0)
572 {
573 if (num17 >= stringBuilder.Length)
574 {
575 throw new ArgumentException(SR.Argument_IdnBadPunycode, "ascii");
576 }
577 if (char.IsSurrogate(stringBuilder[num17]))
578 {
579 num17++;
580 }
581 num16--;
582 num17++;
583 }
584 }
585 else
586 {
587 num17 = num3 + num9;
588 }
589 stringBuilder.Insert(num17, value);
590 if (IsSupplementary(num7))
591 {
592 num10++;
593 }
594 num9++;
595 }
596 bool flag = false;
597 StrongBidiCategory bidiCategory = CharUnicodeInfo.GetBidiCategory(stringBuilder, num3);
598 if (bidiCategory == StrongBidiCategory.StrongRightToLeft)
599 {
600 flag = true;
601 }
602 for (int j = num3; j < stringBuilder.Length; j++)
603 {
604 if (!char.IsLowSurrogate(stringBuilder[j]))
605 {
606 bidiCategory = CharUnicodeInfo.GetBidiCategory(stringBuilder, j);
607 if ((flag && bidiCategory == StrongBidiCategory.StrongLeftToRight) || (!flag && bidiCategory == StrongBidiCategory.StrongRightToLeft))
608 {
609 throw new ArgumentException(SR.Argument_IdnBadBidi, "ascii");
610 }
611 }
612 }
613 if (flag && bidiCategory != StrongBidiCategory.StrongRightToLeft)
614 {
615 throw new ArgumentException(SR.Argument_IdnBadBidi, "ascii");
616 }
617 }
618 if (num - num2 > 63)
619 {
621 }
622 if (num != ascii.Length)
623 {
624 stringBuilder.Append('.');
625 }
626 num2 = num + 1;
627 num3 = stringBuilder.Length;
628 }
629 if (stringBuilder.Length > 255 - ((!IsDot(stringBuilder[stringBuilder.Length - 1])) ? 1 : 0))
630 {
631 throw new ArgumentException(SR.Format(SR.Argument_IdnBadNameSize, 255 - ((!IsDot(stringBuilder[stringBuilder.Length - 1])) ? 1 : 0)), "ascii");
632 }
633 return stringBuilder.ToString();
634 }
635
636 private static int DecodeDigit(char cp)
637 {
638 if (cp >= '0' && cp <= '9')
639 {
640 return cp - 48 + 26;
641 }
642 if (cp >= 'a' && cp <= 'z')
643 {
644 return cp - 97;
645 }
646 if (cp >= 'A' && cp <= 'Z')
647 {
648 return cp - 65;
649 }
651 }
652
653 private static int Adapt(int delta, int numpoints, bool firsttime)
654 {
655 delta = (firsttime ? (delta / 700) : (delta / 2));
656 delta += delta / numpoints;
657 uint num = 0u;
658 while (delta > 455)
659 {
660 delta /= 35;
661 num += 36;
662 }
663 return (int)(num + 36 * delta / (delta + 38));
664 }
665
666 private static char EncodeBasic(char bcp)
667 {
668 if (HasUpperCaseFlag(bcp))
669 {
670 bcp = (char)(bcp + 32);
671 }
672 return bcp;
673 }
674
675 private static bool HasUpperCaseFlag(char punychar)
676 {
677 if (punychar >= 'A')
678 {
679 return punychar <= 'Z';
680 }
681 return false;
682 }
683
684 private static char EncodeDigit(int d)
685 {
686 if (d > 25)
687 {
688 return (char)(d - 26 + 48);
689 }
690 return (char)(d + 97);
691 }
692
693 private unsafe string IcuGetAsciiCore(string unicodeString, char* unicode, int count)
694 {
695 uint icuFlags = IcuFlags;
696 CheckInvalidIdnCharacters(unicode, count, icuFlags, "unicode");
697 int num = (int)Math.Min((long)count * 3L + 4, 512L);
698 int num2;
699 if (num < 512)
700 {
701 char* ptr = stackalloc char[num];
702 num2 = Interop.Globalization.ToAscii(icuFlags, unicode, count, ptr, num);
703 if (num2 > 0 && num2 <= num)
704 {
705 return GetStringForOutput(unicodeString, unicode, count, ptr, num2);
706 }
707 }
708 else
709 {
710 num2 = Interop.Globalization.ToAscii(icuFlags, unicode, count, null, 0);
711 }
712 if (num2 == 0)
713 {
714 throw new ArgumentException(SR.Argument_IdnIllegalName, "unicode");
715 }
716 char[] array = new char[num2];
717 fixed (char* ptr2 = &array[0])
718 {
719 num2 = Interop.Globalization.ToAscii(icuFlags, unicode, count, ptr2, num2);
720 if (num2 == 0 || num2 > array.Length)
721 {
722 throw new ArgumentException(SR.Argument_IdnIllegalName, "unicode");
723 }
724 return GetStringForOutput(unicodeString, unicode, count, ptr2, num2);
725 }
726 }
727
728 private unsafe string IcuGetUnicodeCore(string asciiString, char* ascii, int count)
729 {
730 uint icuFlags = IcuFlags;
731 CheckInvalidIdnCharacters(ascii, count, icuFlags, "ascii");
732 if (count < 512)
733 {
734 char* output = stackalloc char[count];
735 return IcuGetUnicodeCore(asciiString, ascii, count, icuFlags, output, count, reattempt: true);
736 }
737 char[] array = new char[count];
738 fixed (char* output2 = &array[0])
739 {
740 return IcuGetUnicodeCore(asciiString, ascii, count, icuFlags, output2, count, reattempt: true);
741 }
742 }
743
744 private unsafe string IcuGetUnicodeCore(string asciiString, char* ascii, int count, uint flags, char* output, int outputLength, bool reattempt)
745 {
746 int num = Interop.Globalization.ToUnicode(flags, ascii, count, output, outputLength);
747 if (num == 0)
748 {
749 throw new ArgumentException(SR.Argument_IdnIllegalName, "ascii");
750 }
751 if (num <= outputLength)
752 {
753 return GetStringForOutput(asciiString, ascii, count, output, num);
754 }
755 if (reattempt)
756 {
757 fixed (char* output2 = new char[num])
758 {
759 return IcuGetUnicodeCore(asciiString, ascii, count, flags, output2, num, reattempt: false);
760 }
761 }
762 throw new ArgumentException(SR.Argument_IdnIllegalName, "ascii");
763 }
764
765 private unsafe static void CheckInvalidIdnCharacters(char* s, int count, uint flags, string paramName)
766 {
767 if ((flags & 2u) != 0)
768 {
769 return;
770 }
771 for (int i = 0; i < count; i++)
772 {
773 char c = s[i];
774 if (c <= '\u001f' || c == '\u007f')
775 {
776 throw new ArgumentException(SR.Argument_IdnIllegalName, paramName);
777 }
778 }
779 }
780
781 private unsafe string NlsGetAsciiCore(string unicodeString, char* unicode, int count)
782 {
783 uint nlsFlags = NlsFlags;
784 int num = Interop.Normaliz.IdnToAscii(nlsFlags, unicode, count, null, 0);
785 if (num == 0)
786 {
787 ThrowForZeroLength(unicode: true);
788 }
789 if (num < 512)
790 {
791 char* output = stackalloc char[num];
792 return NlsGetAsciiCore(unicodeString, unicode, count, nlsFlags, output, num);
793 }
794 char[] array = new char[num];
795 fixed (char* output2 = &array[0])
796 {
797 return NlsGetAsciiCore(unicodeString, unicode, count, nlsFlags, output2, num);
798 }
799 }
800
801 private unsafe static string NlsGetAsciiCore(string unicodeString, char* unicode, int count, uint flags, char* output, int outputLength)
802 {
803 int num = Interop.Normaliz.IdnToAscii(flags, unicode, count, output, outputLength);
804 if (num == 0)
805 {
806 ThrowForZeroLength(unicode: true);
807 }
808 return GetStringForOutput(unicodeString, unicode, count, output, num);
809 }
810
811 private unsafe string NlsGetUnicodeCore(string asciiString, char* ascii, int count)
812 {
813 uint nlsFlags = NlsFlags;
814 int num = Interop.Normaliz.IdnToUnicode(nlsFlags, ascii, count, null, 0);
815 if (num == 0)
816 {
817 ThrowForZeroLength(unicode: false);
818 }
819 if (num < 512)
820 {
821 char* output = stackalloc char[num];
822 return NlsGetUnicodeCore(asciiString, ascii, count, nlsFlags, output, num);
823 }
824 char[] array = new char[num];
825 fixed (char* output2 = &array[0])
826 {
827 return NlsGetUnicodeCore(asciiString, ascii, count, nlsFlags, output2, num);
828 }
829 }
830
831 private unsafe static string NlsGetUnicodeCore(string asciiString, char* ascii, int count, uint flags, char* output, int outputLength)
832 {
833 int num = Interop.Normaliz.IdnToUnicode(flags, ascii, count, output, outputLength);
834 if (num == 0)
835 {
836 ThrowForZeroLength(unicode: false);
837 }
838 return GetStringForOutput(asciiString, ascii, count, output, num);
839 }
840
841 [DoesNotReturn]
842 private static void ThrowForZeroLength(bool unicode)
843 {
844 int lastPInvokeError = Marshal.GetLastPInvokeError();
845 throw new ArgumentException((lastPInvokeError == 123) ? SR.Argument_IdnIllegalName : (unicode ? SR.Argument_InvalidCharSequenceNoIndex : SR.Argument_IdnBadPunycode), unicode ? "unicode" : "ascii");
846 }
847}
static unsafe int ToUnicode(uint flags, char *src, int srcLen, char *dstBuffer, int dstBufferCapacity)
static unsafe int ToAscii(uint flags, char *src, int srcLen, char *dstBuffer, int dstBufferCapacity)
static unsafe int IdnToAscii(uint dwFlags, char *lpUnicodeCharStr, int cchUnicodeChar, char *lpASCIICharStr, int cchASCIIChar)
static unsafe int IdnToUnicode(uint dwFlags, char *lpASCIICharStr, int cchASCIIChar, char *lpUnicodeCharStr, int cchUnicodeChar)
static StrongBidiCategory GetBidiCategory(string s, int index)
static unsafe void CheckInvalidIdnCharacters(char *s, int count, uint flags, string paramName)
string GetUnicode(string ascii)
Definition IdnMapping.cs:98
unsafe string NlsGetUnicodeCore(string asciiString, char *ascii, int count)
static int DecodeDigit(char cp)
unsafe string GetAscii(string unicode, int index, int count)
Definition IdnMapping.cs:58
static void ThrowForZeroLength(bool unicode)
unsafe string IcuGetUnicodeCore(string asciiString, char *ascii, int count)
static bool IsDot(char c)
override bool Equals([NotNullWhen(true)] object? obj)
static char EncodeDigit(int d)
static readonly char[] s_dotSeparators
Definition IdnMapping.cs:14
static void ValidateStd3(char c, bool bNextToDot)
static unsafe string GetStringForOutput(string originalString, char *input, int inputLength, char *output, int outputLength)
static bool Basic(uint cp)
static char EncodeBasic(char bcp)
string GetAscii(string unicode)
Definition IdnMapping.cs:44
static bool IsSupplementary(int cTest)
unsafe string IcuGetUnicodeCore(string asciiString, char *ascii, int count, uint flags, char *output, int outputLength, bool reattempt)
static bool HasUpperCaseFlag(char punychar)
unsafe string GetUnicode(string ascii, int index, int count)
static unsafe string NlsGetUnicodeCore(string asciiString, char *ascii, int count, uint flags, char *output, int outputLength)
static unsafe string NlsGetAsciiCore(string unicodeString, char *unicode, int count, uint flags, char *output, int outputLength)
unsafe string IcuGetAsciiCore(string unicodeString, char *unicode, int count)
string GetAsciiInvariant(string unicode, int index, int count)
static string PunycodeEncode(string unicode)
unsafe string NlsGetAsciiCore(string unicodeString, char *unicode, int count)
string GetUnicodeInvariant(string ascii, int index, int count)
static string PunycodeDecode(string ascii)
string GetAscii(string unicode, int index)
Definition IdnMapping.cs:49
static bool ValidateStd3AndAscii(string unicode, bool bUseStd3, bool bCheckAscii)
string GetUnicode(string ascii, int index)
static int Adapt(int delta, int numpoints, bool firsttime)
static bool EqualsIgnoreCase(ref char charA, ref char charB, int length)
Definition Ordinal.cs:57
static byte Min(byte val1, byte val2)
Definition Math.cs:912
static string ArgumentOutOfRange_Index
Definition SR.cs:30
static string Argument_IdnBadStd3
Definition SR.cs:624
static string Argument_InvalidCharSequence
Definition SR.cs:648
static string Format(string resourceFormat, object p1)
Definition SR.cs:118
static string Argument_IdnBadNameSize
Definition SR.cs:620
static string Argument_IdnBadPunycode
Definition SR.cs:622
static string ArgumentOutOfRange_IndexCountBuffer
Definition SR.cs:78
static string Argument_IdnIllegalName
Definition SR.cs:626
static string Argument_IdnBadBidi
Definition SR.cs:616
static string ArgumentOutOfRange_NeedNonNegNum
Definition SR.cs:32
static string Argument_IdnBadLabelSize
Definition SR.cs:618
Definition SR.cs:7
unsafe StringBuilder Insert(int index, string? value, int count)
StringBuilder Remove(int startIndex, int length)
override string ToString()
StringBuilder Append(char value, int repeatCount)