13 #include <restinio/impl/include_fmtlib.hpp> 15 #include <restinio/asio_include.hpp> 16 #include <restinio/string_view.hpp> 17 #include <restinio/exception.hpp> 19 #include <restinio/detect_os.hpp> 33 #if defined(RESTINIO_OS_WINDOWS) 34 #include "sendfile_defs_win.hpp" 35 #elif defined(RESTINIO_OS_UNIX) || defined(RESTINIO_OS_APPLE) 36 #include "sendfile_defs_posix.hpp" 38 #if defined (RESTINIO_ENABLE_SENDFILE_DEFAULT_IMPL) 39 #include "sendfile_defs_default.hpp" 41 #error "Sendfile not supported, to enable default implementation define RESTINIO_ENABLE_SENDFILE_DEFAULT_IMPL macro" 78 if( 0 == chunk_size_value )
79 return sendfile_default_chunk_size;
81 if( sendfile_max_chunk_size < chunk_size_value )
82 return sendfile_max_chunk_size;
84 return chunk_size_value;
95 constexpr auto value()
const noexcept {
return m_chunk_size; }
120 swap( left.m_file_descriptor, right.m_file_descriptor );
153 close_file( m_file_descriptor );
160 return null_file_descriptor() != m_file_descriptor;
167 return m_file_descriptor;
173 m_file_descriptor = null_file_descriptor();
192 std::swap( r.m_file_total_size, l.m_file_total_size );
193 std::swap( r.m_last_modified_at, l.m_last_modified_at );
200 file_size_t file_total_size,
201 std::chrono::system_clock::time_point last_modified_at )
noexcept 258 swap( left.m_file_descriptor, right.m_file_descriptor );
259 swap( left.m_meta, right.m_meta );
260 swap( left.m_offset, right.m_offset );
261 swap( left.m_size, right.m_size );
262 swap( left.m_chunk_size, right.m_chunk_size );
263 swap( left.m_timelimit, right.m_timelimit );
298 bool is_valid()
const noexcept {
return m_file_descriptor.is_valid(); }
309 auto offset()
const noexcept {
return m_offset; }
313 auto size()
const noexcept {
return m_size; }
327 file_offset_t offset_value,
332 if(
static_cast< file_size_t >( offset_value ) > m_meta.file_total_size() )
336 RESTINIO_FMT_FORMAT_STRING(
337 "invalid file offset: {}, while file size is {}" ),
339 m_meta.file_total_size() ) };
342 m_offset = offset_value;
344 std::min< file_size_t >(
345 m_meta.file_total_size() -
static_cast< file_size_t >( offset_value ),
353 file_offset_t offset_value,
356 return std::move(
this->offset_and_size( offset_value, size_value ) );
373 m_chunk_size = chunk.value();
381 return std::move(
this->chunk_size( chunk ) );
394 timelimit( std::chrono::steady_clock::duration timelimit_value ) &
398 m_timelimit = std::max( timelimit_value, std::chrono::steady_clock::duration::zero() );
403 timelimit( std::chrono::steady_clock::duration timelimit_value ) &&
405 return std::move(
this->timelimit( timelimit_value ) );
414 return m_file_descriptor.fd();
434 return std::move(target.m_file_descriptor);
444 throw exception_t{
"invalid file descriptor" };
489 return sendfile_t{ std::move( fd ), meta, chunk_size };
496 const char * file_path,
502 auto meta = get_file_meta< file_meta_t >( fd.fd() );
504 return sendfile( std::move( fd ), meta, chunk_size );
511 const std::string & file_path,
515 return sendfile( file_path.c_str(), chunk_size );
522 string_view_t file_path,
528 std::string{ file_path.data(), file_path.size() },
540 const std::filesystem::path & file_path,
546 auto meta = get_file_meta< file_meta_t >( fd.fd() );
548 return sendfile( std::move( fd ), meta, chunk_size );
file_descriptor_holder_t & operator=(file_descriptor_holder_t &&fdh) noexcept
friend void swap(file_descriptor_holder_t &left, file_descriptor_holder_t &right) noexcept
Swap two descriptors.
constexpr file_size_t sendfile_max_chunk_size
Maximum size of a chunk.
sendfile_t && offset_and_size(file_offset_t offset_value, file_size_t size_value=std::numeric_limits< file_size_t >::max()) &&
auto chunk_size() const noexcept
sendfile_t(sendfile_t &&sf) noexcept
const file_size_t m_chunk_size
Valid value of the chunk size.
sendfile_t & timelimit(std::chrono::steady_clock::duration timelimit_value) &
file_size_t m_size
The size of data portion in file.
auto size() const noexcept
Get size of data to write.
auto timelimit() const noexcept
file_descriptor_holder_t(const file_descriptor_holder_t &)=delete
Wrapper class for working with native file handler.
file_offset_t m_offset
Data offset within the file.
friend void swap(sendfile_t &left, sendfile_t &right) noexcept
sendfile_t & operator=(const sendfile_t &)=delete
bool is_valid() const noexcept
Check if file is valid.
~file_descriptor_holder_t() noexcept
std::enable_if< std::is_same< Parameter_Container, query_string_params_t >::value||std::is_same< Parameter_Container, router::route_params_t >::value, std::optional< Value_Type > >::type opt_value(const Parameter_Container ¶ms, string_view_t key)
Gets the value of a parameter specified by key wrapped in std::optional<Value_Type> if parameter exis...
file_descriptor_holder_t m_file_descriptor
Native file descriptor.
sendfile_t & chunk_size(sendfile_chunk_size_guarded_value_t chunk) &
static constexpr file_size_t clarify_chunk_size(file_size_t chunk_size_value) noexcept
Checks chunk_size_value and returns a value in [1, sendfile_max_chunk_size].
sendfile_t(const sendfile_t &)=delete
auto offset() const noexcept
Get offset of data to write.
file_descriptor_t m_file_descriptor
Target file descriptor.
constexpr sendfile_chunk_size_guarded_value_t(file_size_t chunk_size_value) noexcept
sendfile_t && chunk_size(sendfile_chunk_size_guarded_value_t chunk) &&
Set prefered chunk size to use in write operation.
sendfile_t && timelimit(std::chrono::steady_clock::duration timelimit_value) &&
const file_meta_t & meta() const
Get file meta data.
void check_file_is_valid() const
Check if stored file descriptor is valid, and throws if it is not.
sendfile_t sendfile(string_view_t file_path, file_size_t chunk_size=sendfile_default_chunk_size)
file_descriptor_t fd() const noexcept
sendfile_t sendfile(file_descriptor_holder_t fd, file_meta_t meta, file_size_t chunk_size=sendfile_default_chunk_size) noexcept
Send file write operation description.
constexpr auto value() const noexcept
Get the valid value of a chunk size.
file_meta_t m_meta
File meta data.
file_size_t m_chunk_size
A prefered chunk size for a single write call.
sendfile_t & operator=(sendfile_t &&sf) noexcept
file_descriptor_holder_t(file_descriptor_t fd) noexcept
Init constructor.
friend file_descriptor_holder_t takeaway_file_descriptor(sendfile_t &target)
Take away the file description form sendfile object.
std::chrono::steady_clock::duration m_timelimit
Timelimit for writing all the given data.
file_descriptor_holder_t & operator=(const file_descriptor_holder_t &)=delete
sendfile_t sendfile(const std::filesystem::path &file_path, file_size_t chunk_size=sendfile_default_chunk_size)
sendfile_t(file_descriptor_holder_t fdh, file_meta_t meta, sendfile_chunk_size_guarded_value_t chunk) noexcept
constexpr file_size_t sendfile_default_chunk_size
Default chunk size for sendfile operation.
file_descriptor_holder_t(file_descriptor_holder_t &&fdh) noexcept
sendfile_t sendfile(const char *file_path, file_size_t chunk_size=sendfile_default_chunk_size)
A guard class for setting chunk size.
sendfile_t & offset_and_size(file_offset_t offset_value, file_size_t size_value=std::numeric_limits< file_size_t >::max()) &
bool is_valid() const noexcept
Check if file descriptor is valid.
file_descriptor_t file_descriptor() const noexcept
Get the file descriptor of a given sendfile operation.