summaryrefslogtreecommitdiffstats
path: root/src/core/hle/service/am/library_applet_storage.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/hle/service/am/library_applet_storage.cpp')
-rw-r--r--src/core/hle/service/am/library_applet_storage.cpp140
1 files changed, 140 insertions, 0 deletions
diff --git a/src/core/hle/service/am/library_applet_storage.cpp b/src/core/hle/service/am/library_applet_storage.cpp
new file mode 100644
index 000000000..46e6c0111
--- /dev/null
+++ b/src/core/hle/service/am/library_applet_storage.cpp
@@ -0,0 +1,140 @@
+// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "core/hle/kernel/k_transfer_memory.h"
+#include "core/hle/service/am/am_results.h"
+#include "core/hle/service/am/library_applet_storage.h"
+#include "core/memory.h"
+
+namespace Service::AM {
+
+namespace {
+
+Result ValidateOffset(s64 offset, size_t size, size_t data_size) {
+ R_UNLESS(offset >= 0, AM::ResultInvalidOffset);
+
+ const size_t begin = offset;
+ const size_t end = begin + size;
+
+ R_UNLESS(begin <= end && end <= data_size, AM::ResultInvalidOffset);
+ R_SUCCEED();
+}
+
+class BufferLibraryAppletStorage final : public LibraryAppletStorage {
+public:
+ explicit BufferLibraryAppletStorage(std::vector<u8>&& data) : m_data(std::move(data)) {}
+ ~BufferLibraryAppletStorage() = default;
+
+ Result Read(s64 offset, void* buffer, size_t size) override {
+ R_TRY(ValidateOffset(offset, size, m_data.size()));
+
+ std::memcpy(buffer, m_data.data() + offset, size);
+
+ R_SUCCEED();
+ }
+
+ Result Write(s64 offset, const void* buffer, size_t size) override {
+ R_TRY(ValidateOffset(offset, size, m_data.size()));
+
+ std::memcpy(m_data.data() + offset, buffer, size);
+
+ R_SUCCEED();
+ }
+
+ s64 GetSize() override {
+ return m_data.size();
+ }
+
+ Kernel::KTransferMemory* GetHandle() override {
+ return nullptr;
+ }
+
+private:
+ std::vector<u8> m_data;
+};
+
+class TransferMemoryLibraryAppletStorage : public LibraryAppletStorage {
+public:
+ explicit TransferMemoryLibraryAppletStorage(Core::Memory::Memory& memory,
+ Kernel::KTransferMemory* trmem, bool is_writable,
+ s64 size)
+ : m_memory(memory), m_trmem(trmem), m_is_writable(is_writable), m_size(size) {
+ m_trmem->Open();
+ }
+
+ ~TransferMemoryLibraryAppletStorage() {
+ m_trmem->Close();
+ m_trmem = nullptr;
+ }
+
+ Result Read(s64 offset, void* buffer, size_t size) override {
+ R_TRY(ValidateOffset(offset, size, m_size));
+
+ m_memory.ReadBlock(m_trmem->GetSourceAddress(), buffer, size);
+
+ R_SUCCEED();
+ }
+
+ Result Write(s64 offset, const void* buffer, size_t size) override {
+ R_UNLESS(m_is_writable, ResultUnknown);
+ R_TRY(ValidateOffset(offset, size, m_size));
+
+ m_memory.WriteBlock(m_trmem->GetSourceAddress(), buffer, size);
+
+ R_SUCCEED();
+ }
+
+ s64 GetSize() override {
+ return m_size;
+ }
+
+ Kernel::KTransferMemory* GetHandle() override {
+ return nullptr;
+ }
+
+protected:
+ Core::Memory::Memory& m_memory;
+ Kernel::KTransferMemory* m_trmem;
+ bool m_is_writable;
+ s64 m_size;
+};
+
+class HandleLibraryAppletStorage : public TransferMemoryLibraryAppletStorage {
+public:
+ explicit HandleLibraryAppletStorage(Core::Memory::Memory& memory,
+ Kernel::KTransferMemory* trmem, s64 size)
+ : TransferMemoryLibraryAppletStorage(memory, trmem, true, size) {}
+ ~HandleLibraryAppletStorage() = default;
+
+ Kernel::KTransferMemory* GetHandle() override {
+ return m_trmem;
+ }
+};
+
+} // namespace
+
+LibraryAppletStorage::~LibraryAppletStorage() = default;
+
+std::vector<u8> LibraryAppletStorage::GetData() {
+ std::vector<u8> data(this->GetSize());
+ this->Read(0, data.data(), data.size());
+ return data;
+}
+
+std::shared_ptr<LibraryAppletStorage> CreateStorage(std::vector<u8>&& data) {
+ return std::make_shared<BufferLibraryAppletStorage>(std::move(data));
+}
+
+std::shared_ptr<LibraryAppletStorage> CreateTransferMemoryStorage(Core::Memory::Memory& memory,
+ Kernel::KTransferMemory* trmem,
+ bool is_writable, s64 size) {
+ return std::make_shared<TransferMemoryLibraryAppletStorage>(memory, trmem, is_writable, size);
+}
+
+std::shared_ptr<LibraryAppletStorage> CreateHandleStorage(Core::Memory::Memory& memory,
+ Kernel::KTransferMemory* trmem,
+ s64 size) {
+ return std::make_shared<HandleLibraryAppletStorage>(memory, trmem, size);
+}
+
+} // namespace Service::AM