complete ProcedureManager

Signed-off-by: szdytom <szdytom@qq.com>
This commit is contained in:
方而静 2024-02-04 15:55:11 +08:00
parent d233589af0
commit 6b0875ee34
Signed by: szTom
GPG Key ID: 072D999D60C6473C
5 changed files with 123 additions and 12 deletions

View File

@ -3,6 +3,11 @@
BinaryBuffer::BinaryBuffer() {}
BinaryBuffer::BinaryBuffer(std::size_t n, const byte *buf) {
for (std::size_t i = 0; i < n; ++i)
data.push_back(buf[i]);
}
BinaryBuffer& BinaryBuffer::operator<<(const std::string_view& x) {
std::uint32_t len = x.size();
*this << len;
@ -34,3 +39,9 @@ std::ostream& operator<<(std::ostream &out, const BinaryBuffer &x) {
return out;
}
void BinaryBuffer::writeTo(std::FILE *out) const {
auto sz = size();
for (std::size_t i = 0; i < sz; ++i)
fputc(data[i], out);
}

View File

@ -35,6 +35,7 @@ static_assert(IsTupleLike<std::tuple<int, int, int>>);
class BinaryBuffer {
public:
BinaryBuffer();
BinaryBuffer(std::size_t n, const byte *buf);
template <typename T>
requires IsBasicType<T>
@ -115,6 +116,7 @@ public:
std::size_t size() const;
bool empty() const;
void writeTo(std::FILE *out) const;
friend std::ostream& operator<<(std::ostream &, const BinaryBuffer &);

View File

@ -0,0 +1,24 @@
#include "ProcedureManager.h"
ProcedureManager::ProcedureManager() {}
void ProcedureManager::handleCall(FILE *in, FILE *out) const {
ProcedureCallHeader header;
auto ptr = reinterpret_cast<byte*>(&header);
std::size_t sz = 0;
while (sz < sizeof(header))
sz += fread(ptr + sz, 1, sizeof(header) - sz, in);
auto buf = new byte[header.len];
sz = 0;
while (sz < header.len)
sz += fread(buf + sz, 1, header.len - sz, in);
BinaryBuffer bb(header.len, buf);
delete[] buf;
if (procedures.count(header.method)) {
auto res = procedures.at(header.method)(bb);
res.writeTo(out);
}
}

View File

@ -1,41 +1,65 @@
#ifndef OGPC_PMANAGER_H_
#define OGPC_PMANAGER_H_
#include "BinaryBuffer.h"
#include <map>
#include <functional>
#include <cstdint>
#include <tuple>
#include <type_traits>
inline namespace {
template <typename T>
struct FuncArgTraits;
template <typename R, typename T>
struct FuncArgTraits<R(T)> {
using type = T;
template <typename R, typename... T>
struct FuncArgTraits<R(*)(T...)> {
using type = std::tuple<T...>;
};
template <typename R, typename... T>
struct FuncArgTraits<std::function<R(T...)>> {
using type = std::tuple<T...>;
};
template <typename Callable>
struct FuncArgTraits : FuncArgTraits<decltype(&Callable::operator())> {};
template <typename ReturnType, typename ClassType, typename... Args>
struct FuncArgTraits<ReturnType(ClassType::*)(Args...) const> {
using type = std::tuple<Args...>;
};
struct ProcedureCallHeader {
uint64_t rd;
int32_t method;
uint32_t len;
};
}
#include <map>
#include <string>
#include <functional>
class ProcedureManager {
public:
ProcedureManager();
template <typename T>
void registerProcedure(const std::string &name, T&& func) {
procedures[name] = [&func](BinraryBuffer &b) -> BinaryBuffer {
using Arg = typename FuncArgTraits<T::operator()>::type;
void registerProcedure(const std::uint32_t &id, T&& func) {
procedures[id] = [&func](BinaryBuffer &b) -> BinaryBuffer {
using Arg = typename FuncArgTraits<typename std::decay<T>::type>::type;
Arg x;
b >> x;
auto y = func(std::move(x));
auto y = std::apply(func, std::move(x));
BinaryBuffer res;
res << y;
return res;
};
}
void handleCall(FILE *in, FILE *out) const;
private:
std::map<std::string, std::function<BinaryBuffer(BinaryBuffer&)>> procedures;
std::map<std::uint32_t, std::function<BinaryBuffer(BinaryBuffer&)>> procedures;
};
#endif

View File

@ -0,0 +1,50 @@
#include "pc/ProcedureManager.h"
#include "pc/BinaryBuffer.h"
#include "test/u.hpp"
#include <tuple>
#include <cstdint>
inline namespace {
using Void = std::tuple<>;
AddTestCase _(20, "ProcedureManager", [](TestCase& t) {
t.expectEq<int>([] {
std::int32_t x = 0;
auto f1 = [&x] (std::int32_t d) -> Void {
x += d;
return {};
};
auto f2 = [&x] (std::int32_t d) -> Void {
x -= d;
return {};
};
ProcedureManager pm;
pm.registerProcedure(1, f1);
pm.registerProcedure(2, f2);
unsigned char ibuf[256] = {
0x45, 0x27, 0xd1, 0xf2, 0x93, 0x43, 0xfc, 0xb1,
0x01, 0x00, 0x00, 0x00,
0x04, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00,
0x45, 0x27, 0xd1, 0xf2, 0x93, 0x43, 0xfc, 0xb2,
0x02, 0x00, 0x00, 0x00,
0x04, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00,
};
unsigned char obuf[256];
FILE *in = fmemopen(ibuf, 256, "r"),
*out = fmemopen(obuf, 256, "w");
pm.handleCall(in, out);
pm.handleCall(in, out);
return x;
}, 1);
});
}