PageRenderTime 25ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/Mac/Frameworks/Boost.framework/Versions/A/Headers/asio/ip/address_v6.hpp

https://github.com/llazarus1/YAGE
C++ Header | 431 lines | 303 code | 53 blank | 75 comment | 94 complexity | 1417696d5645eb824ea74bc633e5b3ad MD5 | raw file
  1. //
  2. // address_v6.hpp
  3. // ~~~~~~~~~~~~~~
  4. //
  5. // Copyright (c) 2003-2010 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_V6_HPP
  11. #define BOOST_ASIO_IP_ADDRESS_V6_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 <boost/config.hpp>
  18. #if !defined(BOOST_NO_IOSTREAM)
  19. # include <iosfwd>
  20. #endif // !defined(BOOST_NO_IOSTREAM)
  21. #include <cstring>
  22. #include <string>
  23. #include <stdexcept>
  24. #include <typeinfo>
  25. #include <boost/array.hpp>
  26. #include <boost/throw_exception.hpp>
  27. #include <boost/asio/detail/pop_options.hpp>
  28. #include <boost/asio/error.hpp>
  29. #include <boost/asio/detail/socket_ops.hpp>
  30. #include <boost/asio/detail/socket_types.hpp>
  31. #include <boost/asio/detail/throw_error.hpp>
  32. #include <boost/asio/ip/address_v4.hpp>
  33. namespace boost {
  34. namespace asio {
  35. namespace ip {
  36. /// Implements IP version 6 style addresses.
  37. /**
  38. * The boost::asio::ip::address_v6 class provides the ability to use and
  39. * manipulate IP version 6 addresses.
  40. *
  41. * @par Thread Safety
  42. * @e Distinct @e objects: Safe.@n
  43. * @e Shared @e objects: Unsafe.
  44. */
  45. class address_v6
  46. {
  47. public:
  48. /// The type used to represent an address as an array of bytes.
  49. typedef boost::array<unsigned char, 16> bytes_type;
  50. /// Default constructor.
  51. address_v6()
  52. : scope_id_(0)
  53. {
  54. boost::asio::detail::in6_addr_type tmp_addr = IN6ADDR_ANY_INIT;
  55. addr_ = tmp_addr;
  56. }
  57. /// Construct an address from raw bytes and scope ID.
  58. explicit address_v6(const bytes_type& bytes, unsigned long scope_id = 0)
  59. : scope_id_(scope_id)
  60. {
  61. #if UCHAR_MAX > 0xFF
  62. for (std::size_t i = 0; i < bytes.size(); ++i)
  63. {
  64. if (bytes[i] > 0xFF)
  65. {
  66. std::out_of_range ex("address_v6 from bytes_type");
  67. boost::throw_exception(ex);
  68. }
  69. }
  70. #endif // UCHAR_MAX > 0xFF
  71. using namespace std; // For memcpy.
  72. memcpy(addr_.s6_addr, bytes.elems, 16);
  73. }
  74. /// Copy constructor.
  75. address_v6(const address_v6& other)
  76. : addr_(other.addr_),
  77. scope_id_(other.scope_id_)
  78. {
  79. }
  80. /// Assign from another address.
  81. address_v6& operator=(const address_v6& other)
  82. {
  83. addr_ = other.addr_;
  84. scope_id_ = other.scope_id_;
  85. return *this;
  86. }
  87. /// The scope ID of the address.
  88. /**
  89. * Returns the scope ID associated with the IPv6 address.
  90. */
  91. unsigned long scope_id() const
  92. {
  93. return scope_id_;
  94. }
  95. /// The scope ID of the address.
  96. /**
  97. * Modifies the scope ID associated with the IPv6 address.
  98. */
  99. void scope_id(unsigned long id)
  100. {
  101. scope_id_ = id;
  102. }
  103. /// Get the address in bytes.
  104. bytes_type to_bytes() const
  105. {
  106. using namespace std; // For memcpy.
  107. bytes_type bytes;
  108. memcpy(bytes.elems, addr_.s6_addr, 16);
  109. return bytes;
  110. }
  111. /// Get the address as a string.
  112. std::string to_string() const
  113. {
  114. boost::system::error_code ec;
  115. std::string addr = to_string(ec);
  116. boost::asio::detail::throw_error(ec);
  117. return addr;
  118. }
  119. /// Get the address as a string.
  120. std::string to_string(boost::system::error_code& ec) const
  121. {
  122. char addr_str[boost::asio::detail::max_addr_v6_str_len];
  123. const char* addr =
  124. boost::asio::detail::socket_ops::inet_ntop(AF_INET6, &addr_, addr_str,
  125. boost::asio::detail::max_addr_v6_str_len, scope_id_, ec);
  126. if (addr == 0)
  127. return std::string();
  128. return addr;
  129. }
  130. /// Create an address from an IP address string.
  131. static address_v6 from_string(const char* str)
  132. {
  133. boost::system::error_code ec;
  134. address_v6 addr = from_string(str, ec);
  135. boost::asio::detail::throw_error(ec);
  136. return addr;
  137. }
  138. /// Create an address from an IP address string.
  139. static address_v6 from_string(const char* str, boost::system::error_code& ec)
  140. {
  141. address_v6 tmp;
  142. if (boost::asio::detail::socket_ops::inet_pton(
  143. AF_INET6, str, &tmp.addr_, &tmp.scope_id_, ec) <= 0)
  144. return address_v6();
  145. return tmp;
  146. }
  147. /// Create an address from an IP address string.
  148. static address_v6 from_string(const std::string& str)
  149. {
  150. return from_string(str.c_str());
  151. }
  152. /// Create an address from an IP address string.
  153. static address_v6 from_string(const std::string& str,
  154. boost::system::error_code& ec)
  155. {
  156. return from_string(str.c_str(), ec);
  157. }
  158. /// Converts an IPv4-mapped or IPv4-compatible address to an IPv4 address.
  159. address_v4 to_v4() const
  160. {
  161. if (!is_v4_mapped() && !is_v4_compatible())
  162. {
  163. std::bad_cast ex;
  164. boost::throw_exception(ex);
  165. }
  166. address_v4::bytes_type v4_bytes = { { addr_.s6_addr[12],
  167. addr_.s6_addr[13], addr_.s6_addr[14], addr_.s6_addr[15] } };
  168. return address_v4(v4_bytes);
  169. }
  170. /// Determine whether the address is a loopback address.
  171. bool is_loopback() const
  172. {
  173. #if defined(__BORLANDC__)
  174. return ((addr_.s6_addr[0] == 0) && (addr_.s6_addr[1] == 0)
  175. && (addr_.s6_addr[2] == 0) && (addr_.s6_addr[3] == 0)
  176. && (addr_.s6_addr[4] == 0) && (addr_.s6_addr[5] == 0)
  177. && (addr_.s6_addr[6] == 0) && (addr_.s6_addr[7] == 0)
  178. && (addr_.s6_addr[8] == 0) && (addr_.s6_addr[9] == 0)
  179. && (addr_.s6_addr[10] == 0) && (addr_.s6_addr[11] == 0)
  180. && (addr_.s6_addr[12] == 0) && (addr_.s6_addr[13] == 0)
  181. && (addr_.s6_addr[14] == 0) && (addr_.s6_addr[15] == 1));
  182. #else
  183. using namespace boost::asio::detail;
  184. return IN6_IS_ADDR_LOOPBACK(&addr_) != 0;
  185. #endif
  186. }
  187. /// Determine whether the address is unspecified.
  188. bool is_unspecified() const
  189. {
  190. #if defined(__BORLANDC__)
  191. return ((addr_.s6_addr[0] == 0) && (addr_.s6_addr[1] == 0)
  192. && (addr_.s6_addr[2] == 0) && (addr_.s6_addr[3] == 0)
  193. && (addr_.s6_addr[4] == 0) && (addr_.s6_addr[5] == 0)
  194. && (addr_.s6_addr[6] == 0) && (addr_.s6_addr[7] == 0)
  195. && (addr_.s6_addr[8] == 0) && (addr_.s6_addr[9] == 0)
  196. && (addr_.s6_addr[10] == 0) && (addr_.s6_addr[11] == 0)
  197. && (addr_.s6_addr[12] == 0) && (addr_.s6_addr[13] == 0)
  198. && (addr_.s6_addr[14] == 0) && (addr_.s6_addr[15] == 0));
  199. #else
  200. using namespace boost::asio::detail;
  201. return IN6_IS_ADDR_UNSPECIFIED(&addr_) != 0;
  202. #endif
  203. }
  204. /// Determine whether the address is link local.
  205. bool is_link_local() const
  206. {
  207. using namespace boost::asio::detail;
  208. return IN6_IS_ADDR_LINKLOCAL(&addr_) != 0;
  209. }
  210. /// Determine whether the address is site local.
  211. bool is_site_local() const
  212. {
  213. using namespace boost::asio::detail;
  214. return IN6_IS_ADDR_SITELOCAL(&addr_) != 0;
  215. }
  216. /// Determine whether the address is a mapped IPv4 address.
  217. bool is_v4_mapped() const
  218. {
  219. using namespace boost::asio::detail;
  220. return IN6_IS_ADDR_V4MAPPED(&addr_) != 0;
  221. }
  222. /// Determine whether the address is an IPv4-compatible address.
  223. bool is_v4_compatible() const
  224. {
  225. using namespace boost::asio::detail;
  226. return IN6_IS_ADDR_V4COMPAT(&addr_) != 0;
  227. }
  228. /// Determine whether the address is a multicast address.
  229. bool is_multicast() const
  230. {
  231. using namespace boost::asio::detail;
  232. return IN6_IS_ADDR_MULTICAST(&addr_) != 0;
  233. }
  234. /// Determine whether the address is a global multicast address.
  235. bool is_multicast_global() const
  236. {
  237. using namespace boost::asio::detail;
  238. return IN6_IS_ADDR_MC_GLOBAL(&addr_) != 0;
  239. }
  240. /// Determine whether the address is a link-local multicast address.
  241. bool is_multicast_link_local() const
  242. {
  243. using namespace boost::asio::detail;
  244. return IN6_IS_ADDR_MC_LINKLOCAL(&addr_) != 0;
  245. }
  246. /// Determine whether the address is a node-local multicast address.
  247. bool is_multicast_node_local() const
  248. {
  249. using namespace boost::asio::detail;
  250. return IN6_IS_ADDR_MC_NODELOCAL(&addr_) != 0;
  251. }
  252. /// Determine whether the address is a org-local multicast address.
  253. bool is_multicast_org_local() const
  254. {
  255. using namespace boost::asio::detail;
  256. return IN6_IS_ADDR_MC_ORGLOCAL(&addr_) != 0;
  257. }
  258. /// Determine whether the address is a site-local multicast address.
  259. bool is_multicast_site_local() const
  260. {
  261. using namespace boost::asio::detail;
  262. return IN6_IS_ADDR_MC_SITELOCAL(&addr_) != 0;
  263. }
  264. /// Compare two addresses for equality.
  265. friend bool operator==(const address_v6& a1, const address_v6& a2)
  266. {
  267. using namespace std; // For memcmp.
  268. return memcmp(&a1.addr_, &a2.addr_,
  269. sizeof(boost::asio::detail::in6_addr_type)) == 0
  270. && a1.scope_id_ == a2.scope_id_;
  271. }
  272. /// Compare two addresses for inequality.
  273. friend bool operator!=(const address_v6& a1, const address_v6& a2)
  274. {
  275. using namespace std; // For memcmp.
  276. return memcmp(&a1.addr_, &a2.addr_,
  277. sizeof(boost::asio::detail::in6_addr_type)) != 0
  278. || a1.scope_id_ != a2.scope_id_;
  279. }
  280. /// Compare addresses for ordering.
  281. friend bool operator<(const address_v6& a1, const address_v6& a2)
  282. {
  283. using namespace std; // For memcmp.
  284. int memcmp_result = memcmp(&a1.addr_, &a2.addr_,
  285. sizeof(boost::asio::detail::in6_addr_type));
  286. if (memcmp_result < 0)
  287. return true;
  288. if (memcmp_result > 0)
  289. return false;
  290. return a1.scope_id_ < a2.scope_id_;
  291. }
  292. /// Compare addresses for ordering.
  293. friend bool operator>(const address_v6& a1, const address_v6& a2)
  294. {
  295. return a2 < a1;
  296. }
  297. /// Compare addresses for ordering.
  298. friend bool operator<=(const address_v6& a1, const address_v6& a2)
  299. {
  300. return !(a2 < a1);
  301. }
  302. /// Compare addresses for ordering.
  303. friend bool operator>=(const address_v6& a1, const address_v6& a2)
  304. {
  305. return !(a1 < a2);
  306. }
  307. /// Obtain an address object that represents any address.
  308. static address_v6 any()
  309. {
  310. return address_v6();
  311. }
  312. /// Obtain an address object that represents the loopback address.
  313. static address_v6 loopback()
  314. {
  315. address_v6 tmp;
  316. boost::asio::detail::in6_addr_type tmp_addr = IN6ADDR_LOOPBACK_INIT;
  317. tmp.addr_ = tmp_addr;
  318. return tmp;
  319. }
  320. /// Create an IPv4-mapped IPv6 address.
  321. static address_v6 v4_mapped(const address_v4& addr)
  322. {
  323. address_v4::bytes_type v4_bytes = addr.to_bytes();
  324. bytes_type v6_bytes = { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF,
  325. v4_bytes[0], v4_bytes[1], v4_bytes[2], v4_bytes[3] } };
  326. return address_v6(v6_bytes);
  327. }
  328. /// Create an IPv4-compatible IPv6 address.
  329. static address_v6 v4_compatible(const address_v4& addr)
  330. {
  331. address_v4::bytes_type v4_bytes = addr.to_bytes();
  332. bytes_type v6_bytes = { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  333. v4_bytes[0], v4_bytes[1], v4_bytes[2], v4_bytes[3] } };
  334. return address_v6(v6_bytes);
  335. }
  336. private:
  337. // The underlying IPv6 address.
  338. boost::asio::detail::in6_addr_type addr_;
  339. // The scope ID associated with the address.
  340. unsigned long scope_id_;
  341. };
  342. #if !defined(BOOST_NO_IOSTREAM)
  343. /// Output an address as a string.
  344. /**
  345. * Used to output a human-readable string for a specified address.
  346. *
  347. * @param os The output stream to which the string will be written.
  348. *
  349. * @param addr The address to be written.
  350. *
  351. * @return The output stream.
  352. *
  353. * @relates boost::asio::ip::address_v6
  354. */
  355. template <typename Elem, typename Traits>
  356. std::basic_ostream<Elem, Traits>& operator<<(
  357. std::basic_ostream<Elem, Traits>& os, const address_v6& addr)
  358. {
  359. boost::system::error_code ec;
  360. std::string s = addr.to_string(ec);
  361. if (ec)
  362. {
  363. if (os.exceptions() & std::ios::failbit)
  364. boost::asio::detail::throw_error(ec);
  365. else
  366. os.setstate(std::ios_base::failbit);
  367. }
  368. else
  369. for (std::string::iterator i = s.begin(); i != s.end(); ++i)
  370. os << os.widen(*i);
  371. return os;
  372. }
  373. #endif // !defined(BOOST_NO_IOSTREAM)
  374. } // namespace ip
  375. } // namespace asio
  376. } // namespace boost
  377. #include <boost/asio/detail/pop_options.hpp>
  378. #endif // BOOST_ASIO_IP_ADDRESS_V6_HPP