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