Logo Pico-Framework A web-first embedded framework for C++
Loading...
Searching...
No Matches
FatFsStorageManager Class Reference

Concrete implementation of StorageManager using FatFs. More...

#include <FatFsStorageManager.h>

+ Inheritance diagram for FatFsStorageManager:
+ Collaboration diagram for FatFsStorageManager:

Public Member Functions

 FatFsStorageManager ()
 Construct a new FatFsStorageManager object.
 
bool mount () override
 Mount the filesystem at the specified mount point.
 
bool unmount () override
 Unmount the filesystem.
 
bool exists (const std::string &path) override
 Check if the path exists.
 
bool remove (const std::string &path) override
 Remove a file or directory at the specified path.
 
bool rename (const std::string &from, const std::string &to) override
 Rename a file or directory.
 
bool readFile (const std::string &path, std::vector< uint8_t > &buffer) override
 Read a file into a memory buffer.
 
bool readFileString (const std::string &path, uint32_t startPosition, uint32_t length, std::string &buffer)
 Read a file string into a std::string.
 
bool writeFile (const std::string &path, const std::vector< uint8_t > &data) override
 Write a memory buffer to a file.
 
bool writeFile (const std::string &path, const unsigned char *data, size_t size) override
 Write raw data to a file.
 
bool streamFile (const std::string &path, std::function< void(const uint8_t *, size_t)> chunkCallback) override
 Stream a file in chunks via callback.
 
bool listDirectory (const std::string &path, std::vector< FileInfo > &out) override
 List the contents of a directory.
 
bool createDirectory (const std::string &path) override
 Create a directory at the specified path.
 
bool removeDirectory (const std::string &path) override
 Remove a directory at the specified path.
 
size_t getFileSize (const std::string &path) override
 Get the size of a file.
 
bool appendToFile (const std::string &path, const uint8_t *data, size_t size) override
 Append data to a file.
 
bool isMounted () const override
 Check if the filesystem is currently mounted.
 
bool formatStorage () override
 Format the storage device.
 
std::unique_ptr< StorageFileReaderopenReader (const std::string &path) override
 open a file for streaming read access.
 
- Public Member Functions inherited from StorageManager
virtual ~StorageManager ()=default
 

Private Member Functions

std::string resolvePath (const std::string &path) const
 Helper function to normalize full path based on mountPoint and relative path.
 
bool ensureMounted ()
 
bool probeMountPoint ()
 
void refreshMountState ()
 

Private Attributes

bool mounted = false
 Indicates if the filesystem is currently mounted.
 
std::string mountPoint = "sd0"
 Default mount point.
 
SemaphoreHandle_t mutex
 Optional lock for thread safety.
 

Detailed Description

Definition at line 30 of file FatFsStorageManager.h.

Constructor & Destructor Documentation

◆ FatFsStorageManager()

FatFsStorageManager::FatFsStorageManager ( )

Construct a new FatFsStorageManager object.

Definition at line 27 of file FatFsStorageManager.cpp.

27{}

Member Function Documentation

◆ appendToFile()

bool FatFsStorageManager::appendToFile ( const std::string &  path,
const uint8_t *  data,
size_t  size 
)
overridevirtual

Append data to a file.

Parameters
pathPath to the file.
dataPointer to the data buffer.
sizeSize of the data buffer.
Returns
true if successful, false otherwise.
Note
If the file does not exist, it will be created. If the file exists, data will be appended to the end.
Parameters
pathPath to the file.
dataPointer to the data buffer.
sizeSize of the data buffer.
Returns
true if successful, false otherwise.
Note
If the file does not exist, it will be created. If the file exists, data will be appended to the end.

Implements StorageManager.

Definition at line 269 of file FatFsStorageManager.cpp.

270{
271 if (!ensureMounted())
272 {
273 TRACE("SD card not mounted — cannot append to file: %s\n", path.c_str());
274 return false;
275 }
276 FF_FILE *file = ff_fopen(resolvePath(path).c_str(), "a");
277 if (!file)
278 return false;
279
280 size_t written = ff_fwrite(data, 1, size, file);
281 ff_fclose(file);
282 return written == size;
283}
#define TRACE(...)
Default trace (INFO level).
Definition DebugTrace.h:187
std::string resolvePath(const std::string &path) const
Helper function to normalize full path based on mountPoint and relative path.

