Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
IPv4AddressHelper.cs
Go to the documentation of this file.
2
3namespace System;
4
5internal static class IPv4AddressHelper
6{
7 internal unsafe static string ParseCanonicalName(string str, int start, int end, ref bool isLoopback)
8 {
9 byte* ptr = stackalloc byte[4];
10 isLoopback = Parse(str, ptr, start, end);
11 Span<char> span = stackalloc char[15];
12 int num = 0;
13 int charsWritten;
14 for (int i = 0; i < 3; i++)
15 {
16 ptr[i].TryFormat(span.Slice(num), out charsWritten);
17 int num2 = num + charsWritten;
18 span[num2] = '.';
19 num = num2 + 1;
20 }
21 ptr[3].TryFormat(span.Slice(num), out charsWritten);
22 return new string(span.Slice(0, num + charsWritten));
23 }
24
25 private unsafe static bool Parse(string name, byte* numbers, int start, int end)
26 {
27 fixed (char* name2 = name)
28 {
29 int end2 = end;
30 long num = ParseNonCanonical(name2, start, ref end2, notImplicitFile: true);
31 *numbers = (byte)(num >> 24);
32 numbers[1] = (byte)(num >> 16);
33 numbers[2] = (byte)(num >> 8);
34 numbers[3] = (byte)num;
35 }
36 return *numbers == 127;
37 }
38
39 internal static int ParseHostNumber(ReadOnlySpan<char> str, int start, int end)
40 {
41 Span<byte> span = stackalloc byte[4];
42 for (int i = 0; i < span.Length; i++)
43 {
44 int num = 0;
45 char c;
46 while (start < end && (c = str[start]) != '.' && c != ':')
47 {
48 num = num * 10 + c - 48;
49 start++;
50 }
51 span[i] = (byte)num;
52 start++;
53 }
55 }
56
57 internal unsafe static bool IsValid(char* name, int start, ref int end, bool allowIPv6, bool notImplicitFile, bool unknownScheme)
58 {
59 if (allowIPv6 || unknownScheme)
60 {
61 return IsValidCanonical(name, start, ref end, allowIPv6, notImplicitFile);
62 }
63 return ParseNonCanonical(name, start, ref end, notImplicitFile) != -1;
64 }
65
66 internal unsafe static bool IsValidCanonical(char* name, int start, ref int end, bool allowIPv6, bool notImplicitFile)
67 {
68 int num = 0;
69 int num2 = 0;
70 bool flag = false;
71 bool flag2 = false;
72 while (start < end)
73 {
74 char c = name[start];
75 if (allowIPv6)
76 {
77 if (c == ']' || c == '/' || c == '%')
78 {
79 break;
80 }
81 }
82 else if (c == '/' || c == '\\' || (notImplicitFile && (c == ':' || c == '?' || c == '#')))
83 {
84 break;
85 }
86 if (c <= '9' && c >= '0')
87 {
88 if (!flag && c == '0')
89 {
90 if (start + 1 < end && name[start + 1] == '0')
91 {
92 return false;
93 }
94 flag2 = true;
95 }
96 flag = true;
97 num2 = num2 * 10 + (name[start] - 48);
98 if (num2 > 255)
99 {
100 return false;
101 }
102 }
103 else
104 {
105 if (c != '.')
106 {
107 return false;
108 }
109 if (!flag || (num2 > 0 && flag2))
110 {
111 return false;
112 }
113 num++;
114 flag = false;
115 num2 = 0;
116 flag2 = false;
117 }
118 start++;
119 }
120 bool flag3 = num == 3 && flag;
121 if (flag3)
122 {
123 end = start;
124 }
125 return flag3;
126 }
127
128 internal unsafe static long ParseNonCanonical(char* name, int start, ref int end, bool notImplicitFile)
129 {
130 int num = 10;
131 long* ptr = stackalloc long[4];
132 long num2 = 0L;
133 bool flag = false;
134 int num3 = 0;
135 int i;
136 for (i = start; i < end; i++)
137 {
138 char c = name[i];
139 num2 = 0L;
140 num = 10;
141 if (c == '0')
142 {
143 num = 8;
144 i++;
145 flag = true;
146 if (i < end)
147 {
148 c = name[i];
149 if (c == 'x' || c == 'X')
150 {
151 num = 16;
152 i++;
153 flag = false;
154 }
155 }
156 }
157 for (; i < end; i++)
158 {
159 c = name[i];
160 int num4;
161 if ((num == 10 || num == 16) && '0' <= c && c <= '9')
162 {
163 num4 = c - 48;
164 }
165 else if (num == 8 && '0' <= c && c <= '7')
166 {
167 num4 = c - 48;
168 }
169 else if (num == 16 && 'a' <= c && c <= 'f')
170 {
171 num4 = c + 10 - 97;
172 }
173 else
174 {
175 if (num != 16 || 'A' > c || c > 'F')
176 {
177 break;
178 }
179 num4 = c + 10 - 65;
180 }
181 num2 = num2 * num + num4;
182 if (num2 > uint.MaxValue)
183 {
184 return -1L;
185 }
186 flag = true;
187 }
188 if (i >= end || name[i] != '.')
189 {
190 break;
191 }
192 if (num3 >= 3 || !flag || num2 > 255)
193 {
194 return -1L;
195 }
196 ptr[num3] = num2;
197 num3++;
198 flag = false;
199 }
200 if (!flag)
201 {
202 return -1L;
203 }
204 if (i < end)
205 {
206 char c;
207 if ((c = name[i]) != '/' && c != '\\' && (!notImplicitFile || (c != ':' && c != '?' && c != '#')))
208 {
209 return -1L;
210 }
211 end = i;
212 }
213 ptr[num3] = num2;
214 switch (num3)
215 {
216 case 0:
217 if (*ptr > uint.MaxValue)
218 {
219 return -1L;
220 }
221 return *ptr;
222 case 1:
223 if (ptr[1] > 16777215)
224 {
225 return -1L;
226 }
227 return (*ptr << 24) | (ptr[1] & 0xFFFFFF);
228 case 2:
229 if (ptr[2] > 65535)
230 {
231 return -1L;
232 }
233 return (*ptr << 24) | ((ptr[1] & 0xFF) << 16) | (ptr[2] & 0xFFFF);
234 case 3:
235 if (ptr[3] > 255)
236 {
237 return -1L;
238 }
239 return (*ptr << 24) | ((ptr[1] & 0xFF) << 16) | ((ptr[2] & 0xFF) << 8) | (ptr[3] & 0xFF);
240 default:
241 return -1L;
242 }
243 }
244}
static int ReadInt32BigEndian(ReadOnlySpan< byte > source)
static unsafe bool IsValid(char *name, int start, ref int end, bool allowIPv6, bool notImplicitFile, bool unknownScheme)
static unsafe bool IsValidCanonical(char *name, int start, ref int end, bool allowIPv6, bool notImplicitFile)
static unsafe bool Parse(string name, byte *numbers, int start, int end)
static unsafe string ParseCanonicalName(string str, int start, int end, ref bool isLoopback)
static int ParseHostNumber(ReadOnlySpan< char > str, int start, int end)
static unsafe long ParseNonCanonical(char *name, int start, ref int end, bool notImplicitFile)
Span< T > Slice(int start)
Definition Span.cs:271
int Length
Definition Span.cs:70