mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2025-06-05 01:03:43 -04:00
fs/system: deduplicate RomFs code
This commit is contained in:
parent
c45088d1cd
commit
73167448cc
16 changed files with 226 additions and 1723 deletions
|
@ -14,9 +14,9 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
#include "fs_dbm_rom_types.hpp"
|
||||
#include "fs_dbm_rom_path_tool.hpp"
|
||||
#include "fs_dbm_rom_key_value_storage.hpp"
|
||||
#include <stratosphere/fs/common/fs_dbm_rom_types.hpp>
|
||||
#include <stratosphere/fs/common/fs_dbm_rom_path_tool.hpp>
|
||||
#include <stratosphere/fs/common/fs_dbm_rom_key_value_storage.hpp>
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
|
@ -33,19 +33,23 @@ namespace ams::fs {
|
|||
using DirectoryInfo = RomDirectoryInfo;
|
||||
using FileInfo = RomFileInfo;
|
||||
|
||||
static constexpr RomFileId ConvertToFileId(Position pos) {
|
||||
static constexpr RomFileId PositionToFileId(Position pos) {
|
||||
return static_cast<RomFileId>(pos);
|
||||
}
|
||||
|
||||
static constexpr Position FileIdToPosition(RomFileId id) {
|
||||
return static_cast<Position>(id);
|
||||
}
|
||||
private:
|
||||
static constexpr inline Position InvalidPosition = ~Position();
|
||||
static constexpr inline Position RootPosition = 0;
|
||||
static constexpr inline size_t ReservedDirectoryCount = 1;
|
||||
|
||||
static constexpr RomDirectoryId ConvertToDirectoryId(Position pos) {
|
||||
static constexpr RomDirectoryId PositionToDirectoryId(Position pos) {
|
||||
return static_cast<RomDirectoryId>(pos);
|
||||
}
|
||||
|
||||
static constexpr Position ConvertToPosition(RomDirectoryId id) {
|
||||
static constexpr Position DirectoryIdToPosition(RomDirectoryId id) {
|
||||
return static_cast<Position>(id);
|
||||
}
|
||||
|
||||
|
@ -67,20 +71,20 @@ namespace ams::fs {
|
|||
static constexpr inline u32 MaxKeyLength = RomPathTool::MaxPathLength;
|
||||
|
||||
template<typename ImplKeyType, typename ClientKeyType, typename ValueType>
|
||||
class EntryMapTable : public RomKeyValueStorage<ImplKeyType, ValueType, MaxKeyLength> {
|
||||
class EntryMapTable : public KeyValueRomStorageTemplate<ImplKeyType, ValueType, MaxKeyLength> {
|
||||
public:
|
||||
using ImplKey = ImplKeyType;
|
||||
using ClientKey = ClientKeyType;
|
||||
using Value = ValueType;
|
||||
using Position = HierarchicalRomFileTable::Position;
|
||||
using Base = RomKeyValueStorage<ImplKeyType, ValueType, MaxKeyLength>;
|
||||
using Base = KeyValueRomStorageTemplate<ImplKeyType, ValueType, MaxKeyLength>;
|
||||
public:
|
||||
Result Add(Position *out, const ClientKeyType &key, const Value &value) {
|
||||
return Base::AddImpl(out, key.key, key.Hash(), key.name.path, key.name.length * sizeof(RomPathChar), value);
|
||||
return Base::AddInternal(out, key.key, key.Hash(), key.name.path, key.name.length * sizeof(RomPathChar), value);
|
||||
}
|
||||
|
||||
Result Get(Position *out_pos, Value *out_val, const ClientKeyType &key) {
|
||||
return Base::GetImpl(out_pos, out_val, key.key, key.Hash(), key.name.path, key.name.length * sizeof(RomPathChar));
|
||||
return Base::GetInternal(out_pos, out_val, key.key, key.Hash(), key.name.path, key.name.length * sizeof(RomPathChar));
|
||||
}
|
||||
|
||||
Result GetByPosition(ImplKey *out_key, Value *out_val, Position pos) {
|
||||
|
@ -117,8 +121,8 @@ namespace ams::fs {
|
|||
|
||||
constexpr u32 Hash() const {
|
||||
u32 hash = this->key.parent ^ 123456789;
|
||||
const RomPathChar *name = this->name.path;
|
||||
const RomPathChar *end = name + this->name.length;
|
||||
const RomPathChar * name = this->name.path;
|
||||
const RomPathChar * const end = name + this->name.length;
|
||||
while (name < end) {
|
||||
const u32 cur = static_cast<u32>(static_cast<std::make_unsigned<RomPathChar>::type>(*(name++)));
|
||||
hash = ((hash >> 5) | (hash << 27)) ^ cur;
|
||||
|
@ -134,10 +138,10 @@ namespace ams::fs {
|
|||
DirectoryEntryMapTable dir_table;
|
||||
FileEntryMapTable file_table;
|
||||
public:
|
||||
static s64 QueryDirectoryEntryStorageSize(u32 count);
|
||||
static s64 QueryDirectoryEntryBucketStorageSize(s64 count);
|
||||
static s64 QueryFileEntryStorageSize(u32 count);
|
||||
static size_t QueryDirectoryEntrySize(size_t aux_size);
|
||||
static s64 QueryFileEntryBucketStorageSize(s64 count);
|
||||
static size_t QueryFileEntrySize(size_t aux_size);
|
||||
|
||||
static Result Format(SubStorage dir_bucket, SubStorage file_bucket);
|
||||
public:
|
|
@ -14,13 +14,13 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
#include "fs_dbm_rom_types.hpp"
|
||||
#include "fs_substorage.hpp"
|
||||
#include <stratosphere/fs/common/fs_dbm_rom_types.hpp>
|
||||
#include <stratosphere/fs/fs_substorage.hpp>
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
template<typename KeyType, typename ValueType, size_t MaxAuxiliarySize>
|
||||
class RomKeyValueStorage {
|
||||
class KeyValueRomStorageTemplate {
|
||||
public:
|
||||
using Key = KeyType;
|
||||
using Value = ValueType;
|
||||
|
@ -57,8 +57,8 @@ namespace ams::fs {
|
|||
return size / sizeof(Position);
|
||||
}
|
||||
|
||||
static constexpr s64 QueryKeyValueStorageSize(u32 num) {
|
||||
return num * sizeof(Element);
|
||||
static constexpr size_t QueryEntrySize(size_t aux_size) {
|
||||
return util::AlignUp(sizeof(Element) + aux_size, alignof(Element));
|
||||
}
|
||||
|
||||
static Result Format(SubStorage bucket, s64 count) {
|
||||
|
@ -69,13 +69,13 @@ namespace ams::fs {
|
|||
return ResultSuccess();
|
||||
}
|
||||
public:
|
||||
RomKeyValueStorage() : bucket_count(), bucket_storage(), kv_storage(), total_entry_size(), entry_count() { /* ... */ }
|
||||
KeyValueRomStorageTemplate() : bucket_count(), bucket_storage(), kv_storage(), total_entry_size(), entry_count() { /* ... */ }
|
||||
|
||||
Result Initialize(const SubStorage &bucket, s64 count, const SubStorage &kv) {
|
||||
AMS_ASSERT(count > 0);
|
||||
this->bucket_storage = bucket;
|
||||
this->kv_storage = kv;
|
||||
this->bucket_count = count;
|
||||
this->kv_storage = kv;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
|
@ -100,82 +100,17 @@ namespace ams::fs {
|
|||
constexpr u32 GetEntryCount() const {
|
||||
return this->entry_count;
|
||||
}
|
||||
|
||||
Result Add(const Key &key, u32 hash_key, const void *aux, size_t aux_size, const Value &value) {
|
||||
AMS_ASSERT(aux != nullptr);
|
||||
AMS_ASSERT(aux_size <= MaxAuxiliarySize);
|
||||
Position pos;
|
||||
return this->AddImpl(std::addressof(pos), key, hash_key, aux, aux_size, value);
|
||||
}
|
||||
|
||||
Result Get(Value *out, const Key &key, u32 hash_key, const void *aux, size_t aux_size) {
|
||||
AMS_ASSERT(aux != nullptr);
|
||||
AMS_ASSERT(aux_size <= MaxAuxiliarySize);
|
||||
Position pos;
|
||||
return this->GetImpl(std::addressof(pos), out, key, hash_key, aux, aux_size);
|
||||
}
|
||||
|
||||
void FindOpen(FindIndex *out) const {
|
||||
AMS_ASSERT(out != nullptr);
|
||||
|
||||
out->ind = static_cast<BucketIndex>(-1);
|
||||
out->pos = InvalidPosition;
|
||||
}
|
||||
|
||||
Result FindNext(Key *out_key, Value *out_val, FindIndex *find) {
|
||||
AMS_ASSERT(out_key != nullptr);
|
||||
AMS_ASSERT(out_val != nullptr);
|
||||
AMS_ASSERT(find != nullptr);
|
||||
|
||||
BucketIndex ind = find->ind;
|
||||
R_UNLESS((ind < this->bucket_count) || ind == static_cast<BucketIndex>(-1), fs::ResultDbmFindKeyFinished());
|
||||
|
||||
s64 kv_size;
|
||||
R_TRY(this->kv_storage.GetSize(std::addressof(kv_size)));
|
||||
|
||||
while (true) {
|
||||
if (find->pos != InvalidPosition) {
|
||||
Element elem;
|
||||
R_TRY(this->ReadKeyValue(std::addressof(elem), find->pos));
|
||||
|
||||
AMS_ASSERT(elem.next == InvalidPosition || elem.next < kv_size);
|
||||
find->pos = elem.next;
|
||||
*out_key = elem.key;
|
||||
*out_val = elem.val;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
while (true) {
|
||||
ind++;
|
||||
if (ind == this->bucket_count) {
|
||||
find->ind = ind;
|
||||
find->pos = InvalidPosition;
|
||||
return fs::ResultDbmFindKeyFinished();
|
||||
}
|
||||
|
||||
Position pos;
|
||||
R_TRY(this->ReadBucket(std::addressof(pos), ind));
|
||||
AMS_ASSERT(pos == InvalidPosition || pos < kv_size);
|
||||
|
||||
if (pos != InvalidPosition) {
|
||||
find->ind = ind;
|
||||
find->pos = pos;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
protected:
|
||||
Result AddImpl(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(aux != nullptr);
|
||||
AMS_ASSERT(aux != nullptr || aux_size == 0);
|
||||
AMS_ASSERT(this->bucket_count > 0);
|
||||
|
||||
{
|
||||
Position pos, prev_pos;
|
||||
Element elem;
|
||||
|
||||
const Result find_res = this->FindImpl(std::addressof(pos), std::addressof(prev_pos), std::addressof(elem), key, hash_key, aux, aux_size);
|
||||
const Result find_res = this->FindInternal(std::addressof(pos), std::addressof(prev_pos), std::addressof(elem), key, hash_key, aux, aux_size);
|
||||
R_UNLESS(R_FAILED(find_res), fs::ResultDbmAlreadyExists());
|
||||
R_UNLESS(fs::ResultDbmKeyNotFound::Includes(find_res), find_res);
|
||||
}
|
||||
|
@ -195,14 +130,14 @@ namespace ams::fs {
|
|||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result GetImpl(Position *out_pos, Value *out_val, const Key &key, u32 hash_key, const void *aux, size_t aux_size) {
|
||||
Result GetInternal(Position *out_pos, Value *out_val, const Key &key, u32 hash_key, const void *aux, size_t aux_size) {
|
||||
AMS_ASSERT(out_pos != nullptr);
|
||||
AMS_ASSERT(out_val != nullptr);
|
||||
AMS_ASSERT(aux != nullptr);
|
||||
|
||||
Position pos, prev_pos;
|
||||
Element elem;
|
||||
R_TRY(this->FindImpl(std::addressof(pos), std::addressof(prev_pos), std::addressof(elem), key, hash_key, aux, aux_size));
|
||||
R_TRY(this->FindInternal(std::addressof(pos), std::addressof(prev_pos), std::addressof(elem), key, hash_key, aux, aux_size));
|
||||
|
||||
*out_pos = pos;
|
||||
*out_val = elem.value;
|
||||
|
@ -246,11 +181,11 @@ namespace ams::fs {
|
|||
return hash_key % this->bucket_count;
|
||||
}
|
||||
|
||||
Result FindImpl(Position *out_pos, Position *out_prev, Element *out_elem, const Key &key, u32 hash_key, const void *aux, size_t aux_size) {
|
||||
Result FindInternal(Position *out_pos, Position *out_prev, Element *out_elem, const Key &key, u32 hash_key, const void *aux, size_t aux_size) {
|
||||
AMS_ASSERT(out_pos != nullptr);
|
||||
AMS_ASSERT(out_prev != nullptr);
|
||||
AMS_ASSERT(out_elem != nullptr);
|
||||
AMS_ASSERT(aux != nullptr);
|
||||
AMS_ASSERT(aux != nullptr || aux_size == 0);
|
||||
AMS_ASSERT(this->bucket_count > 0);
|
||||
|
||||
*out_pos = 0;
|
||||
|
@ -296,7 +231,7 @@ namespace ams::fs {
|
|||
|
||||
*out = static_cast<Position>(this->total_entry_size);
|
||||
|
||||
this->total_entry_size = util::AlignUp(static_cast<s64>(end_pos), s64(4));
|
||||
this->total_entry_size = util::AlignUp(static_cast<s64>(end_pos), alignof(Position));
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
#include <stratosphere/fs/common/fs_dbm_rom_types.hpp>
|
||||
|
||||
namespace ams::fs::RomPathTool {
|
||||
|
||||
constexpr inline u32 MaxPathLength = 0x300;
|
||||
|
||||
struct RomEntryName {
|
||||
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;
|
||||
}
|
||||
|
||||
constexpr inline bool IsNullTerminator(RomPathChar c) {
|
||||
return c == RomStringTraits::NullTerminator;
|
||||
}
|
||||
|
||||
constexpr inline bool IsDot(RomPathChar c) {
|
||||
return c == RomStringTraits::Dot;
|
||||
}
|
||||
|
||||
constexpr inline bool IsCurrentDirectory(const RomEntryName &name) {
|
||||
return name.length == 1 && IsDot(name.path[0]);
|
||||
}
|
||||
|
||||
constexpr inline bool IsCurrentDirectory(const RomPathChar *p, size_t length) {
|
||||
AMS_ASSERT(p != nullptr);
|
||||
return length == 1 && IsDot(p[0]);
|
||||
}
|
||||
|
||||
constexpr inline bool IsCurrentDirectory(const RomPathChar *p) {
|
||||
AMS_ASSERT(p != nullptr);
|
||||
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]);
|
||||
}
|
||||
|
||||
constexpr inline bool IsParentDirectory(const RomPathChar *p, size_t length) {
|
||||
AMS_ASSERT(p != nullptr);
|
||||
return length == 2 && IsDot(p[0]) && IsDot(p[1]);
|
||||
}
|
||||
|
||||
constexpr inline bool IsEqualPath(const RomPathChar *lhs, const RomPathChar *rhs, size_t length) {
|
||||
AMS_ASSERT(lhs != nullptr);
|
||||
AMS_ASSERT(rhs != nullptr);
|
||||
return std::strncmp(lhs, rhs, length) == 0;
|
||||
}
|
||||
|
||||
Result GetParentDirectoryName(RomEntryName *out, const RomEntryName &cur, const RomPathChar *p);
|
||||
|
||||
class PathParser {
|
||||
private:
|
||||
const RomPathChar *prev_path_start;
|
||||
const RomPathChar *prev_path_end;
|
||||
const RomPathChar *next_path;
|
||||
bool finished;
|
||||
public:
|
||||
constexpr PathParser() : prev_path_start(), prev_path_end(), next_path(), finished() { /* ... */ }
|
||||
|
||||
Result Initialize(const RomPathChar *path);
|
||||
void Finalize();
|
||||
|
||||
bool IsParseFinished() const;
|
||||
bool IsDirectoryPath() const;
|
||||
|
||||
Result GetAsDirectoryName(RomEntryName *out) const;
|
||||
Result GetAsFileName(RomEntryName *out) const;
|
||||
|
||||
Result GetNextDirectoryName(RomEntryName *out);
|
||||
};
|
||||
|
||||
}
|
|
@ -14,7 +14,7 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
#include "fs_common.hpp"
|
||||
#include <stratosphere/fs/fs_common.hpp>
|
||||
|
||||
namespace ams::fs {
|
||||
|
|
@ -1,122 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
#include "fs_dbm_rom_types.hpp"
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
namespace RomPathTool {
|
||||
|
||||
constexpr inline u32 MaxPathLength = 0x300;
|
||||
|
||||
struct RomEntryName {
|
||||
size_t length;
|
||||
const RomPathChar *path;
|
||||
};
|
||||
static_assert(util::is_pod<RomEntryName>::value);
|
||||
|
||||
constexpr void InitializeRomEntryName(RomEntryName *entry) {
|
||||
AMS_ABORT_UNLESS(entry != nullptr);
|
||||
entry->length = 0;
|
||||
}
|
||||
|
||||
constexpr inline bool IsSeparator(RomPathChar c) {
|
||||
return c == RomStringTraits::DirectorySeparator;
|
||||
}
|
||||
|
||||
constexpr inline bool IsNullTerminator(RomPathChar c) {
|
||||
return c == RomStringTraits::NullTerminator;
|
||||
}
|
||||
|
||||
constexpr inline bool IsDot(RomPathChar c) {
|
||||
return c == RomStringTraits::Dot;
|
||||
}
|
||||
|
||||
constexpr inline bool IsCurrentDirectory(const RomEntryName &name) {
|
||||
return name.length == 1 && IsDot(name.path[0]);
|
||||
}
|
||||
|
||||
constexpr inline bool IsCurrentDirectory(const RomPathChar *p, size_t length) {
|
||||
AMS_ABORT_UNLESS(p != nullptr);
|
||||
return length == 1 && IsDot(p[0]);
|
||||
}
|
||||
|
||||
constexpr inline bool IsCurrentDirectory(const RomPathChar *p) {
|
||||
AMS_ABORT_UNLESS(p != nullptr);
|
||||
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_ABORT_UNLESS(p != nullptr);
|
||||
return IsDot(p[0]) && IsDot(p[1]) && IsNullTerminator(p[2]);
|
||||
}
|
||||
|
||||
constexpr inline bool IsParentDirectory(const RomPathChar *p, size_t length) {
|
||||
AMS_ABORT_UNLESS(p != nullptr);
|
||||
return length == 2 && IsDot(p[0]) && IsDot(p[1]);
|
||||
}
|
||||
|
||||
constexpr inline bool IsEqualPath(const RomPathChar *lhs, const RomPathChar *rhs, size_t length) {
|
||||
AMS_ABORT_UNLESS(lhs != nullptr);
|
||||
AMS_ABORT_UNLESS(rhs != nullptr);
|
||||
return std::strncmp(lhs, rhs, length) == 0;
|
||||
}
|
||||
|
||||
constexpr inline bool IsEqualName(const RomEntryName &lhs, const RomPathChar *rhs) {
|
||||
AMS_ABORT_UNLESS(rhs != nullptr);
|
||||
if (strnlen(rhs, MaxPathLength) != lhs.length) {
|
||||
return false;
|
||||
}
|
||||
return IsEqualPath(lhs.path, rhs, lhs.length);
|
||||
}
|
||||
|
||||
constexpr inline bool IsEqualName(const RomEntryName &lhs, const RomEntryName &rhs) {
|
||||
if (lhs.length != rhs.length) {
|
||||
return false;
|
||||
}
|
||||
return IsEqualPath(lhs.path, rhs.path, lhs.length);
|
||||
}
|
||||
|
||||
Result GetParentDirectoryName(RomEntryName *out, const RomEntryName &cur, const RomPathChar *p);
|
||||
|
||||
class PathParser {
|
||||
private:
|
||||
const RomPathChar *prev_path_start;
|
||||
const RomPathChar *prev_path_end;
|
||||
const RomPathChar *next_path;
|
||||
bool finished;
|
||||
public:
|
||||
constexpr PathParser() : prev_path_start(), prev_path_end(), next_path(), finished() { /* ... */ }
|
||||
|
||||
Result Initialize(const RomPathChar *path);
|
||||
void Finalize();
|
||||
|
||||
bool IsFinished() const;
|
||||
bool IsDirectoryPath() const;
|
||||
|
||||
Result GetAsDirectoryName(RomEntryName *out) const;
|
||||
Result GetAsFileName(RomEntryName *out) const;
|
||||
|
||||
Result GetNextDirectoryName(RomEntryName *out);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -14,12 +14,12 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
#include "fs_common.hpp"
|
||||
#include "impl/fs_newable.hpp"
|
||||
#include "fsa/fs_ifile.hpp"
|
||||
#include "fsa/fs_idirectory.hpp"
|
||||
#include "fsa/fs_ifilesystem.hpp"
|
||||
#include "fs_dbm_hierarchical_rom_file_table.hpp"
|
||||
#include <stratosphere/fs/fs_common.hpp>
|
||||
#include <stratosphere/fs/impl/fs_newable.hpp>
|
||||
#include <stratosphere/fs/fsa/fs_ifile.hpp>
|
||||
#include <stratosphere/fs/fsa/fs_idirectory.hpp>
|
||||
#include <stratosphere/fs/fsa/fs_ifilesystem.hpp>
|
||||
#include <stratosphere/fs/common/fs_dbm_hierarchical_rom_file_table.hpp>
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue