Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-10-22 08:34:47

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