sendfile_defs_win.hpp
Go to the documentation of this file.
/*
restinio
*/
#pragma once
#if defined(RESTINIO_ASIO_HAS_WINDOWS_OVERLAPPED_PTR)
#include <cstdio>
namespace restinio
{
using file_descriptor_t = HANDLE;
using file_offset_t = std::uint64_t;
using file_size_t = std::uint64_t;
inline file_descriptor_t null_file_descriptor(){ return INVALID_HANDLE_VALUE; }
inline file_descriptor_t
open_file( const char * file_path )
{
file_descriptor_t file_descriptor =
// We don't support Unicode on Windows, so call Ansi-version of
// CreateFile directly.
::CreateFileA(
file_path,
GENERIC_READ,
FILE_SHARE_READ,
0,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
0 );
if( null_file_descriptor() == file_descriptor )
{
throw exception_t{
fmt::format( "unable to openfile '{}': error({})", file_path, GetLastError() ) };
}
return file_descriptor;
}
template < typename META >
META
get_file_meta( file_descriptor_t fd )
{
file_size_t fsize = 0;
std::chrono::system_clock::time_point flastmodified;
if( null_file_descriptor() != fd )
{
LARGE_INTEGER file_size;
// Obtain file size:
if( GetFileSizeEx( fd, &file_size ) )
{
fsize = static_cast< file_size_t >( file_size.QuadPart );
}
else
{
throw exception_t{
fmt::format( "unable to get file size: error code:{}", GetLastError() ) };
}
FILETIME ftWrite;
if( GetFileTime( fd, NULL, NULL, &ftWrite ) )
{
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms724284(v=vs.85).aspx
// Microseconds between 1601-01-01 00:00:00 UTC and 1970-01-01 00:00:00 UTC
constexpr std::uint64_t nanosec100_in_microsec = 10;
constexpr std::uint64_t epoch_difference_in_microsec =
11644473600ULL * 1000 *1000;
// First convert 100-ns intervals to microseconds, then adjust for the
// epoch difference
ULARGE_INTEGER ull;
ull.LowPart = ftWrite.dwLowDateTime;
ull.HighPart = ftWrite.dwHighDateTime;
flastmodified =
std::chrono::system_clock::time_point{
std::chrono::microseconds(
ull.QuadPart / nanosec100_in_microsec - epoch_difference_in_microsec ) };
}
else
{
throw exception_t{
fmt::format(
"unable to get file last modification: error code:{}",
GetLastError() ) };
}
}
return META{ fsize, flastmodified};
}
inline void
close_file( file_descriptor_t fd )
{
CloseHandle( fd );
}
} /* namespace restinio */
#else // #if defined(RESTINIO_ASIO_HAS_WINDOWS_OVERLAPPED_PTR)
#include <restinio/sendfile_defs_default.hpp>
#endif // #if defined(RESTINIO_ASIO_HAS_WINDOWS_OVERLAPPED_PTR)
restinio
Definition: asio_include.hpp:21
restinio::null_file_descriptor
constexpr file_descriptor_t null_file_descriptor()
Get file descriptor which stands for null.
Definition: sendfile_defs_default.hpp:36
restinio::file_size_t
std::uint64_t file_size_t
Definition: sendfile_defs_default.hpp:23
restinio::close_file
void close_file(file_descriptor_t fd)
Close file by its descriptor.
Definition: sendfile_defs_default.hpp:89
restinio::file_offset_t
std::int64_t file_offset_t
Definition: sendfile_defs_default.hpp:22
restinio::file_descriptor_t
std::FILE * file_descriptor_t
Definition: sendfile_defs_default.hpp:21
restinio::open_file
file_descriptor_t open_file(const char *file_path)
Open file.
Definition: sendfile_defs_default.hpp:40
restinio::get_file_meta
META get_file_meta(file_descriptor_t fd)
Get file size.
Definition: sendfile_defs_default.hpp:55
sendfile_defs_default.hpp