diff --git a/libraries/libstratosphere/include/stratosphere/fs/common/fs_dbm_hierarchical_rom_file_table.hpp b/libraries/libstratosphere/include/stratosphere/fs/common/fs_dbm_hierarchical_rom_file_table.hpp index 1664ab496..16f50396b 100644 --- a/libraries/libstratosphere/include/stratosphere/fs/common/fs_dbm_hierarchical_rom_file_table.hpp +++ b/libraries/libstratosphere/include/stratosphere/fs/common/fs_dbm_hierarchical_rom_file_table.hpp @@ -20,10 +20,11 @@ namespace ams::fs { - /* ACCURATE_TO_VERSION: Unknown */ + /* ACCURATE_TO_VERSION: 14.3.0.0 */ class HierarchicalRomFileTable { public: - using Position = u32; + using Position = u32; + using StorageSizeType = u32; struct FindPosition { Position next_dir; @@ -31,8 +32,7 @@ namespace ams::fs { }; static_assert(util::is_pod::value); - using DirectoryInfo = RomDirectoryInfo; - using FileInfo = RomFileInfo; + using FileInfo = RomFileInfo; static constexpr RomFileId PositionToFileId(Position pos) { return static_cast(pos); @@ -81,11 +81,11 @@ namespace ams::fs { using Base = KeyValueRomStorageTemplate; public: Result Add(Position *out, const ClientKeyType &key, const Value &value) { - R_RETURN(Base::AddInternal(out, key.key, key.Hash(), key.name.path, key.name.length * sizeof(RomPathChar), value)); + R_RETURN(Base::AddInternal(out, key.key, key.Hash(), key.name.begin(), key.name.length(), value)); } Result Get(Position *out_pos, Value *out_val, const ClientKeyType &key) { - R_RETURN(Base::GetInternal(out_pos, out_val, key.key, key.Hash(), key.name.path, key.name.length * sizeof(RomPathChar))); + R_RETURN(Base::GetInternal(out_pos, out_val, key.key, key.Hash(), key.name.begin(), key.name.length())); } Result GetByPosition(ImplKey *out_key, Value *out_val, Position pos) { @@ -122,16 +122,15 @@ namespace ams::fs { constexpr u32 Hash() const { u32 hash = this->key.parent ^ 123456789; - const RomPathChar * name = this->name.path; - const RomPathChar * const end = name + this->name.length; - while (name < end) { - const u32 cur = static_cast(static_cast::type>(*(name++))); - hash = ((hash >> 5) | (hash << 27)) ^ cur; + const RomPathChar * cur = this->name.begin(); + const RomPathChar * const end = this->name.end(); + while (cur < end) { + const u32 c = static_cast(static_cast::type>(*(cur++))); + hash = ((hash >> 5) | (hash << 27)) ^ c; } return hash; } }; - static_assert(util::is_pod::value); using DirectoryEntryMapTable = EntryMapTable; using FileEntryMapTable = EntryMapTable; @@ -139,35 +138,24 @@ namespace ams::fs { DirectoryEntryMapTable m_dir_table; FileEntryMapTable m_file_table; public: - static s64 QueryDirectoryEntryBucketStorageSize(s64 count); - static size_t QueryDirectoryEntrySize(size_t aux_size); - static s64 QueryFileEntryBucketStorageSize(s64 count); - static size_t QueryFileEntrySize(size_t aux_size); + static s64 QueryDirectoryEntryBucketStorageSize(StorageSizeType count); + static s64 QueryDirectoryEntrySize(StorageSizeType aux_size); + static s64 QueryFileEntryBucketStorageSize(StorageSizeType count); + static s64 QueryFileEntrySize(StorageSizeType aux_size); static Result Format(SubStorage dir_bucket, SubStorage file_bucket); public: HierarchicalRomFileTable(); - constexpr u32 GetDirectoryEntryCount() const { - return m_dir_table.GetEntryCount(); - } - - constexpr u32 GetFileEntryCount() const { - return m_file_table.GetEntryCount(); - } - Result Initialize(SubStorage dir_bucket, SubStorage dir_entry, SubStorage file_bucket, SubStorage file_entry); void Finalize(); Result CreateRootDirectory(); - Result CreateDirectory(RomDirectoryId *out, const RomPathChar *path, const DirectoryInfo &info); + Result CreateDirectory(RomDirectoryId *out, const RomPathChar *path); Result CreateFile(RomFileId *out, const RomPathChar *path, const FileInfo &info); Result ConvertPathToDirectoryId(RomDirectoryId *out, const RomPathChar *path); Result ConvertPathToFileId(RomFileId *out, const RomPathChar *path); - Result GetDirectoryInformation(DirectoryInfo *out, const RomPathChar *path); - Result GetDirectoryInformation(DirectoryInfo *out, RomDirectoryId id); - Result OpenFile(FileInfo *out, const RomPathChar *path); Result OpenFile(FileInfo *out, RomFileId id); @@ -179,7 +167,7 @@ namespace ams::fs { Result QueryRomFileSystemSize(s64 *out_dir_entry_size, s64 *out_file_entry_size); private: - Result GetGrandParent(Position *out_pos, EntryKey *out_dir_key, RomDirectoryEntry *out_dir_entry, Position pos, RomPathTool::RomEntryName name, const RomPathChar *path); + Result GetParent(Position *out_pos, EntryKey *out_dir_key, RomDirectoryEntry *out_dir_entry, Position pos, RomPathTool::RomEntryName name, const RomPathChar *path); Result FindParentDirectoryRecursive(Position *out_pos, EntryKey *out_dir_key, RomDirectoryEntry *out_dir_entry, RomPathTool::PathParser *parser, const RomPathChar *path); @@ -195,8 +183,6 @@ namespace ams::fs { Result GetFileEntry(Position *out_pos, RomFileEntry *out_entry, const EntryKey &key); Result GetFileEntry(RomFileEntry *out_entry, RomFileId id); - Result GetDirectoryInformation(DirectoryInfo *out, const EntryKey &key); - Result OpenFile(FileInfo *out, const EntryKey &key); Result FindOpen(FindPosition *out, const EntryKey &key); diff --git a/libraries/libstratosphere/include/stratosphere/fs/common/fs_dbm_rom_key_value_storage.hpp b/libraries/libstratosphere/include/stratosphere/fs/common/fs_dbm_rom_key_value_storage.hpp index 5435d4400..87a571da7 100644 --- a/libraries/libstratosphere/include/stratosphere/fs/common/fs_dbm_rom_key_value_storage.hpp +++ b/libraries/libstratosphere/include/stratosphere/fs/common/fs_dbm_rom_key_value_storage.hpp @@ -19,7 +19,7 @@ namespace ams::fs { - /* ACCURATE_TO_VERSION: Unknown */ + /* ACCURATE_TO_VERSION: 14.3.0.0 */ template class KeyValueRomStorageTemplate { public: @@ -28,6 +28,8 @@ namespace ams::fs { using Position = u32; using BucketIndex = s64; + using StorageSizeType = u32; + struct FindIndex { BucketIndex ind; Position pos; @@ -40,7 +42,7 @@ namespace ams::fs { Key key; Value value; Position next; - u32 size; + StorageSizeType size; }; static_assert(util::is_pod::value); private: @@ -54,23 +56,23 @@ namespace ams::fs { return num * sizeof(Position); } - static constexpr s64 QueryBucketCount(s64 size) { + static constexpr s64 QueryBucketCount(StorageSizeType size) { return size / sizeof(Position); } - static constexpr size_t QueryEntrySize(size_t aux_size) { - return util::AlignUp(sizeof(Element) + aux_size, alignof(Element)); + static constexpr size_t QueryEntrySize(StorageSizeType aux_size) { + return util::AlignUp(sizeof(Element) + aux_size, alignof(Element)); } - static Result Format(SubStorage bucket, s64 count) { + static Result Format(SubStorage bucket, StorageSizeType count) { const Position pos = InvalidPosition; - for (s64 i = 0; i < count; i++) { + for (auto i = 0u; i < count; i++) { R_TRY(bucket.Write(i * sizeof(pos), std::addressof(pos), sizeof(pos))); } R_SUCCEED(); } public: - KeyValueRomStorageTemplate() : m_bucket_count(), m_bucket_storage(), m_kv_storage(), m_total_entry_size(), m_entry_count() { /* ... */ } + constexpr KeyValueRomStorageTemplate() : m_bucket_count(), m_bucket_storage(), m_kv_storage(), m_total_entry_size(), m_entry_count() { /* ... */ } Result Initialize(const SubStorage &bucket, s64 count, const SubStorage &kv) { AMS_ASSERT(count > 0); @@ -82,25 +84,13 @@ namespace ams::fs { void Finalize() { m_bucket_storage = SubStorage(); - m_kv_storage = SubStorage(); m_bucket_count = 0; + m_kv_storage = SubStorage(); } s64 GetTotalEntrySize() const { return m_total_entry_size; } - - Result GetFreeSize(s64 *out) { - AMS_ASSERT(out != nullptr); - s64 kv_size = 0; - R_TRY(m_kv_storage.GetSize(std::addressof(kv_size))); - *out = kv_size - m_total_entry_size; - R_SUCCEED(); - } - - constexpr u32 GetEntryCount() const { - return m_entry_count; - } protected: Result AddInternal(Position *out, const Key &key, u32 hash_key, const void *aux, size_t aux_size, const Value &value) { AMS_ASSERT(out != nullptr); @@ -117,12 +107,12 @@ namespace ams::fs { } Position pos; - R_TRY(this->AllocateEntry(std::addressof(pos), aux_size)); + R_TRY(this->AllocateEntry(std::addressof(pos), static_cast(aux_size))); Position next_pos; R_TRY(this->LinkEntry(std::addressof(next_pos), pos, hash_key)); - const Element elem = { key, value, next_pos, static_cast(aux_size) }; + const Element elem = { key, value, next_pos, static_cast(aux_size) }; R_TRY(this->WriteKeyValue(std::addressof(elem), pos, aux, aux_size)); *out = pos; @@ -203,15 +193,14 @@ namespace ams::fs { R_UNLESS(cur != InvalidPosition, fs::ResultDbmKeyNotFound()); - u8 *buf = static_cast(::ams::fs::impl::Allocate(MaxAuxiliarySize)); - R_UNLESS(buf != nullptr, fs::ResultAllocationMemoryFailedInDbmRomKeyValueStorage()); - ON_SCOPE_EXIT { ::ams::fs::impl::Deallocate(buf, MaxAuxiliarySize); }; + auto buf = ::ams::fs::impl::MakeUnique(MaxAuxiliarySize); + R_UNLESS(buf != nullptr, fs::ResultAllocationMemoryFailedMakeUnique()); while (true) { size_t cur_aux_size; - R_TRY(this->ReadKeyValue(out_elem, buf, std::addressof(cur_aux_size), cur)); + R_TRY(this->ReadKeyValue(out_elem, buf.get(), std::addressof(cur_aux_size), cur)); - if (key.IsEqual(out_elem->key, aux, aux_size, buf, cur_aux_size)) { + if (key.IsEqual(out_elem->key, aux, aux_size, buf.get(), cur_aux_size)) { *out_pos = cur; R_SUCCEED(); } @@ -222,17 +211,17 @@ namespace ams::fs { } } - Result AllocateEntry(Position *out, size_t aux_size) { + Result AllocateEntry(Position *out, StorageSizeType aux_size) { AMS_ASSERT(out != nullptr); s64 kv_size; R_TRY(m_kv_storage.GetSize(std::addressof(kv_size))); - const size_t end_pos = m_total_entry_size + sizeof(Element) + aux_size; + const size_t end_pos = m_total_entry_size + sizeof(Element) + static_cast(aux_size); R_UNLESS(end_pos <= static_cast(kv_size), fs::ResultDbmKeyFull()); *out = static_cast(m_total_entry_size); - m_total_entry_size = util::AlignUp(static_cast(end_pos), alignof(Position)); + m_total_entry_size = util::AlignUp(static_cast(end_pos), alignof(Position)); R_SUCCEED(); } diff --git a/libraries/libstratosphere/include/stratosphere/fs/common/fs_dbm_rom_path_tool.hpp b/libraries/libstratosphere/include/stratosphere/fs/common/fs_dbm_rom_path_tool.hpp index 9780644ee..0fc1bc8ee 100644 --- a/libraries/libstratosphere/include/stratosphere/fs/common/fs_dbm_rom_path_tool.hpp +++ b/libraries/libstratosphere/include/stratosphere/fs/common/fs_dbm_rom_path_tool.hpp @@ -18,36 +18,60 @@ namespace ams::fs::RomPathTool { - /* ACCURATE_TO_VERSION: Unknown */ + /* ACCURATE_TO_VERSION: 14.3.0.0 */ constexpr inline u32 MaxPathLength = 0x300; - struct RomEntryName { - size_t length; - const RomPathChar *path; - }; - static_assert(util::is_pod::value); - - constexpr void InitEntryName(RomEntryName *entry) { - AMS_ASSERT(entry != nullptr); - entry->length = 0; - } - - constexpr inline bool IsSeparator(RomPathChar c) { + constexpr ALWAYS_INLINE bool IsSeparator(RomPathChar c) { return c == RomStringTraits::DirectorySeparator; } - constexpr inline bool IsNullTerminator(RomPathChar c) { + constexpr ALWAYS_INLINE bool IsNullTerminator(RomPathChar c) { return c == RomStringTraits::NullTerminator; } - constexpr inline bool IsDot(RomPathChar c) { + constexpr ALWAYS_INLINE bool IsDot(RomPathChar c) { return c == RomStringTraits::Dot; } - constexpr inline bool IsCurrentDirectory(const RomEntryName &name) { - return name.length == 1 && IsDot(name.path[0]); - } + class RomEntryName { + private: + const RomPathChar *m_path; + size_t m_length; + public: + constexpr RomEntryName() : m_path(nullptr), m_length(0) { + /* ... */ + } + + constexpr void Initialize(const RomPathChar *p, size_t len) { + m_path = p; + m_length = len; + } + + constexpr bool IsCurrentDirectory() const { + return m_length == 1 && IsDot(m_path[0]); + } + + constexpr bool IsParentDirectory() const { + return m_length == 2 && IsDot(m_path[0]) && IsDot(m_path[1]); + } + + constexpr bool IsRootDirectory() const { + return m_length == 0; + } + + constexpr const RomPathChar *begin() const { + return m_path; + } + + constexpr const RomPathChar *end() const { + return m_path + m_length; + } + + constexpr size_t length() const { + return m_length; + } + }; constexpr inline bool IsCurrentDirectory(const RomPathChar *p, size_t length) { AMS_ASSERT(p != nullptr); @@ -59,10 +83,6 @@ namespace ams::fs::RomPathTool { return IsDot(p[0]) && IsNullTerminator(p[1]); } - constexpr inline bool IsParentDirectory(const RomEntryName &name) { - return name.length == 2 && IsDot(name.path[0]) && IsDot(name.path[1]); - } - constexpr inline bool IsParentDirectory(const RomPathChar *p) { AMS_ASSERT(p != nullptr); return IsDot(p[0]) && IsDot(p[1]) && IsNullTerminator(p[2]); diff --git a/libraries/libstratosphere/include/stratosphere/fs/common/fs_dbm_rom_types.hpp b/libraries/libstratosphere/include/stratosphere/fs/common/fs_dbm_rom_types.hpp index d9b4f8482..eda18f8d4 100644 --- a/libraries/libstratosphere/include/stratosphere/fs/common/fs_dbm_rom_types.hpp +++ b/libraries/libstratosphere/include/stratosphere/fs/common/fs_dbm_rom_types.hpp @@ -18,10 +18,10 @@ namespace ams::fs { - /* ACCURATE_TO_VERSION: Unknown */ + /* ACCURATE_TO_VERSION: 14.3.0.0 */ using RomPathChar = char; - using RomFileId = s32; - using RomDirectoryId = s32; + using RomFileId = u32; + using RomDirectoryId = u32; struct RomFileSystemInformation { s64 size; @@ -38,11 +38,6 @@ namespace ams::fs { static_assert(util::is_pod::value); static_assert(sizeof(RomFileSystemInformation) == 0x50); - struct RomDirectoryInfo { - /* ... */ - }; - static_assert(util::is_pod::value); - struct RomFileInfo { Int64 offset; Int64 size; diff --git a/libraries/libstratosphere/source/fs/common/fs_dbm_hierarchical_rom_file_table.cpp b/libraries/libstratosphere/source/fs/common/fs_dbm_hierarchical_rom_file_table.cpp index cc72487bf..aa743cd63 100644 --- a/libraries/libstratosphere/source/fs/common/fs_dbm_hierarchical_rom_file_table.cpp +++ b/libraries/libstratosphere/source/fs/common/fs_dbm_hierarchical_rom_file_table.cpp @@ -17,19 +17,19 @@ namespace ams::fs { - s64 HierarchicalRomFileTable::QueryDirectoryEntryBucketStorageSize(s64 count) { + s64 HierarchicalRomFileTable::QueryDirectoryEntryBucketStorageSize(StorageSizeType count) { return DirectoryEntryMapTable::QueryBucketStorageSize(count); } - size_t HierarchicalRomFileTable::QueryDirectoryEntrySize(size_t aux_size) { + s64 HierarchicalRomFileTable::QueryDirectoryEntrySize(StorageSizeType aux_size) { return DirectoryEntryMapTable::QueryEntrySize(aux_size); } - s64 HierarchicalRomFileTable::QueryFileEntryBucketStorageSize(s64 count) { + s64 HierarchicalRomFileTable::QueryFileEntryBucketStorageSize(StorageSizeType count) { return FileEntryMapTable::QueryBucketStorageSize(count); } - size_t HierarchicalRomFileTable::QueryFileEntrySize(size_t aux_size) { + s64 HierarchicalRomFileTable::QueryFileEntrySize(StorageSizeType aux_size) { return FileEntryMapTable::QueryEntrySize(aux_size); } @@ -68,7 +68,6 @@ namespace ams::fs { Position root_pos = RootPosition; EntryKey root_key = {}; root_key.key.parent = root_pos; - RomPathTool::InitEntryName(std::addressof(root_key.name)); RomDirectoryEntry root_entry = { .next = InvalidPosition, .dir = InvalidPosition, @@ -77,7 +76,7 @@ namespace ams::fs { R_RETURN(m_dir_table.Add(std::addressof(root_pos), root_key, root_entry)); } - Result HierarchicalRomFileTable::CreateDirectory(RomDirectoryId *out, const RomPathChar *path, const DirectoryInfo &info) { + Result HierarchicalRomFileTable::CreateDirectory(RomDirectoryId *out, const RomPathChar *path) { AMS_ASSERT(out != nullptr); AMS_ASSERT(path != nullptr); @@ -92,7 +91,6 @@ namespace ams::fs { .dir = InvalidPosition, .file = InvalidPosition, }; - AMS_UNUSED(info); Position new_pos = 0; R_TRY_CATCH(m_dir_table.Add(std::addressof(new_pos), new_key, new_entry)) { @@ -205,28 +203,6 @@ namespace ams::fs { R_SUCCEED(); } - Result HierarchicalRomFileTable::GetDirectoryInformation(DirectoryInfo *out, const RomPathChar *path) { - AMS_ASSERT(out != nullptr); - AMS_ASSERT(path != nullptr); - - RomDirectoryEntry parent_entry = {}; - EntryKey key = {}; - R_TRY(this->FindDirectoryRecursive(std::addressof(key), std::addressof(parent_entry), path)); - - R_RETURN(this->GetDirectoryInformation(out, key)); - } - - Result HierarchicalRomFileTable::GetDirectoryInformation(DirectoryInfo *out, RomDirectoryId id) { - AMS_ASSERT(out != nullptr); - - RomDirectoryEntry entry = {}; - R_TRY(this->GetDirectoryEntry(std::addressof(entry), id)); - - AMS_UNUSED(out); - - R_SUCCEED(); - } - Result HierarchicalRomFileTable::OpenFile(FileInfo *out, const RomPathChar *path) { AMS_ASSERT(out != nullptr); AMS_ASSERT(path != nullptr); @@ -318,22 +294,22 @@ namespace ams::fs { AMS_ASSERT(out_dir_entry_size != nullptr); AMS_ASSERT(out_file_entry_size != nullptr); - *out_dir_entry_size = m_dir_table.GetTotalEntrySize(); + *out_dir_entry_size = m_dir_table.GetTotalEntrySize(); *out_file_entry_size = m_file_table.GetTotalEntrySize(); R_SUCCEED(); } - Result HierarchicalRomFileTable::GetGrandParent(Position *out_pos, EntryKey *out_dir_key, RomDirectoryEntry *out_dir_entry, Position pos, RomPathTool::RomEntryName name, const RomPathChar *path) { + Result HierarchicalRomFileTable::GetParent(Position *out_pos, EntryKey *out_dir_key, RomDirectoryEntry *out_dir_entry, Position pos, RomPathTool::RomEntryName name, const RomPathChar *path) { AMS_ASSERT(out_pos != nullptr); AMS_ASSERT(out_dir_key != nullptr); AMS_ASSERT(out_dir_entry != nullptr); AMS_ASSERT(path != nullptr); - RomEntryKey gp_key = {}; - RomDirectoryEntry gp_entry = {}; - R_TRY(m_dir_table.GetByPosition(std::addressof(gp_key), std::addressof(gp_entry), pos)); - out_dir_key->key.parent = gp_key.parent; + RomEntryKey p_key = {}; + RomDirectoryEntry p_entry = {}; + R_TRY(m_dir_table.GetByPosition(std::addressof(p_key), std::addressof(p_entry), pos)); + out_dir_key->key = p_key; R_TRY(RomPathTool::GetParentDirectoryName(std::addressof(out_dir_key->name), name, path)); R_TRY(this->GetDirectoryEntry(out_pos, out_dir_entry, *out_dir_key)); @@ -362,13 +338,13 @@ namespace ams::fs { R_TRY(parser->GetNextDirectoryName(std::addressof(dir_key.name))); - if (RomPathTool::IsCurrentDirectory(dir_key.name)) { + if (dir_key.name.IsCurrentDirectory()) { dir_key = old_key; continue; - } else if (RomPathTool::IsParentDirectory(dir_key.name)) { + } else if (dir_key.name.IsParentDirectory()) { R_UNLESS(parent_pos != RootPosition, fs::ResultDirectoryUnobtainable()); - R_TRY(this->GetGrandParent(std::addressof(parent_pos), std::addressof(dir_key), std::addressof(dir_entry), dir_key.key.parent, dir_key.name, path)); + R_TRY(this->GetParent(std::addressof(parent_pos), std::addressof(dir_key), std::addressof(dir_entry), dir_key.key.parent, dir_key.name, path)); } else { dir_key.key.parent = parent_pos; R_TRY_CATCH(this->GetDirectoryEntry(std::addressof(dir_pos), std::addressof(dir_entry), dir_key)) { @@ -401,31 +377,31 @@ namespace ams::fs { RomPathTool::RomEntryName name = {}; R_TRY(parser.GetAsDirectoryName(std::addressof(name))); - if (RomPathTool::IsCurrentDirectory(name)) { + if (name.IsCurrentDirectory()) { *out_key = parent_key; if (out_key->key.parent != RootPosition) { Position pos = 0; - R_TRY(this->GetGrandParent(std::addressof(pos), std::addressof(parent_key), out_dir_entry, out_key->key.parent, out_key->name, path)); + R_TRY(this->GetParent(std::addressof(pos), std::addressof(parent_key), out_dir_entry, out_key->key.parent, out_key->name, path)); } - } else if (RomPathTool::IsParentDirectory(name)) { + } else if (name.IsParentDirectory()) { R_UNLESS(parent_pos != RootPosition, fs::ResultDirectoryUnobtainable()); Position pos = 0; RomDirectoryEntry cur_entry = {}; - R_TRY(this->GetGrandParent(std::addressof(pos), out_key, std::addressof(cur_entry), parent_key.key.parent, parent_key.name, path)); + R_TRY(this->GetParent(std::addressof(pos), out_key, std::addressof(cur_entry), parent_key.key.parent, parent_key.name, path)); if (out_key->key.parent != RootPosition) { - R_TRY(this->GetGrandParent(std::addressof(pos), std::addressof(parent_key), out_dir_entry, out_key->key.parent, out_key->name, path)); + R_TRY(this->GetParent(std::addressof(pos), std::addressof(parent_key), out_dir_entry, out_key->key.parent, out_key->name, path)); } } else { out_key->name = name; - out_key->key.parent = (out_key->name.length > 0) ? parent_pos : RootPosition; + out_key->key.parent = out_key->name.IsRootDirectory() ? RootPosition : parent_pos; } } else { { RomPathTool::RomEntryName name = {}; R_TRY(parser.GetAsDirectoryName(std::addressof(name))); - R_UNLESS(!RomPathTool::IsParentDirectory(name) || parent_pos != RootPosition, fs::ResultDirectoryUnobtainable()); + R_UNLESS(!name.IsParentDirectory() || parent_pos != RootPosition, fs::ResultDirectoryUnobtainable()); } R_UNLESS(!parser.IsDirectoryPath(), fs::ResultDbmInvalidOperation()); @@ -461,7 +437,7 @@ namespace ams::fs { const Result get_res = m_dir_table.Get(std::addressof(pos), std::addressof(entry), key); if (!fs::ResultDbmKeyNotFound::Includes(get_res)) { R_TRY(get_res); - R_RETURN(if_exists); + R_THROW(if_exists); } } @@ -472,9 +448,10 @@ namespace ams::fs { const Result get_res = m_file_table.Get(std::addressof(pos), std::addressof(entry), key); if (!fs::ResultDbmKeyNotFound::Includes(get_res)) { R_TRY(get_res); - R_RETURN(if_exists); + R_THROW(if_exists); } } + R_SUCCEED(); } @@ -542,18 +519,6 @@ namespace ams::fs { R_RETURN(dir_res); } - Result HierarchicalRomFileTable::GetDirectoryInformation(DirectoryInfo *out, const EntryKey &key) { - AMS_ASSERT(out != nullptr); - - Position pos = 0; - RomDirectoryEntry entry = {}; - R_TRY(this->GetDirectoryEntry(std::addressof(pos), std::addressof(entry), key)); - - AMS_UNUSED(out); - - R_SUCCEED(); - } - Result HierarchicalRomFileTable::OpenFile(FileInfo *out, const EntryKey &key) { AMS_ASSERT(out != nullptr); diff --git a/libraries/libstratosphere/source/fs/common/fs_dbm_rom_path_tool.cpp b/libraries/libstratosphere/source/fs/common/fs_dbm_rom_path_tool.cpp index 8f4a45d0f..b3842cb29 100644 --- a/libraries/libstratosphere/source/fs/common/fs_dbm_rom_path_tool.cpp +++ b/libraries/libstratosphere/source/fs/common/fs_dbm_rom_path_tool.cpp @@ -21,16 +21,14 @@ namespace ams::fs::RomPathTool { AMS_ASSERT(path != nullptr); /* Require paths start with a separator, and skip repeated separators. */ - R_UNLESS(IsSeparator(path[0]), fs::ResultDbmInvalidPathFormat()); - while (IsSeparator(path[1])) { - path++; + R_UNLESS(RomPathTool::IsSeparator(path[0]), fs::ResultDbmInvalidPathFormat()); + while (RomPathTool::IsSeparator(path[1])) { + ++path; } m_prev_path_start = path; m_prev_path_end = path; - for (m_next_path = path + 1; IsSeparator(m_next_path[0]); ++m_next_path) { - /* ... */ - } + m_next_path = path + 1; R_SUCCEED(); } @@ -49,52 +47,49 @@ namespace ams::fs::RomPathTool { bool PathParser::IsDirectoryPath() const { AMS_ASSERT(m_next_path != nullptr); - if (IsNullTerminator(m_next_path[0]) && IsSeparator(m_next_path[-1])) { + if (RomPathTool::IsNullTerminator(m_next_path[0]) && RomPathTool::IsSeparator(m_next_path[-1])) { return true; } - if (IsCurrentDirectory(m_next_path)) { + if (RomPathTool::IsCurrentDirectory(m_next_path)) { return true; } - return IsParentDirectory(m_next_path); + return RomPathTool::IsParentDirectory(m_next_path); } Result PathParser::GetNextDirectoryName(RomEntryName *out) { - AMS_ASSERT(out != nullptr); AMS_ASSERT(m_prev_path_start != nullptr); AMS_ASSERT(m_prev_path_end != nullptr); AMS_ASSERT(m_next_path != nullptr); + AMS_ASSERT(out != nullptr); - /* Set the current path to output. */ - out->length = m_prev_path_end - m_prev_path_start; - out->path = m_prev_path_start; + /* Get as directory name. */ + R_TRY(this->GetAsDirectoryName(out)); /* Parse the next path. */ - m_prev_path_start = m_next_path; const RomPathChar *cur = m_next_path; - for (size_t name_len = 0; true; name_len++) { - if (IsSeparator(cur[name_len])) { - R_UNLESS(name_len < MaxPathLength, fs::ResultDbmDirectoryNameTooLong()); - - m_prev_path_end = cur + name_len; - m_next_path = m_prev_path_end + 1; - - while (IsSeparator(m_next_path[0])) { - ++m_next_path; - } - if (IsNullTerminator(m_next_path[0])) { - m_finished = true; - } - break; + size_t name_len; + for (name_len = 0; !RomPathTool::IsSeparator(cur[name_len]); ++name_len) { + if (RomPathTool::IsNullTerminator(cur[name_len])) { + m_finished = true; + m_prev_path_start = m_next_path; + m_next_path = cur + name_len; + m_prev_path_end = cur + name_len; + R_SUCCEED(); } + } - if (IsNullTerminator(cur[name_len])) { - m_finished = true; - m_next_path = cur + name_len; - m_prev_path_end = cur + name_len; - break; - } + /* Advance past separators. */ + m_prev_path_start = m_next_path; + m_prev_path_end = cur + name_len; + for (m_next_path = m_prev_path_end + 1; RomPathTool::IsSeparator(m_next_path[0]); ++m_next_path) { + /* ... */ + } + + /* Check if we're finished. */ + if (RomPathTool::IsNullTerminator(m_next_path[0])) { + m_finished = true; } R_SUCCEED(); @@ -106,11 +101,12 @@ namespace ams::fs::RomPathTool { AMS_ASSERT(m_prev_path_end != nullptr); AMS_ASSERT(m_next_path != nullptr); + AMS_ASSERT(m_prev_path_start <= m_prev_path_end); + const size_t len = m_prev_path_end - m_prev_path_start; R_UNLESS(len <= MaxPathLength, fs::ResultDbmDirectoryNameTooLong()); - out->length = len; - out->path = m_prev_path_start; + out->Initialize(m_prev_path_start, len); R_SUCCEED(); } @@ -120,11 +116,12 @@ namespace ams::fs::RomPathTool { AMS_ASSERT(m_prev_path_end != nullptr); AMS_ASSERT(m_next_path != nullptr); + AMS_ASSERT(m_prev_path_start <= m_prev_path_end); + const size_t len = m_prev_path_end - m_prev_path_start; R_UNLESS(len <= MaxPathLength, fs::ResultDbmFileNameTooLong()); - out->length = len; - out->path = m_prev_path_start; + out->Initialize(m_prev_path_start, len); R_SUCCEED(); } @@ -132,19 +129,18 @@ namespace ams::fs::RomPathTool { AMS_ASSERT(out != nullptr); AMS_ASSERT(p != nullptr); - const RomPathChar *start = cur.path; - const RomPathChar *end = cur.path + cur.length - 1; + const RomPathChar *start = cur.begin(); + const RomPathChar *end = cur.end() - 1; s32 depth = 1; - if (IsParentDirectory(cur)) { + if (cur.IsParentDirectory()) { ++depth; } - if (cur.path > p) { + if (start > p) { size_t len = 0; - const RomPathChar *head = cur.path - 1; - while (head >= p) { - if (IsSeparator(*head)) { + for (const RomPathChar *head = start - 1; head >= p; --head) { + if (RomPathTool::IsSeparator(*head)) { if (IsCurrentDirectory(head + 1, len)) { ++depth; } @@ -158,9 +154,9 @@ namespace ams::fs::RomPathTool { break; } - while (IsSeparator(*head)) { + do { --head; - } + } while (head > p && RomPathTool::IsSeparator(*head)); end = head; len = 0; @@ -168,22 +164,15 @@ namespace ams::fs::RomPathTool { } ++len; - --head; } R_UNLESS(depth == 0, fs::ResultDirectoryUnobtainable()); - - if (head == p) { - start = p + 1; - } } if (end <= p) { - out->path = p; - out->length = 0; + out->Initialize(p, 0); } else { - out->path = start; - out->length = end - start + 1; + out->Initialize(start, end - start + 1); } R_SUCCEED(); diff --git a/libraries/libstratosphere/source/fs/fs_romfs_filesystem.cpp b/libraries/libstratosphere/source/fs/fs_romfs_filesystem.cpp index 22c5bd4d2..0fbeefa1e 100644 --- a/libraries/libstratosphere/source/fs/fs_romfs_filesystem.cpp +++ b/libraries/libstratosphere/source/fs/fs_romfs_filesystem.cpp @@ -482,12 +482,10 @@ namespace ams::fs { } Result RomFsFileSystem::DoGetEntryType(fs::DirectoryEntryType *out, const fs::Path &path) { - RomDirectoryInfo dir_info; - R_TRY_CATCH(m_rom_file_table.GetDirectoryInformation(std::addressof(dir_info), path.GetString())) { + HierarchicalRomFileTable::FindPosition find_pos; + R_TRY_CATCH(m_rom_file_table.FindOpen(std::addressof(find_pos), path.GetString())) { R_CONVERT(fs::ResultDbmNotFound, fs::ResultPathNotFound()) R_CATCH(fs::ResultDbmInvalidOperation) { - RomFileTable::FileInfo file_info; - R_TRY(this->GetFileInfo(std::addressof(file_info), path.GetString())); *out = fs::DirectoryEntryType_File; R_SUCCEED(); } diff --git a/libraries/libstratosphere/source/fssystem/fssystem_romfs_filesystem.cpp b/libraries/libstratosphere/source/fssystem/fssystem_romfs_filesystem.cpp index 57a1c6556..50e7ba541 100644 --- a/libraries/libstratosphere/source/fssystem/fssystem_romfs_filesystem.cpp +++ b/libraries/libstratosphere/source/fssystem/fssystem_romfs_filesystem.cpp @@ -343,14 +343,11 @@ namespace ams::fssystem { R_TRY(this->CheckPathFormat(path)); R_TRY(buffers::DoContinuouslyUntilBufferIsAllocated([&]() -> Result { - fs::RomDirectoryInfo dir_info; + fs::HierarchicalRomFileTable::FindPosition find_pos; - R_TRY_CATCH(m_rom_file_table.GetDirectoryInformation(std::addressof(dir_info), path.GetString())) { + R_TRY_CATCH(m_rom_file_table.FindOpen(std::addressof(find_pos), path.GetString())) { R_CONVERT(fs::ResultDbmNotFound, fs::ResultPathNotFound()) R_CATCH(fs::ResultDbmInvalidOperation) { - RomFileTable::FileInfo file_info; - R_TRY(this->GetFileInfo(std::addressof(file_info), path)); - *out = fs::DirectoryEntryType_File; R_SUCCEED(); } diff --git a/libraries/libvapours/include/vapours/results/fs_results.hpp b/libraries/libvapours/include/vapours/results/fs_results.hpp index 8d3048c71..e47e9f55b 100644 --- a/libraries/libvapours/include/vapours/results/fs_results.hpp +++ b/libraries/libvapours/include/vapours/results/fs_results.hpp @@ -586,7 +586,7 @@ namespace ams::fs { R_DEFINE_ERROR_RANGE(DbmNotFound, 7901, 7904); R_DEFINE_ERROR_RESULT(DbmKeyNotFound, 7902); R_DEFINE_ERROR_RESULT(DbmFileNotFound, 7903); - R_DEFINE_ERROR_RESULT(DbmDirectoryNotFound, 7904); + R_DEFINE_ERROR_RESULT(DbmDirectoryNotFound, 7904); R_DEFINE_ERROR_RESULT(DbmAlreadyExists, 7906); R_DEFINE_ERROR_RESULT(DbmKeyFull, 7907);