diff --git a/libraries/libstratosphere/include/stratosphere/pgl/srv/pgl_srv_api.hpp b/libraries/libstratosphere/include/stratosphere/pgl/srv/pgl_srv_api.hpp index ab49b14af..723ddad5a 100644 --- a/libraries/libstratosphere/include/stratosphere/pgl/srv/pgl_srv_api.hpp +++ b/libraries/libstratosphere/include/stratosphere/pgl/srv/pgl_srv_api.hpp @@ -20,6 +20,6 @@ namespace ams::pgl::srv { - void Initialize(ShellInterface *interface, MemoryResource *mr); + void Initialize(); } diff --git a/libraries/libstratosphere/include/stratosphere/pgl/srv/pgl_srv_shell_interface.hpp b/libraries/libstratosphere/include/stratosphere/pgl/srv/pgl_srv_shell_interface.hpp index f3e4b39f3..1c510a1a4 100644 --- a/libraries/libstratosphere/include/stratosphere/pgl/srv/pgl_srv_shell_interface.hpp +++ b/libraries/libstratosphere/include/stratosphere/pgl/srv/pgl_srv_shell_interface.hpp @@ -20,18 +20,16 @@ namespace ams::pgl::srv { - class ShellInterface final { + class ShellInterface { NON_COPYABLE(ShellInterface); NON_MOVEABLE(ShellInterface); private: - MemoryResource *memory_resource; + using Allocator = ams::sf::ExpHeapAllocator; + using ObjectFactory = ams::sf::ObjectFactory; + private: + Allocator *m_allocator; public: - constexpr ShellInterface() : memory_resource(nullptr) { /* ... */ } - - void Initialize(MemoryResource *mr) { - AMS_ASSERT(this->memory_resource == nullptr); - this->memory_resource = mr; - } + constexpr ShellInterface(Allocator *a) : m_allocator(a) { /* ... */ } public: /* Interface commands. */ Result LaunchProgram(ams::sf::Out out, const ncm::ProgramLocation &loc, u32 pm_flags, u8 pgl_flags); diff --git a/libraries/libstratosphere/include/stratosphere/sf/sf_object_factory.hpp b/libraries/libstratosphere/include/stratosphere/sf/sf_object_factory.hpp index ec3b00332..5e44c2bed 100644 --- a/libraries/libstratosphere/include/stratosphere/sf/sf_object_factory.hpp +++ b/libraries/libstratosphere/include/stratosphere/sf/sf_object_factory.hpp @@ -156,7 +156,7 @@ namespace ams::sf { constexpr virtual void AddReference() override { /* ... */ } constexpr virtual void Release() override { /* ... */ } - constexpr Impl &GetImpl() { return impl::UnmanagedEmplacedImplHolder::GetImplPointer(this); } + constexpr Impl &GetImpl() { return *impl::UnmanagedEmplacedImplHolder::GetImplPointer(this); } constexpr SharedPointer GetShared() { return SharedPointer(this, false); } }; diff --git a/libraries/libstratosphere/source/ncm/ncm_fs_utils.cpp b/libraries/libstratosphere/source/ncm/ncm_fs_utils.cpp index 848ace07e..231ec89ab 100644 --- a/libraries/libstratosphere/source/ncm/ncm_fs_utils.cpp +++ b/libraries/libstratosphere/source/ncm/ncm_fs_utils.cpp @@ -24,17 +24,17 @@ namespace ams::ncm::impl { } - bool PathView::HasPrefix(std::string_view prefix) const { + bool PathView::HasPrefix(util::string_view prefix) const { return this->path.compare(0, prefix.length(), prefix) == 0; } - bool PathView::HasSuffix(std::string_view suffix) const { + bool PathView::HasSuffix(util::string_view suffix) const { return this->path.compare(this->path.length() - suffix.length(), suffix.length(), suffix) == 0; } - std::string_view PathView::GetFileName() const { + util::string_view PathView::GetFileName() const { auto pos = this->path.find_last_of("/"); - return pos != std::string_view::npos ? this->path.substr(pos + 1) : this->path; + return pos != util::string_view::npos ? this->path.substr(pos + 1) : this->path; } MountName CreateUniqueMountName() { diff --git a/libraries/libstratosphere/source/ncm/ncm_fs_utils.hpp b/libraries/libstratosphere/source/ncm/ncm_fs_utils.hpp index d6c4dbf2f..b6dcb0f88 100644 --- a/libraries/libstratosphere/source/ncm/ncm_fs_utils.hpp +++ b/libraries/libstratosphere/source/ncm/ncm_fs_utils.hpp @@ -22,12 +22,12 @@ namespace ams::ncm::impl { class PathView { private: - std::string_view path; /* Nintendo uses util::string_view here. */ + util::string_view path; /* Nintendo uses util::string_view here. */ public: - PathView(std::string_view p) : path(p) { /* ...*/ } - bool HasPrefix(std::string_view prefix) const; - bool HasSuffix(std::string_view suffix) const; - std::string_view GetFileName() const; + PathView(util::string_view p) : path(p) { /* ...*/ } + bool HasPrefix(util::string_view prefix) const; + bool HasSuffix(util::string_view suffix) const; + util::string_view GetFileName() const; }; struct MountName { diff --git a/libraries/libstratosphere/source/pgl/srv/pgl_srv_api.cpp b/libraries/libstratosphere/source/pgl/srv/pgl_srv_api.cpp index 330d11550..c6c634414 100644 --- a/libraries/libstratosphere/source/pgl/srv/pgl_srv_api.cpp +++ b/libraries/libstratosphere/source/pgl/srv/pgl_srv_api.cpp @@ -18,10 +18,7 @@ namespace ams::pgl::srv { - void Initialize(ShellInterface *interface, MemoryResource *mr) { - /* Set the memory resource for the interface. */ - interface->Initialize(mr); - + void Initialize() { /* Enable extra application threads, if we should. */ u8 enable_application_extra_thread; const size_t sz = settings::fwdbg::GetSettingsItemValue(std::addressof(enable_application_extra_thread), sizeof(enable_application_extra_thread), "application_extra_thread", "enable_application_extra_thread"); diff --git a/libraries/libstratosphere/source/pgl/srv/pgl_srv_shell_host_utils.cpp b/libraries/libstratosphere/source/pgl/srv/pgl_srv_shell_host_utils.cpp index a40c03d0d..1047d13f1 100644 --- a/libraries/libstratosphere/source/pgl/srv/pgl_srv_shell_host_utils.cpp +++ b/libraries/libstratosphere/source/pgl/srv/pgl_srv_shell_host_utils.cpp @@ -25,16 +25,16 @@ namespace ams::pgl::srv { static_assert(sizeof(HostPackageMountName) - 1 <= fs::MountNameLengthMax); struct CaseInsensitiveCharTraits : public std::char_traits { - static char to_upper(char c) { + static constexpr char to_upper(char c) { return std::toupper(static_cast(c)); } - static bool eq(char c1, char c2) { + static constexpr bool eq(char c1, char c2) { return to_upper(c1) == to_upper(c2); } - static bool lt(char c1, char c2) { + static constexpr bool lt(char c1, char c2) { return to_upper(c1) < to_upper(c2); } - static int compare(const char *s1, const char *s2, size_t n) { + static constexpr int compare(const char *s1, const char *s2, size_t n) { while ( n-- != 0 ) { if ( to_upper(*s1) < to_upper(*s2) ) return -1; if ( to_upper(*s1) > to_upper(*s2) ) return 1; @@ -42,7 +42,7 @@ namespace ams::pgl::srv { } return 0; } - static const char *find(const char *s, int n, char a) { + static constexpr const char *find(const char *s, int n, char a) { auto const ua (to_upper(a)); while ( n-- != 0 ) { @@ -54,7 +54,7 @@ namespace ams::pgl::srv { } }; - using PathView = std::basic_string_view; + using PathView = util::basic_string_view; enum class ExtensionType { None = 0, diff --git a/libraries/libstratosphere/source/pgl/srv/pgl_srv_shell_interface.cpp b/libraries/libstratosphere/source/pgl/srv/pgl_srv_shell_interface.cpp index 1ececce1b..4d4b34806 100644 --- a/libraries/libstratosphere/source/pgl/srv/pgl_srv_shell_interface.cpp +++ b/libraries/libstratosphere/source/pgl/srv/pgl_srv_shell_interface.cpp @@ -20,12 +20,6 @@ namespace ams::pgl::srv { - namespace { - - using ShellEventObjectFactory = ams::sf::ObjectFactory; - - } - Result ShellInterface::LaunchProgram(ams::sf::Out out, const ncm::ProgramLocation &loc, u32 pm_flags, u8 pgl_flags) { return pgl::srv::LaunchProgram(out.GetPointer(), loc, pm_flags, pgl_flags); } @@ -76,7 +70,7 @@ namespace ams::pgl::srv { Result ShellInterface::GetShellEventObserver(ams::sf::Out> out) { /* Allocate a new interface. */ - auto session = ShellEventObjectFactory::CreateSharedEmplaced(this->memory_resource); + auto session = ObjectFactory::CreateSharedEmplaced(m_allocator); R_UNLESS(session != nullptr, pgl::ResultOutOfMemory()); *out = std::move(session); diff --git a/libraries/libvapours/include/vapours/util.hpp b/libraries/libvapours/include/vapours/util.hpp index 344926fc6..7260a93e3 100644 --- a/libraries/libvapours/include/vapours/util.hpp +++ b/libraries/libvapours/include/vapours/util.hpp @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include diff --git a/libraries/libvapours/include/vapours/util/util_string_view.hpp b/libraries/libvapours/include/vapours/util/util_string_view.hpp new file mode 100644 index 000000000..382b9cf84 --- /dev/null +++ b/libraries/libvapours/include/vapours/util/util_string_view.hpp @@ -0,0 +1,347 @@ +/* + * 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 . + */ +#pragma once +#include +#include + +namespace ams::util { + + template> + class basic_string_view { + static_assert(!std::is_array<_CharT>::value); + static_assert(std::is_trivial<_CharT>::value && std::is_standard_layout<_CharT>::value); + static_assert(std::same_as<_CharT, typename _Traits::char_type>); + public: + using traits_type = _Traits; + using value_type = _CharT; + using pointer = value_type *; + using const_pointer = const value_type *; + using reference = value_type &; + using const_reference = const value_type &; + using const_iterator = const value_type *; + using iterator = const_iterator; + using const_reverse_iterator = std::reverse_iterator; + using reverse_iterator = const_reverse_iterator; + using size_type = size_t; + using difference_type = ptrdiff_t; + static constexpr size_type npos = size_type(-1); + private: + static constexpr int _s_compare(size_type lhs, size_type rhs) noexcept { + const difference_type diff = lhs - rhs; + if (diff > std::numeric_limits::max()) { + return std::numeric_limits::max(); + } + if (diff < std::numeric_limits::min()) { + return std::numeric_limits::min(); + } + return static_cast(diff); + } + private: + const_pointer m_str; + size_type m_len; + public: + constexpr basic_string_view() noexcept : m_str(nullptr), m_len(0) { /* ... */ } + constexpr basic_string_view(const _CharT *str, size_type len) noexcept : m_str(str), m_len(len) { /* ... */ } + constexpr basic_string_view(const _CharT *str) noexcept : m_str(str), m_len(str ? traits_type::length(str) : 0) { /* ... */ } + + template _End> requires std::same_as, _CharT> && (!std::convertible_to<_End, size_type>) + constexpr basic_string_view(_It first, _End last) noexcept : m_str(std::to_address(first)), m_len(last - first) { /* ... */ } + + constexpr basic_string_view(const basic_string_view &) noexcept = default; + constexpr basic_string_view &operator=(const basic_string_view &) noexcept = default; + + constexpr const_iterator begin() const noexcept { return m_str; } + constexpr const_iterator end() const noexcept { return m_str + m_len; } + + constexpr const_iterator cbegin() const noexcept { return m_str; } + constexpr const_iterator cend() const noexcept { return m_str + m_len; } + + constexpr const_reverse_iterator rbegin() const noexcept { return const_reverse_iterator(this->end()); } + constexpr const_reverse_iterator rend() const noexcept { return const_reverse_iterator(this->begin()); } + + constexpr const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator(this->cend()); } + constexpr const_reverse_iterator crend() const noexcept { return const_reverse_iterator(this->cbegin()); } + + constexpr size_type size() const noexcept { return m_len; } + constexpr size_type length() const noexcept { return m_len; } + + constexpr size_type max_size() const noexcept { return (npos - sizeof(size_type) - sizeof(void *)) / sizeof(value_type) / 4; } + + [[nodiscard]] constexpr bool empty() const noexcept { return m_len == 0; } + + constexpr const_reference operator[](size_type pos) const noexcept { + AMS_ASSERT(pos < m_len); + return *(m_str + pos); + } + + constexpr const_reference at(size_type pos) const noexcept { + AMS_ASSERT(pos < m_len); + AMS_ABORT_UNLESS(pos < m_len); + return *(m_str + pos); + } + + constexpr const_reference front() const noexcept { + AMS_ASSERT(m_len > 0); + return *m_str; + } + + constexpr const_reference back() const noexcept { + AMS_ASSERT(m_len > 0); + return *(m_str + m_len - 1); + } + + constexpr const_pointer data() const noexcept { return m_str; } + + constexpr void remove_prefix(size_type n) noexcept { + AMS_ASSERT(m_len >= n); + m_str += n; + m_len -= n; + } + + constexpr void remove_suffix(size_type n) noexcept { + AMS_ASSERT(m_len >= n); + m_len -= n; + } + + constexpr void swap(basic_string_view &rhs) noexcept { + auto tmp = *this; + *this = rhs; + rhs = tmp; + } + + constexpr size_type copy(_CharT *str, size_type n, size_type pos = 0) const noexcept { + AMS_ASSERT(pos <= this->size()); + const size_type rlen = std::min(n, m_len - pos); + traits_type::copy(str, this->data() + pos, rlen); + return rlen; + } + + constexpr basic_string_view substr(size_type pos = 0, size_type n = npos) const noexcept { + AMS_ASSERT(pos <= this->size()); + const size_type rlen = std::min(n, m_len - pos); + return basic_string_view{m_str + pos, rlen}; + } + + constexpr int compare(basic_string_view str) const noexcept { + const size_type rlen = std::min(m_len, str.m_len); + int ret = traits_type::compare(m_str, str.m_str, rlen); + if (ret == 0) { + ret = _s_compare(m_len, str.m_len); + } + return ret; + } + + constexpr int compare(size_type pos, size_type n, basic_string_view str) const noexcept { + return this->substr(pos, n).compare(str); + } + + constexpr int compare(size_type pos1, size_type n1, basic_string_view str, size_type pos2, size_type n2) const { + return this->substr(pos1, n1).compare(str.substr(pos2, n2)); + } + + constexpr int compare(const _CharT *str) const noexcept { + return this->compare(basic_string_view(str)); + } + + constexpr int compare(size_type pos, size_type n, const _CharT *str) const noexcept { + return this->substr(pos, n).compare(basic_string_view(str)); + } + + constexpr int compare(size_type pos, size_type n, const _CharT *str, size_type n2) const noexcept { + return this->substr(pos, n).compare(basic_string_view(str, n2)); + } + + constexpr bool starts_with(basic_string_view x) const noexcept { return this->substr(0, x.size()) == x; } + constexpr bool starts_with(_CharT x) const noexcept { return !this->empty() && traits_type::eq(this->front(), x); } + constexpr bool starts_with(const _CharT *x) const noexcept { return this->starts_with(basic_string_view(x)); } + + constexpr bool ends_with(basic_string_view x) const noexcept { return this->size() >= x.size() && this->compare(this->size() - x.size(), npos, x) == 0; } + constexpr bool ends_with(_CharT x) const noexcept { return !this->empty() && traits_type::eq(this->back(), x); } + constexpr bool ends_with(const _CharT *x) const noexcept { return this->ends_with(basic_string_view(x)); } + + constexpr size_type find(const _CharT *str, size_type pos, size_type n) const noexcept { + if (n == 0) { + return pos + m_len ? pos : npos; + } + + if (n <= m_len) { + for (/* ... */; pos <= m_len - n; ++pos) { + if (traits_type::eq(m_str[pos], str[0]) && traits_type::compare(m_str + pos + 1, str + 1, n - 1) == 0) { + return pos; + } + } + } + + return npos; + } + + constexpr size_type find(_CharT c, size_type pos = 0) const noexcept { + size_type ret = npos; + if (pos < m_len) { + const size_type n = m_len - pos; + if (const _CharT *p = traits_type::find(m_str + pos, n, c); p) { + ret = p - m_str; + } + } + return ret; + } + + constexpr size_type find(basic_string_view str, size_type pos = 0) const noexcept { return this->find(str.m_str, pos, str.m_len); } + + __attribute__((nonnull(1))) + constexpr size_type find(const _CharT *str, size_type pos = 0) const noexcept { return this->find(str, pos, traits_type::length(str)); } + + constexpr size_type rfind(const _CharT *str, size_type pos, size_type n) const noexcept { + if (n <= m_len) { + pos = std::min(size_type(m_len - n), pos); + do { + if (traits_type::compare(m_str + pos, str, n) == 0) { + return pos; + } + } while (pos-- > 0); + } + + return npos; + } + + constexpr size_type rfind(_CharT c, size_type pos = 0) const noexcept { + size_type size = m_len; + if (size > 0) { + if (--size > pos) { + size = pos; + } + for (++size; size-- > 0; /* ... */) { + if (traits_type::eq(m_str[size], c)) { + return size; + } + } + } + return npos; + } + + constexpr size_type rfind(basic_string_view str, size_type pos = 0) const noexcept { return this->rfind(str.m_str, pos, str.m_len); } + + __attribute__((nonnull(1))) + constexpr size_type rfind(const _CharT *str, size_type pos = 0) const noexcept { return this->rfind(str, pos, traits_type::length(str)); } + + constexpr size_type find_first_of(const _CharT *str, size_type pos, size_t n) const noexcept { + for (/* ... */; n && pos < m_len; ++pos) { + if (const _CharT *p = traits_type::find(str, n, m_str[pos]); p) { + return pos; + } + } + return npos; + } + + constexpr size_type find_first_of(basic_string_view str, size_type pos = 0) const noexcept { return this->find_first_of(str.m_str, pos, str.m_len); } + constexpr size_type find_first_of(_CharT c, size_type pos = 0) const noexcept { return this->find(c, pos); } + + __attribute__((nonnull(1))) + constexpr size_type find_first_of(const _CharT *str, size_type pos = 0) const noexcept { return this->find_first_of(str, pos, traits_type::length(str)); } + + constexpr size_type find_last_of(const _CharT *str, size_type pos, size_t n) const noexcept { + size_type size = this->size(); + if (size && n) { + if (--size > pos) { + size = pos; + } + do { + if (traits_type::find(str, n, m_str[size])) { + return size; + } + } while (size-- != 0); + } + return npos; + } + + constexpr size_type find_last_of(basic_string_view str, size_type pos = 0) const noexcept { return this->find_last_of(str.m_str, pos, str.m_len); } + constexpr size_type find_last_of(_CharT c, size_type pos = 0) const noexcept { return this->rfind(c, pos); } + + __attribute__((nonnull(1))) + constexpr size_type find_last_of(const _CharT *str, size_type pos = 0) const noexcept { return this->find_first_of(str, pos, traits_type::length(str)); } + + constexpr size_type find_first_not_of(const _CharT *str, size_type pos, size_t n) const noexcept { + for (/* ... */; pos < m_len; ++pos) { + if (!traits_type::find(str, n, m_str[pos])) { + return pos; + } + } + return npos; + } + + constexpr size_type find_first_not_of(_CharT c, size_type pos = 0) const noexcept { + for (/* ... */; pos < m_len; ++pos) { + if (!traits_type::eq(m_str[pos], c)) { + return pos; + } + } + return npos; + } + + constexpr size_type find_first_not_of(basic_string_view str, size_type pos = 0) const noexcept { return this->find_first_not_of(str.m_str, pos, str.m_len); } + + __attribute__((nonnull(1))) + constexpr size_type find_first_not_of(const _CharT *str, size_type pos = 0) const noexcept { return this->find_first_not_of(str, pos, traits_type::length(str)); } + + constexpr size_type find_last_not_of(const _CharT *str, size_type pos, size_t n) const noexcept { + size_type size = this->size(); + if (size) { + if (--size > pos) { + size = pos; + } + do { + if (!traits_type::find(str, n, m_str[size])) { + return size; + } + } while (size-- != 0); + } + return npos; + } + + constexpr size_type find_last_not_of(_CharT c, size_type pos = 0) const noexcept { + size_type size = this->size(); + if (size) { + if (--size > pos) { + size = pos; + } + do { + if (!traits_type::eq(m_str[size], c)) { + return size; + } + } while (size-- != 0); + } + return npos; + } + + constexpr size_type find_last_not_of(basic_string_view str, size_type pos = 0) const noexcept { return this->find_last_not_of(str.m_str, pos, str.m_len); } + + __attribute__((nonnull(1))) + constexpr size_type find_last_not_of(const _CharT *str, size_type pos = 0) const noexcept { return this->find_last_not_of(str, pos, traits_type::length(str)); } + + constexpr friend bool operator==(const basic_string_view &lhs, const basic_string_view &rhs) noexcept { return lhs.compare(rhs) == 0; } + constexpr friend bool operator!=(const basic_string_view &lhs, const basic_string_view &rhs) noexcept { return lhs.compare(rhs) != 0; } + constexpr friend bool operator<=(const basic_string_view &lhs, const basic_string_view &rhs) noexcept { return lhs.compare(rhs) <= 0; } + constexpr friend bool operator>=(const basic_string_view &lhs, const basic_string_view &rhs) noexcept { return lhs.compare(rhs) >= 0; } + constexpr friend bool operator< (const basic_string_view &lhs, const basic_string_view &rhs) noexcept { return lhs.compare(rhs) < 0; } + constexpr friend bool operator> (const basic_string_view &lhs, const basic_string_view &rhs) noexcept { return lhs.compare(rhs) > 0; } + }; + + template _End> + basic_string_view(_It, _End) -> basic_string_view>; + + using string_view = basic_string_view; + +} diff --git a/stratosphere/ams_mitm/source/sysupdater/sysupdater_fs_utils.cpp b/stratosphere/ams_mitm/source/sysupdater/sysupdater_fs_utils.cpp index b8a88fc13..bf8a9d47b 100644 --- a/stratosphere/ams_mitm/source/sysupdater/sysupdater_fs_utils.cpp +++ b/stratosphere/ams_mitm/source/sysupdater/sysupdater_fs_utils.cpp @@ -210,17 +210,17 @@ namespace ams::mitm::sysupdater { } - bool PathView::HasPrefix(std::string_view prefix) const { + bool PathView::HasPrefix(util::string_view prefix) const { return this->path.compare(0, prefix.length(), prefix) == 0; } - bool PathView::HasSuffix(std::string_view suffix) const { + bool PathView::HasSuffix(util::string_view suffix) const { return this->path.compare(this->path.length() - suffix.length(), suffix.length(), suffix) == 0; } - std::string_view PathView::GetFileName() const { + util::string_view PathView::GetFileName() const { auto pos = this->path.find_last_of("/"); - return pos != std::string_view::npos ? this->path.substr(pos + 1) : this->path; + return pos != util::string_view::npos ? this->path.substr(pos + 1) : this->path; } Result MountSdCardContentMeta(const char *mount_name, const char *path) { diff --git a/stratosphere/ams_mitm/source/sysupdater/sysupdater_fs_utils.hpp b/stratosphere/ams_mitm/source/sysupdater/sysupdater_fs_utils.hpp index 43c094fe9..8aeed741d 100644 --- a/stratosphere/ams_mitm/source/sysupdater/sysupdater_fs_utils.hpp +++ b/stratosphere/ams_mitm/source/sysupdater/sysupdater_fs_utils.hpp @@ -20,12 +20,12 @@ namespace ams::mitm::sysupdater { class PathView { private: - std::string_view path; /* Nintendo uses util::string_view here. */ + util::string_view path; /* Nintendo uses util::string_view here. */ public: - PathView(std::string_view p) : path(p) { /* ...*/ } - bool HasPrefix(std::string_view prefix) const; - bool HasSuffix(std::string_view suffix) const; - std::string_view GetFileName() const; + PathView(util::string_view p) : path(p) { /* ...*/ } + bool HasPrefix(util::string_view prefix) const; + bool HasSuffix(util::string_view suffix) const; + util::string_view GetFileName() const; }; Result MountSdCardContentMeta(const char *mount_name, const char *path); diff --git a/stratosphere/pgl/source/pgl_main.cpp b/stratosphere/pgl/source/pgl_main.cpp index 8532d6cc0..9c0ac7b6d 100644 --- a/stratosphere/pgl/source/pgl_main.cpp +++ b/stratosphere/pgl/source/pgl_main.cpp @@ -21,7 +21,7 @@ extern "C" { u32 __nx_applet_type = AppletType_None; u32 __nx_fs_num_sessions = 1; - #define INNER_HEAP_SIZE 0x4000 + #define INNER_HEAP_SIZE 0x0 size_t nx_inner_heap_size = INNER_HEAP_SIZE; char nx_inner_heap[INNER_HEAP_SIZE]; @@ -33,6 +33,9 @@ extern "C" { alignas(16) u8 __nx_exception_stack[ams::os::MemoryPageSize]; u64 __nx_exception_stack_size = sizeof(__nx_exception_stack); void __libnx_exception_handler(ThreadExceptionDump *ctx); + + void *__libnx_thread_alloc(size_t size); + void __libnx_thread_free(void *mem); } namespace ams { @@ -57,41 +60,52 @@ namespace ams::pgl { namespace { - /* pgl. */ - constexpr size_t NumServers = 1; - ams::sf::hipc::ServerManager g_server_manager; - - constexpr sm::ServiceName ShellServiceName = sm::ServiceName::Encode("pgl"); - constexpr size_t ShellMaxSessions = 8; /* Official maximum is 8. */ - - constinit pgl::srv::ShellInterface g_shell_interface; - - void RegisterServiceSession() { - R_ABORT_UNLESS((g_server_manager.RegisterServer(ShellServiceName, ShellMaxSessions, ams::sf::GetSharedPointerTo(g_shell_interface)))); - } - - void LoopProcess() { - g_server_manager.LoopProcess(); - } - /* NOTE: Nintendo reserves only 0x2000 bytes for this heap, which is used "mostly" to allocate shell event observers. */ /* However, we would like very much for homebrew sysmodules to be able to subscribe to events if they so choose */ /* And so we will use a larger heap (32 KB). */ /* We should have a smaller memory footprint than N in the end, regardless. */ - u8 g_heap_memory[32_KB]; - TYPED_STORAGE(ams::sf::ExpHeapMemoryResource) g_heap_memory_resource; + constinit u8 g_heap_memory[32_KB]; + lmem::HeapHandle g_server_heap_handle; + constinit ams::sf::ExpHeapAllocator g_server_allocator; void *Allocate(size_t size) { - return lmem::AllocateFromExpHeap(GetReference(g_heap_memory_resource).GetHandle(), size); + return lmem::AllocateFromExpHeap(g_server_heap_handle, size); } void Deallocate(void *p, size_t size) { - return lmem::FreeToExpHeap(GetReference(g_heap_memory_resource).GetHandle(), p); + return lmem::FreeToExpHeap(g_server_heap_handle, p); } void InitializeHeap() { - auto heap_handle = lmem::CreateExpHeap(g_heap_memory, sizeof(g_heap_memory), lmem::CreateOption_ThreadSafe); - new (GetPointer(g_heap_memory_resource)) ams::sf::ExpHeapMemoryResource(heap_handle); + g_server_heap_handle = lmem::CreateExpHeap(g_heap_memory, sizeof(g_heap_memory), lmem::CreateOption_ThreadSafe); + g_server_allocator.Attach(g_server_heap_handle); + } + + } + + namespace { + + /* pgl. */ + enum PortIndex { + PortIndex_Shell, + PortIndex_Count, + }; + + constexpr sm::ServiceName ShellServiceName = sm::ServiceName::Encode("pgl"); + constexpr size_t ShellMaxSessions = 8; /* Official maximum is 8. */ + + using ServerManager = ams::sf::hipc::ServerManager; + + ServerManager g_server_manager; + + constinit ams::sf::UnmanagedServiceObject g_shell_interface(std::addressof(g_server_allocator)); + + void RegisterServiceSession() { + R_ABORT_UNLESS(g_server_manager.RegisterObjectForServer(g_shell_interface.GetShared(), ShellServiceName, ShellMaxSessions)); + } + + void LoopProcess() { + g_server_manager.LoopProcess(); } } @@ -138,6 +152,33 @@ void __appExit(void) { setExit(); } +namespace ams { + + void *Malloc(size_t size) { + AMS_ABORT("ams::Malloc was called"); + } + + void Free(void *ptr) { + AMS_ABORT("ams::Free was called"); + } + +} + +void *operator new(size_t size) { + return pgl::Allocate(size); +} + +void operator delete(void *p) { + return pgl::Deallocate(p, 0); +} + +void *__libnx_thread_alloc(size_t size) { + AMS_ABORT("__libnx_thread_alloc was called"); +} + +void __libnx_thread_free(void *mem) { + AMS_ABORT("__libnx_thread_free was called"); +} int main(int argc, char **argv) { @@ -152,7 +193,7 @@ int main(int argc, char **argv) pgl::RegisterServiceSession(); /* Initialize the server library. */ - pgl::srv::Initialize(std::addressof(pgl::g_shell_interface), GetPointer(pgl::g_heap_memory_resource)); + pgl::srv::Initialize(); /* Loop forever, servicing our services. */ pgl::LoopProcess();