// Copyright 2018 yuzu emulator team // Licensed under GPLv2 or any later version // Refer to the license.txt file included. #include #include #include "common/common_types.h" #include "common/logging/log.h" #include "core/file_sys/disk_filesystem.h" #include "core/file_sys/errors.h" namespace FileSys { std::string Disk_FileSystem::GetName() const { return "Disk"; } ResultVal> Disk_FileSystem::OpenFile(const std::string& path, Mode mode) const { std::string mode_str = ""; u32 mode_flags = static_cast(mode); // Calculate the correct open mode for the file. if ((mode_flags & static_cast(Mode::Read)) && (mode_flags & static_cast(Mode::Write))) { if (mode_flags & static_cast(Mode::Append)) mode_str = "a+"; else mode_str = "r+"; } else { if (mode_flags & static_cast(Mode::Read)) mode_str = "r"; else if (mode_flags & static_cast(Mode::Append)) mode_str = "a"; else if (mode_flags & static_cast(Mode::Write)) mode_str = "w"; } mode_str += "b"; std::string full_path = base_directory + path; auto file = std::make_shared(full_path, mode_str.c_str()); if (!file->IsOpen()) { return ERROR_PATH_NOT_FOUND; } return MakeResult>( std::make_unique(std::move(file))); } ResultCode Disk_FileSystem::DeleteFile(const Path& path) const { LOG_WARNING(Service_FS, "(STUBBED) called"); // TODO(bunnei): Use correct error code return ResultCode(-1); } ResultCode Disk_FileSystem::RenameFile(const Path& src_path, const Path& dest_path) const { LOG_WARNING(Service_FS, "(STUBBED) called"); // TODO(wwylele): Use correct error code return ResultCode(-1); } ResultCode Disk_FileSystem::DeleteDirectory(const Path& path) const { LOG_WARNING(Service_FS, "(STUBBED) called"); // TODO(wwylele): Use correct error code return ResultCode(-1); } ResultCode Disk_FileSystem::DeleteDirectoryRecursively(const Path& path) const { LOG_WARNING(Service_FS, "(STUBBED) called"); // TODO(wwylele): Use correct error code return ResultCode(-1); } ResultCode Disk_FileSystem::CreateFile(const std::string& path, u64 size) const { LOG_WARNING(Service_FS, "(STUBBED) called"); std::string full_path = base_directory + path; if (size == 0) { FileUtil::CreateEmptyFile(full_path); return RESULT_SUCCESS; } FileUtil::IOFile file(full_path, "wb"); // Creates a sparse file (or a normal file on filesystems without the concept of sparse files) // We do this by seeking to the right size, then writing a single null byte. if (file.Seek(size - 1, SEEK_SET) && file.WriteBytes("", 1) == 1) { return RESULT_SUCCESS; } LOG_ERROR(Service_FS, "Too large file"); // TODO(Subv): Find out the correct error code return ResultCode(-1); } ResultCode Disk_FileSystem::CreateDirectory(const Path& path) const { LOG_WARNING(Service_FS, "(STUBBED) called"); // TODO(wwylele): Use correct error code return ResultCode(-1); } ResultCode Disk_FileSystem::RenameDirectory(const Path& src_path, const Path& dest_path) const { LOG_WARNING(Service_FS, "(STUBBED) called"); // TODO(wwylele): Use correct error code return ResultCode(-1); } ResultVal> Disk_FileSystem::OpenDirectory( const Path& path) const { return MakeResult>(std::make_unique()); } u64 Disk_FileSystem::GetFreeSpaceSize() const { LOG_WARNING(Service_FS, "(STUBBED) called"); return 0; } ResultVal Disk_FileSystem::GetEntryType(const std::string& path) const { std::string full_path = base_directory + path; if (!FileUtil::Exists(full_path)) { return ERROR_PATH_NOT_FOUND; } // TODO(Subv): Find out the EntryType values UNIMPLEMENTED_MSG("Unimplemented GetEntryType"); } ResultVal Disk_Storage::Read(const u64 offset, const size_t length, u8* buffer) const { LOG_TRACE(Service_FS, "called offset=%llu, length=%zu", offset, length); file->Seek(offset, SEEK_SET); return MakeResult(file->ReadBytes(buffer, length)); } ResultVal Disk_Storage::Write(const u64 offset, const size_t length, const bool flush, const u8* buffer) const { LOG_WARNING(Service_FS, "(STUBBED) called"); file->Seek(offset, SEEK_SET); size_t written = file->WriteBytes(buffer, length); if (flush) { file->Flush(); } return MakeResult(written); } u64 Disk_Storage::GetSize() const { return file->GetSize(); } bool Disk_Storage::SetSize(const u64 size) const { LOG_WARNING(Service_FS, "(STUBBED) called"); return false; } u32 Disk_Directory::Read(const u32 count, Entry* entries) { LOG_WARNING(Service_FS, "(STUBBED) called"); return 0; } bool Disk_Directory::Close() const { LOG_WARNING(Service_FS, "(STUBBED) called"); return true; } } // namespace FileSys