flat_static_buffer.hpp 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337
  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_FLAT_STATIC_BUFFER_HPP
  10. #define BOOST_BEAST_FLAT_STATIC_BUFFER_HPP
  11. #include <boost/beast/core/detail/config.hpp>
  12. #include <boost/asio/buffer.hpp>
  13. #include <algorithm>
  14. #include <cstddef>
  15. #include <cstring>
  16. namespace boost {
  17. namespace beast {
  18. /** A dynamic buffer using a fixed size internal buffer.
  19. A dynamic buffer encapsulates memory storage that may be
  20. automatically resized as required, where the memory is
  21. divided into two regions: readable bytes followed by
  22. writable bytes. These memory regions are internal to
  23. the dynamic buffer, but direct access to the elements
  24. is provided to permit them to be efficiently used with
  25. I/O operations.
  26. Objects of this type meet the requirements of <em>DynamicBuffer</em>
  27. and have the following additional properties:
  28. @li A mutable buffer sequence representing the readable
  29. bytes is returned by @ref data when `this` is non-const.
  30. @li Buffer sequences representing the readable and writable
  31. bytes, returned by @ref data and @ref prepare, will have
  32. length one.
  33. @li Ownership of the underlying storage belongs to the
  34. derived class.
  35. @note Variables are usually declared using the template class
  36. @ref flat_static_buffer; however, to reduce the number of template
  37. instantiations, objects should be passed `flat_static_buffer_base&`.
  38. @see flat_static_buffer
  39. */
  40. class flat_static_buffer_base
  41. {
  42. char* begin_;
  43. char* in_;
  44. char* out_;
  45. char* last_;
  46. char* end_;
  47. flat_static_buffer_base(
  48. flat_static_buffer_base const& other) = delete;
  49. flat_static_buffer_base& operator=(
  50. flat_static_buffer_base const&) = delete;
  51. public:
  52. /** Constructor
  53. This creates a dynamic buffer using the provided storage area.
  54. @param p A pointer to valid storage of at least `n` bytes.
  55. @param n The number of valid bytes pointed to by `p`.
  56. */
  57. flat_static_buffer_base(
  58. void* p, std::size_t n) noexcept
  59. {
  60. reset(p, n);
  61. }
  62. /** Clear the readable and writable bytes to zero.
  63. This function causes the readable and writable bytes
  64. to become empty. The capacity is not changed.
  65. Buffer sequences previously obtained using @ref data or
  66. @ref prepare become invalid.
  67. @esafe
  68. No-throw guarantee.
  69. */
  70. BOOST_BEAST_DECL
  71. void
  72. clear() noexcept;
  73. #ifdef BOOST_BEAST_ALLOW_DEPRECATED
  74. /// Change the number of readable and writable bytes to zero.
  75. void
  76. reset() noexcept
  77. {
  78. clear();
  79. }
  80. #elif ! BOOST_BEAST_DOXYGEN
  81. template<std::size_t I = 0>
  82. void
  83. reset() noexcept
  84. {
  85. static_assert(I != 0,
  86. BOOST_BEAST_DEPRECATION_STRING);
  87. }
  88. #endif
  89. //--------------------------------------------------------------------------
  90. /// The ConstBufferSequence used to represent the readable bytes.
  91. using const_buffers_type = net::const_buffer;
  92. /// The MutableBufferSequence used to represent the readable bytes.
  93. using mutable_data_type = net::mutable_buffer;
  94. /// The MutableBufferSequence used to represent the writable bytes.
  95. using mutable_buffers_type = net::mutable_buffer;
  96. /// Returns the number of readable bytes.
  97. std::size_t
  98. size() const noexcept
  99. {
  100. return out_ - in_;
  101. }
  102. /// Return the maximum number of bytes, both readable and writable, that can ever be held.
  103. std::size_t
  104. max_size() const noexcept
  105. {
  106. return dist(begin_, end_);
  107. }
  108. /// Return the maximum number of bytes, both readable and writable, that can be held without requiring an allocation.
  109. std::size_t
  110. capacity() const noexcept
  111. {
  112. return max_size();
  113. }
  114. /// Returns a constant buffer sequence representing the readable bytes
  115. const_buffers_type
  116. data() const noexcept
  117. {
  118. return {in_, dist(in_, out_)};
  119. }
  120. /// Returns a constant buffer sequence representing the readable bytes
  121. const_buffers_type
  122. cdata() const noexcept
  123. {
  124. return data();
  125. }
  126. /// Returns a mutable buffer sequence representing the readable bytes
  127. mutable_data_type
  128. data() noexcept
  129. {
  130. return {in_, dist(in_, out_)};
  131. }
  132. /** Returns a mutable buffer sequence representing writable bytes.
  133. Returns a mutable buffer sequence representing the writable
  134. bytes containing exactly `n` bytes of storage.
  135. All buffers sequences previously obtained using
  136. @ref data or @ref prepare are invalidated.
  137. @param n The desired number of bytes in the returned buffer
  138. sequence.
  139. @throws std::length_error if `size() + n` exceeds `max_size()`.
  140. @esafe
  141. Strong guarantee.
  142. */
  143. BOOST_BEAST_DECL
  144. mutable_buffers_type
  145. prepare(std::size_t n);
  146. /** Append writable bytes to the readable bytes.
  147. Appends n bytes from the start of the writable bytes to the
  148. end of the readable bytes. The remainder of the writable bytes
  149. are discarded. If n is greater than the number of writable
  150. bytes, all writable bytes are appended to the readable bytes.
  151. All buffers sequences previously obtained using
  152. @ref data or @ref prepare are invalidated.
  153. @param n The number of bytes to append. If this number
  154. is greater than the number of writable bytes, all
  155. writable bytes are appended.
  156. @esafe
  157. No-throw guarantee.
  158. */
  159. void
  160. commit(std::size_t n) noexcept
  161. {
  162. out_ += (std::min<std::size_t>)(n, last_ - out_);
  163. }
  164. /** Remove bytes from beginning of the readable bytes.
  165. Removes n bytes from the beginning of the readable bytes.
  166. All buffers sequences previously obtained using
  167. @ref data or @ref prepare are invalidated.
  168. @param n The number of bytes to remove. If this number
  169. is greater than the number of readable bytes, all
  170. readable bytes are removed.
  171. @esafe
  172. No-throw guarantee.
  173. */
  174. BOOST_BEAST_DECL
  175. void
  176. consume(std::size_t n) noexcept;
  177. protected:
  178. /** Constructor
  179. The buffer will be in an undefined state. It is necessary
  180. for the derived class to call @ref reset with a pointer
  181. and size in order to initialize the object.
  182. */
  183. flat_static_buffer_base() = default;
  184. /** Reset the pointed-to buffer.
  185. This function resets the internal state to the buffer provided.
  186. All input and output sequences are invalidated. This function
  187. allows the derived class to construct its members before
  188. initializing the static buffer.
  189. @param p A pointer to valid storage of at least `n` bytes.
  190. @param n The number of valid bytes pointed to by `p`.
  191. @esafe
  192. No-throw guarantee.
  193. */
  194. BOOST_BEAST_DECL
  195. void
  196. reset(void* p, std::size_t n) noexcept;
  197. private:
  198. static
  199. std::size_t
  200. dist(char const* first, char const* last) noexcept
  201. {
  202. return static_cast<std::size_t>(last - first);
  203. }
  204. };
  205. //------------------------------------------------------------------------------
  206. /** A <em>DynamicBuffer</em> with a fixed size internal buffer.
  207. Buffer sequences returned by @ref data and @ref prepare
  208. will always be of length one.
  209. This implements a dynamic buffer using no memory allocations.
  210. @tparam N The number of bytes in the internal buffer.
  211. @note To reduce the number of template instantiations when passing
  212. objects of this type in a deduced context, the signature of the
  213. receiving function should use @ref flat_static_buffer_base instead.
  214. @see flat_static_buffer_base
  215. */
  216. template<std::size_t N>
  217. class flat_static_buffer : public flat_static_buffer_base
  218. {
  219. char buf_[N];
  220. public:
  221. /// Constructor
  222. flat_static_buffer(flat_static_buffer const&);
  223. /// Constructor
  224. flat_static_buffer()
  225. : flat_static_buffer_base(buf_, N)
  226. {
  227. }
  228. /// Assignment
  229. flat_static_buffer& operator=(flat_static_buffer const&);
  230. /// Returns the @ref flat_static_buffer_base portion of this object
  231. flat_static_buffer_base&
  232. base()
  233. {
  234. return *this;
  235. }
  236. /// Returns the @ref flat_static_buffer_base portion of this object
  237. flat_static_buffer_base const&
  238. base() const
  239. {
  240. return *this;
  241. }
  242. /// Return the maximum sum of the input and output sequence sizes.
  243. std::size_t constexpr
  244. max_size() const
  245. {
  246. return N;
  247. }
  248. /// Return the maximum sum of input and output sizes that can be held without an allocation.
  249. std::size_t constexpr
  250. capacity() const
  251. {
  252. return N;
  253. }
  254. };
  255. } // beast
  256. } // boost
  257. #include <boost/beast/core/impl/flat_static_buffer.hpp>
  258. #ifdef BOOST_BEAST_HEADER_ONLY
  259. #include <boost/beast/core/impl/flat_static_buffer.ipp>
  260. #endif
  261. #endif