RESTinio
sendfile_operation_default.ipp
Go to the documentation of this file.
1 /*
2  restinio
3 */
4 
9 #include <cstdio>
10 
11 namespace restinio
12 {
13 
14 namespace impl
15 {
16 
17 //
18 // sendfile_operation_runner_t
19 //
20 
22 template < typename Socket >
24  : public sendfile_operation_runner_base_t< Socket >
25 {
26  public:
28 
33 
34  // Reuse construstors from base.
35  using base_type_t::base_type_t;
36 
37 
38  virtual void
39  start() override
40  {
41  const auto n =
42  std::fseek(
43  this->m_file_descriptor,
44  this->m_next_write_offset,
45  SEEK_SET );
46 
47  if( 0 == n )
48  {
49  this->init_next_write();
50  }
51  else
52  {
53  this->m_after_sendfile_cb(
54  make_error_code( std::ferror( this->m_file_descriptor ) ),
55  this->m_transfered_size );
56  return;
57  }
58  }
59 
64  void
65  init_next_write() noexcept
66  {
67  const auto desired_size =
68  std::min< file_size_t >( this->m_remained_size, this->m_chunk_size );
69 
70  const auto n =
71  std::fread(
72  this->m_buffer.get(),
73  1,
74  desired_size,
75  this->m_file_descriptor );
76 
77  if( desired_size != n )
78  {
79  this->m_after_sendfile_cb(
80  make_error_code( std::ferror( this->m_file_descriptor ) ),
81  this->m_transfered_size );
82  }
83  else
84  {
85  // If asio_ns::async_write fails we'll call m_after_sendfile_cb.
86  try
87  {
88  asio_ns::async_write(
89  this->m_socket,
91  this->m_buffer.get(),
92  static_cast< std::size_t >( desired_size ) },
93  asio_ns::bind_executor(
94  this->m_executor,
96  }
97  catch( ... )
98  {
99  this->m_after_sendfile_cb(
101  asio_convertible_error_t::async_write_call_failed ),
102  this->m_transfered_size );
103  }
104  }
105  }
106 
107  private:
108  std::unique_ptr< char[] > m_buffer{ new char [ this->m_chunk_size ] };
109 
111  auto
113  {
114  return [ this, ctx = this->shared_from_this() ]
115  // NOTE: this lambda is noexcept since v.0.6.0.
116  ( const asio_ns::error_code & ec, std::size_t written ) noexcept
117  {
118  if( !ec )
119  {
120  this->m_remained_size -= written;
121  this->m_transfered_size += written;
122  if( 0 == this->m_remained_size )
123  {
124  this->m_after_sendfile_cb( ec, this->m_transfered_size );
125  }
126  else
127  {
128  this->init_next_write();
129  }
130  }
131  else
132  {
133  this->m_after_sendfile_cb( ec, this->m_transfered_size );
134  }
135  };
136  }
137 };
138 
139 } /* namespace impl */
140 
141 } /* namespace restinio */
142 
restinio::const_buffer
constexpr const_buffer_t const_buffer(const void *str, std::size_t size) noexcept
Definition: buffers.hpp:424
restinio::impl::sendfile_operation_runner_base_t::m_socket
Socket & m_socket
Definition: sendfile_operation.hpp:82
restinio::make_asio_compaible_error
asio_ns::error_code make_asio_compaible_error(asio_convertible_error_t err) noexcept
Make restinio error_code compatible with asio_ns::error_code.
Definition: asio_include.hpp:210
restinio::impl::sendfile_operation_runner_base_t::m_remained_size
file_size_t m_remained_size
Definition: sendfile_operation.hpp:74
restinio::impl::sendfile_operation_runner_base_t::m_file_descriptor
file_descriptor_t m_file_descriptor
Definition: sendfile_operation.hpp:72
restinio::impl::sendfile_operation_runner_t::sendfile_operation_runner_t
sendfile_operation_runner_t(const sendfile_operation_runner_t &)=delete
restinio::impl::sendfile_operation_runner_base_t
A base runner of sendfile operation (keeps all the data).
Definition: sendfile_operation.hpp:50
restinio::impl::sendfile_operation_runner_t::init_next_write
void init_next_write() noexcept
Definition: sendfile_operation_default.ipp:65
restinio::impl::sendfile_operation_runner_base_t::m_after_sendfile_cb
after_sendfile_cb_t m_after_sendfile_cb
Definition: sendfile_operation.hpp:83
SEEK_SET
#define SEEK_SET
Definition: zconf.h:498
restinio::impl::sendfile_operation_runner_base_t::m_next_write_offset
file_offset_t m_next_write_offset
Definition: sendfile_operation.hpp:73
restinio::impl::sendfile_operation_runner_base_t::m_transfered_size
file_size_t m_transfered_size
Definition: sendfile_operation.hpp:75
restinio::impl::sendfile_operation_runner_t::m_buffer
std::unique_ptr< char[] > m_buffer
Definition: sendfile_operation_default.ipp:108
restinio
Definition: asio_include.hpp:21
restinio::impl::sendfile_operation_runner_t::sendfile_operation_runner_t
sendfile_operation_runner_t(sendfile_operation_runner_t &&)=delete
restinio::impl::sendfile_operation_runner_base_t::m_executor
default_asio_executor m_executor
Definition: sendfile_operation.hpp:81
restinio::impl::sendfile_operation_runner_t::start
virtual void start() override
Definition: sendfile_operation_default.ipp:39
restinio::impl::sendfile_operation_runner_t
A runner of sendfile operation.
Definition: sendfile_operation_default.ipp:25
restinio::impl::make_error_code
auto make_error_code(const Error_Type &e) noexcept
Definition: sendfile_operation.hpp:88
restinio::impl::sendfile_operation_runner_t::make_async_write_handler
auto make_async_write_handler() noexcept
Helper method for making a lambda for async_write completion handler.
Definition: sendfile_operation_default.ipp:112
restinio::impl::sendfile_operation_runner_base_t::m_chunk_size
const file_size_t m_chunk_size
Definition: sendfile_operation.hpp:77
restinio::impl::sendfile_operation_runner_t::operator=
sendfile_operation_runner_t & operator=(const sendfile_operation_runner_t &)=delete