2023-05-29 14:51:44 +02:00

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)