ams: support building unit test programs on windows/linux/macos
This commit is contained in:
@@ -24,7 +24,7 @@ namespace ams::fs::impl {
|
||||
|
||||
template<typename List, typename Iter>
|
||||
void Remove(List &list, Iter *desired) {
|
||||
for (auto it = list.cbegin(); it != list.cend(); it++) {
|
||||
for (auto it = list.cbegin(); it != list.cend(); ++it) {
|
||||
if (it.operator->() == desired) {
|
||||
list.erase(it);
|
||||
return;
|
||||
@@ -35,18 +35,13 @@ namespace ams::fs::impl {
|
||||
AMS_ABORT();
|
||||
}
|
||||
|
||||
Result ValidatePath(const char *mount_name, const char *path) {
|
||||
const size_t mount_name_len = strnlen(mount_name, MountNameLengthMax);
|
||||
const size_t path_len = strnlen(path, EntryNameLengthMax);
|
||||
R_UNLESS(mount_name_len + 1 + path_len <= EntryNameLengthMax, fs::ResultTooLongPath());
|
||||
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result ValidateMountName(const char *name) {
|
||||
Result SetMountName(char *dst, const char *name) {
|
||||
R_UNLESS(name[0] != 0, fs::ResultInvalidMountName());
|
||||
R_UNLESS(strnlen(name, sizeof(MountName)) < sizeof(MountName), fs::ResultInvalidMountName());
|
||||
return ResultSuccess();
|
||||
|
||||
const size_t n_len = util::Strlcpy<char>(dst, name, MountNameLengthMax + 1);
|
||||
R_UNLESS(n_len <= MountNameLengthMax, fs::ResultInvalidMountName());
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
template<typename List>
|
||||
@@ -54,18 +49,21 @@ namespace ams::fs::impl {
|
||||
for (auto it = list.cbegin(); it != list.cend(); it++) {
|
||||
R_UNLESS((it->GetOpenMode() & OpenMode_Write) == 0, fs::ResultWriteModeFileNotClosed());
|
||||
}
|
||||
return ResultSuccess();
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
FileSystemAccessor::FileSystemAccessor(const char *n, std::unique_ptr<fsa::IFileSystem> &&fs, std::unique_ptr<fsa::ICommonMountNameGenerator> &&generator)
|
||||
: m_impl(std::move(fs)), m_open_list_lock(), m_mount_name_generator(std::move(generator)),
|
||||
m_access_log_enabled(false), m_data_cache_attachable(false), m_path_cache_attachable(false), m_path_cache_attached(false), m_multi_commit_supported(false)
|
||||
m_access_log_enabled(false), m_data_cache_attachable(false), m_path_cache_attachable(false), m_path_cache_attached(false), m_multi_commit_supported(false),
|
||||
m_path_flags()
|
||||
{
|
||||
R_ABORT_UNLESS(ValidateMountName(n));
|
||||
std::strncpy(m_name.str, n, MountNameLengthMax);
|
||||
m_name.str[MountNameLengthMax] = 0;
|
||||
R_ABORT_UNLESS(SetMountName(m_name.str, n));
|
||||
|
||||
if (std::strcmp(m_name.str, AMS_FS_IMPL_HOST_ROOT_FILE_SYSTEM_MOUNT_NAME) == 0) {
|
||||
m_path_flags.AllowWindowsPath();
|
||||
}
|
||||
}
|
||||
|
||||
FileSystemAccessor::~FileSystemAccessor() {
|
||||
@@ -83,13 +81,12 @@ namespace ams::fs::impl {
|
||||
|
||||
Result FileSystemAccessor::GetCommonMountName(char *dst, size_t dst_size) const {
|
||||
R_UNLESS(m_mount_name_generator != nullptr, fs::ResultPreconditionViolation());
|
||||
return m_mount_name_generator->GenerateCommonMountName(dst, dst_size);
|
||||
R_RETURN(m_mount_name_generator->GenerateCommonMountName(dst, dst_size));
|
||||
}
|
||||
|
||||
std::shared_ptr<fssrv::impl::FileSystemInterfaceAdapter> FileSystemAccessor::GetMultiCommitTarget() {
|
||||
if (m_multi_commit_supported) {
|
||||
/* TODO: Support multi commit. */
|
||||
AMS_ABORT();
|
||||
AMS_ABORT("TODO: Support multi commit");
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
@@ -104,71 +101,126 @@ namespace ams::fs::impl {
|
||||
Remove(m_open_dir_list, d);
|
||||
}
|
||||
|
||||
Result FileSystemAccessor::SetUpPath(fs::Path *out, const char *p) {
|
||||
/* Initialize the path appropriately. */
|
||||
bool normalized;
|
||||
size_t len;
|
||||
if (R_SUCCEEDED(PathFormatter::IsNormalized(std::addressof(normalized), std::addressof(len), p, m_path_flags)) && normalized) {
|
||||
/* We can use the input buffer directly. */
|
||||
out->SetShallowBuffer(p);
|
||||
} else {
|
||||
/* Initialize with appropriate slash replacement. */
|
||||
if (m_path_flags.IsWindowsPathAllowed()) {
|
||||
R_TRY(out->InitializeWithReplaceForwardSlashes(p));
|
||||
} else {
|
||||
R_TRY(out->InitializeWithReplaceBackslash(p));
|
||||
}
|
||||
|
||||
/* Ensure we're normalized. */
|
||||
R_TRY(out->Normalize(m_path_flags));
|
||||
}
|
||||
|
||||
/* Check the path isn't too long. */
|
||||
R_UNLESS(out->GetLength() <= fs::EntryNameLengthMax, fs::ResultTooLongPath());
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result FileSystemAccessor::CreateFile(const char *path, s64 size, int option) {
|
||||
R_TRY(ValidatePath(m_name.str, path));
|
||||
/* Create path. */
|
||||
fs::Path normalized_path;
|
||||
R_TRY(this->SetUpPath(std::addressof(normalized_path), path));
|
||||
|
||||
if (m_path_cache_attached) {
|
||||
/* TODO: Path cache */
|
||||
R_TRY(m_impl->CreateFile(path, size, option));
|
||||
R_TRY(m_impl->CreateFile(normalized_path, size, option));
|
||||
} else {
|
||||
R_TRY(m_impl->CreateFile(path, size, option));
|
||||
R_TRY(m_impl->CreateFile(normalized_path, size, option));
|
||||
}
|
||||
return ResultSuccess();
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result FileSystemAccessor::DeleteFile(const char *path) {
|
||||
R_TRY(ValidatePath(m_name.str, path));
|
||||
return m_impl->DeleteFile(path);
|
||||
/* Create path. */
|
||||
fs::Path normalized_path;
|
||||
R_TRY(this->SetUpPath(std::addressof(normalized_path), path));
|
||||
|
||||
R_RETURN(m_impl->DeleteFile(normalized_path));
|
||||
}
|
||||
|
||||
Result FileSystemAccessor::CreateDirectory(const char *path) {
|
||||
R_TRY(ValidatePath(m_name.str, path));
|
||||
return m_impl->CreateDirectory(path);
|
||||
/* Create path. */
|
||||
fs::Path normalized_path;
|
||||
R_TRY(this->SetUpPath(std::addressof(normalized_path), path));
|
||||
|
||||
R_RETURN(m_impl->CreateDirectory(normalized_path));
|
||||
}
|
||||
|
||||
Result FileSystemAccessor::DeleteDirectory(const char *path) {
|
||||
R_TRY(ValidatePath(m_name.str, path));
|
||||
return m_impl->DeleteDirectory(path);
|
||||
/* Create path. */
|
||||
fs::Path normalized_path;
|
||||
R_TRY(this->SetUpPath(std::addressof(normalized_path), path));
|
||||
|
||||
R_RETURN(m_impl->DeleteDirectory(normalized_path));
|
||||
}
|
||||
|
||||
Result FileSystemAccessor::DeleteDirectoryRecursively(const char *path) {
|
||||
R_TRY(ValidatePath(m_name.str, path));
|
||||
return m_impl->DeleteDirectoryRecursively(path);
|
||||
/* Create path. */
|
||||
fs::Path normalized_path;
|
||||
R_TRY(this->SetUpPath(std::addressof(normalized_path), path));
|
||||
|
||||
R_RETURN(m_impl->DeleteDirectoryRecursively(normalized_path));
|
||||
}
|
||||
|
||||
Result FileSystemAccessor::RenameFile(const char *old_path, const char *new_path) {
|
||||
R_TRY(ValidatePath(m_name.str, old_path));
|
||||
R_TRY(ValidatePath(m_name.str, new_path));
|
||||
/* Create path. */
|
||||
fs::Path normalized_old_path;
|
||||
fs::Path normalized_new_path;
|
||||
R_TRY(this->SetUpPath(std::addressof(normalized_old_path), old_path));
|
||||
R_TRY(this->SetUpPath(std::addressof(normalized_new_path), new_path));
|
||||
|
||||
if (m_path_cache_attached) {
|
||||
/* TODO: Path cache */
|
||||
R_TRY(m_impl->RenameFile(old_path, new_path));
|
||||
R_TRY(m_impl->RenameFile(normalized_old_path, normalized_new_path));
|
||||
} else {
|
||||
R_TRY(m_impl->RenameFile(old_path, new_path));
|
||||
R_TRY(m_impl->RenameFile(normalized_old_path, normalized_new_path));
|
||||
}
|
||||
return ResultSuccess();
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result FileSystemAccessor::RenameDirectory(const char *old_path, const char *new_path) {
|
||||
R_TRY(ValidatePath(m_name.str, old_path));
|
||||
R_TRY(ValidatePath(m_name.str, new_path));
|
||||
/* Create path. */
|
||||
fs::Path normalized_old_path;
|
||||
fs::Path normalized_new_path;
|
||||
R_TRY(this->SetUpPath(std::addressof(normalized_old_path), old_path));
|
||||
R_TRY(this->SetUpPath(std::addressof(normalized_new_path), new_path));
|
||||
|
||||
if (m_path_cache_attached) {
|
||||
/* TODO: Path cache */
|
||||
R_TRY(m_impl->RenameDirectory(old_path, new_path));
|
||||
R_TRY(m_impl->RenameDirectory(normalized_old_path, normalized_new_path));
|
||||
} else {
|
||||
R_TRY(m_impl->RenameDirectory(old_path, new_path));
|
||||
R_TRY(m_impl->RenameDirectory(normalized_old_path, normalized_new_path));
|
||||
}
|
||||
return ResultSuccess();
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result FileSystemAccessor::GetEntryType(DirectoryEntryType *out, const char *path) {
|
||||
R_TRY(ValidatePath(m_name.str, path));
|
||||
return m_impl->GetEntryType(out, path);
|
||||
/* Create path. */
|
||||
fs::Path normalized_path;
|
||||
R_TRY(this->SetUpPath(std::addressof(normalized_path), path));
|
||||
|
||||
R_RETURN(m_impl->GetEntryType(out, normalized_path));
|
||||
}
|
||||
|
||||
Result FileSystemAccessor::OpenFile(std::unique_ptr<FileAccessor> *out_file, const char *path, OpenMode mode) {
|
||||
R_TRY(ValidatePath(m_name.str, path));
|
||||
/* Create path. */
|
||||
fs::Path normalized_path;
|
||||
R_TRY(this->SetUpPath(std::addressof(normalized_path), path));
|
||||
|
||||
std::unique_ptr<fsa::IFile> file;
|
||||
R_TRY(m_impl->OpenFile(std::addressof(file), path, mode));
|
||||
R_TRY(m_impl->OpenFile(std::addressof(file), normalized_path, mode));
|
||||
|
||||
auto accessor = new FileAccessor(std::move(file), this, mode);
|
||||
R_UNLESS(accessor != nullptr, fs::ResultAllocationFailureInFileSystemAccessorA());
|
||||
@@ -187,14 +239,16 @@ namespace ams::fs::impl {
|
||||
}
|
||||
|
||||
out_file->reset(accessor);
|
||||
return ResultSuccess();
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result FileSystemAccessor::OpenDirectory(std::unique_ptr<DirectoryAccessor> *out_dir, const char *path, OpenDirectoryMode mode) {
|
||||
R_TRY(ValidatePath(m_name.str, path));
|
||||
/* Create path. */
|
||||
fs::Path normalized_path;
|
||||
R_TRY(this->SetUpPath(std::addressof(normalized_path), path));
|
||||
|
||||
std::unique_ptr<fsa::IDirectory> dir;
|
||||
R_TRY(m_impl->OpenDirectory(std::addressof(dir), path, mode));
|
||||
R_TRY(m_impl->OpenDirectory(std::addressof(dir), normalized_path, mode));
|
||||
|
||||
auto accessor = new DirectoryAccessor(std::move(dir), *this);
|
||||
R_UNLESS(accessor != nullptr, fs::ResultAllocationFailureInFileSystemAccessorB());
|
||||
@@ -205,7 +259,7 @@ namespace ams::fs::impl {
|
||||
}
|
||||
|
||||
out_dir->reset(accessor);
|
||||
return ResultSuccess();
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result FileSystemAccessor::Commit() {
|
||||
@@ -213,30 +267,47 @@ namespace ams::fs::impl {
|
||||
std::scoped_lock lk(m_open_list_lock);
|
||||
R_ABORT_UNLESS(ValidateNoOpenWriteModeFiles(m_open_file_list));
|
||||
}
|
||||
return m_impl->Commit();
|
||||
R_RETURN(m_impl->Commit());
|
||||
}
|
||||
|
||||
Result FileSystemAccessor::GetFreeSpaceSize(s64 *out, const char *path) {
|
||||
R_TRY(ValidatePath(m_name.str, path));
|
||||
return m_impl->GetFreeSpaceSize(out, path);
|
||||
/* Create path. */
|
||||
fs::Path normalized_path;
|
||||
R_TRY(this->SetUpPath(std::addressof(normalized_path), path));
|
||||
|
||||
R_RETURN(m_impl->GetFreeSpaceSize(out, normalized_path));
|
||||
}
|
||||
|
||||
Result FileSystemAccessor::GetTotalSpaceSize(s64 *out, const char *path) {
|
||||
R_TRY(ValidatePath(m_name.str, path));
|
||||
return m_impl->GetTotalSpaceSize(out, path);
|
||||
/* Create path. */
|
||||
fs::Path normalized_path;
|
||||
R_TRY(this->SetUpPath(std::addressof(normalized_path), path));
|
||||
|
||||
R_RETURN(m_impl->GetTotalSpaceSize(out, normalized_path));
|
||||
}
|
||||
|
||||
Result FileSystemAccessor::CleanDirectoryRecursively(const char *path) {
|
||||
R_TRY(ValidatePath(m_name.str, path));
|
||||
return m_impl->CleanDirectoryRecursively(path);
|
||||
/* Create path. */
|
||||
fs::Path normalized_path;
|
||||
R_TRY(this->SetUpPath(std::addressof(normalized_path), path));
|
||||
|
||||
R_RETURN(m_impl->CleanDirectoryRecursively(normalized_path));
|
||||
}
|
||||
|
||||
Result FileSystemAccessor::GetFileTimeStampRaw(FileTimeStampRaw *out, const char *path) {
|
||||
return m_impl->GetFileTimeStampRaw(out, path);
|
||||
/* Create path. */
|
||||
fs::Path normalized_path;
|
||||
R_TRY(this->SetUpPath(std::addressof(normalized_path), path));
|
||||
|
||||
R_RETURN(m_impl->GetFileTimeStampRaw(out, normalized_path));
|
||||
}
|
||||
|
||||
Result FileSystemAccessor::QueryEntry(char *dst, size_t dst_size, const char *src, size_t src_size, fsa::QueryId query, const char *path) {
|
||||
return m_impl->QueryEntry(dst, dst_size, src, src_size, query, path);
|
||||
/* Create path. */
|
||||
fs::Path normalized_path;
|
||||
R_TRY(this->SetUpPath(std::addressof(normalized_path), path));
|
||||
|
||||
R_RETURN(m_impl->QueryEntry(dst, dst_size, src, src_size, query, normalized_path));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -42,6 +42,7 @@ namespace ams::fs::impl {
|
||||
bool m_path_cache_attachable;
|
||||
bool m_path_cache_attached;
|
||||
bool m_multi_commit_supported;
|
||||
PathFlags m_path_flags;
|
||||
public:
|
||||
FileSystemAccessor(const char *name, std::unique_ptr<fsa::IFileSystem> &&fs, std::unique_ptr<fsa::ICommonMountNameGenerator> &&generator = nullptr);
|
||||
virtual ~FileSystemAccessor();
|
||||
@@ -93,6 +94,8 @@ namespace ams::fs::impl {
|
||||
private:
|
||||
void NotifyCloseFile(FileAccessor *f);
|
||||
void NotifyCloseDirectory(DirectoryAccessor *d);
|
||||
public:
|
||||
Result SetUpPath(fs::Path *out, const char *p);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -23,22 +23,32 @@ namespace ams::fs::impl {
|
||||
namespace {
|
||||
|
||||
const char *FindMountNameDriveSeparator(const char *path) {
|
||||
for (const char *cur = path; cur < path + MountNameLengthMax + 1; cur++) {
|
||||
for (const char *cur = path; cur < path + MountNameLengthMax + 1 && *cur != StringTraits::NullTerminator; ++cur) {
|
||||
if (*cur == StringTraits::DriveSeparator) {
|
||||
return cur;
|
||||
} else if (PathNormalizer::IsNullTerminator(*cur)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
constexpr bool IsHostRootPath(const char *path) {
|
||||
#if defined(ATMOSPHERE_OS_HORIZON) || defined(ATMOSPHERE_OS_WINDOWS)
|
||||
return fs::IsWindowsDrive(path) || fs::IsUncPath(path);
|
||||
#elif defined(ATMOSPHERE_OS_LINUX) || defined(ATMOSPHERE_OS_MACOS)
|
||||
return fs::IsPathAbsolute(path);
|
||||
#else
|
||||
#error "Unknown OS for host path identification"
|
||||
#endif
|
||||
}
|
||||
|
||||
Result GetMountNameAndSubPath(MountName *out_mount_name, const char **out_sub_path, const char *path) {
|
||||
/* Handle the Host-path case. */
|
||||
if (fs::IsWindowsDrive(path) || fs::IsUnc(path)) {
|
||||
if (IsHostRootPath(path)) {
|
||||
std::strncpy(out_mount_name->str, HostRootFileSystemMountName, MountNameLengthMax);
|
||||
out_mount_name->str[MountNameLengthMax] = '\x00';
|
||||
return ResultSuccess();
|
||||
|
||||
*out_sub_path = path;
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
/* Locate the drive separator. */
|
||||
@@ -47,34 +57,37 @@ namespace ams::fs::impl {
|
||||
|
||||
/* Ensure the mount name isn't too long. */
|
||||
const size_t len = drive_separator - path;
|
||||
R_UNLESS(0 < len, fs::ResultInvalidMountName());
|
||||
R_UNLESS(len <= MountNameLengthMax, fs::ResultInvalidMountName());
|
||||
|
||||
/* Ensure the result sub-path is valid. */
|
||||
const char *sub_path = drive_separator + 1;
|
||||
R_UNLESS(!PathNormalizer::IsNullTerminator(sub_path[0]), fs::ResultInvalidMountName());
|
||||
R_UNLESS(PathNormalizer::IsAnySeparator(sub_path[0]), fs::ResultInvalidPathFormat());
|
||||
|
||||
const auto starts_with_dir = (sub_path[0] == StringTraits::DirectorySeparator) || (sub_path[0] == StringTraits::AlternateDirectorySeparator);
|
||||
R_UNLESS(starts_with_dir, fs::ResultInvalidPathFormat());
|
||||
|
||||
/* Set output. */
|
||||
std::memcpy(out_mount_name->str, path, len);
|
||||
out_mount_name->str[len] = StringTraits::NullTerminator;
|
||||
|
||||
*out_sub_path = sub_path;
|
||||
return ResultSuccess();
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool IsValidMountName(const char *name) {
|
||||
if (PathNormalizer::IsNullTerminator(name[0])) {
|
||||
if (name[0] == StringTraits::NullTerminator) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((('a' <= name[0] && name[0] <= 'z') || ('A' <= name[0] && name[0] <= 'Z')) && PathNormalizer::IsNullTerminator(name[1])) {
|
||||
if ((('a' <= name[0] && name[0] <= 'z') || ('A' <= name[0] && name[0] <= 'Z')) && name[1] == StringTraits::NullTerminator) {
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t len = 0;
|
||||
for (const char *cur = name; !PathNormalizer::IsNullTerminator(*cur); cur++) {
|
||||
if (*cur == StringTraits::DriveSeparator || PathNormalizer::IsSeparator(*cur)) {
|
||||
for (const char *cur = name; *cur != StringTraits::NullTerminator; ++cur) {
|
||||
if (*cur == StringTraits::DriveSeparator || *cur == StringTraits::DirectorySeparator) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -83,8 +96,7 @@ namespace ams::fs::impl {
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO: N validates that the mount name decodes via utf-8 here. */
|
||||
return true;
|
||||
return util::VerifyUtf8String(name, len);
|
||||
}
|
||||
|
||||
bool IsReservedMountName(const char *name) {
|
||||
@@ -108,7 +120,7 @@ namespace ams::fs::impl {
|
||||
R_UNLESS(out_sub_path != nullptr, fs::ResultUnexpectedInFindFileSystemA());
|
||||
R_UNLESS(path != nullptr, fs::ResultNullptrArgument());
|
||||
|
||||
R_UNLESS(strncmp(path, HostRootFileSystemMountName, strnlen(HostRootFileSystemMountName, sizeof(MountName))) != 0, fs::ResultNotMounted());
|
||||
R_UNLESS(strncmp(path, HostRootFileSystemMountName, util::Strnlen(HostRootFileSystemMountName, sizeof(MountName))) != 0, fs::ResultNotMounted());
|
||||
|
||||
MountName mount_name;
|
||||
R_TRY(GetMountNameAndSubPath(std::addressof(mount_name), out_sub_path, path));
|
||||
@@ -132,10 +144,6 @@ namespace ams::fs::impl {
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
namespace {
|
||||
|
||||
}
|
||||
|
||||
Result ConvertToFsCommonPath(char *dst, size_t dst_size, const char *src) {
|
||||
/* Ensure neither argument is nullptr. */
|
||||
AMS_FS_R_UNLESS(dst != nullptr, fs::ResultNullptrArgument());
|
||||
@@ -150,7 +158,7 @@ namespace ams::fs {
|
||||
AMS_FS_R_TRY(impl::Find(std::addressof(accessor), mount_name.str));
|
||||
AMS_FS_R_TRY(accessor->GetCommonMountName(dst, dst_size));
|
||||
|
||||
const auto mount_name_len = strnlen(dst, dst_size);
|
||||
const auto mount_name_len = util::Strnlen(dst, dst_size);
|
||||
const auto common_path_len = util::SNPrintf(dst + mount_name_len, dst_size - mount_name_len, "%s", sub_path);
|
||||
|
||||
AMS_FS_R_UNLESS(static_cast<size_t>(common_path_len) < dst_size - mount_name_len, fs::ResultTooLongPath());
|
||||
|
||||
@@ -164,62 +164,27 @@ namespace ams::fs {
|
||||
}
|
||||
|
||||
Result GetFreeSpaceSize(s64 *out, const char *path) {
|
||||
/* Find the filesystem without access logging. */
|
||||
impl::FileSystemAccessor *accessor;
|
||||
const char *sub_path = nullptr;
|
||||
const char *sub_path;
|
||||
AMS_FS_R_TRY(impl::FindFileSystem(std::addressof(accessor), std::addressof(sub_path), path));
|
||||
|
||||
/* Get the accessor. */
|
||||
auto find_impl = [&]() -> Result {
|
||||
R_UNLESS(out != nullptr, fs::ResultNullptrArgument());
|
||||
R_UNLESS(path != nullptr, fs::ResultNullptrArgument());
|
||||
if (impl::IsValidMountName(path)) {
|
||||
R_TRY(impl::Find(std::addressof(accessor), path));
|
||||
} else {
|
||||
R_TRY(impl::FindFileSystem(std::addressof(accessor), std::addressof(sub_path), path));
|
||||
}
|
||||
return ResultSuccess();
|
||||
};
|
||||
/* Get the total space size. */
|
||||
AMS_FS_R_TRY(accessor->GetFreeSpaceSize(out, sub_path));
|
||||
|
||||
AMS_FS_R_TRY(AMS_FS_IMPL_ACCESS_LOG_UNLESS_R_SUCCEEDED(find_impl(), AMS_FS_IMPL_ACCESS_LOG_FORMAT_GET_SPACE_SIZE(out, path)));
|
||||
|
||||
/* Get the space size. */
|
||||
auto get_size_impl = [&]() -> Result {
|
||||
R_UNLESS(sub_path == nullptr || std::strcmp(sub_path, "/") == 0, fs::ResultInvalidMountName());
|
||||
R_TRY(accessor->GetFreeSpaceSize(out, "/"));
|
||||
return ResultSuccess();
|
||||
};
|
||||
|
||||
AMS_FS_R_TRY(AMS_FS_IMPL_ACCESS_LOG_FILESYSTEM(get_size_impl(), nullptr, accessor, AMS_FS_IMPL_ACCESS_LOG_FORMAT_GET_SPACE_SIZE(out, path)));
|
||||
return ResultSuccess();
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result GetTotalSpaceSize(s64 *out, const char *path) {
|
||||
/* NOTE: Nintendo does not do access logging here, and does not support mount-name instead of path. */
|
||||
/* Find the filesystem without access logging. */
|
||||
impl::FileSystemAccessor *accessor;
|
||||
const char *sub_path = nullptr;
|
||||
const char *sub_path;
|
||||
AMS_FS_R_TRY(impl::FindFileSystem(std::addressof(accessor), std::addressof(sub_path), path));
|
||||
|
||||
/* Get the accessor. */
|
||||
auto find_impl = [&]() -> Result {
|
||||
R_UNLESS(out != nullptr, fs::ResultNullptrArgument());
|
||||
R_UNLESS(path != nullptr, fs::ResultNullptrArgument());
|
||||
if (impl::IsValidMountName(path)) {
|
||||
R_TRY(impl::Find(std::addressof(accessor), path));
|
||||
} else {
|
||||
R_TRY(impl::FindFileSystem(std::addressof(accessor), std::addressof(sub_path), path));
|
||||
}
|
||||
return ResultSuccess();
|
||||
};
|
||||
/* Get the total space size. */
|
||||
AMS_FS_R_TRY(accessor->GetTotalSpaceSize(out, sub_path));
|
||||
|
||||
AMS_FS_R_TRY(AMS_FS_IMPL_ACCESS_LOG_UNLESS_R_SUCCEEDED(find_impl(), AMS_FS_IMPL_ACCESS_LOG_FORMAT_GET_SPACE_SIZE(out, path)));
|
||||
|
||||
/* Get the space size. */
|
||||
auto get_size_impl = [&]() -> Result {
|
||||
R_UNLESS(sub_path == nullptr || std::strcmp(sub_path, "/") == 0, fs::ResultInvalidMountName());
|
||||
R_TRY(accessor->GetTotalSpaceSize(out, "/"));
|
||||
return ResultSuccess();
|
||||
};
|
||||
|
||||
AMS_FS_R_TRY(AMS_FS_IMPL_ACCESS_LOG_FILESYSTEM(get_size_impl(), nullptr, accessor, AMS_FS_IMPL_ACCESS_LOG_FORMAT_GET_SPACE_SIZE(out, path)));
|
||||
return ResultSuccess();
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result SetConcatenationFileAttribute(const char *path) {
|
||||
@@ -229,7 +194,7 @@ namespace ams::fs {
|
||||
|
||||
AMS_FS_R_TRY(accessor->QueryEntry(nullptr, 0, nullptr, 0, fsa::QueryId::SetConcatenationFileAttribute, sub_path));
|
||||
|
||||
return ResultSuccess();
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result OpenFile(FileHandle *out, std::unique_ptr<fsa::IFile> &&file, int mode) {
|
||||
@@ -239,7 +204,7 @@ namespace ams::fs {
|
||||
AMS_FS_R_UNLESS(file_accessor != nullptr, fs::ResultAllocationFailureInNew());
|
||||
out->handle = file_accessor.release();
|
||||
|
||||
return ResultSuccess();
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
namespace {
|
||||
@@ -249,7 +214,7 @@ namespace ams::fs {
|
||||
AMS_FS_R_TRY(AMS_FS_IMPL_ACCESS_LOG_UNLESS_R_SUCCEEDED(impl::Find(std::addressof(accessor), mount_name), AMS_FS_IMPL_ACCESS_LOG_FORMAT_MOUNT, mount_name));
|
||||
|
||||
AMS_FS_R_TRY(AMS_FS_IMPL_ACCESS_LOG_FILESYSTEM_WITH_NAME(accessor->Commit(), nullptr, accessor, func_name, AMS_FS_IMPL_ACCESS_LOG_FORMAT_MOUNT, mount_name));
|
||||
return ResultSuccess();
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -36,9 +36,13 @@ namespace ams::fs {
|
||||
|
||||
}
|
||||
|
||||
Result GetFileTimeStampRawForDebug(FileTimeStampRaw *out, const char *path) {
|
||||
AMS_FS_R_TRY(impl::GetFileTimeStampRawForDebug(out, path));
|
||||
return ResultSuccess();
|
||||
Result GetFileTimeStamp(FileTimeStamp *out, const char *path) {
|
||||
fs::FileTimeStampRaw raw;
|
||||
AMS_FS_R_TRY(impl::GetFileTimeStampRawForDebug(std::addressof(raw), path));
|
||||
|
||||
static_assert(sizeof(raw) == sizeof(*out));
|
||||
std::memcpy(out, std::addressof(raw), sizeof(raw));
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user