diff options
Diffstat (limited to 'src/core/file_sys')
-rw-r--r-- | src/core/file_sys/fs_directory.h | 2 | ||||
-rw-r--r-- | src/core/file_sys/fs_file.h | 14 | ||||
-rw-r--r-- | src/core/file_sys/fs_filesystem.h | 6 | ||||
-rw-r--r-- | src/core/file_sys/fs_memory_management.h | 20 | ||||
-rw-r--r-- | src/core/file_sys/fs_operate_range.h | 4 | ||||
-rw-r--r-- | src/core/file_sys/fs_path.h | 150 | ||||
-rw-r--r-- | src/core/file_sys/fs_path_utility.h | 249 | ||||
-rw-r--r-- | src/core/file_sys/fs_string_util.h | 29 |
8 files changed, 225 insertions, 249 deletions
diff --git a/src/core/file_sys/fs_directory.h b/src/core/file_sys/fs_directory.h index cba6155f8..25c9cb18a 100644 --- a/src/core/file_sys/fs_directory.h +++ b/src/core/file_sys/fs_directory.h @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #pragma once diff --git a/src/core/file_sys/fs_file.h b/src/core/file_sys/fs_file.h index 35f66b959..4fb77e8db 100644 --- a/src/core/file_sys/fs_file.h +++ b/src/core/file_sys/fs_file.h @@ -1,12 +1,14 @@ -// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #pragma once +#include "common/common_types.h" + namespace FileSys { struct ReadOption { - u32 _value; + u32 value; static const ReadOption None; }; @@ -18,7 +20,7 @@ enum ReadOptionFlag : u32 { inline constexpr const ReadOption ReadOption::None = {ReadOptionFlag_None}; inline constexpr bool operator==(const ReadOption& lhs, const ReadOption& rhs) { - return lhs._value == rhs._value; + return lhs.value == rhs.value; } inline constexpr bool operator!=(const ReadOption& lhs, const ReadOption& rhs) { @@ -33,10 +35,10 @@ enum WriteOptionFlag : u32 { }; struct WriteOption { - u32 _value; + u32 value; constexpr inline bool HasFlushFlag() const { - return _value & WriteOptionFlag_Flush; + return value & WriteOptionFlag_Flush; } static const WriteOption None; @@ -47,7 +49,7 @@ inline constexpr const WriteOption WriteOption::None = {WriteOptionFlag_None}; inline constexpr const WriteOption WriteOption::Flush = {WriteOptionFlag_Flush}; inline constexpr bool operator==(const WriteOption& lhs, const WriteOption& rhs) { - return lhs._value == rhs._value; + return lhs.value == rhs.value; } inline constexpr bool operator!=(const WriteOption& lhs, const WriteOption& rhs) { diff --git a/src/core/file_sys/fs_filesystem.h b/src/core/file_sys/fs_filesystem.h index 436d6c731..7f237b7fa 100644 --- a/src/core/file_sys/fs_filesystem.h +++ b/src/core/file_sys/fs_filesystem.h @@ -3,6 +3,9 @@ #pragma once +#include "common/common_funcs.h" +#include "common/common_types.h" + namespace FileSys { enum class OpenMode : u32 { @@ -20,9 +23,6 @@ enum class OpenDirectoryMode : u64 { File = (1 << 1), All = (Directory | File), - - /* TODO: Separate enum, like N? */ - _NotRequireFileSize = (1 << 31), }; DECLARE_ENUM_FLAG_OPERATORS(OpenDirectoryMode) diff --git a/src/core/file_sys/fs_memory_management.h b/src/core/file_sys/fs_memory_management.h index 596143ba9..f03c6354b 100644 --- a/src/core/file_sys/fs_memory_management.h +++ b/src/core/file_sys/fs_memory_management.h @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #pragma once @@ -8,39 +8,31 @@ namespace FileSys { -std::mutex g_mutex; - constexpr size_t RequiredAlignment = alignof(u64); void* AllocateUnsafe(size_t size) { - /* Allocate. */ + // Allocate void* const ptr = ::operator new(size, std::align_val_t{RequiredAlignment}); - /* Check alignment. */ + // Check alignment ASSERT(Common::IsAligned(reinterpret_cast<uintptr_t>(ptr), RequiredAlignment)); - /* Return allocated pointer. */ + // Return allocated pointer return ptr; } void DeallocateUnsafe(void* ptr, size_t size) { - /* Deallocate the pointer. */ + // Deallocate the pointer ::operator delete(ptr, std::align_val_t{RequiredAlignment}); } void* Allocate(size_t size) { - /* Lock the allocator. */ - std::scoped_lock lk(g_mutex); - return AllocateUnsafe(size); } void Deallocate(void* ptr, size_t size) { - /* If the pointer is non-null, deallocate it. */ + // If the pointer is non-null, deallocate it if (ptr != nullptr) { - /* Lock the allocator. */ - std::scoped_lock lk(g_mutex); - DeallocateUnsafe(ptr, size); } } diff --git a/src/core/file_sys/fs_operate_range.h b/src/core/file_sys/fs_operate_range.h index 750999907..04ea64cc0 100644 --- a/src/core/file_sys/fs_operate_range.h +++ b/src/core/file_sys/fs_operate_range.h @@ -1,8 +1,10 @@ -// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #pragma once +#include "common/common_types.h" + namespace FileSys { enum class OperationId : s64 { diff --git a/src/core/file_sys/fs_path.h b/src/core/file_sys/fs_path.h index 9ea452644..56ba08a6a 100644 --- a/src/core/file_sys/fs_path.h +++ b/src/core/file_sys/fs_path.h @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #pragma once @@ -34,8 +34,7 @@ public: size_t m_length_and_is_normalized; public: - constexpr WriteBuffer() : m_buffer(nullptr), m_length_and_is_normalized(0) { /* ... */ - } + constexpr WriteBuffer() : m_buffer(nullptr), m_length_and_is_normalized(0) {} constexpr ~WriteBuffer() { if (m_buffer != nullptr) { @@ -113,35 +112,32 @@ private: WriteBuffer m_write_buffer; public: - constexpr Path() : m_str(EmptyPath), m_write_buffer() { - /* ... */ - } + constexpr Path() : m_str(EmptyPath), m_write_buffer() {} constexpr Path(const char* s) : m_str(s), m_write_buffer() { m_write_buffer.SetNormalized(); } - constexpr ~Path() { /* ... */ - } + constexpr ~Path() = default; constexpr Result SetShallowBuffer(const char* buffer) { - /* Check pre-conditions. */ + // Check pre-conditions ASSERT(m_write_buffer.GetLength() == 0); - /* Check the buffer is valid. */ + // Check the buffer is valid R_UNLESS(buffer != nullptr, ResultNullptrArgument); - /* Set buffer. */ + // Set buffer this->SetReadOnlyBuffer(buffer); - /* Note that we're normalized. */ + // Note that we're normalized this->SetNormalized(); R_SUCCEED(); } constexpr const char* GetString() const { - /* Check pre-conditions. */ + // Check pre-conditions ASSERT(this->IsNormalized()); return m_str; @@ -164,69 +160,69 @@ public: } Result Initialize(const Path& rhs) { - /* Check the other path is normalized. */ + // Check the other path is normalized const bool normalized = rhs.IsNormalized(); R_UNLESS(normalized, ResultNotNormalized); - /* Allocate buffer for our path. */ + // Allocate buffer for our path const auto len = rhs.GetLength(); R_TRY(this->Preallocate(len + 1)); - /* Copy the path. */ + // Copy the path const size_t copied = Strlcpy<char>(m_write_buffer.Get(), rhs.GetString(), len + 1); R_UNLESS(copied == len, ResultUnexpectedInPathA); - /* Set normalized. */ + // Set normalized this->SetNormalized(); R_SUCCEED(); } Result Initialize(const char* path, size_t len) { - /* Check the path is valid. */ + // Check the path is valid R_UNLESS(path != nullptr, ResultNullptrArgument); - /* Initialize. */ + // Initialize R_TRY(this->InitializeImpl(path, len)); - /* Set not normalized. */ + // Set not normalized this->SetNotNormalized(); R_SUCCEED(); } Result Initialize(const char* path) { - /* Check the path is valid. */ + // Check the path is valid R_UNLESS(path != nullptr, ResultNullptrArgument); R_RETURN(this->Initialize(path, std::strlen(path))); } Result InitializeWithReplaceBackslash(const char* path) { - /* Check the path is valid. */ + // Check the path is valid R_UNLESS(path != nullptr, ResultNullptrArgument); - /* Initialize. */ + // Initialize R_TRY(this->InitializeImpl(path, std::strlen(path))); - /* Replace slashes as desired. */ + // Replace slashes as desired if (const auto write_buffer_length = m_write_buffer.GetLength(); write_buffer_length > 1) { Replace(m_write_buffer.Get(), write_buffer_length - 1, '\\', '/'); } - /* Set not normalized. */ + // Set not normalized this->SetNotNormalized(); R_SUCCEED(); } Result InitializeWithReplaceForwardSlashes(const char* path) { - /* Check the path is valid. */ + // Check the path is valid R_UNLESS(path != nullptr, ResultNullptrArgument); - /* Initialize. */ + // Initialize R_TRY(this->InitializeImpl(path, std::strlen(path))); - /* Replace slashes as desired. */ + // Replace slashes as desired if (m_write_buffer.GetLength() > 1) { if (auto* p = m_write_buffer.Get(); p[0] == '/' && p[1] == '/') { p[0] = '\\'; @@ -234,23 +230,23 @@ public: } } - /* Set not normalized. */ + // Set not normalized this->SetNotNormalized(); R_SUCCEED(); } Result InitializeWithNormalization(const char* path, size_t size) { - /* Check the path is valid. */ + // Check the path is valid R_UNLESS(path != nullptr, ResultNullptrArgument); - /* Initialize. */ + // Initialize R_TRY(this->InitializeImpl(path, size)); - /* Set not normalized. */ + // Set not normalized this->SetNotNormalized(); - /* Perform normalization. */ + // Perform normalization PathFlags path_flags; if (IsPathRelative(m_str)) { path_flags.AllowRelativePath(); @@ -269,7 +265,7 @@ public: R_SUCCEED(); } - /* Normalize. */ + // Normalize R_TRY(this->Normalize(path_flags)); this->SetNormalized(); @@ -277,30 +273,30 @@ public: } Result InitializeWithNormalization(const char* path) { - /* Check the path is valid. */ + // Check the path is valid R_UNLESS(path != nullptr, ResultNullptrArgument); R_RETURN(this->InitializeWithNormalization(path, std::strlen(path))); } Result InitializeAsEmpty() { - /* Clear our buffer. */ + // Clear our buffer this->ClearBuffer(); - /* Set normalized. */ + // Set normalized this->SetNormalized(); R_SUCCEED(); } Result AppendChild(const char* child) { - /* Check the path is valid. */ + // Check the path is valid R_UNLESS(child != nullptr, ResultNullptrArgument); - /* Basic checks. If we hvea a path and the child is empty, we have nothing to do. */ + // Basic checks. If we have a path and the child is empty, we have nothing to do const char* c = child; if (m_str[0]) { - /* Skip an early separator. */ + // Skip an early separator if (*c == '/') { ++c; } @@ -308,40 +304,40 @@ public: R_SUCCEED_IF(*c == '\x00'); } - /* If we don't have a string, we can just initialize. */ + // If we don't have a string, we can just initialize auto cur_len = std::strlen(m_str); if (cur_len == 0) { R_RETURN(this->Initialize(child)); } - /* Remove a trailing separator. */ + // Remove a trailing separator if (m_str[cur_len - 1] == '/' || m_str[cur_len - 1] == '\\') { --cur_len; } - /* Get the child path's length. */ + // Get the child path's length auto child_len = std::strlen(c); - /* Reset our write buffer. */ + // Reset our write buffer WriteBuffer old_write_buffer; if (m_write_buffer.Get() != nullptr) { old_write_buffer = std::move(m_write_buffer); this->ClearBuffer(); } - /* Pre-allocate the new buffer. */ + // Pre-allocate the new buffer R_TRY(this->Preallocate(cur_len + 1 + child_len + 1)); - /* Get our write buffer. */ + // Get our write buffer auto* dst = m_write_buffer.Get(); if (old_write_buffer.Get() != nullptr && cur_len > 0) { Strlcpy<char>(dst, old_write_buffer.Get(), cur_len + 1); } - /* Add separator. */ + // Add separator dst[cur_len] = '/'; - /* Copy the child path. */ + // Copy the child path const size_t copied = Strlcpy<char>(dst + cur_len + 1, c, child_len + 1); R_UNLESS(copied == child_len, ResultUnexpectedInPathA); @@ -353,21 +349,21 @@ public: } Result Combine(const Path& parent, const Path& child) { - /* Get the lengths. */ + // Get the lengths const auto p_len = parent.GetLength(); const auto c_len = child.GetLength(); - /* Allocate our buffer. */ + // Allocate our buffer R_TRY(this->Preallocate(p_len + c_len + 1)); - /* Initialize as parent. */ + // Initialize as parent R_TRY(this->Initialize(parent)); - /* If we're empty, we can just initialize as child. */ + // If we're empty, we can just initialize as child if (this->IsEmpty()) { R_TRY(this->Initialize(child)); } else { - /* Otherwise, we should append the child. */ + // Otherwise, we should append the child R_TRY(this->AppendChild(child)); } @@ -375,7 +371,7 @@ public: } Result RemoveChild() { - /* If we don't have a write-buffer, ensure that we have one. */ + // If we don't have a write-buffer, ensure that we have one if (m_write_buffer.Get() == nullptr) { if (const auto len = std::strlen(m_str); len > 0) { R_TRY(this->Preallocate(len)); @@ -383,17 +379,17 @@ public: } } - /* Check that it's possible for us to remove a child. */ + // Check that it's possible for us to remove a child auto* p = m_write_buffer.Get(); s32 len = std::strlen(p); R_UNLESS(len != 1 || (p[0] != '/' && p[0] != '.'), ResultNotImplemented); - /* Handle a trailing separator. */ + // Handle a trailing separator if (len > 0 && (p[len - 1] == '\\' || p[len - 1] == '/')) { --len; } - /* Remove the child path segment. */ + // Remove the child path segment while ((--len) >= 0 && p[len]) { if (p[len] == '/' || p[len] == '\\') { if (len > 0) { @@ -406,25 +402,25 @@ public: } } - /* Check that length remains > 0. */ + // Check that length remains > 0 R_UNLESS(len > 0, ResultNotImplemented); R_SUCCEED(); } Result Normalize(const PathFlags& flags) { - /* If we're already normalized, nothing to do. */ + // If we're already normalized, nothing to do R_SUCCEED_IF(this->IsNormalized()); - /* Check if we're normalized. */ + // Check if we're normalized bool normalized; size_t dummy; R_TRY(PathFormatter::IsNormalized(std::addressof(normalized), std::addressof(dummy), m_str, flags)); - /* If we're not normalized, normalize. */ + // If we're not normalized, normalize if (!normalized) { - /* Determine necessary buffer length. */ + // Determine necessary buffer length auto len = m_write_buffer.GetLength(); if (flags.IsRelativePathAllowed() && IsPathRelative(m_str)) { len += 2; @@ -433,20 +429,20 @@ public: len += 1; } - /* Allocate a new buffer. */ + // Allocate a new buffer const size_t size = Common::AlignUp(len, WriteBufferAlignmentLength); auto buf = WriteBuffer::Make(size); R_UNLESS(buf.Get() != nullptr, ResultAllocationMemoryFailedMakeUnique); - /* Normalize into it. */ + // Normalize into it R_TRY(PathFormatter::Normalize(buf.Get(), size, m_write_buffer.Get(), m_write_buffer.GetLength(), flags)); - /* Set the normalized buffer as our buffer. */ + // Set the normalized buffer as our buffer this->SetModifiableBuffer(std::move(buf)); } - /* Set normalized. */ + // Set normalized this->SetNormalized(); R_SUCCEED(); } @@ -458,19 +454,19 @@ private: } void SetModifiableBuffer(WriteBuffer&& buffer) { - /* Check pre-conditions. */ + // Check pre-conditions ASSERT(buffer.Get() != nullptr); ASSERT(buffer.GetLength() > 0); ASSERT(Common::IsAligned(buffer.GetLength(), WriteBufferAlignmentLength)); - /* Get whether we're normalized. */ + // Get whether we're normalized if (m_write_buffer.IsNormalized()) { buffer.SetNormalized(); } else { buffer.SetNotNormalized(); } - /* Set write buffer. */ + // Set write buffer m_write_buffer = std::move(buffer); m_str = m_write_buffer.Get(); } @@ -481,14 +477,14 @@ private: } Result Preallocate(size_t length) { - /* Allocate additional space, if needed. */ + // Allocate additional space, if needed if (length > m_write_buffer.GetLength()) { - /* Allocate buffer. */ + // Allocate buffer const size_t size = Common::AlignUp(length, WriteBufferAlignmentLength); auto buf = WriteBuffer::Make(size); R_UNLESS(buf.Get() != nullptr, ResultAllocationMemoryFailedMakeUnique); - /* Set write buffer. */ + // Set write buffer this->SetModifiableBuffer(std::move(buf)); } @@ -497,14 +493,14 @@ private: Result InitializeImpl(const char* path, size_t size) { if (size > 0 && path[0]) { - /* Pre allocate a buffer for the path. */ + // Pre allocate a buffer for the path R_TRY(this->Preallocate(size + 1)); - /* Copy the path. */ + // Copy the path const size_t copied = Strlcpy<char>(m_write_buffer.Get(), path, size + 1); R_UNLESS(copied >= size, ResultUnexpectedInPathA); } else { - /* We can just clear the buffer. */ + // We can just clear the buffer this->ClearBuffer(); } @@ -548,14 +544,14 @@ public: }; inline Result SetUpFixedPath(FileSys::Path* out, const char* s) { - /* Verify the path is normalized. */ + // Verify the path is normalized bool normalized; size_t dummy; R_TRY(PathNormalizer::IsNormalized(std::addressof(normalized), std::addressof(dummy), s)); R_UNLESS(normalized, ResultInvalidPathFormat); - /* Set the fixed path. */ + // Set the fixed path R_RETURN(out->SetShallowBuffer(s)); } diff --git a/src/core/file_sys/fs_path_utility.h b/src/core/file_sys/fs_path_utility.h index 276445707..e9011d065 100644 --- a/src/core/file_sys/fs_path_utility.h +++ b/src/core/file_sys/fs_path_utility.h @@ -1,9 +1,10 @@ -// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #pragma once #include "common/assert.h" +#include "common/common_funcs.h" #include "common/common_types.h" #include "common/scope_exit.h" #include "core/file_sys/fs_directory.h" @@ -14,7 +15,6 @@ namespace FileSys { constexpr inline size_t MountNameLengthMax = 15; -using Result = ::Result; namespace StringTraits { @@ -57,15 +57,15 @@ constexpr bool IsInvalidCharacterImpl(char c) { } // namespace impl constexpr bool IsInvalidCharacter(char c) { - return impl::IsInvalidCharacterImpl<InvalidCharacters, size(InvalidCharacters)>(c); + return impl::IsInvalidCharacterImpl<InvalidCharacters, Common::Size(InvalidCharacters)>(c); } constexpr bool IsInvalidCharacterForHostName(char c) { return impl::IsInvalidCharacterImpl<InvalidCharactersForHostName, - size(InvalidCharactersForHostName)>(c); + Common::Size(InvalidCharactersForHostName)>(c); } constexpr bool IsInvalidCharacterForMountName(char c) { return impl::IsInvalidCharacterImpl<InvalidCharactersForMountName, - size(InvalidCharactersForMountName)>(c); + Common::Size(InvalidCharactersForMountName)>(c); } } // namespace StringTraits @@ -177,14 +177,14 @@ constexpr inline bool IsPathStartWithCurrentDirectory(const char* path) { } constexpr inline bool IsSubPath(const char* lhs, const char* rhs) { - /* Check pre-conditions. */ + // Check pre-conditions ASSERT(lhs != nullptr); ASSERT(rhs != nullptr); - /* Import StringTraits names for current scope. */ + // Import StringTraits names for current scope using namespace StringTraits; - /* Special case certain paths. */ + // Special case certain paths if (IsUncPath(lhs) && !IsUncPath(rhs)) { return false; } @@ -201,7 +201,7 @@ constexpr inline bool IsSubPath(const char* lhs, const char* rhs) { return true; } - /* Check subpath. */ + // Check subpath for (size_t i = 0; /* ... */; ++i) { if (lhs[i] == NullTerminator) { return rhs[i] == DirectorySeparator; @@ -213,7 +213,7 @@ constexpr inline bool IsSubPath(const char* lhs, const char* rhs) { } } -/* Path utilities. */ +// Path utilities constexpr inline void Replace(char* dst, size_t dst_size, char old_char, char new_char) { ASSERT(dst != nullptr); for (char* cur = dst; cur < dst + dst_size && *cur; ++cur) { @@ -224,10 +224,10 @@ constexpr inline void Replace(char* dst, size_t dst_size, char old_char, char ne } constexpr inline Result CheckUtf8(const char* s) { - /* Check pre-conditions. */ + // Check pre-conditions ASSERT(s != nullptr); - /* Iterate, checking for utf8-validity. */ + // Iterate, checking for utf8-validity while (*s) { char utf8_buf[4] = {}; @@ -242,7 +242,7 @@ constexpr inline Result CheckUtf8(const char* s) { R_SUCCEED(); } -/* Path formatting. */ +// Path formatting class PathNormalizer { private: enum class PathState { @@ -256,10 +256,10 @@ private: private: static constexpr void ReplaceParentDirectoryPath(char* dst, const char* src) { - /* Use StringTraits names for remainder of scope. */ + // Use StringTraits names for remainder of scope using namespace StringTraits; - /* Start with a dir-separator. */ + // Start with a dir-separator dst[0] = DirectorySeparator; auto i = 1; @@ -292,14 +292,14 @@ private: public: static constexpr bool IsParentDirectoryPathReplacementNeeded(const char* path) { - /* Use StringTraits names for remainder of scope. */ + // Use StringTraits names for remainder of scope using namespace StringTraits; if (path[0] != DirectorySeparator && path[0] != AlternateDirectorySeparator) { return false; } - /* Check to find a parent reference using alternate separators. */ + // Check to find a parent reference using alternate separators if (path[0] != NullTerminator && path[1] != NullTerminator && path[2] != NullTerminator) { size_t i; for (i = 0; path[i + 3] != NullTerminator; ++path) { @@ -333,24 +333,24 @@ public: static constexpr Result IsNormalized(bool* out, size_t* out_len, const char* path, bool allow_all_characters = false) { - /* Use StringTraits names for remainder of scope. */ + // Use StringTraits names for remainder of scope using namespace StringTraits; - /* Parse the path. */ + // Parse the path auto state = PathState::Start; size_t len = 0; while (path[len] != NullTerminator) { - /* Get the current character. */ + // Get the current character const char c = path[len++]; - /* Check the current character is valid. */ + // Check the current character is valid if (!allow_all_characters && state != PathState::Start) { R_UNLESS(!IsInvalidCharacter(c), ResultInvalidCharacter); } - /* Process depending on current state. */ + // Process depending on current state switch (state) { - /* Import the PathState enums for convenience. */ + // Import the PathState enums for convenience using enum PathState; case Start: @@ -401,9 +401,9 @@ public: } } - /* Check the final state. */ + // Check the final state switch (state) { - /* Import the PathState enums for convenience. */ + // Import the PathState enums for convenience using enum PathState; case Start: R_THROW(ResultInvalidPathFormat); @@ -421,7 +421,7 @@ public: break; } - /* Set the output length. */ + // Set the output length *out_len = len; R_SUCCEED(); } @@ -429,21 +429,21 @@ public: static Result Normalize(char* dst, size_t* out_len, const char* path, size_t max_out_size, bool is_windows_path, bool is_drive_relative_path, bool allow_all_characters = false) { - /* Use StringTraits names for remainder of scope. */ + // Use StringTraits names for remainder of scope using namespace StringTraits; - /* Prepare to iterate. */ + // Prepare to iterate const char* cur_path = path; size_t total_len = 0; - /* If path begins with a separator, check that we're not drive relative. */ + // If path begins with a separator, check that we're not drive relative if (cur_path[0] != DirectorySeparator) { R_UNLESS(is_drive_relative_path, ResultInvalidPathFormat); dst[total_len++] = DirectorySeparator; } - /* We're going to need to do path replacement, potentially. */ + // We're going to need to do path replacement, potentially char* replacement_path = nullptr; size_t replacement_path_size = 0; @@ -457,7 +457,7 @@ public: } }); - /* Perform path replacement, if necessary. */ + // Perform path replacement, if necessary if (IsParentDirectoryPathReplacementNeeded(cur_path)) { if (std::is_constant_evaluated()) { replacement_path_size = EntryNameLengthMax + 1; @@ -472,25 +472,24 @@ public: cur_path = replacement_path; } - /* Iterate, normalizing path components. */ + // Iterate, normalizing path components bool skip_next_sep = false; size_t i = 0; while (cur_path[i] != NullTerminator) { - /* Process a directory separator, if we run into one. */ + // Process a directory separator, if we run into one if (cur_path[i] == DirectorySeparator) { - /* Swallow separators. */ + // Swallow separators do { ++i; } while (cur_path[i] == DirectorySeparator); - /* Check if we hit end of string. */ + // Check if we hit end of string if (cur_path[i] == NullTerminator) { break; } - /* If we aren't skipping the separator, write it, checking that we remain in bounds. - */ + // If we aren't skipping the separator, write it, checking that we remain in bounds. if (!skip_next_sep) { if (total_len + 1 == max_out_size) { dst[total_len] = NullTerminator; @@ -501,15 +500,15 @@ public: dst[total_len++] = DirectorySeparator; } - /* Don't skip the next separator. */ + // Don't skip the next separator skip_next_sep = false; } - /* Get the length of the current directory component. */ + // Get the length of the current directory component size_t dir_len = 0; while (cur_path[i + dir_len] != DirectorySeparator && cur_path[i + dir_len] != NullTerminator) { - /* Check for validity. */ + // Check for validity if (!allow_all_characters) { R_UNLESS(!IsInvalidCharacter(cur_path[i + dir_len]), ResultInvalidCharacter); } @@ -517,19 +516,19 @@ public: ++dir_len; } - /* Handle the current dir component. */ + // Handle the current dir component if (IsCurrentDirectory(cur_path + i)) { skip_next_sep = true; } else if (IsParentDirectory(cur_path + i)) { - /* We should have just written a separator. */ + // We should have just written a separator ASSERT(dst[total_len - 1] == DirectorySeparator); - /* We should have started with a separator, for non-windows paths. */ + // We should have started with a separator, for non-windows paths if (!is_windows_path) { ASSERT(dst[0] == DirectorySeparator); } - /* Remove the previous component. */ + // Remove the previous component if (total_len == 1) { R_UNLESS(is_windows_path, ResultDirectoryUnobtainable); @@ -544,15 +543,15 @@ public: } while ((--total_len) != 0); } - /* We should be pointing to a directory separator, for non-windows paths. */ + // We should be pointing to a directory separator, for non-windows paths if (!is_windows_path) { ASSERT(dst[total_len] == DirectorySeparator); } - /* We should remain in bounds. */ + // We should remain in bounds ASSERT(total_len < max_out_size); } else { - /* Copy, possibly truncating. */ + // Copy, possibly truncating if (total_len + dir_len + 1 > max_out_size) { const size_t copy_len = max_out_size - (total_len + 1); @@ -570,7 +569,7 @@ public: } } - /* Advance past the current directory component. */ + // Advance past the current directory component i += dir_len; } @@ -583,22 +582,22 @@ public: dst[0] = DirectorySeparator; } - /* NOTE: Probable nintendo bug, as max_out_size must be at least total_len + 1 for the null - * terminator. */ + // NOTE: Probable nintendo bug, as max_out_size must be at least total_len + 1 for the null + // terminator. R_UNLESS(max_out_size >= total_len - 1, ResultTooLongPath); dst[total_len] = NullTerminator; - /* Check that the result path is normalized. */ + // Check that the result path is normalized bool is_normalized; size_t dummy; R_TRY(IsNormalized(std::addressof(is_normalized), std::addressof(dummy), dst, allow_all_characters)); - /* Assert that the result path is normalized. */ + // Assert that the result path is normalized ASSERT(is_normalized); - /* Set the output length. */ + // Set the output length *out_len = total_len; R_SUCCEED(); } @@ -607,7 +606,7 @@ public: class PathFormatter { private: static constexpr Result CheckSharedName(const char* name, size_t len) { - /* Use StringTraits names for remainder of scope. */ + // Use StringTraits names for remainder of scope using namespace StringTraits; if (len == 1) { @@ -624,7 +623,7 @@ private: } static constexpr Result CheckHostName(const char* name, size_t len) { - /* Use StringTraits names for remainder of scope. */ + // Use StringTraits names for remainder of scope using namespace StringTraits; if (len == 2) { @@ -640,10 +639,10 @@ private: static constexpr Result CheckInvalidBackslash(bool* out_contains_backslash, const char* path, bool allow_backslash) { - /* Use StringTraits names for remainder of scope. */ + // Use StringTraits names for remainder of scope using namespace StringTraits; - /* Default to no backslashes, so we can just write if we see one. */ + // Default to no backslashes, so we can just write if we see one *out_contains_backslash = false; while (*path != NullTerminator) { @@ -670,34 +669,34 @@ public: static constexpr Result ParseMountName(const char** out, size_t* out_len, char* out_mount_name, size_t out_mount_name_buffer_size, const char* path) { - /* Check pre-conditions. */ + // Check pre-conditions ASSERT(path != nullptr); ASSERT(out_len != nullptr); ASSERT(out != nullptr); ASSERT((out_mount_name == nullptr) == (out_mount_name_buffer_size == 0)); - /* Use StringTraits names for remainder of scope. */ + // Use StringTraits names for remainder of scope using namespace StringTraits; - /* Determine max mount length. */ + // Determine max mount length const auto max_mount_len = out_mount_name_buffer_size == 0 ? MountNameLengthMax + 1 : std::min(MountNameLengthMax + 1, out_mount_name_buffer_size); - /* Parse the path until we see a drive separator. */ + // Parse the path until we see a drive separator size_t mount_len = 0; for (/* ... */; mount_len < max_mount_len && path[mount_len]; ++mount_len) { const char c = path[mount_len]; - /* If we see a drive separator, advance, then we're done with the pre-drive separator - * part of the mount. */ + // If we see a drive separator, advance, then we're done with the pre-drive separator + // part of the mount. if (c == DriveSeparator) { ++mount_len; break; } - /* If we see a directory separator, we're not in a mount name. */ + // If we see a directory separator, we're not in a mount name if (c == DirectorySeparator || c == AlternateDirectorySeparator) { *out = path; *out_len = 0; @@ -705,19 +704,19 @@ public: } } - /* Check to be sure we're actually looking at a mount name. */ + // Check to be sure we're actually looking at a mount name if (mount_len <= 2 || path[mount_len - 1] != DriveSeparator) { *out = path; *out_len = 0; R_SUCCEED(); } - /* Check that all characters in the mount name are allowable. */ + // Check that all characters in the mount name are allowable for (size_t i = 0; i < mount_len; ++i) { R_UNLESS(!IsInvalidCharacterForMountName(path[i]), ResultInvalidCharacter); } - /* Copy out the mount name. */ + // Copy out the mount name if (out_mount_name_buffer_size > 0) { R_UNLESS(mount_len < out_mount_name_buffer_size, ResultTooLongPath); @@ -727,7 +726,7 @@ public: out_mount_name[mount_len] = NullTerminator; } - /* Set the output. */ + // Set the output *out = path + mount_len; *out_len = mount_len; R_SUCCEED(); @@ -742,21 +741,21 @@ public: char* out_relative, size_t out_relative_buffer_size, const char* path) { - /* Check pre-conditions. */ + // Check pre-conditions ASSERT(path != nullptr); ASSERT(out_len != nullptr); ASSERT(out != nullptr); ASSERT((out_relative == nullptr) == (out_relative_buffer_size == 0)); - /* Use StringTraits names for remainder of scope. */ + // Use StringTraits names for remainder of scope using namespace StringTraits; - /* Initialize the output buffer, if we have one. */ + // Initialize the output buffer, if we have one if (out_relative_buffer_size > 0) { out_relative[0] = NullTerminator; } - /* Check if the path is relative. */ + // Check if the path is relative if (path[0] == Dot && (path[1] == NullTerminator || path[1] == DirectorySeparator || path[1] == AlternateDirectorySeparator)) { if (out_relative_buffer_size > 0) { @@ -771,10 +770,10 @@ public: R_SUCCEED(); } - /* Ensure the path isn't a parent directory. */ + // Ensure the path isn't a parent directory R_UNLESS(!(path[0] == Dot && path[1] == Dot), ResultDirectoryUnobtainable); - /* There was no relative dot path. */ + // There was no relative dot path *out = path; *out_len = 0; R_SUCCEED(); @@ -782,7 +781,7 @@ public: static constexpr Result SkipWindowsPath(const char** out, size_t* out_len, bool* out_normalized, const char* path, bool has_mount_name) { - /* We're normalized if and only if the parsing doesn't throw ResultNotNormalized(). */ + // We're normalized if and only if the parsing doesn't throw ResultNotNormalized() *out_normalized = true; R_TRY_CATCH(ParseWindowsPath(out, out_len, nullptr, 0, path, has_mount_name)) { @@ -801,21 +800,21 @@ public: static constexpr Result ParseWindowsPath(const char** out, size_t* out_len, char* out_win, size_t out_win_buffer_size, const char* path, bool has_mount_name) { - /* Check pre-conditions. */ + // Check pre-conditions ASSERT(path != nullptr); ASSERT(out_len != nullptr); ASSERT(out != nullptr); ASSERT((out_win == nullptr) == (out_win_buffer_size == 0)); - /* Use StringTraits names for remainder of scope. */ + // Use StringTraits names for remainder of scope using namespace StringTraits; - /* Initialize the output buffer, if we have one. */ + // Initialize the output buffer, if we have one if (out_win_buffer_size > 0) { out_win[0] = NullTerminator; } - /* Handle path start. */ + // Handle path start const char* cur_path = path; if (has_mount_name && path[0] == DirectorySeparator) { if (path[1] == AlternateDirectorySeparator && path[2] == AlternateDirectorySeparator) { @@ -829,9 +828,9 @@ public: } } - /* Handle windows drive. */ + // Handle windows drive if (IsWindowsDrive(cur_path)) { - /* Parse up to separator. */ + // Parse up to separator size_t win_path_len = WindowsDriveLength; for (/* ... */; cur_path[win_path_len] != NullTerminator; ++win_path_len) { R_UNLESS(!IsInvalidCharacter(cur_path[win_path_len]), ResultInvalidCharacter); @@ -842,13 +841,13 @@ public: } } - /* Ensure that we're normalized, if we're required to be. */ + // Ensure that we're normalized, if we're required to be if (out_win_buffer_size == 0) { for (size_t i = 0; i < win_path_len; ++i) { R_UNLESS(cur_path[i] != AlternateDirectorySeparator, ResultNotNormalized); } } else { - /* Ensure we can copy into the normalized buffer. */ + // Ensure we can copy into the normalized buffer R_UNLESS(win_path_len < out_win_buffer_size, ResultTooLongPath); for (size_t i = 0; i < win_path_len; ++i) { @@ -864,7 +863,7 @@ public: R_SUCCEED(); } - /* Handle DOS device. */ + // Handle DOS device if (IsDosDevicePath(cur_path)) { size_t dos_prefix_len = DosDevicePathPrefixLength; @@ -875,7 +874,7 @@ public: } if (out_win_buffer_size > 0) { - /* Ensure we can copy into the normalized buffer. */ + // Ensure we can copy into the normalized buffer R_UNLESS(dos_prefix_len < out_win_buffer_size, ResultTooLongPath); for (size_t i = 0; i < dos_prefix_len; ++i) { @@ -891,7 +890,7 @@ public: R_SUCCEED(); } - /* Handle UNC path. */ + // Handle UNC path if (IsUncPath(cur_path, false, true)) { const char* final_path = cur_path; @@ -932,13 +931,13 @@ public: size_t unc_prefix_len = final_path - cur_path; - /* Ensure that we're normalized, if we're required to be. */ + // Ensure that we're normalized, if we're required to be if (out_win_buffer_size == 0) { for (size_t i = 0; i < unc_prefix_len; ++i) { R_UNLESS(cur_path[i] != DirectorySeparator, ResultNotNormalized); } } else { - /* Ensure we can copy into the normalized buffer. */ + // Ensure we can copy into the normalized buffer R_UNLESS(unc_prefix_len < out_win_buffer_size, ResultTooLongPath); for (size_t i = 0; i < unc_prefix_len; ++i) { @@ -954,7 +953,7 @@ public: R_SUCCEED(); } - /* There's no windows path to parse. */ + // There's no windows path to parse *out = path; *out_len = 0; R_SUCCEED(); @@ -962,18 +961,18 @@ public: static constexpr Result IsNormalized(bool* out, size_t* out_len, const char* path, const PathFlags& flags = {}) { - /* Ensure nothing is null. */ + // Ensure nothing is null R_UNLESS(out != nullptr, ResultNullptrArgument); R_UNLESS(out_len != nullptr, ResultNullptrArgument); R_UNLESS(path != nullptr, ResultNullptrArgument); - /* Verify that the path is valid utf-8. */ + // Verify that the path is valid utf-8 R_TRY(CheckUtf8(path)); - /* Use StringTraits names for remainder of scope. */ + // Use StringTraits names for remainder of scope using namespace StringTraits; - /* Handle the case where the path is empty. */ + // Handle the case where the path is empty if (path[0] == NullTerminator) { R_UNLESS(flags.IsEmptyPathAllowed(), ResultInvalidPathFormat); @@ -982,32 +981,32 @@ public: R_SUCCEED(); } - /* All normalized paths start with a directory separator...unless they're windows paths, - * relative paths, or have mount names. */ + // All normalized paths start with a directory separator...unless they're windows paths, + // relative paths, or have mount names. if (path[0] != DirectorySeparator) { R_UNLESS(flags.IsWindowsPathAllowed() || flags.IsRelativePathAllowed() || flags.IsMountNameAllowed(), ResultInvalidPathFormat); } - /* Check that the path is allowed to be a windows path, if it is. */ + // Check that the path is allowed to be a windows path, if it is if (IsWindowsPath(path, false)) { R_UNLESS(flags.IsWindowsPathAllowed(), ResultInvalidPathFormat); } - /* Skip past the mount name, if one is present. */ + // Skip past the mount name, if one is present size_t total_len = 0; size_t mount_name_len = 0; R_TRY(SkipMountName(std::addressof(path), std::addressof(mount_name_len), path)); - /* If we had a mount name, check that that was allowed. */ + // If we had a mount name, check that that was allowed if (mount_name_len > 0) { R_UNLESS(flags.IsMountNameAllowed(), ResultInvalidPathFormat); total_len += mount_name_len; } - /* Check that the path starts as a normalized path should. */ + // Check that the path starts as a normalized path should if (path[0] != DirectorySeparator && !IsPathStartWithCurrentDirectory(path) && !IsWindowsPath(path, false)) { R_UNLESS(flags.IsRelativePathAllowed(), ResultInvalidPathFormat); @@ -1017,11 +1016,11 @@ public: R_SUCCEED(); } - /* Process relative path. */ + // Process relative path size_t relative_len = 0; R_TRY(SkipRelativeDotPath(std::addressof(path), std::addressof(relative_len), path)); - /* If we have a relative path, check that was allowed. */ + // If we have a relative path, check that was allowed if (relative_len > 0) { R_UNLESS(flags.IsRelativePathAllowed(), ResultInvalidPathFormat); @@ -1034,13 +1033,13 @@ public: } } - /* Process windows path. */ + // Process windows path size_t windows_len = 0; bool normalized_win = false; R_TRY(SkipWindowsPath(std::addressof(path), std::addressof(windows_len), std::addressof(normalized_win), path, mount_name_len > 0)); - /* If the windows path wasn't normalized, we're not normalized. */ + // If the windows path wasn't normalized, we're not normalized if (!normalized_win) { R_UNLESS(flags.IsWindowsPathAllowed(), ResultInvalidPathFormat); @@ -1048,22 +1047,22 @@ public: R_SUCCEED(); } - /* If we had a windows path, check that was allowed. */ + // If we had a windows path, check that was allowed if (windows_len > 0) { R_UNLESS(flags.IsWindowsPathAllowed(), ResultInvalidPathFormat); total_len += windows_len; - /* We can't have both a relative path and a windows path. */ + // We can't have both a relative path and a windows path R_UNLESS(relative_len == 0, ResultInvalidPathFormat); - /* A path ending in a windows path isn't normalized. */ + // A path ending in a windows path isn't normalized if (path[0] == NullTerminator) { *out = false; R_SUCCEED(); } - /* Check that there are no windows directory separators in the path. */ + // Check that there are no windows directory separators in the path for (size_t i = 0; path[i] != NullTerminator; ++i) { if (path[i] == AlternateDirectorySeparator) { *out = false; @@ -1072,48 +1071,48 @@ public: } } - /* Check that parent directory replacement is not needed if backslashes are allowed. */ + // Check that parent directory replacement is not needed if backslashes are allowed if (flags.IsBackslashAllowed() && PathNormalizer::IsParentDirectoryPathReplacementNeeded(path)) { *out = false; R_SUCCEED(); } - /* Check that the backslash state is valid. */ + // Check that the backslash state is valid bool is_backslash_contained = false; R_TRY(CheckInvalidBackslash(std::addressof(is_backslash_contained), path, flags.IsWindowsPathAllowed() || flags.IsBackslashAllowed())); - /* Check that backslashes are contained only if allowed. */ + // Check that backslashes are contained only if allowed if (is_backslash_contained && !flags.IsBackslashAllowed()) { *out = false; R_SUCCEED(); } - /* Check that the final result path is normalized. */ + // Check that the final result path is normalized size_t normal_len = 0; R_TRY(PathNormalizer::IsNormalized(out, std::addressof(normal_len), path, flags.IsAllCharactersAllowed())); - /* Add the normal length. */ + // Add the normal length total_len += normal_len; - /* Set the output length. */ + // Set the output length *out_len = total_len; R_SUCCEED(); } static Result Normalize(char* dst, size_t dst_size, const char* path, size_t path_len, const PathFlags& flags) { - /* Use StringTraits names for remainder of scope. */ + // Use StringTraits names for remainder of scope using namespace StringTraits; - /* Prepare to iterate. */ + // Prepare to iterate const char* src = path; size_t cur_pos = 0; bool is_windows_path = false; - /* Check if the path is empty. */ + // Check if the path is empty if (src[0] == NullTerminator) { if (dst_size != 0) { dst[0] = NullTerminator; @@ -1124,7 +1123,7 @@ public: R_SUCCEED(); } - /* Handle a mount name. */ + // Handle a mount name size_t mount_name_len = 0; if (flags.IsMountNameAllowed()) { R_TRY(ParseMountName(std::addressof(src), std::addressof(mount_name_len), dst + cur_pos, @@ -1133,7 +1132,7 @@ public: cur_pos += mount_name_len; } - /* Handle a drive-relative prefix. */ + // Handle a drive-relative prefix bool is_drive_relative = false; if (src[0] != DirectorySeparator && !IsPathStartWithCurrentDirectory(src) && !IsWindowsPath(src, false)) { @@ -1161,7 +1160,7 @@ public: } } - /* Handle a windows path. */ + // Handle a windows path if (flags.IsWindowsPathAllowed()) { const char* const orig = src; @@ -1187,16 +1186,16 @@ public: } } - /* Check for invalid backslash. */ + // Check for invalid backslash bool backslash_contained = false; R_TRY(CheckInvalidBackslash(std::addressof(backslash_contained), src, flags.IsWindowsPathAllowed() || flags.IsBackslashAllowed())); - /* Handle backslash replacement as necessary. */ + // Handle backslash replacement as necessary if (backslash_contained && flags.IsWindowsPathAllowed()) { - /* Create a temporary buffer holding a slash-replaced version of the path. */ - /* NOTE: Nintendo unnecessarily allocates and replaces here a fully copy of the path, - * despite having skipped some of it already. */ + // Create a temporary buffer holding a slash-replaced version of the path. + // NOTE: Nintendo unnecessarily allocates and replaces here a fully copy of the path, + // despite having skipped some of it already. const size_t replaced_src_len = path_len - (src - path); char* replaced_src = nullptr; @@ -1226,7 +1225,7 @@ public: dst_size - cur_pos, is_windows_path, is_drive_relative, flags.IsAllCharactersAllowed())); } else { - /* We can just do normalization. */ + // We can just do normalization size_t dummy; R_TRY(PathNormalizer::Normalize(dst + cur_pos, std::addressof(dummy), src, dst_size - cur_pos, is_windows_path, is_drive_relative, diff --git a/src/core/file_sys/fs_string_util.h b/src/core/file_sys/fs_string_util.h index 68114e72c..874e09054 100644 --- a/src/core/file_sys/fs_string_util.h +++ b/src/core/file_sys/fs_string_util.h @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #pragma once @@ -71,21 +71,6 @@ static constexpr int Strlcpy(T* dst, const T* src, int count) { return static_cast<int>(cur - src); } -/* std::size() does not support zero-size C arrays. We're fixing that. */ -template <class C> -constexpr auto size(const C& c) -> decltype(c.size()) { - return std::size(c); -} - -template <class C> -constexpr std::size_t size(const C& c) { - if constexpr (sizeof(C) == 0) { - return 0; - } else { - return std::size(c); - } -} - enum CharacterEncodingResult { CharacterEncodingResult_Success = 0, CharacterEncodingResult_InsufficientLength = 1, @@ -116,11 +101,11 @@ public: } // namespace impl constexpr inline CharacterEncodingResult ConvertCharacterUtf8ToUtf32(u32* dst, const char* src) { - /* Check pre-conditions. */ + // Check pre-conditions ASSERT(dst != nullptr); ASSERT(src != nullptr); - /* Perform the conversion. */ + // Perform the conversion const auto* p = src; switch (impl::CharacterEncodingHelper::GetUtf8NBytes(static_cast<unsigned char>(p[0]))) { case 1: @@ -164,24 +149,24 @@ constexpr inline CharacterEncodingResult ConvertCharacterUtf8ToUtf32(u32* dst, c break; } - /* We failed to convert. */ + // We failed to convert return CharacterEncodingResult_InvalidFormat; } constexpr inline CharacterEncodingResult PickOutCharacterFromUtf8String(char* dst, const char** str) { - /* Check pre-conditions. */ + // Check pre-conditions ASSERT(dst != nullptr); ASSERT(str != nullptr); ASSERT(*str != nullptr); - /* Clear the output. */ + // Clear the output dst[0] = 0; dst[1] = 0; dst[2] = 0; dst[3] = 0; - /* Perform the conversion. */ + // Perform the conversion const auto* p = *str; u32 c = static_cast<u32>(*p); switch (impl::CharacterEncodingHelper::GetUtf8NBytes(c)) { |