References ensureMounted(), resolvePath(), and TRACE.

+ Here is the call graph for this function:

◆ createDirectory()

bool FatFsStorageManager::createDirectory ( const std::string &  path)
overridevirtual
Parameters
pathPath to create the directory.
Returns
true if successful, false otherwise.

Implements StorageManager.

Definition at line 120 of file FatFsStorageManager.cpp.

121{
122 if (!ensureMounted())
123 {
124 TRACE("SD card not mounted — cannot create directory: %s\n", path.c_str());
125 return false;
126 }
127 TRACE("[FatFs] Creating directory: %s\n", path.c_str());
128 return ff_mkdir(resolvePath(path).c_str()) == FF_ERR_NONE;
129}

References ensureMounted(), resolvePath(), and TRACE.

+ Here is the call graph for this function:

◆ ensureMounted()

bool FatFsStorageManager::ensureMounted ( )
private

Definition at line 319 of file FatFsStorageManager.cpp.

320{
321 if (!mounted)
322 {
323 return mount();
324 }
325 return true;
326}
bool mount() override
Mount the filesystem at the specified mount point.
bool mounted
Indicates if the filesystem is currently mounted.

References mount(), and mounted.

Referenced by appendToFile(), createDirectory(), exists(), getFileSize(), listDirectory(), openReader(), readFile(), readFileString(), remove(), removeDirectory(), rename(), streamFile(), writeFile(), and writeFile().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ exists()

bool FatFsStorageManager::exists ( const std::string &  path)
overridevirtual

Check if the path exists.

Returns
true if so, false otherwise.
Returns
true if so, false otherwise.

Implements StorageManager.

Definition at line 65 of file FatFsStorageManager.cpp.

66{
67 TRACE("[FatFs] Checking if path exists: %s\n", path.c_str());
68 if (!ensureMounted())
69 {
70 printf("[FatFs] SD card not mounted — cannot check path exists: %s\n", path.c_str());
71 return false;
72 }
73 TRACE("[FatFs] Checking if exists: %s\n", resolvePath(path).c_str());
74 FF_Stat_t xStat;
75
76 // Use ff_stat to check if the file or directory exists
77 TRACE("[FatFs] Calling ff_stat on path: %s\n",resolvePath(path).c_str());
78 int err = ff_stat(resolvePath(path).c_str(), &xStat);
79 TRACE("[FatFs] ff_stat returned: %d\n", err);
80 if (err == FF_ERR_NONE){
81 TRACE("[FatFs] Path exists: %s, size: %ld bytes\n", resolvePath(path).c_str(), xStat.st_size);
82 return true;
83 }
84 TRACE("Path does not exist: %s\n", path.c_str());
85 return false;
86}

References ensureMounted(), resolvePath(), and TRACE.

+ Here is the call graph for this function:

◆ formatStorage()

bool FatFsStorageManager::formatStorage ( )
overridevirtual
Returns
true if successful, false otherwise.
Note
This will erase all data on the device and reinitialize the filesystem.

Implements StorageManager.

Definition at line 350 of file FatFsStorageManager.cpp.

351{
352 if (!mounted) {
353 printf("[FatFs] Cannot format: card not mounted\n");
354 return false;
355 }
356
357 if (!format(mountPoint.c_str())) {
358 printf("[FatFs] Format failed for device: %s\n", mountPoint.c_str());
359 return false;
360 }
361
362 printf("[FatFs] Format successful for device: %s\n", mountPoint.c_str());
363
364 // Optionally re-mount to refresh filesystem state
365 unmount();
366 mount();
367
368 return mounted;
369}
bool unmount() override
Unmount the filesystem.
std::string mountPoint
Default mount point.

References mount(), mounted, mountPoint, and unmount().

+ Here is the call graph for this function:

◆ getFileSize()

size_t FatFsStorageManager::getFileSize ( const std::string &  path)
overridevirtual

Get the size of a file.

Parameters
pathPath to the file.
Returns
Size of the file in bytes, or 0 if the file does not exist.
Parameters
pathPath to the file.
Returns
Size of the file in bytes, or 0 if the file does not exist.

