LCOV - code coverage report
Current view: top level - url - ipv6_address.hpp (source / functions) Coverage Total Hit
Test: coverage_remapped.info Lines: 100.0 % 16 16
Test Date: 2026-02-25 21:00:01 Functions: 100.0 % 7 7

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

Generated by: LCOV version 2.3