LCOV - code coverage report
Current view: top level - boost/url - ipv6_address.hpp (source / functions) Hit Total Coverage
Test: coverage_filtered.info Lines: 14 14 100.0 %
Date: 2024-01-19 15:42:53 Functions: 6 6 100.0 %

          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             :     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_DECL
     125             :     ipv6_address(
     126             :         bytes_type const& bytes) noexcept;
     127             : 
     128             :     /** Construct from an IPv4 address.
     129             : 
     130             :         This function constructs an IPv6 address
     131             :         from the IPv4 address `addr`. The resulting
     132             :         address is an IPv4-Mapped IPv6 Address.
     133             : 
     134             :         @param addr The address to construct from.
     135             : 
     136             :         @par Specification
     137             :         @li <a href="https://datatracker.ietf.org/doc/html/rfc4291#section-2.5.5.2"
     138             :             >2.5.5.2. IPv4-Mapped IPv6 Address (rfc4291)</a>
     139             :     */
     140             :     BOOST_URL_DECL
     141             :     ipv6_address(
     142             :         ipv4_address const& addr) noexcept;
     143             : 
     144             :     /** Construct from a string.
     145             : 
     146             :         This function constructs an address from
     147             :         the string `s`, which must contain a valid
     148             :         IPv6 address string or else an exception
     149             :         is thrown.
     150             : 
     151             :         @note For a non-throwing parse function,
     152             :         use @ref parse_ipv6_address.
     153             : 
     154             :         @par Exception Safety
     155             :         Exceptions thrown on invalid input.
     156             : 
     157             :         @throw system_error
     158             :         The input failed to parse correctly.
     159             : 
     160             :         @param s The string to parse.
     161             : 
     162             :         @par Specification
     163             :         @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2"
     164             :             >3.2.2. Host (rfc3986)</a>
     165             : 
     166             :         @see
     167             :             @ref parse_ipv6_address.
     168             :     */
     169             :     BOOST_URL_DECL
     170             :     ipv6_address(
     171             :         core::string_view s);
     172             : 
     173             :     /** Return the address as bytes, in network byte order
     174             :     */
     175             :     bytes_type
     176         120 :     to_bytes() const noexcept
     177             :     {
     178         120 :         return addr_;
     179             :     }
     180             : 
     181             :     /** Return the address as a string.
     182             : 
     183             :         The returned string does not
     184             :         contain surrounding square brackets.
     185             : 
     186             :         When called with no arguments, the
     187             :         return type is `std::string`.
     188             :         Otherwise, the return type and style
     189             :         of output is determined by which string
     190             :         token is passed.
     191             : 
     192             :         @par Example
     193             :         @code
     194             :         ipv6_address::bytes_type b = {{
     195             :                 0, 1, 0, 2, 0, 3, 0, 4,
     196             :                 0, 5, 0, 6, 0, 7, 0, 8 }};
     197             :         ipv6_address a(b);
     198             :         assert(a.to_string() == "1:2:3:4:5:6:7:8");
     199             :         assert( ipv4_address(0x01020304).to_string() == "1.2.3.4" );
     200             :         @endcode
     201             : 
     202             :         @par Complexity
     203             :         Constant.
     204             : 
     205             :         @par Exception Safety
     206             :         Strong guarantee.
     207             :         Calls to allocate may throw.
     208             :         String tokens may throw exceptions.
     209             : 
     210             :         @return The return type of the string token.
     211             :         If the token parameter is omitted, then
     212             :         a new `std::string` is returned.
     213             :         Otherwise, the function return type
     214             :         is the result type of the token.
     215             : 
     216             :         @param token An optional string token.
     217             : 
     218             :         @par Specification
     219             :         @li <a href="https://datatracker.ietf.org/doc/html/rfc4291#section-2.2">
     220             :             2.2. Text Representation of Addresses (rfc4291)</a>
     221             :     */
     222             :     template<BOOST_URL_STRTOK_TPARAM>
     223             :     BOOST_URL_STRTOK_RETURN
     224          38 :     to_string(
     225             :         BOOST_URL_STRTOK_ARG(token)) const
     226             :     {
     227          38 :         to_string_impl(token);
     228          38 :         return token.result();
     229             :     }
     230             : 
     231             :     /** Write a dotted decimal string representing the address to a buffer
     232             : 
     233             :         The resulting buffer is not null-terminated.
     234             : 
     235             :         @throw std::length_error `dest_size < ipv6_address::max_str_len`
     236             : 
     237             :         @return The formatted string
     238             : 
     239             :         @param dest The buffer in which to write,
     240             :         which must have at least `dest_size` space.
     241             : 
     242             :         @param dest_size The size of the output buffer.
     243             :     */
     244             :     BOOST_URL_DECL
     245             :     core::string_view
     246             :     to_buffer(
     247             :         char* dest,
     248             :         std::size_t dest_size) const;
     249             : 
     250             :     /** Return true if the address is unspecified
     251             : 
     252             :         The address 0:0:0:0:0:0:0:0 is called the
     253             :         unspecified address. It indicates the
     254             :         absence of an address.
     255             : 
     256             :         @par Specification
     257             :         @li <a href="https://datatracker.ietf.org/doc/html/rfc4291#section-2.5.2">
     258             :             2.5.2. The Unspecified Address (rfc4291)</a>
     259             :     */
     260             :     BOOST_URL_DECL
     261             :     bool
     262             :     is_unspecified() const noexcept;
     263             : 
     264             :     /** Return true if the address is a loopback address
     265             : 
     266             :         The unicast address 0:0:0:0:0:0:0:1 is called
     267             :         the loopback address. It may be used by a node
     268             :         to send an IPv6 packet to itself.
     269             : 
     270             :         @par Specification
     271             :         @li <a href="https://datatracker.ietf.org/doc/html/rfc4291#section-2.5.3">
     272             :             2.5.3. The Loopback Address (rfc4291)</a>
     273             :     */
     274             :     BOOST_URL_DECL
     275             :     bool
     276             :     is_loopback() const noexcept;
     277             : 
     278             :     /** Return true if the address is a mapped IPv4 address
     279             : 
     280             :         This address type is used to represent the
     281             :         addresses of IPv4 nodes as IPv6 addresses.
     282             : 
     283             :         @par Specification
     284             :         @li <a href="https://datatracker.ietf.org/doc/html/rfc4291#section-2.5.5.2">
     285             :             2.5.5.2. IPv4-Mapped IPv6 Address (rfc4291)</a>
     286             :     */
     287             :     BOOST_URL_DECL
     288             :     bool
     289             :     is_v4_mapped() const noexcept;
     290             : 
     291             :     /** Return true if two addresses are equal
     292             :     */
     293             :     friend
     294             :     bool
     295          81 :     operator==(
     296             :         ipv6_address const& a1,
     297             :         ipv6_address const& a2) noexcept
     298             :     {
     299          81 :         return a1.addr_ == a2.addr_;
     300             :     }
     301             : 
     302             :     /** Return true if two addresses are not equal
     303             :     */
     304             :     friend
     305             :     bool
     306           4 :     operator!=(
     307             :         ipv6_address const& a1,
     308             :         ipv6_address const& a2) noexcept
     309             :     {
     310           4 :         return !( a1 == a2 );
     311             :     }
     312             : 
     313             :     /** Return an address object that represents the loopback address
     314             : 
     315             :         The unicast address 0:0:0:0:0:0:0:1 is called
     316             :         the loopback address. It may be used by a node
     317             :         to send an IPv6 packet to itself.
     318             : 
     319             :         @par Specification
     320             :         @li <a href="https://datatracker.ietf.org/doc/html/rfc4291#section-2.5.3">
     321             :             2.5.3. The Loopback Address (rfc4291)</a>
     322             :     */
     323             :     BOOST_URL_DECL
     324             :     static
     325             :     ipv6_address
     326             :     loopback() noexcept;
     327             : 
     328             :     // hidden friend
     329             :     friend
     330             :     std::ostream&
     331           1 :     operator<<(
     332             :         std::ostream& os,
     333             :         ipv6_address const& addr)
     334             :     {
     335             :         char buf[ipv6_address::max_str_len];
     336             :         auto const s = addr.to_buffer(
     337           1 :             buf, sizeof(buf));
     338           1 :         os << s;
     339           1 :         return os;
     340             :     }
     341             : 
     342             : 
     343             : private:
     344             :     BOOST_URL_DECL
     345             :     std::size_t
     346             :     print_impl(
     347             :         char* dest) const noexcept;
     348             : 
     349             :     BOOST_URL_DECL
     350             :     void
     351             :     to_string_impl(
     352             :         string_token::arg& t) const;
     353             : 
     354             :     bytes_type addr_{{}};
     355             : };
     356             : 
     357             : /** Format the address to an output stream
     358             : 
     359             :     This function writes the address to an
     360             :     output stream using standard notation.
     361             : 
     362             :     @return The output stream, for chaining.
     363             : 
     364             :     @param os The output stream to write to.
     365             : 
     366             :     @param addr The address to write.
     367             : */
     368             : std::ostream&
     369             : operator<<(
     370             :     std::ostream& os,
     371             :     ipv6_address const& addr);
     372             : 
     373             : //------------------------------------------------
     374             : 
     375             : /** Parse a string containing an IPv6 address.
     376             : 
     377             :     This function attempts to parse the string
     378             :     as an IPv6 address and returns a result
     379             :     containing the address upon success, or
     380             :     an error code if the string does not contain
     381             :     a valid IPv6 address.
     382             : 
     383             :     @par Exception Safety
     384             :     Throws nothing.
     385             : 
     386             :     @return A result containing the address.
     387             : 
     388             :     @param s The string to parse.
     389             : */
     390             : BOOST_URL_DECL
     391             : system::result<ipv6_address>
     392             : parse_ipv6_address(
     393             :     core::string_view s) noexcept;
     394             : 
     395             : } // urls
     396             : } // boost
     397             : 
     398             : #endif

Generated by: LCOV version 1.15