Line data Source code
1 : // Copyright 2025 Accenture.
2 :
3 : #include "ip/to_str.h"
4 :
5 : #include <cstdio>
6 :
7 : // snprintf is used intentionally for fixed-format IPv4/IPv6 string rendering.
8 : // NOLINTBEGIN(cppcoreguidelines-pro-type-vararg)
9 : namespace ip
10 : {
11 4 : ::etl::span<char> to_str(IPAddress const& ipAddr, ::etl::span<char> const& buffer)
12 : {
13 4 : IPAddress::Family const family = addressFamilyOf(ipAddr);
14 4 : size_t const bufferSize = buffer.size();
15 :
16 4 : int printfResult = 0;
17 :
18 4 : if ((IPAddress::IPV4 == family) && (bufferSize >= IP4_MAX_STRING_LENGTH))
19 : {
20 1 : printfResult = ::std::snprintf(
21 : buffer.data(),
22 : bufferSize,
23 : "%d.%d.%d.%d",
24 1 : ipAddr.raw[internal::RAW_IP4_IDX + 0U],
25 1 : ipAddr.raw[internal::RAW_IP4_IDX + 1U],
26 1 : ipAddr.raw[internal::RAW_IP4_IDX + 2U],
27 1 : ipAddr.raw[internal::RAW_IP4_IDX + 3U]);
28 : }
29 3 : else if ((IPAddress::IPV6 == family) && (bufferSize >= IP6_MAX_STRING_LENGTH))
30 : {
31 1 : printfResult = ::std::snprintf(
32 : buffer.data(),
33 : bufferSize,
34 : "%x%x:%x%x:%x%x:%x%x:%x%x:%x%x:%x%x:%x%x",
35 1 : ipAddr.raw[0U],
36 1 : ipAddr.raw[1U],
37 1 : ipAddr.raw[2U],
38 1 : ipAddr.raw[3U],
39 1 : ipAddr.raw[4U],
40 1 : ipAddr.raw[5U],
41 1 : ipAddr.raw[6U],
42 1 : ipAddr.raw[7U],
43 1 : ipAddr.raw[8U],
44 1 : ipAddr.raw[9U],
45 1 : ipAddr.raw[10U],
46 1 : ipAddr.raw[11U],
47 1 : ipAddr.raw[12U],
48 1 : ipAddr.raw[13U],
49 1 : ipAddr.raw[14U],
50 1 : ipAddr.raw[15U]);
51 : }
52 : else
53 : {
54 2 : return {};
55 : }
56 :
57 : // The posix specification allows a possible negative code although for sprintf there's no
58 : // condition in which any error should be triggered. That's why it's not checked here.
59 2 : return ::etl::span<char>(buffer.data(), static_cast<size_t>(printfResult));
60 : }
61 :
62 4 : ::etl::span<char> to_str(IPEndpoint const& endp, ::etl::span<char> const& buffer)
63 : {
64 4 : IPAddress const& ipAddr = endp.getAddress();
65 4 : IPAddress::Family const family = addressFamilyOf(ipAddr);
66 4 : size_t const bufferSize = buffer.size();
67 :
68 4 : int printfResult = 0;
69 :
70 4 : if ((IPAddress::IPV4 == family) && (bufferSize >= IP4_ENDPOINT_MAX_STRING_LENGTH))
71 : {
72 1 : printfResult = ::std::snprintf(
73 : buffer.data(),
74 : bufferSize,
75 : "%d.%d.%d.%d:%d",
76 1 : ipAddr.raw[internal::RAW_IP4_IDX + 0U],
77 1 : ipAddr.raw[internal::RAW_IP4_IDX + 1U],
78 1 : ipAddr.raw[internal::RAW_IP4_IDX + 2U],
79 1 : ipAddr.raw[internal::RAW_IP4_IDX + 3U],
80 1 : endp.getPort());
81 : }
82 3 : else if ((IPAddress::IPV6 == family) && (bufferSize >= IP6_ENDPOINT_MAX_STRING_LENGTH))
83 : {
84 1 : printfResult = ::std::snprintf(
85 : buffer.data(),
86 : bufferSize,
87 : "[%x%x:%x%x:%x%x:%x%x:%x%x:%x%x:%x%x:%x%x]:%d",
88 1 : ipAddr.raw[0U],
89 1 : ipAddr.raw[1U],
90 1 : ipAddr.raw[2U],
91 1 : ipAddr.raw[3U],
92 1 : ipAddr.raw[4U],
93 1 : ipAddr.raw[5U],
94 1 : ipAddr.raw[6U],
95 1 : ipAddr.raw[7U],
96 1 : ipAddr.raw[8U],
97 1 : ipAddr.raw[9U],
98 1 : ipAddr.raw[10U],
99 1 : ipAddr.raw[11U],
100 1 : ipAddr.raw[12U],
101 1 : ipAddr.raw[13U],
102 1 : ipAddr.raw[14U],
103 1 : ipAddr.raw[15U],
104 1 : endp.getPort());
105 : }
106 : else
107 : {
108 2 : return {};
109 : }
110 :
111 : // The posix specification allows a possible negative code although for sprintf there's no
112 : // condition in which any error should be triggered. That's why it's not checked here.
113 2 : return ::etl::span<char>(buffer.data(), static_cast<size_t>(printfResult));
114 : }
115 :
116 : } /* namespace ip */
117 :
118 : // NOLINTEND(cppcoreguidelines-pro-type-vararg)
|