Audio plugin host https://kx.studio/carla
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

317 lines
6.1KB

  1. //
  2. // detail/socket_option.hpp
  3. // ~~~~~~~~~~~~~~~~~~~~~~~~
  4. //
  5. // Copyright (c) 2003-2019 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 ASIO_DETAIL_SOCKET_OPTION_HPP
  11. #define ASIO_DETAIL_SOCKET_OPTION_HPP
  12. #if defined(_MSC_VER) && (_MSC_VER >= 1200)
  13. # pragma once
  14. #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
  15. #include "asio/detail/config.hpp"
  16. #include <cstddef>
  17. #include <stdexcept>
  18. #include "asio/detail/socket_types.hpp"
  19. #include "asio/detail/throw_exception.hpp"
  20. #include "asio/detail/push_options.hpp"
  21. namespace asio {
  22. namespace detail {
  23. namespace socket_option {
  24. // Helper template for implementing boolean-based options.
  25. template <int Level, int Name>
  26. class boolean
  27. {
  28. public:
  29. // Default constructor.
  30. boolean()
  31. : value_(0)
  32. {
  33. }
  34. // Construct with a specific option value.
  35. explicit boolean(bool v)
  36. : value_(v ? 1 : 0)
  37. {
  38. }
  39. // Set the current value of the boolean.
  40. boolean& operator=(bool v)
  41. {
  42. value_ = v ? 1 : 0;
  43. return *this;
  44. }
  45. // Get the current value of the boolean.
  46. bool value() const
  47. {
  48. return !!value_;
  49. }
  50. // Convert to bool.
  51. operator bool() const
  52. {
  53. return !!value_;
  54. }
  55. // Test for false.
  56. bool operator!() const
  57. {
  58. return !value_;
  59. }
  60. // Get the level of the socket option.
  61. template <typename Protocol>
  62. int level(const Protocol&) const
  63. {
  64. return Level;
  65. }
  66. // Get the name of the socket option.
  67. template <typename Protocol>
  68. int name(const Protocol&) const
  69. {
  70. return Name;
  71. }
  72. // Get the address of the boolean data.
  73. template <typename Protocol>
  74. int* data(const Protocol&)
  75. {
  76. return &value_;
  77. }
  78. // Get the address of the boolean data.
  79. template <typename Protocol>
  80. const int* data(const Protocol&) const
  81. {
  82. return &value_;
  83. }
  84. // Get the size of the boolean data.
  85. template <typename Protocol>
  86. std::size_t size(const Protocol&) const
  87. {
  88. return sizeof(value_);
  89. }
  90. // Set the size of the boolean data.
  91. template <typename Protocol>
  92. void resize(const Protocol&, std::size_t s)
  93. {
  94. // On some platforms (e.g. Windows Vista), the getsockopt function will
  95. // return the size of a boolean socket option as one byte, even though a
  96. // four byte integer was passed in.
  97. switch (s)
  98. {
  99. case sizeof(char):
  100. value_ = *reinterpret_cast<char*>(&value_) ? 1 : 0;
  101. break;
  102. case sizeof(value_):
  103. break;
  104. default:
  105. {
  106. std::length_error ex("boolean socket option resize");
  107. asio::detail::throw_exception(ex);
  108. }
  109. }
  110. }
  111. private:
  112. int value_;
  113. };
  114. // Helper template for implementing integer options.
  115. template <int Level, int Name>
  116. class integer
  117. {
  118. public:
  119. // Default constructor.
  120. integer()
  121. : value_(0)
  122. {
  123. }
  124. // Construct with a specific option value.
  125. explicit integer(int v)
  126. : value_(v)
  127. {
  128. }
  129. // Set the value of the int option.
  130. integer& operator=(int v)
  131. {
  132. value_ = v;
  133. return *this;
  134. }
  135. // Get the current value of the int option.
  136. int value() const
  137. {
  138. return value_;
  139. }
  140. // Get the level of the socket option.
  141. template <typename Protocol>
  142. int level(const Protocol&) const
  143. {
  144. return Level;
  145. }
  146. // Get the name of the socket option.
  147. template <typename Protocol>
  148. int name(const Protocol&) const
  149. {
  150. return Name;
  151. }
  152. // Get the address of the int data.
  153. template <typename Protocol>
  154. int* data(const Protocol&)
  155. {
  156. return &value_;
  157. }
  158. // Get the address of the int data.
  159. template <typename Protocol>
  160. const int* data(const Protocol&) const
  161. {
  162. return &value_;
  163. }
  164. // Get the size of the int data.
  165. template <typename Protocol>
  166. std::size_t size(const Protocol&) const
  167. {
  168. return sizeof(value_);
  169. }
  170. // Set the size of the int data.
  171. template <typename Protocol>
  172. void resize(const Protocol&, std::size_t s)
  173. {
  174. if (s != sizeof(value_))
  175. {
  176. std::length_error ex("integer socket option resize");
  177. asio::detail::throw_exception(ex);
  178. }
  179. }
  180. private:
  181. int value_;
  182. };
  183. // Helper template for implementing linger options.
  184. template <int Level, int Name>
  185. class linger
  186. {
  187. public:
  188. // Default constructor.
  189. linger()
  190. {
  191. value_.l_onoff = 0;
  192. value_.l_linger = 0;
  193. }
  194. // Construct with specific option values.
  195. linger(bool e, int t)
  196. {
  197. enabled(e);
  198. timeout ASIO_PREVENT_MACRO_SUBSTITUTION(t);
  199. }
  200. // Set the value for whether linger is enabled.
  201. void enabled(bool value)
  202. {
  203. value_.l_onoff = value ? 1 : 0;
  204. }
  205. // Get the value for whether linger is enabled.
  206. bool enabled() const
  207. {
  208. return value_.l_onoff != 0;
  209. }
  210. // Set the value for the linger timeout.
  211. void timeout ASIO_PREVENT_MACRO_SUBSTITUTION(int value)
  212. {
  213. #if defined(WIN32)
  214. value_.l_linger = static_cast<u_short>(value);
  215. #else
  216. value_.l_linger = value;
  217. #endif
  218. }
  219. // Get the value for the linger timeout.
  220. int timeout ASIO_PREVENT_MACRO_SUBSTITUTION() const
  221. {
  222. return static_cast<int>(value_.l_linger);
  223. }
  224. // Get the level of the socket option.
  225. template <typename Protocol>
  226. int level(const Protocol&) const
  227. {
  228. return Level;
  229. }
  230. // Get the name of the socket option.
  231. template <typename Protocol>
  232. int name(const Protocol&) const
  233. {
  234. return Name;
  235. }
  236. // Get the address of the linger data.
  237. template <typename Protocol>
  238. detail::linger_type* data(const Protocol&)
  239. {
  240. return &value_;
  241. }
  242. // Get the address of the linger data.
  243. template <typename Protocol>
  244. const detail::linger_type* data(const Protocol&) const
  245. {
  246. return &value_;
  247. }
  248. // Get the size of the linger data.
  249. template <typename Protocol>
  250. std::size_t size(const Protocol&) const
  251. {
  252. return sizeof(value_);
  253. }
  254. // Set the size of the int data.
  255. template <typename Protocol>
  256. void resize(const Protocol&, std::size_t s)
  257. {
  258. if (s != sizeof(value_))
  259. {
  260. std::length_error ex("linger socket option resize");
  261. asio::detail::throw_exception(ex);
  262. }
  263. }
  264. private:
  265. detail::linger_type value_;
  266. };
  267. } // namespace socket_option
  268. } // namespace detail
  269. } // namespace asio
  270. #include "asio/detail/pop_options.hpp"
  271. #endif // ASIO_DETAIL_SOCKET_OPTION_HPP