Skip to content

Commit

Permalink
Rewrite IPAddress from std::array to C-style array.
Browse files Browse the repository at this point in the history
  • Loading branch information
safocl committed Nov 28, 2023
1 parent 717a120 commit d85523f
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 13 deletions.
19 changes: 9 additions & 10 deletions api/IPAddress.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@

#include "IPAddress.h"
#include "Print.h"
#include <algorithm>
#include <cstdint>

using namespace arduino;

Expand Down Expand Up @@ -58,9 +56,9 @@ IPAddress::IPAddress(const uint8_t *address) : IPAddress(IPv4, address) {}
IPAddress::IPAddress(IPType ip_type, const uint8_t *address) : _type(ip_type)
{
if (ip_type == IPv4) {
std::copy(address, address + 4, &_address[IPADDRESS_V4_BYTES_INDEX]);
memcpy(&_address[IPADDRESS_V4_BYTES_INDEX], address, sizeof(uint32_t));
} else {
std::copy(address, address + _address.size(), _address.begin());
memcpy(_address, address, sizeof(_address));
}
}

Expand Down Expand Up @@ -110,7 +108,7 @@ bool IPAddress::fromString4(const char *address)
int16_t acc = -1; // Accumulator
uint8_t dots = 0;

_address.fill(0);
memset(_address, 0, sizeof(_address));
while (*address)
{
char c = *address++;
Expand Down Expand Up @@ -228,8 +226,8 @@ IPAddress& IPAddress::operator=(const uint8_t *address)
// IPv4 only conversion from byte pointer
_type = IPv4;

_address.fill(0);
std::copy(address, address + 4, &_address[IPADDRESS_V4_BYTES_INDEX]);
memset(_address, 0, sizeof(_address));
memcpy(&_address[IPADDRESS_V4_BYTES_INDEX], address, sizeof(uint32_t));

return *this;
}
Expand All @@ -245,21 +243,22 @@ IPAddress& IPAddress::operator=(uint32_t address)
// IPv4 conversion
// See note on conversion/comparison and uint32_t
_type = IPv4;
_address.fill(0);
memset(_address, 0, sizeof(_address));
uint32_t& addressRef = reinterpret_cast<uint32_t&>(_address[IPADDRESS_V4_BYTES_INDEX]);
addressRef = address;
return *this;
}

bool IPAddress::operator==(const IPAddress& addr) const {
return addr._type == _type && std::equal(addr._address.begin(), addr._address.end(), _address.begin());
return (addr._type == _type)
&& (memcmp(addr._address, _address, sizeof(_address)) == 0);
}

bool IPAddress::operator==(const uint8_t* addr) const
{
// IPv4 only comparison to byte pointer
// Can't support IPv6 as we know our type, but not the length of the pointer
return _type == IPv4 && std::equal(_address.begin() + IPADDRESS_V4_BYTES_INDEX, _address.end(), addr);
return _type == IPv4 && memcmp(addr, &_address[IPADDRESS_V4_BYTES_INDEX], sizeof(uint32_t)) == 0;
}

uint8_t IPAddress::operator[](int index) const {
Expand Down
5 changes: 2 additions & 3 deletions api/IPAddress.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@

#pragma once

#include <array>
#include <stdint.h>
#include "Printable.h"
#include "String.h"
Expand All @@ -42,14 +41,14 @@ enum IPType {

class IPAddress : public Printable {
private:
alignas(alignof(uint32_t)) std::array<uint8_t, 16> _address{};
alignas(alignof(uint32_t)) uint8_t _address[16]{};
IPType _type{IPv4};

// Access the raw byte array containing the address. Because this returns a pointer
// to the internal structure rather than a copy of the address this function should only
// be used when you know that the usage of the returned uint8_t* will be transient and not
// stored.
uint8_t* raw_address() { return _type == IPv4 ? &_address[IPADDRESS_V4_BYTES_INDEX] : _address.data(); }
uint8_t* raw_address() { return _type == IPv4 ? &_address[IPADDRESS_V4_BYTES_INDEX] : _address; }

public:
// Constructors
Expand Down

0 comments on commit d85523f

Please sign in to comment.