6#include "Stroika/Foundation/Memory/Common.h"
22 : fAddressFamily_ (AddressFamily::V4)
23#if qStroika_Foundation_Common_Platform_POSIX
25#elif qStroika_Foundation_Common_Platform_Windows
26 , fV4_{in_addr{{
static_cast<uint8_t> (Memory::BitSubstring (i, 0, 8)),
static_cast<uint8_t> (Memory::BitSubstring (i, 8, 16)),
27 static_cast<uint8_t> (Memory::BitSubstring (i, 16, 24)),
static_cast<uint8_t> (Memory::BitSubstring (i, 24, 32))}}}
30#if qStroika_Foundation_Common_Platform_Windows
31 Assert (fV4_.s_addr == i);
34 inline InternetAddress::InternetAddress (
const in_addr_t& i, ByteOrder byteOrder)
35 : fAddressFamily_{AddressFamily::V4}
36#if qStroika_Foundation_Common_Platform_POSIX
40#if qStroika_Foundation_Common_Platform_Windows
44 fV4_.s_addr =
htonl (fV4_.s_addr);
48 : fAddressFamily_{AddressFamily::V4}
53 : fAddressFamily_{AddressFamily::V4}
57 fV4_.s_addr =
htonl (fV4_.s_addr);
70 , fArray_4_uint_{octets}
75 , fArray_4_byte_{octets}
79 : fAddressFamily_{AddressFamily::V6}
85 , fArray_16_uint_{octets}
90 , fArray_16_byte_{octets}
93 template <ranges::range ITERABLE_OF_UINT8OrByte>
95 requires (Traversal::IIterableOfTo<ITERABLE_OF_UINT8OrByte, byte> or Traversal::IIterableOfTo<ITERABLE_OF_UINT8OrByte, uint8_t>)
98 Require (af != AddressFamily::V4 or octets.size () == 4);
99 Require (af != AddressFamily::V6 or octets.size () == 16);
101 for (
auto b : octets) {
102 fArray_16_uint_[i++] =
static_cast<uint8_t
> (b);
107 return fAddressFamily_ == AddressFamily::UNKNOWN;
111 fAddressFamily_ = AddressFamily::UNKNOWN;
115 return fAddressFamily_;
120 case AddressFamily::V4:
122 case AddressFamily::V6:
156#if qStroika_Foundation_Common_Platform_POSIX
160 Require (fAddressFamily_ == AddressFamily::V4);
167 Require (fAddressFamily_ == AddressFamily::V4);
173 Require (GetAddressSize () == 4u);
174 return fArray_4_uint_;
179 Require (GetAddressSize () == 4u);
180 return fArray_4_byte_;
185 Require (GetAddressSize () == 16u);
186 return fArray_16_uint_;
191 Require (GetAddressSize () == 16u);
192 return fArray_16_byte_;
197 if (GetAddressSize ().has_value ()) {
198 Assert (*GetAddressSize () <= 16);
199 return vector<byte>{fArray_16_byte_.begin (), fArray_16_byte_.begin () + *GetAddressSize ()};
202 return vector<byte>{};
208 if (GetAddressSize ().has_value ()) {
209 Assert (*GetAddressSize () <= 16);
210 return vector<uint8_t>{fArray_16_uint_.begin (), fArray_16_uint_.begin () + *GetAddressSize ()};
213 return vector<uint8_t>{};
219 Require (fAddressFamily_ == AddressFamily::V6);
225 Require (fAddressFamily_ == AddressFamily::V4);
235 inline strong_ordering InternetAddress::operator<=> (
const InternetAddress& rhs)
const
237 return TWC_ (*
this,
rhs);
239 inline bool InternetAddress::operator== (
const InternetAddress& rhs)
const
241 return TWC_ (*
this,
rhs) == 0;
243 inline strong_ordering InternetAddress::TWC_ (
const InternetAddress& lhs,
const InternetAddress& rhs)
245 if (
auto cmp =
lhs.fAddressFamily_ <=>
rhs.fAddressFamily_;
cmp != strong_ordering::equal) {
248 switch (
lhs.fAddressFamily_) {
249 case AddressFamily::UNKNOWN: {
250 return strong_ordering::equal;
252 case AddressFamily::V4: {
253 return Memory::CompareBytes (Traversal::Iterator2Pointer (
lhs.fArray_4_uint_.begin ()),
254 Traversal::Iterator2Pointer (
rhs.fArray_4_uint_.begin ()), 4) <=> 0;
256 case AddressFamily::V6: {
257 return Memory::CompareBytes (Traversal::Iterator2Pointer (
lhs.fArray_16_uint_.begin ()),
258 Traversal::Iterator2Pointer (
rhs.fArray_16_uint_.begin ()), 16) <=> 0;
262 return strong_ordering::equal;
266 constexpr InternetAddress kAddrAny{in_addr{}};
269 constexpr InternetAddress kAddrAny{in6_addr{}};
272 constexpr InternetAddress kLocalhost{0x7f, 0x0, 0x0, 0x1};
275 constexpr InternetAddress kLocalhost{in6_addr{{{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}}}};
278 constexpr InternetAddress kV4MappedLocalhost{in6_addr{{{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 0x7f, 0, 0, 1}}}};
285 inline IO::Network::InternetAddress Default<IO::Network::InternetAddress>::GetNext (IO::Network::InternetAddress n)
287 Require (n != kUpperBound);
290 inline IO::Network::InternetAddress Default<IO::Network::InternetAddress>::GetPrevious (IO::Network::InternetAddress n [[maybe_unused]])
292 Require (n != kLowerBound);
297 constexpr auto Default<IO::Network::InternetAddress>::Difference (Common::ArgByValueType<value_type> lhs,
298 Common::ArgByValueType<value_type> rhs) -> SignedDifferenceType
300 using IO::Network::InternetAddress;
301 Require (lhs.GetAddressFamily () == InternetAddress::AddressFamily::V4);
302 Require (rhs.GetAddressFamily () == InternetAddress::AddressFamily::V4);
303 array<uint8_t, 4> l = lhs.As<array<uint8_t, 4>> ();
304 array<uint8_t, 4> r = rhs.As<array<uint8_t, 4>> ();
305 return (SignedDifferenceType (r[0]) - SignedDifferenceType (l[0])) * (1 << 24) +
306 (SignedDifferenceType (r[1]) - SignedDifferenceType (l[1])) * (1 << 16) +
307 (SignedDifferenceType (r[2]) - SignedDifferenceType (l[2])) * (1 << 8) +
308 (SignedDifferenceType (r[3]) - SignedDifferenceType (l[3])) * (1 << 0);
310 inline constexpr IO::Network::InternetAddress Default<IO::Network::InternetAddress>::kLowerBound = IO::Network::InternetAddress::min ();
311 inline constexpr IO::Network::InternetAddress Default<IO::Network::InternetAddress>::kUpperBound = IO::Network::InternetAddress::max ();
#define AssertNotImplemented()
String is like std::u32string, except it is much easier to use, often much more space efficient,...
nonvirtual constexpr bool empty() const
constexpr InternetAddress()
nonvirtual constexpr optional< size_t > GetAddressSize() const
nonvirtual constexpr AddressFamily GetAddressFamily() const
static constexpr InternetAddress max()
static constexpr InternetAddress min()