EVOG2-Spiffs-Avery/FileLib.ino

369 lines
8.8 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "FileLib.h"
FileLibClass::FileLibClass(StorageType type) : _type(type) {}
FileLibClass::~FileLibClass()
{
_printMessage("Unmounting file system\n");
if (_type == StorageType::FL_SPIFFS)
{
LITTLEFS.end();
}
else if (_type == StorageType::FL_MMC)
{
SD_MMC.end();
}
else if (_type == StorageType::FL_SD)
{
SD.end();
}
}
bool FileLibClass::begin(uint8_t csPin, uint8_t misoPin, uint8_t mosiPin, uint8_t sckPin)
{
_printMessage("Initializing file system\n");
if (_type == StorageType::FL_SPIFFS)
{
_filesystem = &LITTLEFS;
return LITTLEFS.begin(true);
}
if (_type == StorageType::FL_MMC)
{
_filesystem = &SD_MMC;
return SD_MMC.begin();
}
if (_type == StorageType::FL_SD)
{
_spi.begin(sckPin, misoPin, mosiPin, csPin);
_filesystem = &SD;
return SD.begin(5, _spi);
}
return false;
}
File FileLibClass::openForWriting(const char *fileName)
{
_printMessage("Opening file '%s' for writing\n", fileName);
return _filesystem->open(fileName, FILE_WRITE);
}
File FileLibClass::open(const char *fileName, const char *mode)
{
if (!_filesystem)
{
_printMessage("File system not initialized");
return File(); // Return an empty File object if filesystem is not initialized
}
return _filesystem->open(fileName, mode);
}
bool FileLibClass::readPartial(const char *fileName, uint32_t startPos, uint8_t *buffer, uint16_t bufferSize)
{
if (!_filesystem)
{
_printMessage("File system not initialized");
return false;
}
File file = _filesystem->open(fileName, FILE_READ);
if (!file)
{
_printMessage("Failed to open file");
return false;
}
if (!file.seek(startPos))
{
_printMessage("Failed to seek to position %u in file", startPos);
file.close();
return false;
}
size_t bytesRead = file.read(buffer, bufferSize);
file.close();
if (bytesRead == 0)
{
_printMessage("No data read from file");
return false;
}
return true;
}
bool FileLibClass::write(const char *fileName, const uint8_t *data, size_t dataSize, bool append)
{
_printMessage("Writing %d bytes to file '%s'\n", dataSize, fileName);
File file = _filesystem->open(fileName, append ? FILE_APPEND : FILE_WRITE);
// Sanity check
if (!file || file.isDirectory())
{
_printMessage("Failed to open file '%s' for writing\n", fileName);
return false;
}
// size_t written = file.write(reinterpret_cast<const uint8_t *>(data), dataSize);
size_t written = 0;
for (size_t i = 0; i < dataSize; i++)
{
written += file.write(data[i]);
}
// Confirm that the data was written
if (written == dataSize)
{
file.close();
return true;
}
if (written > 0)
{
_printMessage("Only wrote %d bytes of %d\n", written, dataSize);
file.close();
return false;
}
_printMessage("Failed to write to file '%s'\n", fileName);
file.close();
return false;
}
bool FileLibClass::writeString(const char *fileName, const uint8_t *data, bool append)
{
_printMessage("Writing string to file '%s'\n", fileName);
// use strlen so we don't write the null terminator
int strLen = strlen((char *)&data);
return write(fileName, reinterpret_cast<const uint8_t *>(data), strLen, append);
}
void FileLibClass::listDir(const char *dirName, uint8_t levels)
{
if (!_verbose)
{
return;
}
_printMessage("Listing directory: %s\r\n", dirName);
File root = _filesystem->open(dirName);
if (!root)
{
_printMessage(" failed to open directory");
return;
}
if (!root.isDirectory())
{
_printMessage(" not a directory");
return;
}
File file = root.openNextFile();
while (file)
{
if (file.isDirectory())
{
Serial.printf(" DIR : %s\n", file.name());
if (levels)
{
listDir(file.name(), levels - 1);
}
}
else
{
Serial.printf(" FILE: %s", file.name());
Serial.printf("\tSIZE: %d\n", file.size());
}
file = root.openNextFile();
}
}
bool FileLibClass::read(const char *fileName, uint8_t *buffer, uint16_t bufferSize, bool clearBuffer)
{
_printMessage("Reading file '%s'\n", fileName);
if (clearBuffer)
{
memset(buffer, 0, bufferSize);
}
File file = _filesystem->open(fileName, FILE_READ);
uint16_t fileSize = file.size();
// Sanity check
if (!file || file.isDirectory())
{
_printMessage("Failed to open file '%s'.\n", fileName);
return false;
}
// check if the buffer is big enough
if (bufferSize < fileSize)
{
_printMessage("Buffer size is too small for file '%s'.\n", fileName);
file.close();
return false;
}
if (!file.available())
{
_printMessage("File '%s' is empty.\n", fileName);
}
// size_t bytesRead = file.readBytes(buffer, fileSize);
// read the data byte by byte
for (size_t i = 0; i < fileSize; i++)
{
buffer[i] = file.read();
}
file.close();
return true;
}
bool FileLibClass::remove(const char *fileName)
{
_printMessage("Removing file '%s'\n", fileName);
if (!_filesystem->exists(fileName))
{
_printMessage("File '%s' does not exist.\n", fileName);
return false;
}
return _filesystem->remove(fileName);
}
bool FileLibClass::rename(const char *fileName, const char *newName, bool overwrite)
{
_printMessage("Renaming file '%s' to '%s'\n", fileName, newName);
if (_filesystem->exists(newName) && !overwrite)
{
_printMessage("File '%s' already exists.\n", newName);
return false;
}
return _filesystem->rename(fileName, newName);
}
bool FileLibClass::mkdir(const char *path)
{
_printMessage("Creating directory '%s'\n", path);
if (_filesystem->exists(path))
{
_printMessage("Directory '%s' already exists.\n", path);
return false;
}
return _filesystem->mkdir(path);
}
uint64_t FileLibClass::getFreeSpace()
{
_printMessage("Getting free space\n");
if (_type == StorageType::FL_SPIFFS)
{
return LITTLEFS.totalBytes() - LITTLEFS.usedBytes();
}
if (_type == StorageType::FL_MMC)
{
uint64_t cardSize = SD_MMC.totalBytes();
uint64_t usedSpace = SD_MMC.usedBytes();
if (usedSpace > cardSize)
{
_printMessage("ERROR: Used space is greater than card size \n");
return 0;
}
uint64_t freeSpace = cardSize - usedSpace;
return freeSpace;
}
if (_type == StorageType::FL_SD)
{
uint64_t cardSize = SD.totalBytes();
uint64_t usedSpace = SD.usedBytes();
if (usedSpace > cardSize)
{
_printMessage("Error: Used space is greater than card size \n");
return 0;
}
uint64_t freeSpace = cardSize - usedSpace;
return freeSpace;
}
return 0;
}
bool copy(File &source, File &dest)
{
if (!source || !dest)
{
return false;
}
int bufferSize = 512;
char buffer[bufferSize];
while (source.available())
{
int bytesRead = source.readBytes(buffer, bufferSize);
int bytesWritten = dest.write((uint8_t *)&buffer, bytesRead);
if (bytesWritten != bytesRead)
{
return false;
}
}
dest.flush();
return true;
}
void FileLibClass::_printMessage(const char *message, ...)
{
if (_verbose)
{
// get the type name
const char *typeName;
switch (_type)
{
case FL_SPIFFS:
typeName = "FL_SPIFFS";
break;
case FL_SD:
typeName = "FL_SD";
break;
case FL_MMC:
typeName = "FL_MMC";
break;
default:
typeName = "Unknown";
break;
}
char buffer[256];
va_list args;
va_start(args, message);
vsnprintf(buffer, sizeof(buffer), message, args);
va_end(args);
// switch for different storage types
Serial.printf("%s: %s", typeName, buffer);
}
}
//Create FileLibClass::exists function
bool FileLibClass::exists(const char* fileName)
{
return _filesystem->exists(fileName);
}