]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/beast/core/impl/file_stdio.ipp
update source to Ceph Pacific 16.2.2
[ceph.git] / ceph / src / boost / boost / beast / core / impl / file_stdio.ipp
CommitLineData
b32b8144 1//
92f5a8d4 2// Copyright (c) 2015-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
b32b8144
FG
3//
4// Distributed under the Boost Software License, Version 1.0. (See accompanying
5// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6//
7// Official repository: https://github.com/boostorg/beast
8//
9
10#ifndef BOOST_BEAST_CORE_IMPL_FILE_STDIO_IPP
11#define BOOST_BEAST_CORE_IMPL_FILE_STDIO_IPP
12
92f5a8d4 13#include <boost/beast/core/file_stdio.hpp>
f67539c2 14#include <boost/beast/core/detail/win32_unicode_path.hpp>
92f5a8d4
TL
15#include <boost/config/workaround.hpp>
16#include <boost/core/exchange.hpp>
b32b8144
FG
17#include <limits>
18
19namespace boost {
20namespace beast {
21
b32b8144
FG
22file_stdio::
23~file_stdio()
24{
25 if(f_)
26 fclose(f_);
27}
28
b32b8144
FG
29file_stdio::
30file_stdio(file_stdio&& other)
92f5a8d4 31 : f_(boost::exchange(other.f_, nullptr))
b32b8144 32{
b32b8144
FG
33}
34
b32b8144
FG
35file_stdio&
36file_stdio::
37operator=(file_stdio&& other)
38{
39 if(&other == this)
40 return *this;
41 if(f_)
42 fclose(f_);
43 f_ = other.f_;
44 other.f_ = nullptr;
45 return *this;
46}
47
b32b8144
FG
48void
49file_stdio::
50native_handle(FILE* f)
51{
52 if(f_)
53 fclose(f_);
54 f_ = f;
55}
56
b32b8144
FG
57void
58file_stdio::
59close(error_code& ec)
60{
61 if(f_)
62 {
63 int failed = fclose(f_);
64 f_ = nullptr;
65 if(failed)
66 {
67 ec.assign(errno, generic_category());
68 return;
69 }
70 }
92f5a8d4 71 ec = {};
b32b8144
FG
72}
73
b32b8144
FG
74void
75file_stdio::
76open(char const* path, file_mode mode, error_code& ec)
77{
78 if(f_)
79 {
80 fclose(f_);
81 f_ = nullptr;
82 }
f67539c2
TL
83 ec = {};
84#ifdef BOOST_MSVC
85 boost::winapi::WCHAR_ const* s;
86 detail::win32_unicode_path unicode_path(path, ec);
87 if (ec)
88 return;
89#else
b32b8144 90 char const* s;
f67539c2 91#endif
b32b8144
FG
92 switch(mode)
93 {
94 default:
92f5a8d4 95 case file_mode::read:
f67539c2
TL
96 #ifdef BOOST_MSVC
97 s = L"rb";
98 #else
92f5a8d4 99 s = "rb";
f67539c2 100 #endif
92f5a8d4
TL
101 break;
102
103 case file_mode::scan:
104 #ifdef BOOST_MSVC
f67539c2 105 s = L"rbS";
92f5a8d4
TL
106 #else
107 s = "rb";
108 #endif
109 break;
110
111 case file_mode::write:
f67539c2
TL
112 #ifdef BOOST_MSVC
113 s = L"wb+";
114 #else
92f5a8d4 115 s = "wb+";
f67539c2 116 #endif
92f5a8d4
TL
117 break;
118
119 case file_mode::write_new:
120 {
121#if BOOST_WORKAROUND(BOOST_MSVC, < 1910)
122 FILE* f0;
f67539c2 123 auto const ev = ::_wfopen_s(&f0, unicode_path.c_str(), L"rb");
92f5a8d4
TL
124 if(! ev)
125 {
126 std::fclose(f0);
127 ec = make_error_code(errc::file_exists);
128 return;
129 }
130 else if(ev !=
131 errc::no_such_file_or_directory)
132 {
133 ec.assign(ev, generic_category());
134 return;
135 }
f67539c2
TL
136 s = L"wb";
137#elif defined(BOOST_MSVC)
138 s = L"wbx";
92f5a8d4 139#else
92f5a8d4
TL
140 s = "wbx";
141#endif
142 break;
143 }
144
145 case file_mode::write_existing:
f67539c2
TL
146 #ifdef BOOST_MSVC
147 s = L"rb+";
148 #else
92f5a8d4 149 s = "rb+";
f67539c2 150 #endif
92f5a8d4
TL
151 break;
152
153 case file_mode::append:
f67539c2
TL
154 #ifdef BOOST_MSVC
155 s = L"ab";
156 #else
92f5a8d4 157 s = "ab";
f67539c2 158 #endif
92f5a8d4
TL
159 break;
160
161 case file_mode::append_existing:
162 {
163#ifdef BOOST_MSVC
164 FILE* f0;
165 auto const ev =
f67539c2 166 ::_wfopen_s(&f0, unicode_path.c_str(), L"rb+");
92f5a8d4
TL
167 if(ev)
168 {
169 ec.assign(ev, generic_category());
170 return;
171 }
172#else
173 auto const f0 =
174 std::fopen(path, "rb+");
175 if(! f0)
176 {
177 ec.assign(errno, generic_category());
178 return;
179 }
180#endif
181 std::fclose(f0);
f67539c2
TL
182 #ifdef BOOST_MSVC
183 s = L"ab";
184 #else
92f5a8d4 185 s = "ab";
f67539c2 186 #endif
92f5a8d4
TL
187 break;
188 }
189 }
190
191#ifdef BOOST_MSVC
f67539c2 192 auto const ev = ::_wfopen_s(&f_, unicode_path.c_str(), s);
b32b8144
FG
193 if(ev)
194 {
195 f_ = nullptr;
196 ec.assign(ev, generic_category());
197 return;
198 }
199#else
200 f_ = std::fopen(path, s);
201 if(! f_)
202 {
203 ec.assign(errno, generic_category());
204 return;
205 }
206#endif
b32b8144
FG
207}
208
b32b8144
FG
209std::uint64_t
210file_stdio::
211size(error_code& ec) const
212{
213 if(! f_)
214 {
92f5a8d4 215 ec = make_error_code(errc::bad_file_descriptor);
b32b8144
FG
216 return 0;
217 }
218 long pos = std::ftell(f_);
219 if(pos == -1L)
220 {
221 ec.assign(errno, generic_category());
222 return 0;
223 }
224 int result = std::fseek(f_, 0, SEEK_END);
225 if(result != 0)
226 {
227 ec.assign(errno, generic_category());
228 return 0;
229 }
230 long size = std::ftell(f_);
231 if(size == -1L)
232 {
233 ec.assign(errno, generic_category());
234 std::fseek(f_, pos, SEEK_SET);
235 return 0;
236 }
237 result = std::fseek(f_, pos, SEEK_SET);
238 if(result != 0)
239 ec.assign(errno, generic_category());
240 else
92f5a8d4 241 ec = {};
b32b8144
FG
242 return size;
243}
244
b32b8144
FG
245std::uint64_t
246file_stdio::
247pos(error_code& ec) const
248{
249 if(! f_)
250 {
92f5a8d4 251 ec = make_error_code(errc::bad_file_descriptor);
b32b8144
FG
252 return 0;
253 }
254 long pos = std::ftell(f_);
255 if(pos == -1L)
256 {
257 ec.assign(errno, generic_category());
258 return 0;
259 }
92f5a8d4 260 ec = {};
b32b8144
FG
261 return pos;
262}
263
b32b8144
FG
264void
265file_stdio::
266seek(std::uint64_t offset, error_code& ec)
267{
268 if(! f_)
269 {
92f5a8d4 270 ec = make_error_code(errc::bad_file_descriptor);
b32b8144
FG
271 return;
272 }
92f5a8d4 273 if(offset > static_cast<std::uint64_t>(std::numeric_limits<long>::max()))
b32b8144
FG
274 {
275 ec = make_error_code(errc::invalid_seek);
276 return;
277 }
278 int result = std::fseek(f_,
279 static_cast<long>(offset), SEEK_SET);
280 if(result != 0)
281 ec.assign(errno, generic_category());
282 else
92f5a8d4 283 ec = {};
b32b8144
FG
284}
285
b32b8144
FG
286std::size_t
287file_stdio::
288read(void* buffer, std::size_t n, error_code& ec) const
289{
290 if(! f_)
291 {
92f5a8d4 292 ec = make_error_code(errc::bad_file_descriptor);
b32b8144
FG
293 return 0;
294 }
295 auto nread = std::fread(buffer, 1, n, f_);
296 if(std::ferror(f_))
297 {
298 ec.assign(errno, generic_category());
299 return 0;
300 }
301 return nread;
302}
303
b32b8144
FG
304std::size_t
305file_stdio::
306write(void const* buffer, std::size_t n, error_code& ec)
307{
308 if(! f_)
309 {
92f5a8d4 310 ec = make_error_code(errc::bad_file_descriptor);
b32b8144
FG
311 return 0;
312 }
313 auto nwritten = std::fwrite(buffer, 1, n, f_);
314 if(std::ferror(f_))
315 {
316 ec.assign(errno, generic_category());
317 return 0;
318 }
319 return nwritten;
320}
321
322} // beast
323} // boost
324
325#endif