19
19
20
20
#include " IPAddress.h"
21
21
#include " Print.h"
22
+ #include < algorithm>
23
+ #include < cstdint>
22
24
23
25
using namespace arduino ;
24
26
25
- IPAddress::IPAddress () : IPAddress(IPv4) {}
27
+ IPAddress::IPAddress () = default;
26
28
27
- IPAddress::IPAddress (IPType ip_type)
28
- {
29
- _type = ip_type;
30
- memset (_address.bytes , 0 , sizeof (_address.bytes ));
31
- }
29
+ IPAddress::IPAddress (IPType ip_type) : _type(ip_type) {}
32
30
33
31
IPAddress::IPAddress (uint8_t first_octet, uint8_t second_octet, uint8_t third_octet, uint8_t fourth_octet)
34
32
{
35
- _type = IPv4;
36
- memset (_address.bytes , 0 , sizeof (_address.bytes ));
37
- _address.bytes [IPADDRESS_V4_BYTES_INDEX] = first_octet;
38
- _address.bytes [IPADDRESS_V4_BYTES_INDEX + 1 ] = second_octet;
39
- _address.bytes [IPADDRESS_V4_BYTES_INDEX + 2 ] = third_octet;
40
- _address.bytes [IPADDRESS_V4_BYTES_INDEX + 3 ] = fourth_octet;
33
+ _address[IPADDRESS_V4_BYTES_INDEX] = first_octet;
34
+ _address[IPADDRESS_V4_BYTES_INDEX + 1 ] = second_octet;
35
+ _address[IPADDRESS_V4_BYTES_INDEX + 2 ] = third_octet;
36
+ _address[IPADDRESS_V4_BYTES_INDEX + 3 ] = fourth_octet;
41
37
}
42
38
43
- IPAddress::IPAddress (uint8_t o1, uint8_t o2, uint8_t o3, uint8_t o4, uint8_t o5, uint8_t o6, uint8_t o7, uint8_t o8, uint8_t o9, uint8_t o10, uint8_t o11, uint8_t o12, uint8_t o13, uint8_t o14, uint8_t o15, uint8_t o16) {
44
- _type = IPv6;
45
- _address.bytes [0 ] = o1;
46
- _address.bytes [1 ] = o2;
47
- _address.bytes [2 ] = o3;
48
- _address.bytes [3 ] = o4;
49
- _address.bytes [4 ] = o5;
50
- _address.bytes [5 ] = o6;
51
- _address.bytes [6 ] = o7;
52
- _address.bytes [7 ] = o8;
53
- _address.bytes [8 ] = o9;
54
- _address.bytes [9 ] = o10;
55
- _address.bytes [10 ] = o11;
56
- _address.bytes [11 ] = o12;
57
- _address.bytes [12 ] = o13;
58
- _address.bytes [13 ] = o14;
59
- _address.bytes [14 ] = o15;
60
- _address.bytes [15 ] = o16;
61
- }
39
+ IPAddress::IPAddress (uint8_t o1, uint8_t o2, uint8_t o3, uint8_t o4, uint8_t o5, uint8_t o6, uint8_t o7, uint8_t o8, uint8_t o9, uint8_t o10, uint8_t o11, uint8_t o12, uint8_t o13, uint8_t o14, uint8_t o15, uint8_t o16) : _address{o1, o2, o3, o4, o5, o6, o7, o8, o9, o10, o11, o12, o13, o14, o15, o16}, _type(IPv6) {}
62
40
63
- IPAddress::IPAddress (uint32_t address)
41
+ // IPv4 only
42
+ IPAddress::IPAddress (uint32_t address)
64
43
{
65
- // IPv4 only
66
- _type = IPv4;
67
- memset (_address.bytes , 0 , sizeof (_address.bytes ));
68
- _address.dword [IPADDRESS_V4_DWORD_INDEX] = address;
44
+ uint32_t & addressRef = reinterpret_cast <uint32_t &>(_address[IPADDRESS_V4_BYTES_INDEX]);
45
+ addressRef = address;
69
46
70
47
// NOTE on conversion/comparison and uint32_t:
71
48
// These conversions are host platform dependent.
@@ -78,14 +55,12 @@ IPAddress::IPAddress(uint32_t address)
78
55
79
56
IPAddress::IPAddress (const uint8_t *address) : IPAddress(IPv4, address) {}
80
57
81
- IPAddress::IPAddress (IPType ip_type, const uint8_t *address)
58
+ IPAddress::IPAddress (IPType ip_type, const uint8_t *address) : _type(ip_type)
82
59
{
83
- _type = ip_type;
84
60
if (ip_type == IPv4) {
85
- memset (_address.bytes , 0 , sizeof (_address.bytes ));
86
- memcpy (&_address.bytes [IPADDRESS_V4_BYTES_INDEX], address, sizeof (uint32_t ));
61
+ std::copy (address, address + 4 , &_address[IPADDRESS_V4_BYTES_INDEX]);
87
62
} else {
88
- memcpy (_address. bytes , address, sizeof ( _address.bytes ));
63
+ std::copy (address , address + _address. size (), _address.begin ( ));
89
64
}
90
65
}
91
66
@@ -97,18 +72,18 @@ IPAddress::IPAddress(const char *address)
97
72
String IPAddress::toString4 () const
98
73
{
99
74
char szRet[16 ];
100
- snprintf (szRet, sizeof (szRet), " %u.%u.%u.%u" , _address. bytes [IPADDRESS_V4_BYTES_INDEX], _address. bytes [IPADDRESS_V4_BYTES_INDEX + 1 ], _address. bytes [IPADDRESS_V4_BYTES_INDEX + 2 ], _address. bytes [IPADDRESS_V4_BYTES_INDEX + 3 ]);
75
+ snprintf (szRet, sizeof (szRet), " %u.%u.%u.%u" , _address[IPADDRESS_V4_BYTES_INDEX], _address[IPADDRESS_V4_BYTES_INDEX + 1 ], _address[IPADDRESS_V4_BYTES_INDEX + 2 ], _address[IPADDRESS_V4_BYTES_INDEX + 3 ]);
101
76
return String (szRet);
102
77
}
103
78
104
79
String IPAddress::toString6 () const
105
80
{
106
81
char szRet[40 ];
107
82
snprintf (szRet, sizeof (szRet), " %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x" ,
108
- _address. bytes [0 ], _address. bytes [1 ], _address. bytes [2 ], _address. bytes [3 ],
109
- _address. bytes [4 ], _address. bytes [5 ], _address. bytes [6 ], _address. bytes [7 ],
110
- _address. bytes [8 ], _address. bytes [9 ], _address. bytes [10 ], _address. bytes [11 ],
111
- _address. bytes [12 ], _address. bytes [13 ], _address. bytes [14 ], _address. bytes [15 ]);
83
+ _address[0 ], _address[1 ], _address[2 ], _address[3 ],
84
+ _address[4 ], _address[5 ], _address[6 ], _address[7 ],
85
+ _address[8 ], _address[9 ], _address[10 ], _address[11 ],
86
+ _address[12 ], _address[13 ], _address[14 ], _address[15 ]);
112
87
return String (szRet);
113
88
}
114
89
@@ -135,7 +110,7 @@ bool IPAddress::fromString4(const char *address)
135
110
int16_t acc = -1 ; // Accumulator
136
111
uint8_t dots = 0 ;
137
112
138
- memset ( _address.bytes , 0 , sizeof (_address. bytes ) );
113
+ _address.fill ( 0 );
139
114
while (*address)
140
115
{
141
116
char c = *address++;
@@ -157,7 +132,7 @@ bool IPAddress::fromString4(const char *address)
157
132
/* No value between dots, e.g. '1..' */
158
133
return false ;
159
134
}
160
- _address. bytes [IPADDRESS_V4_BYTES_INDEX + dots++] = acc;
135
+ _address[IPADDRESS_V4_BYTES_INDEX + dots++] = acc;
161
136
acc = -1 ;
162
137
}
163
138
else
@@ -175,7 +150,7 @@ bool IPAddress::fromString4(const char *address)
175
150
/* No value between dots, e.g. '1..' */
176
151
return false ;
177
152
}
178
- _address. bytes [IPADDRESS_V4_BYTES_INDEX + 3 ] = acc;
153
+ _address[IPADDRESS_V4_BYTES_INDEX + 3 ] = acc;
179
154
_type = IPv4;
180
155
return true ;
181
156
}
@@ -215,8 +190,8 @@ bool IPAddress::fromString6(const char *address) {
215
190
if (colons == 7 )
216
191
// too many separators
217
192
return false ;
218
- _address. bytes [colons * 2 ] = acc >> 8 ;
219
- _address. bytes [colons * 2 + 1 ] = acc & 0xff ;
193
+ _address[colons * 2 ] = acc >> 8 ;
194
+ _address[colons * 2 + 1 ] = acc & 0xff ;
220
195
colons++;
221
196
acc = 0 ;
222
197
}
@@ -233,15 +208,15 @@ bool IPAddress::fromString6(const char *address) {
233
208
// Too many segments (double colon must be at least one zero field)
234
209
return false ;
235
210
}
236
- _address. bytes [colons * 2 ] = acc >> 8 ;
237
- _address. bytes [colons * 2 + 1 ] = acc & 0xff ;
211
+ _address[colons * 2 ] = acc >> 8 ;
212
+ _address[colons * 2 + 1 ] = acc & 0xff ;
238
213
colons++;
239
214
240
215
if (double_colons != -1 ) {
241
216
for (int i = colons * 2 - double_colons * 2 - 1 ; i >= 0 ; i--)
242
- _address. bytes [16 - colons * 2 + double_colons * 2 + i] = _address. bytes [double_colons * 2 + i];
217
+ _address[16 - colons * 2 + double_colons * 2 + i] = _address[double_colons * 2 + i];
243
218
for (int i = double_colons * 2 ; i < 16 - colons * 2 + double_colons * 2 ; i++)
244
- _address. bytes [i] = 0 ;
219
+ _address[i] = 0 ;
245
220
}
246
221
247
222
_type = IPv6;
@@ -252,8 +227,10 @@ IPAddress& IPAddress::operator=(const uint8_t *address)
252
227
{
253
228
// IPv4 only conversion from byte pointer
254
229
_type = IPv4;
255
- memset (_address.bytes , 0 , sizeof (_address.bytes ));
256
- memcpy (&_address.bytes [IPADDRESS_V4_BYTES_INDEX], address, sizeof (uint32_t ));
230
+
231
+ _address.fill (0 );
232
+ std::copy (address, address + 4 , &_address[IPADDRESS_V4_BYTES_INDEX]);
233
+
257
234
return *this ;
258
235
}
259
236
@@ -268,35 +245,35 @@ IPAddress& IPAddress::operator=(uint32_t address)
268
245
// IPv4 conversion
269
246
// See note on conversion/comparison and uint32_t
270
247
_type = IPv4;
271
- memset (_address.bytes , 0 , sizeof (_address.bytes ));
272
- _address.dword [IPADDRESS_V4_DWORD_INDEX] = address;
248
+ _address.fill (0 );
249
+ uint32_t & addressRef = reinterpret_cast <uint32_t &>(_address[IPADDRESS_V4_BYTES_INDEX]);
250
+ addressRef = address;
273
251
return *this ;
274
252
}
275
253
276
254
bool IPAddress::operator ==(const IPAddress& addr) const {
277
- return (addr._type == _type)
278
- && (memcmp (addr._address .bytes , _address.bytes , sizeof (_address.bytes )) == 0 );
255
+ return addr._type == _type && std::equal (addr._address .begin (), addr._address .end (), _address.begin ());
279
256
}
280
257
281
258
bool IPAddress::operator ==(const uint8_t * addr) const
282
259
{
283
260
// IPv4 only comparison to byte pointer
284
261
// Can't support IPv6 as we know our type, but not the length of the pointer
285
- return _type == IPv4 && memcmp (addr, & _address.bytes [IPADDRESS_V4_BYTES_INDEX], sizeof ( uint32_t )) == 0 ;
262
+ return _type == IPv4 && std::equal ( _address.begin (), _address. end (), addr) ;
286
263
}
287
264
288
265
uint8_t IPAddress::operator [](int index) const {
289
266
if (_type == IPv4) {
290
- return _address. bytes [IPADDRESS_V4_BYTES_INDEX + index ];
267
+ return _address[IPADDRESS_V4_BYTES_INDEX + index ];
291
268
}
292
- return _address. bytes [index ];
269
+ return _address[index ];
293
270
}
294
271
295
272
uint8_t & IPAddress::operator [](int index) {
296
273
if (_type == IPv4) {
297
- return _address. bytes [IPADDRESS_V4_BYTES_INDEX + index ];
274
+ return _address[IPADDRESS_V4_BYTES_INDEX + index ];
298
275
}
299
- return _address. bytes [index ];
276
+ return _address[index ];
300
277
}
301
278
302
279
size_t IPAddress::printTo (Print& p) const
@@ -310,7 +287,7 @@ size_t IPAddress::printTo(Print& p) const
310
287
int8_t current_start = -1 ;
311
288
int8_t current_length = 0 ;
312
289
for (int8_t f = 0 ; f < 8 ; f++) {
313
- if (_address. bytes [f * 2 ] == 0 && _address. bytes [f * 2 + 1 ] == 0 ) {
290
+ if (_address[f * 2 ] == 0 && _address[f * 2 + 1 ] == 0 ) {
314
291
if (current_start == -1 ) {
315
292
current_start = f;
316
293
current_length = 1 ;
@@ -327,10 +304,10 @@ size_t IPAddress::printTo(Print& p) const
327
304
}
328
305
for (int f = 0 ; f < 8 ; f++) {
329
306
if (f < longest_start || f >= longest_start + longest_length) {
330
- uint8_t c1 = _address. bytes [f * 2 ] >> 4 ;
331
- uint8_t c2 = _address. bytes [f * 2 ] & 0xf ;
332
- uint8_t c3 = _address. bytes [f * 2 + 1 ] >> 4 ;
333
- uint8_t c4 = _address. bytes [f * 2 + 1 ] & 0xf ;
307
+ uint8_t c1 = _address[f * 2 ] >> 4 ;
308
+ uint8_t c2 = _address[f * 2 ] & 0xf ;
309
+ uint8_t c3 = _address[f * 2 + 1 ] >> 4 ;
310
+ uint8_t c4 = _address[f * 2 + 1 ] & 0xf ;
334
311
if (c1 > 0 ) {
335
312
n += p.print ((char )(c1 < 10 ? ' 0' + c1 : ' a' + c1 - 10 ));
336
313
}
@@ -357,10 +334,10 @@ size_t IPAddress::printTo(Print& p) const
357
334
// IPv4
358
335
for (int i =0 ; i < 3 ; i++)
359
336
{
360
- n += p.print (_address. bytes [IPADDRESS_V4_BYTES_INDEX + i], DEC);
337
+ n += p.print (_address[IPADDRESS_V4_BYTES_INDEX + i], DEC);
361
338
n += p.print (' .' );
362
339
}
363
- n += p.print (_address. bytes [IPADDRESS_V4_BYTES_INDEX + 3 ], DEC);
340
+ n += p.print (_address[IPADDRESS_V4_BYTES_INDEX + 3 ], DEC);
364
341
return n;
365
342
}
366
343
0 commit comments