Revert "hoc-clk: add live vdd2, live boost clock and basic pwm dimming"

This reverts commit 15b7df8ef1.
This commit is contained in:
souldbminersmwc
2025-11-09 16:14:52 -05:00
parent 22ec140738
commit 21a3f953d7
3804 changed files with 435 additions and 570162 deletions

View File

@@ -1,191 +0,0 @@
/*
* Copyright (c) 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>
#include <stratosphere/fs/common/fs_dbm_rom_path_tool.hpp>
#include <stratosphere/fs/common/fs_dbm_rom_key_value_storage.hpp>
namespace ams::fs {
/* ACCURATE_TO_VERSION: 14.3.0.0 */
class HierarchicalRomFileTable {
public:
using Position = u32;
using StorageSizeType = u32;
struct FindPosition {
Position next_dir;
Position next_file;
};
static_assert(util::is_pod<FindPosition>::value);
using FileInfo = RomFileInfo;
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 PositionToDirectoryId(Position pos) {
return static_cast<RomDirectoryId>(pos);
}
static constexpr Position DirectoryIdToPosition(RomDirectoryId id) {
return static_cast<Position>(id);
}
static_assert(std::is_same<RomDirectoryId, RomFileId>::value);
struct RomDirectoryEntry {
Position next;
Position dir;
Position file;
};
static_assert(util::is_pod<RomDirectoryEntry>::value);
struct RomFileEntry {
Position next;
FileInfo info;
};
static_assert(util::is_pod<RomFileEntry>::value);
static constexpr inline u32 MaxKeyLength = RomPathTool::MaxPathLength;
template<typename ImplKeyType, typename ClientKeyType, typename ValueType>
class EntryMapTable : public KeyValueRomStorageTemplate<ImplKeyType, ValueType, MaxKeyLength> {
public:
using ImplKey = ImplKeyType;
using ClientKey = ClientKeyType;
using Value = ValueType;
using Position = HierarchicalRomFileTable::Position;
using Base = KeyValueRomStorageTemplate<ImplKeyType, ValueType, MaxKeyLength>;
public:
Result Add(Position *out, const ClientKeyType &key, const Value &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.begin(), key.name.length()));
}
Result GetByPosition(ImplKey *out_key, Value *out_val, Position pos) {
R_RETURN(Base::GetByPosition(out_key, out_val, pos));
}
Result GetByPosition(ImplKey *out_key, Value *out_val, void *out_aux, size_t *out_aux_size, Position pos) {
R_RETURN(Base::GetByPosition(out_key, out_val, out_aux, out_aux_size, pos));
}
Result SetByPosition(Position pos, const Value &value) {
R_RETURN(Base::SetByPosition(pos, value));
}
};
struct RomEntryKey {
Position parent;
bool IsEqual(const RomEntryKey &rhs, const void *aux_lhs, size_t aux_lhs_size, const void *aux_rhs, size_t aux_rhs_size) const {
if (this->parent != rhs.parent) {
return false;
}
if (aux_lhs_size != aux_rhs_size) {
return false;
}
return RomPathTool::IsEqualPath(reinterpret_cast<const RomPathChar *>(aux_lhs), reinterpret_cast<const RomPathChar *>(aux_rhs), aux_lhs_size / sizeof(RomPathChar));
}
};
static_assert(util::is_pod<RomEntryKey>::value);
struct EntryKey {
RomEntryKey key;
RomPathTool::RomEntryName name;
constexpr u32 Hash() const {
u32 hash = this->key.parent ^ 123456789;
const RomPathChar * cur = this->name.begin();
const RomPathChar * const end = this->name.end();
while (cur < end) {
const u32 c = static_cast<u32>(static_cast<std::make_unsigned<RomPathChar>::type>(*(cur++)));
hash = ((hash >> 5) | (hash << 27)) ^ c;
}
return hash;
}
};
using DirectoryEntryMapTable = EntryMapTable<RomEntryKey, EntryKey, RomDirectoryEntry>;
using FileEntryMapTable = EntryMapTable<RomEntryKey, EntryKey, RomFileEntry>;
private:
DirectoryEntryMapTable m_dir_table;
FileEntryMapTable m_file_table;
public:
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();
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);
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 OpenFile(FileInfo *out, const RomPathChar *path);
Result OpenFile(FileInfo *out, RomFileId id);
Result FindOpen(FindPosition *out, const RomPathChar *path);
Result FindOpen(FindPosition *out, RomDirectoryId id);
Result FindNextDirectory(RomPathChar *out, FindPosition *find, size_t length);
Result FindNextFile(RomPathChar *out, FindPosition *find, size_t length);
Result QueryRomFileSystemSize(s64 *out_dir_entry_size, s64 *out_file_entry_size);
private:
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 FindPathRecursive(EntryKey *out_key, RomDirectoryEntry *out_dir_entry, bool is_dir, const RomPathChar *path);
Result FindDirectoryRecursive(EntryKey *out_key, RomDirectoryEntry *out_dir_entry, const RomPathChar *path);
Result FindFileRecursive(EntryKey *out_key, RomDirectoryEntry *out_dir_entry, const RomPathChar *path);
Result CheckSameEntryExists(const EntryKey &key, Result if_exists);
Result GetDirectoryEntry(Position *out_pos, RomDirectoryEntry *out_entry, const EntryKey &key);
Result GetDirectoryEntry(RomDirectoryEntry *out_entry, RomDirectoryId id);
Result GetFileEntry(Position *out_pos, RomFileEntry *out_entry, const EntryKey &key);
Result GetFileEntry(RomFileEntry *out_entry, RomFileId id);
Result OpenFile(FileInfo *out, const EntryKey &key);
Result FindOpen(FindPosition *out, const EntryKey &key);
};
}

