137 lines
3.2 KiB
C++

#include "./filesystem.hpp"
#include "../platform/folders.hpp"
namespace mijin
{
//
// internal defines
//
//
// internal constants
//
//
// internal types
//
//
// internal variables
//
//
// internal functions
//
//
// public functions
//
fs::path OSFileSystemAdapter::getHomeFolder()
{
return getKnownFolder(KnownFolder::USER_HOME);
}
std::vector<FileInfo> OSFileSystemAdapter::listFiles(const fs::path& folder)
{
std::vector<FileInfo> entries;
std::error_code err;
const fs::directory_iterator iterator(folder, fs::directory_options::skip_permission_denied, err);
if (err) {
return {}; // TODO: propagate?
}
for (const fs::directory_entry& entry : iterator)
{
FileInfo& info = entries.emplace_back();
info.path = entry.path();
info.exists = true;
info.isFolder = entry.is_directory(err);
info.isSymlink = entry.is_symlink(err);
info.isSpecial = !info.isFolder && !entry.is_regular_file(err);
info.isHidden = info.path.filename().string().starts_with('.'); // at least for Linux
if (info.isFolder)
{
std::error_code errorCode;
fs::directory_iterator dirIt(info.path, errorCode);
if (errorCode != std::error_code{})
{
info.size = std::distance(dirIt, fs::directory_iterator());
}
else
{
info.size = 0;
}
}
else if (!info.isSpecial)
{
info.size = entry.file_size(err);
if (err)
{
info.size = 0;
}
}
}
return entries;
}
FileInfo OSFileSystemAdapter::getFileInfo(const fs::path& file)
{
FileInfo info = {};
std::error_code err;
info.path = file;
info.exists = fs::exists(file, err);
if (info.exists)
{
info.isFolder = fs::is_directory(file, err);
info.isSymlink = fs::is_symlink(file, err);
info.isSpecial = !info.isFolder && !fs::is_regular_file(file, err);
info.isHidden = info.path.filename().string().starts_with('.'); // at least for Linux
if (info.isFolder) {
MIJIN_TRY
{
info.size = std::distance(fs::directory_iterator(info.path), fs::directory_iterator());
}
MIJIN_CATCH(std::runtime_error&)
{
info.size = 0;
}
}
else if (!info.isSpecial)
{
info.size = fs::file_size(file, err);
if (err) {
info.size = 0;
}
}
}
return info;
}
Optional<fs::path> OSFileSystemAdapter::getNativePath(const fs::path& file)
{
return file;
}
StreamError OSFileSystemAdapter::open(const fs::path& path, FileOpenMode mode, std::unique_ptr<Stream>& outStream)
{
const std::string pathStr = path.string();
auto stream = std::make_unique<FileStream>();
const StreamError error = stream->open(pathStr.c_str(), mode);
if (error != StreamError::SUCCESS) {
return error;
}
outStream = std::move(stream);
return StreamError::SUCCESS;
}
OSFileSystemAdapter& OSFileSystemAdapter::getInstance() // static
{
static OSFileSystemAdapter instance;
return instance;
}
} // namespace mijin