buffers_prefix.hpp 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. //
  2. // Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
  3. //
  4. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  5. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. //
  7. // Official repository: https://github.com/boostorg/beast
  8. //
  9. #ifndef BOOST_BEAST_BUFFERS_PREFIX_HPP
  10. #define BOOST_BEAST_BUFFERS_PREFIX_HPP
  11. #include <boost/beast/core/detail/config.hpp>
  12. #include <boost/beast/core/buffer_traits.hpp>
  13. #include <boost/optional/optional.hpp> // for in_place_init_t
  14. #include <algorithm>
  15. #include <cstdint>
  16. #include <type_traits>
  17. #if BOOST_WORKAROUND(BOOST_MSVC, < 1910)
  18. #include <boost/type_traits.hpp>
  19. #endif
  20. namespace boost {
  21. namespace beast {
  22. /** A buffer sequence adaptor that shortens the sequence size.
  23. The class adapts a buffer sequence to efficiently represent
  24. a shorter subset of the original list of buffers starting
  25. with the first byte of the original sequence.
  26. @tparam BufferSequence The buffer sequence to adapt.
  27. */
  28. template<class BufferSequence>
  29. class buffers_prefix_view
  30. {
  31. using iter_type =
  32. buffers_iterator_type<BufferSequence>;
  33. BufferSequence bs_;
  34. std::size_t size_ = 0;
  35. std::size_t remain_ = 0;
  36. iter_type end_{};
  37. void
  38. setup(std::size_t size);
  39. buffers_prefix_view(
  40. buffers_prefix_view const& other,
  41. std::size_t dist);
  42. public:
  43. /** The type for each element in the list of buffers.
  44. If the type `BufferSequence` meets the requirements of
  45. <em>MutableBufferSequence</em>, then `value_type` is
  46. `net::mutable_buffer`. Otherwise, `value_type` is
  47. `net::const_buffer`.
  48. @see buffers_type
  49. */
  50. #if BOOST_BEAST_DOXYGEN
  51. using value_type = __see_below__;
  52. #elif BOOST_WORKAROUND(BOOST_MSVC, < 1910)
  53. using value_type = typename std::conditional<
  54. boost::is_convertible<typename
  55. std::iterator_traits<iter_type>::value_type,
  56. net::mutable_buffer>::value,
  57. net::mutable_buffer,
  58. net::const_buffer>::type;
  59. #else
  60. using value_type = buffers_type<BufferSequence>;
  61. #endif
  62. #if BOOST_BEAST_DOXYGEN
  63. /// A bidirectional iterator type that may be used to read elements.
  64. using const_iterator = __implementation_defined__;
  65. #else
  66. class const_iterator;
  67. #endif
  68. /// Copy Constructor
  69. buffers_prefix_view(buffers_prefix_view const&);
  70. /// Copy Assignment
  71. buffers_prefix_view& operator=(buffers_prefix_view const&);
  72. /** Construct a buffer sequence prefix.
  73. @param size The maximum number of bytes in the prefix.
  74. If this is larger than the size of passed buffers,
  75. the resulting sequence will represent the entire
  76. input sequence.
  77. @param buffers The buffer sequence to adapt. A copy of
  78. the sequence will be made, but ownership of the underlying
  79. memory is not transferred. The copy is maintained for
  80. the lifetime of the view.
  81. */
  82. buffers_prefix_view(
  83. std::size_t size,
  84. BufferSequence const& buffers);
  85. /** Construct a buffer sequence prefix in-place.
  86. @param size The maximum number of bytes in the prefix.
  87. If this is larger than the size of passed buffers,
  88. the resulting sequence will represent the entire
  89. input sequence.
  90. @param args Arguments forwarded to the contained buffer's constructor.
  91. */
  92. template<class... Args>
  93. buffers_prefix_view(
  94. std::size_t size,
  95. boost::in_place_init_t,
  96. Args&&... args);
  97. /// Returns an iterator to the first buffer in the sequence
  98. const_iterator
  99. begin() const;
  100. /// Returns an iterator to one past the last buffer in the sequence
  101. const_iterator
  102. end() const;
  103. #if ! BOOST_BEAST_DOXYGEN
  104. std::size_t
  105. buffer_bytes_impl() const noexcept
  106. {
  107. return size_;
  108. }
  109. #endif
  110. };
  111. //------------------------------------------------------------------------------
  112. /** Returns a prefix of a constant or mutable buffer sequence.
  113. The returned buffer sequence points to the same memory as the
  114. passed buffer sequence, but with a size that is equal to or
  115. smaller. No memory allocations are performed; the resulting
  116. sequence is calculated as a lazy range.
  117. @param size The maximum size of the returned buffer sequence
  118. in bytes. If this is greater than or equal to the size of
  119. the passed buffer sequence, the result will have the same
  120. size as the original buffer sequence.
  121. @param buffers An object whose type meets the requirements
  122. of <em>BufferSequence</em>. The returned value will
  123. maintain a copy of the passed buffers for its lifetime;
  124. however, ownership of the underlying memory is not
  125. transferred.
  126. @return A constant buffer sequence that represents the prefix
  127. of the original buffer sequence. If the original buffer sequence
  128. also meets the requirements of <em>MutableBufferSequence</em>,
  129. then the returned value will also be a mutable buffer sequence.
  130. */
  131. template<class BufferSequence>
  132. buffers_prefix_view<BufferSequence>
  133. buffers_prefix(
  134. std::size_t size, BufferSequence const& buffers)
  135. {
  136. static_assert(
  137. net::is_const_buffer_sequence<BufferSequence>::value,
  138. "BufferSequence type requirements not met");
  139. return buffers_prefix_view<BufferSequence>(size, buffers);
  140. }
  141. /** Returns the first buffer in a buffer sequence
  142. This returns the first buffer in the buffer sequence.
  143. If the buffer sequence is an empty range, the returned
  144. buffer will have a zero buffer size.
  145. @param buffers The buffer sequence. If the sequence is
  146. mutable, the returned buffer sequence will also be mutable.
  147. Otherwise, the returned buffer sequence will be constant.
  148. */
  149. template<class BufferSequence>
  150. buffers_type<BufferSequence>
  151. buffers_front(BufferSequence const& buffers)
  152. {
  153. auto const first =
  154. net::buffer_sequence_begin(buffers);
  155. if(first == net::buffer_sequence_end(buffers))
  156. return {};
  157. return *first;
  158. }
  159. } // beast
  160. } // boost
  161. #include <boost/beast/core/impl/buffers_prefix.hpp>
  162. #endif