Implements StorageManager.

Definition at line 250 of file FatFsStorageManager.cpp.

251{
252 if (!ensureMounted())
253 {
254 TRACE("SD card not mounted — cannot get file size: %s\n", path.c_str());
255 return false;
256 }
257 FF_FILE *file = ff_fopen(resolvePath(path).c_str(), "r");
258 if (!file)
259 return 0;
260
261 ff_fseek(file, 0, SEEK_END);
262 long size = ff_ftell(file);
263 ff_fclose(file);
264
265 return (size >= 0) ? static_cast<size_t>(size) : 0;
266}

References ensureMounted(), resolvePath(), and TRACE.

+ Here is the call graph for this function:

◆ isMounted()

bool FatFsStorageManager::isMounted ( ) const
overridevirtual
Returns
true if mounted, false otherwise.
Note
This can be used to check if the filesystem is ready for operations.

Implements StorageManager.

Definition at line 328 of file FatFsStorageManager.cpp.

329{
330 return mounted;
331}

References mounted.

◆ listDirectory()

bool FatFsStorageManager::listDirectory ( const std::string &  path,
std::vector< FileInfo > &  out 
)
overridevirtual

List the contents of a directory.

Parameters
pathPath to the directory.
outOutput vector to fill with FileInfo objects.
Returns
true if successful, false otherwise.
Parameters
pathPath to the directory.
outOutput vector to fill with FileInfo objects.
Returns
true if successful, false otherwise.

Implements StorageManager.

Definition at line 89 of file FatFsStorageManager.cpp.

90{
91 if (!ensureMounted()) {
92 TRACE("SD card not mounted — cannot list directory: %s\n", path.c_str());
93 return false;
94 }
95 TRACE("[FatFs] Listing directory: %s\n", path.c_str());
96 FF_FindData_t xFindStruct{};
97 std::string searchPath = resolvePath(path.empty() ? "/" : path);
98 TRACE("[FatFs] Search path: %s\n", searchPath.c_str());
99 int result = ff_findfirst(searchPath.c_str(), &xFindStruct);
100
101 if (result != FF_ERR_NONE) {
102 printf("[FatFs] ff_findfirst failed with error: %d\n", result);
103 return false;
104 }
105
106 do {
107 if (xFindStruct.pcFileName && strlen(xFindStruct.pcFileName) > 0) {
108 FileInfo info;
109 info.name = xFindStruct.pcFileName;
110 info.isDirectory = xFindStruct.ucAttributes & FF_FAT_ATTR_DIR;
111 info.isReadOnly = xFindStruct.ucAttributes & FF_FAT_ATTR_READONLY;
112 info.size = static_cast<size_t>(xFindStruct.ulFileSize);
113 out.push_back(info);
114 }
115 } while (ff_findnext(&xFindStruct) == FF_ERR_NONE);
116
117 return true;
118}
Structure representing metadata for a file or directory.
bool isDirectory
True if item is a directory.
size_t size
Size in bytes.
bool isReadOnly
True if item is read-only.
std::string name
File or directory name.

References ensureMounted(), FileInfo::isDirectory, FileInfo::isReadOnly, FileInfo::name, resolvePath(), FileInfo::size, and TRACE.

+ Here is the call graph for this function:

◆ mount()

bool FatFsStorageManager::mount ( )
overridevirtual

Mount the filesystem at the specified mount point.

Returns
true if successful, false otherwise.
Returns
true if successful, false otherwise.

Implements StorageManager.

Definition at line 30 of file FatFsStorageManager.cpp.

31{
32 if (mounted)
33 return true;
34
35 TRACE("Mounting SD card at: %s\n", mountPoint.c_str());
36 mounted = ::mount(mountPoint.c_str());
37
38 if (mounted && !probeMountPoint())
39 {
40 TRACE("SD mount appears successful, but directory listing failed — treating as mount failure\n");
41 mounted = false;
42 }
43
44 if (!mounted)
45 {
46 TRACE("ERROR: SD mount FAILED for %s\n", mountPoint.c_str());
47 }
48 else
49 {
50 TRACE("SD card mounted successfully\n");
51 }
52
53 return mounted;
54}

