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);
123 const QChar *ret = checkedToAscii(buffer, begin, end);
127 const char *ptr = buffer.data();
128 const char *
const stop = ptr + buffer.size();
141 if (dotCount != 0 && dotCount != 3)
144 memset(address, 0,
sizeof address);
145 if (colonCount == 2 && end - begin == 2)
154 if ((ptr[0] ==
':' && ptr[1] ==
':') ||
155 (ptr[end - begin - 2] ==
':' && ptr[end - begin - 1] ==
':')) {
156 zeroWordsToFill = 9 - colonCount;
157 }
else if (colonCount < 2 || colonCount > 7) {
160 zeroWordsToFill = 8 - colonCount;
169 if (zeroWordsToFill < 1)
170 return begin + (ptr - buffer.data());
171 if (pos == 0 || pos == colonCount * 2) {
172 if (ptr[0] ==
'\0' || ptr[1] !=
':')
173 return begin + (ptr - buffer.data());
176 pos += zeroWordsToFill * 2;
182 auto [ll, used] = qstrntoull(ptr, stop - ptr, 16);
188 if (used <= 0 || used > 4)
189 return begin + (ptr - buffer.data());
191 if (ptr[used] ==
'.') {
195 return begin + (ptr - buffer.data());
199 return begin + (ptr - buffer.data());
201 address[12] = ip4 >> 24;
202 address[13] = ip4 >> 16;
203 address[14] = ip4 >> 8;
208 address[pos++] = x >> 8;
209 address[pos++] = x & 0xff;
211 if (ptr[used] ==
'\0')
213 if (ptr[used] !=
':')
214 return begin + (used + ptr - buffer.data());
217 return pos == 16 ?
nullptr : end;
234 static const int Ip6AddressMaxLen =
sizeof "1111:2222:3333:4444:5555:6666:7777:8888";
235 static const int Ip6WithIp4AddressMaxLen =
sizeof "::ffff:255.255.255.255";
238 const quint64 zeroes[] = { 0, 0 };
239 bool embeddedIp4 =
false;
244 if (memcmp(address, zeroes, 10) == 0) {
245 if (address[10] == 0xff && address[11] == 0xff) {
247 }
else if (address[10] == 0 && address[11] == 0) {
248 if (address[12] != 0 || address[13] != 0 || address[14] != 0) {
250 }
else if (address[15] == 0) {
251 appendTo.append(
"::"_L1);
258 appendTo.reserve(appendTo.size() +
259 (embeddedIp4 ? Ip6WithIp4AddressMaxLen : Ip6AddressMaxLen));
262 int zeroRunLength = 0;
263 int zeroRunOffset = 0;
264 for (
int i = 0; i < 16; i += 2) {
265 if (address[i] == 0 && address[i + 1] == 0) {
268 for (j = i; j < 16; j += 2) {
269 if (address[j] != 0 || address[j+1] != 0)
273 if (j - i > zeroRunLength) {
274 zeroRunLength = j - i;
281 const QChar colon = u':';
282 if (zeroRunLength < 4)
284 else if (zeroRunOffset == 0)
285 appendTo.append(colon);
287 for (
int i = 0; i < 16; i += 2) {
288 if (i == zeroRunOffset) {
289 appendTo.append(colon);
290 i += zeroRunLength - 2;
294 if (i == 12 && embeddedIp4) {
299 toString(appendTo, ip4);
304 if (address[i] >> 4) {
305 appendTo.append(toHex(address[i] >> 4));
306 appendTo.append(toHex(address[i] & 0xf));
307 appendTo.append(toHex(address[i + 1] >> 4));
308 appendTo.append(toHex(address[i + 1] & 0xf));
309 }
else if (address[i] & 0xf) {
310 appendTo.append(toHex(address[i] & 0xf));
311 appendTo.append(toHex(address[i + 1] >> 4));
312 appendTo.append(toHex(address[i + 1] & 0xf));
314 }
else if (address[i + 1] >> 4) {
315 appendTo.append(toHex(address[i + 1] >> 4));
316 appendTo.append(toHex(address[i + 1] & 0xf));
318 appendTo.append(toHex(address[i + 1] & 0xf));
322 appendTo.append(colon);