mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2024-12-18 16:32:05 +00:00
fs: update romfs types
This commit is contained in:
parent
a8b52dc123
commit
28f11a86fd
9 changed files with 156 additions and 217 deletions
|
@ -20,10 +20,11 @@
|
||||||
|
|
||||||
namespace ams::fs {
|
namespace ams::fs {
|
||||||
|
|
||||||
/* ACCURATE_TO_VERSION: Unknown */
|
/* ACCURATE_TO_VERSION: 14.3.0.0 */
|
||||||
class HierarchicalRomFileTable {
|
class HierarchicalRomFileTable {
|
||||||
public:
|
public:
|
||||||
using Position = u32;
|
using Position = u32;
|
||||||
|
using StorageSizeType = u32;
|
||||||
|
|
||||||
struct FindPosition {
|
struct FindPosition {
|
||||||
Position next_dir;
|
Position next_dir;
|
||||||
|
@ -31,8 +32,7 @@ namespace ams::fs {
|
||||||
};
|
};
|
||||||
static_assert(util::is_pod<FindPosition>::value);
|
static_assert(util::is_pod<FindPosition>::value);
|
||||||
|
|
||||||
using DirectoryInfo = RomDirectoryInfo;
|
using FileInfo = RomFileInfo;
|
||||||
using FileInfo = RomFileInfo;
|
|
||||||
|
|
||||||
static constexpr RomFileId PositionToFileId(Position pos) {
|
static constexpr RomFileId PositionToFileId(Position pos) {
|
||||||
return static_cast<RomFileId>(pos);
|
return static_cast<RomFileId>(pos);
|
||||||
|
@ -81,11 +81,11 @@ namespace ams::fs {
|
||||||
using Base = KeyValueRomStorageTemplate<ImplKeyType, ValueType, MaxKeyLength>;
|
using Base = KeyValueRomStorageTemplate<ImplKeyType, ValueType, MaxKeyLength>;
|
||||||
public:
|
public:
|
||||||
Result Add(Position *out, const ClientKeyType &key, const Value &value) {
|
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) {
|
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) {
|
Result GetByPosition(ImplKey *out_key, Value *out_val, Position pos) {
|
||||||
|
@ -122,16 +122,15 @@ namespace ams::fs {
|
||||||
|
|
||||||
constexpr u32 Hash() const {
|
constexpr u32 Hash() const {
|
||||||
u32 hash = this->key.parent ^ 123456789;
|
u32 hash = this->key.parent ^ 123456789;
|
||||||
const RomPathChar * name = this->name.path;
|
const RomPathChar * cur = this->name.begin();
|
||||||
const RomPathChar * const end = name + this->name.length;
|
const RomPathChar * const end = this->name.end();
|
||||||
while (name < end) {
|
while (cur < end) {
|
||||||
const u32 cur = static_cast<u32>(static_cast<std::make_unsigned<RomPathChar>::type>(*(name++)));
|
const u32 c = static_cast<u32>(static_cast<std::make_unsigned<RomPathChar>::type>(*(cur++)));
|
||||||
hash = ((hash >> 5) | (hash << 27)) ^ cur;
|
hash = ((hash >> 5) | (hash << 27)) ^ c;
|
||||||
}
|
}
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
static_assert(util::is_pod<EntryKey>::value);
|
|
||||||
|
|
||||||
using DirectoryEntryMapTable = EntryMapTable<RomEntryKey, EntryKey, RomDirectoryEntry>;
|
using DirectoryEntryMapTable = EntryMapTable<RomEntryKey, EntryKey, RomDirectoryEntry>;
|
||||||
using FileEntryMapTable = EntryMapTable<RomEntryKey, EntryKey, RomFileEntry>;
|
using FileEntryMapTable = EntryMapTable<RomEntryKey, EntryKey, RomFileEntry>;
|
||||||
|
@ -139,35 +138,24 @@ namespace ams::fs {
|
||||||
DirectoryEntryMapTable m_dir_table;
|
DirectoryEntryMapTable m_dir_table;
|
||||||
FileEntryMapTable m_file_table;
|
FileEntryMapTable m_file_table;
|
||||||
public:
|
public:
|
||||||
static s64 QueryDirectoryEntryBucketStorageSize(s64 count);
|
static s64 QueryDirectoryEntryBucketStorageSize(StorageSizeType count);
|
||||||
static size_t QueryDirectoryEntrySize(size_t aux_size);
|
static s64 QueryDirectoryEntrySize(StorageSizeType aux_size);
|
||||||
static s64 QueryFileEntryBucketStorageSize(s64 count);
|
static s64 QueryFileEntryBucketStorageSize(StorageSizeType count);
|
||||||
static size_t QueryFileEntrySize(size_t aux_size);
|
static s64 QueryFileEntrySize(StorageSizeType aux_size);
|
||||||
|
|
||||||
static Result Format(SubStorage dir_bucket, SubStorage file_bucket);
|
static Result Format(SubStorage dir_bucket, SubStorage file_bucket);
|
||||||
public:
|
public:
|
||||||
HierarchicalRomFileTable();
|
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);
|
Result Initialize(SubStorage dir_bucket, SubStorage dir_entry, SubStorage file_bucket, SubStorage file_entry);
|
||||||
void Finalize();
|
void Finalize();
|
||||||
|
|
||||||
Result CreateRootDirectory();
|
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 CreateFile(RomFileId *out, const RomPathChar *path, const FileInfo &info);
|
||||||
Result ConvertPathToDirectoryId(RomDirectoryId *out, const RomPathChar *path);
|
Result ConvertPathToDirectoryId(RomDirectoryId *out, const RomPathChar *path);
|
||||||
Result ConvertPathToFileId(RomFileId *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, const RomPathChar *path);
|
||||||
Result OpenFile(FileInfo *out, RomFileId id);
|
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);
|
Result QueryRomFileSystemSize(s64 *out_dir_entry_size, s64 *out_file_entry_size);
|
||||||
private:
|
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);
|
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(Position *out_pos, RomFileEntry *out_entry, const EntryKey &key);
|
||||||
Result GetFileEntry(RomFileEntry *out_entry, RomFileId id);
|
Result GetFileEntry(RomFileEntry *out_entry, RomFileId id);
|
||||||
|
|
||||||
Result GetDirectoryInformation(DirectoryInfo *out, const EntryKey &key);
|
|
||||||
|
|
||||||
Result OpenFile(FileInfo *out, const EntryKey &key);
|
Result OpenFile(FileInfo *out, const EntryKey &key);
|
||||||
|
|
||||||
Result FindOpen(FindPosition *out, const EntryKey &key);
|
Result FindOpen(FindPosition *out, const EntryKey &key);
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
|
|
||||||
namespace ams::fs {
|
namespace ams::fs {
|
||||||
|
|
||||||
/* ACCURATE_TO_VERSION: Unknown */
|
/* ACCURATE_TO_VERSION: 14.3.0.0 */
|
||||||
template<typename KeyType, typename ValueType, size_t MaxAuxiliarySize>
|
template<typename KeyType, typename ValueType, size_t MaxAuxiliarySize>
|
||||||
class KeyValueRomStorageTemplate {
|
class KeyValueRomStorageTemplate {
|
||||||
public:
|
public:
|
||||||
|
@ -28,6 +28,8 @@ namespace ams::fs {
|
||||||
using Position = u32;
|
using Position = u32;
|
||||||
using BucketIndex = s64;
|
using BucketIndex = s64;
|
||||||
|
|
||||||
|
using StorageSizeType = u32;
|
||||||
|
|
||||||
struct FindIndex {
|
struct FindIndex {
|
||||||
BucketIndex ind;
|
BucketIndex ind;
|
||||||
Position pos;
|
Position pos;
|
||||||
|
@ -40,7 +42,7 @@ namespace ams::fs {
|
||||||
Key key;
|
Key key;
|
||||||
Value value;
|
Value value;
|
||||||
Position next;
|
Position next;
|
||||||
u32 size;
|
StorageSizeType size;
|
||||||
};
|
};
|
||||||
static_assert(util::is_pod<Element>::value);
|
static_assert(util::is_pod<Element>::value);
|
||||||
private:
|
private:
|
||||||
|
@ -54,23 +56,23 @@ namespace ams::fs {
|
||||||
return num * sizeof(Position);
|
return num * sizeof(Position);
|
||||||
}
|
}
|
||||||
|
|
||||||
static constexpr s64 QueryBucketCount(s64 size) {
|
static constexpr s64 QueryBucketCount(StorageSizeType size) {
|
||||||
return size / sizeof(Position);
|
return size / sizeof(Position);
|
||||||
}
|
}
|
||||||
|
|
||||||
static constexpr size_t QueryEntrySize(size_t aux_size) {
|
static constexpr size_t QueryEntrySize(StorageSizeType aux_size) {
|
||||||
return util::AlignUp(sizeof(Element) + aux_size, alignof(Element));
|
return util::AlignUp<size_t>(sizeof(Element) + aux_size, alignof(Element));
|
||||||
}
|
}
|
||||||
|
|
||||||
static Result Format(SubStorage bucket, s64 count) {
|
static Result Format(SubStorage bucket, StorageSizeType count) {
|
||||||
const Position pos = InvalidPosition;
|
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_TRY(bucket.Write(i * sizeof(pos), std::addressof(pos), sizeof(pos)));
|
||||||
}
|
}
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
public:
|
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) {
|
Result Initialize(const SubStorage &bucket, s64 count, const SubStorage &kv) {
|
||||||
AMS_ASSERT(count > 0);
|
AMS_ASSERT(count > 0);
|
||||||
|
@ -82,25 +84,13 @@ namespace ams::fs {
|
||||||
|
|
||||||
void Finalize() {
|
void Finalize() {
|
||||||
m_bucket_storage = SubStorage();
|
m_bucket_storage = SubStorage();
|
||||||
m_kv_storage = SubStorage();
|
|
||||||
m_bucket_count = 0;
|
m_bucket_count = 0;
|
||||||
|
m_kv_storage = SubStorage();
|
||||||
}
|
}
|
||||||
|
|
||||||
s64 GetTotalEntrySize() const {
|
s64 GetTotalEntrySize() const {
|
||||||
return m_total_entry_size;
|
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:
|
protected:
|
||||||
Result AddInternal(Position *out, const Key &key, u32 hash_key, const void *aux, size_t aux_size, const Value &value) {
|
Result AddInternal(Position *out, const Key &key, u32 hash_key, const void *aux, size_t aux_size, const Value &value) {
|
||||||
AMS_ASSERT(out != nullptr);
|
AMS_ASSERT(out != nullptr);
|
||||||
|
@ -117,12 +107,12 @@ namespace ams::fs {
|
||||||
}
|
}
|
||||||
|
|
||||||
Position pos;
|
Position pos;
|
||||||
R_TRY(this->AllocateEntry(std::addressof(pos), aux_size));
|
R_TRY(this->AllocateEntry(std::addressof(pos), static_cast<StorageSizeType>(aux_size)));
|
||||||
|
|
||||||
Position next_pos;
|
Position next_pos;
|
||||||
R_TRY(this->LinkEntry(std::addressof(next_pos), pos, hash_key));
|
R_TRY(this->LinkEntry(std::addressof(next_pos), pos, hash_key));
|
||||||
|
|
||||||
const Element elem = { key, value, next_pos, static_cast<u32>(aux_size) };
|
const Element elem = { key, value, next_pos, static_cast<StorageSizeType>(aux_size) };
|
||||||
R_TRY(this->WriteKeyValue(std::addressof(elem), pos, aux, aux_size));
|
R_TRY(this->WriteKeyValue(std::addressof(elem), pos, aux, aux_size));
|
||||||
|
|
||||||
*out = pos;
|
*out = pos;
|
||||||
|
@ -203,15 +193,14 @@ namespace ams::fs {
|
||||||
|
|
||||||
R_UNLESS(cur != InvalidPosition, fs::ResultDbmKeyNotFound());
|
R_UNLESS(cur != InvalidPosition, fs::ResultDbmKeyNotFound());
|
||||||
|
|
||||||
u8 *buf = static_cast<u8 *>(::ams::fs::impl::Allocate(MaxAuxiliarySize));
|
auto buf = ::ams::fs::impl::MakeUnique<u8[]>(MaxAuxiliarySize);
|
||||||
R_UNLESS(buf != nullptr, fs::ResultAllocationMemoryFailedInDbmRomKeyValueStorage());
|
R_UNLESS(buf != nullptr, fs::ResultAllocationMemoryFailedMakeUnique());
|
||||||
ON_SCOPE_EXIT { ::ams::fs::impl::Deallocate(buf, MaxAuxiliarySize); };
|
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
size_t cur_aux_size;
|
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;
|
*out_pos = cur;
|
||||||
R_SUCCEED();
|
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);
|
AMS_ASSERT(out != nullptr);
|
||||||
|
|
||||||
s64 kv_size;
|
s64 kv_size;
|
||||||
R_TRY(m_kv_storage.GetSize(std::addressof(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<size_t>(aux_size);
|
||||||
R_UNLESS(end_pos <= static_cast<size_t>(kv_size), fs::ResultDbmKeyFull());
|
R_UNLESS(end_pos <= static_cast<size_t>(kv_size), fs::ResultDbmKeyFull());
|
||||||
|
|
||||||
*out = static_cast<Position>(m_total_entry_size);
|
*out = static_cast<Position>(m_total_entry_size);
|
||||||
|
|
||||||
m_total_entry_size = util::AlignUp(static_cast<s64>(end_pos), alignof(Position));
|
m_total_entry_size = util::AlignUp<s64>(static_cast<s64>(end_pos), alignof(Position));
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,36 +18,60 @@
|
||||||
|
|
||||||
namespace ams::fs::RomPathTool {
|
namespace ams::fs::RomPathTool {
|
||||||
|
|
||||||
/* ACCURATE_TO_VERSION: Unknown */
|
/* ACCURATE_TO_VERSION: 14.3.0.0 */
|
||||||
|
|
||||||
constexpr inline u32 MaxPathLength = 0x300;
|
constexpr inline u32 MaxPathLength = 0x300;
|
||||||
|
|
||||||
struct RomEntryName {
|
constexpr ALWAYS_INLINE bool IsSeparator(RomPathChar c) {
|
||||||
size_t length;
|
|
||||||
const RomPathChar *path;
|
|
||||||
};
|
|
||||||
static_assert(util::is_pod<RomEntryName>::value);
|
|
||||||
|
|
||||||
constexpr void InitEntryName(RomEntryName *entry) {
|
|
||||||
AMS_ASSERT(entry != nullptr);
|
|
||||||
entry->length = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr inline bool IsSeparator(RomPathChar c) {
|
|
||||||
return c == RomStringTraits::DirectorySeparator;
|
return c == RomStringTraits::DirectorySeparator;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr inline bool IsNullTerminator(RomPathChar c) {
|
constexpr ALWAYS_INLINE bool IsNullTerminator(RomPathChar c) {
|
||||||
return c == RomStringTraits::NullTerminator;
|
return c == RomStringTraits::NullTerminator;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr inline bool IsDot(RomPathChar c) {
|
constexpr ALWAYS_INLINE bool IsDot(RomPathChar c) {
|
||||||
return c == RomStringTraits::Dot;
|
return c == RomStringTraits::Dot;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr inline bool IsCurrentDirectory(const RomEntryName &name) {
|
class RomEntryName {
|
||||||
return name.length == 1 && IsDot(name.path[0]);
|
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) {
|
constexpr inline bool IsCurrentDirectory(const RomPathChar *p, size_t length) {
|
||||||
AMS_ASSERT(p != nullptr);
|
AMS_ASSERT(p != nullptr);
|
||||||
|
@ -59,10 +83,6 @@ namespace ams::fs::RomPathTool {
|
||||||
return IsDot(p[0]) && IsNullTerminator(p[1]);
|
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) {
|
constexpr inline bool IsParentDirectory(const RomPathChar *p) {
|
||||||
AMS_ASSERT(p != nullptr);
|
AMS_ASSERT(p != nullptr);
|
||||||
return IsDot(p[0]) && IsDot(p[1]) && IsNullTerminator(p[2]);
|
return IsDot(p[0]) && IsDot(p[1]) && IsNullTerminator(p[2]);
|
||||||
|
|
|
@ -18,10 +18,10 @@
|
||||||
|
|
||||||
namespace ams::fs {
|
namespace ams::fs {
|
||||||
|
|
||||||
/* ACCURATE_TO_VERSION: Unknown */
|
/* ACCURATE_TO_VERSION: 14.3.0.0 */
|
||||||
using RomPathChar = char;
|
using RomPathChar = char;
|
||||||
using RomFileId = s32;
|
using RomFileId = u32;
|
||||||
using RomDirectoryId = s32;
|
using RomDirectoryId = u32;
|
||||||
|
|
||||||
struct RomFileSystemInformation {
|
struct RomFileSystemInformation {
|
||||||
s64 size;
|
s64 size;
|
||||||
|
@ -38,11 +38,6 @@ namespace ams::fs {
|
||||||
static_assert(util::is_pod<RomFileSystemInformation>::value);
|
static_assert(util::is_pod<RomFileSystemInformation>::value);
|
||||||
static_assert(sizeof(RomFileSystemInformation) == 0x50);
|
static_assert(sizeof(RomFileSystemInformation) == 0x50);
|
||||||
|
|
||||||
struct RomDirectoryInfo {
|
|
||||||
/* ... */
|
|
||||||
};
|
|
||||||
static_assert(util::is_pod<RomDirectoryInfo>::value);
|
|
||||||
|
|
||||||
struct RomFileInfo {
|
struct RomFileInfo {
|
||||||
Int64 offset;
|
Int64 offset;
|
||||||
Int64 size;
|
Int64 size;
|
||||||
|
|
|
@ -17,19 +17,19 @@
|
||||||
|
|
||||||
namespace ams::fs {
|
namespace ams::fs {
|
||||||
|
|
||||||
s64 HierarchicalRomFileTable::QueryDirectoryEntryBucketStorageSize(s64 count) {
|
s64 HierarchicalRomFileTable::QueryDirectoryEntryBucketStorageSize(StorageSizeType count) {
|
||||||
return DirectoryEntryMapTable::QueryBucketStorageSize(count);
|
return DirectoryEntryMapTable::QueryBucketStorageSize(count);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t HierarchicalRomFileTable::QueryDirectoryEntrySize(size_t aux_size) {
|
s64 HierarchicalRomFileTable::QueryDirectoryEntrySize(StorageSizeType aux_size) {
|
||||||
return DirectoryEntryMapTable::QueryEntrySize(aux_size);
|
return DirectoryEntryMapTable::QueryEntrySize(aux_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
s64 HierarchicalRomFileTable::QueryFileEntryBucketStorageSize(s64 count) {
|
s64 HierarchicalRomFileTable::QueryFileEntryBucketStorageSize(StorageSizeType count) {
|
||||||
return FileEntryMapTable::QueryBucketStorageSize(count);
|
return FileEntryMapTable::QueryBucketStorageSize(count);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t HierarchicalRomFileTable::QueryFileEntrySize(size_t aux_size) {
|
s64 HierarchicalRomFileTable::QueryFileEntrySize(StorageSizeType aux_size) {
|
||||||
return FileEntryMapTable::QueryEntrySize(aux_size);
|
return FileEntryMapTable::QueryEntrySize(aux_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,7 +68,6 @@ namespace ams::fs {
|
||||||
Position root_pos = RootPosition;
|
Position root_pos = RootPosition;
|
||||||
EntryKey root_key = {};
|
EntryKey root_key = {};
|
||||||
root_key.key.parent = root_pos;
|
root_key.key.parent = root_pos;
|
||||||
RomPathTool::InitEntryName(std::addressof(root_key.name));
|
|
||||||
RomDirectoryEntry root_entry = {
|
RomDirectoryEntry root_entry = {
|
||||||
.next = InvalidPosition,
|
.next = InvalidPosition,
|
||||||
.dir = InvalidPosition,
|
.dir = InvalidPosition,
|
||||||
|
@ -77,7 +76,7 @@ namespace ams::fs {
|
||||||
R_RETURN(m_dir_table.Add(std::addressof(root_pos), root_key, root_entry));
|
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(out != nullptr);
|
||||||
AMS_ASSERT(path != nullptr);
|
AMS_ASSERT(path != nullptr);
|
||||||
|
|
||||||
|
@ -92,7 +91,6 @@ namespace ams::fs {
|
||||||
.dir = InvalidPosition,
|
.dir = InvalidPosition,
|
||||||
.file = InvalidPosition,
|
.file = InvalidPosition,
|
||||||
};
|
};
|
||||||
AMS_UNUSED(info);
|
|
||||||
|
|
||||||
Position new_pos = 0;
|
Position new_pos = 0;
|
||||||
R_TRY_CATCH(m_dir_table.Add(std::addressof(new_pos), new_key, new_entry)) {
|
R_TRY_CATCH(m_dir_table.Add(std::addressof(new_pos), new_key, new_entry)) {
|
||||||
|
@ -205,28 +203,6 @@ namespace ams::fs {
|
||||||
R_SUCCEED();
|
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) {
|
Result HierarchicalRomFileTable::OpenFile(FileInfo *out, const RomPathChar *path) {
|
||||||
AMS_ASSERT(out != nullptr);
|
AMS_ASSERT(out != nullptr);
|
||||||
AMS_ASSERT(path != nullptr);
|
AMS_ASSERT(path != nullptr);
|
||||||
|
@ -318,22 +294,22 @@ namespace ams::fs {
|
||||||
AMS_ASSERT(out_dir_entry_size != nullptr);
|
AMS_ASSERT(out_dir_entry_size != nullptr);
|
||||||
AMS_ASSERT(out_file_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();
|
*out_file_entry_size = m_file_table.GetTotalEntrySize();
|
||||||
R_SUCCEED();
|
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_pos != nullptr);
|
||||||
AMS_ASSERT(out_dir_key != nullptr);
|
AMS_ASSERT(out_dir_key != nullptr);
|
||||||
AMS_ASSERT(out_dir_entry != nullptr);
|
AMS_ASSERT(out_dir_entry != nullptr);
|
||||||
AMS_ASSERT(path != nullptr);
|
AMS_ASSERT(path != nullptr);
|
||||||
|
|
||||||
RomEntryKey gp_key = {};
|
RomEntryKey p_key = {};
|
||||||
RomDirectoryEntry gp_entry = {};
|
RomDirectoryEntry p_entry = {};
|
||||||
R_TRY(m_dir_table.GetByPosition(std::addressof(gp_key), std::addressof(gp_entry), pos));
|
R_TRY(m_dir_table.GetByPosition(std::addressof(p_key), std::addressof(p_entry), pos));
|
||||||
out_dir_key->key.parent = gp_key.parent;
|
|
||||||
|
|
||||||
|
out_dir_key->key = p_key;
|
||||||
R_TRY(RomPathTool::GetParentDirectoryName(std::addressof(out_dir_key->name), name, path));
|
R_TRY(RomPathTool::GetParentDirectoryName(std::addressof(out_dir_key->name), name, path));
|
||||||
|
|
||||||
R_TRY(this->GetDirectoryEntry(out_pos, out_dir_entry, *out_dir_key));
|
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)));
|
R_TRY(parser->GetNextDirectoryName(std::addressof(dir_key.name)));
|
||||||
|
|
||||||
if (RomPathTool::IsCurrentDirectory(dir_key.name)) {
|
if (dir_key.name.IsCurrentDirectory()) {
|
||||||
dir_key = old_key;
|
dir_key = old_key;
|
||||||
continue;
|
continue;
|
||||||
} else if (RomPathTool::IsParentDirectory(dir_key.name)) {
|
} else if (dir_key.name.IsParentDirectory()) {
|
||||||
R_UNLESS(parent_pos != RootPosition, fs::ResultDirectoryUnobtainable());
|
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 {
|
} else {
|
||||||
dir_key.key.parent = parent_pos;
|
dir_key.key.parent = parent_pos;
|
||||||
R_TRY_CATCH(this->GetDirectoryEntry(std::addressof(dir_pos), std::addressof(dir_entry), dir_key)) {
|
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 = {};
|
RomPathTool::RomEntryName name = {};
|
||||||
R_TRY(parser.GetAsDirectoryName(std::addressof(name)));
|
R_TRY(parser.GetAsDirectoryName(std::addressof(name)));
|
||||||
|
|
||||||
if (RomPathTool::IsCurrentDirectory(name)) {
|
if (name.IsCurrentDirectory()) {
|
||||||
*out_key = parent_key;
|
*out_key = parent_key;
|
||||||
if (out_key->key.parent != RootPosition) {
|
if (out_key->key.parent != RootPosition) {
|
||||||
Position pos = 0;
|
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());
|
R_UNLESS(parent_pos != RootPosition, fs::ResultDirectoryUnobtainable());
|
||||||
|
|
||||||
Position pos = 0;
|
Position pos = 0;
|
||||||
RomDirectoryEntry cur_entry = {};
|
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) {
|
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 {
|
} else {
|
||||||
out_key->name = name;
|
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 {
|
} else {
|
||||||
{
|
{
|
||||||
RomPathTool::RomEntryName name = {};
|
RomPathTool::RomEntryName name = {};
|
||||||
R_TRY(parser.GetAsDirectoryName(std::addressof(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());
|
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);
|
const Result get_res = m_dir_table.Get(std::addressof(pos), std::addressof(entry), key);
|
||||||
if (!fs::ResultDbmKeyNotFound::Includes(get_res)) {
|
if (!fs::ResultDbmKeyNotFound::Includes(get_res)) {
|
||||||
R_TRY(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);
|
const Result get_res = m_file_table.Get(std::addressof(pos), std::addressof(entry), key);
|
||||||
if (!fs::ResultDbmKeyNotFound::Includes(get_res)) {
|
if (!fs::ResultDbmKeyNotFound::Includes(get_res)) {
|
||||||
R_TRY(get_res);
|
R_TRY(get_res);
|
||||||
R_RETURN(if_exists);
|
R_THROW(if_exists);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -542,18 +519,6 @@ namespace ams::fs {
|
||||||
R_RETURN(dir_res);
|
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) {
|
Result HierarchicalRomFileTable::OpenFile(FileInfo *out, const EntryKey &key) {
|
||||||
AMS_ASSERT(out != nullptr);
|
AMS_ASSERT(out != nullptr);
|
||||||
|
|
||||||
|
|
|
@ -21,16 +21,14 @@ namespace ams::fs::RomPathTool {
|
||||||
AMS_ASSERT(path != nullptr);
|
AMS_ASSERT(path != nullptr);
|
||||||
|
|
||||||
/* Require paths start with a separator, and skip repeated separators. */
|
/* Require paths start with a separator, and skip repeated separators. */
|
||||||
R_UNLESS(IsSeparator(path[0]), fs::ResultDbmInvalidPathFormat());
|
R_UNLESS(RomPathTool::IsSeparator(path[0]), fs::ResultDbmInvalidPathFormat());
|
||||||
while (IsSeparator(path[1])) {
|
while (RomPathTool::IsSeparator(path[1])) {
|
||||||
path++;
|
++path;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_prev_path_start = path;
|
m_prev_path_start = path;
|
||||||
m_prev_path_end = 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();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
@ -49,52 +47,49 @@ namespace ams::fs::RomPathTool {
|
||||||
bool PathParser::IsDirectoryPath() const {
|
bool PathParser::IsDirectoryPath() const {
|
||||||
AMS_ASSERT(m_next_path != nullptr);
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsCurrentDirectory(m_next_path)) {
|
if (RomPathTool::IsCurrentDirectory(m_next_path)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return IsParentDirectory(m_next_path);
|
return RomPathTool::IsParentDirectory(m_next_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result PathParser::GetNextDirectoryName(RomEntryName *out) {
|
Result PathParser::GetNextDirectoryName(RomEntryName *out) {
|
||||||
AMS_ASSERT(out != nullptr);
|
|
||||||
AMS_ASSERT(m_prev_path_start != nullptr);
|
AMS_ASSERT(m_prev_path_start != nullptr);
|
||||||
AMS_ASSERT(m_prev_path_end != nullptr);
|
AMS_ASSERT(m_prev_path_end != nullptr);
|
||||||
AMS_ASSERT(m_next_path != nullptr);
|
AMS_ASSERT(m_next_path != nullptr);
|
||||||
|
AMS_ASSERT(out != nullptr);
|
||||||
|
|
||||||
/* Set the current path to output. */
|
/* Get as directory name. */
|
||||||
out->length = m_prev_path_end - m_prev_path_start;
|
R_TRY(this->GetAsDirectoryName(out));
|
||||||
out->path = m_prev_path_start;
|
|
||||||
|
|
||||||
/* Parse the next path. */
|
/* Parse the next path. */
|
||||||
m_prev_path_start = m_next_path;
|
|
||||||
const RomPathChar *cur = m_next_path;
|
const RomPathChar *cur = m_next_path;
|
||||||
for (size_t name_len = 0; true; name_len++) {
|
size_t name_len;
|
||||||
if (IsSeparator(cur[name_len])) {
|
for (name_len = 0; !RomPathTool::IsSeparator(cur[name_len]); ++name_len) {
|
||||||
R_UNLESS(name_len < MaxPathLength, fs::ResultDbmDirectoryNameTooLong());
|
if (RomPathTool::IsNullTerminator(cur[name_len])) {
|
||||||
|
m_finished = true;
|
||||||
m_prev_path_end = cur + name_len;
|
m_prev_path_start = m_next_path;
|
||||||
m_next_path = m_prev_path_end + 1;
|
m_next_path = cur + name_len;
|
||||||
|
m_prev_path_end = cur + name_len;
|
||||||
while (IsSeparator(m_next_path[0])) {
|
R_SUCCEED();
|
||||||
++m_next_path;
|
|
||||||
}
|
|
||||||
if (IsNullTerminator(m_next_path[0])) {
|
|
||||||
m_finished = true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (IsNullTerminator(cur[name_len])) {
|
/* Advance past separators. */
|
||||||
m_finished = true;
|
m_prev_path_start = m_next_path;
|
||||||
m_next_path = cur + name_len;
|
m_prev_path_end = cur + name_len;
|
||||||
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) {
|
||||||
break;
|
/* ... */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check if we're finished. */
|
||||||
|
if (RomPathTool::IsNullTerminator(m_next_path[0])) {
|
||||||
|
m_finished = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
|
@ -106,11 +101,12 @@ namespace ams::fs::RomPathTool {
|
||||||
AMS_ASSERT(m_prev_path_end != nullptr);
|
AMS_ASSERT(m_prev_path_end != nullptr);
|
||||||
AMS_ASSERT(m_next_path != 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;
|
const size_t len = m_prev_path_end - m_prev_path_start;
|
||||||
R_UNLESS(len <= MaxPathLength, fs::ResultDbmDirectoryNameTooLong());
|
R_UNLESS(len <= MaxPathLength, fs::ResultDbmDirectoryNameTooLong());
|
||||||
|
|
||||||
out->length = len;
|
out->Initialize(m_prev_path_start, len);
|
||||||
out->path = m_prev_path_start;
|
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,11 +116,12 @@ namespace ams::fs::RomPathTool {
|
||||||
AMS_ASSERT(m_prev_path_end != nullptr);
|
AMS_ASSERT(m_prev_path_end != nullptr);
|
||||||
AMS_ASSERT(m_next_path != 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;
|
const size_t len = m_prev_path_end - m_prev_path_start;
|
||||||
R_UNLESS(len <= MaxPathLength, fs::ResultDbmFileNameTooLong());
|
R_UNLESS(len <= MaxPathLength, fs::ResultDbmFileNameTooLong());
|
||||||
|
|
||||||
out->length = len;
|
out->Initialize(m_prev_path_start, len);
|
||||||
out->path = m_prev_path_start;
|
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,19 +129,18 @@ namespace ams::fs::RomPathTool {
|
||||||
AMS_ASSERT(out != nullptr);
|
AMS_ASSERT(out != nullptr);
|
||||||
AMS_ASSERT(p != nullptr);
|
AMS_ASSERT(p != nullptr);
|
||||||
|
|
||||||
const RomPathChar *start = cur.path;
|
const RomPathChar *start = cur.begin();
|
||||||
const RomPathChar *end = cur.path + cur.length - 1;
|
const RomPathChar *end = cur.end() - 1;
|
||||||
|
|
||||||
s32 depth = 1;
|
s32 depth = 1;
|
||||||
if (IsParentDirectory(cur)) {
|
if (cur.IsParentDirectory()) {
|
||||||
++depth;
|
++depth;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cur.path > p) {
|
if (start > p) {
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
const RomPathChar *head = cur.path - 1;
|
for (const RomPathChar *head = start - 1; head >= p; --head) {
|
||||||
while (head >= p) {
|
if (RomPathTool::IsSeparator(*head)) {
|
||||||
if (IsSeparator(*head)) {
|
|
||||||
if (IsCurrentDirectory(head + 1, len)) {
|
if (IsCurrentDirectory(head + 1, len)) {
|
||||||
++depth;
|
++depth;
|
||||||
}
|
}
|
||||||
|
@ -158,9 +154,9 @@ namespace ams::fs::RomPathTool {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (IsSeparator(*head)) {
|
do {
|
||||||
--head;
|
--head;
|
||||||
}
|
} while (head > p && RomPathTool::IsSeparator(*head));
|
||||||
|
|
||||||
end = head;
|
end = head;
|
||||||
len = 0;
|
len = 0;
|
||||||
|
@ -168,22 +164,15 @@ namespace ams::fs::RomPathTool {
|
||||||
}
|
}
|
||||||
|
|
||||||
++len;
|
++len;
|
||||||
--head;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
R_UNLESS(depth == 0, fs::ResultDirectoryUnobtainable());
|
R_UNLESS(depth == 0, fs::ResultDirectoryUnobtainable());
|
||||||
|
|
||||||
if (head == p) {
|
|
||||||
start = p + 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (end <= p) {
|
if (end <= p) {
|
||||||
out->path = p;
|
out->Initialize(p, 0);
|
||||||
out->length = 0;
|
|
||||||
} else {
|
} else {
|
||||||
out->path = start;
|
out->Initialize(start, end - start + 1);
|
||||||
out->length = end - start + 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
|
|
|
@ -482,12 +482,10 @@ namespace ams::fs {
|
||||||
}
|
}
|
||||||
|
|
||||||
Result RomFsFileSystem::DoGetEntryType(fs::DirectoryEntryType *out, const fs::Path &path) {
|
Result RomFsFileSystem::DoGetEntryType(fs::DirectoryEntryType *out, const fs::Path &path) {
|
||||||
RomDirectoryInfo dir_info;
|
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_CONVERT(fs::ResultDbmNotFound, fs::ResultPathNotFound())
|
||||||
R_CATCH(fs::ResultDbmInvalidOperation) {
|
R_CATCH(fs::ResultDbmInvalidOperation) {
|
||||||
RomFileTable::FileInfo file_info;
|
|
||||||
R_TRY(this->GetFileInfo(std::addressof(file_info), path.GetString()));
|
|
||||||
*out = fs::DirectoryEntryType_File;
|
*out = fs::DirectoryEntryType_File;
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
|
@ -343,14 +343,11 @@ namespace ams::fssystem {
|
||||||
R_TRY(this->CheckPathFormat(path));
|
R_TRY(this->CheckPathFormat(path));
|
||||||
|
|
||||||
R_TRY(buffers::DoContinuouslyUntilBufferIsAllocated([&]() -> Result {
|
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_CONVERT(fs::ResultDbmNotFound, fs::ResultPathNotFound())
|
||||||
R_CATCH(fs::ResultDbmInvalidOperation) {
|
R_CATCH(fs::ResultDbmInvalidOperation) {
|
||||||
RomFileTable::FileInfo file_info;
|
|
||||||
R_TRY(this->GetFileInfo(std::addressof(file_info), path));
|
|
||||||
|
|
||||||
*out = fs::DirectoryEntryType_File;
|
*out = fs::DirectoryEntryType_File;
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
|
@ -586,7 +586,7 @@ namespace ams::fs {
|
||||||
R_DEFINE_ERROR_RANGE(DbmNotFound, 7901, 7904);
|
R_DEFINE_ERROR_RANGE(DbmNotFound, 7901, 7904);
|
||||||
R_DEFINE_ERROR_RESULT(DbmKeyNotFound, 7902);
|
R_DEFINE_ERROR_RESULT(DbmKeyNotFound, 7902);
|
||||||
R_DEFINE_ERROR_RESULT(DbmFileNotFound, 7903);
|
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(DbmAlreadyExists, 7906);
|
||||||
R_DEFINE_ERROR_RESULT(DbmKeyFull, 7907);
|
R_DEFINE_ERROR_RESULT(DbmKeyFull, 7907);
|
||||||
|
|
Loading…
Reference in a new issue