1919
2020#include " IPAddress.h"
2121#include " Print.h"
22+ #include < algorithm>
23+ #include < cstdint>
2224
2325using namespace arduino ;
2426
25- IPAddress::IPAddress (): IPAddress(IPv4) {}
27+ IPAddress::IPAddress ()= default;
2628
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) {}
3230
3331IPAddress::IPAddress (uint8_t first_octet,uint8_t second_octet,uint8_t third_octet,uint8_t fourth_octet)
3432{
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;
4137}
4238
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) {}
6240
63- IPAddress::IPAddress (uint32_t address)
41+ // IPv4 only
42+ IPAddress::IPAddress (uint32_t address)
6443{
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;
6946
7047// NOTE on conversion/comparison and uint32_t:
7148// These conversions are host platform dependent.
@@ -78,14 +55,12 @@ IPAddress::IPAddress(uint32_t address)
7855
7956IPAddress::IPAddress (const uint8_t *address) : IPAddress(IPv4, address) {}
8057
81- IPAddress::IPAddress (IPType ip_type,const uint8_t *address)
58+ IPAddress::IPAddress (IPType ip_type,const uint8_t *address) : _type(ip_type)
8259{
83- _type = ip_type;
8460if (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]);
8762 }else {
88- memcpy (_address. bytes , address, sizeof ( _address.bytes ));
63+ std::copy (address , address + _address. size (), _address.begin ( ));
8964 }
9065}
9166
@@ -97,18 +72,18 @@ IPAddress::IPAddress(const char *address)
9772StringIPAddress::toString4 ()const
9873{
9974char 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 ]);
10176return String (szRet);
10277}
10378
10479StringIPAddress::toString6 ()const
10580{
10681char szRet[40 ];
10782snprintf (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 ]);
11287return String (szRet);
11388}
11489
@@ -135,7 +110,7 @@ bool IPAddress::fromString4(const char *address)
135110int16_t acc = -1 ;// Accumulator
136111uint8_t dots =0 ;
137112
138- memset ( _address.bytes , 0 , sizeof (_address. bytes ) );
113+ _address.fill ( 0 );
139114while (*address)
140115 {
141116char c = *address++;
@@ -157,7 +132,7 @@ bool IPAddress::fromString4(const char *address)
157132/* No value between dots, e.g. '1..'*/
158133return false ;
159134 }
160- _address. bytes [IPADDRESS_V4_BYTES_INDEX + dots++] = acc;
135+ _address[IPADDRESS_V4_BYTES_INDEX + dots++] = acc;
161136 acc = -1 ;
162137 }
163138else
@@ -175,7 +150,7 @@ bool IPAddress::fromString4(const char *address)
175150/* No value between dots, e.g. '1..'*/
176151return false ;
177152 }
178- _address. bytes [IPADDRESS_V4_BYTES_INDEX +3 ] = acc;
153+ _address[IPADDRESS_V4_BYTES_INDEX +3 ] = acc;
179154 _type = IPv4;
180155return true ;
181156}
@@ -215,8 +190,8 @@ bool IPAddress::fromString6(const char *address) {
215190if (colons ==7 )
216191// too many separators
217192return 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 ;
220195 colons++;
221196 acc =0 ;
222197 }
@@ -233,15 +208,15 @@ bool IPAddress::fromString6(const char *address) {
233208// Too many segments (double colon must be at least one zero field)
234209return false ;
235210 }
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 ;
238213 colons++;
239214
240215if (double_colons != -1 ) {
241216for (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];
243218for (int i = double_colons *2 ; i <16 - colons *2 + double_colons *2 ; i++)
244- _address. bytes [i] =0 ;
219+ _address[i] =0 ;
245220 }
246221
247222 _type = IPv6;
@@ -252,8 +227,10 @@ IPAddress& IPAddress::operator=(const uint8_t *address)
252227{
253228// IPv4 only conversion from byte pointer
254229 _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+
257234return *this ;
258235}
259236
@@ -268,35 +245,35 @@ IPAddress& IPAddress::operator=(uint32_t address)
268245// IPv4 conversion
269246// See note on conversion/comparison and uint32_t
270247 _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;
273251return *this ;
274252}
275253
276254bool 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 ());
279256}
280257
281258bool IPAddress::operator ==(const uint8_t * addr)const
282259{
283260// IPv4 only comparison to byte pointer
284261// 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) ;
286263}
287264
288265uint8_t IPAddress::operator [](int index)const {
289266if (_type == IPv4) {
290- return _address. bytes [IPADDRESS_V4_BYTES_INDEX + index];
267+ return _address[IPADDRESS_V4_BYTES_INDEX + index];
291268 }
292- return _address. bytes [index];
269+ return _address[index];
293270}
294271
295272uint8_t & IPAddress::operator [](int index) {
296273if (_type == IPv4) {
297- return _address. bytes [IPADDRESS_V4_BYTES_INDEX + index];
274+ return _address[IPADDRESS_V4_BYTES_INDEX + index];
298275 }
299- return _address. bytes [index];
276+ return _address[index];
300277}
301278
302279size_t IPAddress::printTo (Print& p)const
@@ -310,7 +287,7 @@ size_t IPAddress::printTo(Print& p) const
310287int8_t current_start = -1 ;
311288int8_t current_length =0 ;
312289for (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 ) {
314291if (current_start == -1 ) {
315292 current_start = f;
316293 current_length =1 ;
@@ -327,10 +304,10 @@ size_t IPAddress::printTo(Print& p) const
327304 }
328305for (int f =0 ; f <8 ; f++) {
329306if (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 ;
334311if (c1 >0 ) {
335312 n += p.print ((char )(c1 <10 ?' 0' + c1 :' a' + c1 -10 ));
336313 }
@@ -357,10 +334,10 @@ size_t IPAddress::printTo(Print& p) const
357334// IPv4
358335for (int i =0 ; i <3 ; i++)
359336 {
360- n += p.print (_address. bytes [IPADDRESS_V4_BYTES_INDEX + i], DEC);
337+ n += p.print (_address[IPADDRESS_V4_BYTES_INDEX + i], DEC);
361338 n += p.print (' .' );
362339 }
363- n += p.print (_address. bytes [IPADDRESS_V4_BYTES_INDEX +3 ], DEC);
340+ n += p.print (_address[IPADDRESS_V4_BYTES_INDEX +3 ], DEC);
364341return n;
365342}
366343