buffer_ref.hpp 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. //
  2. // Copyright (c) 2022 Klemens D. Morgenstern (klemens dot morgenstern at gmx dot net)
  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. #ifndef BOOST_BEAST_BUFFER_REF_HPP
  7. #define BOOST_BEAST_BUFFER_REF_HPP
  8. #include <cstddef>
  9. namespace boost {
  10. namespace beast {
  11. #if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
  12. /** The buffer ref provides a wrapper around beast buffers
  13. * to make them usable with asio dynamic_buffer v1.
  14. *
  15. * v2 is current not supported, so that
  16. * `BOOST_ASIO_NO_DYNAMIC_BUFFER_V1` mustn't be defined.
  17. *
  18. * @par Example
  19. *
  20. * @code
  21. *
  22. * asio::tcp::socket sock;
  23. * beast::flat_buffer fb;
  24. * asio::read_until(sock, ref(fb) '\n');
  25. *
  26. * @endcode
  27. *
  28. * @tparam Buffer The underlying buffer
  29. */
  30. template<typename Buffer>
  31. struct buffer_ref
  32. {
  33. /// The ConstBufferSequence used to represent the readable bytes.
  34. using const_buffers_type = typename Buffer::const_buffers_type;
  35. /// The MutableBufferSequence used to represent the writable bytes.
  36. using mutable_buffers_type = typename Buffer::mutable_buffers_type;
  37. /// Returns the number of readable bytes.
  38. std::size_t
  39. size() const noexcept
  40. {
  41. return buffer_.size();
  42. }
  43. /// Return the maximum number of bytes, both readable and writable, that can ever be held.
  44. std::size_t
  45. max_size() const noexcept
  46. {
  47. return buffer_.max_size();
  48. }
  49. /// Return the maximum number of bytes, both readable and writable, that can be held without requiring an allocation.
  50. std::size_t
  51. capacity() const noexcept
  52. {
  53. return buffer_.capacity();
  54. }
  55. /// Returns a constant buffer sequence representing the readable bytes
  56. const_buffers_type
  57. data() const noexcept
  58. {
  59. return buffer_.data();
  60. }
  61. /// Get a list of buffers that represents the output
  62. /// sequence, with the given size.
  63. /**
  64. * Ensures that the output sequence can accommodate @c n bytes, resizing the
  65. * vector object as necessary.
  66. *
  67. * @returns An object of type @c mutable_buffers_type that satisfies
  68. * MutableBufferSequence requirements, representing vector memory at the
  69. * start of the output sequence of size @c n.
  70. *
  71. * @throws std::length_error If <tt>size() + n > max_size()</tt>.
  72. *
  73. * @note The returned object is invalidated by any @c dynamic_vector_buffer
  74. * or @c vector member function that modifies the input sequence or output
  75. * sequence.
  76. */
  77. mutable_buffers_type prepare(std::size_t n)
  78. {
  79. return buffer_.prepare(n);
  80. }
  81. /// Move bytes from the output sequence to the input
  82. /// sequence.
  83. /**
  84. * @param n The number of bytes to append from the start of the output
  85. * sequence to the end of the input sequence. The remainder of the output
  86. * sequence is discarded.
  87. *
  88. * Requires a preceding call <tt>prepare(x)</tt> where <tt>x >= n</tt>, and
  89. * no intervening operations that modify the input or output sequence.
  90. *
  91. * @note If @c n is greater than the size of the output sequence, the entire
  92. * output sequence is moved to the input sequence and no error is issued.
  93. */
  94. void commit(std::size_t n)
  95. {
  96. return buffer_.commit(n);
  97. }
  98. /// Remove `n` bytes from the readable byte sequence.
  99. /**
  100. * @b DynamicBuffer_v1: Removes @c n characters from the beginning of the
  101. * input sequence. @note If @c n is greater than the size of the input
  102. * sequence, the entire input sequence is consumed and no error is issued.
  103. */
  104. void consume(std::size_t n)
  105. {
  106. return buffer_.consume(n);
  107. }
  108. /// The type of the underlying buffer.
  109. using buffer_type = Buffer;
  110. /// Create a buffer reference around @c buffer.
  111. buffer_ref(Buffer & buffer) : buffer_(buffer) {}
  112. /// Copy the reference.
  113. buffer_ref(const buffer_ref& buffer) = default;
  114. private:
  115. Buffer &buffer_;
  116. };
  117. template<class Allocator>
  118. class basic_flat_buffer;
  119. template<std::size_t N>
  120. class flat_static_buffer;
  121. template<class Allocator>
  122. class basic_multi_buffer;
  123. template<std::size_t N>
  124. class static_buffer;
  125. /// Create a buffer_ref for basic_flat_buffer.
  126. template<class Allocator>
  127. inline buffer_ref<basic_flat_buffer<Allocator>> ref(basic_flat_buffer<Allocator> & buf)
  128. {
  129. return buffer_ref<basic_flat_buffer<Allocator>>(buf);
  130. }
  131. /// Create a buffer_ref for flat_static_buffer.
  132. template<std::size_t N>
  133. inline buffer_ref<flat_static_buffer<N>> ref(flat_static_buffer<N> & buf)
  134. {
  135. return buffer_ref<flat_static_buffer<N>>(buf);
  136. }
  137. /// Create a buffer_ref for basic_multi_buffer.
  138. template<class Allocator>
  139. inline buffer_ref<basic_multi_buffer<Allocator>> ref(basic_multi_buffer<Allocator> & buf)
  140. {
  141. return buffer_ref<basic_multi_buffer<Allocator>>(buf);
  142. }
  143. /// Create a buffer_ref for static_buffer.
  144. template<std::size_t N>
  145. inline buffer_ref<static_buffer<N>> ref(static_buffer<N> & buf)
  146. {
  147. return buffer_ref<static_buffer<N>>(buf);
  148. }
  149. #endif // !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
  150. }
  151. }
  152. #endif //BOOST_BEAST_BUFFER_REF_HPP