RESTinio
Toggle main menu visibility
Loading...
Searching...
No Matches
restinio
sendfile_defs_default.hpp
Go to the documentation of this file.
1
/*
2
restinio
3
*/
4
5
/*!
6
Sendfile routine definitions (default implementation via <cstdio>).
7
8
@since v.0.4.3
9
*/
10
11
#
pragma
once
12
13
#
include
<
cstdio
>
14
#
include
<
cerrno
>
15
16
// for fixing #199 (https://github.com/Stiffstream/restinio/issues/199)
17
// fopen_s seems to be defined in the global namespace.
18
#
include
<
stdio
.
h
>
19
20
namespace
restinio
21
{
22
23
/** @name Aliases for sendfile operation.
24
*/
25
///@{
26
using
file_descriptor_t
= std::FILE*;
27
using
file_offset_t
=
std
::
int64_t
;
28
using
file_size_t
=
std
::
uint64_t
;
29
///@}
30
31
32
/** @name File operations.
33
* @brief A minimal set of file operations.
34
*
35
* Incapsulates the details *cstdio* API for a set of file operations neccessary
36
* for sendfile_t class implementation.
37
*/
38
///@{
39
40
//! Get file descriptor which stands for null.
41
[[
nodiscard
]]
42
constexpr
file_descriptor_t
null_file_descriptor
(){
return
nullptr
; }
43
44
//! Open file.
45
/*!
46
* @note
47
* It uses `fopen_s` if the compiler is VC++.
48
*
49
* @note
50
* It's expected that @a file_path contains names in ANSI encoding
51
* on Windows platform.
52
*/
53
[[
nodiscard
]]
54
inline
file_descriptor_t
55
open_file
(
const
char
* file_path )
56
{
57
//NOTE: fopen_s is only used for VC++ compiler.
58
#
if
defined
(
_MSC_VER
)
59
file_descriptor_t file_descriptor{};
60
const
auto
result = fopen_s( &file_descriptor, file_path,
"rb"
);
61
62
if
( result )
63
{
64
const
auto
err_code = errno;
65
throw
exception_t{
66
fmt::format(
67
RESTINIO_FMT_FORMAT_STRING(
"fopen_s('{}') failed; errno={}"
),
68
file_path, err_code )
69
};
70
}
71
72
return
file_descriptor;
73
#
else
74
file_descriptor_t
file_descriptor = std::fopen( file_path,
"rb"
);
75
76
if
(
null_file_descriptor
(
)
== file_descriptor )
77
{
78
throw
exception_t{
79
fmt::format(
80
RESTINIO_FMT_FORMAT_STRING(
"std::fopen failed: '{}'"
),
81
file_path )
82
};
83
}
84
85
return
file_descriptor;
86
#
endif
87
}
88
89
/*!
90
* @brief Helper function that accepts std::filesystem::path.
91
*
92
* @note
93
* It uses `_wfopen_s` if the compiler is VC++.
94
*
95
* @note
96
* It's expected that @a file_path contains names in ANSI encoding
97
* on Windows platform.
98
*
99
* @since v.0.7.1
100
*/
101
[[
nodiscard
]]
102
inline
file_descriptor_t
103
open_file
(
const
std::filesystem::path & file_path )
104
{
105
//NOTE: _wfopen_s is only used for VC++ compiler.
106
#
if
defined
(
_MSC_VER
)
107
file_descriptor_t file_descriptor{};
108
const
auto
result = _wfopen_s( &file_descriptor, file_path.c_str(), L"rb" );
109
110
if
( result )
111
{
112
const
auto
err_code = errno;
113
throw
exception_t{
114
fmt::format(
115
RESTINIO_FMT_FORMAT_STRING(
"_wfopen_s failed; errno={}"
),
116
err_code )
117
};
118
}
119
120
return
file_descriptor;
121
#
else
122
// Just delegate to ordinary open_file assuming that file_path is in UTF-8.
123
return
open_file( file_path.c_str() );
124
#
endif
125
}
126
127
//! Get file size.
128
template
<
typename
META >
129
[[nodiscard]]
130
META
131
get_file_meta
(
file_descriptor_t
fd )
132
{
133
file_size_t fsize = 0;
134
135
if
(
null_file_descriptor
(
)
!= fd )
136
{
137
// Obtain file size:
138
if
( 0 == std::fseek( fd , 0 , SEEK_END ) )
139
{
140
const
auto
end_pos = std::ftell( fd );
141
142
if
( -1 != end_pos )
143
{
144
fsize =
static_cast
< file_size_t >( end_pos );
145
std::rewind( fd );
146
}
147
else
148
{
149
throw
exception_t{
"std::ftell failed"
};
150
}
151
}
152
else
153
{
154
throw
exception_t{
"std::fseek failed"
};
155
}
156
}
157
158
// No way to get last modification,
159
// Use current time instead.
160
return
META{ fsize, std::chrono::system_clock::now() };
161
}
162
163
//! Close file by its descriptor.
164
inline
void
165
close_file
(
file_descriptor_t
fd )
166
{
167
std::fclose( fd );
168
}
169
///@}
170
171
}
/* namespace restinio */
restinio
Definition
sendfile_operation_default.ipp:12
restinio::null_file_descriptor
constexpr file_descriptor_t null_file_descriptor()
Get file descriptor which stands for null.
Definition
sendfile_defs_default.hpp:42
restinio::close_file
void close_file(file_descriptor_t fd)
Close file by its descriptor.
Definition
sendfile_defs_default.hpp:165
restinio::open_file
file_descriptor_t open_file(const char *file_path)
Open file.
Definition
sendfile_defs_default.hpp:55
restinio::file_descriptor_t
std::FILE * file_descriptor_t
Definition
sendfile_defs_default.hpp:26
restinio::open_file
file_descriptor_t open_file(const std::filesystem::path &file_path)
Helper function that accepts std::filesystem::path.
Definition
sendfile_defs_default.hpp:103
restinio::get_file_meta
META get_file_meta(file_descriptor_t fd)
Get file size.
Definition
sendfile_defs_default.hpp:131
Generated by
1.17.0