137 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			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
 |