/* esp_globalFS.cpp - ESP3D global FS support class Copyright (c) 2014 Luc Lebosse. All rights reserved. This code is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with This code; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ // #define ESP_LOG_FEATURE LOG_OUTPUT_SERIAL0 #include "../../include/esp3d_config.h" #if defined(GLOBAL_FILESYSTEM_FEATURE) #include "esp_globalFS.h" // to verify FS is accessible bool ESP_GBFS::isavailable(uint8_t FS) { #ifdef FILESYSTEM_FEATURE if (FS == FS_FLASH) { return ESP_FileSystem::started(); } #endif // FILESYSTEM_FEATURE #ifdef SD_DEVICE if (FS == FS_SD) { return (ESP_SD::getState(true) == ESP_SDCARD_IDLE); } #endif // SD_DEVICE return false; } uint8_t ESP_GBFS::_nbFS = 0; String ESP_GBFS::_rootlist[MAX_FS]; // helper to format size to readable string String &ESP_GBFS::formatBytes(uint64_t bytes) { static String res; if (bytes < 1024) { res = String((uint16_t)bytes) + " B"; } else if (bytes < (1024 * 1024)) { res = String((float)(bytes / 1024.0), 2) + " KB"; } else if (bytes < (1024 * 1024 * 1024)) { res = String((float)(bytes / 1024.0 / 1024.0), 2) + " MB"; } else { res = String((float)(bytes / 1024.0 / 1024.0 / 1024.0), 2) + " GB"; } return res; } // depending FS uint64_t ESP_GBFS::totalBytes(uint8_t FS) { #ifdef FILESYSTEM_FEATURE if (FS == FS_FLASH) { return ESP_FileSystem::totalBytes(); } #endif // FILESYSTEM_FEATURE #ifdef SD_DEVICE if (FS == FS_SD) { return ESP_SD::totalBytes(); } #endif // SD_DEVICE return 0; } uint64_t ESP_GBFS::usedBytes(uint8_t FS) { #ifdef FILESYSTEM_FEATURE if (FS == FS_FLASH) { return ESP_FileSystem::usedBytes(); } #endif // FILESYSTEM_FEATURE #ifdef SD_DEVICE if (FS == FS_SD) { return ESP_SD::usedBytes(); } #endif // SD_DEVICE return 0; } uint ESP_GBFS::maxPathLength() { uint size = 255; #ifdef FILESYSTEM_FEATURE if (size > 32) { size = 32; } #endif // FILESYSTEM_FEATURE #ifdef SD_DEVICE if (size > 255) { size = 255; } #endif // SD_DEVICE return size; } bool ESP_GBFS::accessFS(uint8_t FS) { if (FS == FS_ROOT) { return true; } #ifdef FILESYSTEM_FEATURE if (FS == FS_FLASH) { return ESP_FileSystem::accessFS(); } #endif // FILESYSTEM_FEATURE #ifdef SD_DEVICE if (FS == FS_SD) { bool canAccess = ESP_SD::accessFS(); if (canAccess) { if (ESP_SD::getState(true) == ESP_SDCARD_NOT_PRESENT) { canAccess = false; ESP_SD::releaseFS(); } else { ESP_SD::setState(ESP_SDCARD_BUSY); canAccess = true; } } return canAccess; } #endif // SD_DEVICE return false; } void ESP_GBFS::releaseFS(uint8_t FS) { #ifdef FILESYSTEM_FEATURE if (FS == FS_FLASH) { ESP_FileSystem::releaseFS(); } #endif // FILESYSTEM_FEATURE #ifdef SD_DEVICE if (FS == FS_SD) { ESP_SD::releaseFS(); } #endif // SD_DEVICE } uint64_t ESP_GBFS::freeBytes(uint8_t FS) { #ifdef FILESYSTEM_FEATURE if (FS == FS_FLASH) { return ESP_FileSystem::freeBytes(); } #endif // FILESYSTEM_FEATURE #ifdef SD_DEVICE if (FS == FS_SD) { return ESP_SD::freeBytes(); } #endif // SD_DEVICE return 0; } // Format is not always available for all FS bool format(uint8_t FS, ESP3DOutput *output = nullptr) { #ifdef FILESYSTEM_FEATURE if (FS == FS_FLASH) { return ESP_FileSystem::format(); } #endif // FILESYSTEM_FEATURE #ifdef SD_DEVICE if (FS == FS_SD) { return ESP_SD::format(output); } #endif // SD_DEVICE output->printERROR("Not available"); return false; } // check type of FS according root dir uint8_t ESP_GBFS::getFSType(const char *path) { String p = path; p.trim(); if (p == "/") { return FS_ROOT; } #if defined(FILESYSTEM_FEATURE) if (p.startsWith(ESP_FLASH_FS_HEADER)) { return FS_FLASH; } #endif // FILESYSTEM_FEATURE #if defined(SD_DEVICE) if (p.startsWith(ESP_SD_FS_HEADER)) { return FS_SD; } #endif // SD_DEVICE return FS_UNKNOWN; } const char *ESP_GBFS::getRealPath(const char *path) { static String p; uint8_t t = getFSType(path); p = ""; #if defined(FILESYSTEM_FEATURE) if (t == FS_FLASH) { p = path; // remove header p.remove(0, strlen(ESP_FLASH_FS_HEADER)); // if nothing it is root if (p.length() == 0) { p = "/"; } } #endif // FILESYSTEM_FEATURE #if defined(SD_DEVICE) if (t == FS_SD) { p = path; // remove header p.remove(0, strlen(ESP_SD_FS_HEADER)); // if nothing it is root if (p.length() == 0) { p = "/"; } } #endif // SD_DEVICE return p.c_str(); } // path exists on / or SD or FS bool ESP_GBFS::exists(const char *path) { #if defined(FILESYSTEM_FEATURE) || defined(SD_DEVICE) uint8_t t = getFSType(path); if (t == FS_ROOT) { return true; } #if defined(FILESYSTEM_FEATURE) if (t == FS_FLASH) { return ESP_FileSystem::exists(getRealPath(path)); } #endif // FILESYSTEM_FEATURE #if defined(SD_DEVICE) if (t == FS_SD) { return ESP_SD::exists(getRealPath(path)); } #endif // SD_DEVICE #endif // FILESYSTEM_FEATURE || SD_DEVICE return false; } bool ESP_GBFS::remove(const char *path) { #if defined(FILESYSTEM_FEATURE) || defined(SD_DEVICE) uint8_t t = getFSType(path); if (t == FS_ROOT) { return false; } #if defined(FILESYSTEM_FEATURE) if (t == FS_FLASH) { return ESP_FileSystem::remove(getRealPath(path)); } #endif // FILESYSTEM_FEATURE #if defined(SD_DEVICE) if (t == FS_SD) { return ESP_SD::remove(getRealPath(path)); } #endif // SD_DEVICE #endif // FILESYSTEM_FEATURE || SD_DEVICE return false; } bool ESP_GBFS::rename(const char *oldpath, const char *newpath) { log_esp3d("rename global %s to %s", oldpath, newpath); #if defined(FILESYSTEM_FEATURE) || defined(SD_DEVICE) uint8_t t = getFSType(oldpath); if (t == FS_ROOT) { log_esp3d_e("rename on root not allowed"); return false; } String o = getRealPath(oldpath); String n = getRealPath(newpath); #if defined(FILESYSTEM_FEATURE) if (t == FS_FLASH) { log_esp3d("rename FS %s to %s", n.c_str(), o.c_str()); return ESP_FileSystem::rename(o.c_str(), n.c_str()); } #endif // FILESYSTEM_FEATURE #if defined(SD_DEVICE) if (t == FS_SD) { log_esp3d("rename FS %s to %s", o.c_str(), n.c_str()); return ESP_SD::rename(o.c_str(), n.c_str()); } #endif // SD_DEVICE #endif // FILESYSTEM_FEATURE || SD_DEVICE log_esp3d_e("Unknow FS, rename not allowed"); return false; } bool ESP_GBFS::mkdir(const char *path) { #if defined(FILESYSTEM_FEATURE) || defined(SD_DEVICE) uint8_t t = getFSType(path); if (t == FS_ROOT) { return false; } #if defined(FILESYSTEM_FEATURE) if (t == FS_FLASH) { return ESP_FileSystem::mkdir(getRealPath(path)); ; } #endif // FILESYSTEM_FEATURE #if defined(SD_DEVICE) if (t == FS_SD) { return ESP_SD::mkdir(getRealPath(path)); } #endif // SD_DEVICE #endif // FILESYSTEM_FEATURE || SD_DEVICE return false; } bool ESP_GBFS::rmdir(const char *path) { #if defined(FILESYSTEM_FEATURE) || defined(SD_DEVICE) uint8_t t = getFSType(path); if (t == FS_ROOT) { return false; } #if defined(FILESYSTEM_FEATURE) if (t == FS_FLASH) { return ESP_FileSystem::rmdir(getRealPath(path)); } #endif // FILESYSTEM_FEATURE #if defined(SD_DEVICE) if (t == FS_SD) { return ESP_SD::rmdir(getRealPath(path)); ; } #endif // SD_DEVICE #endif // FILESYSTEM_FEATURE || SD_DEVICE return false; } void ESP_GBFS::closeAll() { getNextFS(true); #if defined(FILESYSTEM_FEATURE) ESP_FileSystem::closeAll(); #endif // FILESYSTEM_FEATURE #if defined(SD_DEVICE) ESP_SD::closeAll(); #endif // SD_DEVICE } ESP_GBFile ESP_GBFS::open(const char *path, uint8_t mode) { ESP_GBFile f; log_esp3d("open %s", path); #if defined(FILESYSTEM_FEATURE) || defined(SD_DEVICE) uint8_t t = getFSType(path); log_esp3d("type %d", t); if ((t == FS_ROOT) && (mode == ESP_FILE_READ)) { f = ESP_GBFile(FS_ROOT, "/"); log_esp3d("root"); getNextFS(true); } #if defined(FILESYSTEM_FEATURE) if (t == FS_FLASH) { log_esp3d("open flash : %s", getRealPath(path)); f = ESP_FileSystem::open(getRealPath(path), mode); } #endif // FILESYSTEM_FEATURE #if defined(SD_DEVICE) if (t == FS_SD) { log_esp3d("open SD : %s", getRealPath(path)); f = ESP_SD::open(getRealPath(path), mode); } #endif // SD_DEVICE #endif // FILESYSTEM_FEATURE || SD_DEVICE return f; } // Default File is no file ESP_GBFile::ESP_GBFile() { _type = FS_UNKNOWN; } // File handle for the root ESP_GBFile::ESP_GBFile(uint8_t FS, const char *name) { _type = FS; _name = name; } // Handle for flash file #ifdef FILESYSTEM_FEATURE ESP_GBFile::ESP_GBFile(ESP_File &flashFile) { _type = FS_FLASH; _flashFile = flashFile; #ifdef SD_DEVICE _sdFile = ESP_SDFile(); #endif // SD_DEVICE } #endif // FILESYSTEM_FEATURE // Handle for SD file #ifdef SD_DEVICE ESP_GBFile::ESP_GBFile(ESP_SDFile &sdFile) { _type = FS_SD; _sdFile = sdFile; #ifdef FILESYSTEM_FEATURE _flashFile = ESP_File(); #endif // FILESYSTEM_FEATURE } #endif // SD_DEVICE // Destructor ESP_GBFile::~ESP_GBFile() {} ESP_GBFile::operator bool() const { #if defined(FILESYSTEM_FEATURE) || defined(SD_DEVICE) if (_type == FS_ROOT) { return true; } #endif // FILESYSTEM_FEATURE || SD_DEVICE #ifdef FILESYSTEM_FEATURE if (_type == FS_FLASH) { return _flashFile; } #endif // FILESYSTEM_FEATURE #ifdef SD_DEVICE if (_type == FS_SD) { return _sdFile; } #endif // SD_DEVICE return false; } bool ESP_GBFile::seek(uint32_t pos, uint8_t mode) { #if defined(FILESYSTEM_FEATURE) || defined(SD_DEVICE) if (_type == FS_ROOT) { return false; } #endif // FILESYSTEM_FEATURE || SD_DEVICE #ifdef FILESYSTEM_FEATURE if (_type == FS_FLASH) { _flashFile.seek(pos, mode); } #endif // FILESYSTEM_FEATURE #ifdef SD_DEVICE if (_type == FS_SD) { return _sdFile.seek(pos, mode); } #endif // SD_DEVICE return false; } void ESP_GBFile::close() { #if defined(FILESYSTEM_FEATURE) || defined(SD_DEVICE) if (_type == FS_ROOT) { // TBD } #endif // FILESYSTEM_FEATURE || SD_DEVICE #ifdef FILESYSTEM_FEATURE if (_type == FS_FLASH) { _flashFile.close(); } #endif // FILESYSTEM_FEATURE #ifdef SD_DEVICE if (_type == FS_SD) { return _sdFile.close(); } #endif // SD_DEVICE } bool ESP_GBFile::isOpen() { #if defined(FILESYSTEM_FEATURE) || defined(SD_DEVICE) if (_type == FS_ROOT) { return true; } #endif // FILESYSTEM_FEATURE || SD_DEVICE #ifdef FILESYSTEM_FEATURE if (_type == FS_FLASH) { return _flashFile.isOpen(); } #endif // FILESYSTEM_FEATURE #ifdef SD_DEVICE if (_type == FS_SD) { return _sdFile.isOpen(); } #endif // SD_DEVICE return false; } const char *ESP_GBFile::name() const { static String s; #if defined(FILESYSTEM_FEATURE) || defined(SD_DEVICE) if (_type == FS_ROOT) { return _name.c_str(); } #endif // FILESYSTEM_FEATURE || SD_DEVICE #ifdef FILESYSTEM_FEATURE if (_type == FS_FLASH) { if (strcmp(_flashFile.name(), "/") == 0) { s = ESP_FLASH_FS_HEADER; s.remove(0, 1); return s.c_str(); } return _flashFile.name(); } #endif // FILESYSTEM_FEATURE #ifdef SD_DEVICE if (_type == FS_SD) { if (strcmp(_sdFile.name(), "/") == 0) { s = ESP_SD_FS_HEADER; s.remove(0, 1); return s.c_str(); } return _sdFile.name(); } #endif // SD_DEVICE return ""; } const char *ESP_GBFile::filename() const { #if defined(FILESYSTEM_FEATURE) || defined(SD_DEVICE) static String s; if (_type == FS_ROOT) { return "/"; } #endif // FILESYSTEM_FEATURE || SD_DEVICE #ifdef FILESYSTEM_FEATURE if (_type == FS_FLASH) { s = ESP_FLASH_FS_HEADER; s += _flashFile.filename(); return s.c_str(); } #endif // FILESYSTEM_FEATURE #ifdef SD_DEVICE if (_type == FS_SD) { s = ESP_SD_FS_HEADER; s += s += _sdFile.filename(); return s.c_str(); } #endif // SD_DEVICE return ""; } bool ESP_GBFile::isDirectory() { #if defined(FILESYSTEM_FEATURE) || defined(SD_DEVICE) if (_type == FS_ROOT) { return true; } #endif // FILESYSTEM_FEATURE || SD_DEVICE #ifdef FILESYSTEM_FEATURE if (_type == FS_FLASH) { return _flashFile.isDirectory(); } #endif // FILESYSTEM_FEATURE #ifdef SD_DEVICE if (_type == FS_SD) { return _sdFile.isDirectory(); } #endif // SD_DEVICE return false; } size_t ESP_GBFile::size() { #if defined(FILESYSTEM_FEATURE) || defined(SD_DEVICE) if (_type == FS_ROOT) { return 0; } #endif // FILESYSTEM_FEATURE || SD_DEVICE #ifdef FILESYSTEM_FEATURE if (_type == FS_FLASH) { return _flashFile.size(); } #endif // FILESYSTEM_FEATURE #ifdef SD_DEVICE if (_type == FS_SD) { return _sdFile.size(); } #endif // SD_DEVICE return 0; } time_t ESP_GBFile::getLastWrite() { if (_type == FS_FLASH) { return _flashFile.getLastWrite(); } #ifdef SD_DEVICE if (_type == FS_SD) { return _sdFile.getLastWrite(); } #endif // SD_DEVICE return 0; } int ESP_GBFile::available() { #if defined(FILESYSTEM_FEATURE) || defined(SD_DEVICE) if (_type == FS_ROOT) { return 0; } #endif // FILESYSTEM_FEATURE || SD_DEVICE #ifdef FILESYSTEM_FEATURE if (_type == FS_FLASH) { return _flashFile.available(); } #endif // FILESYSTEM_FEATURE #ifdef SD_DEVICE if (_type == FS_SD) { return _sdFile.available(); } #endif // SD_DEVICE return 0; } size_t ESP_GBFile::write(uint8_t i) { #if defined(FILESYSTEM_FEATURE) || defined(SD_DEVICE) if (_type == FS_ROOT) { return 0; } #endif // FILESYSTEM_FEATURE || SD_DEVICE #ifdef FILESYSTEM_FEATURE if (_type == FS_FLASH) { return _flashFile.write(i); } #endif // FILESYSTEM_FEATURE #ifdef SD_DEVICE if (_type == FS_SD) { return _sdFile.write(i); } #endif // SD_DEVICE return 0; } size_t ESP_GBFile::write(const uint8_t *buf, size_t size) { #if defined(FILESYSTEM_FEATURE) || defined(SD_DEVICE) if (_type == FS_ROOT) { return 0; } #endif // FILESYSTEM_FEATURE || SD_DEVICE #ifdef FILESYSTEM_FEATURE if (_type == FS_FLASH) { return _flashFile.write(buf, size); } #endif // FILESYSTEM_FEATURE #ifdef SD_DEVICE if (_type == FS_SD) { return _sdFile.write(buf, size); } #endif // SD_DEVICE return 0; } int ESP_GBFile::read() { #if defined(FILESYSTEM_FEATURE) || defined(SD_DEVICE) if (_type == FS_ROOT) { return -1; } #endif // FILESYSTEM_FEATURE || SD_DEVICE #ifdef FILESYSTEM_FEATURE if (_type == FS_FLASH) { return _flashFile.read(); } #endif // FILESYSTEM_FEATURE #ifdef SD_DEVICE if (_type == FS_SD) { return _sdFile.read(); } #endif // SD_DEVICE return -1; } size_t ESP_GBFile::read(uint8_t *buf, size_t size) { #if defined(FILESYSTEM_FEATURE) || defined(SD_DEVICE) if (_type == FS_ROOT) { return -1; } #endif // FILESYSTEM_FEATURE || SD_DEVICE #ifdef FILESYSTEM_FEATURE if (_type == FS_FLASH) { return _flashFile.read(buf, size); } #endif // FILESYSTEM_FEATURE #ifdef SD_DEVICE if (_type == FS_SD) { return _sdFile.read(buf, size); } #endif // SD_DEVICE return -1; } void ESP_GBFile::flush() { #ifdef FILESYSTEM_FEATURE if (_type == FS_FLASH) { return _flashFile.flush(); } #endif // FILESYSTEM_FEATURE #ifdef SD_DEVICE if (_type == FS_SD) { return _sdFile.flush(); } #endif // SD_DEVICE return; } ESP_GBFile &ESP_GBFile::operator=(const ESP_GBFile &other) { #ifdef FILESYSTEM_FEATURE _flashFile = other._flashFile; #endif // FILESYSTEM_FEATURE #ifdef SD_DEVICE _sdFile = other._sdFile; #endif // SD_DEVICE _type = other._type; _name = other._name; return *this; } #ifdef FILESYSTEM_FEATURE ESP_GBFile &ESP_GBFile::operator=(const ESP_File &other) { _flashFile = other; #ifdef SD_DEVICE _sdFile = ESP_SDFile(); #endif // SD_DEVICE _type = FS_FLASH; return *this; } #endif // FILESYSTEM_FEATURE #ifdef SD_DEVICE ESP_GBFile &ESP_GBFile::operator=(const ESP_SDFile &other) { #ifdef FILESYSTEM_FEATURE _flashFile = ESP_File(); #endif // FILESYSTEM_FEATURE _sdFile = other; _type = FS_SD; return *this; } #endif // SD_DEVICE const char *ESP_GBFS::getNextFS(bool reset) { static uint8_t index = 0; if (reset) { index = 0; if (_nbFS == 0) { #ifdef FILESYSTEM_FEATURE _rootlist[_nbFS] = ESP_FLASH_FS_HEADER; _nbFS++; #endif // FILESYSTEM_FEATURE #ifdef SD_DEVICE _rootlist[_nbFS] = ESP_SD_FS_HEADER; _nbFS++; #endif // SD_DEVICE } return ""; } if (index < _nbFS) { uint8_t i = index; index++; return _rootlist[i].c_str(); } index = 0; return ""; } ESP_GBFile ESP_GBFile::openNextFile() { ESP_GBFile f; if (_type == FS_ROOT) { String path = ESP_GBFS::getNextFS(); if (path.length() > 0) { f = ESP_GBFile(FS_ROOT, &path[1]); } } #ifdef FILESYSTEM_FEATURE if (_type == FS_FLASH) { f = _flashFile.openNextFile(); } #endif // FILESYSTEM_FEATURE #ifdef SD_DEVICE if (_type == FS_SD) { f = _sdFile.openNextFile(); } #endif // SD_DEVICE return f; } #endif // GLOBAL_FILESYSTEM_FEATURE