33 static void zeroUnusedBytes (uint8* address) noexcept
35 for (
int i = 4; i < 16; ++i)
41 for (
int i = 0; i < 16; ++i)
47 for (
int i = 0; i < (isIPv6 ? 16 : 4); ++i)
48 address[i] = bytes[i];
51 zeroUnusedBytes (address);
56 IPAddressByteUnion temp;
58 for (
int i = 0; i < 8; ++i)
60 temp.combined = bytes[i];
62 address[i * 2] = temp.split[0];
63 address[i * 2 + 1] = temp.split[1];
69 address[0] = a0; address[1] = a1;
70 address[2] = a2; address[3] = a3;
72 zeroUnusedBytes (address);
76 uint16 a5, uint16 a6, uint16 a7, uint16 a8) noexcept : isIPv6 (
true)
79 uint16 array[8] = { a1, a2, a3, a4, a5, a6, a7, a8 };
83 for (
int i = 0; i < 8; ++i)
85 temp.combined = array[i];
86 address[i * 2] = temp.split[0];
87 address[i * 2 + 1] = temp.split[1];
93 address[0] = (n >> 24);
94 address[1] = (n >> 16) & 255;
95 address[2] = (n >> 8) & 255;
96 address[3] = (n & 255);
98 zeroUnusedBytes (address);
103 for (
int i = 0; i < 16; ++i)
123 auto ipAddress = removePort (adr);
125 isIPv6 = ipAddress.contains (
":");
131 for (
int i = 0; i < 4; ++i)
132 address[i] = (uint8) tokens[i].getIntValue();
140 if (tokens.contains ({}))
142 auto idx = tokens.
indexOf ({});
143 tokens.set (idx,
"0");
144 tokens.removeEmptyStrings();
147 if (tokens[tokens.size() - 1].containsChar (
'.'))
150 while (tokens.size() < 8)
151 tokens.insert (idx,
"0");
154 for (
int i = 0; i < 8; ++i)
171 address[i * 2] = temp.split[0];
172 address[i * 2 + 1] = temp.split[1];
183 for (
int i = 1; i < 4; ++i)
196 for (
int i = 1; i < 8; ++i)
198 temp.split[0] =
address[i * 2];
199 temp.split[1] =
address[i * 2 + 1];
207 bool IPAddress::operator== (
const IPAddress& other)
const noexcept {
return compare (other) == 0; }
208 bool IPAddress::operator!= (
const IPAddress& other)
const noexcept {
return compare (other) != 0; }
209 bool IPAddress::operator< (
const IPAddress& other)
const noexcept {
return compare (other) < 0; }
210 bool IPAddress::operator<= (
const IPAddress& other)
const noexcept {
return compare (other) <= 0; }
211 bool IPAddress::operator> (
const IPAddress& other)
const noexcept {
return compare (other) > 0; }
212 bool IPAddress::operator>= (
const IPAddress& other)
const noexcept {
return compare (other) >= 0; }
216 if (isIPv6 != other.isIPv6)
220 if (isIPv4MappedAddress (*
this))
221 return convertIPv4MappedAddressToIPv4 (*this).compare (other);
226 if (isIPv4MappedAddress (other))
227 return compare (convertIPv4MappedAddressToIPv4 (other));
232 for (
int i = 0; i < (isIPv6 ? 16 : 4); ++i)
234 if (address[i] > other.address[i])
return 1;
235 if (address[i] < other.address[i])
return -1;
243 IPAddress IPAddress::local (
bool IPv6) noexcept {
return IPv6 ?
IPAddress (0, 0, 0, 0, 0, 0, 0, 1)
248 jassert (unformattedAddress.
contains (
":") && ! unformattedAddress.
contains (
"::"));
256 int numZerosTemp = 0;
257 bool isFirst =
false;
260 for (
int i = 0; i < tokens.size(); ++i)
264 if (t.getHexValue32() == 0x0000)
270 else if (i == tokens.size() - 1 && numZeros > numZerosTemp)
276 if (isFirst && numZerosTemp != 0 && numZeros > numZerosTemp)
281 addressString = addressString.
replace (t, t.trimCharactersAtStart (
"0").toLowerCase());
285 if (numZeros > numZerosTemp)
286 numZerosTemp = numZeros;
293 if (numZerosTemp > numZeros)
294 numZeros = numZerosTemp;
298 if (numZeros == tokens.size())
300 addressString =
"::,";
307 addressString = addressString.replaceFirstOccurrenceOf (zeroString,
":");
310 addressString <<
':';
314 if (portString.isNotEmpty())
315 addressString =
"[" + addressString +
"]" + portString;
317 return addressString;
322 if (! mappedAddress.isIPv6)
325 for (
int i = 0; i < 10; ++i)
326 if (mappedAddress.
address[i] != 0)
329 if (mappedAddress.
address[10] != 255 || mappedAddress.
address[11] != 255)
338 jassert (mappedAddress.isIPv6);
350 jassert (! addressToMap.isIPv6);
352 return { 0x0, 0x0, 0x0, 0x0, 0x0, 0xffff,
353 static_cast<uint16
> ((addressToMap.
address[0] << 8) | addressToMap.
address[1]),
354 static_cast<uint16
> ((addressToMap.
address[2] << 8) | addressToMap.
address[3]) };
361 for (
auto& a : addresses)
378 struct IPAddressTests :
public UnitTest
381 :
UnitTest (
"IPAddress",
"Networking")
385 void runTest()
override
388 testFindAllAddresses();
389 testFindBroadcastAddress();
392 void testConstructors()
394 beginTest (
"constructors");
397 IPAddress defaultConstructed;
398 expect (defaultConstructed.isNull());
400 auto local = IPAddress::local();
401 expect (! local.isNull());
403 IPAddress ipv4{1, 2, 3, 4};
404 expect (! ipv4.isNull());
405 expect (! ipv4.isIPv6);
406 expect (ipv4.toString() ==
"1.2.3.4");
409 void testFindAllAddresses()
411 beginTest (
"find all addresses");
413 Array<IPAddress> ipv4Addresses;
414 Array<IPAddress> allAddresses;
419 expect (allAddresses.size() >= ipv4Addresses.size());
421 for (
auto& a : ipv4Addresses)
423 expect (! a.isNull());
427 for (
auto& a : allAddresses)
429 expect (! a.isNull());
433 void testFindBroadcastAddress()
435 beginTest (
"broadcast addresses");
437 Array<IPAddress> addresses;
442 for (
auto& a : addresses)
444 expect (! a.isNull());
449 if (! broadcastAddress.isNull())
456 IPAddress address{1, 2, 3, 4};
461 static IPAddressTests iPAddressTests;