LCOV - code coverage report
Current view: top level - boost/url/ipv6_address.hpp (source / functions) Coverage Total Hit
Test: coverage_filtered.info Lines: 100.0 % 14 14
Test Date: 2025-04-22 15:26:24 Functions: 100.0 % 6 6

            Line data    Source code
       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_IPV6_ADDRESS_HPP
      12              : #define BOOST_URL_IPV6_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 <array>
      20              : #include <cstdint>
      21              : #include <iosfwd>
      22              : 
      23              : namespace boost {
      24              : namespace urls {
      25              : 
      26              : #ifndef BOOST_URL_DOCS
      27              : class ipv4_address;
      28              : #endif
      29              : 
      30              : /** An IP version 6 style address.
      31              : 
      32              :     Objects of this type are used to construct,
      33              :     parse, and manipulate IP version 6 addresses.
      34              : 
      35              :     @par BNF
      36              :     @code
      37              :     IPv6address =                            6( h16 ":" ) ls32
      38              :                 /                       "::" 5( h16 ":" ) ls32
      39              :                 / [               h16 ] "::" 4( h16 ":" ) ls32
      40              :                 / [ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32
      41              :                 / [ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32
      42              :                 / [ *3( h16 ":" ) h16 ] "::"    h16 ":"   ls32
      43              :                 / [ *4( h16 ":" ) h16 ] "::"              ls32
      44              :                 / [ *5( h16 ":" ) h16 ] "::"              h16
      45              :                 / [ *6( h16 ":" ) h16 ] "::"
      46              : 
      47              :     ls32        = ( h16 ":" h16 ) / IPv4address
      48              :                 ; least-significant 32 bits of address
      49              : 
      50              :     h16         = 1*4HEXDIG
      51              :                 ; 16 bits of address represented in hexadecimal
      52              :     @endcode
      53              : 
      54              :     @par Specification
      55              :     @li <a href="https://datatracker.ietf.org/doc/html/rfc4291"
      56              :         >IP Version 6 Addressing Architecture (rfc4291)</a>
      57              :     @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2"
      58              :         >3.2.2. Host (rfc3986)</a>
      59              : 
      60              :     @see
      61              :         @ref ipv4_address,
      62              :         @ref parse_ipv6_address.
      63              : */
      64              : class ipv6_address
      65              : {
      66              : public:
      67              :     /** The number of characters in the longest possible IPv6 string.
      68              : 
      69              :         The longest IPv6 address is:
      70              :         @code
      71              :         ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
      72              :         @endcode
      73              : 
      74              :         @see
      75              :             @ref to_buffer.
      76              :     */
      77              :     // ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
      78              :     // ::ffff:255.255.255.255
      79              :     // 12345678901234567890123456789012345678901234567890
      80              :     //          1         2         3        4
      81              :     static
      82              :     constexpr
      83              :     std::size_t max_str_len = 49;
      84              : 
      85              :     /** The type used to represent an address as an array of bytes.
      86              : 
      87              :         Octets are stored in network byte order.
      88              :     */
      89              :     using bytes_type = std::array<
      90              :         unsigned char, 16>;
      91              : 
      92              :     /** Constructor.
      93              : 
      94              :         Default constructed objects represent
      95              :         the unspecified address.
      96              : 
      97              :         @li <a href="https://datatracker.ietf.org/doc/html/rfc4291#section-2.5.2"
      98              :             >2.5.2. The Unspecified Address</a>
      99              : 
     100              :         @see
     101              :             @ref is_unspecified
     102              :     */
     103           96 :     ipv6_address() = default;
     104              : 
     105              :     /** Constructor.
     106              :     */
     107              :     ipv6_address(
     108              :         ipv6_address const&) = default;
     109              : 
     110              :     /** Copy Assignment
     111              : 
     112              :         @return `*this`
     113              :     */
     114              :     ipv6_address&
     115              :     operator=(
     116              :         ipv6_address const&) = default;
     117              : 
     118              :     /** Construct from an array of bytes.
     119              : 
     120              :         This function constructs an address
     121              :         from the array in `bytes`, which is
     122              :         interpreted in big-endian.
     123              : 
     124              :         @param bytes The value to construct from.
     125              :     */
     126              :     BOOST_URL_DECL
     127              :     ipv6_address(
     128              :         bytes_type const& bytes) noexcept;
     129              : 
     130              :     /** Construct from an IPv4 address.
     131              : 
     132              :         This function constructs an IPv6 address
     133              :         from the IPv4 address `addr`. The resulting
     134              :         address is an IPv4-Mapped IPv6 Address.
     135              : 
     136              :         @param addr The address to construct from.
     137              : 
     138              :         @par Specification
     139              :         @li <a href="https://datatracker.ietf.org/doc/html/rfc4291#section-2.5.5.2"
     140              :             >2.5.5.2. IPv4-Mapped IPv6 Address (rfc4291)</a>
     141              :     */
     142              :     BOOST_URL_DECL
     143              :     ipv6_address(
     144              :         ipv4_address const& addr) noexcept;
     145              : 
     146              :     /** Construct from a string.
     147              : 
     148              :         This function constructs an address from
     149              :         the string `s`, which must contain a valid
     150              :         IPv6 address string or else an exception
     151              :         is thrown.
     152              : 
     153              :         @note For a non-throwing parse function,
     154              :         use @ref parse_ipv6_address.
     155              : 
     156              :         @par Exception Safety
     157              :         Exceptions thrown on invalid input.
     158              : 
     159              :         @throw system_error
     160              :         The input failed to parse correctly.
     161              : 
     162              :         @param s The string to parse.
     163              : 
     164              :         @par Specification
     165              :         @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2"
     166              :             >3.2.2. Host (rfc3986)</a>
     167              : 
     168              :         @see
     169              :             @ref parse_ipv6_address.
     170              :     */
     171              :     BOOST_URL_DECL
     172              :     ipv6_address(
     173              :         core::string_view s);
     174              : 
     175              :     /** Return the address as bytes, in network byte order
     176              : 
     177              :         @return The address as an array of bytes.
     178              :     */
     179              :     bytes_type
     180          120 :     to_bytes() const noexcept
     181              :     {
     182          120 :         return addr_;
     183              :     }
     184              : 
     185              :     /** Return the address as a string.
     186              : 
     187              :         The returned string does not
     188              :         contain surrounding square brackets.
     189              : 
     190              :         When called with no arguments, the
     191              :         return type is `std::string`.
     192              :         Otherwise, the return type and style
     193              :         of output is determined by which string
     194              :         token is passed.
     195              : 
     196              :         @par Example
     197              :         @code
     198              :         ipv6_address::bytes_type b = {{
     199              :                 0, 1, 0, 2, 0, 3, 0, 4,
     200              :                 0, 5, 0, 6, 0, 7, 0, 8 }};
     201              :         ipv6_address a(b);
     202              :         assert(a.to_string() == "1:2:3:4:5:6:7:8");
     203              :         assert( ipv4_address(0x01020304).to_string() == "1.2.3.4" );
     204              :         @endcode
     205              : 
     206              :         @par Complexity
     207              :         Constant.
     208              : 
     209              :         @par Exception Safety
     210              :         Strong guarantee.
     211              :         Calls to allocate may throw.
     212              :         String tokens may throw exceptions.
     213              : 
     214              :         @return The return type of the string token.
     215              :         If the token parameter is omitted, then
     216              :         a new `std::string` is returned.
     217              :         Otherwise, the function return type
     218              :         is the result type of the token.
     219              : 
     220              :         @param token An optional string token.
     221              : 
     222              :         @par Specification
     223              :         @li <a href="https://datatracker.ietf.org/doc/html/rfc4291#section-2.2">
     224              :             2.2. Text Representation of Addresses (rfc4291)</a>
     225              :     */
     226              :     template<BOOST_URL_STRTOK_TPARAM>
     227              :     BOOST_URL_STRTOK_RETURN
     228           38 :     to_string(
     229              :         BOOST_URL_STRTOK_ARG(token)) const
     230              :     {
     231           38 :         to_string_impl(token);
     232           38 :         return token.result();
     233              :     }
     234              : 
     235              :     /** Write a dotted decimal string representing the address to a buffer
     236              : 
     237              :         The resulting buffer is not null-terminated.
     238              : 
     239              :         @throw std::length_error `dest_size < ipv6_address::max_str_len`
     240              : 
     241              :         @return The formatted string
     242              : 
     243              :         @param dest The buffer in which to write,
     244              :         which must have at least `dest_size` space.
     245              : 
     246              :         @param dest_size The size of the output buffer.
     247              :     */
     248              :     BOOST_URL_DECL
     249              :     core::string_view
     250              :     to_buffer(
     251              :         char* dest,
     252              :         std::size_t dest_size) const;
     253              : 
     254              :     /** Return true if the address is unspecified
     255              : 
     256              :         The address 0:0:0:0:0:0:0:0 is called the
     257              :         unspecified address. It indicates the
     258              :         absence of an address.
     259              : 
     260              :         @return `true` if the address is unspecified
     261              : 
     262              :         @par Specification
     263              :         @li <a href="https://datatracker.ietf.org/doc/html/rfc4291#section-2.5.2">
     264              :             2.5.2. The Unspecified Address (rfc4291)</a>
     265              :     */
     266              :     BOOST_URL_DECL
     267              :     bool
     268              :     is_unspecified() const noexcept;
     269              : 
     270              :     /** Return true if the address is a loopback address
     271              : 
     272              :         The unicast address 0:0:0:0:0:0:0:1 is called
     273              :         the loopback address. It may be used by a node
     274              :         to send an IPv6 packet to itself.
     275              : 
     276              :         @return `true` if the address is a loopback address
     277              : 
     278              :         @par Specification
     279              :         @li <a href="https://datatracker.ietf.org/doc/html/rfc4291#section-2.5.3">
     280              :             2.5.3. The Loopback Address (rfc4291)</a>
     281              :     */
     282              :     BOOST_URL_DECL
     283              :     bool
     284              :     is_loopback() const noexcept;
     285              : 
     286              :     /** Return true if the address is a mapped IPv4 address
     287              : 
     288              :         This address type is used to represent the
     289              :         addresses of IPv4 nodes as IPv6 addresses.
     290              : 
     291              :         @return `true` if the address is a mapped IPv4 address
     292              : 
     293              :         @par Specification
     294              :         @li <a href="https://datatracker.ietf.org/doc/html/rfc4291#section-2.5.5.2">
     295              :             2.5.5.2. IPv4-Mapped IPv6 Address (rfc4291)</a>
     296              :     */
     297              :     BOOST_URL_DECL
     298              :     bool
     299              :     is_v4_mapped() const noexcept;
     300              : 
     301              :     /** Return true if two addresses are equal
     302              : 
     303              :         @param a1 The first address to compare.
     304              :         @param a2 The second address to compare.
     305              :         @return `true` if the addresses are equal
     306              :     */
     307              :     friend
     308              :     bool
     309           81 :     operator==(
     310              :         ipv6_address const& a1,
     311              :         ipv6_address const& a2) noexcept
     312              :     {
     313           81 :         return a1.addr_ == a2.addr_;
     314              :     }
     315              : 
     316              :     /** Return true if two addresses are not equal
     317              : 
     318              :         @param a1 The first address to compare.
     319              :         @param a2 The second address to compare.
     320              :         @return `true` if the addresses are not equal
     321              :     */
     322              :     friend
     323              :     bool
     324            4 :     operator!=(
     325              :         ipv6_address const& a1,
     326              :         ipv6_address const& a2) noexcept
     327              :     {
     328            4 :         return !( a1 == a2 );
     329              :     }
     330              : 
     331              :     /** Return an address object that represents the loopback address
     332              : 
     333              :         The unicast address 0:0:0:0:0:0:0:1 is called
     334              :         the loopback address. It may be used by a node
     335              :         to send an IPv6 packet to itself.
     336              : 
     337              :         @par Specification
     338              :         @li <a href="https://datatracker.ietf.org/doc/html/rfc4291#section-2.5.3">
     339              :             2.5.3. The Loopback Address (rfc4291)</a>
     340              : 
     341              :         @return The loopback address.
     342              :     */
     343              :     BOOST_URL_DECL
     344              :     static
     345              :     ipv6_address
     346              :     loopback() noexcept;
     347              : 
     348              :     /** Format the address to an output stream
     349              : 
     350              :         This hidden friend function writes the
     351              :         address to an output stream using
     352              :         standard notation.
     353              : 
     354              :         @return The output stream, for chaining.
     355              : 
     356              :         @param os The output stream to write to.
     357              : 
     358              :         @param addr The address to write.
     359              :     */
     360              :     friend
     361              :     std::ostream&
     362            1 :     operator<<(
     363              :         std::ostream& os,
     364              :         ipv6_address const& addr)
     365              :     {
     366              :         char buf[ipv6_address::max_str_len];
     367            1 :         auto const s = addr.to_buffer(
     368              :             buf, sizeof(buf));
     369            1 :         os << s;
     370            1 :         return os;
     371              :     }
     372              : 
     373              : 
     374              : private:
     375              :     BOOST_URL_DECL
     376              :     std::size_t
     377              :     print_impl(
     378              :         char* dest) const noexcept;
     379              : 
     380              :     BOOST_URL_DECL
     381              :     void
     382              :     to_string_impl(
     383              :         string_token::arg& t) const;
     384              : 
     385              :     bytes_type addr_{{}};
     386              : };
     387              : 
     388              : /** Format the address to an output stream
     389              : 
     390              :     This function writes the address to an
     391              :     output stream using standard notation.
     392              : 
     393              :     @return The output stream, for chaining.
     394              : 
     395              :     @param os The output stream to write to.
     396              : 
     397              :     @param addr The address to write.
     398              : */
     399              : std::ostream&
     400              : operator<<(
     401              :     std::ostream& os,
     402              :     ipv6_address const& addr);
     403              : 
     404              : //------------------------------------------------
     405              : 
     406              : /** Parse a string containing an IPv6 address.
     407              : 
     408              :     This function attempts to parse the string
     409              :     as an IPv6 address and returns a result
     410              :     containing the address upon success, or
     411              :     an error code if the string does not contain
     412              :     a valid IPv6 address.
     413              : 
     414              :     @par Exception Safety
     415              :     Throws nothing.
     416              : 
     417              :     @return A result containing the address.
     418              : 
     419              :     @param s The string to parse.
     420              : */
     421              : BOOST_URL_DECL
     422              : system::result<ipv6_address>
     423              : parse_ipv6_address(
     424              :     core::string_view s) noexcept;
     425              : 
     426              : } // urls
     427              : } // boost
     428              : 
     429              : #endif
        

Generated by: LCOV version 2.1