33static 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] =
static_cast<uint8
> (n >> 24);
94 address[1] =
static_cast<uint8
> ((n >> 16) & 255);
95 address[2] =
static_cast<uint8
> ((n >> 8) & 255);
96 address[3] =
static_cast<uint8
> ((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];
207bool IPAddress::operator== (
const IPAddress& other)
const noexcept {
return compare (other) == 0; }
208bool IPAddress::operator!= (
const IPAddress& other)
const noexcept {
return compare (other) != 0; }
209bool IPAddress::operator< (
const IPAddress& other)
const noexcept {
return compare (other) < 0; }
210bool IPAddress::operator<= (
const IPAddress& other)
const noexcept {
return compare (other) <= 0; }
211bool IPAddress::operator> (
const IPAddress& other)
const noexcept {
return compare (other) > 0; }
212bool 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;
248 jassert (unformattedAddress.
contains (
":") && ! unformattedAddress.
contains (
"::"));
256 int numZerosTemp = 0;
257 bool isFirst =
false;
260 for (
int i = 0; i < tokens.size(); ++i)
262 auto& t = tokens.getReference (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)
380struct IPAddressTests final :
public UnitTest
383 :
UnitTest (
"IPAddress", UnitTestCategories::networking)
386 void runTest()
override
389 testFindAllAddresses();
390 testFindBroadcastAddress();
393 void testConstructors()
395 beginTest (
"constructors");
398 IPAddress defaultConstructed;
399 expect (defaultConstructed.isNull());
401 auto local = IPAddress::local();
402 expect (! local.isNull());
404 IPAddress ipv4{1, 2, 3, 4};
405 expect (! ipv4.isNull());
406 expect (! ipv4.isIPv6);
407 expect (ipv4.toString() ==
"1.2.3.4");
410 void testFindAllAddresses()
412 beginTest (
"find all addresses");
414 Array<IPAddress> ipv4Addresses;
415 Array<IPAddress> allAddresses;
417 IPAddress::findAllAddresses (ipv4Addresses,
false);
418 IPAddress::findAllAddresses (allAddresses,
true);
420 expect (allAddresses.size() >= ipv4Addresses.size());
422 for (
auto& a : ipv4Addresses)
424 expect (! a.isNull());
428 for (
auto& a : allAddresses)
430 expect (! a.isNull());
434 void testFindBroadcastAddress()
436 beginTest (
"broadcast addresses");
438 Array<IPAddress> addresses;
441 IPAddress::findAllAddresses (addresses,
false);
443 for (
auto& a : addresses)
445 expect (! a.isNull());
447 auto broadcastAddress = IPAddress::getInterfaceBroadcastAddress (a);
450 if (! broadcastAddress.isNull())
457 IPAddress address{1, 2, 3, 4};
458 expect (IPAddress::getInterfaceBroadcastAddress (address).isNull());
462static IPAddressTests iPAddressTests;
static Array< IPAddress > getAllAddresses(bool includeIPv6=false)
static IPAddress getLocalAddress(bool includeIPv6=false)
static IPAddress local(bool IPv6=false) noexcept
static bool isIPv4MappedAddress(const IPAddress &mappedAddress)
static IPAddress any() noexcept
static String getFormattedAddress(const String &unformattedAddress)
int compare(const IPAddress &) const noexcept
static IPAddress broadcast() noexcept
static void findAllAddresses(Array< IPAddress > &results, bool includeIPv6=false)
static IPAddress convertIPv4AddressToIPv4Mapped(const IPAddress &addressToMap)
static IPAddress convertIPv4MappedAddressToIPv4(const IPAddress &mappedAddress)
static StringArray fromTokens(StringRef stringToTokenise, bool preserveQuotedStrings)
static String repeatedString(StringRef stringToRepeat, int numberOfTimesToRepeat)
String removeCharacters(StringRef charactersToRemove) const
int indexOf(StringRef textToLookFor) const noexcept
int lastIndexOf(StringRef textToLookFor) const noexcept
String dropLastCharacters(int numberToDrop) const
bool contains(StringRef text) const noexcept
static String toHexString(IntegerType number)
String upToLastOccurrenceOf(StringRef substringToFind, bool includeSubStringInResult, bool ignoreCase) const
bool containsAnyOf(StringRef charactersItMightContain) const noexcept
String fromFirstOccurrenceOf(StringRef substringToStartFrom, bool includeSubStringInResult, bool ignoreCase) const