13namespace swoc {
inline namespace SWOC_VERSION_NS {
17bwformat(BufferWriter &w, Spec
const &spec, in6_addr
const &addr) {
18 using QUAD = uint16_t
const;
19 Spec local_spec{spec};
20 uint8_t
const *ptr = addr.s6_addr;
21 uint8_t
const *limit = ptr +
sizeof(addr.s6_addr);
22 QUAD *lower =
nullptr;
23 QUAD *upper =
nullptr;
26 if (spec.
_ext.size()) {
27 if (spec.
_ext.front() ==
'=') {
29 local_spec._fill =
'0';
30 }
else if (spec.
_ext.size() > 1 && spec.
_ext[1] ==
'=') {
32 local_spec._fill = spec.
_ext[0];
38 local_spec._align = Spec::Align::RIGHT;
42 for (QUAD *spot =
reinterpret_cast<QUAD *
>(ptr), *last =
reinterpret_cast<QUAD *
>(limit), *current =
nullptr; spot < last;
47 if (!lower || (upper - lower < spot - current)) {
60 if (!local_spec.has_numeric_type()) {
61 local_spec._type =
'x';
64 for (; ptr < limit; ptr += 2) {
65 if (
reinterpret_cast<uint8_t
const *
>(lower) <= ptr && ptr <=
reinterpret_cast<uint8_t
const *
>(upper)) {
66 if (ptr == addr.s6_addr) {
69 if (ptr ==
reinterpret_cast<uint8_t
const *
>(upper)) {
73 uint16_t f = (ptr[0] << 8) + ptr[1];
75 if (ptr != limit - 2) {
84bwformat(BufferWriter &w, Spec
const &spec, sockaddr
const *addr) {
85 Spec local_spec{spec};
89 bool local_numeric_fill_p{
false};
90 char local_numeric_fill_char{
'0'};
93 bwformat(w, spec,
static_cast<void const *
>(addr));
97 if (spec.
_ext.size()) {
98 if (spec.
_ext.front() ==
'=') {
99 local_numeric_fill_p =
true;
100 local_spec._ext.remove_prefix(1);
101 }
else if (spec.
_ext.size() > 1 && spec.
_ext[1] ==
'=') {
102 local_numeric_fill_p =
true;
103 local_numeric_fill_char = spec.
_ext.front();
104 local_spec._ext.remove_prefix(2);
107 if (local_spec._ext.size()) {
108 addr_p = port_p =
false;
109 for (
char c : local_spec._ext) {
128 bool bracket_p =
false;
129 switch (addr->sa_family) {
131 bwformat(w, spec, IP4Addr{IP4Addr::reorder(
reinterpret_cast<sockaddr_in
const *
>(addr)->sin_addr.s_addr)});
138 bwformat(w, spec,
reinterpret_cast<sockaddr_in6
const *
>(addr)->sin6_addr);
141 w.
print(
"*Invalid IP family [{}]*", addr->sa_family);
152 if (local_numeric_fill_p) {
154 local_spec._fill = local_numeric_fill_char;
155 local_spec._align = Spec::Align::RIGHT;
159 bwformat(w, local_spec,
static_cast<uintmax_t
>(IPEndpoint::host_order_port(addr)));
163 if (addr_p || port_p) {
167 bwformat(w, local_spec,
static_cast<uintmax_t
>(addr->sa_family));
169 swoc::bwformat(w, local_spec, IPEndpoint::family_name(addr->sa_family));
176bwformat(BufferWriter &w, Spec
const &spec, IP4Addr
const &addr) {
178 Spec local_spec{spec};
179 bool align_p =
false;
181 if (spec.
_ext.size()) {
182 if (spec.
_ext.front() ==
'=') {
184 local_spec._fill =
'0';
185 }
else if (spec.
_ext.size() > 1 && spec.
_ext[1] ==
'=') {
187 local_spec._fill = spec.
_ext[0];
193 local_spec._align = Spec::Align::RIGHT;
198 bwformat(w, local_spec,
static_cast<uint8_t
>(host >> 24 & 0xFF));
200 bwformat(w, local_spec,
static_cast<uint8_t
>(host >> 16 & 0xFF));
202 bwformat(w, local_spec,
static_cast<uint8_t
>(host >> 8 & 0xFF));
204 bwformat(w, local_spec,
static_cast<uint8_t
>(host & 0xFF));
209bwformat(BufferWriter &w, Spec
const &spec, IP6Addr
const &addr) {
214bwformat(BufferWriter &w, Spec
const &spec, IP4Srv
const &srv) {
223bwformat(BufferWriter &w, Spec
const &spec, IP6Srv
const &srv) {
228 w.
print(
"]:{}", port);
236bwformat(BufferWriter &w, Spec
const &spec, IPSrv
const &srv) {
239 }
else if (srv.
is_ip6()) {
246bwformat(BufferWriter &w, Spec
const &spec, IPAddr
const &addr) {
247 Spec local_spec{spec};
249 bool family_p{
false};
251 if (spec.
_ext.size()) {
252 if (spec.
_ext.front() ==
'=') {
253 local_spec._ext.remove_prefix(1);
254 }
else if (spec.
_ext.size() > 1 && spec.
_ext[1] ==
'=') {
255 local_spec._ext.remove_prefix(2);
258 if (local_spec._ext.size()) {
260 for (
char c : local_spec._ext) {
277 }
else if (addr.
is_ip6()) {
299bwformat(BufferWriter &w, Spec
const &spec, IP4Range
const &range) {
304 if (spec.
_ext.find(
'c') != spec.
_ext.npos) {
309 if (mask.is_valid()) {
312 bwformat(w, bwf::Spec::DEFAULT, mask);
324bwformat(BufferWriter &w, Spec
const &spec, IP6Range
const &range) {
329 if (spec.
_ext.find(
'c') != spec.
_ext.npos) {
334 if (mask.is_valid()) {
337 bwformat(w, bwf::Spec::DEFAULT, mask);
349bwformat(BufferWriter &w, Spec
const &spec, IPRange
const &range) {
351 range.is(AF_INET6) ?
bwformat(w, spec, range.ip6()) :
356bwformat(BufferWriter &w, Spec
const &spec, IPRangeView
const &rv) {
357 return rv.
is(AF_INET) ?
bwformat(w, spec, rv.
ip4()) : rv.is(AF_INET6) ?
bwformat(w, spec, rv.ip6()) : w.write(
"*-*"_tv);
361bwformat(BufferWriter &w, Spec
const &spec, IP4Net
const &net) {
369bwformat(BufferWriter &w, Spec
const &spec, IP6Net
const &net) {
377bwformat(BufferWriter &w, Spec
const &spec, IPNet
const &net) {
380 }
else if (net.
is_ip4()) {
383 return w.
write(
"*invalid*");
387bwformat(BufferWriter &w, Spec
const &spec, IPMask
const &mask) {
BufferWriter & print(const TextView &fmt, Args &&...args)
virtual BufferWriter & write(char c)=0
metric_type const & max() const
bool is_singleton() const
Check if the interval is exactly one element.
metric_type const & min() const
in_addr_t host_order() const
IPMask const & mask() const
IPMask network_mask() const
constexpr IP4Addr const & addr() const
in_port_t host_order_port() const
in6_addr network_order() const
Return the address in network order.
IPMask const & mask() const
IPMask network_mask() const
in_port_t host_order_port() const
constexpr IP6Addr const & addr() const
bool is_ip6() const
Test for IPv6.
bool is_ip4() const
Test for IPv4.
IP6Addr const & ip6() const
IP4Addr const & ip4() const
sa_family_t family() const
raw_type width() const
The width of the mask.
bool is(sa_family_t family) const
IP4Range const & ip4() const
IP4Range const & ip4() const
bool is(sa_family_t family) const
For template deduction guides.
BufferWriter & bwformat(BufferWriter &w, bwf::Spec const &spec, std::string_view sv)
char _type
Type / radix indicator.
bool has_numeric_type() const
Check if the type in this is numeric.
std::string_view _ext
Extension if provided.