RESTinio
sendfile_operation_default.ipp
Go to the documentation of this file.
1/*
2 restinio
3*/
4
9#include <cstdio>
10
11namespace restinio
12{
13
14namespace impl
15{
16
17//
18// sendfile_operation_runner_t
19//
20
22template < 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(
45 SEEK_SET );
46
47 if( 0 == n )
48 {
49 this->init_next_write();
50 }
51 else
52 {
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 {
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 {
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
A base runner of sendfile operation (keeps all the data).
auto make_async_write_handler() noexcept
Helper method for making a lambda for async_write completion handler.
sendfile_operation_runner_t(const sendfile_operation_runner_t &)=delete
sendfile_operation_runner_t & operator=(const sendfile_operation_runner_t &)=delete
sendfile_operation_runner_t(sendfile_operation_runner_t &&)=delete
auto make_error_code(const Error_Type &e) noexcept
@ async_write_call_failed
A call to async_write failed. The corresponding write operation wasn't done.
constexpr const_buffer_t const_buffer(const void *str, std::size_t size) noexcept
Definition: buffers.hpp:424
asio_ns::error_code make_asio_compaible_error(asio_convertible_error_t err) noexcept
Make restinio error_code compatible with asio_ns::error_code.
#define SEEK_SET
Definition: zconf.h:498