Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-02 09:03:38

0001 //
0002 // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
0003 // Copyright (c) 2022 Alan de Freitas (alandefreitas@gmail.com)
0004 //
0005 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0006 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0007 //
0008 // Official repository: https://github.com/boostorg/url
0009 //
0010 
0011 #ifndef BOOST_URL_IPV6_ADDRESS_HPP
0012 #define BOOST_URL_IPV6_ADDRESS_HPP
0013 
0014 #include <boost/url/detail/config.hpp>
0015 #include <boost/url/error.hpp>
0016 #include <boost/url/error_types.hpp>
0017 #include <boost/core/detail/string_view.hpp>
0018 #include <boost/url/grammar/string_token.hpp>
0019 #include <array>
0020 #include <cstdint>
0021 #include <iosfwd>
0022 
0023 namespace boost {
0024 namespace urls {
0025 
0026 class ipv4_address;
0027 
0028 /** An IP version 6 style address.
0029 
0030     Objects of this type are used to construct,
0031     parse, and manipulate IP version 6 addresses.
0032 
0033     @par BNF
0034     @code
0035     IPv6address =                            6( h16 ":" ) ls32
0036                 /                       "::" 5( h16 ":" ) ls32
0037                 / [               h16 ] "::" 4( h16 ":" ) ls32
0038                 / [ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32
0039                 / [ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32
0040                 / [ *3( h16 ":" ) h16 ] "::"    h16 ":"   ls32
0041                 / [ *4( h16 ":" ) h16 ] "::"              ls32
0042                 / [ *5( h16 ":" ) h16 ] "::"              h16
0043                 / [ *6( h16 ":" ) h16 ] "::"
0044 
0045     ls32        = ( h16 ":" h16 ) / IPv4address
0046                 ; least-significant 32 bits of address
0047 
0048     h16         = 1*4HEXDIG
0049                 ; 16 bits of address represented in hexadecimal
0050     @endcode
0051 
0052     @par Specification
0053     @li <a href="https://datatracker.ietf.org/doc/html/rfc4291"
0054         >IP Version 6 Addressing Architecture (rfc4291)</a>
0055     @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2"
0056         >3.2.2. Host (rfc3986)</a>
0057 
0058     @see
0059         @ref ipv4_address,
0060         @ref parse_ipv6_address.
0061 */
0062 class ipv6_address
0063 {
0064 public:
0065     /** The number of characters in the longest possible IPv6 string.
0066 
0067         The longest IPv6 address is:
0068         @code
0069         ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
0070         @endcode
0071 
0072         @see
0073             @ref to_buffer.
0074     */
0075     // ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
0076     // ::ffff:255.255.255.255
0077     // 12345678901234567890123456789012345678901234567890
0078     //          1         2         3        4
0079     static
0080     constexpr
0081     std::size_t max_str_len = 49;
0082 
0083     /** The type used to represent an address as an array of bytes.
0084 
0085         Octets are stored in network byte order.
0086     */
0087     using bytes_type = std::array<
0088         unsigned char, 16>;
0089 
0090     /** Constructor.
0091 
0092         Default constructed objects represent
0093         the unspecified address.
0094 
0095         @li <a href="https://datatracker.ietf.org/doc/html/rfc4291#section-2.5.2"
0096             >2.5.2. The Unspecified Address</a>
0097 
0098         @see
0099             @ref is_unspecified
0100     */
0101     ipv6_address() = default;
0102 
0103     /** Constructor.
0104     */
0105     ipv6_address(
0106         ipv6_address const&) = default;
0107 
0108     /** Copy Assignment
0109 
0110         @return `*this`
0111     */
0112     ipv6_address&
0113     operator=(
0114         ipv6_address const&) = default;
0115 
0116     /** Construct from an array of bytes.
0117 
0118         This function constructs an address
0119         from the array in `bytes`, which is
0120         interpreted in big-endian.
0121 
0122         @param bytes The value to construct from.
0123     */
0124     BOOST_URL_DECL
0125     ipv6_address(
0126         bytes_type const& bytes) noexcept;
0127 
0128     /** Construct from an IPv4 address.
0129 
0130         This function constructs an IPv6 address
0131         from the IPv4 address `addr`. The resulting
0132         address is an IPv4-Mapped IPv6 Address.
0133 
0134         @param addr The address to construct from.
0135 
0136         @par Specification
0137         @li <a href="https://datatracker.ietf.org/doc/html/rfc4291#section-2.5.5.2"
0138             >2.5.5.2. IPv4-Mapped IPv6 Address (rfc4291)</a>
0139     */
0140     BOOST_URL_DECL
0141     ipv6_address(
0142         ipv4_address const& addr) noexcept;
0143 
0144     /** Construct from a string.
0145 
0146         This function constructs an address from
0147         the string `s`, which must contain a valid
0148         IPv6 address string or else an exception
0149         is thrown.
0150 
0151         @note For a non-throwing parse function,
0152         use @ref parse_ipv6_address.
0153 
0154         @par Exception Safety
0155         Exceptions thrown on invalid input.
0156 
0157         @throw system_error
0158         The input failed to parse correctly.
0159 
0160         @param s The string to parse.
0161 
0162         @par Specification
0163         @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2"
0164             >3.2.2. Host (rfc3986)</a>
0165 
0166         @see
0167             @ref parse_ipv6_address.
0168     */
0169     BOOST_URL_DECL
0170     ipv6_address(
0171         core::string_view s);
0172 
0173     /** Return the address as bytes, in network byte order
0174 
0175         @return The address as an array of bytes.
0176     */
0177     bytes_type
0178     to_bytes() const noexcept
0179     {
0180         return addr_;
0181     }
0182 
0183     /** Return the address as a string.
0184 
0185         The returned string does not
0186         contain surrounding square brackets.
0187 
0188         When called with no arguments, the
0189         return type is `std::string`.
0190         Otherwise, the return type and style
0191         of output is determined by which string
0192         token is passed.
0193 
0194         @par Example
0195         @code
0196         ipv6_address::bytes_type b = {{
0197                 0, 1, 0, 2, 0, 3, 0, 4,
0198                 0, 5, 0, 6, 0, 7, 0, 8 }};
0199         ipv6_address a(b);
0200         assert(a.to_string() == "1:2:3:4:5:6:7:8");
0201         assert( ipv4_address(0x01020304).to_string() == "1.2.3.4" );
0202         @endcode
0203 
0204         @par Complexity
0205         Constant.
0206 
0207         @par Exception Safety
0208         Strong guarantee.
0209         Calls to allocate may throw.
0210         String tokens may throw exceptions.
0211 
0212         @return The return type of the string token.
0213         If the token parameter is omitted, then
0214         a new `std::string` is returned.
0215         Otherwise, the function return type
0216         is the result type of the token.
0217 
0218         @param token An optional string token.
0219 
0220         @par Specification
0221         @li <a href="https://datatracker.ietf.org/doc/html/rfc4291#section-2.2">
0222             2.2. Text Representation of Addresses (rfc4291)</a>
0223     */
0224     template<BOOST_URL_STRTOK_TPARAM>
0225     BOOST_URL_STRTOK_RETURN
0226     to_string(
0227         BOOST_URL_STRTOK_ARG(token)) const
0228     {
0229         to_string_impl(token);
0230         return token.result();
0231     }
0232 
0233     /** Write a dotted decimal string representing the address to a buffer
0234 
0235         The resulting buffer is not null-terminated.
0236 
0237         @throw std::length_error `dest_size < ipv6_address::max_str_len`
0238 
0239         @return The formatted string
0240 
0241         @param dest The buffer in which to write,
0242         which must have at least `dest_size` space.
0243 
0244         @param dest_size The size of the output buffer.
0245     */
0246     BOOST_URL_DECL
0247     core::string_view
0248     to_buffer(
0249         char* dest,
0250         std::size_t dest_size) const;
0251 
0252     /** Return true if the address is unspecified
0253 
0254         The address 0:0:0:0:0:0:0:0 is called the
0255         unspecified address. It indicates the
0256         absence of an address.
0257 
0258         @return `true` if the address is unspecified
0259 
0260         @par Specification
0261         @li <a href="https://datatracker.ietf.org/doc/html/rfc4291#section-2.5.2">
0262             2.5.2. The Unspecified Address (rfc4291)</a>
0263     */
0264     BOOST_URL_DECL
0265     bool
0266     is_unspecified() const noexcept;
0267 
0268     /** Return true if the address is a loopback address
0269 
0270         The unicast address 0:0:0:0:0:0:0:1 is called
0271         the loopback address. It may be used by a node
0272         to send an IPv6 packet to itself.
0273 
0274         @return `true` if the address is a loopback address
0275 
0276         @par Specification
0277         @li <a href="https://datatracker.ietf.org/doc/html/rfc4291#section-2.5.3">
0278             2.5.3. The Loopback Address (rfc4291)</a>
0279     */
0280     BOOST_URL_DECL
0281     bool
0282     is_loopback() const noexcept;
0283 
0284     /** Return true if the address is a mapped IPv4 address
0285 
0286         This address type is used to represent the
0287         addresses of IPv4 nodes as IPv6 addresses.
0288 
0289         @return `true` if the address is a mapped IPv4 address
0290 
0291         @par Specification
0292         @li <a href="https://datatracker.ietf.org/doc/html/rfc4291#section-2.5.5.2">
0293             2.5.5.2. IPv4-Mapped IPv6 Address (rfc4291)</a>
0294     */
0295     BOOST_URL_DECL
0296     bool
0297     is_v4_mapped() const noexcept;
0298 
0299     /** Return true if two addresses are equal
0300 
0301         @param a1 The first address to compare.
0302         @param a2 The second address to compare.
0303         @return `true` if the addresses are equal
0304     */
0305     friend
0306     bool
0307     operator==(
0308         ipv6_address const& a1,
0309         ipv6_address const& a2) noexcept
0310     {
0311         return a1.addr_ == a2.addr_;
0312     }
0313 
0314     /** Return true if two addresses are not equal
0315 
0316         @param a1 The first address to compare.
0317         @param a2 The second address to compare.
0318         @return `true` if the addresses are not equal
0319     */
0320     friend
0321     bool
0322     operator!=(
0323         ipv6_address const& a1,
0324         ipv6_address const& a2) noexcept
0325     {
0326         return !( a1 == a2 );
0327     }
0328 
0329     /** Return an address object that represents the loopback address
0330 
0331         The unicast address 0:0:0:0:0:0:0:1 is called
0332         the loopback address. It may be used by a node
0333         to send an IPv6 packet to itself.
0334 
0335         @par Specification
0336         @li <a href="https://datatracker.ietf.org/doc/html/rfc4291#section-2.5.3">
0337             2.5.3. The Loopback Address (rfc4291)</a>
0338 
0339         @return The loopback address.
0340     */
0341     BOOST_URL_DECL
0342     static
0343     ipv6_address
0344     loopback() noexcept;
0345 
0346     /** Format the address to an output stream
0347 
0348         This function writes the address to an
0349         output stream using standard notation.
0350 
0351         @return The output stream, for chaining.
0352 
0353         @param os The output stream to write to.
0354 
0355         @param addr The address to write.
0356     */
0357     friend
0358     std::ostream&
0359     operator<<(
0360         std::ostream& os,
0361         ipv6_address const& addr)
0362     {
0363         addr.write_ostream(os);
0364         return os;
0365     }
0366 
0367 private:
0368     BOOST_URL_DECL void write_ostream(std::ostream&) const;
0369 
0370     BOOST_URL_DECL
0371     std::size_t
0372     print_impl(
0373         char* dest) const noexcept;
0374 
0375     BOOST_URL_DECL
0376     void
0377     to_string_impl(
0378         string_token::arg& t) const;
0379 
0380     bytes_type addr_{{}};
0381 };
0382 
0383 //------------------------------------------------
0384 
0385 /** Parse a string containing an IPv6 address.
0386 
0387     This function attempts to parse the string
0388     as an IPv6 address and returns a result
0389     containing the address upon success, or
0390     an error code if the string does not contain
0391     a valid IPv6 address.
0392 
0393     @par Exception Safety
0394     Throws nothing.
0395 
0396     @return A result containing the address.
0397 
0398     @param s The string to parse.
0399 */
0400 BOOST_URL_DECL
0401 system::result<ipv6_address>
0402 parse_ipv6_address(
0403     core::string_view s) noexcept;
0404 
0405 } // urls
0406 } // boost
0407 
0408 #endif