]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/beast/core/impl/file_stdio.ipp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / boost / beast / core / impl / file_stdio.ipp
1 //
2 // Copyright (c) 2015-2016 Vinnie Falco (vinnie dot falco at gmail dot com)
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
13 #include <limits>
14
15 namespace boost {
16 namespace beast {
17
18 inline
19 file_stdio::
20 ~file_stdio()
21 {
22 if(f_)
23 fclose(f_);
24 }
25
26 inline
27 file_stdio::
28 file_stdio(file_stdio&& other)
29 : f_(other.f_)
30 {
31 other.f_ = nullptr;
32 }
33
34 inline
35 file_stdio&
36 file_stdio::
37 operator=(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
48 inline
49 void
50 file_stdio::
51 native_handle(FILE* f)
52 {
53 if(f_)
54 fclose(f_);
55 f_ = f;
56 }
57
58 inline
59 void
60 file_stdio::
61 close(error_code& ec)
62 {
63 if(f_)
64 {
65 int failed = fclose(f_);
66 f_ = nullptr;
67 if(failed)
68 {
69 ec.assign(errno, generic_category());
70 return;
71 }
72 }
73 ec.assign(0, ec.category());
74 }
75
76 inline
77 void
78 file_stdio::
79 open(char const* path, file_mode mode, error_code& ec)
80 {
81 if(f_)
82 {
83 fclose(f_);
84 f_ = nullptr;
85 }
86 char const* s;
87 switch(mode)
88 {
89 default:
90 case file_mode::read: s = "rb"; break;
91 case file_mode::scan: s = "rb"; break;
92 case file_mode::write: s = "wb"; break;
93 case file_mode::write_new: s = "wbx"; break;
94 case file_mode::write_existing: s = "wb"; break;
95 case file_mode::append: s = "ab"; break;
96 case file_mode::append_new: s = "abx"; break;
97 case file_mode::append_existing: s = "ab"; break;
98 }
99 #if BOOST_MSVC
100 auto const ev = fopen_s(&f_, path, s);
101 if(ev)
102 {
103 f_ = nullptr;
104 ec.assign(ev, generic_category());
105 return;
106 }
107 #else
108 f_ = std::fopen(path, s);
109 if(! f_)
110 {
111 ec.assign(errno, generic_category());
112 return;
113 }
114 #endif
115 ec.assign(0, ec.category());
116 }
117
118 inline
119 std::uint64_t
120 file_stdio::
121 size(error_code& ec) const
122 {
123 if(! f_)
124 {
125 ec.assign(errc::invalid_argument, generic_category());
126 return 0;
127 }
128 long pos = std::ftell(f_);
129 if(pos == -1L)
130 {
131 ec.assign(errno, generic_category());
132 return 0;
133 }
134 int result = std::fseek(f_, 0, SEEK_END);
135 if(result != 0)
136 {
137 ec.assign(errno, generic_category());
138 return 0;
139 }
140 long size = std::ftell(f_);
141 if(size == -1L)
142 {
143 ec.assign(errno, generic_category());
144 std::fseek(f_, pos, SEEK_SET);
145 return 0;
146 }
147 result = std::fseek(f_, pos, SEEK_SET);
148 if(result != 0)
149 ec.assign(errno, generic_category());
150 else
151 ec.assign(0, ec.category());
152 return size;
153 }
154
155 inline
156 std::uint64_t
157 file_stdio::
158 pos(error_code& ec) const
159 {
160 if(! f_)
161 {
162 ec.assign(errc::invalid_argument, generic_category());
163 return 0;
164 }
165 long pos = std::ftell(f_);
166 if(pos == -1L)
167 {
168 ec.assign(errno, generic_category());
169 return 0;
170 }
171 ec.assign(0, ec.category());
172 return pos;
173 }
174
175 inline
176 void
177 file_stdio::
178 seek(std::uint64_t offset, error_code& ec)
179 {
180 if(! f_)
181 {
182 ec.assign(errc::invalid_argument, generic_category());
183 return;
184 }
185 if(offset > (std::numeric_limits<long>::max)())
186 {
187 ec = make_error_code(errc::invalid_seek);
188 return;
189 }
190 int result = std::fseek(f_,
191 static_cast<long>(offset), SEEK_SET);
192 if(result != 0)
193 ec.assign(errno, generic_category());
194 else
195 ec.assign(0, ec.category());
196 }
197
198 inline
199 std::size_t
200 file_stdio::
201 read(void* buffer, std::size_t n, error_code& ec) const
202 {
203 if(! f_)
204 {
205 ec.assign(errc::invalid_argument, generic_category());
206 return 0;
207 }
208 auto nread = std::fread(buffer, 1, n, f_);
209 if(std::ferror(f_))
210 {
211 ec.assign(errno, generic_category());
212 return 0;
213 }
214 return nread;
215 }
216
217 inline
218 std::size_t
219 file_stdio::
220 write(void const* buffer, std::size_t n, error_code& ec)
221 {
222 if(! f_)
223 {
224 ec.assign(errc::invalid_argument, generic_category());
225 return 0;
226 }
227 auto nwritten = std::fwrite(buffer, 1, n, f_);
228 if(std::ferror(f_))
229 {
230 ec.assign(errno, generic_category());
231 return 0;
232 }
233 return nwritten;
234 }
235
236 } // beast
237 } // boost
238
239 #endif