106 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			106 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| 
 | |
| #pragma once
 | |
| 
 | |
| #if !defined(MIJIN_VIRTUAL_FILESYSTEM_FILESYSTEM_HPP_INCLUDED)
 | |
| #define MIJIN_VIRTUAL_FILESYSTEM_FILESYSTEM_HPP_INCLUDED 1
 | |
| 
 | |
| #include <array>
 | |
| #include <cmath>
 | |
| #include <filesystem>
 | |
| #include <sstream>
 | |
| #include <string>
 | |
| #include <vector>
 | |
| #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<fs::path> getRoots() = 0;
 | |
|     [[nodiscard]] virtual fs::path getHomeFolder() = 0;
 | |
|     [[nodiscard]] virtual std::vector<FileInfo> 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<Stream>& outStream) = 0;
 | |
| };
 | |
| 
 | |
| class OSFileSystemAdapter : public FileSystemAdapter
 | |
| {
 | |
| public:
 | |
|     std::vector<fs::path> getRoots() override;
 | |
|     fs::path getHomeFolder() override;
 | |
|     std::vector<FileInfo> listFiles(const fs::path& folder) override;
 | |
|     FileInfo getFileInfo(const fs::path& file) override;
 | |
|     StreamError open(const fs::path& path, FileOpenMode mode, std::unique_ptr<Stream>& 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::size_t>(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<float>(sizeInBytes) / std::pow(2.f, 10.f * static_cast<float>(pos));
 | |
|         oss << converted << " " << suffixes[pos];
 | |
|     }
 | |
|     return oss.str();
 | |
| }
 | |
| 
 | |
| } // namespace mijin
 | |
| 
 | |
| #endif // !defined(MIJIN_VIRTUAL_FILESYSTEM_FILESYSTEM_HPP_INCLUDED)
 |