Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:54:51

0001 ///////////////////////////////////////////////////////////////////////////////
0002 // Copyright (c) Lewis Baker
0003 // Licenced under MIT license. See LICENSE.txt for details.
0004 ///////////////////////////////////////////////////////////////////////////////
0005 #ifndef CPPCORO_NET_IPV4_ADDRESS_HPP_INCLUDED
0006 #define CPPCORO_NET_IPV4_ADDRESS_HPP_INCLUDED
0007 
0008 #include <cstdint>
0009 #include <optional>
0010 #include <string>
0011 #include <string_view>
0012 
0013 namespace cppcoro::net
0014 {
0015     class ipv4_address
0016     {
0017         using bytes_t = std::uint8_t[4];
0018 
0019     public:
0020 
0021         constexpr ipv4_address()
0022             : m_bytes{ 0, 0, 0, 0 }
0023         {}
0024 
0025         explicit constexpr ipv4_address(std::uint32_t integer)
0026             : m_bytes{
0027             static_cast<std::uint8_t>(integer >> 24),
0028             static_cast<std::uint8_t>(integer >> 16),
0029             static_cast<std::uint8_t>(integer >> 8),
0030             static_cast<std::uint8_t>(integer) }
0031         {}
0032 
0033         explicit constexpr ipv4_address(const std::uint8_t(&bytes)[4])
0034             : m_bytes{ bytes[0], bytes[1], bytes[2], bytes[3] }
0035         {}
0036 
0037         explicit constexpr ipv4_address(
0038             std::uint8_t b0,
0039             std::uint8_t b1,
0040             std::uint8_t b2,
0041             std::uint8_t b3)
0042             : m_bytes{ b0, b1, b2, b3 }
0043         {}
0044 
0045         constexpr const bytes_t& bytes() const { return m_bytes; }
0046 
0047         constexpr std::uint32_t to_integer() const
0048         {
0049             return
0050                 std::uint32_t(m_bytes[0]) << 24 |
0051                 std::uint32_t(m_bytes[1]) << 16 |
0052                 std::uint32_t(m_bytes[2]) << 8 |
0053                 std::uint32_t(m_bytes[3]);
0054         }
0055 
0056         static constexpr ipv4_address loopback()
0057         {
0058             return ipv4_address(127, 0, 0, 1);
0059         }
0060 
0061         constexpr bool is_loopback() const
0062         {
0063             return m_bytes[0] == 127;
0064         }
0065 
0066         constexpr bool is_private_network() const
0067         {
0068             return m_bytes[0] == 10 ||
0069                 (m_bytes[0] == 172 && (m_bytes[1] & 0xF0) == 0x10) ||
0070                 (m_bytes[0] == 192 && m_bytes[2] == 168);
0071         }
0072 
0073         constexpr bool operator==(ipv4_address other) const
0074         {
0075             return
0076                 m_bytes[0] == other.m_bytes[0] &&
0077                 m_bytes[1] == other.m_bytes[1] &&
0078                 m_bytes[2] == other.m_bytes[2] &&
0079                 m_bytes[3] == other.m_bytes[3];
0080         }
0081 
0082         constexpr bool operator!=(ipv4_address other) const
0083         {
0084             return !(*this == other);
0085         }
0086 
0087         constexpr bool operator<(ipv4_address other) const
0088         {
0089             return to_integer() < other.to_integer();
0090         }
0091 
0092         constexpr bool operator>(ipv4_address other) const
0093         {
0094             return other < *this;
0095         }
0096 
0097         constexpr bool operator<=(ipv4_address other) const
0098         {
0099             return !(other < *this);
0100         }
0101 
0102         constexpr bool operator>=(ipv4_address other) const
0103         {
0104             return !(*this < other);
0105         }
0106 
0107         /// Parse a string representation of an IP address.
0108         ///
0109         /// Parses strings of the form:
0110         /// - "num.num.num.num" where num is an integer in range [0, 255].
0111         /// - A single integer value in range [0, 2^32).
0112         ///
0113         /// \param string
0114         /// The string to parse.
0115         /// Must be in ASCII, UTF-8 or Latin-1 encoding.
0116         ///
0117         /// \return
0118         /// The IP address if successful, otherwise std::nullopt if the string
0119         /// could not be parsed as an IPv4 address.
0120         static std::optional<ipv4_address> from_string(std::string_view string) noexcept;
0121 
0122         /// Convert the IP address to dotted decimal notation.
0123         ///
0124         /// eg. "12.67.190.23"
0125         std::string to_string() const;
0126 
0127     private:
0128 
0129         alignas(std::uint32_t) std::uint8_t m_bytes[4];
0130 
0131     };
0132 }
0133 
0134 #endif