FastLED 3.9.15
Loading...
Searching...
No Matches
file_system.cpp.hpp
Go to the documentation of this file.
3#include "fl/log/log.h"
4#include "fl/stl/vector.h"
5#include "fl/math/math.h"
6
7// NOTE: SD card support (FileSystem::beginSd and make_sdcard_filesystem)
8// lives in a SEPARATE translation unit at
9// `src/fl/system/sd/file_system_sd.cpp.hpp`, compiled into
10// `fl.system.sd+.cpp.o` via `src/fl/build/fl.system.sd+.cpp`.
11//
12// This split lets the linker tree-shake the entire SD chain (libSD.a,
13// libFS.a, Arduino's VFSImpl, the printf engine VFSFileImpl drags in
14// via snprintf) AUTOMATICALLY when the user never calls
15// `FileSystem::beginSd()` — no FASTLED_USE_SDCARD opt-in required, and
16// the macro that the earlier macro-gate PR (#2778 v1) shipped is
17// removed by this PR. See FastLED #2773 item 1.2 and the SD TU header
18// for the mechanism.
19//
20// All other FileSystem methods (begin, openRead, readText, ...) and the
21// NullFileSystem stub stay here, so existing sketches that use only
22// `FileSystem::begin(platform_filesystem)` are unaffected.
23
24#include "fl/stl/json.h"
25#include "fl/math/screenmap.h"
26#include "fl/math/math.h" // for min
27#include "fl/stl/cstring.h"
28#include "fl/stl/noexcept.h"
29
30// Codec-dependent methods (openMp3, loadJpeg, openMpeg1Video, Mpeg1FileHandle)
31// moved to fl/codec/file_system_codecs.cpp.hpp to break fl.system+ -> fl.codec+ chain.
32
33namespace fl {
34
35class NullFileHandle : public filebuf {
36 public:
39
40 bool is_open() const override { return false; }
41 fl::size_t size() const override { return 0; }
42 fl::size_t read(char *dst, fl::size_t bytesToRead) override {
43 FASTLED_UNUSED(dst);
44 FASTLED_UNUSED(bytesToRead);
45 return 0;
46 }
47 fl::size_t write(const char *data, fl::size_t count) override {
48 FASTLED_UNUSED(data);
49 FASTLED_UNUSED(count);
50 return 0;
51 }
52 fl::size_t tell() override { return 0; }
53 const char *path() const override { return "nullptr filebuf"; }
54 bool seek(fl::size_t pos, seek_dir dir) override {
56 FASTLED_UNUSED(dir);
57 return false;
58 }
59 using filebuf::seek; // single-arg overload
60 void close() override {}
61 bool is_eof() const override { return true; }
62 bool has_error() const override { return false; }
63 void clear_error() override {}
64 int error_code() const override { return 0; }
65 const char *error_message() const override { return "NullFileHandle"; }
66};
67
68class NullFileSystem : public FsImpl {
69 public:
71 FL_WARN("NullFileSystem instantiated as a placeholder, please "
72 "implement a file system for your platform.");
73 }
75
76 bool begin() override { return true; }
77 void end() override {}
78
79 filebuf_ptr openRead(const char *_path) override {
80 FASTLED_UNUSED(_path);
82 filebuf_ptr out = ptr;
83 return out;
84 }
85};
86
87
88// FileSystem::beginSd() is intentionally NOT defined in this TU. The
89// definition lives in `fl/system/sd/file_system_sd.cpp.hpp` which is
90// compiled into its own `.o` (`fl.system.sd+.cpp.o`). The linker only
91// pulls that `.o` when the user actually calls `fs.beginSd(...)`,
92// keeping all SD library code (~15 KB on ESP32-S3) out of sketches that
93// don't use it. See FastLED #2773 item 1.2.
94
95bool FileSystem::begin(FsImplPtr platform_filesystem) {
96 mFs = platform_filesystem;
97 if (!mFs) {
98 return false;
99 }
100 mFs->begin();
101 return true;
102}
103
105
107 if (mFs) {
108 mFs->end();
109 }
110}
111
112bool FileSystem::readJson(const char *path, json *doc) {
113 string text;
114 if (!readText(path, &text)) {
115 return false;
116 }
117
118 // Parse using the new json class
119 *doc = fl::json::parse(text);
120 return !doc->is_null();
121}
122
123bool FileSystem::readScreenMaps(const char *path,
124 fl::flat_map<string, ScreenMap> *out, string *error) {
125 string text;
126 if (!readText(path, &text)) {
127 FL_WARN("Failed to read file: " << path);
128 if (error) {
129 *error = "Failed to read file: ";
130 error->append(path);
131 }
132 return false;
133 }
134 string err;
135 bool ok = ScreenMap::ParseJson(text.c_str(), out, &err);
136 if (!ok) {
137 FL_WARN("Failed to parse screen map: " << err.c_str());
138 *error = err;
139 return false;
140 }
141 return true;
142}
143
144bool FileSystem::readScreenMap(const char *path, const char *name,
145 ScreenMap *out, string *error) {
146 string text;
147 if (!readText(path, &text)) {
148 FL_WARN("Failed to read file: " << path);
149 if (error) {
150 *error = "Failed to read file: ";
151 error->append(path);
152 }
153 return false;
154 }
155 string err;
156 bool ok = ScreenMap::ParseJson(text.c_str(), name, out, &err);
157 if (!ok) {
158 FL_WARN("Failed to parse screen map: " << err.c_str());
159 *error = err;
160 return false;
161 }
162 return true;
163}
164
166 return fl::ifstream(mFs->openRead(path));
167}
168Video FileSystem::openVideo(const char *path, fl::size pixelsPerFrame, float fps,
169 fl::size nFrameHistory) {
170 Video video(pixelsPerFrame, fps, nFrameHistory);
171 fl::ifstream file = openRead(path);
172 if (!file.is_open()) {
173 video.setError(fl::string("Could not open file: ").append(path));
174 return video;
175 }
176 video.begin(file.rdbuf());
177 return video;
178}
179
180bool FileSystem::readText(const char *path, fl::string *out) {
181 fl::ifstream file = openRead(path);
182 if (!file.is_open()) {
183 FL_WARN("Failed to open file: " << path);
184 return false;
185 }
186 fl::size size = file.size();
187 out->reserve(size + out->size());
188 bool wrote = false;
189 while (file.available()) {
190 u8 buf[64];
191 fl::size n = file.read(buf, sizeof(buf));
192 out->append((const char *)buf, n);
193 wrote = true;
194 }
195 file.close();
196 FL_DBG_IF(!wrote, "Failed to write any data to the output string.");
197 return wrote;
198}
199
200} // namespace fl
201
202// `make_sdcard_filesystem(int cs_pin)` is defined in the separate SD TU
203// (`fl/system/sd/file_system_sd.cpp.hpp`). When the SD TU is not linked
204// (the user never calls `fs.beginSd()`), the symbol is also dead-stripped
205// alongside `FileSystem::beginSd` itself.
bool readText(const char *path, string *out)
bool readJson(const char *path, json *doc)
fl::ifstream openRead(const char *path)
bool readScreenMap(const char *path, const char *name, ScreenMap *out, string *error=nullptr)
FileSystem() FL_NOEXCEPT
bool begin(FsImplPtr platform_filesystem)
Video openVideo(const char *path, fl::size pixelsPerFrame, float fps=30.0f, fl::size nFrameHistory=0)
FsImplPtr mFs
Definition file_system.h:82
bool readScreenMaps(const char *path, fl::flat_map< string, ScreenMap > *out, string *error=nullptr)
FsImpl() FL_NOEXCEPT=default
int error_code() const override
const char * path() const override
bool is_eof() const override
fl::size_t tell() override
bool is_open() const override
fl::size_t size() const override
fl::size_t read(char *dst, fl::size_t bytesToRead) override
bool seek(fl::size_t pos, seek_dir dir) override
void clear_error() override
const char * error_message() const override
void close() override
bool has_error() const override
fl::size_t write(const char *data, fl::size_t count) override
NullFileHandle() FL_NOEXCEPT=default
NullFileSystem() FL_NOEXCEPT
void end() override
bool begin() override
~NullFileSystem() FL_NOEXCEPT override
filebuf_ptr openRead(const char *_path) override
static bool ParseJson(const char *jsonStrScreenMap, fl::flat_map< string, ScreenMap > *segmentMaps, string *err=nullptr) FL_NOEXCEPT
void reserve(fl::size newCapacity) FL_NOEXCEPT
const char * c_str() const FL_NOEXCEPT
fl::size size() const FL_NOEXCEPT
virtual bool seek(fl::size_t pos, seek_dir dir)=0
fl::size_t pos() const
bool available() const
Definition fstream.h:161
fl::size_t size() const
Definition fstream.h:146
ifstream & read(char *buffer, fl::size_t count)
bool is_open() const
Definition fstream.h:111
filebuf_ptr rdbuf() const
Definition fstream.h:143
bool is_null() const FL_NOEXCEPT
Definition json.h:238
static json parse(const fl::string &txt) FL_NOEXCEPT
Definition json.h:677
string & append(const bitset_fixed< N > &bs) FL_NOEXCEPT
Definition string.h:284
FastLED's Elegant JSON Library: fl::json
#define FL_DBG_IF
Definition log.h:389
#define FL_WARN(X)
Definition log.h:276
Centralized logging categories for FastLED hardware interfaces and subsystems.
__SIZE_TYPE__ size_t
Definition s16x16x4.h:16
unsigned char u8
Definition stdint.h:131
seek_dir
Definition file_handle.h:19
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 FASTLED_UNUSED(x)
#define FL_NOEXCEPT