address.hpp 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  1. //
  2. // address.hpp
  3. // ~~~~~~~~~~~
  4. //
  5. // Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff dot com)
  6. //
  7. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  8. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  9. //
  10. #ifndef BOOST_ASIO_IP_ADDRESS_HPP
  11. #define BOOST_ASIO_IP_ADDRESS_HPP
  12. #if defined(_MSC_VER) && (_MSC_VER >= 1200)
  13. # pragma once
  14. #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
  15. #include <boost/asio/detail/push_options.hpp>
  16. #include <boost/asio/detail/push_options.hpp>
  17. #include <iosfwd>
  18. #include <string>
  19. #include <boost/throw_exception.hpp>
  20. #include <boost/asio/detail/pop_options.hpp>
  21. #include <boost/asio/error.hpp>
  22. #include <boost/asio/ip/address_v4.hpp>
  23. #include <boost/asio/ip/address_v6.hpp>
  24. #include <boost/asio/detail/throw_error.hpp>
  25. namespace boost {
  26. namespace asio {
  27. namespace ip {
  28. /// Implements version-independent IP addresses.
  29. /**
  30. * The boost::asio::ip::address class provides the ability to use either IP
  31. * version 4 or version 6 addresses.
  32. *
  33. * @par Thread Safety
  34. * @e Distinct @e objects: Safe.@n
  35. * @e Shared @e objects: Unsafe.
  36. */
  37. class address
  38. {
  39. public:
  40. /// Default constructor.
  41. address()
  42. : type_(ipv4),
  43. ipv4_address_(),
  44. ipv6_address_()
  45. {
  46. }
  47. /// Construct an address from an IPv4 address.
  48. address(const boost::asio::ip::address_v4& ipv4_address)
  49. : type_(ipv4),
  50. ipv4_address_(ipv4_address),
  51. ipv6_address_()
  52. {
  53. }
  54. /// Construct an address from an IPv6 address.
  55. address(const boost::asio::ip::address_v6& ipv6_address)
  56. : type_(ipv6),
  57. ipv4_address_(),
  58. ipv6_address_(ipv6_address)
  59. {
  60. }
  61. /// Copy constructor.
  62. address(const address& other)
  63. : type_(other.type_),
  64. ipv4_address_(other.ipv4_address_),
  65. ipv6_address_(other.ipv6_address_)
  66. {
  67. }
  68. /// Assign from another address.
  69. address& operator=(const address& other)
  70. {
  71. type_ = other.type_;
  72. ipv4_address_ = other.ipv4_address_;
  73. ipv6_address_ = other.ipv6_address_;
  74. return *this;
  75. }
  76. /// Assign from an IPv4 address.
  77. address& operator=(const boost::asio::ip::address_v4& ipv4_address)
  78. {
  79. type_ = ipv4;
  80. ipv4_address_ = ipv4_address;
  81. ipv6_address_ = boost::asio::ip::address_v6();
  82. return *this;
  83. }
  84. /// Assign from an IPv6 address.
  85. address& operator=(const boost::asio::ip::address_v6& ipv6_address)
  86. {
  87. type_ = ipv6;
  88. ipv4_address_ = boost::asio::ip::address_v4();
  89. ipv6_address_ = ipv6_address;
  90. return *this;
  91. }
  92. /// Get whether the address is an IP version 4 address.
  93. bool is_v4() const
  94. {
  95. return type_ == ipv4;
  96. }
  97. /// Get whether the address is an IP version 6 address.
  98. bool is_v6() const
  99. {
  100. return type_ == ipv6;
  101. }
  102. /// Get the address as an IP version 4 address.
  103. boost::asio::ip::address_v4 to_v4() const
  104. {
  105. if (type_ != ipv4)
  106. {
  107. boost::system::system_error e(
  108. boost::asio::error::address_family_not_supported);
  109. boost::throw_exception(e);
  110. }
  111. return ipv4_address_;
  112. }
  113. /// Get the address as an IP version 6 address.
  114. boost::asio::ip::address_v6 to_v6() const
  115. {
  116. if (type_ != ipv6)
  117. {
  118. boost::system::system_error e(
  119. boost::asio::error::address_family_not_supported);
  120. boost::throw_exception(e);
  121. }
  122. return ipv6_address_;
  123. }
  124. /// Get the address as a string in dotted decimal format.
  125. std::string to_string() const
  126. {
  127. if (type_ == ipv6)
  128. return ipv6_address_.to_string();
  129. return ipv4_address_.to_string();
  130. }
  131. /// Get the address as a string in dotted decimal format.
  132. std::string to_string(boost::system::error_code& ec) const
  133. {
  134. if (type_ == ipv6)
  135. return ipv6_address_.to_string(ec);
  136. return ipv4_address_.to_string(ec);
  137. }
  138. /// Create an address from an IPv4 address string in dotted decimal form,
  139. /// or from an IPv6 address in hexadecimal notation.
  140. static address from_string(const char* str)
  141. {
  142. boost::system::error_code ec;
  143. address addr = from_string(str, ec);
  144. boost::asio::detail::throw_error(ec);
  145. return addr;
  146. }
  147. /// Create an address from an IPv4 address string in dotted decimal form,
  148. /// or from an IPv6 address in hexadecimal notation.
  149. static address from_string(const char* str, boost::system::error_code& ec)
  150. {
  151. boost::asio::ip::address_v6 ipv6_address =
  152. boost::asio::ip::address_v6::from_string(str, ec);
  153. if (!ec)
  154. {
  155. address tmp;
  156. tmp.type_ = ipv6;
  157. tmp.ipv6_address_ = ipv6_address;
  158. return tmp;
  159. }
  160. boost::asio::ip::address_v4 ipv4_address =
  161. boost::asio::ip::address_v4::from_string(str, ec);
  162. if (!ec)
  163. {
  164. address tmp;
  165. tmp.type_ = ipv4;
  166. tmp.ipv4_address_ = ipv4_address;
  167. return tmp;
  168. }
  169. return address();
  170. }
  171. /// Create an address from an IPv4 address string in dotted decimal form,
  172. /// or from an IPv6 address in hexadecimal notation.
  173. static address from_string(const std::string& str)
  174. {
  175. return from_string(str.c_str());
  176. }
  177. /// Create an address from an IPv4 address string in dotted decimal form,
  178. /// or from an IPv6 address in hexadecimal notation.
  179. static address from_string(const std::string& str,
  180. boost::system::error_code& ec)
  181. {
  182. return from_string(str.c_str(), ec);
  183. }
  184. /// Compare two addresses for equality.
  185. friend bool operator==(const address& a1, const address& a2)
  186. {
  187. if (a1.type_ != a2.type_)
  188. return false;
  189. if (a1.type_ == ipv6)
  190. return a1.ipv6_address_ == a2.ipv6_address_;
  191. return a1.ipv4_address_ == a2.ipv4_address_;
  192. }
  193. /// Compare two addresses for inequality.
  194. friend bool operator!=(const address& a1, const address& a2)
  195. {
  196. if (a1.type_ != a2.type_)
  197. return true;
  198. if (a1.type_ == ipv6)
  199. return a1.ipv6_address_ != a2.ipv6_address_;
  200. return a1.ipv4_address_ != a2.ipv4_address_;
  201. }
  202. /// Compare addresses for ordering.
  203. friend bool operator<(const address& a1, const address& a2)
  204. {
  205. if (a1.type_ < a2.type_)
  206. return true;
  207. if (a1.type_ > a2.type_)
  208. return false;
  209. if (a1.type_ == ipv6)
  210. return a1.ipv6_address_ < a2.ipv6_address_;
  211. return a1.ipv4_address_ < a2.ipv4_address_;
  212. }
  213. private:
  214. // The type of the address.
  215. enum { ipv4, ipv6 } type_;
  216. // The underlying IPv4 address.
  217. boost::asio::ip::address_v4 ipv4_address_;
  218. // The underlying IPv6 address.
  219. boost::asio::ip::address_v6 ipv6_address_;
  220. };
  221. /// Output an address as a string.
  222. /**
  223. * Used to output a human-readable string for a specified address.
  224. *
  225. * @param os The output stream to which the string will be written.
  226. *
  227. * @param addr The address to be written.
  228. *
  229. * @return The output stream.
  230. *
  231. * @relates boost::asio::ip::address
  232. */
  233. template <typename Elem, typename Traits>
  234. std::basic_ostream<Elem, Traits>& operator<<(
  235. std::basic_ostream<Elem, Traits>& os, const address& addr)
  236. {
  237. os << addr.to_string();
  238. return os;
  239. }
  240. } // namespace ip
  241. } // namespace asio
  242. } // namespace boost
  243. #include <boost/asio/detail/pop_options.hpp>
  244. #endif // BOOST_ASIO_IP_ADDRESS_HPP