GCC Code Coverage Report


Directory: libs/url/
File: boost/url/ipv4_address.hpp
Date: 2024-04-08 19:38:36
Exec Total Coverage
Lines: 17 17 100.0%
Functions: 8 8 100.0%
Branches: 2 4 50.0%

Line Branch Exec Source
1 //
2 // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
3 // Copyright (c) 2022 Alan de Freitas (alandefreitas@gmail.com)
4 //
5 // Distributed under the Boost Software License, Version 1.0. (See accompanying
6 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 //
8 // Official repository: https://github.com/boostorg/url
9 //
10
11 #ifndef BOOST_URL_IPV4_ADDRESS_HPP
12 #define BOOST_URL_IPV4_ADDRESS_HPP
13
14 #include <boost/url/detail/config.hpp>
15 #include <boost/url/error.hpp>
16 #include <boost/url/error_types.hpp>
17 #include <boost/core/detail/string_view.hpp>
18 #include <boost/url/grammar/string_token.hpp>
19 #include <string>
20 #include <array>
21 #include <cstdint>
22 #include <iosfwd>
23
24 namespace boost {
25 namespace urls {
26
27 /** An IP version 4 style address.
28
29 Objects of this type are used to construct,
30 parse, and manipulate IP version 6 addresses.
31
32 @par BNF
33 @code
34 IPv4address = dec-octet "." dec-octet "." dec-octet "." dec-octet
35
36 dec-octet = DIGIT ; 0-9
37 / %x31-39 DIGIT ; 10-99
38 / "1" 2DIGIT ; 100-199
39 / "2" %x30-34 DIGIT ; 200-249
40 / "25" %x30-35 ; 250-255
41 @endcode
42
43 @par Specification
44 @li <a href="https://en.wikipedia.org/wiki/IPv4"
45 >IPv4 (Wikipedia)</a>
46 @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2"
47 >3.2.2. Host (rfc3986)</a>
48
49 @see
50 @ref parse_ipv4_address,
51 @ref ipv6_address.
52 */
53 class ipv4_address
54 {
55 public:
56 /** The number of characters in the longest possible IPv4 string.
57
58 The longest ipv4 address string is "255.255.255.255".
59 */
60 static
61 constexpr
62 std::size_t max_str_len = 15;
63
64 /** The type used to represent an address as an unsigned integer
65 */
66 using uint_type =
67 std::uint_least32_t;
68
69 /** The type used to represent an address as an array of bytes
70 */
71 using bytes_type =
72 std::array<unsigned char, 4>;
73
74 /** Constructor.
75 */
76 77 ipv4_address() = default;
77
78 /** Constructor.
79 */
80 ipv4_address(
81 ipv4_address const&) = default;
82
83 /** Copy Assignment.
84 */
85 ipv4_address&
86 operator=(
87 ipv4_address const&) = default;
88
89 //
90 //---
91 //
92
93 /** Construct from an unsigned integer.
94
95 This function constructs an address from
96 the unsigned integer `u`, where the most
97 significant byte forms the first octet
98 of the resulting address.
99
100 @param u The integer to construct from.
101 */
102 BOOST_URL_DECL
103 explicit
104 ipv4_address(
105 uint_type u) noexcept;
106
107 /** Construct from an array of bytes.
108
109 This function constructs an address
110 from the array in `bytes`, which is
111 interpreted in big-endian.
112
113 @param bytes The value to construct from.
114 */
115 BOOST_URL_DECL
116 explicit
117 ipv4_address(
118 bytes_type const& bytes) noexcept;
119
120 /** Construct from a string.
121
122 This function constructs an address from
123 the string `s`, which must contain a valid
124 IPv4 address string or else an exception
125 is thrown.
126
127 @note For a non-throwing parse function,
128 use @ref parse_ipv4_address.
129
130 @par Exception Safety
131 Exceptions thrown on invalid input.
132
133 @throw system_error
134 The input failed to parse correctly.
135
136 @param s The string to parse.
137
138 @par Specification
139 @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2"
140 >3.2.2. Host (rfc3986)</a>
141
142 @see
143 @ref parse_ipv4_address.
144 */
145 BOOST_URL_DECL
146 explicit
147 ipv4_address(
148 core::string_view s);
149
150 /** Return the address as bytes, in network byte order.
151 */
152 BOOST_URL_DECL
153 bytes_type
154 to_bytes() const noexcept;
155
156 /** Return the address as an unsigned integer.
157 */
158 BOOST_URL_DECL
159 uint_type
160 to_uint() const noexcept;
161
162 /** Return the address as a string in dotted decimal format
163
164 When called with no arguments, the
165 return type is `std::string`.
166 Otherwise, the return type and style
167 of output is determined by which string
168 token is passed.
169
170 @par Example
171 @code
172 assert( ipv4_address(0x01020304).to_string() == "1.2.3.4" );
173 @endcode
174
175 @par Complexity
176 Constant.
177
178 @par Exception Safety
179 Strong guarantee.
180 Calls to allocate may throw.
181 String tokens may throw exceptions.
182
183 @return The return type of the string token.
184 If the token parameter is omitted, then
185 a new `std::string` is returned.
186 Otherwise, the function return type
187 is the result type of the token.
188
189 @param token An optional string token.
190
191 @par Specification
192 @li <a href="https://datatracker.ietf.org/doc/html/rfc4291#section-2.2">
193 2.2. Text Representation of Addresses (rfc4291)</a>
194 */
195 template<BOOST_URL_STRTOK_TPARAM>
196 BOOST_URL_STRTOK_RETURN
197 2 to_string(
198 BOOST_URL_STRTOK_ARG(token)) const
199 {
200 2 to_string_impl(token);
201 2 return token.result();
202 }
203
204 /** Write a dotted decimal string representing the address to a buffer
205
206 The resulting buffer is not null-terminated.
207
208 @throw std::length_error `dest_size < ipv4_address::max_str_len`
209
210 @return The formatted string
211
212 @param dest The buffer in which to write,
213 which must have at least `dest_size` space.
214
215 @param dest_size The size of the output buffer.
216 */
217 BOOST_URL_DECL
218 core::string_view
219 to_buffer(
220 char* dest,
221 std::size_t dest_size) const;
222
223 /** Return true if the address is a loopback address
224 */
225 BOOST_URL_DECL
226 bool
227 is_loopback() const noexcept;
228
229 /** Return true if the address is unspecified
230 */
231 BOOST_URL_DECL
232 bool
233 is_unspecified() const noexcept;
234
235 /** Return true if the address is a multicast address
236 */
237 BOOST_URL_DECL
238 bool
239 is_multicast() const noexcept;
240
241 /** Return true if two addresses are equal
242 */
243 friend
244 bool
245 57 operator==(
246 ipv4_address const& a1,
247 ipv4_address const& a2) noexcept
248 {
249 57 return a1.addr_ == a2.addr_;
250 }
251
252 /** Return true if two addresses are not equal
253 */
254 friend
255 bool
256 3 operator!=(
257 ipv4_address const& a1,
258 ipv4_address const& a2) noexcept
259 {
260 3 return a1.addr_ != a2.addr_;
261 }
262
263 /** Return an address object that represents any address
264 */
265 static
266 ipv4_address
267 3 any() noexcept
268 {
269 3 return ipv4_address();
270 }
271
272 /** Return an address object that represents the loopback address
273 */
274 static
275 ipv4_address
276 3 loopback() noexcept
277 {
278 3 return ipv4_address(0x7F000001);
279 }
280
281 /** Return an address object that represents the broadcast address
282 */
283 static
284 ipv4_address
285 3 broadcast() noexcept
286 {
287 3 return ipv4_address(0xFFFFFFFF);
288 }
289
290 // hidden friend
291 friend
292 std::ostream&
293 1 operator<<(
294 std::ostream& os,
295 ipv4_address const& addr)
296 {
297 char buf[ipv4_address::max_str_len];
298
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 os << addr.to_buffer(buf, sizeof(buf));
299 1 return os;
300 }
301
302 private:
303 friend class ipv6_address;
304
305 BOOST_URL_DECL
306 std::size_t
307 print_impl(
308 char* dest) const noexcept;
309
310 BOOST_URL_DECL
311 void
312 to_string_impl(
313 string_token::arg& t) const;
314
315 uint_type addr_ = 0;
316 };
317
318 /** Format the address to an output stream.
319
320 IPv4 addresses written to output streams
321 are written in their dotted decimal format.
322
323 @param os The output stream.
324
325 @param addr The address to format.
326 */
327 std::ostream&
328 operator<<(
329 std::ostream& os,
330 ipv4_address const& addr);
331
332 //------------------------------------------------
333
334 /** Return an IPv4 address from an IP address string in dotted decimal form
335 */
336 BOOST_URL_DECL
337 system::result<ipv4_address>
338 parse_ipv4_address(
339 core::string_view s) noexcept;
340
341 } // urls
342 } // boost
343
344 #endif
345