buffer_sequence_adapter.hpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837
  1. //
  2. // detail/buffer_sequence_adapter.hpp
  3. // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  4. //
  5. // Copyright (c) 2003-2023 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/registered_buffer.hpp"
  20. #include "asio/detail/push_options.hpp"
  21. namespace asio {
  22. namespace detail {
  23. class buffer_sequence_adapter_base
  24. {
  25. #if defined(ASIO_WINDOWS_RUNTIME)
  26. public:
  27. // The maximum number of buffers to support in a single operation.
  28. enum { max_buffers = 1 };
  29. protected:
  30. typedef Windows::Storage::Streams::IBuffer^ native_buffer_type;
  31. ASIO_DECL static void init_native_buffer(
  32. native_buffer_type& buf,
  33. const asio::mutable_buffer& buffer);
  34. ASIO_DECL static void init_native_buffer(
  35. native_buffer_type& buf,
  36. const asio::const_buffer& buffer);
  37. #elif defined(ASIO_WINDOWS) || defined(__CYGWIN__)
  38. public:
  39. // The maximum number of buffers to support in a single operation.
  40. enum { max_buffers = 64 < max_iov_len ? 64 : max_iov_len };
  41. protected:
  42. typedef WSABUF native_buffer_type;
  43. static void init_native_buffer(WSABUF& buf,
  44. const asio::mutable_buffer& buffer)
  45. {
  46. buf.buf = static_cast<char*>(buffer.data());
  47. buf.len = static_cast<ULONG>(buffer.size());
  48. }
  49. static void init_native_buffer(WSABUF& buf,
  50. const asio::const_buffer& buffer)
  51. {
  52. buf.buf = const_cast<char*>(static_cast<const char*>(buffer.data()));
  53. buf.len = static_cast<ULONG>(buffer.size());
  54. }
  55. #else // defined(ASIO_WINDOWS) || defined(__CYGWIN__)
  56. public:
  57. // The maximum number of buffers to support in a single operation.
  58. enum { max_buffers = 64 < max_iov_len ? 64 : max_iov_len };
  59. protected:
  60. typedef iovec native_buffer_type;
  61. static void init_iov_base(void*& base, void* addr)
  62. {
  63. base = addr;
  64. }
  65. template <typename T>
  66. static void init_iov_base(T& base, void* addr)
  67. {
  68. base = static_cast<T>(addr);
  69. }
  70. static void init_native_buffer(iovec& iov,
  71. const asio::mutable_buffer& buffer)
  72. {
  73. init_iov_base(iov.iov_base, buffer.data());
  74. iov.iov_len = buffer.size();
  75. }
  76. static void init_native_buffer(iovec& iov,
  77. const asio::const_buffer& buffer)
  78. {
  79. init_iov_base(iov.iov_base, const_cast<void*>(buffer.data()));
  80. iov.iov_len = buffer.size();
  81. }
  82. #endif // defined(ASIO_WINDOWS) || defined(__CYGWIN__)
  83. };
  84. // Helper class to translate buffers into the native buffer representation.
  85. template <typename Buffer, typename Buffers>
  86. class buffer_sequence_adapter
  87. : buffer_sequence_adapter_base
  88. {
  89. public:
  90. enum { is_single_buffer = false };
  91. enum { is_registered_buffer = false };
  92. explicit buffer_sequence_adapter(const Buffers& buffer_sequence)
  93. : count_(0), total_buffer_size_(0)
  94. {
  95. buffer_sequence_adapter::init(
  96. asio::buffer_sequence_begin(buffer_sequence),
  97. asio::buffer_sequence_end(buffer_sequence));
  98. }
  99. native_buffer_type* buffers()
  100. {
  101. return buffers_;
  102. }
  103. std::size_t count() const
  104. {
  105. return count_;
  106. }
  107. std::size_t total_size() const
  108. {
  109. return total_buffer_size_;
  110. }
  111. registered_buffer_id registered_id() const
  112. {
  113. return registered_buffer_id();
  114. }
  115. bool all_empty() const
  116. {
  117. return total_buffer_size_ == 0;
  118. }
  119. static bool all_empty(const Buffers& buffer_sequence)
  120. {
  121. return buffer_sequence_adapter::all_empty(
  122. asio::buffer_sequence_begin(buffer_sequence),
  123. asio::buffer_sequence_end(buffer_sequence));
  124. }
  125. static void validate(const Buffers& buffer_sequence)
  126. {
  127. buffer_sequence_adapter::validate(
  128. asio::buffer_sequence_begin(buffer_sequence),
  129. asio::buffer_sequence_end(buffer_sequence));
  130. }
  131. static Buffer first(const Buffers& buffer_sequence)
  132. {
  133. return buffer_sequence_adapter::first(
  134. asio::buffer_sequence_begin(buffer_sequence),
  135. asio::buffer_sequence_end(buffer_sequence));
  136. }
  137. enum { linearisation_storage_size = 8192 };
  138. static Buffer linearise(const Buffers& buffer_sequence,
  139. const asio::mutable_buffer& storage)
  140. {
  141. return buffer_sequence_adapter::linearise(
  142. asio::buffer_sequence_begin(buffer_sequence),
  143. asio::buffer_sequence_end(buffer_sequence), storage);
  144. }
  145. private:
  146. template <typename Iterator>
  147. void init(Iterator begin, Iterator end)
  148. {
  149. Iterator iter = begin;
  150. for (; iter != end && count_ < max_buffers; ++iter, ++count_)
  151. {
  152. Buffer buffer(*iter);
  153. init_native_buffer(buffers_[count_], buffer);
  154. total_buffer_size_ += buffer.size();
  155. }
  156. }
  157. template <typename Iterator>
  158. static bool all_empty(Iterator begin, Iterator end)
  159. {
  160. Iterator iter = begin;
  161. std::size_t i = 0;
  162. for (; iter != end && i < max_buffers; ++iter, ++i)
  163. if (Buffer(*iter).size() > 0)
  164. return false;
  165. return true;
  166. }
  167. template <typename Iterator>
  168. static void validate(Iterator begin, Iterator end)
  169. {
  170. Iterator iter = begin;
  171. for (; iter != end; ++iter)
  172. {
  173. Buffer buffer(*iter);
  174. buffer.data();
  175. }
  176. }
  177. template <typename Iterator>
  178. static Buffer first(Iterator begin, Iterator end)
  179. {
  180. Iterator iter = begin;
  181. for (; iter != end; ++iter)
  182. {
  183. Buffer buffer(*iter);
  184. if (buffer.size() != 0)
  185. return buffer;
  186. }
  187. return Buffer();
  188. }
  189. template <typename Iterator>
  190. static Buffer linearise(Iterator begin, Iterator end,
  191. const asio::mutable_buffer& storage)
  192. {
  193. asio::mutable_buffer unused_storage = storage;
  194. Iterator iter = begin;
  195. while (iter != end && unused_storage.size() != 0)
  196. {
  197. Buffer buffer(*iter);
  198. ++iter;
  199. if (buffer.size() == 0)
  200. continue;
  201. if (unused_storage.size() == storage.size())
  202. {
  203. if (iter == end)
  204. return buffer;
  205. if (buffer.size() >= unused_storage.size())
  206. return buffer;
  207. }
  208. unused_storage += asio::buffer_copy(unused_storage, buffer);
  209. }
  210. return Buffer(storage.data(), storage.size() - unused_storage.size());
  211. }
  212. native_buffer_type buffers_[max_buffers];
  213. std::size_t count_;
  214. std::size_t total_buffer_size_;
  215. };
  216. template <typename Buffer>
  217. class buffer_sequence_adapter<Buffer, asio::mutable_buffer>
  218. : buffer_sequence_adapter_base
  219. {
  220. public:
  221. enum { is_single_buffer = true };
  222. enum { is_registered_buffer = false };
  223. explicit buffer_sequence_adapter(
  224. const asio::mutable_buffer& buffer_sequence)
  225. {
  226. init_native_buffer(buffer_, Buffer(buffer_sequence));
  227. total_buffer_size_ = buffer_sequence.size();
  228. }
  229. native_buffer_type* buffers()
  230. {
  231. return &buffer_;
  232. }
  233. std::size_t count() const
  234. {
  235. return 1;
  236. }
  237. std::size_t total_size() const
  238. {
  239. return total_buffer_size_;
  240. }
  241. registered_buffer_id registered_id() const
  242. {
  243. return registered_buffer_id();
  244. }
  245. bool all_empty() const
  246. {
  247. return total_buffer_size_ == 0;
  248. }
  249. static bool all_empty(const asio::mutable_buffer& buffer_sequence)
  250. {
  251. return buffer_sequence.size() == 0;
  252. }
  253. static void validate(const asio::mutable_buffer& buffer_sequence)
  254. {
  255. buffer_sequence.data();
  256. }
  257. static Buffer first(const asio::mutable_buffer& buffer_sequence)
  258. {
  259. return Buffer(buffer_sequence);
  260. }
  261. enum { linearisation_storage_size = 1 };
  262. static Buffer linearise(const asio::mutable_buffer& buffer_sequence,
  263. const Buffer&)
  264. {
  265. return Buffer(buffer_sequence);
  266. }
  267. private:
  268. native_buffer_type buffer_;
  269. std::size_t total_buffer_size_;
  270. };
  271. template <typename Buffer>
  272. class buffer_sequence_adapter<Buffer, asio::const_buffer>
  273. : buffer_sequence_adapter_base
  274. {
  275. public:
  276. enum { is_single_buffer = true };
  277. enum { is_registered_buffer = false };
  278. explicit buffer_sequence_adapter(
  279. const asio::const_buffer& buffer_sequence)
  280. {
  281. init_native_buffer(buffer_, Buffer(buffer_sequence));
  282. total_buffer_size_ = buffer_sequence.size();
  283. }
  284. native_buffer_type* buffers()
  285. {
  286. return &buffer_;
  287. }
  288. std::size_t count() const
  289. {
  290. return 1;
  291. }
  292. std::size_t total_size() const
  293. {
  294. return total_buffer_size_;
  295. }
  296. registered_buffer_id registered_id() const
  297. {
  298. return registered_buffer_id();
  299. }
  300. bool all_empty() const
  301. {
  302. return total_buffer_size_ == 0;
  303. }
  304. static bool all_empty(const asio::const_buffer& buffer_sequence)
  305. {
  306. return buffer_sequence.size() == 0;
  307. }
  308. static void validate(const asio::const_buffer& buffer_sequence)
  309. {
  310. buffer_sequence.data();
  311. }
  312. static Buffer first(const asio::const_buffer& buffer_sequence)
  313. {
  314. return Buffer(buffer_sequence);
  315. }
  316. enum { linearisation_storage_size = 1 };
  317. static Buffer linearise(const asio::const_buffer& buffer_sequence,
  318. const Buffer&)
  319. {
  320. return Buffer(buffer_sequence);
  321. }
  322. private:
  323. native_buffer_type buffer_;
  324. std::size_t total_buffer_size_;
  325. };
  326. #if !defined(ASIO_NO_DEPRECATED)
  327. template <typename Buffer>
  328. class buffer_sequence_adapter<Buffer, asio::mutable_buffers_1>
  329. : buffer_sequence_adapter_base
  330. {
  331. public:
  332. enum { is_single_buffer = true };
  333. enum { is_registered_buffer = false };
  334. explicit buffer_sequence_adapter(
  335. const asio::mutable_buffers_1& buffer_sequence)
  336. {
  337. init_native_buffer(buffer_, Buffer(buffer_sequence));
  338. total_buffer_size_ = buffer_sequence.size();
  339. }
  340. native_buffer_type* buffers()
  341. {
  342. return &buffer_;
  343. }
  344. std::size_t count() const
  345. {
  346. return 1;
  347. }
  348. std::size_t total_size() const
  349. {
  350. return total_buffer_size_;
  351. }
  352. registered_buffer_id registered_id() const
  353. {
  354. return registered_buffer_id();
  355. }
  356. bool all_empty() const
  357. {
  358. return total_buffer_size_ == 0;
  359. }
  360. static bool all_empty(const asio::mutable_buffers_1& buffer_sequence)
  361. {
  362. return buffer_sequence.size() == 0;
  363. }
  364. static void validate(const asio::mutable_buffers_1& buffer_sequence)
  365. {
  366. buffer_sequence.data();
  367. }
  368. static Buffer first(const asio::mutable_buffers_1& buffer_sequence)
  369. {
  370. return Buffer(buffer_sequence);
  371. }
  372. enum { linearisation_storage_size = 1 };
  373. static Buffer linearise(const asio::mutable_buffers_1& buffer_sequence,
  374. const Buffer&)
  375. {
  376. return Buffer(buffer_sequence);
  377. }
  378. private:
  379. native_buffer_type buffer_;
  380. std::size_t total_buffer_size_;
  381. };
  382. template <typename Buffer>
  383. class buffer_sequence_adapter<Buffer, asio::const_buffers_1>
  384. : buffer_sequence_adapter_base
  385. {
  386. public:
  387. enum { is_single_buffer = true };
  388. enum { is_registered_buffer = false };
  389. explicit buffer_sequence_adapter(
  390. const asio::const_buffers_1& buffer_sequence)
  391. {
  392. init_native_buffer(buffer_, Buffer(buffer_sequence));
  393. total_buffer_size_ = buffer_sequence.size();
  394. }
  395. native_buffer_type* buffers()
  396. {
  397. return &buffer_;
  398. }
  399. std::size_t count() const
  400. {
  401. return 1;
  402. }
  403. std::size_t total_size() const
  404. {
  405. return total_buffer_size_;
  406. }
  407. registered_buffer_id registered_id() const
  408. {
  409. return registered_buffer_id();
  410. }
  411. bool all_empty() const
  412. {
  413. return total_buffer_size_ == 0;
  414. }
  415. static bool all_empty(const asio::const_buffers_1& buffer_sequence)
  416. {
  417. return buffer_sequence.size() == 0;
  418. }
  419. static void validate(const asio::const_buffers_1& buffer_sequence)
  420. {
  421. buffer_sequence.data();
  422. }
  423. static Buffer first(const asio::const_buffers_1& buffer_sequence)
  424. {
  425. return Buffer(buffer_sequence);
  426. }
  427. enum { linearisation_storage_size = 1 };
  428. static Buffer linearise(const asio::const_buffers_1& buffer_sequence,
  429. const Buffer&)
  430. {
  431. return Buffer(buffer_sequence);
  432. }
  433. private:
  434. native_buffer_type buffer_;
  435. std::size_t total_buffer_size_;
  436. };
  437. #endif // !defined(ASIO_NO_DEPRECATED)
  438. template <typename Buffer>
  439. class buffer_sequence_adapter<Buffer, asio::mutable_registered_buffer>
  440. : buffer_sequence_adapter_base
  441. {
  442. public:
  443. enum { is_single_buffer = true };
  444. enum { is_registered_buffer = true };
  445. explicit buffer_sequence_adapter(
  446. const asio::mutable_registered_buffer& buffer_sequence)
  447. {
  448. init_native_buffer(buffer_, buffer_sequence.buffer());
  449. total_buffer_size_ = buffer_sequence.size();
  450. registered_id_ = buffer_sequence.id();
  451. }
  452. native_buffer_type* buffers()
  453. {
  454. return &buffer_;
  455. }
  456. std::size_t count() const
  457. {
  458. return 1;
  459. }
  460. std::size_t total_size() const
  461. {
  462. return total_buffer_size_;
  463. }
  464. registered_buffer_id registered_id() const
  465. {
  466. return registered_id_;
  467. }
  468. bool all_empty() const
  469. {
  470. return total_buffer_size_ == 0;
  471. }
  472. static bool all_empty(
  473. const asio::mutable_registered_buffer& buffer_sequence)
  474. {
  475. return buffer_sequence.size() == 0;
  476. }
  477. static void validate(
  478. const asio::mutable_registered_buffer& buffer_sequence)
  479. {
  480. buffer_sequence.data();
  481. }
  482. static Buffer first(
  483. const asio::mutable_registered_buffer& buffer_sequence)
  484. {
  485. return Buffer(buffer_sequence.buffer());
  486. }
  487. enum { linearisation_storage_size = 1 };
  488. static Buffer linearise(
  489. const asio::mutable_registered_buffer& buffer_sequence,
  490. const Buffer&)
  491. {
  492. return Buffer(buffer_sequence.buffer());
  493. }
  494. private:
  495. native_buffer_type buffer_;
  496. std::size_t total_buffer_size_;
  497. registered_buffer_id registered_id_;
  498. };
  499. template <typename Buffer>
  500. class buffer_sequence_adapter<Buffer, asio::const_registered_buffer>
  501. : buffer_sequence_adapter_base
  502. {
  503. public:
  504. enum { is_single_buffer = true };
  505. enum { is_registered_buffer = true };
  506. explicit buffer_sequence_adapter(
  507. const asio::const_registered_buffer& buffer_sequence)
  508. {
  509. init_native_buffer(buffer_, buffer_sequence.buffer());
  510. total_buffer_size_ = buffer_sequence.size();
  511. registered_id_ = buffer_sequence.id();
  512. }
  513. native_buffer_type* buffers()
  514. {
  515. return &buffer_;
  516. }
  517. std::size_t count() const
  518. {
  519. return 1;
  520. }
  521. std::size_t total_size() const
  522. {
  523. return total_buffer_size_;
  524. }
  525. registered_buffer_id registered_id() const
  526. {
  527. return registered_id_;
  528. }
  529. bool all_empty() const
  530. {
  531. return total_buffer_size_ == 0;
  532. }
  533. static bool all_empty(
  534. const asio::const_registered_buffer& buffer_sequence)
  535. {
  536. return buffer_sequence.size() == 0;
  537. }
  538. static void validate(
  539. const asio::const_registered_buffer& buffer_sequence)
  540. {
  541. buffer_sequence.data();
  542. }
  543. static Buffer first(
  544. const asio::const_registered_buffer& buffer_sequence)
  545. {
  546. return Buffer(buffer_sequence.buffer());
  547. }
  548. enum { linearisation_storage_size = 1 };
  549. static Buffer linearise(
  550. const asio::const_registered_buffer& buffer_sequence,
  551. const Buffer&)
  552. {
  553. return Buffer(buffer_sequence.buffer());
  554. }
  555. private:
  556. native_buffer_type buffer_;
  557. std::size_t total_buffer_size_;
  558. registered_buffer_id registered_id_;
  559. };
  560. template <typename Buffer, typename Elem>
  561. class buffer_sequence_adapter<Buffer, boost::array<Elem, 2>>
  562. : buffer_sequence_adapter_base
  563. {
  564. public:
  565. enum { is_single_buffer = false };
  566. enum { is_registered_buffer = false };
  567. explicit buffer_sequence_adapter(
  568. const boost::array<Elem, 2>& buffer_sequence)
  569. {
  570. init_native_buffer(buffers_[0], Buffer(buffer_sequence[0]));
  571. init_native_buffer(buffers_[1], Buffer(buffer_sequence[1]));
  572. total_buffer_size_ = buffer_sequence[0].size() + buffer_sequence[1].size();
  573. }
  574. native_buffer_type* buffers()
  575. {
  576. return buffers_;
  577. }
  578. std::size_t count() const
  579. {
  580. return 2;
  581. }
  582. std::size_t total_size() const
  583. {
  584. return total_buffer_size_;
  585. }
  586. registered_buffer_id registered_id() const
  587. {
  588. return registered_buffer_id();
  589. }
  590. bool all_empty() const
  591. {
  592. return total_buffer_size_ == 0;
  593. }
  594. static bool all_empty(const boost::array<Elem, 2>& buffer_sequence)
  595. {
  596. return buffer_sequence[0].size() == 0 && buffer_sequence[1].size() == 0;
  597. }
  598. static void validate(const boost::array<Elem, 2>& buffer_sequence)
  599. {
  600. buffer_sequence[0].data();
  601. buffer_sequence[1].data();
  602. }
  603. static Buffer first(const boost::array<Elem, 2>& buffer_sequence)
  604. {
  605. return Buffer(buffer_sequence[0].size() != 0
  606. ? buffer_sequence[0] : buffer_sequence[1]);
  607. }
  608. enum { linearisation_storage_size = 8192 };
  609. static Buffer linearise(const boost::array<Elem, 2>& buffer_sequence,
  610. const asio::mutable_buffer& storage)
  611. {
  612. if (buffer_sequence[0].size() == 0)
  613. return Buffer(buffer_sequence[1]);
  614. if (buffer_sequence[1].size() == 0)
  615. return Buffer(buffer_sequence[0]);
  616. return Buffer(storage.data(),
  617. asio::buffer_copy(storage, buffer_sequence));
  618. }
  619. private:
  620. native_buffer_type buffers_[2];
  621. std::size_t total_buffer_size_;
  622. };
  623. template <typename Buffer, typename Elem>
  624. class buffer_sequence_adapter<Buffer, std::array<Elem, 2>>
  625. : buffer_sequence_adapter_base
  626. {
  627. public:
  628. enum { is_single_buffer = false };
  629. enum { is_registered_buffer = false };
  630. explicit buffer_sequence_adapter(
  631. const std::array<Elem, 2>& buffer_sequence)
  632. {
  633. init_native_buffer(buffers_[0], Buffer(buffer_sequence[0]));
  634. init_native_buffer(buffers_[1], Buffer(buffer_sequence[1]));
  635. total_buffer_size_ = buffer_sequence[0].size() + buffer_sequence[1].size();
  636. }
  637. native_buffer_type* buffers()
  638. {
  639. return buffers_;
  640. }
  641. std::size_t count() const
  642. {
  643. return 2;
  644. }
  645. std::size_t total_size() const
  646. {
  647. return total_buffer_size_;
  648. }
  649. registered_buffer_id registered_id() const
  650. {
  651. return registered_buffer_id();
  652. }
  653. bool all_empty() const
  654. {
  655. return total_buffer_size_ == 0;
  656. }
  657. static bool all_empty(const std::array<Elem, 2>& buffer_sequence)
  658. {
  659. return buffer_sequence[0].size() == 0 && buffer_sequence[1].size() == 0;
  660. }
  661. static void validate(const std::array<Elem, 2>& buffer_sequence)
  662. {
  663. buffer_sequence[0].data();
  664. buffer_sequence[1].data();
  665. }
  666. static Buffer first(const std::array<Elem, 2>& buffer_sequence)
  667. {
  668. return Buffer(buffer_sequence[0].size() != 0
  669. ? buffer_sequence[0] : buffer_sequence[1]);
  670. }
  671. enum { linearisation_storage_size = 8192 };
  672. static Buffer linearise(const std::array<Elem, 2>& buffer_sequence,
  673. const asio::mutable_buffer& storage)
  674. {
  675. if (buffer_sequence[0].size() == 0)
  676. return Buffer(buffer_sequence[1]);
  677. if (buffer_sequence[1].size() == 0)
  678. return Buffer(buffer_sequence[0]);
  679. return Buffer(storage.data(),
  680. asio::buffer_copy(storage, buffer_sequence));
  681. }
  682. private:
  683. native_buffer_type buffers_[2];
  684. std::size_t total_buffer_size_;
  685. };
  686. } // namespace detail
  687. } // namespace asio
  688. #include "asio/detail/pop_options.hpp"
  689. #if defined(ASIO_HEADER_ONLY)
  690. # include "asio/detail/impl/buffer_sequence_adapter.ipp"
  691. #endif // defined(ASIO_HEADER_ONLY)
  692. #endif // ASIO_DETAIL_BUFFER_SEQUENCE_ADAPTER_HPP