View File

@@ -1,304 +0,0 @@
/*
* Copyright (c) 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>
#include <stratosphere/fs/fs_substorage.hpp>
namespace ams::fs {
/* ACCURATE_TO_VERSION: 14.3.0.0 */
template<typename KeyType, typename ValueType, size_t MaxAuxiliarySize>
class KeyValueRomStorageTemplate {
public:
using Key = KeyType;
using Value = ValueType;
using Position = u32;
using BucketIndex = s64;
using StorageSizeType = u32;
struct FindIndex {
BucketIndex ind;
Position pos;
};
static_assert(util::is_pod<FindIndex>::value);
private:
static constexpr inline Position InvalidPosition = ~Position();
struct Element {
Key key;
Value value;
Position next;
StorageSizeType size;
};
static_assert(util::is_pod<Element>::value);
private:
s64 m_bucket_count;
SubStorage m_bucket_storage;
SubStorage m_kv_storage;
s64 m_total_entry_size;
u32 m_entry_count;
public:
static constexpr s64 QueryBucketStorageSize(s64 num) {
return num * sizeof(Position);
}
static constexpr s64 QueryBucketCount(StorageSizeType size) {
return size / sizeof(Position);
}
static constexpr size_t QueryEntrySize(StorageSizeType aux_size) {
return util::AlignUp<size_t>(sizeof(Element) + aux_size, alignof(Element));
}
static Result Format(SubStorage bucket, StorageSizeType count) {
const Position pos = InvalidPosition;
for (auto i = 0u; i < count; i++) {
R_TRY(bucket.Write(i * sizeof(pos), std::addressof(pos), sizeof(pos)));
}
R_SUCCEED();
}
public:
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);
m_bucket_storage = bucket;
m_bucket_count = count;
m_kv_storage = kv;
R_SUCCEED();
}
void Finalize() {
m_bucket_storage = SubStorage();
m_bucket_count = 0;
m_kv_storage = SubStorage();
}
s64 GetTotalEntrySize() const {
return m_total_entry_size;
}
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);
AMS_ASSERT(aux != nullptr || aux_size == 0);
AMS_ASSERT(m_bucket_count > 0);
{
Position pos, prev_pos;
Element elem;
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);
}
Position pos;
R_TRY(this->AllocateEntry(std::addressof(pos), static_cast<StorageSizeType>(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<StorageSizeType>(aux_size) };
R_TRY(this->WriteKeyValue(std::addressof(elem), pos, aux, aux_size));
*out = pos;
m_entry_count++;
R_SUCCEED();
}
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->FindInternal(std::addressof(pos), std::addressof(prev_pos), std::addressof(elem), key, hash_key, aux, aux_size));
*out_pos = pos;
*out_val = elem.value;
R_SUCCEED();
}
Result GetByPosition(Key *out_key, Value *out_val, Position pos) {
AMS_ASSERT(out_key != nullptr);
AMS_ASSERT(out_val != nullptr);
Element elem;
R_TRY(this->ReadKeyValue(std::addressof(elem), pos));
*out_key = elem.key;
*out_val = elem.value;
R_SUCCEED();
}
Result GetByPosition(Key *out_key, Value *out_val, void *out_aux, size_t *out_aux_size, Position pos) {
AMS_ASSERT(out_key != nullptr);
AMS_ASSERT(out_val != nullptr);
AMS_ASSERT(out_aux != nullptr);
AMS_ASSERT(out_aux_size != nullptr);
Element elem;
R_TRY(this->ReadKeyValue(std::addressof(elem), out_aux, out_aux_size, pos));
*out_key = elem.key;
*out_val = elem.value;
R_SUCCEED();
}
Result SetByPosition(Position pos, const Value &value) {
Element elem;
R_TRY(this->ReadKeyValue(std::addressof(elem), pos));
elem.value = value;
R_RETURN(this->WriteKeyValue(std::addressof(elem), pos, nullptr, 0));
}
private:
BucketIndex HashToBucket(u32 hash_key) const {
return hash_key % m_bucket_count;
}
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 || aux_size == 0);
AMS_ASSERT(m_bucket_count > 0);
*out_pos = 0;
*out_prev = 0;
const BucketIndex ind = HashToBucket(hash_key);
Position cur;
R_TRY(this->ReadBucket(std::addressof(cur), ind));
s64 kv_size;
R_TRY(m_kv_storage.GetSize(std::addressof(kv_size)));
AMS_ASSERT(cur == InvalidPosition || cur < kv_size);
R_UNLESS(cur != InvalidPosition, fs::ResultDbmKeyNotFound());
auto buf = ::ams::fs::impl::MakeUnique<u8[]>(MaxAuxiliarySize);
R_UNLESS(buf != nullptr, fs::ResultAllocationMemoryFailedMakeUnique());
while (true) {
size_t cur_aux_size;
R_TRY(this->ReadKeyValue(out_elem, buf.get(), std::addressof(cur_aux_size), cur));
if (key.IsEqual(out_elem->key, aux, aux_size, buf.get(), cur_aux_size)) {
*out_pos = cur;
R_SUCCEED();
}
*out_prev = cur;
cur = out_elem->next;
R_UNLESS(cur != InvalidPosition, fs::ResultDbmKeyNotFound());
}
}
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) + static_cast<size_t>(aux_size);
R_UNLESS(end_pos <= static_cast<size_t>(kv_size), fs::ResultDbmKeyFull());
*out = static_cast<Position>(m_total_entry_size);
m_total_entry_size = util::AlignUp<s64>(static_cast<s64>(end_pos), alignof(Position));
R_SUCCEED();
}
Result LinkEntry(Position *out, Position pos, u32 hash_key) {
AMS_ASSERT(out != nullptr);
const BucketIndex ind = HashToBucket(hash_key);
Position next;
R_TRY(this->ReadBucket(std::addressof(next), ind));
s64 kv_size;
R_TRY(m_kv_storage.GetSize(std::addressof(kv_size)));
AMS_ASSERT(next == InvalidPosition || next < kv_size);
R_TRY(this->WriteBucket(pos, ind));
*out = next;
R_SUCCEED();
}
Result ReadBucket(Position *out, BucketIndex ind) {
AMS_ASSERT(out != nullptr);
AMS_ASSERT(ind < m_bucket_count);
const s64 offset = ind * sizeof(Position);
R_RETURN(m_bucket_storage.Read(offset, out, sizeof(*out)));
}
Result WriteBucket(Position pos, BucketIndex ind) {
AMS_ASSERT(ind < m_bucket_count);
const s64 offset = ind * sizeof(Position);
R_RETURN(m_bucket_storage.Write(offset, std::addressof(pos), sizeof(pos)));
}
Result ReadKeyValue(Element *out, Position pos) {
AMS_ASSERT(out != nullptr);
s64 kv_size;
R_TRY(m_kv_storage.GetSize(std::addressof(kv_size)));
AMS_ASSERT(pos < kv_size);
R_RETURN(m_kv_storage.Read(pos, out, sizeof(*out)));
}
Result ReadKeyValue(Element *out, void *out_aux, size_t *out_aux_size, Position pos) {
AMS_ASSERT(out != nullptr);
AMS_ASSERT(out_aux != nullptr);
AMS_ASSERT(out_aux_size != nullptr);
R_TRY(this->ReadKeyValue(out, pos));
*out_aux_size = out->size;
if (out->size > 0) {
R_TRY(m_kv_storage.Read(pos + sizeof(*out), out_aux, out->size));
}
R_SUCCEED();
}
Result WriteKeyValue(const Element *elem, Position pos, const void *aux, size_t aux_size) {
AMS_ASSERT(elem != nullptr);
AMS_ASSERT(aux != nullptr);
s64 kv_size;
R_TRY(m_kv_storage.GetSize(std::addressof(kv_size)));
AMS_ASSERT(pos < kv_size);
R_TRY(m_kv_storage.Write(pos, elem, sizeof(*elem)));
if (aux != nullptr && aux_size > 0) {
R_TRY(m_kv_storage.Write(pos + sizeof(*elem), aux, aux_size));
}
R_SUCCEED();
}
};
}

