blob: 55c6d10d03e88a125e4b2475482c4612a3e8a961 [file] [log] [blame]
William A. Kennington IIIbb0eacc2022-10-21 15:22:06 -07001#include "types.hpp"
2
William A. Kennington IIIbb0eacc2022-10-21 15:22:06 -07003#include <charconv>
4
5namespace phosphor::network::detail
6{
7
8std::string_view AddrBufMaker<ether_addr>::operator()(ether_addr val) noexcept
9{
10 for (char* ptr = buf.data() + 2; ptr < buf.end(); ptr += 3)
11 {
12 *ptr = ':';
13 }
14 for (size_t i = 0; i < 6; ++i)
15 {
16 char* tmp = buf.data() + i * 3;
17 uint8_t byte = val.ether_addr_octet[i];
18 if (byte < 16)
19 {
20 *(tmp++) = '0';
21 }
22 std::to_chars(tmp, buf.end(), byte, 16);
23 }
24 return {buf.begin(), buf.size()};
25}
26
27std::string_view AddrBufMaker<in_addr>::operator()(in_addr val) noexcept
28{
William A. Kennington III71de63a2022-11-08 10:50:54 -080029 auto v = bswap(ntoh(val.s_addr));
William A. Kennington IIIbb0eacc2022-10-21 15:22:06 -070030 char* ptr = buf.begin();
31 for (size_t i = 0; i < 3; ++i)
32 {
33 const auto res = std::to_chars(ptr, buf.end(), v & 0xff, 10);
34 *res.ptr = '.';
35 ptr = res.ptr + 1;
36 v >>= 8;
37 }
38 const auto res = std::to_chars(ptr, buf.end(), v & 0xff, 10);
39 return {buf.data(), res.ptr};
40}
41
42std::string_view AddrBufMaker<in6_addr>::operator()(in6_addr val) noexcept
43{
44 size_t skip_start = 0;
45 size_t skip_size = 0;
46 {
47 size_t new_start = 0;
48 size_t new_size = 0;
49 for (size_t i = 0; i < 9; ++i)
50 {
51 if (i < 8 && val.s6_addr16[i] == 0)
52 {
53 if (new_start + new_size == i)
54 {
55 new_size++;
56 }
57 else
58 {
59 new_start = i;
60 new_size = 1;
61 }
62 }
63 else if (new_start + new_size == i && new_size > skip_size)
64 {
65 skip_start = new_start;
66 skip_size = new_size;
67 }
68 }
69 }
70 char* ptr = buf.begin();
71 for (size_t i = 0; i < 8; ++i)
72 {
73 if (i == skip_start && skip_size > 0)
74 {
75 if (i == 0)
76 {
77 *(ptr++) = ':';
78 }
79 *(ptr++) = ':';
80 i += skip_size - 1;
81 continue;
82 }
83 const auto res =
William A. Kennington III71de63a2022-11-08 10:50:54 -080084 std::to_chars(ptr, buf.end(), ntoh(val.s6_addr16[i]), 16);
William A. Kennington IIIbb0eacc2022-10-21 15:22:06 -070085 ptr = res.ptr;
86 if (i < 7)
87 {
88 *(ptr++) = ':';
89 }
90 }
91 return {buf.data(), ptr};
92}
93
94} // namespace phosphor::network::detail
95
William A. Kennington III653114f2022-11-01 22:34:04 -070096std::size_t std::hash<in_addr>::operator()(in_addr addr) const noexcept
97{
98 return std::hash<decltype(addr.s_addr)>{}(addr.s_addr);
99}
100
101std::size_t std::hash<in6_addr>::operator()(in6_addr addr) const noexcept
102{
103 return phosphor::network::hash_multi(addr.s6_addr32[0], addr.s6_addr32[1],
104 addr.s6_addr32[2], addr.s6_addr32[3]);
105}
106
William A. Kennington IIIbb0eacc2022-10-21 15:22:06 -0700107std::string std::to_string(ether_addr value)
108{
109 return string(phosphor::network::detail::AddrBufMaker<ether_addr>{}(value));
110}
111std::string std::to_string(in_addr value)
112{
113 return string(phosphor::network::detail::AddrBufMaker<in_addr>{}(value));
114}
115std::string std::to_string(in6_addr value)
116{
117 return string(phosphor::network::detail::AddrBufMaker<in6_addr>{}(value));
118}
119std::string std::to_string(phosphor::network::InAddrAny value)
120{
121 return std::visit([](auto v) { return std::to_string(v); }, value);
122}