RESTinio
buffers.hpp
Go to the documentation of this file.
1 /*
2  restinio
3 */
4 
5 /*!
6  Restinio buffers.
7 */
8 
9 #pragma once
10 
11 #include <memory>
12 #include <array>
13 #include <string>
14 #include <cstring>
15 #include <type_traits>
16 
17 #include <restinio/asio_include.hpp>
18 #include <restinio/exception.hpp>
19 #include <restinio/sendfile.hpp>
20 
21 #include <restinio/compiler_features.hpp>
22 #include <restinio/utils/suppress_exceptions.hpp>
23 #include <restinio/utils/impl/safe_uint_truncate.hpp>
24 
25 #include <restinio/impl/include_fmtlib.hpp>
26 
27 
28 namespace restinio
29 {
30 
31 //
32 // fmt_minimal_memory_buffer_t
33 //
34 /*!
35  * @brief An alias for fmt::basic_memory_buffer<char,1>.
36  *
37  * @since v.0.6.3
38  */
40 
41 namespace impl
42 {
43 
44 //
45 // writable_base_t
46 //
47 
48 //! A base class for writable items.
49 /*!
50  Having a condition to put heterogeneous writable-items sequence in vector
51  and to transfer it from builders to connection context,
52  internal writable-items are the pieces encapsulating various
53  implementation that fit into a fixed memory space.
54  That's makes it possible to fit any of them in a binary
55  buffer that resides in writable_item_t.
56  While different descendants might vary in size
57  size of writable_item_t remains the same, so it can be used in a vector.
58 */
60 {
61  public:
62  writable_base_t() = default;
63  writable_base_t( const writable_base_t & ) = default;
64  writable_base_t( writable_base_t && ) = default;
65  writable_base_t & operator = ( const writable_base_t & ) = delete;
66  writable_base_t & operator = ( writable_base_t && ) = delete;
67 
68  virtual ~writable_base_t()
69  {}
70 
71  //! Move this buffer enitity to a given location.
72  //! \note storage must have a sufficient space and proper alignment.
73  virtual void relocate_to( void * storage ) = 0;
74 
75  //! Get the size of a writable piece of data.
76  virtual std::size_t size() const = 0;
77 };
78 
79 //! Internal interface for a trivial buffer-like entity.
81 {
82  public:
83  //! Get asio buf entity.
84  /*!
85  Prepares an item for being used with ASIO API.
86  */
87  virtual asio_ns::const_buffer buffer() const = 0;
88 };
89 
90 //! Empty buffer entity.
91 class empty_buf_t final : public buf_iface_t
92 {
93  public:
94  empty_buf_t() noexcept {}
95 
96  empty_buf_t( const empty_buf_t & ) = delete;
97  empty_buf_t & operator = ( const empty_buf_t & ) = delete;
98 
99  empty_buf_t( empty_buf_t && ) = default; // allow only explicit move.
100  empty_buf_t & operator = ( empty_buf_t && ) = delete;
101 
102  /*!
103  @name An implementation of writable_base_t interface.
104 
105  \see writable_base_t
106  */
107  ///@{
108  virtual asio_ns::const_buffer buffer() const override
109  {
110  return asio_ns::const_buffer{ nullptr, 0 };
111  }
112 
113  virtual void relocate_to( void * storage ) override
114  {
115  new( storage ) empty_buf_t{};
116  }
117  ///@}
118 
119  /*!
120  @name An implementation of buf_iface_t interface.
121 
122  \see buf_iface_t
123  */
124  ///@{
125  virtual std::size_t size() const override { return 0; }
126  ///@}
127 };
128 
129 //! Buffer entity for const buffer.
130 class const_buf_t final : public buf_iface_t
131 {
132  public:
133  const_buf_t() = delete;
134 
135  constexpr const_buf_t( const void * data, std::size_t size ) noexcept
136  : m_data{ data }
137  , m_size{ size }
138  {}
139 
140  const_buf_t( const const_buf_t & ) = delete;
141  const_buf_t & operator = ( const const_buf_t & ) = delete;
142 
143  const_buf_t( const_buf_t && ) = default; // allow only explicit move.
144  const_buf_t & operator = ( const_buf_t && ) = delete;
145 
146  /*!
147  @name An implementation of writable_base_t interface.
148 
149  \see writable_base_t
150  */
151  ///@{
152  virtual asio_ns::const_buffer buffer() const override
153  {
154  return asio_ns::const_buffer{ m_data, m_size };
155  }
156 
157  virtual void relocate_to( void * storage ) override
158  {
159  new( storage ) const_buf_t{ std::move( *this ) };
160  }
161  ///@}
162 
163  /*!
164  @name An implementation of buf_iface_t interface.
165 
166  \see buf_iface_t
167  */
168  ///@{
169  virtual std::size_t size() const override { return m_size; }
170  ///@}
171 
172  private:
173  //! A pointer to data.
174  const void * const m_data;
175  //! The size of data.
176  const std::size_t m_size;
177 };
178 
179 //! User defined datasizable object.
180 /*!
181  \note there is a limitation on how large a `Datasizeable` type can be.
182  The limitation is checked with a following predicate:
183  \code
184  sizeof(datasizeable_buf_t<D>) <= needed_storage_max_size;
185  \endcode
186 */
187 template < typename Datasizeable >
189 {
190  // Check datasizeable contract:
191  static_assert(
193  decltype( std::declval< const Datasizeable >().data() ),
194  const void *
195  >::value,
196  "Datasizeable requires 'T* data() const' member function, "
197  "where 'T*' is convertible to 'void*' " );
198 
199  static_assert(
201  decltype( std::declval< const Datasizeable >().size() ),
202  std::size_t
203  >::value,
204  "Datasizeable requires 'N size() const' member function, "
205  "where 'N' is convertible to 'std::size_t'" );
206 
207  static_assert(
209  "Datasizeable must be move constructible" );
210 
211  public:
212  datasizeable_buf_t( Datasizeable buf )
213  : m_custom_buffer{ std::move( buf ) }
214  {}
215 
216  datasizeable_buf_t( datasizeable_buf_t && ) noexcept = default; // allow only explicit move.
217 
218  /*!
219  @name An implementation of writable_base_t interface.
220 
221  \see writable_base_t
222  */
223  ///@{
224  virtual asio_ns::const_buffer buffer() const override
225  {
226  return asio_ns::const_buffer{
228  m_custom_buffer.size() };
229  }
230 
231  virtual void relocate_to( void * storage ) override
232  {
233  new( storage ) datasizeable_buf_t{ std::move( *this ) };
234  }
235  ///@}
236 
237  /*!
238  @name An implementation of buf_iface_t interface.
239 
240  \see buf_iface_t
241  */
242  ///@{
243  virtual std::size_t size() const override { return m_custom_buffer.size(); }
244  ///@}
245 
246  private:
247  //! A datasizeable item that represents buffer.
248  Datasizeable m_custom_buffer;
249 };
250 
251 //! An alias for a std::string instantiation of datasizeable_buf_t<D> template.
252 /*!
253  Used to figure out buffer_storage_align and needed_storage_max_size
254  constants.
255 */
257 
258 //! An alias for a fmt_minimal_memory_buffer_t instantiation of datasizeable_buf_t<D> template.
259 /*!
260  Used to figure out buffer_storage_align and needed_storage_max_size
261  constants.
262 */
265 
266 //
267 // shared_datasizeable_buf_t
268 //
269 
270 //! Buffer based on shared_ptr of data-sizeable entity.
271 template < typename Datasizeable >
273 {
274  public:
276 
277  shared_datasizeable_buf_t() = delete;
278 
279  shared_datasizeable_buf_t( shared_ptr_t buf_ptr ) noexcept
280  : m_buf_ptr{ std::move( buf_ptr ) }
281  {}
282 
285 
286  shared_datasizeable_buf_t( shared_datasizeable_buf_t && ) noexcept = default; // allow only explicit move.
288 
289  /*!
290  @name An implementation of writable_base_t interface.
291 
292  \see writable_base_t
293  */
294  ///@{
295  virtual asio_ns::const_buffer buffer() const override
296  {
297  return asio_ns::const_buffer{ m_buf_ptr->data(), m_buf_ptr->size() };
298  }
299 
300  virtual void relocate_to( void * storage ) override
301  {
302  new( storage ) shared_datasizeable_buf_t{ std::move( *this ) };
303  }
304  ///@}
305 
306  /*!
307  @name An implementation of buf_iface_t interface.
308 
309  \see buf_iface_t
310  */
311  ///@{
312  virtual std::size_t size() const override { return m_buf_ptr->size(); }
313  ///@}
314 
315  private:
316  //! A shared pointer to a datasizeable entity.
318 };
319 
320 //
321 // sendfile_write_operation_t
322 //
323 
324 //! Send file operation wrapper.
326 {
327  public:
328  sendfile_write_operation_t() = delete;
329 
330  sendfile_write_operation_t( sendfile_t && sf_opts )
332  {}
333 
336 
339 
340  /*!
341  @name An implementation of writable_base_t interface.
342 
343  \see writable_base_t
344  */
345  ///@{
346  virtual void relocate_to( void * storage ) override
347  {
348  new( storage ) sendfile_write_operation_t{ std::move( *this ) };
349  }
350 
351  virtual std::size_t size() const override
352  {
353  return m_sendfile_options
354  ? ::restinio::utils::impl::uint64_to_size_t(
355  m_sendfile_options->size())
356  : std::size_t{ 0 };
357  }
358  ///@}
359 
360  //! Get sendfile operation detaiols.
361  /*!
362  @note
363  Since v.0.4.9 it is non-const method. It is because we have
364  to work with mutable sendfile_t on some platform (like Windows).
365  */
366  sendfile_t &
367  sendfile_options() noexcept
368  {
369  return *m_sendfile_options;
370  }
371 
372  private:
373  //! A pointer to sendfile operation details.
375 };
376 
377 // Constant for suitable alignment of any entity in writable_base_t hierarchy.
379  std::max< std::size_t >( {
380  alignof( empty_buf_t ),
381  alignof( const_buf_t ),
382  alignof( string_buf_t ),
383  alignof( shared_datasizeable_buf_t< std::string > ),
384  alignof( sendfile_write_operation_t ),
385  alignof( fmt_minimal_memory_buffer_buf_t ) } );
386 
387 //! An of memory that is to be enough to hold any possible buffer entity.
389  std::max< std::size_t >( {
390  sizeof( empty_buf_t ),
391  sizeof( const_buf_t ),
392  sizeof( string_buf_t ),
393  sizeof( shared_datasizeable_buf_t< std::string > ),
394  sizeof( sendfile_write_operation_t ),
395  sizeof( fmt_minimal_memory_buffer_buf_t ) } );
396 
397 } /* namespace impl */
398 
399 //
400 // const_buffer_t/
401 
402 //! Helper class for setting a constant buffer storage explicitly.
403 /*
404  A proxy DTO type.
405  Its instances are emitted with const_buffer functions and
406  are possible to converted to writable_item_t as it has a constructor for it.
407 */
409 {
410  constexpr const_buffer_t(
411  const void * str,
412  std::size_t size ) noexcept
413  : m_str{ str }
414  , m_size{ size }
415  {}
416 
417  const void * const m_str;
418  const std::size_t m_size;
419 };
420 
421 //! @name Create const buffers.
422 ///@{
423 inline constexpr const_buffer_t
424 const_buffer( const void * str, std::size_t size ) noexcept
425 {
426  return const_buffer_t{ str, size };
427 }
428 
429 inline const_buffer_t
430 const_buffer( const char * str ) noexcept
431 {
432  return const_buffer( str, std::strlen( str ) );
433 }
434 ///@}
435 
436 //
437 // writable_item_type_t
438 //
439 
440 //! Buffers write operation type.
442 {
443  //! Item is a buffer and must be written trivially
445 
446  //! Item is a sendfile operation and implicates file write operation.
448 };
449 
450 //
451 // writable_item_t
452 //
453 
454 //! Class for storing the buffers used for streaming body (request/response).
455 /*!
456  Supporting different types of entities that eventually result in
457  output data sent to peer is a bit tricky.
458  In the first step RESTionio distinguish two types of output data sources:
459  - trivial buffers (those ones that can be presented as a pair
460  of a pointer to data and the size of the data).
461  - sendfile (send a piece of data from file utilizing native
462  sendfile support Linux/FreeBSD/macOS and TransmitFile on windows).
463 
464  Also trivial buffers are implemented diferently for different cases,
465  includeing a template classes `impl::datasizeable_buf_t<Datasizeable>` and
466  `impl::shared_datasizeable_buf_t<Datasizeable>`.
467 
468  When using RESTinio response builder, response body can be constructed
469  using different types of buffers, and once the result
470  is flushed to the connection it must be sent to the socket.
471  A couple of issues arises here.
472  And one of them is how to store all these heterogeneous buffers
473  with fewer allocations and less boilerplate necessary
474  to handle each corner case.
475  Storing and moving a bunch of buffers as a vector would be
476  nice, but vector demands a single type to be used.
477  And writable_item_t represents a custom variant-like abstraction
478  for storing an arbitrary buffer object (`std::variant` itself is not the option
479  as it is restricted to types defined beforehand and cannot benifit
480  from the knowledge that all stored items are types derrived from
481  impl::writable_base_t).
482 
483  For storing the data of buffers #m_storage is used.
484  It is an aligned buffer sufficient to store
485  any impl::writable_base_t descendant (there is a limitation
486  concerned with impl::datasizeable_buf_t).
487  Also writable_item_t exposes interface to treat it
488  like a trivial buffer or a sendfile operation.
489  The type of buffer currently stored in writable_item_t
490  instance a write_type() function used.
491 
492  Having such writable_item_t class, RESTinio can store a sequence
493  of arbitrary buffers in `std::vector`.
494 */
496 {
497  public:
498  writable_item_t( const writable_item_t & ) = delete;
499  writable_item_t & operator = ( const writable_item_t & ) = delete;
500 
503  {
504  new( &m_storage ) impl::empty_buf_t{};
505  }
506 
509  {
510  new( &m_storage ) impl::const_buf_t{ const_buf.m_str, const_buf.m_size };
511  }
512 
513  template <
514  typename Datasizeable,
515  typename S = typename
516  std::enable_if_t<
517  !std::is_same<
519  Datasizeable >::value > >
522  {
523  static_assert(
525  "size of type is too big" );
526 
528  }
529 
530  writable_item_t( const char * str )
531  // We can't be sure whether it is valid to consider
532  // data pointed by str a const buffer, so we make a string copy here.
533  : writable_item_t{ std::string{ str } }
534  {}
535 
536  template < typename Datasizeable >
539  {
540  static_assert(
542  "size of shared_ptr on a type is too big" );
543 
544  if( !sp )
545  throw exception_t{ "empty shared_ptr cannot be used as buffer" };
546 
548  }
549 
552  {
554  }
555 
558  {
560  }
561 
564  {
565  if( this != &b )
566  {
570  }
571 
572  return *this;
573  }
574 
576  {
578  }
579 
580  //! Get a type of a stored buffer object.
582  write_type() const noexcept
583  {
584  return m_write_type;
585  }
586 
587  //! Get the size of the underlying buffer object.
588  std::size_t size() const { return get_writable_base()->size(); }
589 
590  //! Create a buf reference object used by ASIO.
591  /*!
592  \note Stored buffer must be of writable_item_type_t::trivial_write_operation.
593  */
594  asio_ns::const_buffer buf() const { return get_buf()->buffer(); }
595 
596  //! Get a reference to a sendfile operation.
597  /*!
598  @note Stored buffer must be of writable_item_type_t::file_write_operation.
599  @note
600  Since v.0.4.9 it is non-const method. It is because we have
601  to work with mutable sendfile_t on some platform (like Windows).
602  */
603  sendfile_t &
605  {
606  return get_sfwo()->sendfile_options();
607  }
608 
609  private:
610  void
612  {
615  }
616 
618 
619  /** @name Access an item as an object of specific types.
620  * @brief Casts a stored object to one of the types.
621  */
622  ///@{
623 
624  //! Access as writable_base_t item.
625  const impl::writable_base_t * get_writable_base() const noexcept
626  {
627  return reinterpret_cast< const impl::writable_base_t * >( &m_storage );
628  }
629 
630  //! Access as writable_base_t item.
632  {
633  return reinterpret_cast< impl::writable_base_t * >( &m_storage );
634  }
635 
636  //! Access as trivial buf item.
637  const impl::buf_iface_t * get_buf() const noexcept
638  {
639  return reinterpret_cast< const impl::buf_iface_t * >( &m_storage );
640  }
641 
642  //! Access as trivial buf item.
643  impl::buf_iface_t * get_buf() noexcept
644  {
645  return reinterpret_cast< impl::buf_iface_t * >( &m_storage );
646  }
647 
648  //! Access as sendfile_write_operation_t item.
650  {
651  return reinterpret_cast< impl::sendfile_write_operation_t * >( &m_storage );
652  }
653  ///@}
654 
655  using storage_t =
659 
660  //! A storage for a buffer object of various types.
662 };
663 
664 //
665 // writable_items_container_t
666 //
667 
669 
670 //
671 // write_status_cb_t
672 //
673 
674 //! An alias for a callback to be invoked after the write operation of
675 //! a particular group of "buffers".
676 /*!
677  @since v.0.4.8
678 */
679 using write_status_cb_t =
680  std::function< void( const asio_ns::error_code & ec ) >;
681 
682 //
683 // write_group_t
684 //
685 
686 //! Group of writable items transported to the context of underlying connection
687 //! as one solid piece.
688 /*!
689  @since v.0.4.8
690 */
692 {
693  public:
694  //! Swap two groups.
695  friend void
696  swap( write_group_t & left, write_group_t & right ) noexcept
697  {
698  using std::swap;
699  swap( left.m_items, right.m_items );
700  swap( left.m_status_line_size, right.m_status_line_size );
701  swap( left.m_after_write_notificator, right.m_after_write_notificator );
702  }
703 
704  //! Construct write group with a given bunch of writable items.
705  explicit write_group_t(
706  //! A buffer objects included in this group.
707  writable_items_container_t items ) noexcept
708  : m_items{ std::move( items ) }
709  , m_status_line_size{ 0 }
710  {}
711 
712  /** @name Copy semantics.
713  * @brief Not allowed.
714  */
715  ///@{
716  write_group_t( const write_group_t & ) = delete;
717  write_group_t & operator = ( const write_group_t & ) = delete;
718  ///@}
719 
720  /** @name Move semantics.
721  * @brief Moves object leaving a moved one in clean state.
722  */
723  ///@{
724  write_group_t( write_group_t && wg ) noexcept
725  : m_items{ std::move( wg.m_items ) }
728  {
729  wg.m_after_write_notificator = write_status_cb_t{}; // Make sure src is cleaned.
730  wg.m_status_line_size = 0;
731  }
732 
733  write_group_t & operator = ( write_group_t && wg ) noexcept
734  {
735  write_group_t tmp{ std::move( wg ) };
736  swap( *this, tmp );
737 
738  return *this;
739  }
740  ///@}
741 
742  //! Destruct object.
743  /*!
744  If notificator was not called it would be invoked with error.
745  */
746  ~write_group_t() noexcept
747  {
748  if( m_after_write_notificator )
749  {
750  restinio::utils::suppress_exceptions_quietly( [&] {
751  invoke_after_write_notificator_if_exists(
752  make_asio_compaible_error(
753  asio_convertible_error_t::write_group_destroyed_passively ) );
754  } );
755  }
756  }
757 
758  /** @name Auxiliary data.
759  * @brief Accessors for working with auxiliary data.
760  */
761  ///@{
762  void
763  status_line_size( std::size_t n )
764  {
765  if( std::size_t{0} != n )
766  {
767  if( m_items.empty() )
768  {
769  throw exception_t{
770  "cannot set status line size for empty write group" };
771  }
772 
773  if( writable_item_type_t::trivial_write_operation !=
774  m_items.front().write_type() )
775  {
776  throw exception_t{
777  "cannot set status line size for write group: "
778  "first writable item must be 'trivial_write_operation'" };
779  }
780 
781  if( m_items.front().size() < n )
782  {
783  throw exception_t{
784  "cannot set status line size for write group: "
785  "first writable item size is less than provided value" };
786  }
787 
788  m_status_line_size = n;
789  }
790  }
791 
792  //! Get status line size.
793  std::size_t
794  status_line_size() const noexcept
795  {
796  return m_status_line_size;
797  }
798 
799  //! Set after write notificator.
800  void
801  after_write_notificator( write_status_cb_t notificator ) noexcept
802  {
803  m_after_write_notificator = std::move( notificator );
804  }
805 
806  //! Is there an after write notificator set?
807  bool
809  {
810  return static_cast< bool >( m_after_write_notificator );
811  }
812 
813  //! Get after write notificator.
814  void
815  invoke_after_write_notificator_if_exists( const asio_ns::error_code & ec )
816  {
817  if( m_after_write_notificator )
818  {
819  auto tmp = std::move( m_after_write_notificator );
820 
821  // Make sure we clean notificator,
822  // because on some platforms/compilers `std::move()` does not clean it.
823  m_after_write_notificator = write_status_cb_t{};
824 
825  tmp( ec );
826  }
827  }
828  ///@}
829 
830  //! Get the count of stored items.
831  auto
832  items_count() const noexcept
833  {
834  return m_items.size();
835  }
836 
837  //! Get access to the stored items.
838  const auto &
839  items() const noexcept
840  {
841  return m_items;
842  }
843 
844  //! Get access to the stored items.
845  /*!
846  Should be used for cases where we should have a non-const
847  access to writeable items.
848 
849  @since v.0.4.9
850  */
851  auto &
852  items() noexcept
853  {
854  return m_items;
855  }
856 
857  //! Reset group.
858  void
859  reset() noexcept
860  {
861 
862  RESTINIO_ENSURE_NOEXCEPT_CALL( m_items.clear() );
863  m_status_line_size = 0;
864 
865  // This assign is expected to be noexcept.
866  // And it is on some compilers.
867  // But for some compilers std::function::operator= is not noexcept
868  // (for example for Visual C++ from VisualStudio 2017).
869  // So we have to hope that this assign won't throw.
870  // Otherwise there is no way to recover from an exception
871  // from std::function::operator= in that place.
872  m_after_write_notificator = write_status_cb_t{};
873  }
874 
875  //! Merges with another group.
876  /*!
877  Two groups can be merged if the first one has no after-write callback
878  and the second one has no status line size.
879  */
880  void
882  {
883  auto & second_items = second.m_items;
884  m_items.reserve( m_items.size() + second_items.size() );
885 
886  std::move(
887  begin( second_items ),
888  end( second_items ),
889  std::back_inserter( m_items ) );
890 
891  m_after_write_notificator = std::move( second.m_after_write_notificator );
892  }
893 
894  private:
895  //! A buffer objects included in this group.
897 
898  //! A size of status line located in first "buffer".
899  /*!
900  If the value is not 0 then it means it references
901  a piece of data stored in the first buffer of m_items container.
902  */
904 
905  //! A callback to invoke once the the write opertaion of a given group completes.
907 };
908 
909 } /* namespace restinio */
const_buf_t(const const_buf_t &)=delete
write_group_t & operator=(write_group_t &&wg) noexcept
Definition: buffers.hpp:733
const impl::buf_iface_t * get_buf() const noexcept
Access as trivial buf item.
Definition: buffers.hpp:637
Item is a sendfile operation and implicates file write operation.
write_status_cb_t m_after_write_notificator
A callback to invoke once the the write opertaion of a given group completes.
Definition: buffers.hpp:906
A base class for writable items.
Definition: buffers.hpp:59
Send file operation wrapper.
Definition: buffers.hpp:325
shared_datasizeable_buf_t & operator=(const shared_datasizeable_buf_t &)=delete
virtual void relocate_to(void *storage) override
Move this buffer enitity to a given location.
Definition: buffers.hpp:157
virtual std::size_t size() const override
Get the size of a writable piece of data.
Definition: buffers.hpp:125
sendfile_write_operation_t & operator=(const sendfile_write_operation_t &)=delete
constexpr const_buffer_t const_buffer(const void *str, std::size_t size) noexcept
Definition: buffers.hpp:424
sendfile_write_operation_t(sendfile_t &&sf_opts)
Definition: buffers.hpp:330
storage_t m_storage
A storage for a buffer object of various types.
Definition: buffers.hpp:661
writable_items_container_t m_items
A buffer objects included in this group.
Definition: buffers.hpp:896
virtual void relocate_to(void *storage) override
Move this buffer enitity to a given location.
Definition: buffers.hpp:231
writable_item_type_t
Buffers write operation type.
Definition: buffers.hpp:441
writable_base_t(writable_base_t &&)=default
bool has_after_write_notificator() const noexcept
Is there an after write notificator set?
Definition: buffers.hpp:808
~write_group_t() noexcept
Destruct object.
Definition: buffers.hpp:746
virtual asio_ns::const_buffer buffer() const override
Get asio buf entity.
Definition: buffers.hpp:108
empty_buf_t(const empty_buf_t &)=delete
const_buffer_t const_buffer(const char *str) noexcept
Definition: buffers.hpp:430
Item is a buffer and must be written trivially.
const_buf_t & operator=(const const_buf_t &)=delete
empty_buf_t(empty_buf_t &&)=default
const_buf_t(const_buf_t &&)=default
virtual std::size_t size() const override
Get the size of a writable piece of data.
Definition: buffers.hpp:243
constexpr const_buffer_t(const void *str, std::size_t size) noexcept
Definition: buffers.hpp:410
impl::buf_iface_t * get_buf() noexcept
Access as trivial buf item.
Definition: buffers.hpp:643
virtual void relocate_to(void *storage)=0
Move this buffer enitity to a given location.
void merge(write_group_t second)
Merges with another group.
Definition: buffers.hpp:881
void after_write_notificator(write_status_cb_t notificator) noexcept
Set after write notificator.
Definition: buffers.hpp:801
write_group_t(const write_group_t &)=delete
Helper class for setting a constant buffer storage explicitly.
Definition: buffers.hpp:408
empty_buf_t & operator=(const empty_buf_t &)=delete
virtual std::size_t size() const override
Get the size of a writable piece of data.
Definition: buffers.hpp:169
virtual void relocate_to(void *storage) override
Move this buffer enitity to a given location.
Definition: buffers.hpp:300
std::size_t status_line_size() const noexcept
Get status line size.
Definition: buffers.hpp:794
constexpr std::size_t needed_storage_max_size
An of memory that is to be enough to hold any possible buffer entity.
Definition: buffers.hpp:388
auto items_count() const noexcept
Get the count of stored items.
Definition: buffers.hpp:832
const impl::writable_base_t * get_writable_base() const noexcept
Access as writable_base_t item.
Definition: buffers.hpp:625
auto & items() noexcept
Get access to the stored items.
Definition: buffers.hpp:852
Internal interface for a trivial buffer-like entity.
Definition: buffers.hpp:80
const void *const m_str
Definition: buffers.hpp:417
writable_base_t(const writable_base_t &)=default
virtual void relocate_to(void *storage) override
Move this buffer enitity to a given location.
Definition: buffers.hpp:346
virtual std::size_t size() const override
Get the size of a writable piece of data.
Definition: buffers.hpp:351
writable_item_t & operator=(const writable_item_t &)=delete
virtual void relocate_to(void *storage) override
Move this buffer enitity to a given location.
Definition: buffers.hpp:113
std::unique_ptr< sendfile_t > m_sendfile_options
A pointer to sendfile operation details.
Definition: buffers.hpp:374
writable_item_t(const_buffer_t const_buf)
Definition: buffers.hpp:507
impl::sendfile_write_operation_t * get_sfwo() noexcept
Access as sendfile_write_operation_t item.
Definition: buffers.hpp:649
const auto & items() const noexcept
Get access to the stored items.
Definition: buffers.hpp:839
writable_base_t & operator=(const writable_base_t &)=delete
empty_buf_t & operator=(empty_buf_t &&)=delete
write_group_t(writable_items_container_t items) noexcept
Construct write group with a given bunch of writable items.
Definition: buffers.hpp:705
void invoke_after_write_notificator_if_exists(const asio_ns::error_code &ec)
Get after write notificator.
Definition: buffers.hpp:815
Group of writable items transported to the context of underlying connection as one solid piece...
Definition: buffers.hpp:691
impl::writable_base_t * get_writable_base() noexcept
Access as writable_base_t item.
Definition: buffers.hpp:631
shared_datasizeable_buf_t & operator=(shared_datasizeable_buf_t &&)=delete
datasizeable_buf_t(datasizeable_buf_t &&) noexcept=default
RESTINIO_NODISCARD char to_lower_case(unsigned char ch)
sendfile_t & sendfile_options() noexcept
Get sendfile operation detaiols.
Definition: buffers.hpp:367
write_group_t(write_group_t &&wg) noexcept
Definition: buffers.hpp:724
void status_line_size(std::size_t n)
Definition: buffers.hpp:763
shared_datasizeable_buf_t(shared_datasizeable_buf_t &&) noexcept=default
virtual std::size_t size() const override
Get the size of a writable piece of data.
Definition: buffers.hpp:312
friend void swap(write_group_t &left, write_group_t &right) noexcept
Swap two groups.
Definition: buffers.hpp:696
const void *const m_data
A pointer to data.
Definition: buffers.hpp:174
const_buf_t & operator=(const_buf_t &&)=delete
virtual asio_ns::const_buffer buffer() const override
Get asio buf entity.
Definition: buffers.hpp:152
sendfile_write_operation_t(const sendfile_write_operation_t &)=delete
void reset() noexcept
Reset group.
Definition: buffers.hpp:859
const std::size_t m_size
The size of data.
Definition: buffers.hpp:176
sendfile_write_operation_t(sendfile_write_operation_t &&)=default
writable_base_t & operator=(writable_base_t &&)=delete
constexpr std::size_t buffer_storage_align
Definition: buffers.hpp:378
datasizeable_buf_t(Datasizeable buf)
Definition: buffers.hpp:212
virtual asio_ns::const_buffer buffer() const override
Get asio buf entity.
Definition: buffers.hpp:224
const std::size_t m_size
Definition: buffers.hpp:418
Datasizeable m_custom_buffer
A datasizeable item that represents buffer.
Definition: buffers.hpp:248
write_group_t & operator=(const write_group_t &)=delete
sendfile_write_operation_t & operator=(sendfile_write_operation_t &&)=delete
shared_ptr_t m_buf_ptr
A shared pointer to a datasizeable entity.
Definition: buffers.hpp:317
writable_item_t(const writable_item_t &)=delete
virtual std::size_t size() const =0
Get the size of a writable piece of data.
virtual asio_ns::const_buffer buffer() const =0
Get asio buf entity.
shared_datasizeable_buf_t(shared_ptr_t buf_ptr) noexcept
Definition: buffers.hpp:279
shared_datasizeable_buf_t(const shared_datasizeable_buf_t &)=delete
User defined datasizable object.
Definition: buffers.hpp:188
constexpr const_buf_t(const void *data, std::size_t size) noexcept
Definition: buffers.hpp:135
virtual asio_ns::const_buffer buffer() const override
Get asio buf entity.
Definition: buffers.hpp:295
std::enable_if< std::is_same< Parameter_Container, query_string_params_t >::value||std::is_same< Parameter_Container, router::route_params_t >::value, optional_t< Value_Type > >::type opt_value(const Parameter_Container &params, string_view_t key)
Gets the value of a parameter specified by key wrapped in optional_t<Value_Type> if parameter exists ...
Definition: value_or.hpp:64
Buffer based on shared_ptr of data-sizeable entity.
Definition: buffers.hpp:272
std::size_t m_status_line_size
A size of status line located in first "buffer".
Definition: buffers.hpp:903