References mount(), mounted, mountPoint, probeMountPoint(), and TRACE.

Referenced by ensureMounted(), formatStorage(), and mount().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ openReader()

std::unique_ptr< StorageFileReader > FatFsStorageManager::openReader ( const std::string &  path)
overridevirtual
Parameters
pathThe file path
Returns
A new reader object, or nullptr on failure

Implements StorageManager.

Definition at line 414 of file FatFsStorageManager.cpp.

414 {
415 if (!ensureMounted()) return nullptr;
416
417 auto reader = std::make_unique<FatFsFileReader>();
418 if (!reader->open(resolvePath(path))) return nullptr;
419 return reader;
420}

References ensureMounted(), and resolvePath().

+ Here is the call graph for this function:

◆ probeMountPoint()

bool FatFsStorageManager::probeMountPoint ( )
private

Definition at line 342 of file FatFsStorageManager.cpp.

343{
344 FF_FindData_t xFindStruct = {};
345 std::string root = "/" + mountPoint;
346 int result = ff_findfirst(root.c_str(), &xFindStruct);
347 return result == FF_ERR_NONE;
348}

References mountPoint.

Referenced by mount(), and refreshMountState().

+ Here is the caller graph for this function:

◆ readFile()

bool FatFsStorageManager::readFile ( const std::string &  path,
std::vector< uint8_t > &  buffer 
)
overridevirtual

Read a file into a memory buffer.

Parameters
pathPath to the file.
bufferOutput buffer to fill with data.
Returns
true if successful, false otherwise.
Parameters
pathPath to the file.
bufferOutput buffer to fill with data.
Returns
true if successful, false otherwise.

Implements StorageManager.

Definition at line 142 of file FatFsStorageManager.cpp.

143{
144 if (!ensureMounted())
145 {
146 TRACE("SD card not mounted — cannot read file: %s\n", path.c_str());
147 return false;
148 }
149 FF_FILE *file = ff_fopen(resolvePath(path).c_str(), "r");
150 if (!file)
151 return false;
152
153 ff_fseek(file, 0, SEEK_END);
154 long fileSize = ff_ftell(file);
155 ff_fseek(file, 0, SEEK_SET);
156
157 if (fileSize < 0)
158 {
159 ff_fclose(file);
160 return false;
161 }
162
163 buffer.resize(fileSize);
164 ff_fread(buffer.data(), 1, fileSize, file);
165 ff_fclose(file);
166 return true;
167}

References ensureMounted(), resolvePath(), and TRACE.

+ Here is the call graph for this function:

◆ readFileString()

bool FatFsStorageManager::readFileString ( const std::string &  path,
uint32_t  startPosition,
uint32_t  length,
std::string &  buffer 
)
virtual
Parameters
pathPath to the file.
startPositionStart position in the file.
lengthLength of data to read.
bufferOutput string to fill with data.
Returns
true if successful.

Implements StorageManager.

Definition at line 371 of file FatFsStorageManager.cpp.

372{
373 if (!ensureMounted())
374 {
375 TRACE("SD card not mounted — cannot read file string: %s\n", path.c_str());
376 return false;
377 }
378
379 FF_FILE *file = ff_fopen(resolvePath(path).c_str(), "r");
380 if (!file)
381 {
382 TRACE("Failed to open file: %s\n", path.c_str());
383 return false;
384 }
385
386 ff_fseek(file, 0, SEEK_END);
387 size_t fileSize = ff_ftell(file);
388 if (startPosition >= fileSize)
389 {
390 ff_fclose(file);
391 buffer.clear();
392 return true;
393 }
394
395 size_t readLength = std::min<size_t>(length, fileSize - startPosition);
396 ff_fseek(file, startPosition, SEEK_SET);
397
398 buffer.resize(readLength);
399 size_t bytesRead = ff_fread(buffer.data(), 1, readLength, file);
400 ff_fclose(file);
401
402 if (bytesRead != readLength)
403 {
404 buffer.resize(bytesRead);
405 TRACE("Read only %zu bytes from file: %s\n", bytesRead, path.c_str());
406 }
407
408 return true;
409}

