From ff500a7b6838f2eaca25b79ce602c499a71b9c10 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Thu, 19 Jul 2018 16:10:12 -0400 Subject: [PATCH] hle_ipc: Introduce generic WriteBuffer overload for multiple container types This introduces a slightly more generic variant of WriteBuffer(). Notably, this variant doesn't constrain the arguments to only accepting std::vector instances. It accepts whatever adheres to the ContiguousContainer concept in the C++ standard library. This essentially means, std::array, std::string, and std::vector can be used directly with this interface. The interface no longer forces you to solely use containers that dynamically allocate. To ensure our overloads play nice with one another, we only enable the container-based WriteBuffer if the argument is not a pointer, otherwise we fall back to the pointer-based one. --- src/core/hle/kernel/hle_ipc.cpp | 4 ---- src/core/hle/kernel/hle_ipc.h | 23 +++++++++++++++++++++-- src/core/hle/service/audio/audout_u.cpp | 2 +- src/core/hle/service/audio/audren_u.cpp | 4 ++-- src/core/hle/service/set/set.cpp | 2 +- 5 files changed, 25 insertions(+), 10 deletions(-) diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/kernel/hle_ipc.cpp index 911e6fbc1..8f40bdd5a 100644 --- a/src/core/hle/kernel/hle_ipc.cpp +++ b/src/core/hle/kernel/hle_ipc.cpp @@ -301,10 +301,6 @@ size_t HLERequestContext::WriteBuffer(const void* buffer, size_t size, int buffe return size; } -size_t HLERequestContext::WriteBuffer(const std::vector& buffer, int buffer_index) const { - return WriteBuffer(buffer.data(), buffer.size(), buffer_index); -} - size_t HLERequestContext::GetReadBufferSize(int buffer_index) const { const bool is_buffer_a{BufferDescriptorA().size() && BufferDescriptorA()[buffer_index].Size()}; return is_buffer_a ? BufferDescriptorA()[buffer_index].Size() diff --git a/src/core/hle/kernel/hle_ipc.h b/src/core/hle/kernel/hle_ipc.h index 88f93ad22..01b805df8 100644 --- a/src/core/hle/kernel/hle_ipc.h +++ b/src/core/hle/kernel/hle_ipc.h @@ -5,8 +5,10 @@ #pragma once #include +#include #include #include +#include #include #include #include "common/common_types.h" @@ -171,8 +173,25 @@ public: /// Helper function to write a buffer using the appropriate buffer descriptor size_t WriteBuffer(const void* buffer, size_t size, int buffer_index = 0) const; - /// Helper function to write a buffer using the appropriate buffer descriptor - size_t WriteBuffer(const std::vector& buffer, int buffer_index = 0) const; + /* Helper function to write a buffer using the appropriate buffer descriptor + * + * @tparam ContiguousContainer an arbitrary container that satisfies the + * ContiguousContainer concept in the C++ standard library. + * + * @param container The container to write the data of into a buffer. + * @param buffer_index The buffer in particular to write to. + */ + template >> + size_t WriteBuffer(const ContiguousContainer& container, int buffer_index = 0) const { + using ContiguousType = typename ContiguousContainer::value_type; + + static_assert(std::is_trivially_copyable_v, + "Container to WriteBuffer must contain trivially copyable objects"); + + return WriteBuffer(std::data(container), std::size(container) * sizeof(ContiguousType), + buffer_index); + } /// Helper function to get the size of the input buffer size_t GetReadBufferSize(int buffer_index = 0) const; diff --git a/src/core/hle/service/audio/audout_u.cpp b/src/core/hle/service/audio/audout_u.cpp index 8bf273b22..4217ea4fb 100644 --- a/src/core/hle/service/audio/audout_u.cpp +++ b/src/core/hle/service/audio/audout_u.cpp @@ -168,7 +168,7 @@ void AudOutU::ListAudioOutsImpl(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; const std::string audio_interface = "AudioInterface"; - ctx.WriteBuffer(audio_interface.c_str(), audio_interface.size()); + ctx.WriteBuffer(audio_interface); IPC::ResponseBuilder rb = rp.MakeBuilder(3, 0, 0); diff --git a/src/core/hle/service/audio/audren_u.cpp b/src/core/hle/service/audio/audren_u.cpp index b7f591c6d..3bb15bd9f 100644 --- a/src/core/hle/service/audio/audren_u.cpp +++ b/src/core/hle/service/audio/audren_u.cpp @@ -299,7 +299,7 @@ private: IPC::RequestParser rp{ctx}; const std::string audio_interface = "AudioInterface"; - ctx.WriteBuffer(audio_interface.c_str(), audio_interface.size()); + ctx.WriteBuffer(audio_interface); IPC::ResponseBuilder rb = rp.MakeBuilder(3, 0, 0); rb.Push(RESULT_SUCCESS); @@ -324,7 +324,7 @@ private: IPC::RequestParser rp{ctx}; const std::string audio_interface = "AudioDevice"; - ctx.WriteBuffer(audio_interface.c_str(), audio_interface.size()); + ctx.WriteBuffer(audio_interface); IPC::ResponseBuilder rb = rp.MakeBuilder(3, 0, 0); rb.Push(RESULT_SUCCESS); diff --git a/src/core/hle/service/set/set.cpp b/src/core/hle/service/set/set.cpp index bd295cdf6..886133b74 100644 --- a/src/core/hle/service/set/set.cpp +++ b/src/core/hle/service/set/set.cpp @@ -31,7 +31,7 @@ void SET::GetAvailableLanguageCodes(Kernel::HLERequestContext& ctx) { LanguageCode::ZH_HANS, LanguageCode::ZH_HANT, }}; - ctx.WriteBuffer(available_language_codes.data(), available_language_codes.size()); + ctx.WriteBuffer(available_language_codes); IPC::ResponseBuilder rb{ctx, 4}; rb.Push(RESULT_SUCCESS);