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.
This commit is contained in:
Lioncash 2018-07-19 16:10:12 -04:00
parent 7eace8f512
commit ff500a7b68
5 changed files with 25 additions and 10 deletions

View File

@ -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<u8>& 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()

View File

@ -5,8 +5,10 @@
#pragma once
#include <array>
#include <iterator>
#include <memory>
#include <string>
#include <type_traits>
#include <vector>
#include <boost/container/small_vector.hpp>
#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<u8>& 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 <typename ContiguousContainer,
typename = std::enable_if_t<!std::is_pointer_v<ContiguousContainer>>>
size_t WriteBuffer(const ContiguousContainer& container, int buffer_index = 0) const {
using ContiguousType = typename ContiguousContainer::value_type;
static_assert(std::is_trivially_copyable_v<ContiguousType>,
"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;

View File

@ -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);

View File

@ -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);

View File

@ -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);