| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115 | #pragma once#include "common.h"#include <WiFi.h>#include <lwip/inet.h>#include <esp_wifi.h>//// There are no less than 3 different types for IP addresses used// by different APIs. This class attempts to unify them to mask the// differences.//class IP4 {private:    union {	uint8_t b[4];	uint32_t l;    };    // assumes gcc    static constexpr uint32_t netswap(uint32_t v) {#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__	return v;#else	return __builtin_bswap32(v);#endif    }    static constexpr uint32_t hostmask(unsigned int n) {	return n >= 32 ? 0 : netswap(((uint32_t)1 << n)-1);    }public:    constexpr IP4() : l{0} { }    constexpr IP4(nullptr_t) : l{0} { }    constexpr IP4(int ll) : l{(uint32_t)ll} { }    constexpr IP4(uint32_t ll) : l{ll} { }    constexpr IP4(uint8_t b0, uint8_t b1, uint8_t b2, uint8_t b3) :	b{b0,b1,b2,b3} { }    IP4(const IPAddress & ip) : l{ip} { }    constexpr IP4(const ip_addr_t & ip) :	l{ip.type == IPADDR_TYPE_V4 ? ip.u_addr.ip4.addr : 0} { }    constexpr IP4(const esp_ip_addr_t & ip) :	l{ip.type == IPADDR_TYPE_V4 ? ip.u_addr.ip4.addr : 0} { }    constexpr IP4(const IP4 &nip, const IP4 &hip, unsigned int n) :	l{(nip.l & ~hostmask(n)) | (hip.l & hostmask(n))} { }    constexpr IP4(const IP4 &nip, const IP4 &hip, const IP4 &mask) :	l{(nip.l & ~mask.l) | (hip.l & mask.l)} { }    IP4(const char *str);    operator uint32_t () const { return l; }    operator IPAddress () const { return IPAddress(l); }    constexpr operator ip_addr_t () const {	return ip_addr_t {	    .u_addr = {.ip4 = {.addr = l}},	    .type = IPADDR_TYPE_V4	};    }    constexpr operator esp_ip_addr_t () const {	return esp_ip_addr_t {	    .u_addr = {.ip4 = {.addr = l}},	    .type = IPADDR_TYPE_V4	};    }    //    // XXX: for C++20, this should implement operator <=>.    //    constexpr operator bool () const { return l != 0; }    constexpr bool operator ! () const { return l == 0; }    constexpr bool operator == (const IP4 &b) const { return l == b.l; }    constexpr bool operator != (const IP4 &b) const { return l != b.l; }    constexpr bool operator < (const IP4 &b) const {	return netswap(l) < netswap(b.l);    }    constexpr bool operator >= (const IP4 &b) const {	return netswap(l) >= netswap(b.l);    }    constexpr bool operator <= (const IP4 &b) const {	return netswap(l) <= netswap(b.l);    }    constexpr bool operator > (const IP4 &b) const {	return netswap(l) > netswap(b.l);    }#ifdef __cpp_impl_three_way_comparison    constexpr auto operator <=> (const IP4 &b) const {	return netswap(l) <=> netswap(b.l);    }#endif    constexpr IP4 operator & (const IP4 &b) const { return IP4(l & b.l); }    constexpr IP4 operator | (const IP4 &b) const { return IP4(l | b.l); }    constexpr IP4 operator ^ (const IP4 &b) const { return IP4(l ^ b.l); }    constexpr IP4 operator ~ () const { return IP4(~l); }    constexpr IP4 operator / (unsigned int n) const {	return IP4(l & ~hostmask(n));    }    constexpr IP4 operator % (unsigned int n) const {	return IP4(l & hostmask(n));    }    constexpr IP4 operator + (uint32_t n) const {	return IP4(netswap(netswap(l) + n));    }    constexpr IP4 operator - (uint32_t n) const {	return IP4(netswap(netswap(l) - n));    }    constexpr int32_t operator - (const IP4 &b) const {	return netswap(l) - netswap(b.l);    }    constexpr uint8_t operator [] (size_t n) const { return b[n]; }    uint8_t & operator [] (size_t n) { return b[n]; }    const char *cstr();};constexpr IP4 null_ip((uint32_t)0);constexpr IP4 any_ip(~(uint32_t)0);
 |