ams: support building unit test programs on windows/linux/macos

This commit is contained in:
Michael Scire 2022-03-06 12:08:20 -08:00 committed by SciresM
parent 9a38be201a
commit 64a97576d0
756 changed files with 33359 additions and 9372 deletions

View file

@ -39,13 +39,13 @@ namespace ams::fssrv::impl {
class FileInterfaceAdapter {
NON_COPYABLE(FileInterfaceAdapter);
NON_MOVEABLE(FileInterfaceAdapter);
private:
ams::sf::SharedPointer<FileSystemInterfaceAdapter> m_parent_filesystem;
std::unique_ptr<fs::fsa::IFile> m_base_file;
util::unique_lock<fssystem::SemaphoreAdapter> m_open_count_semaphore;
bool m_allow_all_operations;
public:
FileInterfaceAdapter(std::unique_ptr<fs::fsa::IFile> &&file, FileSystemInterfaceAdapter *parent, util::unique_lock<fssystem::SemaphoreAdapter> &&sema);
~FileInterfaceAdapter();
FileInterfaceAdapter(std::unique_ptr<fs::fsa::IFile> &&file, FileSystemInterfaceAdapter *parent, bool allow_all);
private:
void InvalidateCache();
public:
@ -62,13 +62,13 @@ namespace ams::fssrv::impl {
class DirectoryInterfaceAdapter {
NON_COPYABLE(DirectoryInterfaceAdapter);
NON_MOVEABLE(DirectoryInterfaceAdapter);
private:
ams::sf::SharedPointer<FileSystemInterfaceAdapter> m_parent_filesystem;
std::unique_ptr<fs::fsa::IDirectory> m_base_dir;
util::unique_lock<fssystem::SemaphoreAdapter> m_open_count_semaphore;
bool m_allow_all_operations;
public:
DirectoryInterfaceAdapter(std::unique_ptr<fs::fsa::IDirectory> &&dir, FileSystemInterfaceAdapter *parent, util::unique_lock<fssystem::SemaphoreAdapter> &&sema);
~DirectoryInterfaceAdapter();
DirectoryInterfaceAdapter(std::unique_ptr<fs::fsa::IDirectory> &&dir, FileSystemInterfaceAdapter *parent, bool allow_all);
public:
/* Command API */
Result Read(ams::sf::Out<s64> out, const ams::sf::OutBuffer &out_entries);
@ -78,22 +78,26 @@ namespace ams::fssrv::impl {
class FileSystemInterfaceAdapter : public ams::sf::ISharedObject {
NON_COPYABLE(FileSystemInterfaceAdapter);
NON_MOVEABLE(FileSystemInterfaceAdapter);
private:
std::shared_ptr<fs::fsa::IFileSystem> m_base_fs;
util::unique_lock<fssystem::SemaphoreAdapter> m_mount_count_semaphore;
os::ReaderWriterLock m_invalidation_lock;
bool m_open_count_limited;
bool m_deep_retry_enabled = false;
fs::PathFlags m_path_flags;
bool m_allow_all_operations;
bool m_is_mitm_interface;
public:
FileSystemInterfaceAdapter(std::shared_ptr<fs::fsa::IFileSystem> &&fs, bool open_limited);
/* TODO: Other constructors. */
FileSystemInterfaceAdapter(std::shared_ptr<fs::fsa::IFileSystem> &&fs, const fs::PathFlags &flags, bool allow_all, bool is_mitm_interface = false)
: m_base_fs(std::move(fs)), m_path_flags(flags), m_allow_all_operations(allow_all), m_is_mitm_interface(is_mitm_interface)
{
/* ... */
}
~FileSystemInterfaceAdapter();
public:
bool IsDeepRetryEnabled() const;
bool IsAccessFailureDetectionObserved() const;
util::optional<std::shared_lock<os::ReaderWriterLock>> AcquireCacheInvalidationReadLock();
os::ReaderWriterLock &GetReaderWriterLockForCacheInvalidation();
FileSystemInterfaceAdapter(std::shared_ptr<fs::fsa::IFileSystem> &&fs, bool allow_all, bool is_mitm_interface = false)
: m_base_fs(std::move(fs)), m_path_flags(), m_allow_all_operations(allow_all), m_is_mitm_interface(is_mitm_interface)
{
/* ... */
}
private:
Result SetUpPath(fs::Path *out, const fssrv::sf::Path &sf_path);
public:
/* Command API. */
Result CreateFile(const fssrv::sf::Path &path, s64 size, s32 option);
@ -116,4 +120,143 @@ namespace ams::fssrv::impl {
Result QueryEntry(const ams::sf::OutBuffer &out_buf, const ams::sf::InBuffer &in_buf, s32 query_id, const fssrv::sf::Path &path);
};
#if defined(ATMOSPHERE_OS_HORIZON)
class RemoteFile {
NON_COPYABLE(RemoteFile);
NON_MOVEABLE(RemoteFile);
private:
::FsFile m_base_file;
public:
RemoteFile(::FsFile &s) : m_base_file(s) { /* ... */}
virtual ~RemoteFile() { fsFileClose(std::addressof(m_base_file)); }
public:
Result Read(ams::sf::Out<s64> out, s64 offset, const ams::sf::OutNonSecureBuffer &buffer, s64 size, fs::ReadOption option) {
return fsFileRead(std::addressof(m_base_file), offset, buffer.GetPointer(), size, option._value, reinterpret_cast<u64 *>(out.GetPointer()));
}
Result Write(s64 offset, const ams::sf::InNonSecureBuffer &buffer, s64 size, fs::WriteOption option) {
return fsFileWrite(std::addressof(m_base_file), offset, buffer.GetPointer(), size, option._value);
}
Result Flush(){
return fsFileFlush(std::addressof(m_base_file));
}
Result SetSize(s64 size) {
return fsFileSetSize(std::addressof(m_base_file), size);
}
Result GetSize(ams::sf::Out<s64> out) {
return fsFileGetSize(std::addressof(m_base_file), out.GetPointer());
}
Result OperateRange(ams::sf::Out<fs::FileQueryRangeInfo> out, s32 op_id, s64 offset, s64 size) {
static_assert(sizeof(::FsRangeInfo) == sizeof(fs::FileQueryRangeInfo));
return fsFileOperateRange(std::addressof(m_base_file), static_cast<::FsOperationId>(op_id), offset, size, reinterpret_cast<::FsRangeInfo *>(out.GetPointer()));
}
Result OperateRangeWithBuffer(const ams::sf::OutNonSecureBuffer &out_buf, const ams::sf::InNonSecureBuffer &in_buf, s32 op_id, s64 offset, s64 size) {
AMS_UNUSED(out_buf, in_buf, op_id, offset, size);
AMS_ABORT("TODO");
}
};
static_assert(fssrv::sf::IsIFile<RemoteFile>);
class RemoteDirectory {
NON_COPYABLE(RemoteDirectory);
NON_MOVEABLE(RemoteDirectory);
private:
::FsDir m_base_dir;
public:
RemoteDirectory(::FsDir &s) : m_base_dir(s) { /* ... */}
virtual ~RemoteDirectory() { fsDirClose(std::addressof(m_base_dir)); }
public:
Result Read(ams::sf::Out<s64> out, const ams::sf::OutBuffer &out_entries) {
static_assert(sizeof(::FsDirectoryEntry) == sizeof(fs::DirectoryEntry));
return fsDirRead(std::addressof(m_base_dir), out.GetPointer(), out_entries.GetSize() / sizeof(fs::DirectoryEntry), reinterpret_cast<::FsDirectoryEntry *>(out_entries.GetPointer()));
}
Result GetEntryCount(ams::sf::Out<s64> out) {
return fsDirGetEntryCount(std::addressof(m_base_dir), out.GetPointer());
}
};
static_assert(fssrv::sf::IsIDirectory<RemoteDirectory>);
class RemoteFileSystem {
NON_COPYABLE(RemoteFileSystem);
NON_MOVEABLE(RemoteFileSystem);
private:
::FsFileSystem m_base_fs;
public:
RemoteFileSystem(::FsFileSystem &s) : m_base_fs(s) { /* ... */}
virtual ~RemoteFileSystem() { fsFsClose(std::addressof(m_base_fs)); }
public:
/* Command API. */
Result CreateFile(const fssrv::sf::Path &path, s64 size, s32 option) {
return fsFsCreateFile(std::addressof(m_base_fs), path.str, size, option);
}
Result DeleteFile(const fssrv::sf::Path &path) {
return fsFsDeleteFile(std::addressof(m_base_fs), path.str);
}
Result CreateDirectory(const fssrv::sf::Path &path) {
return fsFsCreateDirectory(std::addressof(m_base_fs), path.str);
}
Result DeleteDirectory(const fssrv::sf::Path &path) {
return fsFsDeleteDirectory(std::addressof(m_base_fs), path.str);
}
Result DeleteDirectoryRecursively(const fssrv::sf::Path &path) {
return fsFsDeleteDirectoryRecursively(std::addressof(m_base_fs), path.str);
}
Result RenameFile(const fssrv::sf::Path &old_path, const fssrv::sf::Path &new_path) {
return fsFsRenameFile(std::addressof(m_base_fs), old_path.str, new_path.str);
}
Result RenameDirectory(const fssrv::sf::Path &old_path, const fssrv::sf::Path &new_path) {
return fsFsRenameDirectory(std::addressof(m_base_fs), old_path.str, new_path.str);
}
Result GetEntryType(ams::sf::Out<u32> out, const fssrv::sf::Path &path) {
static_assert(sizeof(::FsDirEntryType) == sizeof(u32));
return fsFsGetEntryType(std::addressof(m_base_fs), path.str, reinterpret_cast<::FsDirEntryType *>(out.GetPointer()));
}
Result Commit() {
return fsFsCommit(std::addressof(m_base_fs));
}
Result GetFreeSpaceSize(ams::sf::Out<s64> out, const fssrv::sf::Path &path) {
return fsFsGetFreeSpace(std::addressof(m_base_fs), path.str, out.GetPointer());
}
Result GetTotalSpaceSize(ams::sf::Out<s64> out, const fssrv::sf::Path &path) {
return fsFsGetTotalSpace(std::addressof(m_base_fs), path.str, out.GetPointer());
}
Result CleanDirectoryRecursively(const fssrv::sf::Path &path) {
return fsFsCleanDirectoryRecursively(std::addressof(m_base_fs), path.str);
}
Result GetFileTimeStampRaw(ams::sf::Out<fs::FileTimeStampRaw> out, const fssrv::sf::Path &path) {
static_assert(sizeof(fs::FileTimeStampRaw) == sizeof(::FsTimeStampRaw));
return fsFsGetFileTimeStampRaw(std::addressof(m_base_fs), path.str, reinterpret_cast<::FsTimeStampRaw *>(out.GetPointer()));
}
Result QueryEntry(const ams::sf::OutBuffer &out_buf, const ams::sf::InBuffer &in_buf, s32 query_id, const fssrv::sf::Path &path) {
return fsFsQueryEntry(std::addressof(m_base_fs), out_buf.GetPointer(), out_buf.GetSize(), in_buf.GetPointer(), in_buf.GetSize(), path.str, static_cast<FsFileSystemQueryId>(query_id));
}
Result OpenFile(ams::sf::Out<ams::sf::SharedPointer<fssrv::sf::IFile>> out, const fssrv::sf::Path &path, u32 mode);
Result OpenDirectory(ams::sf::Out<ams::sf::SharedPointer<fssrv::sf::IDirectory>> out, const fssrv::sf::Path &path, u32 mode);
};
static_assert(fssrv::sf::IsIFileSystem<RemoteFileSystem>);
#endif
}

View file

@ -30,21 +30,9 @@ namespace ams::fssrv::impl {
class StorageInterfaceAdapter {
NON_COPYABLE(StorageInterfaceAdapter);
private:
/* TODO: Nintendo uses fssystem::AsynchronousAccessStorage here. */
std::shared_ptr<fs::IStorage> m_base_storage;
util::unique_lock<fssystem::SemaphoreAdapter> m_open_count_semaphore;
os::ReaderWriterLock m_invalidation_lock;
/* TODO: DataStorageContext. */
bool m_deep_retry_enabled = false;
public:
StorageInterfaceAdapter(fs::IStorage *storage);
StorageInterfaceAdapter(std::unique_ptr<fs::IStorage> storage);
explicit StorageInterfaceAdapter(std::shared_ptr<fs::IStorage> storage);
/* TODO: Other constructors. */
~StorageInterfaceAdapter();
private:
util::optional<std::shared_lock<os::ReaderWriterLock>> AcquireCacheInvalidationReadLock();
explicit StorageInterfaceAdapter(std::shared_ptr<fs::IStorage> &&storage) : m_base_storage(std::move(storage)) { /* ... */ }
public:
/* Command API. */
Result Read(s64 offset, const ams::sf::OutNonSecureBuffer &buffer, s64 size);
@ -56,4 +44,43 @@ namespace ams::fssrv::impl {
};
static_assert(fssrv::sf::IsIStorage<StorageInterfaceAdapter>);
#if defined(ATMOSPHERE_OS_HORIZON)
class RemoteStorage {
NON_COPYABLE(RemoteStorage);
NON_MOVEABLE(RemoteStorage);
private:
::FsStorage m_base_storage;
public:
RemoteStorage(::FsStorage &s) : m_base_storage(s) { /* ... */}
virtual ~RemoteStorage() { fsStorageClose(std::addressof(m_base_storage)); }
public:
Result Read(s64 offset, const ams::sf::OutNonSecureBuffer &buffer, s64 size) {
return fsStorageRead(std::addressof(m_base_storage), offset, buffer.GetPointer(), size);
}
Result Write(s64 offset, const ams::sf::InNonSecureBuffer &buffer, s64 size) {
return fsStorageWrite(std::addressof(m_base_storage), offset, buffer.GetPointer(), size);
}
Result Flush(){
return fsStorageFlush(std::addressof(m_base_storage));
}
Result SetSize(s64 size) {
return fsStorageSetSize(std::addressof(m_base_storage), size);
}
Result GetSize(ams::sf::Out<s64> out) {
return fsStorageGetSize(std::addressof(m_base_storage), out.GetPointer());
}
Result OperateRange(ams::sf::Out<fs::StorageQueryRangeInfo> out, s32 op_id, s64 offset, s64 size) {
static_assert(sizeof(::FsRangeInfo) == sizeof(fs::StorageQueryRangeInfo));
return fsStorageOperateRange(std::addressof(m_base_storage), static_cast<::FsOperationId>(op_id), offset, size, reinterpret_cast<::FsRangeInfo *>(out.GetPointer()));
}
};
static_assert(fssrv::sf::IsIStorage<RemoteStorage>);
#endif
}