References ensureMounted(), resolvePath(), and TRACE.

+ Here is the call graph for this function:

◆ refreshMountState()

void FatFsStorageManager::refreshMountState ( )
private

Definition at line 333 of file FatFsStorageManager.cpp.

334{
335 if (mounted && !probeMountPoint())
336 {
337 TRACE("SD no longer accessible — marking as unmounted\n");
338 mounted = false;
339 }
340}

References mounted, probeMountPoint(), and TRACE.

+ Here is the call graph for this function:

◆ remove()

bool FatFsStorageManager::remove ( const std::string &  path)
overridevirtual

Remove a file or directory at the specified path.

Returns
true if successful, false otherwise.
Note
For directories, this will only succeed if the directory is empty.
Returns
true if successful, false otherwise.
Note
For directories, this will only succeed if the directory is empty.

Implements StorageManager.

Definition at line 205 of file FatFsStorageManager.cpp.

206{
207 if (!ensureMounted())
208 {
209 TRACE("SD card not mounted — cannot remove file: %s\n", path.c_str());
210 return false;
211 }
212 return ff_remove(resolvePath(path).c_str()) == FF_ERR_NONE;
213}

References ensureMounted(), resolvePath(), and TRACE.

+ Here is the call graph for this function:

◆ removeDirectory()

bool FatFsStorageManager::removeDirectory ( const std::string &  path)
overridevirtual
Parameters
pathPath to the directory to remove.
Returns
true if successful, false otherwise.
Note
This will only succeed if the directory is empty.

Implements StorageManager.

Definition at line 131 of file FatFsStorageManager.cpp.

132{
133 if (!ensureMounted())
134 {
135 TRACE("SD card not mounted — cannot remove directory: %s\n", path.c_str());
136 return false;
137 }
138 return ff_rmdir(resolvePath(path).c_str()) == FF_ERR_NONE;
139}

References ensureMounted(), resolvePath(), and TRACE.

+ Here is the call graph for this function:

◆ rename()

bool FatFsStorageManager::rename ( const std::string &  from,
const std::string &  to 
)
overridevirtual

Rename a file or directory.

Parameters
fromCurrent path of the file or directory.
toNew path for the file or directory.
Returns
true if successful, false otherwise.
Note
This will fail if the destination already exists.
Parameters
fromCurrent path of the file or directory.
toNew path for the file or directory.
Returns
true if successful, false otherwise.
Note
This will fail if the destination already exists.

Implements StorageManager.

Definition at line 216 of file FatFsStorageManager.cpp.

217{
218 if (!ensureMounted())
219 {
220 TRACE("SD card not mounted — cannot rename file %s to file: %s\n", from.c_str(), to.c_str());
221 return false;
222 }
223 return ff_rename(resolvePath(from).c_str(), resolvePath(to).c_str(), false) == 0;
224}

References ensureMounted(), resolvePath(), and TRACE.

+ Here is the call graph for this function:

◆ resolvePath()

std::string FatFsStorageManager::resolvePath ( const std::string &  path) const
private

Definition at line 286 of file FatFsStorageManager.cpp.

287{
288 std::string fullPath = "/" + mountPoint;
289 if (!path.empty())
290 {
291 if (path[0] != '/')
292 fullPath += "/";
293 fullPath += path;
294 }
295
296 // Normalize duplicate slashes
297 std::string normalized;
298 bool lastWasSlash = false;
299 for (char c : fullPath)
300 {
301 if (c == '/')
302 {
303 if (!lastWasSlash)
304 {
305 normalized += c;
306 lastWasSlash = true;
307 }
308 }
309 else
310 {
311 normalized += c;
312 lastWasSlash = false;
313 }
314 }
315
316 return normalized;
317}

References mountPoint.

Referenced by appendToFile(), createDirectory(), exists(), getFileSize(), listDirectory(), openReader(), readFile(), readFileString(), remove(), removeDirectory(), rename(), streamFile(), writeFile(), and writeFile().

+ Here is the caller graph for this function:

◆ streamFile()

bool FatFsStorageManager::streamFile ( const std::string &  path,
std::function< void(const uint8_t *, size_t)>  chunkCallback 
)
overridevirtual

Stream a file in chunks via callback.

