10 changed files with 329 additions and 16 deletions
-
4src/core/CMakeLists.txt
-
147src/core/file_sys/disk_filesystem.cpp
-
66src/core/file_sys/disk_filesystem.h
-
25src/core/file_sys/filesystem.h
-
12src/core/file_sys/romfs_filesystem.cpp
-
7src/core/file_sys/romfs_filesystem.h
-
41src/core/file_sys/savedata_factory.cpp
-
31src/core/file_sys/savedata_factory.h
-
11src/core/hle/service/filesystem/filesystem.cpp
-
1src/core/hle/service/filesystem/filesystem.h
@ -0,0 +1,147 @@ |
|||
// Copyright 2018 yuzu emulator team
|
|||
// Licensed under GPLv2 or any later version
|
|||
// Refer to the license.txt file included.
|
|||
|
|||
#include <cstring>
|
|||
#include <memory>
|
|||
#include "common/common_types.h"
|
|||
#include "common/logging/log.h"
|
|||
#include "core/file_sys/disk_filesystem.h"
|
|||
|
|||
namespace FileSys { |
|||
|
|||
std::string Disk_FileSystem::GetName() const { |
|||
return "Disk"; |
|||
} |
|||
|
|||
ResultVal<std::unique_ptr<StorageBackend>> Disk_FileSystem::OpenFile(const std::string& path, |
|||
Mode mode) const { |
|||
ASSERT_MSG(mode == Mode::Read || mode == Mode::Write, "Other file modes are not supported"); |
|||
|
|||
std::string full_path = base_directory + path; |
|||
auto file = std::make_shared<FileUtil::IOFile>(full_path, mode == Mode::Read ? "rb" : "wb"); |
|||
|
|||
if (!file->IsOpen()) { |
|||
// TODO(Subv): Find out the correct error code.
|
|||
return ResultCode(-1); |
|||
} |
|||
|
|||
return MakeResult<std::unique_ptr<StorageBackend>>( |
|||
std::make_unique<Disk_Storage>(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<std::unique_ptr<DirectoryBackend>> Disk_FileSystem::OpenDirectory( |
|||
const Path& path) const { |
|||
return MakeResult<std::unique_ptr<DirectoryBackend>>(std::make_unique<Disk_Directory>()); |
|||
} |
|||
|
|||
u64 Disk_FileSystem::GetFreeSpaceSize() const { |
|||
LOG_WARNING(Service_FS, "(STUBBED) called"); |
|||
return 0; |
|||
} |
|||
|
|||
ResultVal<FileSys::EntryType> Disk_FileSystem::GetEntryType(const std::string& path) const { |
|||
std::string full_path = base_directory + path; |
|||
if (!FileUtil::Exists(full_path)) { |
|||
// TODO(Subv): Find out what this actually means
|
|||
return ResultCode(ErrorModule::FS, 1); |
|||
} |
|||
|
|||
// TODO(Subv): Find out the EntryType values
|
|||
UNIMPLEMENTED_MSG("Unimplemented GetEntryType"); |
|||
} |
|||
|
|||
ResultVal<size_t> 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<size_t>(file->ReadBytes(buffer, length)); |
|||
} |
|||
|
|||
ResultVal<size_t> 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<size_t>(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
|
|||
@ -0,0 +1,66 @@ |
|||
// Copyright 2018 yuzu emulator team |
|||
// Licensed under GPLv2 or any later version |
|||
// Refer to the license.txt file included. |
|||
|
|||
#pragma once |
|||
|
|||
#include <cstddef> |
|||
#include <memory> |
|||
#include <string> |
|||
#include "common/common_types.h" |
|||
#include "common/file_util.h" |
|||
#include "core/file_sys/directory.h" |
|||
#include "core/file_sys/filesystem.h" |
|||
#include "core/file_sys/storage.h" |
|||
#include "core/hle/result.h" |
|||
|
|||
namespace FileSys { |
|||
|
|||
class Disk_FileSystem : public FileSystemBackend { |
|||
public: |
|||
explicit Disk_FileSystem(std::string base_directory) |
|||
: base_directory(std::move(base_directory)) {} |
|||
|
|||
std::string GetName() const override; |
|||
|
|||
ResultVal<std::unique_ptr<StorageBackend>> OpenFile(const std::string& path, |
|||
Mode mode) const override; |
|||
ResultCode DeleteFile(const Path& path) const override; |
|||
ResultCode RenameFile(const Path& src_path, const Path& dest_path) const override; |
|||
ResultCode DeleteDirectory(const Path& path) const override; |
|||
ResultCode DeleteDirectoryRecursively(const Path& path) const override; |
|||
ResultCode CreateFile(const std::string& path, u64 size) const override; |
|||
ResultCode CreateDirectory(const Path& path) const override; |
|||
ResultCode RenameDirectory(const Path& src_path, const Path& dest_path) const override; |
|||
ResultVal<std::unique_ptr<DirectoryBackend>> OpenDirectory(const Path& path) const override; |
|||
u64 GetFreeSpaceSize() const override; |
|||
ResultVal<EntryType> GetEntryType(const std::string& path) const override; |
|||
|
|||
protected: |
|||
std::string base_directory; |
|||
}; |
|||
|
|||
class Disk_Storage : public StorageBackend { |
|||
public: |
|||
Disk_Storage(std::shared_ptr<FileUtil::IOFile> file) : file(std::move(file)) {} |
|||
|
|||
ResultVal<size_t> Read(u64 offset, size_t length, u8* buffer) const override; |
|||
ResultVal<size_t> Write(u64 offset, size_t length, bool flush, const u8* buffer) const override; |
|||
u64 GetSize() const override; |
|||
bool SetSize(u64 size) const override; |
|||
bool Close() const override { |
|||
return false; |
|||
} |
|||
void Flush() const override {} |
|||
|
|||
private: |
|||
std::shared_ptr<FileUtil::IOFile> file; |
|||
}; |
|||
|
|||
class Disk_Directory : public DirectoryBackend { |
|||
public: |
|||
u32 Read(const u32 count, Entry* entries) override; |
|||
bool Close() const override; |
|||
}; |
|||
|
|||
} // namespace FileSys |
|||
@ -0,0 +1,41 @@ |
|||
// Copyright 2018 yuzu emulator team
|
|||
// Licensed under GPLv2 or any later version
|
|||
// Refer to the license.txt file included.
|
|||
|
|||
#include <cinttypes>
|
|||
#include <memory>
|
|||
#include "common/common_types.h"
|
|||
#include "common/logging/log.h"
|
|||
#include "common/string_util.h"
|
|||
#include "core/file_sys/disk_filesystem.h"
|
|||
#include "core/file_sys/savedata_factory.h"
|
|||
|
|||
namespace FileSys { |
|||
|
|||
SaveData_Factory::SaveData_Factory(std::string nand_directory) |
|||
: nand_directory(std::move(nand_directory)) {} |
|||
|
|||
ResultVal<std::unique_ptr<FileSystemBackend>> SaveData_Factory::Open(const Path& path) { |
|||
// TODO(Subv): Somehow obtain these values.
|
|||
u64 title_id = 0; |
|||
u32 user = 0; |
|||
std::string save_directory = Common::StringFromFormat("%ssave/%016" PRIX64 "/%08X", |
|||
nand_directory.c_str(), title_id, user); |
|||
auto archive = std::make_unique<Disk_FileSystem>(save_directory); |
|||
return MakeResult<std::unique_ptr<FileSystemBackend>>(std::move(archive)); |
|||
} |
|||
|
|||
ResultCode SaveData_Factory::Format(const Path& path, |
|||
const FileSys::ArchiveFormatInfo& format_info) { |
|||
LOG_ERROR(Service_FS, "Unimplemented Format archive %s", GetName().c_str()); |
|||
// TODO(bunnei): Find the right error code for this
|
|||
return ResultCode(-1); |
|||
} |
|||
|
|||
ResultVal<ArchiveFormatInfo> SaveData_Factory::GetFormatInfo(const Path& path) const { |
|||
LOG_ERROR(Service_FS, "Unimplemented GetFormatInfo archive %s", GetName().c_str()); |
|||
// TODO(bunnei): Find the right error code for this
|
|||
return ResultCode(-1); |
|||
} |
|||
|
|||
} // namespace FileSys
|
|||
@ -0,0 +1,31 @@ |
|||
// Copyright 2018 yuzu emulator team |
|||
// Licensed under GPLv2 or any later version |
|||
// Refer to the license.txt file included. |
|||
|
|||
#pragma once |
|||
|
|||
#include <memory> |
|||
#include <string> |
|||
#include "common/common_types.h" |
|||
#include "core/file_sys/filesystem.h" |
|||
#include "core/hle/result.h" |
|||
|
|||
namespace FileSys { |
|||
|
|||
/// File system interface to the SaveData archive |
|||
class SaveData_Factory final : public FileSystemFactory { |
|||
public: |
|||
explicit SaveData_Factory(std::string nand_directory); |
|||
|
|||
std::string GetName() const override { |
|||
return "SaveData_Factory"; |
|||
} |
|||
ResultVal<std::unique_ptr<FileSystemBackend>> Open(const Path& path) override; |
|||
ResultCode Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info) override; |
|||
ResultVal<ArchiveFormatInfo> GetFormatInfo(const Path& path) const override; |
|||
|
|||
private: |
|||
std::string nand_directory; |
|||
}; |
|||
|
|||
} // namespace FileSys |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue