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