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