View File

@@ -1,125 +0,0 @@
/*
* Copyright (c) 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 {
/* ACCURATE_TO_VERSION: 14.3.0.0 */
constexpr inline u32 MaxPathLength = 0x300;
constexpr ALWAYS_INLINE bool IsSeparator(RomPathChar c) {
return c == RomStringTraits::DirectorySeparator;
}
constexpr ALWAYS_INLINE bool IsNullTerminator(RomPathChar c) {
return c == RomStringTraits::NullTerminator;
}
constexpr ALWAYS_INLINE bool IsDot(RomPathChar c) {
return c == RomStringTraits::Dot;
}
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);
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 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 *m_prev_path_start;
const RomPathChar *m_prev_path_end;
const RomPathChar *m_next_path;
bool m_finished;
public:
constexpr PathParser() : m_prev_path_start(), m_prev_path_end(), m_next_path(), m_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);
};
}

View File

@@ -1,55 +0,0 @@
/*
* Copyright (c) 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/fs_common.hpp>
namespace ams::fs {
/* ACCURATE_TO_VERSION: 14.3.0.0 */
using RomPathChar = char;
using RomFileId = u32;
using RomDirectoryId = u32;
struct RomFileSystemInformation {
s64 size;
s64 directory_bucket_offset;
s64 directory_bucket_size;
s64 directory_entry_offset;
s64 directory_entry_size;
s64 file_bucket_offset;
s64 file_bucket_size;
s64 file_entry_offset;
s64 file_entry_size;
s64 body_offset;
};
static_assert(util::is_pod<RomFileSystemInformation>::value);
static_assert(sizeof(RomFileSystemInformation) == 0x50);
struct RomFileInfo {
Int64 offset;
Int64 size;
};
static_assert(util::is_pod<RomFileInfo>::value);
namespace RomStringTraits {
constexpr inline char DirectorySeparator = '/';
constexpr inline char NullTerminator = '\x00';
constexpr inline char Dot = '.';
}
}

