FastLED 3.10.8
Loading...
Searching...
No Matches
fstream.h
Go to the documentation of this file.
1#pragma once
2
3#include "fl/stl/int.h"
4#include "fl/stl/bit_cast.h"
5#include "fl/fs/file_handle.h"
6#include "fl/stl/shared_ptr.h"
7
8// Platform-aware file stream implementation (analogous to std::ifstream / std::ofstream)
9// - Host/Testing platforms (FASTLED_TESTING): Full file I/O implementation via posix_filebuf
10// - Embedded platforms (ESP32, Uno, etc.): No-op stubs (no file system support)
11//
12// These stream classes accept any filebuf subclass via shared_ptr,
13// enabling polymorphic dispatch to different backends (POSIX, SD card, WASM, memory).
14
15#ifdef FASTLED_TESTING
16#include "fl/stl/cstring.h" // For fl::strerror
17#include "fl/stl/noexcept.h"
18#endif
19
20namespace fl {
21
22// Shared pointer to the polymorphic backend
23using filebuf_ptr = fl::shared_ptr<filebuf>;
24
25// File stream mode flags and seek directions
26namespace ios {
27 // Mode flags (bitmask)
28 using openmode = unsigned int;
29 static constexpr openmode binary = 0x01; // Binary mode
30 static constexpr openmode ate = 0x02; // Seek to end after opening
31 static constexpr openmode in = 0x04; // Open for reading
32 static constexpr openmode out = 0x08; // Open for writing
33 static constexpr openmode trunc = 0x10; // Truncate file if exists
34 static constexpr openmode app = 0x20; // Append mode
35
36 // Seek direction
37 enum class seekdir {
38 beg = 0, // Beginning of file
39 cur = 1, // Current position
40 end = 2 // End of file
41 };
42}
43
44// ============================================================================
45// Input file stream (analogous to std::ifstream)
46// ============================================================================
47
48class ifstream {
49private:
52 bool mGood;
53 bool mEof;
54 bool mFail;
55
57 if (mHandle && mHandle->is_open()) {
58 mEof = mHandle->is_eof();
59 mFail = mHandle->has_error();
60 mGood = !mEof && !mFail;
61 } else {
62 mGood = false;
63 mEof = false;
64 mFail = true;
65 }
66 }
67
68public:
69 ifstream() FL_NO_EXCEPT : mLastRead(0), mGood(false), mEof(false), mFail(true) {}
70
71 explicit ifstream(const char* path, ios::openmode mode = ios::in) FL_NO_EXCEPT;
72
73 explicit ifstream(filebuf_ptr handle) FL_NO_EXCEPT;
74
76
77 // Non-copyable
78 ifstream(const ifstream&) FL_NO_EXCEPT = delete;
79 ifstream& operator=(const ifstream&) = delete;
80
81 // Moveable
83 : mHandle(other.mHandle), mLastRead(other.mLastRead),
84 mGood(other.mGood), mEof(other.mEof), mFail(other.mFail) {
85 other.mHandle.reset();
86 other.mLastRead = 0;
87 other.mGood = false;
88 other.mEof = false;
89 other.mFail = true;
90 }
91
93 if (this != &other) {
94 close();
95 mHandle = other.mHandle;
96 mLastRead = other.mLastRead;
97 mGood = other.mGood;
98 mEof = other.mEof;
99 mFail = other.mFail;
100 other.mHandle.reset();
101 other.mLastRead = 0;
102 other.mGood = false;
103 other.mEof = false;
104 other.mFail = true;
105 }
106 return *this;
107 }
108
109 void open(const char* path, ios::openmode mode = ios::in) FL_NO_EXCEPT;
110
111 bool is_open() const FL_NO_EXCEPT {
112 return mHandle && mHandle->is_open();
113 }
114
115 void close() FL_NO_EXCEPT;
116
117 ifstream& read(char* buffer, fl::size_t count) FL_NO_EXCEPT;
118
119 fl::size_t gcount() const FL_NO_EXCEPT {
120 return mLastRead;
121 }
122
124
125 ifstream& seekg(fl::size_t pos, ios::seekdir dir = ios::seekdir::beg) FL_NO_EXCEPT;
126
127 bool good() const FL_NO_EXCEPT { return mGood; }
128 bool eof() const FL_NO_EXCEPT { return mEof; }
129 bool fail() const FL_NO_EXCEPT { return mFail; }
130
131 // Get last error code (0 if no error)
132 int error() const FL_NO_EXCEPT;
133
134 // Get human-readable error message
135 const char* error_message() const FL_NO_EXCEPT;
136
137 // Manually clear error state (for retry scenarios)
139
140 // --- Enriched API (forwarded from filebuf) ---
141
142 // Access the underlying buffer (like std::ifstream::rdbuf())
144
145 // Total file size in bytes
147 return mHandle ? mHandle->size() : 0;
148 }
149
150 // Bytes remaining from current position to end
152 return mHandle ? mHandle->bytes_left() : 0;
153 }
154
155 // File path (or description for non-file buffers)
156 const char* path() const FL_NO_EXCEPT {
157 return mHandle ? mHandle->path() : "";
158 }
159
160 // Check if data is available for reading
161 bool available() const FL_NO_EXCEPT {
162 return mHandle ? mHandle->available() : false;
163 }
164
165 // Check if at least n bytes are available
167 return mHandle ? mHandle->available(n) : false;
168 }
169
170 // Convenience: read into u8 buffer
175
176 // Convenience: read into u8 span
178 return read(dst.data(), dst.size());
179 }
180
181 // Convenience: read RGB8 pixels (3 bytes per pixel)
183 read(fl::reinterpret_cast_<char*>(dst.data()), dst.size() * 3);
184 return mLastRead / 3;
185 }
186
187 // Backward-compat aliases
188 bool valid() const FL_NO_EXCEPT { return is_open(); }
189 fl::size_t pos() const FL_NO_EXCEPT { return mHandle ? mHandle->pos() : 0; }
193 return good();
194 }
198 seekg(p, d);
199 return good();
200 }
201};
202
203// ============================================================================
204// Output file stream (analogous to std::ofstream)
205// ============================================================================
206
207class ofstream {
208private:
210 bool mGood;
211 bool mEof;
212 bool mFail;
214
216 if (mHandle && mHandle->is_open()) {
217 mEof = mHandle->is_eof();
218 mFail = mHandle->has_error() || (mLocalError != 0);
219 mGood = !mEof && !mFail;
220 } else {
221 mGood = false;
222 mEof = false;
223 mFail = true;
224 }
225 }
226
227public:
228 ofstream() FL_NO_EXCEPT : mGood(false), mEof(false), mFail(true), mLocalError(0) {}
229
230 explicit ofstream(const char* path, ios::openmode mode = ios::out) FL_NO_EXCEPT;
231
232 explicit ofstream(filebuf_ptr handle) FL_NO_EXCEPT;
233
235
236 // Non-copyable
238 ofstream& operator=(const ofstream&) = delete;
239
240 // Moveable
242 : mHandle(other.mHandle), mGood(other.mGood), mEof(other.mEof),
243 mFail(other.mFail), mLocalError(other.mLocalError) {
244 other.mHandle.reset();
245 other.mGood = false;
246 other.mEof = false;
247 other.mFail = true;
248 other.mLocalError = 0;
249 }
250
252 if (this != &other) {
253 close();
254 mHandle = other.mHandle;
255 mGood = other.mGood;
256 mEof = other.mEof;
257 mFail = other.mFail;
258 mLocalError = other.mLocalError;
259 other.mHandle.reset();
260 other.mGood = false;
261 other.mEof = false;
262 other.mFail = true;
263 other.mLocalError = 0;
264 }
265 return *this;
266 }
267
268 void open(const char* path, ios::openmode mode = ios::out) FL_NO_EXCEPT;
269
270 bool is_open() const FL_NO_EXCEPT {
271 return mHandle && mHandle->is_open();
272 }
273
274 void close() FL_NO_EXCEPT;
275
276 ofstream& write(const char* data, fl::size_t count) FL_NO_EXCEPT;
277
278 bool good() const FL_NO_EXCEPT { return mGood; }
279 bool eof() const FL_NO_EXCEPT { return mEof; }
280 bool fail() const FL_NO_EXCEPT { return mFail; }
281
282 // Get last error code (0 if no error)
283 int error() const FL_NO_EXCEPT;
284
285 // Get human-readable error message
286 const char* error_message() const FL_NO_EXCEPT;
287
288 // Manually clear error state (for retry scenarios)
290
291 // Access the underlying buffer
293};
294
295// ============================================================================
296// Generic file stream (supports both reading and writing)
297// ============================================================================
298
299class fstream {
300private:
303 bool mGood;
304 bool mEof;
305 bool mFail;
307
309 if (mHandle && mHandle->is_open()) {
310 mEof = mHandle->is_eof();
311 mFail = mHandle->has_error() || (mLocalError != 0);
312 mGood = !mEof && !mFail;
313 } else {
314 mGood = false;
315 mEof = false;
316 mFail = true;
317 }
318 }
319
320public:
321 fstream() FL_NO_EXCEPT : mLastRead(0), mGood(false), mEof(false), mFail(true), mLocalError(0) {}
322
323 explicit fstream(const char* path, ios::openmode mode = ios::in | ios::out) FL_NO_EXCEPT;
324
325 explicit fstream(filebuf_ptr handle) FL_NO_EXCEPT;
326
328
329 // Non-copyable
330 fstream(const fstream&) FL_NO_EXCEPT = delete;
331 fstream& operator=(const fstream&) = delete;
332
333 // Moveable
335 : mHandle(other.mHandle), mLastRead(other.mLastRead),
336 mGood(other.mGood), mEof(other.mEof), mFail(other.mFail),
337 mLocalError(other.mLocalError) {
338 other.mHandle.reset();
339 other.mLastRead = 0;
340 other.mGood = false;
341 other.mEof = false;
342 other.mFail = true;
343 other.mLocalError = 0;
344 }
345
347 if (this != &other) {
348 close();
349 mHandle = other.mHandle;
350 mLastRead = other.mLastRead;
351 mGood = other.mGood;
352 mEof = other.mEof;
353 mFail = other.mFail;
354 mLocalError = other.mLocalError;
355 other.mHandle.reset();
356 other.mLastRead = 0;
357 other.mGood = false;
358 other.mEof = false;
359 other.mFail = true;
360 other.mLocalError = 0;
361 }
362 return *this;
363 }
364
365 void open(const char* path, ios::openmode mode = ios::in | ios::out) FL_NO_EXCEPT;
366
367 bool is_open() const FL_NO_EXCEPT {
368 return mHandle && mHandle->is_open();
369 }
370
371 void close() FL_NO_EXCEPT;
372
373 fstream& read(char* buffer, fl::size_t count) FL_NO_EXCEPT;
374
375 fl::size_t gcount() const FL_NO_EXCEPT {
376 return mLastRead;
377 }
378
379 fstream& write(const char* data, fl::size_t count) FL_NO_EXCEPT;
380
382
383 fstream& seekg(fl::size_t pos, ios::seekdir dir = ios::seekdir::beg) FL_NO_EXCEPT;
384
385 bool good() const FL_NO_EXCEPT { return mGood; }
386 bool eof() const FL_NO_EXCEPT { return mEof; }
387 bool fail() const FL_NO_EXCEPT { return mFail; }
388
389 // Get last error code (0 if no error)
390 int error() const FL_NO_EXCEPT;
391
392 // Get human-readable error message
393 const char* error_message() const FL_NO_EXCEPT;
394
395 // Manually clear error state (for retry scenarios)
397
398 // Access the underlying buffer
400};
401
402} // namespace fl
uint8_t pos
Definition Blur.ino:11
filebuf_ptr rdbuf() const FL_NO_EXCEPT
Definition fstream.h:399
int error() const FL_NO_EXCEPT
void open(const char *path, ios::openmode mode=ios::in|ios::out) FL_NO_EXCEPT
void updateState() FL_NO_EXCEPT
Definition fstream.h:308
bool mGood
Definition fstream.h:303
bool mEof
Definition fstream.h:304
const char * error_message() const FL_NO_EXCEPT
filebuf_ptr mHandle
Definition fstream.h:301
void close() FL_NO_EXCEPT
fstream & seekg(fl::size_t pos, ios::seekdir dir=ios::seekdir::beg) FL_NO_EXCEPT
void clear_error() FL_NO_EXCEPT
fl::size_t tellg() FL_NO_EXCEPT
~fstream() FL_NO_EXCEPT
fl::size_t gcount() const FL_NO_EXCEPT
Definition fstream.h:375
fstream & write(const char *data, fl::size_t count) FL_NO_EXCEPT
fstream & operator=(fstream &&other) FL_NO_EXCEPT
Definition fstream.h:346
bool mFail
Definition fstream.h:305
fl::size_t mLastRead
Definition fstream.h:302
fstream() FL_NO_EXCEPT
Definition fstream.h:321
bool eof() const FL_NO_EXCEPT
Definition fstream.h:386
bool is_open() const FL_NO_EXCEPT
Definition fstream.h:367
int mLocalError
Definition fstream.h:306
bool good() const FL_NO_EXCEPT
Definition fstream.h:385
bool fail() const FL_NO_EXCEPT
Definition fstream.h:387
fl::size_t bytes_left() const FL_NO_EXCEPT
Definition fstream.h:151
filebuf_ptr mHandle
Definition fstream.h:50
bool mEof
Definition fstream.h:53
fl::size_t size() const FL_NO_EXCEPT
Definition fstream.h:146
void clear_error() FL_NO_EXCEPT
fl::size_t read(fl::u8 *dst, fl::size_t n) FL_NO_EXCEPT
Definition fstream.h:171
fl::size_t gcount() const FL_NO_EXCEPT
Definition fstream.h:119
bool seek(fl::size_t p) FL_NO_EXCEPT
Definition fstream.h:191
int error() const FL_NO_EXCEPT
bool available(fl::size_t n) const FL_NO_EXCEPT
Definition fstream.h:166
fl::size_t pos() const FL_NO_EXCEPT
Definition fstream.h:189
bool available() const FL_NO_EXCEPT
Definition fstream.h:161
bool is_open() const FL_NO_EXCEPT
Definition fstream.h:111
ifstream & seekg(fl::size_t pos, ios::seekdir dir=ios::seekdir::beg) FL_NO_EXCEPT
void open(const char *path, ios::openmode mode=ios::in) FL_NO_EXCEPT
fl::size_t readRGB8(fl::span< CRGB > dst) FL_NO_EXCEPT
Definition fstream.h:182
void updateState() FL_NO_EXCEPT
Definition fstream.h:56
fl::size_t mLastRead
Definition fstream.h:51
filebuf_ptr rdbuf() const FL_NO_EXCEPT
Definition fstream.h:143
ifstream() FL_NO_EXCEPT
Definition fstream.h:69
bool good() const FL_NO_EXCEPT
Definition fstream.h:127
const char * error_message() const FL_NO_EXCEPT
bool mFail
Definition fstream.h:54
fl::size_t bytesLeft() const FL_NO_EXCEPT
Definition fstream.h:190
bool seek(fl::size_t p, seek_dir dir) FL_NO_EXCEPT
Definition fstream.h:195
ifstream & operator=(ifstream &&other) FL_NO_EXCEPT
Definition fstream.h:92
void close() FL_NO_EXCEPT
bool mGood
Definition fstream.h:52
bool fail() const FL_NO_EXCEPT
Definition fstream.h:129
fl::size_t tellg() FL_NO_EXCEPT
fl::size_t read(fl::span< fl::u8 > dst) FL_NO_EXCEPT
Definition fstream.h:177
const char * path() const FL_NO_EXCEPT
Definition fstream.h:156
bool eof() const FL_NO_EXCEPT
Definition fstream.h:128
~ifstream() FL_NO_EXCEPT
bool valid() const FL_NO_EXCEPT
Definition fstream.h:188
bool fail() const FL_NO_EXCEPT
Definition fstream.h:280
void clear_error() FL_NO_EXCEPT
ofstream() FL_NO_EXCEPT
Definition fstream.h:228
bool good() const FL_NO_EXCEPT
Definition fstream.h:278
const char * error_message() const FL_NO_EXCEPT
filebuf_ptr rdbuf() const FL_NO_EXCEPT
Definition fstream.h:292
void open(const char *path, ios::openmode mode=ios::out) FL_NO_EXCEPT
bool is_open() const FL_NO_EXCEPT
Definition fstream.h:270
bool eof() const FL_NO_EXCEPT
Definition fstream.h:279
void updateState() FL_NO_EXCEPT
Definition fstream.h:215
ofstream & operator=(ofstream &&other) FL_NO_EXCEPT
Definition fstream.h:251
ofstream & write(const char *data, fl::size_t count) FL_NO_EXCEPT
~ofstream() FL_NO_EXCEPT
int mLocalError
Definition fstream.h:213
filebuf_ptr mHandle
Definition fstream.h:209
void close() FL_NO_EXCEPT
int error() const FL_NO_EXCEPT
__SIZE_TYPE__ size_t
Definition s16x16x4.h:16
static constexpr openmode in
Definition fstream.h:31
static constexpr openmode ate
Definition fstream.h:30
static constexpr openmode trunc
Definition fstream.h:33
static constexpr openmode out
Definition fstream.h:32
static constexpr openmode binary
Definition fstream.h:29
static constexpr openmode app
Definition fstream.h:34
unsigned int openmode
Definition fstream.h:28
unsigned char u8
Definition stdint.h:131
u8 u8 fract8 blur_amount FL_NO_EXCEPT
Definition blur.h:186
seek_dir
Definition file_handle.h:20
int read() FL_NO_EXCEPT
To reinterpret_cast_(const From &from) FL_NO_EXCEPT
Definition bit_cast.h:88
fl::shared_ptr< filebuf > filebuf_ptr
Definition idecoder.h:15
Base definition for an LED controller.
Definition crgb.hpp:179