flat_static_buffer.hpp 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317
  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 using no memory allocations.
  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. a type of net::const_buffer or net::mutable_buffer.
  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. //--------------------------------------------------------------------------
  74. /// The ConstBufferSequence used to represent the readable bytes.
  75. using const_buffers_type = net::const_buffer;
  76. /// The MutableBufferSequence used to represent the writable bytes.
  77. using mutable_buffers_type = net::mutable_buffer;
  78. /// Returns the number of readable bytes.
  79. std::size_t
  80. size() const noexcept
  81. {
  82. return out_ - in_;
  83. }
  84. /// Return the maximum number of bytes, both readable and writable, that can ever be held.
  85. std::size_t
  86. max_size() const noexcept
  87. {
  88. return dist(begin_, end_);
  89. }
  90. /// Return the maximum number of bytes, both readable and writable, that can be held without requiring an allocation.
  91. std::size_t
  92. capacity() const noexcept
  93. {
  94. return max_size();
  95. }
  96. /// Returns a constant buffer sequence representing the readable bytes
  97. const_buffers_type
  98. data() const noexcept
  99. {
  100. return {in_, dist(in_, out_)};
  101. }
  102. /// Returns a constant buffer sequence representing the readable bytes
  103. const_buffers_type
  104. cdata() const noexcept
  105. {
  106. return data();
  107. }
  108. /// Returns a mutable buffer sequence representing the readable bytes
  109. mutable_buffers_type
  110. data() noexcept
  111. {
  112. return {in_, dist(in_, out_)};
  113. }
  114. /** Returns a mutable buffer sequence representing writable bytes.
  115. Returns a mutable buffer sequence representing the writable
  116. bytes containing exactly `n` bytes of storage.
  117. All buffers sequences previously obtained using
  118. @ref data or @ref prepare are invalidated.
  119. @param n The desired number of bytes in the returned buffer
  120. sequence.
  121. @throws std::length_error if `size() + n` exceeds `max_size()`.
  122. @esafe
  123. Strong guarantee.
  124. */
  125. BOOST_BEAST_DECL
  126. mutable_buffers_type
  127. prepare(std::size_t n);
  128. /** Append writable bytes to the readable bytes.
  129. Appends n bytes from the start of the writable bytes to the
  130. end of the readable bytes. The remainder of the writable bytes
  131. are discarded. If n is greater than the number of writable
  132. bytes, all writable bytes are appended to the readable bytes.
  133. All buffers sequences previously obtained using
  134. @ref data or @ref prepare are invalidated.
  135. @param n The number of bytes to append. If this number
  136. is greater than the number of writable bytes, all
  137. writable bytes are appended.
  138. @esafe
  139. No-throw guarantee.
  140. */
  141. void
  142. commit(std::size_t n) noexcept
  143. {
  144. out_ += (std::min<std::size_t>)(n, last_ - out_);
  145. }
  146. /** Remove bytes from beginning of the readable bytes.
  147. Removes n bytes from the beginning of the readable bytes.
  148. All buffers sequences previously obtained using
  149. @ref data or @ref prepare are invalidated.
  150. @param n The number of bytes to remove. If this number
  151. is greater than the number of readable bytes, all
  152. readable bytes are removed.
  153. @esafe
  154. No-throw guarantee.
  155. */
  156. BOOST_BEAST_DECL
  157. void
  158. consume(std::size_t n) noexcept;
  159. protected:
  160. /** Constructor
  161. The buffer will be in an undefined state. It is necessary
  162. for the derived class to call @ref reset with a pointer
  163. and size in order to initialize the object.
  164. */
  165. flat_static_buffer_base() = default;
  166. /** Reset the pointed-to buffer.
  167. This function resets the internal state to the buffer provided.
  168. All input and output sequences are invalidated. This function
  169. allows the derived class to construct its members before
  170. initializing the static buffer.
  171. @param p A pointer to valid storage of at least `n` bytes.
  172. @param n The number of valid bytes pointed to by `p`.
  173. @esafe
  174. No-throw guarantee.
  175. */
  176. BOOST_BEAST_DECL
  177. void
  178. reset(void* p, std::size_t n) noexcept;
  179. private:
  180. static
  181. std::size_t
  182. dist(char const* first, char const* last) noexcept
  183. {
  184. return static_cast<std::size_t>(last - first);
  185. }
  186. };
  187. //------------------------------------------------------------------------------
  188. /** A <em>DynamicBuffer</em> with a fixed size internal buffer using no memory allocations.
  189. Buffer sequences representing the readable and writable
  190. bytes, returned by @ref data and @ref prepare, will have
  191. a type of net::const_buffer or net::mutable_buffer.
  192. @tparam N The number of bytes in the internal buffer.
  193. @note To reduce the number of template instantiations when passing
  194. objects of this type in a deduced context, the signature of the
  195. receiving function should use @ref flat_static_buffer_base instead.
  196. @see flat_static_buffer_base
  197. */
  198. template<std::size_t N>
  199. class flat_static_buffer : public flat_static_buffer_base
  200. {
  201. char buf_[N];
  202. public:
  203. /// Constructor
  204. flat_static_buffer(flat_static_buffer const&);
  205. /// Constructor
  206. flat_static_buffer()
  207. : flat_static_buffer_base(buf_, N)
  208. {
  209. }
  210. /// Assignment
  211. flat_static_buffer& operator=(flat_static_buffer const&);
  212. /// Returns the @ref flat_static_buffer_base portion of this object
  213. flat_static_buffer_base&
  214. base()
  215. {
  216. return *this;
  217. }
  218. /// Returns the @ref flat_static_buffer_base portion of this object
  219. flat_static_buffer_base const&
  220. base() const
  221. {
  222. return *this;
  223. }
  224. /// Return the maximum sum of the input and output sequence sizes.
  225. std::size_t constexpr
  226. max_size() const
  227. {
  228. return N;
  229. }
  230. /// Return the maximum sum of input and output sizes that can be held without an allocation.
  231. std::size_t constexpr
  232. capacity() const
  233. {
  234. return N;
  235. }
  236. };
  237. } // beast
  238. } // boost
  239. #include <boost/beast/core/impl/flat_static_buffer.hpp>
  240. #ifdef BOOST_BEAST_HEADER_ONLY
  241. #include <boost/beast/core/impl/flat_static_buffer.ipp>
  242. #endif
  243. #endif