135 lines
3.2 KiB
C++
135 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)
|
|
{
|
|
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 = 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
|