From 25668a2154e3285ecffb4cba7a8fa3301f6ae102 Mon Sep 17 00:00:00 2001 From: mikee47 Date: Tue, 16 Feb 2021 13:02:06 +0000 Subject: [PATCH 01/11] Move `IFS::Directory` and `IFS::FsBase` objects into IFS library Don't belong in Stream. --- Sming/Core/Data/Stream/Directory.h | 2 +- Sming/Core/Data/Stream/IFS/Directory.cpp | 102 ---------------- Sming/Core/Data/Stream/IFS/Directory.h | 111 ------------------ .../Core/Data/Stream/IFS/DirectoryTemplate.h | 2 +- Sming/Core/Data/Stream/IFS/FileStream.h | 2 +- Sming/Core/Data/Stream/IFS/FsBase.h | 72 ------------ 6 files changed, 3 insertions(+), 288 deletions(-) delete mode 100644 Sming/Core/Data/Stream/IFS/Directory.cpp delete mode 100644 Sming/Core/Data/Stream/IFS/Directory.h delete mode 100644 Sming/Core/Data/Stream/IFS/FsBase.h diff --git a/Sming/Core/Data/Stream/Directory.h b/Sming/Core/Data/Stream/Directory.h index e1c203d876..81ee133379 100644 --- a/Sming/Core/Data/Stream/Directory.h +++ b/Sming/Core/Data/Stream/Directory.h @@ -12,7 +12,7 @@ #pragma once -#include "IFS/Directory.h" +#include #include /** diff --git a/Sming/Core/Data/Stream/IFS/Directory.cpp b/Sming/Core/Data/Stream/IFS/Directory.cpp deleted file mode 100644 index 2405e208d7..0000000000 --- a/Sming/Core/Data/Stream/IFS/Directory.cpp +++ /dev/null @@ -1,102 +0,0 @@ -/**** - * Sming Framework Project - Open Source framework for high efficiency native ESP8266 development. - * Created 2015 by Skurydin Alexey - * http://github.com/anakod/Sming - * All files of the Sming Core are provided under the LGPL v3 license. - * - * Directory.cpp - * - * @author mikee47 May 2019 - * - ****/ - -#include "Directory.h" - -namespace IFS -{ -bool Directory::open(const String& dirName) -{ - auto fs = getFileSystem(); - if(fs == nullptr) { - return false; - } - - DirHandle dir; - int err = fs->opendir(dirName, dir); - if(!check(err)) { - debug_w("Directory '%s' open error: %s", dirName.c_str(), fs->getErrorString(err).c_str()); - return false; - } - - close(); - name = dirName ?: ""; - this->dir = dir; - - return true; -} - -void Directory::close() -{ - if(dir != nullptr) { - auto fs = getFileSystem(); - assert(fs != nullptr); - fs->closedir(dir); - dir = nullptr; - } - lastError = FS_OK; -} - -bool Directory::rewind() -{ - auto fs = getFileSystem(); - if(fs == nullptr) { - return false; - } - - int err = fs->rewinddir(dir); - return err == FS_OK; -} - -String Directory::getPath() const -{ - String path('/'); - path += name; - if(name.length() != 0 && name[name.length() - 1] != '/') { - path += '/'; - } - return path; -} - -String Directory::getParent() const -{ - if(name.length() == 0 || name == "/") { - return nullptr; - } - String path('/'); - int i = name.lastIndexOf('/'); - if(i >= 0) { - path.concat(name.c_str(), i); - } - return path; -} - -bool Directory::next() -{ - auto fs = getFileSystem(); - if(fs == nullptr) { - return false; - } - - int err = fs->readdir(dir, dirStat); - if(check(err)) { - totalSize += dirStat.size; - ++currentIndex; - return true; - } - - debug_w("Directory '%s' read error: %s", name.c_str(), getErrorString(err).c_str()); - - return false; -} - -} // namespace IFS diff --git a/Sming/Core/Data/Stream/IFS/Directory.h b/Sming/Core/Data/Stream/IFS/Directory.h deleted file mode 100644 index 5b1af25adf..0000000000 --- a/Sming/Core/Data/Stream/IFS/Directory.h +++ /dev/null @@ -1,111 +0,0 @@ -/**** - * Sming Framework Project - Open Source framework for high efficiency native ESP8266 development. - * Created 2015 by Skurydin Alexey - * http://github.com/anakod/Sming - * All files of the Sming Core are provided under the LGPL v3 license. - * - * Directory.h - * - * @author mikee47 May 2019 - * - ****/ - -#pragma once - -#include "FsBase.h" - -namespace IFS -{ -/** - * @brief Wrapper class for enumerating a directory - */ -class Directory : public FsBase -{ -public: - using FsBase::FsBase; - - ~Directory() - { - close(); - } - - /** - * @brief Open a directory and attach this stream object to it - * @param dirName - * @retval bool true on success, false on error - * @note call getLastError() to determine cause of failure - */ - bool open(const String& dirName); - - /** - * @brief Close directory - */ - void close(); - - /** - * @brief Rewind directory stream to start so it can be re-enumerated - * @retval bool true on success, false on error - * @note call getLastError() to determine cause of failure - */ - bool rewind(); - - /** - * @brief Name of directory stream is attached to - * @retval String invalid if stream isn't open - */ - const String& getDirName() const - { - return name; - } - - /** - * @brief Determine if directory exists - * @retval bool true if stream is attached to a directory - */ - bool dirExist() const - { - return dir != nullptr; - } - - /** - * @brief Get path with leading separator /path/to/dir - */ - String getPath() const; - - /** - * @brief Get parent directory - * @retval String invalid if there is no parent directory - */ - String getParent() const; - - int index() const - { - return currentIndex; - } - - bool isValid() const - { - return currentIndex >= 0; - } - - size_t size() const - { - return totalSize; - } - - const FileStat& stat() const - { - return dirStat; - } - - bool next(); - -private: - String name; - DirHandle dir{}; - FileNameStat dirStat; - int currentIndex{-1}; - size_t totalSize{0}; -}; - -} // namespace IFS diff --git a/Sming/Core/Data/Stream/IFS/DirectoryTemplate.h b/Sming/Core/Data/Stream/IFS/DirectoryTemplate.h index 4e88dd5d0c..287c70b422 100644 --- a/Sming/Core/Data/Stream/IFS/DirectoryTemplate.h +++ b/Sming/Core/Data/Stream/IFS/DirectoryTemplate.h @@ -14,7 +14,7 @@ #pragma once #include "../SectionTemplate.h" -#include "Directory.h" +#include #define DIRSTREAM_FIELD_MAP(XX) \ XX(file_id, "File identifier") \ diff --git a/Sming/Core/Data/Stream/IFS/FileStream.h b/Sming/Core/Data/Stream/IFS/FileStream.h index 9fb9491317..3b8863a681 100644 --- a/Sming/Core/Data/Stream/IFS/FileStream.h +++ b/Sming/Core/Data/Stream/IFS/FileStream.h @@ -11,7 +11,7 @@ #pragma once #include "../ReadWriteStream.h" -#include "FsBase.h" +#include namespace IFS { diff --git a/Sming/Core/Data/Stream/IFS/FsBase.h b/Sming/Core/Data/Stream/IFS/FsBase.h deleted file mode 100644 index 98d00f4cf0..0000000000 --- a/Sming/Core/Data/Stream/IFS/FsBase.h +++ /dev/null @@ -1,72 +0,0 @@ -/**** - * Sming Framework Project - Open Source framework for high efficiency native ESP8266 development. - * Created 2015 by Skurydin Alexey - * http://github.com/SmingHub/Sming - * All files of the Sming Core are provided under the LGPL v3 license. - * - * FsBase.h - common base for file system classes - * - ****/ - -#pragma once - -#include - -namespace IFS -{ -class FsBase -{ -public: - FsBase(IFileSystem* filesys) : fileSystem(filesys) - { - } - - /** @brief determine if an error occurred during operation - * @retval int filesystem error code - */ - int getLastError() - { - return lastError; - } - - String getErrorString(int err) const - { - return fileSystem == nullptr ? Error::toString(err) : fileSystem->getErrorString(err); - } - - String getLastErrorString() const - { - return getErrorString(lastError); - } - - IFileSystem* getFileSystem() const - { - lastError = (fileSystem == nullptr) ? Error::NoFileSystem : FS_OK; - return fileSystem; - } - -protected: - /** @brief Check file operation result and note error code - * @param res result of fileXXX() operation to check - * @retval bool true if operation was successful, false if error occurred - */ - bool check(int res) - { - if(res >= 0) { - return true; - } - - if(lastError >= 0) { - lastError = res; - } - return false; - } - -protected: - mutable int lastError{FS_OK}; - -private: - IFileSystem* fileSystem; -}; - -} // namespace IFS From dd98be29f92ccbe99dedfe82808be64ce69fc46a Mon Sep 17 00:00:00 2001 From: mikee47 Date: Fri, 19 Feb 2021 08:08:44 +0000 Subject: [PATCH 02/11] Add structure for Compression information --- Sming/Core/Data/Stream/IFS/DirectoryTemplate.cpp | 4 ++-- Sming/Core/Network/Http/HttpResponse.cpp | 6 +++--- samples/Basic_IFS/app/application.cpp | 6 +++--- samples/Basic_IFS/resource/listing.json | 3 ++- 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/Sming/Core/Data/Stream/IFS/DirectoryTemplate.cpp b/Sming/Core/Data/Stream/IFS/DirectoryTemplate.cpp index 460aa885a5..63453bd88a 100644 --- a/Sming/Core/Data/Stream/IFS/DirectoryTemplate.cpp +++ b/Sming/Core/Data/Stream/IFS/DirectoryTemplate.cpp @@ -66,7 +66,7 @@ String DirectoryTemplate::getValue(const char* name) return statValid ? String(s.size) : nullptr; case Field::original_size: - return statValid ? String(s.originalSize) : nullptr; + return statValid ? String(s.compression.originalSize) : nullptr; case Field::attr: return statValid ? IFS::File::getAttributeString(s.attr) : nullptr; @@ -80,7 +80,7 @@ String DirectoryTemplate::getValue(const char* name) } else if(!s.attr[File::Attribute::Compressed]) { return ""; } else { - return toString(s.compression); + return toString(s.compression.type); } case Field::access: diff --git a/Sming/Core/Network/Http/HttpResponse.cpp b/Sming/Core/Network/Http/HttpResponse.cpp index 6990cd6615..78f9173ad7 100644 --- a/Sming/Core/Network/Http/HttpResponse.cpp +++ b/Sming/Core/Network/Http/HttpResponse.cpp @@ -59,9 +59,9 @@ bool HttpResponse::sendString(String&& text) noexcept bool HttpResponse::sendFile(const FileStat& stat) { auto file = new FileStream(stat); - if(stat.compression == File::Compression::GZip) { + if(stat.compression.type == File::Compression::Type::GZip) { headers[HTTP_HEADER_CONTENT_ENCODING] = F("gzip"); - } else if(stat.compression != File::Compression::None) { + } else if(stat.compression.type != File::Compression::Type::None) { debug_e("Unsupported compression type: %u", stat.compression); } @@ -76,7 +76,7 @@ bool HttpResponse::sendFile(const String& fileName, bool allowGzipFileCheck) String fnCompressed = fileName + _F(".gz"); if(fileStats(fnCompressed, stat) >= 0) { debug_d("found %s", stat.name); - stat.compression = File::Compression::GZip; + stat.compression.type = File::Compression::Type::GZip; stat.name = IFS::NameBuffer(fnCompressed); return sendFile(stat); } diff --git a/samples/Basic_IFS/app/application.cpp b/samples/Basic_IFS/app/application.cpp index 07f0c8ae98..57f8a9c0cd 100644 --- a/samples/Basic_IFS/app/application.cpp +++ b/samples/Basic_IFS/app/application.cpp @@ -80,10 +80,10 @@ void onFile(HttpRequest& request, HttpResponse& response) } else { // response.setCache(86400, true); // It's important to use cache for better performance. auto stream = new FileStream(stat); - if(stat.compression == File::Compression::GZip) { + if(stat.compression.type == File::Compression::Type::GZip) { response.headers[HTTP_HEADER_CONTENT_ENCODING] = F("gzip"); - } else if(stat.compression != File::Compression::None) { - debug_e("Unsupported compression type: %u", stat.compression); + } else if(stat.compression.type != File::Compression::Type::None) { + debug_e("Unsupported compression type: %u", stat.compression.type); } auto mimeType = ContentType::fromFullFileName(file.c_str(), MIME_TEXT); diff --git a/samples/Basic_IFS/resource/listing.json b/samples/Basic_IFS/resource/listing.json index 5a20750249..9c15c47968 100644 --- a/samples/Basic_IFS/resource/listing.json +++ b/samples/Basic_IFS/resource/listing.json @@ -12,7 +12,8 @@ "size": {{!as_int:size}}, "original_size": {{!as_int:original_size}}, "attr": "{{attr}}", - "access": "{{access}}" + "access": "{{access}}", + "compression": "{{compression}}" }{/SECTION} {SECTION} From 530e51a137d43b1101a44489ad776cde97c1cc22 Mon Sep 17 00:00:00 2001 From: mikee47 Date: Tue, 16 Feb 2021 08:43:50 +0000 Subject: [PATCH 03/11] Change setattr() to accept filename instead of handle If file is set to read-only, then it can't be changed back! --- Sming/Core/FileSystem.h | 16 ++++++++++++---- samples/Basic_IFS/fsimage.fwfs | 6 +++++- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/Sming/Core/FileSystem.h b/Sming/Core/FileSystem.h index e34e5488a5..c7788e4c78 100644 --- a/Sming/Core/FileSystem.h +++ b/Sming/Core/FileSystem.h @@ -505,15 +505,23 @@ inline int fileSetACL(file_t file, const File::ACL& acl) return fileSystem->setacl(file, acl); } -/** @brief Set file attributes - * @param file handle to open file, must have write access +/** @name Set file attributes + * @param filename + * @param attr * @retval int Error code + * @{ */ -inline int fileSetAttr(file_t file, File::Attributes attr) +inline int fileSetAttr(const char* filename, File::Attributes attr) { CHECK_FS(setattr) - return fileSystem->setattr(file, attr); + return fileSystem->setattr(filename, attr); +} + +inline int fileSetAttr(const String& filename, File::Attributes attr) +{ + return fileSetAttr(filename.c_str(), attr); } +/** @} */ /** @brief Set access control information for file * @param file handle to open file, must have write access diff --git a/samples/Basic_IFS/fsimage.fwfs b/samples/Basic_IFS/fsimage.fwfs index bb1a6be2e2..b8e7cbe19a 100644 --- a/samples/Basic_IFS/fsimage.fwfs +++ b/samples/Basic_IFS/fsimage.fwfs @@ -29,7 +29,11 @@ "read": "admin" }, { - "mask": "*.html", + "mask": [ + "*.html", + "*.css", + "*.png" + ], "readonly": true }, { From 658ee9856fd5b5350d27d356e8345c0bd55bf40b Mon Sep 17 00:00:00 2001 From: mikee47 Date: Sat, 20 Feb 2021 18:09:22 +0000 Subject: [PATCH 04/11] Define `_FILE_OFFSET_BITS=64` in Host builds to ensure file calls function correctly --- Sming/Arch/Host/build.mk | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Sming/Arch/Host/build.mk b/Sming/Arch/Host/build.mk index 5700a06743..db1582468f 100644 --- a/Sming/Arch/Host/build.mk +++ b/Sming/Arch/Host/build.mk @@ -21,7 +21,8 @@ GCC_UPGRADE_URL := https://sming.readthedocs.io/en/latest/arch/host/host-emulato CPPFLAGS += \ -m32 \ - -Wno-deprecated-declarations + -Wno-deprecated-declarations \ + -D_FILE_OFFSET_BITS=64 # => Tools MEMANALYZER = size From bd8c48f898360d85724df0e2e4ca866610041a7e Mon Sep 17 00:00:00 2001 From: mikee47 Date: Sat, 20 Feb 2021 11:19:40 +0000 Subject: [PATCH 05/11] CUSTOM_TARGETS handled in project.mk --- Sming/Arch/Esp32/app.mk | 2 +- Sming/Arch/Esp8266/app.mk | 2 +- Sming/Arch/Host/app.mk | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Sming/Arch/Esp32/app.mk b/Sming/Arch/Esp32/app.mk index 4c9fca76bd..a4f06d5efb 100644 --- a/Sming/Arch/Esp32/app.mk +++ b/Sming/Arch/Esp32/app.mk @@ -11,7 +11,7 @@ LDFLAGS += \ .PHONY: application -application: $(CUSTOM_TARGETS) $(TARGET_BIN) +application: $(TARGET_BIN) # $1 -> Linker script define LinkTarget diff --git a/Sming/Arch/Esp8266/app.mk b/Sming/Arch/Esp8266/app.mk index 2521c1df13..96ad91ec04 100644 --- a/Sming/Arch/Esp8266/app.mk +++ b/Sming/Arch/Esp8266/app.mk @@ -35,7 +35,7 @@ LDFLAGS += \ .PHONY: application -application: $(CUSTOM_TARGETS) $(FW_FILE_1) $(FW_FILE_2) +application: $(FW_FILE_1) $(FW_FILE_2) # $1 -> Linker script define LinkTarget diff --git a/Sming/Arch/Host/app.mk b/Sming/Arch/Host/app.mk index d5484569cf..f94ae254cf 100644 --- a/Sming/Arch/Host/app.mk +++ b/Sming/Arch/Host/app.mk @@ -15,7 +15,7 @@ TARGET_OUT_0 := $(FW_BASE)/$(APP_NAME)$(TOOL_EXT) # Target definitions .PHONY: application -application: $(CUSTOM_TARGETS) $(TARGET_OUT_0) +application: $(TARGET_OUT_0) $(TARGET_OUT_0): $(COMPONENTS_AR) $(info $(notdir $(PROJECT_DIR)): Linking $@) From bbf246338672d70d0de869c7cf8404ed14a2aab4 Mon Sep 17 00:00:00 2001 From: mikee47 Date: Sat, 20 Feb 2021 14:11:52 +0000 Subject: [PATCH 06/11] Define `HOME` in MinGW builds (required for openssl rand) --- Sming/Arch/Host/build.mk | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Sming/Arch/Host/build.mk b/Sming/Arch/Host/build.mk index db1582468f..c2fc4c9e8b 100644 --- a/Sming/Arch/Host/build.mk +++ b/Sming/Arch/Host/build.mk @@ -34,6 +34,9 @@ CLI_TARGET_OPTIONS = # $1 -> Command to execute ifeq ($(UNAME),Windows) DetachCommand = start $1 +# May be required by some applications (e.g. openssl) +HOME ?= $(USERPROFILE) +export HOME else DetachCommand = gnome-terminal -- bash -c "sleep 1; $1" endif From 1a4e02e749f274f92e1849b2b82f88c4120fef75 Mon Sep 17 00:00:00 2001 From: mikee47 Date: Sun, 21 Feb 2021 14:51:29 +0000 Subject: [PATCH 07/11] Remove `File` namespace and reassign `File` as object for easier file manipulation --- .../Host/Components/spi_flash/flashmem.cpp | 38 +++++----- .../Host/Core/Data/Stream/HostFileStream.cpp | 3 +- .../Host/Core/Data/Stream/HostFileStream.h | 2 +- Sming/Core/Data/Stream/Directory.h | 28 -------- .../Data/Stream/IFS/DirectoryTemplate.cpp | 6 +- Sming/Core/Data/Stream/IFS/FileStream.cpp | 14 ++-- Sming/Core/Data/Stream/IFS/FileStream.h | 8 +-- .../Data/Stream/IFS/HtmlDirectoryTemplate.cpp | 2 +- Sming/Core/FileSystem.h | 70 ++++++++++++------- Sming/Core/Network/Http/HttpResponse.cpp | 6 +- samples/Basic_IFS/app/application.cpp | 7 +- tests/HostTests/modules/Spiffs.cpp | 17 +++-- 12 files changed, 93 insertions(+), 108 deletions(-) delete mode 100644 Sming/Core/Data/Stream/Directory.h diff --git a/Sming/Arch/Host/Components/spi_flash/flashmem.cpp b/Sming/Arch/Host/Components/spi_flash/flashmem.cpp index 0237f9eaf4..6fead07de7 100644 --- a/Sming/Arch/Host/Components/spi_flash/flashmem.cpp +++ b/Sming/Arch/Host/Components/spi_flash/flashmem.cpp @@ -21,12 +21,11 @@ #include "flashmem.h" #include #include -#include +#include namespace { -IFS::IFileSystem& fileSys{IFS::Host::fileSystem}; -IFS::File::Handle flashFile{-1}; +IFS::File flashFile(&IFS::Host::getFileSystem()); size_t flashFileSize{0x400000U}; char flashFileName[256]; const char defaultFlashFileName[]{"flash.bin"}; @@ -59,26 +58,24 @@ bool host_flashmem_init(FlashmemConfig& config) config.filename = flashFileName; } - flashFile = fileSys.open(flashFileName, IFS::File::Create | IFS::File::ReadWrite); - if(flashFile < 0) { + if(!flashFile.open(flashFileName, IFS::File::Create | IFS::File::ReadWrite)) { hostmsg("Error opening \"%s\"", flashFileName); return false; } - int res = fileSys.lseek(flashFile, 0, SeekOrigin::End); + int res = flashFile.seek(0, SeekOrigin::End); if(res < 0) { - hostmsg("Error seeking \"%s\": %s", flashFileName, fileSys.getErrorString(res).c_str()); - fileSys.close(flashFile); - flashFile = -1; + hostmsg("Error seeking \"%s\": %s", flashFileName, flashFile.getErrorString(res).c_str()); + flashFile.close(); return false; } if(res == 0) { size_t size = config.createSize ?: flashFileSize; - res = fileSys.lseek(flashFile, size, SeekOrigin::Start); + res = flashFile.seek(size, SeekOrigin::Start); if(res != int(size)) { hostmsg("Error seeking beyond end of file \"%s\"", flashFileName); - } else if(fileSys.truncate(flashFile, size) < 0) { + } else if(!flashFile.truncate(size)) { hostmsg("Error truncating \"%s\" to %u bytes", flashFileName, size); } else { hostmsg("Created blank \"%s\", %u bytes", flashFileName, size); @@ -95,37 +92,36 @@ bool host_flashmem_init(FlashmemConfig& config) void host_flashmem_cleanup() { - fileSys.close(flashFile); - flashFile = -1; + flashFile.close(); hostmsg("Closed \"%s\"", flashFileName); } static int readFlashFile(uint32_t offset, void* buffer, size_t count) { - if(flashFile < 0) { + if(!flashFile) { return -1; } - int res = fileSys.lseek(flashFile, offset, SeekOrigin::Start); + int res = flashFile.seek(offset, SeekOrigin::Start); if(res >= 0) { - res = fileSys.read(flashFile, buffer, count); + res = flashFile.read(buffer, count); } if(res < 0) { - debug_w("readFlashFile(0x%08x, %u) failed: %s", offset, count, fileSys.getErrorString(res).c_str()); + debug_w("readFlashFile(0x%08x, %u) failed: %s", offset, count, flashFile.getErrorString(res).c_str()); } return res; } static int writeFlashFile(uint32_t offset, const void* data, size_t count) { - if(flashFile < 0) { + if(!flashFile) { return -1; } - int res = fileSys.lseek(flashFile, offset, SeekOrigin::Start); + int res = flashFile.seek(offset, SeekOrigin::Start); if(res >= 0) { - res = fileSys.write(flashFile, data, count); + res = flashFile.write(data, count); } if(res < 0) { - debug_w("writeFlashFile(0x%08x, %u) failed: %s", offset, count, fileSys.getErrorString(res).c_str()); + debug_w("writeFlashFile(0x%08x, %u) failed: %s", offset, count, flashFile.getErrorString(res).c_str()); } return res; } diff --git a/Sming/Arch/Host/Core/Data/Stream/HostFileStream.cpp b/Sming/Arch/Host/Core/Data/Stream/HostFileStream.cpp index 95832ad28a..70783b5703 100644 --- a/Sming/Arch/Host/Core/Data/Stream/HostFileStream.cpp +++ b/Sming/Arch/Host/Core/Data/Stream/HostFileStream.cpp @@ -9,8 +9,7 @@ ****/ #include "HostFileStream.h" -#include -HostFileStream::HostFileStream() : IFS::FileStream(&IFS::Host::fileSystem) +HostFileStream::HostFileStream() : IFS::FileStream(&IFS::Host::getFileSystem()) { } diff --git a/Sming/Arch/Host/Core/Data/Stream/HostFileStream.h b/Sming/Arch/Host/Core/Data/Stream/HostFileStream.h index 0332203d5c..381e955812 100644 --- a/Sming/Arch/Host/Core/Data/Stream/HostFileStream.h +++ b/Sming/Arch/Host/Core/Data/Stream/HostFileStream.h @@ -21,7 +21,7 @@ class HostFileStream : public IFS::FileStream public: HostFileStream(); - HostFileStream(const String& fileName, IFS::File::OpenFlags openFlags = IFS::File::ReadOnly) : HostFileStream() + HostFileStream(const String& fileName, IFS::OpenFlags openFlags = IFS::OpenFlag::Read) : HostFileStream() { open(fileName, openFlags); } diff --git a/Sming/Core/Data/Stream/Directory.h b/Sming/Core/Data/Stream/Directory.h deleted file mode 100644 index 81ee133379..0000000000 --- a/Sming/Core/Data/Stream/Directory.h +++ /dev/null @@ -1,28 +0,0 @@ -/**** - * Sming Framework Project - Open Source framework for high efficiency native ESP8266 development. - * Created 2015 by Skurydin Alexey - * http://github.com/anakod/Sming - * All files of the Sming Core are provided under the LGPL v3 license. - * - * Directory.h - * - * @author mikee47 May 2019 - * - ****/ - -#pragma once - -#include -#include - -/** - * @brief Directory stream class - * @ingroup stream data - */ -class Directory : public IFS::Directory -{ -public: - Directory() : IFS::Directory(::getFileSystem()) - { - } -}; diff --git a/Sming/Core/Data/Stream/IFS/DirectoryTemplate.cpp b/Sming/Core/Data/Stream/IFS/DirectoryTemplate.cpp index 63453bd88a..ca667ef846 100644 --- a/Sming/Core/Data/Stream/IFS/DirectoryTemplate.cpp +++ b/Sming/Core/Data/Stream/IFS/DirectoryTemplate.cpp @@ -69,7 +69,7 @@ String DirectoryTemplate::getValue(const char* name) return statValid ? String(s.compression.originalSize) : nullptr; case Field::attr: - return statValid ? IFS::File::getAttributeString(s.attr) : nullptr; + return statValid ? IFS::getFileAttributeString(s.attr) : nullptr; case Field::attr_long: return statValid ? toString(s.attr) : nullptr; @@ -77,14 +77,14 @@ String DirectoryTemplate::getValue(const char* name) case Field::compression: if(!statValid) { return nullptr; - } else if(!s.attr[File::Attribute::Compressed]) { + } else if(!s.attr[FileAttribute::Compressed]) { return ""; } else { return toString(s.compression.type); } case Field::access: - return statValid ? IFS::File::getAclString(s.acl) : nullptr; + return statValid ? IFS::getAclString(s.acl) : nullptr; case Field::access_long: return statValid ? toString(s.acl) : nullptr; diff --git a/Sming/Core/Data/Stream/IFS/FileStream.cpp b/Sming/Core/Data/Stream/IFS/FileStream.cpp index 66caa0c383..4f83212156 100644 --- a/Sming/Core/Data/Stream/IFS/FileStream.cpp +++ b/Sming/Core/Data/Stream/IFS/FileStream.cpp @@ -14,7 +14,7 @@ namespace IFS { -void FileStream::attach(File::Handle file, size_t size) +void FileStream::attach(FileHandle file, size_t size) { close(); if(file < 0) { @@ -33,7 +33,7 @@ void FileStream::attach(File::Handle file, size_t size) debug_d("attached file: '%s' (%u bytes) #0x%08X", fileName().c_str(), size, this); } -bool FileStream::open(const FileStat& stat, File::OpenFlags openFlags) +bool FileStream::open(const Stat& stat, OpenFlags openFlags) { auto fs = getFileSystem(); if(fs == nullptr) { @@ -42,7 +42,7 @@ bool FileStream::open(const FileStat& stat, File::OpenFlags openFlags) lastError = FS_OK; - File::Handle file = fs->fopen(stat, openFlags); + FileHandle file = fs->fopen(stat, openFlags); if(!check(file)) { return false; } @@ -51,7 +51,7 @@ bool FileStream::open(const FileStat& stat, File::OpenFlags openFlags) return true; } -bool FileStream::open(const String& fileName, File::OpenFlags openFlags) +bool FileStream::open(const String& fileName, OpenFlags openFlags) { auto fs = getFileSystem(); if(fs == nullptr) { @@ -60,7 +60,7 @@ bool FileStream::open(const String& fileName, File::OpenFlags openFlags) lastError = FS_OK; - File::Handle file = fs->open(fileName, openFlags); + FileHandle file = fs->open(fileName, openFlags); if(!check(file)) { debug_w("File '%s' open error: %s", fileName.c_str(), fs->getErrorString(file).c_str()); return false; @@ -179,7 +179,7 @@ String FileStream::fileName() const return nullptr; } - FileNameStat stat; + NameStat stat; int res = fs->fstat(handle, stat); return (res < 0 || stat.name.length == 0) ? nullptr : stat.name.buffer; } @@ -191,7 +191,7 @@ String FileStream::id() const return 0; } - FileStat stat; + Stat stat; int res = fs->fstat(handle, stat); if(res < 0) { return nullptr; diff --git a/Sming/Core/Data/Stream/IFS/FileStream.h b/Sming/Core/Data/Stream/IFS/FileStream.h index 3b8863a681..bac5188ce4 100644 --- a/Sming/Core/Data/Stream/IFS/FileStream.h +++ b/Sming/Core/Data/Stream/IFS/FileStream.h @@ -33,9 +33,9 @@ class FileStream : public FsBase, public ReadWriteStream * @param file * @param size */ - void attach(File::Handle file, size_t size); + void attach(FileHandle file, size_t size); - bool open(const FileStat& stat, File::OpenFlags openFlags = File::ReadOnly); + bool open(const Stat& stat, OpenFlags openFlags = OpenFlag::Read); /** @brief Open a file and attach this stream object to it * @param fileName @@ -43,7 +43,7 @@ class FileStream : public FsBase, public ReadWriteStream * @retval bool true on success, false on error * @note call getLastError() to determine cause of failure */ - bool open(const String& fileName, File::OpenFlags openFlags = File::ReadOnly); + bool open(const String& fileName, IFS::OpenFlags openFlags = OpenFlag::Read); /** @brief Close file */ @@ -138,7 +138,7 @@ class FileStream : public FsBase, public ReadWriteStream } private: - File::Handle handle{-1}; + FileHandle handle{-1}; size_t pos{0}; size_t size{0}; }; diff --git a/Sming/Core/Data/Stream/IFS/HtmlDirectoryTemplate.cpp b/Sming/Core/Data/Stream/IFS/HtmlDirectoryTemplate.cpp index 05cdeb47c7..579e709f9e 100644 --- a/Sming/Core/Data/Stream/IFS/HtmlDirectoryTemplate.cpp +++ b/Sming/Core/Data/Stream/IFS/HtmlDirectoryTemplate.cpp @@ -27,7 +27,7 @@ String HtmlDirectoryTemplate::getValue(const char* name) auto& stat = dir().stat(); if(FS("icon") == name) { - if(stat.attr[File::Attribute::Directory]) { + if(stat.attr[FileAttribute::Directory]) { return F("📁"); } diff --git a/Sming/Core/FileSystem.h b/Sming/Core/FileSystem.h index c7788e4c78..3255f8e959 100644 --- a/Sming/Core/FileSystem.h +++ b/Sming/Core/FileSystem.h @@ -16,32 +16,23 @@ #pragma once #include +#include +#include #include #include "WVector.h" ///< @deprecated see fileList() -namespace File -{ -using namespace IFS::File; -} - -using file_t = IFS::File::Handle; +using file_t = IFS::FileHandle; typedef SeekOrigin SeekOriginFlags; ///< @deprecated Use `SeekOrigin` instead +using FileHandle = IFS::FileHandle; using DirHandle = IFS::DirHandle; -using FileOpenFlag = File::OpenFlag; -using FileOpenFlags = File::OpenFlags; -using FileStat = File::Stat; -using FileNameStat = File::NameStat; +using FileOpenFlag = IFS::OpenFlag; +using FileOpenFlags = IFS::OpenFlags; +using FileAttribute = IFS::FileAttribute; +using FileAttributes = IFS::FileAttributes; +using FileStat = IFS::Stat; +using FileNameStat = IFS::NameStat; constexpr int FS_OK = IFS::FS_OK; -// Various file flag combinations -constexpr FileOpenFlags eFO_ReadOnly SMING_DEPRECATED{File::ReadOnly}; ///< @deprecated use File::ReadOnly -constexpr FileOpenFlags eFO_WriteOnly SMING_DEPRECATED{File::WriteOnly}; ///< @deprecated use File::WriteOnly -constexpr FileOpenFlags eFO_ReadWrite{File::ReadWrite}; ///< @deprecated use File::ReadWrite -constexpr FileOpenFlags eFO_CreateIfNotExist{File::Create}; ///< @deprecated use File::Create -constexpr FileOpenFlags eFO_Append{File::Append}; ///< @deprecated use File::Append -constexpr FileOpenFlags eFO_Truncate{File::Truncate}; ///< @deprecated use File::Truncate -constexpr FileOpenFlags eFO_CreateNewAlways{File::CreateNewAlways}; ///< @deprecated use File::CreateNewAlways - constexpr SeekOrigin eSO_FileStart{SeekOrigin::Start}; ///< @deprecated use SeekOrigin::Start constexpr SeekOrigin eSO_CurrentPos{SeekOrigin::Current}; ///< @deprecated use SeekOrigin::Current constexpr SeekOrigin eSO_FileEnd{SeekOrigin::End}; ///< @deprecated use SeekOrigin::End @@ -60,11 +51,40 @@ extern IFS::IFileSystem* activeFileSystem; } // namespace SmingInternal +class File : public IFS::File +{ +public: + File() : IFS::File(SmingInternal::activeFileSystem) + { + } +}; + +/** + * @brief Directory stream class + * @ingroup stream data + */ +class Directory : public IFS::Directory +{ +public: + Directory() : IFS::Directory(SmingInternal::activeFileSystem) + { + } +}; + +// Various file flag combinations +constexpr FileOpenFlags eFO_ReadOnly{File::ReadOnly}; ///< @deprecated use File::ReadOnly +constexpr FileOpenFlags eFO_WriteOnly{File::WriteOnly}; ///< @deprecated use File::WriteOnly +constexpr FileOpenFlags eFO_ReadWrite{File::ReadWrite}; ///< @deprecated use File::ReadWrite +constexpr FileOpenFlags eFO_CreateIfNotExist{File::Create}; ///< @deprecated use File::Create +constexpr FileOpenFlags eFO_Append{File::Append}; ///< @deprecated use File::Append +constexpr FileOpenFlags eFO_Truncate{File::Truncate}; ///< @deprecated use File::Truncate +constexpr FileOpenFlags eFO_CreateNewAlways{File::CreateNewAlways}; ///< @deprecated use File::CreateNewAlways + /* * Boilerplate check for file function wrappers to catch undefined filesystem. */ #define CHECK_FS(_method) \ - auto fileSystem = SmingInternal::activeFileSystem; \ + auto fileSystem = static_cast(SmingInternal::activeFileSystem); \ if(fileSystem == nullptr) { \ debug_e("ERROR in %s(): No active file system", __FUNCTION__); \ return file_t(IFS::Error::NoFileSystem); \ @@ -74,12 +94,12 @@ extern IFS::IFileSystem* activeFileSystem; * @brief Get the currently active file system, if any * @retval IFS::IFileSystem* */ -inline IFS::IFileSystem* getFileSystem() +inline IFS::FileSystem* getFileSystem() { if(SmingInternal::activeFileSystem == nullptr) { debug_e("ERROR: No active file system"); } - return SmingInternal::activeFileSystem; + return static_cast(SmingInternal::activeFileSystem); } /** @brief Sets the currently active file system @@ -499,7 +519,7 @@ inline int fileSystemCheck() * @param acl * @retval int Error code */ -inline int fileSetACL(file_t file, const File::ACL& acl) +inline int fileSetACL(file_t file, const IFS::ACL& acl) { CHECK_FS(setacl) return fileSystem->setacl(file, acl); @@ -511,13 +531,13 @@ inline int fileSetACL(file_t file, const File::ACL& acl) * @retval int Error code * @{ */ -inline int fileSetAttr(const char* filename, File::Attributes attr) +inline int fileSetAttr(const char* filename, FileAttributes attr) { CHECK_FS(setattr) return fileSystem->setattr(filename, attr); } -inline int fileSetAttr(const String& filename, File::Attributes attr) +inline int fileSetAttr(const String& filename, FileAttributes attr) { return fileSetAttr(filename.c_str(), attr); } diff --git a/Sming/Core/Network/Http/HttpResponse.cpp b/Sming/Core/Network/Http/HttpResponse.cpp index 78f9173ad7..0f8e9e52b5 100644 --- a/Sming/Core/Network/Http/HttpResponse.cpp +++ b/Sming/Core/Network/Http/HttpResponse.cpp @@ -59,9 +59,9 @@ bool HttpResponse::sendString(String&& text) noexcept bool HttpResponse::sendFile(const FileStat& stat) { auto file = new FileStream(stat); - if(stat.compression.type == File::Compression::Type::GZip) { + if(stat.compression.type == IFS::Compression::Type::GZip) { headers[HTTP_HEADER_CONTENT_ENCODING] = F("gzip"); - } else if(stat.compression.type != File::Compression::Type::None) { + } else if(stat.compression.type != IFS::Compression::Type::None) { debug_e("Unsupported compression type: %u", stat.compression); } @@ -76,7 +76,7 @@ bool HttpResponse::sendFile(const String& fileName, bool allowGzipFileCheck) String fnCompressed = fileName + _F(".gz"); if(fileStats(fnCompressed, stat) >= 0) { debug_d("found %s", stat.name); - stat.compression.type = File::Compression::Type::GZip; + stat.compression.type = IFS::Compression::Type::GZip; stat.name = IFS::NameBuffer(fnCompressed); return sendFile(stat); } diff --git a/samples/Basic_IFS/app/application.cpp b/samples/Basic_IFS/app/application.cpp index 57f8a9c0cd..3af196cb5b 100644 --- a/samples/Basic_IFS/app/application.cpp +++ b/samples/Basic_IFS/app/application.cpp @@ -5,7 +5,6 @@ #include #include -#include #include #include #include @@ -59,7 +58,7 @@ void onFile(HttpRequest& request, HttpResponse& response) return; } - if(stat.attr[File::Attribute::Directory]) { + if(stat.attr[FileAttribute::Directory]) { auto dir = new Directory; IFS::DirectoryTemplate* tmpl; String fmt = request.uri.Query["format"]; @@ -80,9 +79,9 @@ void onFile(HttpRequest& request, HttpResponse& response) } else { // response.setCache(86400, true); // It's important to use cache for better performance. auto stream = new FileStream(stat); - if(stat.compression.type == File::Compression::Type::GZip) { + if(stat.compression.type == IFS::Compression::Type::GZip) { response.headers[HTTP_HEADER_CONTENT_ENCODING] = F("gzip"); - } else if(stat.compression.type != File::Compression::Type::None) { + } else if(stat.compression.type != IFS::Compression::Type::None) { debug_e("Unsupported compression type: %u", stat.compression.type); } diff --git a/tests/HostTests/modules/Spiffs.cpp b/tests/HostTests/modules/Spiffs.cpp index 058d0a5a4d..75fd9e6eb1 100644 --- a/tests/HostTests/modules/Spiffs.cpp +++ b/tests/HostTests/modules/Spiffs.cpp @@ -3,9 +3,8 @@ #ifdef ARCH_HOST #include -#include #include -using IFileSystem = IFS::IFileSystem; +using FileSystem = IFS::FileSystem; #endif class SpiffsTest : public TestGroup @@ -84,13 +83,13 @@ class SpiffsTest : public TestGroup */ void checkSpiffsGen() { - IFS::IFileSystem::Info info; + FileSystem::Info info; int err = fileGetSystemInfo(info); CHECK(err >= 0); debug_i("fs attr = %s", toString(info.attr).c_str()); - IFileSystem* fsOld; - if(info.attr[IFileSystem::Attribute::NoMeta]) { + FileSystem* fsOld; + if(info.attr[FileSystem::Attribute::NoMeta]) { fsOld = mountSpiffsFromFile("old", "spiffsgen/spiff_rom_orig.bin"); } else { fsOld = mountSpiffsFromFile("old", "spiffsgen/spiff_rom_meta.bin"); @@ -106,9 +105,9 @@ class SpiffsTest : public TestGroup delete Storage::findDevice("old"); } - IFileSystem* mountSpiffsFromFile(const String& tag, const String& filename) + FileSystem* mountSpiffsFromFile(const String& tag, const String& filename) { - auto& hfs = IFS::Host::fileSystem; + auto& hfs = IFS::Host::getFileSystem(); auto f = hfs.open(filename, IFS::File::ReadOnly); if(f < 0) { debug_e("Failed to open '%s': %s", filename.c_str(), hfs.getErrorString(f).c_str()); @@ -129,10 +128,10 @@ class SpiffsTest : public TestGroup } debug_i("Mounted '%s' as '%s'", filename.c_str(), tag.c_str()); - return fs; + return FileSystem::cast(fs); } - void readCheck(IFileSystem* fsOld, IFileSystem* fsNew) + void readCheck(IFS::FileSystem* fsOld, IFS::FileSystem* fsNew) { DirHandle dir{}; int res = fsOld->opendir(nullptr, dir); From 1a32a4b7c74ced8d8472e979df65221a4afb15b6 Mon Sep 17 00:00:00 2001 From: mikee47 Date: Sun, 21 Feb 2021 17:22:49 +0000 Subject: [PATCH 08/11] Remove x permission --- .ci/build.cmd | 0 .ci/install.cmd | 0 Sming/Core/DateTime.cpp | 0 Sming/Core/DateTime.h | 0 Sming/Core/SmingLocale.h | 0 5 files changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 .ci/build.cmd mode change 100755 => 100644 .ci/install.cmd mode change 100755 => 100644 Sming/Core/DateTime.cpp mode change 100755 => 100644 Sming/Core/DateTime.h mode change 100755 => 100644 Sming/Core/SmingLocale.h diff --git a/.ci/build.cmd b/.ci/build.cmd old mode 100755 new mode 100644 diff --git a/.ci/install.cmd b/.ci/install.cmd old mode 100755 new mode 100644 diff --git a/Sming/Core/DateTime.cpp b/Sming/Core/DateTime.cpp old mode 100755 new mode 100644 diff --git a/Sming/Core/DateTime.h b/Sming/Core/DateTime.h old mode 100755 new mode 100644 diff --git a/Sming/Core/SmingLocale.h b/Sming/Core/SmingLocale.h old mode 100755 new mode 100644 From a68081cfe2f7128f72072f6296656b2caaab4d11 Mon Sep 17 00:00:00 2001 From: mikee47 Date: Mon, 22 Feb 2021 09:18:35 +0000 Subject: [PATCH 09/11] Rename `truncate` -> `ftruncate` for consistency --- Sming/Core/Data/Stream/IFS/FileStream.cpp | 2 +- Sming/Core/FileSystem.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Sming/Core/Data/Stream/IFS/FileStream.cpp b/Sming/Core/Data/Stream/IFS/FileStream.cpp index 4f83212156..d4f9e5be6d 100644 --- a/Sming/Core/Data/Stream/IFS/FileStream.cpp +++ b/Sming/Core/Data/Stream/IFS/FileStream.cpp @@ -210,7 +210,7 @@ bool FileStream::truncate(size_t newSize) return 0; } - bool res = check(fs->truncate(handle, newSize)); + bool res = check(fs->ftruncate(handle, newSize)); if(res) { size = newSize; if(pos > size) { diff --git a/Sming/Core/FileSystem.h b/Sming/Core/FileSystem.h index 3255f8e959..3c1feb5e33 100644 --- a/Sming/Core/FileSystem.h +++ b/Sming/Core/FileSystem.h @@ -277,7 +277,7 @@ template inline uint32_t fileGetSize(const TFileName& fileN inline int fileTruncate(file_t file, size_t newSize) { CHECK_FS(truncate); - return fileSystem->truncate(file, newSize); + return fileSystem->ftruncate(file, newSize); } /** @brief Truncate an open file at the current cursor position @@ -287,7 +287,7 @@ inline int fileTruncate(file_t file, size_t newSize) inline int fileTruncate(file_t file) { CHECK_FS(truncate); - return fileSystem->truncate(file); + return fileSystem->ftruncate(file); } /** @brief Truncate (reduce) the size of a file From 4a47a8cbb279451c0b9856064f52db1ea422226a Mon Sep 17 00:00:00 2001 From: mikee47 Date: Sat, 20 Feb 2021 18:09:49 +0000 Subject: [PATCH 10/11] Update IFS library --- Sming/Components/IFS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sming/Components/IFS b/Sming/Components/IFS index 1e50d014fa..4d6fcdb7d1 160000 --- a/Sming/Components/IFS +++ b/Sming/Components/IFS @@ -1 +1 @@ -Subproject commit 1e50d014fac7604026d0d4112f1855431a44496a +Subproject commit 4d6fcdb7d1e808b66acc8f03a99b77b79abac67d From 723c5cb4bd56392160972d1d0213929564ffb7bb Mon Sep 17 00:00:00 2001 From: mikee47 Date: Mon, 22 Feb 2021 22:31:54 +0000 Subject: [PATCH 11/11] Update spiffsgen.py to reflect revised metadata layout --- Sming/Components/spiffs/spiffsgen.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Sming/Components/spiffs/spiffsgen.py b/Sming/Components/spiffs/spiffsgen.py index b161c1c957..0ca153dcca 100644 --- a/Sming/Components/spiffs/spiffsgen.py +++ b/Sming/Components/spiffs/spiffsgen.py @@ -228,9 +228,10 @@ def to_binary(self): magic = 0xE3457A77 mtime = self.mtime attr = 0 - flags = 0xff userRole_admin = 0x04 - meta = struct.pack(b'