FastLED 3.9.15
Loading...
Searching...
No Matches
fstream.cpp.hpp
Go to the documentation of this file.
1// Implementation file for fl::fstream, fl::ifstream, fl::ofstream
2// This file contains out-of-line definitions to reduce header compilation overhead
3
4#include "fl/stl/fstream.h"
5#include "fl/stl/memory.h"
6#include "fl/stl/noexcept.h"
7
8namespace fl {
9
10// ============================================================================
11// ifstream Implementation
12// ============================================================================
13
15 : mLastRead(0), mGood(false), mEof(false), mFail(true) {
16 open(path, mode);
17}
18
20 : mHandle(handle), mLastRead(0), mGood(false), mEof(false), mFail(true) {
22}
23
27
28void ifstream::open(const char* path, ios::openmode mode) {
29 close();
30
31 // Build fopen mode string
32 const char* fmode = (mode & ios::binary) ? "rb" : "r";
33
35
36 if (mHandle->is_open()) {
37 if (mode & ios::ate) {
38 mHandle->seek(0, seek_dir::end);
39 }
41 } else {
43 }
44}
45
47 if (mHandle && mHandle->is_open()) {
48 mHandle->close();
49 // After successful close: keep good() = true to match std::ofstream behavior
50 // This allows fs_stub.hpp's createTextFile to work correctly
51 if (!mHandle->has_error()) {
52 mGood = true;
53 mEof = false;
54 mFail = false;
55 } else {
57 }
58 }
59}
60
61ifstream& ifstream::read(char* buffer, fl::size_t count) {
62 mLastRead = 0;
63 if (mHandle && mHandle->is_open()) {
64 mLastRead = mHandle->read(buffer, count);
66 }
67 return *this;
68}
69
71 if (!mHandle) {
72 return 0;
73 }
74 return mHandle->tell();
75}
76
78 if (mHandle && mHandle->is_open()) {
79 seek_dir seek_direction =
82 mHandle->seek(pos, seek_direction);
84 }
85 return *this;
86}
87
88int ifstream::error() const {
89 if (!mHandle) {
91 }
92 return mHandle->error_code();
93}
94
95const char* ifstream::error_message() const {
96 if (!mHandle) {
97 return "No handle";
98 }
99 return mHandle->error_message();
100}
101
103 if (mHandle) {
104 mHandle->clear_error();
105 }
106 mFail = false;
107 updateState();
108}
109
110// ============================================================================
111// ofstream Implementation
112// ============================================================================
113
114ofstream::ofstream(const char* path, ios::openmode mode)
115 : mGood(false), mEof(false), mFail(true), mLocalError(0) {
116 open(path, mode);
117}
118
120 : mHandle(handle), mGood(false), mEof(false), mFail(true), mLocalError(0) {
121 updateState();
122}
123
127
128void ofstream::open(const char* path, ios::openmode mode) {
129 close();
130
131 // Build fopen mode string
132 const char* fmode;
133 if (mode & ios::app) {
134 fmode = (mode & ios::binary) ? "ab" : "a";
135 } else if (mode & ios::trunc) {
136 fmode = (mode & ios::binary) ? "wb" : "w";
137 } else {
138 // Default for 'out' is truncate
139 fmode = (mode & ios::binary) ? "wb" : "w";
140 }
141
143
144 if (mHandle->is_open()) {
145 if (mode & ios::ate) {
146 mHandle->seek(0, seek_dir::end);
147 }
148 updateState();
149 } else {
150 updateState();
151 }
152}
153
155 if (mHandle && mHandle->is_open()) {
156 mHandle->close();
157 // After successful close: keep good() = true to match std::ofstream behavior
158 // This allows fs_stub.hpp's createTextFile to work correctly
159 if (!mHandle->has_error()) {
160 mGood = true;
161 mEof = false;
162 mFail = false;
163 } else {
164 updateState();
165 }
166 }
167}
168
169ofstream& ofstream::write(const char* data, fl::size_t count) {
170 if (mHandle && mHandle->is_open()) {
171 fl::size_t written = mHandle->write(data, count);
172 if (written != count) {
173 mFail = true;
174 mGood = false;
175 }
176 updateState();
177 } else {
178 // Writing to closed stream - set bad file error
180 mFail = true;
181 mGood = false;
182 }
183 return *this;
184}
185
186int ofstream::error() const {
187 if (mLocalError != 0) {
188 return mLocalError;
189 }
190 if (!mHandle) {
192 }
193 return mHandle->error_code();
194}
195
196const char* ofstream::error_message() const {
197 if (mLocalError != 0) {
198#ifdef FASTLED_TESTING
200#else
201 return "Write to closed stream";
202#endif
203 }
204 if (!mHandle) {
205 return "No handle";
206 }
207 return mHandle->error_message();
208}
209
211 mLocalError = 0;
212 if (mHandle) {
213 mHandle->clear_error();
214 }
215 mFail = false;
216 updateState();
217}
218
219// ============================================================================
220// fstream Implementation
221// ============================================================================
222
223fstream::fstream(const char* path, ios::openmode mode)
224 : mLastRead(0), mGood(false), mEof(false), mFail(true), mLocalError(0) {
225 open(path, mode);
226}
227
229 : mHandle(handle), mLastRead(0), mGood(false), mEof(false), mFail(true), mLocalError(0) {
230 updateState();
231}
232
236
237void fstream::open(const char* path, ios::openmode mode) {
238 close();
239
240 // Build fopen mode string for read+write
241 const char* fmode;
242 if (mode & ios::app) {
243 fmode = (mode & ios::binary) ? "a+b" : "a+";
244 } else if (mode & ios::trunc) {
245 fmode = (mode & ios::binary) ? "w+b" : "w+";
246 } else {
247 fmode = (mode & ios::binary) ? "r+b" : "r+";
248 }
249
251
252 if (mHandle->is_open()) {
253 if (mode & ios::ate) {
254 mHandle->seek(0, seek_dir::end);
255 }
256 updateState();
257 } else {
258 updateState();
259 }
260}
261
263 if (mHandle && mHandle->is_open()) {
264 mHandle->close();
265 // After successful close: keep good() = true to match std::ofstream behavior
266 // This allows fs_stub.hpp's createTextFile to work correctly
267 if (!mHandle->has_error()) {
268 mGood = true;
269 mEof = false;
270 mFail = false;
271 } else {
272 updateState();
273 }
274 }
275}
276
277fstream& fstream::read(char* buffer, fl::size_t count) {
278 mLastRead = 0;
279 if (mHandle && mHandle->is_open()) {
280 mLastRead = mHandle->read(buffer, count);
281 updateState();
282 }
283 return *this;
284}
285
286fstream& fstream::write(const char* data, fl::size_t count) {
287 if (mHandle && mHandle->is_open()) {
288 fl::size_t written = mHandle->write(data, count);
289 if (written != count) {
290 mFail = true;
291 mGood = false;
292 }
293 updateState();
294 } else {
295 // Writing to closed stream - set bad file error
297 mFail = true;
298 mGood = false;
299 }
300 return *this;
301}
302
304 if (!mHandle) {
305 return 0;
306 }
307 return mHandle->tell();
308}
309
311 if (mHandle && mHandle->is_open()) {
312 seek_dir seek_direction =
315 mHandle->seek(pos, seek_direction);
316 updateState();
317 }
318 return *this;
319}
320
321int fstream::error() const {
322 if (mLocalError != 0) {
323 return mLocalError;
324 }
325 if (!mHandle) {
327 }
328 return mHandle->error_code();
329}
330
331const char* fstream::error_message() const {
332 if (mLocalError != 0) {
333#ifdef FASTLED_TESTING
335#else
336 return "Write to closed stream";
337#endif
338 }
339 if (!mHandle) {
340 return "No handle";
341 }
342 return mHandle->error_message();
343}
344
346 mLocalError = 0;
347 if (mHandle) {
348 mHandle->clear_error();
349 }
350 mFail = false;
351 updateState();
352}
353
354} // namespace fl
uint8_t pos
Definition Blur.ino:11
const char * error_message() const
fstream & write(const char *data, fl::size_t count)
bool mGood
Definition fstream.h:303
bool mEof
Definition fstream.h:304
~fstream() FL_NOEXCEPT
fl::size_t tellg()
fstream & seekg(fl::size_t pos, ios::seekdir dir=ios::seekdir::beg)
void updateState()
Definition fstream.h:308
filebuf_ptr mHandle
Definition fstream.h:301
fstream() FL_NOEXCEPT
Definition fstream.h:321
void clear_error()
bool mFail
Definition fstream.h:305
void open(const char *path, ios::openmode mode=ios::in|ios::out)
fl::size_t mLastRead
Definition fstream.h:302
fstream & read(char *buffer, fl::size_t count)
int mLocalError
Definition fstream.h:306
int error() const
filebuf_ptr mHandle
Definition fstream.h:50
void open(const char *path, ios::openmode mode=ios::in)
bool mEof
Definition fstream.h:53
const char * error_message() const
~ifstream() FL_NOEXCEPT
ifstream & read(char *buffer, fl::size_t count)
const char * path() const
Definition fstream.h:156
int error() const
fl::size_t mLastRead
Definition fstream.h:51
bool mFail
Definition fstream.h:54
ifstream & seekg(fl::size_t pos, ios::seekdir dir=ios::seekdir::beg)
fl::size_t pos() const
Definition fstream.h:189
bool mGood
Definition fstream.h:52
ifstream() FL_NOEXCEPT
Definition fstream.h:69
fl::size_t tellg()
void updateState()
Definition fstream.h:56
ofstream & write(const char *data, fl::size_t count)
const char * error_message() const
ofstream() FL_NOEXCEPT
Definition fstream.h:228
void open(const char *path, ios::openmode mode=ios::out)
int error() const
int mLocalError
Definition fstream.h:213
~ofstream() FL_NOEXCEPT
void updateState()
Definition fstream.h:215
filebuf_ptr mHandle
Definition fstream.h:209
__SIZE_TYPE__ size_t
Definition s16x16x4.h:16
constexpr int err_bad_file
Definition file_io.h:45
static constexpr openmode ate
Definition fstream.h:30
static constexpr openmode trunc
Definition fstream.h:33
static constexpr openmode binary
Definition fstream.h:29
static constexpr openmode app
Definition fstream.h:34
unsigned int openmode
Definition fstream.h:28
seek_dir
Definition file_handle.h:19
char * strerror(int errnum) FL_NOEXCEPT
shared_ptr< T > make_shared(Args &&... args) FL_NOEXCEPT
Definition shared_ptr.h:414
fl::shared_ptr< filebuf > filebuf_ptr
Definition idecoder.h:15
Base definition for an LED controller.
Definition crgb.hpp:179
#define FL_NOEXCEPT