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);
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();
134 zeroUnusedBytes (address);
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)
156 if (i == 6 && isIPv4MappedAddress (
IPAddress (address,
true)))
160 address[12] = v4Address.
address[0];
161 address[13] = v4Address.
address[1];
162 address[14] = v4Address.
address[2];
163 address[15] = v4Address.
address[3];
171 address[i * 2] = temp.split[0];
172 address[i * 2 + 1] = temp.split[1];
181 String s ((
int) address[0]);
183 for (
int i = 1; i < 4; ++i)
184 s <<
'.' << (
int) address[i];
191 temp.split[0] = address[0];
192 temp.split[1] = address[1];
196 for (
int i = 1; i < 8; ++i)
198 temp.split[0] = address[i * 2];
199 temp.split[1] = address[i * 2 + 1];
204 return getFormattedAddress (addressString);
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;
244 : IPAddress (127, 0, 0, 1); }
248 jassert (unformattedAddress.
contains (
":") && ! unformattedAddress.
contains (
"::"));
251 auto addressString = unformattedAddress.
dropLastCharacters (portString.length()).removeCharacters (
"[]");
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);
340 if (isIPv4MappedAddress (mappedAddress))
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]) };
359 auto addresses = getAllAddresses (includeIPv6);
361 for (
auto& a : addresses)
371 findAllAddresses (addresses, includeIPv6);
380 struct IPAddressTests :
public UnitTest 383 :
UnitTest (
"IPAddress", UnitTestCategories::networking)
386 void runTest()
override 389 testFindAllAddresses();
390 testFindBroadcastAddress();
393 void testConstructors()
395 beginTest (
"constructors");
399 expect (defaultConstructed.
isNull());
402 expect (! local.isNull());
405 expect (! ipv4.isNull());
406 expect (! ipv4.isIPv6);
407 expect (ipv4.toString() ==
"1.2.3.4");
410 void testFindAllAddresses()
412 beginTest (
"find all addresses");
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");
443 for (
auto& a : addresses)
445 expect (! a.isNull());
450 if (! broadcastAddress.isNull())
462 static IPAddressTests iPAddressTests;
static IPAddress convertIPv4AddressToIPv4Mapped(const IPAddress &addressToMap)
static String getFormattedAddress(const String &unformattedAddress)
String fromFirstOccurrenceOf(StringRef substringToStartFrom, bool includeSubStringInResult, bool ignoreCase) const
static IPAddress broadcast() noexcept
int lastIndexOf(StringRef textToLookFor) const noexcept
String dropLastCharacters(int numberToDrop) const
static bool isIPv4MappedAddress(const IPAddress &mappedAddress)
String & getReference(int index) noexcept
int indexOf(StringRef stringToLookFor, bool ignoreCase=false, int startIndex=0) const
static String repeatedString(StringRef stringToRepeat, int numberOfTimesToRepeat)
bool containsAnyOf(StringRef charactersItMightContain) const noexcept
static IPAddress convertIPv4MappedAddressToIPv4(const IPAddress &mappedAddress)
bool contains(StringRef text) const noexcept
static void findAllAddresses(Array< IPAddress > &results, bool includeIPv6=false)
static String toHexString(IntegerType number)
String upToLastOccurrenceOf(StringRef substringToFind, bool includeSubStringInResult, bool ignoreCase) const
static StringArray fromTokens(StringRef stringToTokenise, bool preserveQuotedStrings)
static Array< IPAddress > getAllAddresses(bool includeIPv6=false)
int indexOf(StringRef textToLookFor) const noexcept
int size() const noexcept
static IPAddress getLocalAddress(bool includeIPv6=false)
String replace(StringRef stringToReplace, StringRef stringToInsertInstead, bool ignoreCase=false) const
static IPAddress any() noexcept
static IPAddress local(bool IPv6=false) noexcept
int compare(const IPAddress &) const noexcept
static IPAddress getInterfaceBroadcastAddress(const IPAddress &interfaceAddress)