basic_endpoint.hpp 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. //
  2. // basic_endpoint.hpp
  3. // ~~~~~~~~~~~~~~~~~~
  4. //
  5. // Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff dot com)
  6. // Derived from a public domain implementation written by Daniel Casimiro.
  7. //
  8. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  9. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  10. //
  11. #ifndef BOOST_ASIO_LOCAL_BASIC_ENDPOINT_HPP
  12. #define BOOST_ASIO_LOCAL_BASIC_ENDPOINT_HPP
  13. #if defined(_MSC_VER) && (_MSC_VER >= 1200)
  14. # pragma once
  15. #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
  16. #include <boost/asio/detail/push_options.hpp>
  17. #include <boost/asio/detail/push_options.hpp>
  18. #include <boost/throw_exception.hpp>
  19. #include <cstddef>
  20. #include <cstring>
  21. #include <ostream>
  22. #include <boost/system/system_error.hpp>
  23. #include <boost/asio/detail/pop_options.hpp>
  24. #include <boost/asio/error.hpp>
  25. #include <boost/asio/detail/socket_ops.hpp>
  26. #include <boost/asio/detail/socket_types.hpp>
  27. #include <boost/asio/detail/throw_error.hpp>
  28. #if !defined(BOOST_ASIO_DISABLE_LOCAL_SOCKETS)
  29. # if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
  30. # define BOOST_ASIO_HAS_LOCAL_SOCKETS 1
  31. # endif // !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
  32. #endif // !defined(BOOST_ASIO_DISABLE_LOCAL_SOCKETS)
  33. #if defined(BOOST_ASIO_HAS_LOCAL_SOCKETS) \
  34. || defined(GENERATING_DOCUMENTATION)
  35. namespace boost {
  36. namespace asio {
  37. namespace local {
  38. /// Describes an endpoint for a UNIX socket.
  39. /**
  40. * The boost::asio::local::basic_endpoint class template describes an endpoint
  41. * that may be associated with a particular UNIX socket.
  42. *
  43. * @par Thread Safety
  44. * @e Distinct @e objects: Safe.@n
  45. * @e Shared @e objects: Unsafe.
  46. *
  47. * @par Concepts:
  48. * Endpoint.
  49. */
  50. template <typename Protocol>
  51. class basic_endpoint
  52. {
  53. public:
  54. /// The protocol type associated with the endpoint.
  55. typedef Protocol protocol_type;
  56. /// The type of the endpoint structure. This type is dependent on the
  57. /// underlying implementation of the socket layer.
  58. #if defined(GENERATING_DOCUMENTATION)
  59. typedef implementation_defined data_type;
  60. #else
  61. typedef boost::asio::detail::socket_addr_type data_type;
  62. #endif
  63. /// Default constructor.
  64. basic_endpoint()
  65. {
  66. init("", 0);
  67. }
  68. /// Construct an endpoint using the specified path name.
  69. basic_endpoint(const char* path)
  70. {
  71. using namespace std; // For strlen.
  72. init(path, strlen(path));
  73. }
  74. /// Construct an endpoint using the specified path name.
  75. basic_endpoint(const std::string& path)
  76. {
  77. init(path.data(), path.length());
  78. }
  79. /// Copy constructor.
  80. basic_endpoint(const basic_endpoint& other)
  81. : data_(other.data_),
  82. path_length_(other.path_length_)
  83. {
  84. }
  85. /// Assign from another endpoint.
  86. basic_endpoint& operator=(const basic_endpoint& other)
  87. {
  88. data_ = other.data_;
  89. path_length_ = other.path_length_;
  90. return *this;
  91. }
  92. /// The protocol associated with the endpoint.
  93. protocol_type protocol() const
  94. {
  95. return protocol_type();
  96. }
  97. /// Get the underlying endpoint in the native type.
  98. data_type* data()
  99. {
  100. return &data_.base;
  101. }
  102. /// Get the underlying endpoint in the native type.
  103. const data_type* data() const
  104. {
  105. return &data_.base;
  106. }
  107. /// Get the underlying size of the endpoint in the native type.
  108. std::size_t size() const
  109. {
  110. return path_length_
  111. + offsetof(boost::asio::detail::sockaddr_un_type, sun_path);
  112. }
  113. /// Set the underlying size of the endpoint in the native type.
  114. void resize(std::size_t size)
  115. {
  116. if (size > sizeof(boost::asio::detail::sockaddr_un_type))
  117. {
  118. boost::system::system_error e(boost::asio::error::invalid_argument);
  119. boost::throw_exception(e);
  120. }
  121. else if (size == 0)
  122. {
  123. path_length_ = 0;
  124. }
  125. else
  126. {
  127. path_length_ = size
  128. - offsetof(boost::asio::detail::sockaddr_un_type, sun_path);
  129. // The path returned by the operating system may be NUL-terminated.
  130. if (path_length_ > 0 && data_.local.sun_path[path_length_ - 1] == 0)
  131. --path_length_;
  132. }
  133. }
  134. /// Get the capacity of the endpoint in the native type.
  135. std::size_t capacity() const
  136. {
  137. return sizeof(boost::asio::detail::sockaddr_un_type);
  138. }
  139. /// Get the path associated with the endpoint.
  140. std::string path() const
  141. {
  142. return std::string(data_.local.sun_path, path_length_);
  143. }
  144. /// Set the path associated with the endpoint.
  145. void path(const char* p)
  146. {
  147. using namespace std; // For strlen.
  148. init(p, strlen(p));
  149. }
  150. /// Set the path associated with the endpoint.
  151. void path(const std::string& p)
  152. {
  153. init(p.data(), p.length());
  154. }
  155. /// Compare two endpoints for equality.
  156. friend bool operator==(const basic_endpoint<Protocol>& e1,
  157. const basic_endpoint<Protocol>& e2)
  158. {
  159. return e1.path() == e2.path();
  160. }
  161. /// Compare two endpoints for inequality.
  162. friend bool operator!=(const basic_endpoint<Protocol>& e1,
  163. const basic_endpoint<Protocol>& e2)
  164. {
  165. return e1.path() != e2.path();
  166. }
  167. /// Compare endpoints for ordering.
  168. friend bool operator<(const basic_endpoint<Protocol>& e1,
  169. const basic_endpoint<Protocol>& e2)
  170. {
  171. return e1.path() < e2.path();
  172. }
  173. private:
  174. // The underlying UNIX socket address.
  175. union data_union
  176. {
  177. boost::asio::detail::socket_addr_type base;
  178. boost::asio::detail::sockaddr_un_type local;
  179. } data_;
  180. // The length of the path associated with the endpoint.
  181. std::size_t path_length_;
  182. // Initialise with a specified path.
  183. void init(const char* path, std::size_t path_length)
  184. {
  185. if (path_length > sizeof(data_.local.sun_path) - 1)
  186. {
  187. // The buffer is not large enough to store this address.
  188. boost::system::error_code ec(boost::asio::error::name_too_long);
  189. boost::asio::detail::throw_error(ec);
  190. }
  191. using namespace std; // For memcpy.
  192. data_.local = boost::asio::detail::sockaddr_un_type();
  193. data_.local.sun_family = AF_UNIX;
  194. memcpy(data_.local.sun_path, path, path_length);
  195. path_length_ = path_length;
  196. // NUL-terminate normal path names. Names that start with a NUL are in the
  197. // UNIX domain protocol's "abstract namespace" and are not NUL-terminated.
  198. if (path_length > 0 && data_.local.sun_path[0] == 0)
  199. data_.local.sun_path[path_length] = 0;
  200. }
  201. };
  202. /// Output an endpoint as a string.
  203. /**
  204. * Used to output a human-readable string for a specified endpoint.
  205. *
  206. * @param os The output stream to which the string will be written.
  207. *
  208. * @param endpoint The endpoint to be written.
  209. *
  210. * @return The output stream.
  211. *
  212. * @relates boost::asio::local::basic_endpoint
  213. */
  214. template <typename Elem, typename Traits, typename Protocol>
  215. std::basic_ostream<Elem, Traits>& operator<<(
  216. std::basic_ostream<Elem, Traits>& os,
  217. const basic_endpoint<Protocol>& endpoint)
  218. {
  219. os << endpoint.path();
  220. return os;
  221. }
  222. } // namespace local
  223. } // namespace asio
  224. } // namespace boost
  225. #endif // defined(BOOST_ASIO_HAS_LOCAL_SOCKETS)
  226. // || defined(GENERATING_DOCUMENTATION)
  227. #include <boost/asio/detail/pop_options.hpp>
  228. #endif // BOOST_ASIO_LOCAL_BASIC_ENDPOINT_HPP