Move string allocation to a point where get_ip_address() is called

This saves RAM/stack on typical socket usage where human readable
format is not exchanged so often.
pull/7192/head
Seppo Takalo 2018-06-12 17:34:52 +03:00
parent 407b2f275d
commit 96ef8e345d
2 changed files with 43 additions and 14 deletions

View File

@ -106,35 +106,36 @@ static void ipv6_to_address(char *addr, const uint8_t *bytes)
SocketAddress::SocketAddress(nsapi_addr_t addr, uint16_t port) SocketAddress::SocketAddress(nsapi_addr_t addr, uint16_t port)
{ {
_ip_address[0] = '\0'; _ip_address = NULL;
set_addr(addr); set_addr(addr);
set_port(port); set_port(port);
} }
SocketAddress::SocketAddress(const char *addr, uint16_t port) SocketAddress::SocketAddress(const char *addr, uint16_t port)
{ {
_ip_address[0] = '\0'; _ip_address = NULL;
set_ip_address(addr); set_ip_address(addr);
set_port(port); set_port(port);
} }
SocketAddress::SocketAddress(const void *bytes, nsapi_version_t version, uint16_t port) SocketAddress::SocketAddress(const void *bytes, nsapi_version_t version, uint16_t port)
{ {
_ip_address[0] = '\0'; _ip_address = NULL;
set_ip_bytes(bytes, version); set_ip_bytes(bytes, version);
set_port(port); set_port(port);
} }
SocketAddress::SocketAddress(const SocketAddress &addr) SocketAddress::SocketAddress(const SocketAddress &addr)
{ {
_ip_address[0] = '\0'; _ip_address = NULL;
set_addr(addr.get_addr()); set_addr(addr.get_addr());
set_port(addr.get_port()); set_port(addr.get_port());
} }
bool SocketAddress::set_ip_address(const char *addr) bool SocketAddress::set_ip_address(const char *addr)
{ {
_ip_address[0] = '\0'; delete[] _ip_address;
_ip_address = NULL;
if (addr && ipv4_is_valid(addr)) { if (addr && ipv4_is_valid(addr)) {
_addr.version = NSAPI_IPv4; _addr.version = NSAPI_IPv4;
@ -166,7 +167,8 @@ void SocketAddress::set_ip_bytes(const void *bytes, nsapi_version_t version)
void SocketAddress::set_addr(nsapi_addr_t addr) void SocketAddress::set_addr(nsapi_addr_t addr)
{ {
_ip_address[0] = '\0'; delete[] _ip_address;
_ip_address = NULL;
_addr = addr; _addr = addr;
} }
@ -181,7 +183,8 @@ const char *SocketAddress::get_ip_address() const
return NULL; return NULL;
} }
if (!_ip_address[0]) { if (!_ip_address) {
_ip_address = new char[NSAPI_IP_SIZE];
if (_addr.version == NSAPI_IPv4) { if (_addr.version == NSAPI_IPv4) {
ipv4_to_address(_ip_address, _addr.bytes); ipv4_to_address(_ip_address, _addr.bytes);
} else if (_addr.version == NSAPI_IPv6) { } else if (_addr.version == NSAPI_IPv6) {
@ -235,6 +238,15 @@ SocketAddress::operator bool() const
} }
} }
SocketAddress &SocketAddress::operator=(const SocketAddress &addr)
{
delete[] _ip_address;
_ip_address = NULL;
set_addr(addr.get_addr());
set_port(addr.get_port());
return *this;
}
bool operator==(const SocketAddress &a, const SocketAddress &b) bool operator==(const SocketAddress &a, const SocketAddress &b)
{ {
if (!a && !b) { if (!a && !b) {
@ -257,7 +269,7 @@ bool operator!=(const SocketAddress &a, const SocketAddress &b)
void SocketAddress::_SocketAddress(NetworkStack *iface, const char *host, uint16_t port) void SocketAddress::_SocketAddress(NetworkStack *iface, const char *host, uint16_t port)
{ {
_ip_address[0] = '\0'; _ip_address = NULL;
// gethostbyname must check for literals, so can call it directly // gethostbyname must check for literals, so can call it directly
int err = iface->gethostbyname(host, this); int err = iface->gethostbyname(host, this);
@ -267,3 +279,8 @@ void SocketAddress::_SocketAddress(NetworkStack *iface, const char *host, uint16
_port = 0; _port = 0;
} }
} }
SocketAddress::~SocketAddress()
{
delete[] _ip_address;
}

View File

@ -28,7 +28,7 @@ class NetworkInterface;
/** SocketAddress class /** SocketAddress class
* *
* Representation of an IP address and port pair. * Representation of an IP address and port pair.
* @addtogroup netsocket * @addtogroup netsocket
*/ */
class SocketAddress { class SocketAddress {
@ -83,7 +83,10 @@ public:
* @param addr SocketAddress to copy * @param addr SocketAddress to copy
*/ */
SocketAddress(const SocketAddress &addr); SocketAddress(const SocketAddress &addr);
/** Destructor */
~SocketAddress();
/** Set the IP address /** Set the IP address
* *
* @param addr Null-terminated represention of the IP address * @param addr Null-terminated represention of the IP address
@ -110,8 +113,11 @@ public:
* @param port 16-bit port * @param port 16-bit port
*/ */
void set_port(uint16_t port); void set_port(uint16_t port);
/** Get the IP address /** Get the human readable IP address
*
* Allocates memory for a string and converts binary address to
* human readable format. String is freed in the destructor.
* *
* @return Null-terminated representation of the IP Address * @return Null-terminated representation of the IP Address
*/ */
@ -134,7 +140,7 @@ public:
* @return Raw IP address * @return Raw IP address
*/ */
nsapi_addr_t get_addr() const; nsapi_addr_t get_addr() const;
/** Get the port /** Get the port
* *
* @return The 16-bit port * @return The 16-bit port
@ -147,6 +153,12 @@ public:
*/ */
operator bool() const; operator bool() const;
/** Copy addres from another SocketAddress
*
* @param addr SocketAddress to copy
*/
SocketAddress &operator=(const SocketAddress &addr);
/** Compare two addresses for equality /** Compare two addresses for equality
* *
* @return True if both addresses are equal * @return True if both addresses are equal
@ -162,7 +174,7 @@ public:
private: private:
void _SocketAddress(NetworkStack *iface, const char *host, uint16_t port); void _SocketAddress(NetworkStack *iface, const char *host, uint16_t port);
mutable char _ip_address[NSAPI_IP_SIZE]; mutable char *_ip_address;
nsapi_addr_t _addr; nsapi_addr_t _addr;
uint16_t _port; uint16_t _port;
}; };