View File

@@ -1,124 +0,0 @@
/*
* Copyright (c) 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/fs_common.hpp>
#include <stratosphere/fs/fs_path.hpp>
namespace ams::fs {
/* ACCURATE_TO_VERSION: 13.4.0.0 */
class DirectoryPathParser {
NON_COPYABLE(DirectoryPathParser);
NON_MOVEABLE(DirectoryPathParser);
private:
char *m_buffer;
char m_replaced_char;
s32 m_position;
fs::Path m_current_path;
public:
DirectoryPathParser() : m_buffer(nullptr), m_replaced_char(StringTraits::NullTerminator), m_position(0), m_current_path() { /* ... */ }
const fs::Path &GetCurrentPath() const {
return m_current_path;
}
Result Initialize(fs::Path *path) {
/* Declare a default buffer, in case the path has no write buffer. */
static constinit char EmptyBuffer[1] = "";
/* Get a usable buffer. */
char *buf = path->GetWriteBufferLength() > 0 ? path->GetWriteBuffer() : EmptyBuffer;
/* Get the windows skip length. */
const auto windows_skip_len = fs::GetWindowsSkipLength(buf);
/* Set our buffer. */
m_buffer = buf + windows_skip_len;
/* Set up our initial state. */
if (windows_skip_len) {
R_TRY(m_current_path.InitializeWithNormalization(buf, windows_skip_len + 1));
} else {
if (char * const first = this->ReadNextImpl(); first != nullptr) {
R_TRY(m_current_path.InitializeWithNormalization(first));
}
}
R_SUCCEED();
}
Result ReadNext(bool *out_finished) {
/* Default to not finished. */
*out_finished = false;
/* Get the next child component. */
if (auto * const child = this->ReadNextImpl(); child != nullptr) {
/* Append the child component to our current path. */
R_TRY(m_current_path.AppendChild(child));
} else {
/* We have no child component, so we're finished. */
*out_finished = true;
}
R_SUCCEED();
}
private:
char *ReadNextImpl() {
/* Check that we have characters to read. */
if (m_position < 0 || m_buffer[0] == StringTraits::NullTerminator) {
return nullptr;
}
/* If we have a replaced character, restore it. */
if (m_replaced_char != StringTraits::NullTerminator) {
m_buffer[m_position] = m_replaced_char;
if (m_replaced_char == StringTraits::DirectorySeparator) {
++m_position;
}
}
/* If we're at the start of a root-relative path, begin by returning the root. */
if (m_position == 0 && m_buffer[0] == StringTraits::DirectorySeparator) {
m_replaced_char = m_buffer[1];
m_buffer[1] = StringTraits::NullTerminator;
m_position = 1;
return m_buffer;
}
/* Otherwise, find the end of the next path component. */
s32 i;
for (i = m_position; m_buffer[i] != StringTraits::DirectorySeparator; ++i) {
if (m_buffer[i] == StringTraits::NullTerminator) {
char * const ret = (i != m_position) ? m_buffer + m_position : nullptr;
m_position = -1;
return ret;
}
}
/* Sanity check that we're not ending on a separator. */
AMS_ASSERT(m_buffer[i + 1] != StringTraits::NullTerminator);
char * const ret = m_buffer + m_position;
m_replaced_char = StringTraits::DirectorySeparator;
m_buffer[i] = 0;
m_position = i;
return ret;
}
};
}

