#pragma once #if !defined(MIJIN_VIRTUAL_FILESYSTEM_FILESYSTEM_HPP_INCLUDED) #define MIJIN_VIRTUAL_FILESYSTEM_FILESYSTEM_HPP_INCLUDED 1 #include #include #include #include #include #include #include "../io/stream.hpp" namespace fs = std::filesystem; namespace mijin { // // public defines // // // public constants // // // public types // struct FileInfo { fs::path path; std::size_t size = 0; bool exists : 1 = false; bool isFolder : 1 = false; bool isSymlink : 1 = false; bool isSpecial : 1 = false; bool isHidden : 1 = false; }; class FileSystemAdapter { public: virtual ~FileSystemAdapter() = default; [[nodiscard]] virtual std::vector getRoots() = 0; [[nodiscard]] virtual fs::path getHomeFolder() = 0; [[nodiscard]] virtual std::vector listFiles(const fs::path& folder) = 0; [[nodiscard]] virtual FileInfo getFileInfo(const fs::path& file) = 0; [[nodiscard]] virtual StreamError open(const fs::path& path, FileOpenMode mode, std::unique_ptr& outStream) = 0; }; class OSFileSystemAdapter : public FileSystemAdapter { public: std::vector getRoots() override; fs::path getHomeFolder() override; std::vector listFiles(const fs::path& folder) override; FileInfo getFileInfo(const fs::path& file) override; StreamError open(const fs::path& path, FileOpenMode mode, std::unique_ptr& outStream) override; static OSFileSystemAdapter& getInstance(); }; // // public functions // inline std::string formatFileType(const FileInfo& info) { if (info.isFolder) { return "Folder"; } if (info.isSpecial) { return "Special"; } return "File"; } inline std::string formatFileSize(std::size_t sizeInBytes) { static constexpr std::array suffixes = {"bytes", "KiB", "MiB", "GiB", "TiB"}; // enough? if (sizeInBytes == 0) { return "0 bytes"; } const std::size_t pos = std::min(static_cast(std::ceil(std::log2(sizeInBytes))) / 10, suffixes.size() - 1); std::stringstream oss; oss << std::setprecision(2) << std::fixed; if (pos == 0) { oss << sizeInBytes << " bytes"; } else { const float converted = static_cast(sizeInBytes) / std::pow(2.f, 10.f * static_cast(pos)); oss << converted << " " << suffixes[pos]; } return oss.str(); } } // namespace mijin #endif // !defined(MIJIN_VIRTUAL_FILESYSTEM_FILESYSTEM_HPP_INCLUDED)