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