View File

@@ -1,118 +0,0 @@
/*
* Copyright (c) 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/fs_common.hpp>
#include <stratosphere/fs/fs_istorage.hpp>
#include <stratosphere/fs/fsa/fs_ifile.hpp>
#include <stratosphere/fs/fsa/fs_ifilesystem.hpp>
#include <stratosphere/fs/impl/fs_newable.hpp>
namespace ams::fs {
/* ACCURATE_TO_VERSION: Unknown */
class FileStorage : public IStorage, public impl::Newable {
NON_COPYABLE(FileStorage);
NON_MOVEABLE(FileStorage);
private:
static constexpr s64 InvalidSize = -1;
private:
std::unique_ptr<fsa::IFile> m_unique_file;
std::shared_ptr<fsa::IFile> m_shared_file;
fsa::IFile *m_base_file;
s64 m_size;
public:
FileStorage(fsa::IFile *f) : m_unique_file(f), m_size(InvalidSize) {
m_base_file = m_unique_file.get();
}
FileStorage(std::unique_ptr<fsa::IFile> f) : m_unique_file(std::move(f)), m_size(InvalidSize) {
m_base_file = m_unique_file.get();
}
FileStorage(std::shared_ptr<fsa::IFile> f) : m_shared_file(f), m_size(InvalidSize) {
m_base_file = m_shared_file.get();
}
virtual ~FileStorage() { /* ... */ }
private:
Result UpdateSize();
protected:
constexpr FileStorage() : m_unique_file(), m_shared_file(), m_base_file(nullptr), m_size(InvalidSize) { /* ... */ }
void SetFile(fs::fsa::IFile *file) {
AMS_ASSERT(file != nullptr);
AMS_ASSERT(m_base_file == nullptr);
m_base_file = file;
}
void SetFile(std::unique_ptr<fs::fsa::IFile> &&file) {
AMS_ASSERT(file != nullptr);
AMS_ASSERT(m_base_file == nullptr);
AMS_ASSERT(m_unique_file == nullptr);
m_unique_file = std::move(file);
m_base_file = m_unique_file.get();
}
public:
virtual Result Read(s64 offset, void *buffer, size_t size) override;
virtual Result Write(s64 offset, const void *buffer, size_t size) override;
virtual Result Flush() override;
virtual Result GetSize(s64 *out_size) override;
virtual Result SetSize(s64 size) override;
virtual Result OperateRange(void *dst, size_t dst_size, OperationId op_id, s64 offset, s64 size, const void *src, size_t src_size) override;
};
/* ACCURATE_TO_VERSION: Unknown */
class FileStorageBasedFileSystem : public FileStorage {
NON_COPYABLE(FileStorageBasedFileSystem);
NON_MOVEABLE(FileStorageBasedFileSystem);
private:
std::shared_ptr<fs::fsa::IFileSystem> m_base_file_system;
public:
constexpr FileStorageBasedFileSystem() : FileStorage(), m_base_file_system(nullptr) { /* ... */ }
Result Initialize(std::shared_ptr<fs::fsa::IFileSystem> base_file_system, const fs::Path &path, fs::OpenMode mode);
};
class FileHandleStorage : public IStorage, public impl::Newable {
private:
static constexpr s64 InvalidSize = -1;
private:
FileHandle m_handle;
bool m_close_file;
s64 m_size;
os::SdkMutex m_mutex;
public:
constexpr explicit FileHandleStorage(FileHandle handle, bool close_file) : m_handle(handle), m_close_file(close_file), m_size(InvalidSize), m_mutex() { /* ... */ }
constexpr explicit FileHandleStorage(FileHandle handle) : FileHandleStorage(handle, false) { /* ... */ }
virtual ~FileHandleStorage() override {
if (m_close_file) {
CloseFile(m_handle);
}
}
protected:
Result UpdateSize();
public:
virtual Result Read(s64 offset, void *buffer, size_t size) override;
virtual Result Write(s64 offset, const void *buffer, size_t size) override;
virtual Result Flush() override;
virtual Result GetSize(s64 *out_size) override;
virtual Result SetSize(s64 size) override;
virtual Result OperateRange(void *dst, size_t dst_size, OperationId op_id, s64 offset, s64 size, const void *src, size_t src_size) override;
};
}