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.

545 lines
12KB

  1. //
  2. // detail/buffer_sequence_adapter.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_BUFFER_SEQUENCE_ADAPTER_HPP
  11. #define ASIO_DETAIL_BUFFER_SEQUENCE_ADAPTER_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 "asio/buffer.hpp"
  17. #include "asio/detail/array_fwd.hpp"
  18. #include "asio/detail/socket_types.hpp"
  19. #include "asio/detail/push_options.hpp"
  20. namespace asio {
  21. namespace detail {
  22. class buffer_sequence_adapter_base
  23. {
  24. #if defined(ASIO_WINDOWS_RUNTIME)
  25. public:
  26. // The maximum number of buffers to support in a single operation.
  27. enum { max_buffers = 1 };
  28. protected:
  29. typedef Windows::Storage::Streams::IBuffer^ native_buffer_type;
  30. ASIO_DECL static void init_native_buffer(
  31. native_buffer_type& buf,
  32. const asio::mutable_buffer& buffer);
  33. ASIO_DECL static void init_native_buffer(
  34. native_buffer_type& buf,
  35. const asio::const_buffer& buffer);
  36. #elif defined(ASIO_WINDOWS) || defined(__CYGWIN__)
  37. public:
  38. // The maximum number of buffers to support in a single operation.
  39. enum { max_buffers = 64 < max_iov_len ? 64 : max_iov_len };
  40. protected:
  41. typedef WSABUF native_buffer_type;
  42. static void init_native_buffer(WSABUF& buf,
  43. const asio::mutable_buffer& buffer)
  44. {
  45. buf.buf = static_cast<char*>(buffer.data());
  46. buf.len = static_cast<ULONG>(buffer.size());
  47. }
  48. static void init_native_buffer(WSABUF& buf,
  49. const asio::const_buffer& buffer)
  50. {
  51. buf.buf = const_cast<char*>(static_cast<const char*>(buffer.data()));
  52. buf.len = static_cast<ULONG>(buffer.size());
  53. }
  54. #else // defined(ASIO_WINDOWS) || defined(__CYGWIN__)
  55. public:
  56. // The maximum number of buffers to support in a single operation.
  57. enum { max_buffers = 64 < max_iov_len ? 64 : max_iov_len };
  58. protected:
  59. typedef iovec native_buffer_type;
  60. static void init_iov_base(void*& base, void* addr)
  61. {
  62. base = addr;
  63. }
  64. template <typename T>
  65. static void init_iov_base(T& base, void* addr)
  66. {
  67. base = static_cast<T>(addr);
  68. }
  69. static void init_native_buffer(iovec& iov,
  70. const asio::mutable_buffer& buffer)
  71. {
  72. init_iov_base(iov.iov_base, buffer.data());
  73. iov.iov_len = buffer.size();
  74. }
  75. static void init_native_buffer(iovec& iov,
  76. const asio::const_buffer& buffer)
  77. {
  78. init_iov_base(iov.iov_base, const_cast<void*>(buffer.data()));
  79. iov.iov_len = buffer.size();
  80. }
  81. #endif // defined(ASIO_WINDOWS) || defined(__CYGWIN__)
  82. };
  83. // Helper class to translate buffers into the native buffer representation.
  84. template <typename Buffer, typename Buffers>
  85. class buffer_sequence_adapter
  86. : buffer_sequence_adapter_base
  87. {
  88. public:
  89. explicit buffer_sequence_adapter(const Buffers& buffer_sequence)
  90. : count_(0), total_buffer_size_(0)
  91. {
  92. buffer_sequence_adapter::init(
  93. asio::buffer_sequence_begin(buffer_sequence),
  94. asio::buffer_sequence_end(buffer_sequence));
  95. }
  96. native_buffer_type* buffers()
  97. {
  98. return buffers_;
  99. }
  100. std::size_t count() const
  101. {
  102. return count_;
  103. }
  104. std::size_t total_size() const
  105. {
  106. return total_buffer_size_;
  107. }
  108. bool all_empty() const
  109. {
  110. return total_buffer_size_ == 0;
  111. }
  112. static bool all_empty(const Buffers& buffer_sequence)
  113. {
  114. return buffer_sequence_adapter::all_empty(
  115. asio::buffer_sequence_begin(buffer_sequence),
  116. asio::buffer_sequence_end(buffer_sequence));
  117. }
  118. static void validate(const Buffers& buffer_sequence)
  119. {
  120. buffer_sequence_adapter::validate(
  121. asio::buffer_sequence_begin(buffer_sequence),
  122. asio::buffer_sequence_end(buffer_sequence));
  123. }
  124. static Buffer first(const Buffers& buffer_sequence)
  125. {
  126. return buffer_sequence_adapter::first(
  127. asio::buffer_sequence_begin(buffer_sequence),
  128. asio::buffer_sequence_end(buffer_sequence));
  129. }
  130. private:
  131. template <typename Iterator>
  132. void init(Iterator begin, Iterator end)
  133. {
  134. Iterator iter = begin;
  135. for (; iter != end && count_ < max_buffers; ++iter, ++count_)
  136. {
  137. Buffer buffer(*iter);
  138. init_native_buffer(buffers_[count_], buffer);
  139. total_buffer_size_ += buffer.size();
  140. }
  141. }
  142. template <typename Iterator>
  143. static bool all_empty(Iterator begin, Iterator end)
  144. {
  145. Iterator iter = begin;
  146. std::size_t i = 0;
  147. for (; iter != end && i < max_buffers; ++iter, ++i)
  148. if (Buffer(*iter).size() > 0)
  149. return false;
  150. return true;
  151. }
  152. template <typename Iterator>
  153. static void validate(Iterator begin, Iterator end)
  154. {
  155. Iterator iter = begin;
  156. for (; iter != end; ++iter)
  157. {
  158. Buffer buffer(*iter);
  159. buffer.data();
  160. }
  161. }
  162. template <typename Iterator>
  163. static Buffer first(Iterator begin, Iterator end)
  164. {
  165. Iterator iter = begin;
  166. for (; iter != end; ++iter)
  167. {
  168. Buffer buffer(*iter);
  169. if (buffer.size() != 0)
  170. return buffer;
  171. }
  172. return Buffer();
  173. }
  174. native_buffer_type buffers_[max_buffers];
  175. std::size_t count_;
  176. std::size_t total_buffer_size_;
  177. };
  178. template <typename Buffer>
  179. class buffer_sequence_adapter<Buffer, asio::mutable_buffer>
  180. : buffer_sequence_adapter_base
  181. {
  182. public:
  183. explicit buffer_sequence_adapter(
  184. const asio::mutable_buffer& buffer_sequence)
  185. {
  186. init_native_buffer(buffer_, Buffer(buffer_sequence));
  187. total_buffer_size_ = buffer_sequence.size();
  188. }
  189. native_buffer_type* buffers()
  190. {
  191. return &buffer_;
  192. }
  193. std::size_t count() const
  194. {
  195. return 1;
  196. }
  197. std::size_t total_size() const
  198. {
  199. return total_buffer_size_;
  200. }
  201. bool all_empty() const
  202. {
  203. return total_buffer_size_ == 0;
  204. }
  205. static bool all_empty(const asio::mutable_buffer& buffer_sequence)
  206. {
  207. return buffer_sequence.size() == 0;
  208. }
  209. static void validate(const asio::mutable_buffer& buffer_sequence)
  210. {
  211. buffer_sequence.data();
  212. }
  213. static Buffer first(const asio::mutable_buffer& buffer_sequence)
  214. {
  215. return Buffer(buffer_sequence);
  216. }
  217. private:
  218. native_buffer_type buffer_;
  219. std::size_t total_buffer_size_;
  220. };
  221. template <typename Buffer>
  222. class buffer_sequence_adapter<Buffer, asio::const_buffer>
  223. : buffer_sequence_adapter_base
  224. {
  225. public:
  226. explicit buffer_sequence_adapter(
  227. const asio::const_buffer& buffer_sequence)
  228. {
  229. init_native_buffer(buffer_, Buffer(buffer_sequence));
  230. total_buffer_size_ = buffer_sequence.size();
  231. }
  232. native_buffer_type* buffers()
  233. {
  234. return &buffer_;
  235. }
  236. std::size_t count() const
  237. {
  238. return 1;
  239. }
  240. std::size_t total_size() const
  241. {
  242. return total_buffer_size_;
  243. }
  244. bool all_empty() const
  245. {
  246. return total_buffer_size_ == 0;
  247. }
  248. static bool all_empty(const asio::const_buffer& buffer_sequence)
  249. {
  250. return buffer_sequence.size() == 0;
  251. }
  252. static void validate(const asio::const_buffer& buffer_sequence)
  253. {
  254. buffer_sequence.data();
  255. }
  256. static Buffer first(const asio::const_buffer& buffer_sequence)
  257. {
  258. return Buffer(buffer_sequence);
  259. }
  260. private:
  261. native_buffer_type buffer_;
  262. std::size_t total_buffer_size_;
  263. };
  264. #if !defined(ASIO_NO_DEPRECATED)
  265. template <typename Buffer>
  266. class buffer_sequence_adapter<Buffer, asio::mutable_buffers_1>
  267. : buffer_sequence_adapter_base
  268. {
  269. public:
  270. explicit buffer_sequence_adapter(
  271. const asio::mutable_buffers_1& buffer_sequence)
  272. {
  273. init_native_buffer(buffer_, Buffer(buffer_sequence));
  274. total_buffer_size_ = buffer_sequence.size();
  275. }
  276. native_buffer_type* buffers()
  277. {
  278. return &buffer_;
  279. }
  280. std::size_t count() const
  281. {
  282. return 1;
  283. }
  284. std::size_t total_size() const
  285. {
  286. return total_buffer_size_;
  287. }
  288. bool all_empty() const
  289. {
  290. return total_buffer_size_ == 0;
  291. }
  292. static bool all_empty(const asio::mutable_buffers_1& buffer_sequence)
  293. {
  294. return buffer_sequence.size() == 0;
  295. }
  296. static void validate(const asio::mutable_buffers_1& buffer_sequence)
  297. {
  298. buffer_sequence.data();
  299. }
  300. static Buffer first(const asio::mutable_buffers_1& buffer_sequence)
  301. {
  302. return Buffer(buffer_sequence);
  303. }
  304. private:
  305. native_buffer_type buffer_;
  306. std::size_t total_buffer_size_;
  307. };
  308. template <typename Buffer>
  309. class buffer_sequence_adapter<Buffer, asio::const_buffers_1>
  310. : buffer_sequence_adapter_base
  311. {
  312. public:
  313. explicit buffer_sequence_adapter(
  314. const asio::const_buffers_1& buffer_sequence)
  315. {
  316. init_native_buffer(buffer_, Buffer(buffer_sequence));
  317. total_buffer_size_ = buffer_sequence.size();
  318. }
  319. native_buffer_type* buffers()
  320. {
  321. return &buffer_;
  322. }
  323. std::size_t count() const
  324. {
  325. return 1;
  326. }
  327. std::size_t total_size() const
  328. {
  329. return total_buffer_size_;
  330. }
  331. bool all_empty() const
  332. {
  333. return total_buffer_size_ == 0;
  334. }
  335. static bool all_empty(const asio::const_buffers_1& buffer_sequence)
  336. {
  337. return buffer_sequence.size() == 0;
  338. }
  339. static void validate(const asio::const_buffers_1& buffer_sequence)
  340. {
  341. buffer_sequence.data();
  342. }
  343. static Buffer first(const asio::const_buffers_1& buffer_sequence)
  344. {
  345. return Buffer(buffer_sequence);
  346. }
  347. private:
  348. native_buffer_type buffer_;
  349. std::size_t total_buffer_size_;
  350. };
  351. #endif // !defined(ASIO_NO_DEPRECATED)
  352. template <typename Buffer, typename Elem>
  353. class buffer_sequence_adapter<Buffer, boost::array<Elem, 2> >
  354. : buffer_sequence_adapter_base
  355. {
  356. public:
  357. explicit buffer_sequence_adapter(
  358. const boost::array<Elem, 2>& buffer_sequence)
  359. {
  360. init_native_buffer(buffers_[0], Buffer(buffer_sequence[0]));
  361. init_native_buffer(buffers_[1], Buffer(buffer_sequence[1]));
  362. total_buffer_size_ = buffer_sequence[0].size() + buffer_sequence[1].size();
  363. }
  364. native_buffer_type* buffers()
  365. {
  366. return buffers_;
  367. }
  368. std::size_t count() const
  369. {
  370. return 2;
  371. }
  372. std::size_t total_size() const
  373. {
  374. return total_buffer_size_;
  375. }
  376. bool all_empty() const
  377. {
  378. return total_buffer_size_ == 0;
  379. }
  380. static bool all_empty(const boost::array<Elem, 2>& buffer_sequence)
  381. {
  382. return buffer_sequence[0].size() == 0 && buffer_sequence[1].size() == 0;
  383. }
  384. static void validate(const boost::array<Elem, 2>& buffer_sequence)
  385. {
  386. buffer_sequence[0].data();
  387. buffer_sequence[1].data();
  388. }
  389. static Buffer first(const boost::array<Elem, 2>& buffer_sequence)
  390. {
  391. return Buffer(buffer_sequence[0].size() != 0
  392. ? buffer_sequence[0] : buffer_sequence[1]);
  393. }
  394. private:
  395. native_buffer_type buffers_[2];
  396. std::size_t total_buffer_size_;
  397. };
  398. #if defined(ASIO_HAS_STD_ARRAY)
  399. template <typename Buffer, typename Elem>
  400. class buffer_sequence_adapter<Buffer, std::array<Elem, 2> >
  401. : buffer_sequence_adapter_base
  402. {
  403. public:
  404. explicit buffer_sequence_adapter(
  405. const std::array<Elem, 2>& buffer_sequence)
  406. {
  407. init_native_buffer(buffers_[0], Buffer(buffer_sequence[0]));
  408. init_native_buffer(buffers_[1], Buffer(buffer_sequence[1]));
  409. total_buffer_size_ = buffer_sequence[0].size() + buffer_sequence[1].size();
  410. }
  411. native_buffer_type* buffers()
  412. {
  413. return buffers_;
  414. }
  415. std::size_t count() const
  416. {
  417. return 2;
  418. }
  419. std::size_t total_size() const
  420. {
  421. return total_buffer_size_;
  422. }
  423. bool all_empty() const
  424. {
  425. return total_buffer_size_ == 0;
  426. }
  427. static bool all_empty(const std::array<Elem, 2>& buffer_sequence)
  428. {
  429. return buffer_sequence[0].size() == 0 && buffer_sequence[1].size() == 0;
  430. }
  431. static void validate(const std::array<Elem, 2>& buffer_sequence)
  432. {
  433. buffer_sequence[0].data();
  434. buffer_sequence[1].data();
  435. }
  436. static Buffer first(const std::array<Elem, 2>& buffer_sequence)
  437. {
  438. return Buffer(buffer_sequence[0].size() != 0
  439. ? buffer_sequence[0] : buffer_sequence[1]);
  440. }
  441. private:
  442. native_buffer_type buffers_[2];
  443. std::size_t total_buffer_size_;
  444. };
  445. #endif // defined(ASIO_HAS_STD_ARRAY)
  446. } // namespace detail
  447. } // namespace asio
  448. #include "asio/detail/pop_options.hpp"
  449. #if defined(ASIO_HEADER_ONLY)
  450. # include "asio/detail/impl/buffer_sequence_adapter.ipp"
  451. #endif // defined(ASIO_HEADER_ONLY)
  452. #endif // ASIO_DETAIL_BUFFER_SEQUENCE_ADAPTER_HPP