Punycode
Represents a Punycode encoding helper class.
using AngleSharp.Extensions;
using System;
using System.Text;
namespace AngleSharp.Foundation
{
internal static class Punycode
{
private const int PunycodeBase = 36;
private const int Tmin = 1;
private const int Tmax = 26;
private static readonly string acePrefix = "xn--";
private static readonly char[] possibleDots = new char[4] {
'.',
'。',
'.',
'。'
};
public static string Encode(string text)
{
if (text.Length == 0)
return text;
StringBuilder stringBuilder = new StringBuilder(text.Length);
int num = 0;
int num2 = 0;
int num3 = 0;
while (num < text.Length) {
num = text.IndexOfAny(possibleDots, num2);
if (num < 0)
num = text.Length;
if (num == num2)
break;
stringBuilder.Append(acePrefix);
int num4 = 0;
int num5 = 0;
for (num4 = num2; num4 < num; num4++) {
if (text[num4] < '') {
stringBuilder.Append(EncodeBasic(text[num4]));
num5++;
} else if (char.IsSurrogatePair(text, num4)) {
num4++;
}
}
int num6 = num5;
if (num6 == num - num2)
stringBuilder.Remove(num3, acePrefix.Length);
else {
if (text.Length - num2 >= acePrefix.Length && text.Substring(num2, acePrefix.Length).Equals(acePrefix, StringComparison.OrdinalIgnoreCase))
break;
int num7 = 0;
if (num6 > 0)
stringBuilder.Append('-');
int num8 = 128;
int num9 = 0;
int num10 = 72;
while (num5 < num - num2) {
int num11 = 0;
int num12 = 0;
int num13 = 0;
num12 = 134217727;
for (num11 = num2; num11 < num; num11 += ((!IsSupplementary(num13)) ? 1 : 2)) {
num13 = text.ConvertToUtf32(num11);
if (num13 >= num8 && num13 < num12)
num12 = num13;
}
num9 += (num12 - num8) * (num5 - num7 + 1);
num8 = num12;
for (num11 = num2; num11 < num; num11 += ((!IsSupplementary(num13)) ? 1 : 2)) {
num13 = text.ConvertToUtf32(num11);
if (num13 < num8)
num9++;
else if (num13 == num8) {
int num14 = num9;
int num15 = 36;
while (true) {
int num16 = (num15 <= num10) ? 1 : ((num15 >= num10 + 26) ? 26 : (num15 - num10));
if (num14 < num16)
break;
stringBuilder.Append(EncodeDigit(num16 + (num14 - num16) % (36 - num16)));
num14 = (num14 - num16) / (36 - num16);
num15 += 36;
}
stringBuilder.Append(EncodeDigit(num14));
num10 = AdaptChar(num9, num5 - num7 + 1, num5 == num6);
num9 = 0;
num5++;
if (IsSupplementary(num12)) {
num5++;
num7++;
}
}
}
num9++;
num8++;
}
}
if (stringBuilder.Length - num3 > 63)
throw new ArgumentException();
if (num != text.Length)
stringBuilder.Append(possibleDots[0]);
num2 = num + 1;
num3 = stringBuilder.Length;
}
int num17 = (!IsDot(text[text.Length - 1])) ? 1 : 0;
int num18 = 255 - num17;
if (stringBuilder.Length > num18)
stringBuilder.Remove(num18, stringBuilder.Length - num18);
return stringBuilder.ToString();
}
private static bool IsSupplementary(int test)
{
return test >= 65536;
}
private static bool IsDot(char c)
{
for (int i = 0; i < possibleDots.Length; i++) {
if (possibleDots[i] == c)
return true;
}
return false;
}
private static char EncodeDigit(int digit)
{
if (digit > 25)
return (char)(digit + 22);
return (char)(digit + 97);
}
private static char EncodeBasic(char character)
{
if (char.IsUpper(character))
character = (char)(character + 32);
return character;
}
private static int AdaptChar(int delta, int numPoints, bool firstTime)
{
uint num = 0;
delta = (firstTime ? (delta / 700) : (delta / 2));
delta += delta / numPoints;
num = 0;
while (delta > 455) {
delta /= 35;
num += 36;
}
return (int)(num + 36 * delta / (delta + 38));
}
}
}