Parameters
pathPath to the file.
chunkCallbackCallback function to handle each chunk of data.
Returns
true if successful, false otherwise.
Note
The callback will be called multiple times with chunks of data from the file.
Parameters
pathPath to the file.
chunkCallbackCallback function to handle each chunk of data.
Returns
true if successful, false otherwise.
Note
The callback will be called multiple times with chunks of data from the file.

Implements StorageManager.

Definition at line 227 of file FatFsStorageManager.cpp.

228{
229 if (!ensureMounted())
230 {
231 TRACE("SD card not mounted — cannot stream file: %s\n", path.c_str());
232 return false;
233 }
234 FF_FILE *file = ff_fopen(resolvePath(path).c_str(), "r");
235 if (!file)
236 return false;
237
238 uint8_t buffer[HTTP_BUFFER_SIZE];
239 size_t bytes;
240 while ((bytes = ff_fread(buffer, 1, sizeof(buffer), file)) > 0)
241 {
242 chunkCallback(buffer, bytes);
243 }
244
245 ff_fclose(file);
246 return true;
247}
#define HTTP_BUFFER_SIZE
Size of the HTTP buffer for request/response data.

References ensureMounted(), HTTP_BUFFER_SIZE, resolvePath(), and TRACE.

+ Here is the call graph for this function:

◆ unmount()

bool FatFsStorageManager::unmount ( )
overridevirtual

Unmount the filesystem.

Returns
true if successful, false otherwise.
Returns
true if successful, false otherwise.

Implements StorageManager.

Definition at line 57 of file FatFsStorageManager.cpp.

58{
59 ::unmount(mountPoint.c_str());
60 mounted = false;
61 return true;
62}

References mounted, mountPoint, and unmount().

Referenced by formatStorage(), and unmount().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ writeFile() [1/2]

bool FatFsStorageManager::writeFile ( const std::string &  path,
const std::vector< uint8_t > &  data 
)
overridevirtual

Write a memory buffer to a file.

Parameters
pathPath to the file.
dataData to write.
Returns
true if successful, false otherwise.
Parameters
pathPath to the file.
dataData to write.
Returns
true if successful, false otherwise.

Implements StorageManager.

Definition at line 170 of file FatFsStorageManager.cpp.

171{
172 if (!ensureMounted())
173 {
174 TRACE("SD card not mounted — cannot write to file: %s\n", path.c_str());
175 return false;
176 }
177 FF_FILE *file = ff_fopen(resolvePath(path).c_str(), "w");
178 if (!file)
179 return false;
180
181 ff_fwrite(data.data(), 1, data.size(), file);
182 ff_fclose(file);
183 return true;
184}

References ensureMounted(), resolvePath(), and TRACE.

+ Here is the call graph for this function:

◆ writeFile() [2/2]

bool FatFsStorageManager::writeFile ( const std::string &  path,
const unsigned char *  data,
size_t  size 
)
overridevirtual
Parameters
pathPath to the file.
dataPointer to the data buffer.
sizeSize of the data buffer.
Returns
true if successful, false otherwise.

Implements StorageManager.

Definition at line 186 of file FatFsStorageManager.cpp.

187{
188 if (!ensureMounted())
189 {
190 TRACE("SD card not mounted — cannot write to file: %s\n", path.c_str());
191 return false;
192 }
193
194 FF_FILE* file = ff_fopen(resolvePath(path).c_str(), "w");
195 if (!file)
196 return false;
197
198 size_t written = ff_fwrite(data, 1, size, file);
199 ff_fclose(file);
200
201 return (written == size);
202}

References ensureMounted(), resolvePath(), and TRACE.

+ Here is the call graph for this function:

Member Data Documentation

◆ mounted

bool FatFsStorageManager::mounted = false
private

◆ mountPoint

std::string FatFsStorageManager::mountPoint = "sd0"
private

Definition at line 182 of file FatFsStorageManager.h.

Referenced by formatStorage(), mount(), probeMountPoint(), resolvePath(), and unmount().

◆ mutex

SemaphoreHandle_t FatFsStorageManager::mutex
private

Definition at line 184 of file FatFsStorageManager.h.


The documentation for this class was generated from the following files: