Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:53:29

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     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     bytes_type
0176     to_bytes() const noexcept
0177     {
0178         return addr_;
0179     }
0180 
0181     /** Return the address as a string.
0182 
0183         The returned string does not
0184         contain surrounding square brackets.
0185 
0186         When called with no arguments, the
0187         return type is `std::string`.
0188         Otherwise, the return type and style
0189         of output is determined by which string
0190         token is passed.
0191 
0192         @par Example
0193         @code
0194         ipv6_address::bytes_type b = {{
0195                 0, 1, 0, 2, 0, 3, 0, 4,
0196                 0, 5, 0, 6, 0, 7, 0, 8 }};
0197         ipv6_address a(b);
0198         assert(a.to_string() == "1:2:3:4:5:6:7:8");
0199         assert( ipv4_address(0x01020304).to_string() == "1.2.3.4" );
0200         @endcode
0201 
0202         @par Complexity
0203         Constant.
0204 
0205         @par Exception Safety
0206         Strong guarantee.
0207         Calls to allocate may throw.
0208         String tokens may throw exceptions.
0209 
0210         @return The return type of the string token.
0211         If the token parameter is omitted, then
0212         a new `std::string` is returned.
0213         Otherwise, the function return type
0214         is the result type of the token.
0215 
0216         @param token An optional string token.
0217 
0218         @par Specification
0219         @li <a href="https://datatracker.ietf.org/doc/html/rfc4291#section-2.2">
0220             2.2. Text Representation of Addresses (rfc4291)</a>
0221     */
0222     template<BOOST_URL_STRTOK_TPARAM>
0223     BOOST_URL_STRTOK_RETURN
0224     to_string(
0225         BOOST_URL_STRTOK_ARG(token)) const
0226     {
0227         to_string_impl(token);
0228         return token.result();
0229     }
0230 
0231     /** Write a dotted decimal string representing the address to a buffer
0232 
0233         The resulting buffer is not null-terminated.
0234 
0235         @throw std::length_error `dest_size < ipv6_address::max_str_len`
0236 
0237         @return The formatted string
0238 
0239         @param dest The buffer in which to write,
0240         which must have at least `dest_size` space.
0241 
0242         @param dest_size The size of the output buffer.
0243     */
0244     BOOST_URL_DECL
0245     core::string_view
0246     to_buffer(
0247         char* dest,
0248         std::size_t dest_size) const;
0249 
0250     /** Return true if the address is unspecified
0251 
0252         The address 0:0:0:0:0:0:0:0 is called the
0253         unspecified address. It indicates the
0254         absence of an address.
0255 
0256         @par Specification
0257         @li <a href="https://datatracker.ietf.org/doc/html/rfc4291#section-2.5.2">
0258             2.5.2. The Unspecified Address (rfc4291)</a>
0259     */
0260     BOOST_URL_DECL
0261     bool
0262     is_unspecified() const noexcept;
0263 
0264     /** Return true if the address is a loopback address
0265 
0266         The unicast address 0:0:0:0:0:0:0:1 is called
0267         the loopback address. It may be used by a node
0268         to send an IPv6 packet to itself.
0269 
0270         @par Specification
0271         @li <a href="https://datatracker.ietf.org/doc/html/rfc4291#section-2.5.3">
0272             2.5.3. The Loopback Address (rfc4291)</a>
0273     */
0274     BOOST_URL_DECL
0275     bool
0276     is_loopback() const noexcept;
0277 
0278     /** Return true if the address is a mapped IPv4 address
0279 
0280         This address type is used to represent the
0281         addresses of IPv4 nodes as IPv6 addresses.
0282 
0283         @par Specification
0284         @li <a href="https://datatracker.ietf.org/doc/html/rfc4291#section-2.5.5.2">
0285             2.5.5.2. IPv4-Mapped IPv6 Address (rfc4291)</a>
0286     */
0287     BOOST_URL_DECL
0288     bool
0289     is_v4_mapped() const noexcept;
0290 
0291     /** Return true if two addresses are equal
0292     */
0293     friend
0294     bool
0295     operator==(
0296         ipv6_address const& a1,
0297         ipv6_address const& a2) noexcept
0298     {
0299         return a1.addr_ == a2.addr_;
0300     }
0301 
0302     /** Return true if two addresses are not equal
0303     */
0304     friend
0305     bool
0306     operator!=(
0307         ipv6_address const& a1,
0308         ipv6_address const& a2) noexcept
0309     {
0310         return !( a1 == a2 );
0311     }
0312 
0313     /** Return an address object that represents the loopback address
0314 
0315         The unicast address 0:0:0:0:0:0:0:1 is called
0316         the loopback address. It may be used by a node
0317         to send an IPv6 packet to itself.
0318 
0319         @par Specification
0320         @li <a href="https://datatracker.ietf.org/doc/html/rfc4291#section-2.5.3">
0321             2.5.3. The Loopback Address (rfc4291)</a>
0322     */
0323     BOOST_URL_DECL
0324     static
0325     ipv6_address
0326     loopback() noexcept;
0327 
0328     // hidden friend
0329     friend
0330     std::ostream&
0331     operator<<(
0332         std::ostream& os,
0333         ipv6_address const& addr)
0334     {
0335         char buf[ipv6_address::max_str_len];
0336         auto const s = addr.to_buffer(
0337             buf, sizeof(buf));
0338         os << s;
0339         return os;
0340     }
0341 
0342 
0343 private:
0344     BOOST_URL_DECL
0345     std::size_t
0346     print_impl(
0347         char* dest) const noexcept;
0348 
0349     BOOST_URL_DECL
0350     void
0351     to_string_impl(
0352         string_token::arg& t) const;
0353 
0354     bytes_type addr_{{}};
0355 };
0356 
0357 /** Format the address to an output stream
0358 
0359     This function writes the address to an
0360     output stream using standard notation.
0361 
0362     @return The output stream, for chaining.
0363 
0364     @param os The output stream to write to.
0365 
0366     @param addr The address to write.
0367 */
0368 std::ostream&
0369 operator<<(
0370     std::ostream& os,
0371     ipv6_address const& addr);
0372 
0373 //------------------------------------------------
0374 
0375 /** Parse a string containing an IPv6 address.
0376 
0377     This function attempts to parse the string
0378     as an IPv6 address and returns a result
0379     containing the address upon success, or
0380     an error code if the string does not contain
0381     a valid IPv6 address.
0382 
0383     @par Exception Safety
0384     Throws nothing.
0385 
0386     @return A result containing the address.
0387 
0388     @param s The string to parse.
0389 */
0390 BOOST_URL_DECL
0391 system::result<ipv6_address>
0392 parse_ipv6_address(
0393     core::string_view s) noexcept;
0394 
0395 } // urls
0396 } // boost
0397 
0398 #endif