#include "./filesystem.hpp" #include "../platform/folders.hpp" #include namespace fs = std::filesystem; namespace mijin { // // internal defines // // // internal constants // // // internal types // // // internal variables // // // internal functions // namespace { void doGetFileInfo(const fs::path& stlPath, FileInfo& outInfo) { std::error_code err; outInfo.isFolder = fs::is_directory(stlPath, err); outInfo.isSymlink = fs::is_symlink(stlPath, err); outInfo.isSpecial = !outInfo.isFolder && !fs::is_regular_file(stlPath, err); outInfo.isHidden = stlPath.c_str()[0] == '.'; // at least for Linux if (outInfo.isFolder) { const fs::directory_iterator dirIt(stlPath, err); if (err != std::error_code{}) { outInfo.size = std::distance(dirIt, fs::directory_iterator()); } else { outInfo.size = 0; } } else if (!outInfo.isSpecial) { outInfo.size = fs::file_size(stlPath, err); if (err) { outInfo.size = 0; } } } } // // public functions // std::vector OSFileSystemAdapter::listFiles(PathView folder) { std::vector entries; std::error_code err; const fs::path stlFolder(folder.stringView()); const fs::directory_iterator iterator(stlFolder, fs::directory_options::skip_permission_denied, err); if (err) { return {}; // TODO: propagate? } for (const fs::directory_entry& stlEntry : iterator) { FolderEntry& entry = entries.emplace_back(); entry.path = stlEntry.path().generic_string(); entry.info.exists = true; doGetFileInfo(stlEntry.path(), entry.info); } return entries; } FileInfo OSFileSystemAdapter::getFileInfo(PathView file) { const fs::path stlFile(file.stringView()); FileInfo info = {}; std::error_code err; info.exists = fs::exists(stlFile, err); if (info.exists) { doGetFileInfo(fs::path(file.stringView()), info); } return info; } Optional OSFileSystemAdapter::getNativePath(PathView file) { return NativePath(file); } StreamError OSFileSystemAdapter::open(PathView path, FileOpenMode mode, std::unique_ptr& outStream) { const PathView::string_view_t pathSv = path.stringView(); char* pathStr = static_cast(alloca(pathSv.size() + 1)); std::memcpy(pathStr, pathSv.data(), pathSv.size()); pathStr[pathSv.size()] = '\0'; auto stream = std::make_unique(); const StreamError error = stream->open(pathStr, 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