58 const char *
const stop = ptr + qstrlen(ptr);
59 while (dotCount < 4) {
60 if (!acceptLeadingZero && *ptr ==
'0' &&
61 ptr[1] !=
'.' && ptr[1] !=
'\0')
64 auto [ll, used] = qstrntoull(ptr, stop - ptr, 0);
65 const quint32 x = quint32(ll);
66 if (used <= 0 || ll != x)
69 if (ptr[used] ==
'.' || dotCount == 3) {
73 }
else if (dotCount == 2) {
77 }
else if (dotCount == 1) {
84 if (dotCount == 3 || ptr[used] ==
'\0')
85 return ptr[used] ==
'\0';
117 Q_ASSERT(begin != end);
119 const QChar *ret = checkedToAscii(buffer, begin, end);
123 const char *ptr = buffer.data();
124 const char *
const stop = ptr + buffer.size();
137 if (dotCount != 0 && dotCount != 3)
140 memset(address, 0,
sizeof address);
141 if (colonCount == 2 && end - begin == 2)
150 if ((ptr[0] ==
':' && ptr[1] ==
':') ||
151 (ptr[end - begin - 2] ==
':' && ptr[end - begin - 1] ==
':')) {
152 zeroWordsToFill = 9 - colonCount;
153 }
else if (colonCount < 2 || colonCount > 7) {
156 zeroWordsToFill = 8 - colonCount;
165 if (zeroWordsToFill < 1)
166 return begin + (ptr - buffer.data());
167 if (pos == 0 || pos == colonCount * 2) {
168 if (ptr[0] ==
'\0' || ptr[1] !=
':')
169 return begin + (ptr - buffer.data());
172 pos += zeroWordsToFill * 2;
178 auto [ll, used] = qstrntoull(ptr, stop - ptr, 16);
184 if (used <= 0 || used > 4)
185 return begin + (ptr - buffer.data());
187 if (ptr[used] ==
'.') {
191 return begin + (ptr - buffer.data());
195 return begin + (ptr - buffer.data());
197 address[12] = ip4 >> 24;
198 address[13] = ip4 >> 16;
199 address[14] = ip4 >> 8;
204 address[pos++] = x >> 8;
205 address[pos++] = x & 0xff;
207 if (ptr[used] ==
'\0')
209 if (ptr[used] !=
':')
210 return begin + (used + ptr - buffer.data());
213 return pos == 16 ?
nullptr : end;
230 static const int Ip6AddressMaxLen =
sizeof "1111:2222:3333:4444:5555:6666:7777:8888";
231 static const int Ip6WithIp4AddressMaxLen =
sizeof "::ffff:255.255.255.255";
234 const quint64 zeroes[] = { 0, 0 };
235 bool embeddedIp4 =
false;
240 if (memcmp(address, zeroes, 10) == 0) {
241 if (address[10] == 0xff && address[11] == 0xff) {
243 }
else if (address[10] == 0 && address[11] == 0) {
244 if (address[12] != 0 || address[13] != 0 || address[14] != 0) {
246 }
else if (address[15] == 0) {
247 appendTo.append(
"::"_L1);
254 appendTo.reserve(appendTo.size() +
255 (embeddedIp4 ? Ip6WithIp4AddressMaxLen : Ip6AddressMaxLen));
258 int zeroRunLength = 0;
259 int zeroRunOffset = 0;
260 for (
int i = 0; i < 16; i += 2) {
261 if (address[i] == 0 && address[i + 1] == 0) {
264 for (j = i; j < 16; j += 2) {
265 if (address[j] != 0 || address[j+1] != 0)
269 if (j - i > zeroRunLength) {
270 zeroRunLength = j - i;
277 const QChar colon = u':';
278 if (zeroRunLength < 4)
280 else if (zeroRunOffset == 0)
281 appendTo.append(colon);
283 for (
int i = 0; i < 16; i += 2) {
284 if (i == zeroRunOffset) {
285 appendTo.append(colon);
286 i += zeroRunLength - 2;
290 if (i == 12 && embeddedIp4) {
295 toString(appendTo, ip4);
300 if (address[i] >> 4) {
301 appendTo.append(toHex(address[i] >> 4));
302 appendTo.append(toHex(address[i] & 0xf));
303 appendTo.append(toHex(address[i + 1] >> 4));
304 appendTo.append(toHex(address[i + 1] & 0xf));
305 }
else if (address[i] & 0xf) {
306 appendTo.append(toHex(address[i] & 0xf));
307 appendTo.append(toHex(address[i + 1] >> 4));
308 appendTo.append(toHex(address[i + 1] & 0xf));
310 }
else if (address[i + 1] >> 4) {
311 appendTo.append(toHex(address[i + 1] >> 4));
312 appendTo.append(toHex(address[i + 1] & 0xf));
314 appendTo.append(toHex(address[i + 1] & 0xf));
318 appendTo.append(colon);