init repo.
This commit is contained in:
10
3party/rpc_core/include/rpc_core.hpp
Normal file
10
3party/rpc_core/include/rpc_core.hpp
Normal file
@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
// first include
|
||||
#include "rpc_core/serialize.hpp"
|
||||
|
||||
// other include
|
||||
#include "rpc_core/connection.hpp"
|
||||
#include "rpc_core/dispose.hpp"
|
||||
#include "rpc_core/request.hpp"
|
||||
#include "rpc_core/rpc.hpp"
|
3
3party/rpc_core/include/rpc_core/config.hpp
Normal file
3
3party/rpc_core/include/rpc_core/config.hpp
Normal file
@ -0,0 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
#include "version.hpp"
|
86
3party/rpc_core/include/rpc_core/connection.hpp
Normal file
86
3party/rpc_core/include/rpc_core/connection.hpp
Normal file
@ -0,0 +1,86 @@
|
||||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
// config
|
||||
#include "config.hpp"
|
||||
|
||||
// include
|
||||
#include "detail/data_packer.hpp"
|
||||
#include "detail/noncopyable.hpp"
|
||||
|
||||
namespace rpc_core {
|
||||
|
||||
/**
|
||||
* Defines interfaces for sending and receiving messages
|
||||
* Usage:
|
||||
* 1. Both sending and receiving should ensure that a complete package of data is sent/received.
|
||||
* 2. Call on_recv_package when a package of data is actually received.
|
||||
* 3. Provide the implementation of sending data, send_package_impl.
|
||||
*/
|
||||
struct connection : detail::noncopyable {
|
||||
std::function<void(std::string)> send_package_impl;
|
||||
std::function<void(std::string)> on_recv_package;
|
||||
};
|
||||
|
||||
/**
|
||||
* Default connection avoid crash
|
||||
*/
|
||||
struct default_connection : connection {
|
||||
default_connection() {
|
||||
send_package_impl = [](const std::string &payload) {
|
||||
RPC_CORE_LOGE("need send_package_impl: %zu", payload.size());
|
||||
};
|
||||
on_recv_package = [](const std::string &payload) {
|
||||
RPC_CORE_LOGE("need on_recv_package: %zu", payload.size());
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Loopback connection for testing
|
||||
*/
|
||||
struct loopback_connection : public connection {
|
||||
loopback_connection() {
|
||||
send_package_impl = [this](std::string payload) {
|
||||
on_recv_package(std::move(payload));
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Stream connection
|
||||
* for bytes stream: tcp socket, serial port, etc.
|
||||
*/
|
||||
struct stream_connection : public connection {
|
||||
explicit stream_connection(uint32_t max_body_size = UINT32_MAX) : data_packer_(max_body_size) {
|
||||
send_package_impl = [this](const std::string &package) {
|
||||
auto payload = data_packer_.pack(package);
|
||||
send_bytes_impl(std::move(payload));
|
||||
};
|
||||
data_packer_.on_data = [this](std::string payload) {
|
||||
on_recv_package(std::move(payload));
|
||||
};
|
||||
on_recv_bytes = [this](const void *data, size_t size) {
|
||||
data_packer_.feed(data, size);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* should call on connected or disconnected
|
||||
*/
|
||||
void reset() {
|
||||
data_packer_.reset();
|
||||
}
|
||||
|
||||
public:
|
||||
std::function<void(std::string)> send_bytes_impl;
|
||||
std::function<void(const void *data, size_t size)> on_recv_bytes;
|
||||
|
||||
private:
|
||||
detail::data_packer data_packer_;
|
||||
};
|
||||
|
||||
} // namespace rpc_core
|
@ -0,0 +1,58 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
#include <functional>
|
||||
|
||||
#include "function.hpp"
|
||||
#include "functor.hpp"
|
||||
#include "helpers.hpp"
|
||||
#include "member_function.hpp"
|
||||
|
||||
namespace rpc_core {
|
||||
|
||||
// There are three basic kinds of callable types
|
||||
// function types
|
||||
struct function_tag {};
|
||||
// function pointer types
|
||||
struct function_ptr_tag {};
|
||||
// classes with operator()
|
||||
struct functor_tag {};
|
||||
|
||||
namespace detail {
|
||||
|
||||
/** Define traits for a operator() member function pointer type */
|
||||
|
||||
// classes with operator()
|
||||
template <typename Callable>
|
||||
struct callable_traits : functor_traits<Callable> {
|
||||
typedef functor_tag callable_category;
|
||||
};
|
||||
|
||||
// functions
|
||||
template <typename Ret, typename... Args>
|
||||
struct callable_traits<Ret(Args...)> : function_traits<Ret(Args...)> {
|
||||
typedef function_tag callable_category;
|
||||
};
|
||||
|
||||
// function pointers
|
||||
template <typename Ret, typename... Args>
|
||||
struct callable_traits<Ret (*)(Args...)> : function_traits<Ret(Args...)> {
|
||||
typedef function_ptr_tag callable_category;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
// Main template
|
||||
|
||||
/** Traits for a callable (function/functor/lambda/...) */
|
||||
template <typename Callable>
|
||||
struct callable_traits : detail::callable_traits<detail::remove_cvref_t<Callable>> {};
|
||||
|
||||
/** Convert a callable to a std::function<> */
|
||||
template <typename Callable>
|
||||
std::function<typename callable_traits<Callable>::function_type> to_stdfunction(Callable fun) {
|
||||
std::function<typename callable_traits<Callable>::function_type> stdfun(std::forward<Callable>(fun));
|
||||
return stdfun;
|
||||
}
|
||||
|
||||
} // namespace rpc_core
|
@ -0,0 +1,40 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#include "helpers.hpp"
|
||||
|
||||
namespace rpc_core {
|
||||
|
||||
namespace detail {
|
||||
|
||||
namespace {
|
||||
|
||||
/** Define traits for a function type */
|
||||
template <typename Fun>
|
||||
struct function_traits;
|
||||
|
||||
template <typename Ret, typename... Args>
|
||||
struct function_traits<Ret(Args...)> {
|
||||
typedef Ret function_type(Args...);
|
||||
typedef Ret return_type;
|
||||
static constexpr std::size_t argc = types_count<Args...>::value;
|
||||
|
||||
template <std::size_t N>
|
||||
using argument_type = typename types_n<N, Args...>::type;
|
||||
};
|
||||
|
||||
template <typename Ret, typename... Args>
|
||||
const std::size_t function_traits<Ret(Args...)>::argc;
|
||||
|
||||
} // namespace
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <typename Func>
|
||||
struct function_traits : detail::function_traits<detail::remove_cvref_t<Func>> {};
|
||||
|
||||
template <typename Func>
|
||||
struct function_traits<Func*> : detail::function_traits<detail::remove_cvref_t<Func>> {};
|
||||
|
||||
} // namespace rpc_core
|
25
3party/rpc_core/include/rpc_core/detail/callable/functor.hpp
Normal file
25
3party/rpc_core/include/rpc_core/detail/callable/functor.hpp
Normal file
@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
|
||||
#include "function.hpp"
|
||||
#include "helpers.hpp"
|
||||
#include "member_function.hpp"
|
||||
|
||||
namespace rpc_core {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <typename Class>
|
||||
using call_operator_traits = member_function_traits<decltype(&Class::operator())>;
|
||||
|
||||
// classes with operator()
|
||||
template <typename Class>
|
||||
struct functor_traits : function_traits<typename call_operator_traits<Class>::function_type> {
|
||||
typedef call_operator_traits<Class> call_operator;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <typename Class>
|
||||
struct functor_traits : detail::functor_traits<detail::remove_cvref_t<Class>> {};
|
||||
|
||||
} // namespace rpc_core
|
58
3party/rpc_core/include/rpc_core/detail/callable/helpers.hpp
Normal file
58
3party/rpc_core/include/rpc_core/detail/callable/helpers.hpp
Normal file
@ -0,0 +1,58 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
namespace rpc_core {
|
||||
|
||||
namespace detail {
|
||||
|
||||
/** Remove reference and cv qualification */
|
||||
template <typename T>
|
||||
using remove_cvref_t = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
|
||||
|
||||
/** Count the number of types given to the template */
|
||||
template <typename... Types>
|
||||
struct types_count;
|
||||
|
||||
template <>
|
||||
struct types_count<> {
|
||||
static constexpr std::size_t value = 0;
|
||||
};
|
||||
|
||||
template <typename Type, typename... Types>
|
||||
struct types_count<Type, Types...> {
|
||||
static constexpr std::size_t value = types_count<Types...>::value + 1;
|
||||
};
|
||||
|
||||
/** Get the nth type given to the template */
|
||||
template <std::size_t n, typename... Types>
|
||||
struct types_n;
|
||||
|
||||
template <std::size_t N, typename Type, typename... Types>
|
||||
struct types_n<N, Type, Types...> : types_n<N - 1, Types...> {};
|
||||
|
||||
template <typename Type, typename... Types>
|
||||
struct types_n<0, Type, Types...> {
|
||||
typedef Type type;
|
||||
};
|
||||
|
||||
/** Test if a type is in a list given types */
|
||||
template <typename Q, typename... Ts>
|
||||
struct types_has;
|
||||
|
||||
template <typename Q>
|
||||
struct types_has<Q> {
|
||||
static constexpr bool value = false;
|
||||
};
|
||||
|
||||
template <typename Q, typename... Ts>
|
||||
struct types_has<Q, Q, Ts...> {
|
||||
static constexpr bool value = true;
|
||||
};
|
||||
|
||||
template <typename Q, typename T, typename... Ts>
|
||||
struct types_has<Q, T, Ts...> : types_has<Q, Ts...> {};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace rpc_core
|
@ -0,0 +1,139 @@
|
||||
#pragma once
|
||||
|
||||
#include "helpers.hpp"
|
||||
|
||||
namespace rpc_core {
|
||||
|
||||
namespace detail {
|
||||
|
||||
// Tags for member function qualifiers
|
||||
struct const_tag {};
|
||||
struct volatile_tag {};
|
||||
struct lref_tag {};
|
||||
struct rref_tag {};
|
||||
struct noexcept_tag {};
|
||||
|
||||
namespace {
|
||||
|
||||
template <typename Class, typename Func, typename... Qual>
|
||||
struct member_function_traits_q : function_traits<Func> {
|
||||
typedef Class class_type;
|
||||
static constexpr bool is_const = types_has<const_tag, Qual...>::value;
|
||||
static constexpr bool is_volatile = types_has<volatile_tag, Qual...>::value;
|
||||
static constexpr bool is_lref = types_has<lref_tag, Qual...>::value;
|
||||
static constexpr bool is_rref = types_has<rref_tag, Qual...>::value;
|
||||
#if __cpp_noexcept_function_type
|
||||
static constexpr bool is_noexcept = types_has<noexcept_tag, Qual...>::value;
|
||||
#endif
|
||||
};
|
||||
|
||||
// We need these until C++17 in case someone takes the address of one
|
||||
// of those static variables or passses it by reference to a function
|
||||
template <typename Class, typename Func, typename... Qual>
|
||||
const bool member_function_traits_q<Class, Func, Qual...>::is_const;
|
||||
template <typename Class, typename Func, typename... Qual>
|
||||
const bool member_function_traits_q<Class, Func, Qual...>::is_volatile;
|
||||
template <typename Class, typename Func, typename... Qual>
|
||||
const bool member_function_traits_q<Class, Func, Qual...>::is_lref;
|
||||
template <typename Class, typename Func, typename... Qual>
|
||||
const bool member_function_traits_q<Class, Func, Qual...>::is_rref;
|
||||
#if __cpp_noexcept_function_type
|
||||
template <typename Class, typename Func, typename... Qual>
|
||||
const bool member_function_traits_q<Class, Func, Qual...>::is_noexcept;
|
||||
#endif
|
||||
|
||||
} // namespace
|
||||
|
||||
template <typename MemFun>
|
||||
struct member_function_traits;
|
||||
|
||||
template <typename Class, typename Ret, typename... Args>
|
||||
struct member_function_traits<Ret (Class::*)(Args...)> : member_function_traits_q<Class, Ret(Args...)> {};
|
||||
|
||||
template <typename Class, typename Ret, typename... Args>
|
||||
struct member_function_traits<Ret (Class::*)(Args...) const> : member_function_traits_q<Class, Ret(Args...), const_tag> {};
|
||||
|
||||
template <typename Class, typename Ret, typename... Args>
|
||||
struct member_function_traits<Ret (Class::*)(Args...) volatile> : member_function_traits_q<Class, Ret(Args...), volatile_tag> {};
|
||||
|
||||
template <typename Class, typename Ret, typename... Args>
|
||||
struct member_function_traits<Ret (Class::*)(Args...) const volatile> : member_function_traits_q<Class, Ret(Args...), const_tag, volatile_tag> {};
|
||||
|
||||
template <typename Class, typename Ret, typename... Args>
|
||||
struct member_function_traits<Ret (Class::*)(Args...) &> : member_function_traits_q<Class, Ret(Args...), lref_tag> {};
|
||||
|
||||
template <typename Class, typename Ret, typename... Args>
|
||||
struct member_function_traits<Ret (Class::*)(Args...) const &> : member_function_traits_q<Class, Ret(Args...), const_tag, lref_tag> {};
|
||||
|
||||
template <typename Class, typename Ret, typename... Args>
|
||||
struct member_function_traits<Ret (Class::*)(Args...) volatile &> : member_function_traits_q<Class, Ret(Args...), volatile_tag, lref_tag> {};
|
||||
|
||||
template <typename Class, typename Ret, typename... Args>
|
||||
struct member_function_traits<Ret (Class::*)(Args...) const volatile &>
|
||||
: member_function_traits_q<Class, Ret(Args...), const_tag, volatile_tag, lref_tag> {};
|
||||
|
||||
template <typename Class, typename Ret, typename... Args>
|
||||
struct member_function_traits<Ret (Class::*)(Args...) &&> : member_function_traits_q<Class, Ret(Args...), rref_tag> {};
|
||||
|
||||
template <typename Class, typename Ret, typename... Args>
|
||||
struct member_function_traits<Ret (Class::*)(Args...) const &&> : member_function_traits_q<Class, Ret(Args...), const_tag, rref_tag> {};
|
||||
|
||||
template <typename Class, typename Ret, typename... Args>
|
||||
struct member_function_traits<Ret (Class::*)(Args...) volatile &&> : member_function_traits_q<Class, Ret(Args...), volatile_tag, rref_tag> {};
|
||||
|
||||
template <typename Class, typename Ret, typename... Args>
|
||||
struct member_function_traits<Ret (Class::*)(Args...) const volatile &&>
|
||||
: member_function_traits_q<Class, Ret(Args...), const_tag, volatile_tag, rref_tag> {};
|
||||
|
||||
#if __cpp_noexcept_function_type
|
||||
template <typename Class, typename Ret, typename... Args>
|
||||
struct member_function_traits<Ret (Class::*)(Args...) noexcept> : member_function_traits_q<Class, Ret(Args...), noexcept_tag> {};
|
||||
|
||||
template <typename Class, typename Ret, typename... Args>
|
||||
struct member_function_traits<Ret (Class::*)(Args...) const noexcept> : member_function_traits_q<Class, Ret(Args...), const_tag, noexcept_tag> {};
|
||||
|
||||
template <typename Class, typename Ret, typename... Args>
|
||||
struct member_function_traits<Ret (Class::*)(Args...) volatile noexcept> : member_function_traits_q<Class, Ret(Args...), volatile_tag, noexcept_tag> {
|
||||
};
|
||||
|
||||
template <typename Class, typename Ret, typename... Args>
|
||||
struct member_function_traits<Ret (Class::*)(Args...) const volatile noexcept>
|
||||
: member_function_traits_q<Class, Ret(Args...), const_tag, volatile_tag, noexcept_tag> {};
|
||||
|
||||
template <typename Class, typename Ret, typename... Args>
|
||||
struct member_function_traits<Ret (Class::*)(Args...) & noexcept> : member_function_traits_q<Class, Ret(Args...), lref_tag, noexcept_tag> {};
|
||||
|
||||
template <typename Class, typename Ret, typename... Args>
|
||||
struct member_function_traits<Ret (Class::*)(Args...) const & noexcept>
|
||||
: member_function_traits_q<Class, Ret(Args...), const_tag, lref_tag, noexcept_tag> {};
|
||||
|
||||
template <typename Class, typename Ret, typename... Args>
|
||||
struct member_function_traits<Ret (Class::*)(Args...) volatile & noexcept>
|
||||
: member_function_traits_q<Class, Ret(Args...), volatile_tag, lref_tag, noexcept_tag> {};
|
||||
|
||||
template <typename Class, typename Ret, typename... Args>
|
||||
struct member_function_traits<Ret (Class::*)(Args...) const volatile & noexcept>
|
||||
: member_function_traits_q<Class, Ret(Args...), const_tag, volatile_tag, lref_tag, noexcept_tag> {};
|
||||
|
||||
template <typename Class, typename Ret, typename... Args>
|
||||
struct member_function_traits<Ret (Class::*)(Args...) && noexcept> : member_function_traits_q<Class, Ret(Args...), rref_tag, noexcept_tag> {};
|
||||
|
||||
template <typename Class, typename Ret, typename... Args>
|
||||
struct member_function_traits<Ret (Class::*)(Args...) const && noexcept>
|
||||
: member_function_traits_q<Class, Ret(Args...), const_tag, rref_tag, noexcept_tag> {};
|
||||
|
||||
template <typename Class, typename Ret, typename... Args>
|
||||
struct member_function_traits<Ret (Class::*)(Args...) volatile && noexcept>
|
||||
: member_function_traits_q<Class, Ret(Args...), volatile_tag, rref_tag, noexcept_tag> {};
|
||||
|
||||
template <typename Class, typename Ret, typename... Args>
|
||||
struct member_function_traits<Ret (Class::*)(Args...) const volatile && noexcept>
|
||||
: member_function_traits_q<Class, Ret(Args...), const_tag, volatile_tag, rref_tag, noexcept_tag> {};
|
||||
#endif // __cpp_noexcept_function_type
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <typename MemFunPtr>
|
||||
struct member_function_traits : detail::member_function_traits<detail::remove_cvref_t<MemFunPtr>> {};
|
||||
|
||||
} // namespace rpc_core
|
56
3party/rpc_core/include/rpc_core/detail/coder.hpp
Normal file
56
3party/rpc_core/include/rpc_core/detail/coder.hpp
Normal file
@ -0,0 +1,56 @@
|
||||
#pragma once
|
||||
|
||||
#include "msg_wrapper.hpp"
|
||||
|
||||
namespace rpc_core {
|
||||
namespace detail {
|
||||
|
||||
class coder {
|
||||
public:
|
||||
static std::string serialize(const msg_wrapper& msg) {
|
||||
std::string payload;
|
||||
payload.reserve(PayloadMinLen + msg.cmd.size() + msg.data.size());
|
||||
payload.append((char*)&msg.seq, 4);
|
||||
uint16_t cmdLen = msg.cmd.length();
|
||||
payload.append((char*)&cmdLen, 2);
|
||||
payload.append((char*)msg.cmd.data(), cmdLen);
|
||||
payload.append((char*)&msg.type, 1);
|
||||
if (msg.request_payload) {
|
||||
payload.append(*msg.request_payload);
|
||||
} else {
|
||||
payload.append(msg.data);
|
||||
}
|
||||
return payload;
|
||||
}
|
||||
|
||||
static msg_wrapper deserialize(const std::string& payload, bool& ok) {
|
||||
msg_wrapper msg;
|
||||
if (payload.size() < PayloadMinLen) {
|
||||
ok = false;
|
||||
return msg;
|
||||
}
|
||||
char* p = (char*)payload.data();
|
||||
const char* pend = payload.data() + payload.size();
|
||||
msg.seq = *(seq_type*)p;
|
||||
p += 4;
|
||||
uint16_t cmdLen = *(uint16_t*)p;
|
||||
p += 2;
|
||||
if (p + cmdLen + 1 > pend) {
|
||||
ok = false;
|
||||
return msg;
|
||||
}
|
||||
msg.cmd.append(p, cmdLen);
|
||||
p += cmdLen;
|
||||
msg.type = *(msg_wrapper::msg_type*)(p);
|
||||
p += 1;
|
||||
msg.data.append(p, pend - p);
|
||||
ok = true;
|
||||
return msg;
|
||||
}
|
||||
|
||||
private:
|
||||
static const uint8_t PayloadMinLen = 4 /*seq*/ + 2 /*cmdLen*/ + 1 /*type*/;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace rpc_core
|
17
3party/rpc_core/include/rpc_core/detail/copyable.hpp
Normal file
17
3party/rpc_core/include/rpc_core/detail/copyable.hpp
Normal file
@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
namespace rpc_core {
|
||||
namespace detail {
|
||||
|
||||
class copyable {
|
||||
public:
|
||||
copyable(const copyable&) = default;
|
||||
copyable& operator=(const copyable&) = default;
|
||||
|
||||
protected:
|
||||
copyable() = default;
|
||||
~copyable() = default;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace rpc_core
|
120
3party/rpc_core/include/rpc_core/detail/data_packer.hpp
Normal file
120
3party/rpc_core/include/rpc_core/detail/data_packer.hpp
Normal file
@ -0,0 +1,120 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <string>
|
||||
|
||||
// #define RPC_CORE_LOG_SHOW_VERBOSE
|
||||
#include "log.h"
|
||||
#include "noncopyable.hpp"
|
||||
|
||||
namespace rpc_core {
|
||||
namespace detail {
|
||||
|
||||
class data_packer : detail::noncopyable {
|
||||
public:
|
||||
explicit data_packer(uint32_t max_body_size = UINT32_MAX) : max_body_size_(max_body_size) {}
|
||||
|
||||
public:
|
||||
bool pack(const void *data, size_t size, const std::function<bool(const void *data, size_t size)> &cb) const {
|
||||
if (size > max_body_size_) {
|
||||
return false;
|
||||
}
|
||||
auto ret = cb(&size, 4);
|
||||
if (!ret) return false;
|
||||
ret = cb(data, size);
|
||||
if (!ret) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string pack(const void *data, size_t size) const {
|
||||
std::string payload;
|
||||
if (size > max_body_size_) {
|
||||
RPC_CORE_LOGW("size > max_body_size: %zu > %u", size, max_body_size_);
|
||||
return payload;
|
||||
}
|
||||
payload.insert(0, (char *)&size, 4);
|
||||
payload.insert(payload.size(), (char *)data, size);
|
||||
return payload;
|
||||
}
|
||||
|
||||
std::string pack(const std::string &data) const {
|
||||
return pack(data.data(), data.size());
|
||||
}
|
||||
|
||||
public:
|
||||
bool feed(const void *data, size_t size) { // NOLINT(misc-no-recursion)
|
||||
if (body_size_ != 0) {
|
||||
feed_body(data, size);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// wait header(4 bytes)
|
||||
if (header_len_now_ + size < 4) {
|
||||
buffer_.insert(buffer_.size(), (char *)data, size);
|
||||
header_len_now_ += size;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// herder data ready, start read body
|
||||
// 1. read header, aka: body size
|
||||
uint8_t header_len = 4 - header_len_now_;
|
||||
size_t body_len = size - header_len;
|
||||
for (int i = 0; i < header_len; ++i) {
|
||||
buffer_.push_back(((char *)data)[i]);
|
||||
}
|
||||
body_size_ = *(uint32_t *)(buffer_.data());
|
||||
buffer_.clear();
|
||||
RPC_CORE_LOGV("feed: wait body_size: %u", body_size_);
|
||||
if (body_size_ > max_body_size_) {
|
||||
RPC_CORE_LOGW("body_size > max_body_size: %u > %u", body_size_, max_body_size_);
|
||||
reset();
|
||||
return false;
|
||||
}
|
||||
|
||||
// 2. feed body
|
||||
if (body_len != 0) {
|
||||
feed_body((char *)data + header_len, body_len);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void reset() {
|
||||
buffer_.clear();
|
||||
buffer_.shrink_to_fit();
|
||||
header_len_now_ = 0;
|
||||
body_size_ = 0;
|
||||
}
|
||||
|
||||
private:
|
||||
void feed_body(const void *data, size_t size) { // NOLINT(misc-no-recursion)
|
||||
if (buffer_.size() + size < body_size_) {
|
||||
buffer_.insert(buffer_.size(), (char *)data, size);
|
||||
} else {
|
||||
size_t body_need = body_size_ - buffer_.size();
|
||||
size_t body_left = size - body_need;
|
||||
buffer_.insert(buffer_.size(), (char *)data, body_need);
|
||||
if (on_data) on_data(std::move(buffer_));
|
||||
|
||||
reset();
|
||||
|
||||
if (body_left != 0) {
|
||||
feed((char *)data + body_need, body_left);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
std::function<void(std::string)> on_data;
|
||||
|
||||
private:
|
||||
uint32_t max_body_size_;
|
||||
std::string buffer_;
|
||||
|
||||
uint32_t header_len_now_ = 0;
|
||||
uint32_t body_size_ = 0;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace rpc_core
|
272
3party/rpc_core/include/rpc_core/detail/log.h
Normal file
272
3party/rpc_core/include/rpc_core/detail/log.h
Normal file
@ -0,0 +1,272 @@
|
||||
// 1. 全局控制
|
||||
// L_O_G_NDEBUG 关闭DEBUG日志(默认依据NDEBUG自动判断)
|
||||
// L_O_G_SHOW_DEBUG 强制开启DEBUG日志
|
||||
// L_O_G_DISABLE_ALL 关闭所有日志
|
||||
// L_O_G_DISABLE_COLOR 禁用颜色显示
|
||||
// L_O_G_LINE_END_CRLF 默认是\n结尾 添加此宏将以\r\n结尾
|
||||
// L_O_G_FOR_MCU 更适用于MCU环境
|
||||
// L_O_G_NOT_EXIT_ON_FATAL FATAL默认退出程序 添加此宏将不退出
|
||||
// L_O_G_SHOW_FULL_PATH 显示文件绝对路径
|
||||
//
|
||||
// c++11环境默认打开以下内容
|
||||
// L_O_G_ENABLE_THREAD_SAFE 线程安全
|
||||
// L_O_G_ENABLE_THREAD_ID 显示线程ID
|
||||
// L_O_G_ENABLE_DATE_TIME 显示日期
|
||||
// 分别可通过下列禁用
|
||||
// L_O_G_DISABLE_THREAD_SAFE
|
||||
// L_O_G_DISABLE_THREAD_ID
|
||||
// L_O_G_DISABLE_DATE_TIME
|
||||
// 可通过`L_O_G_GET_TID_CUSTOM`自定义获取线程ID的实现
|
||||
//
|
||||
// 2. 自定义实现
|
||||
// L_O_G_PRINTF_CUSTOM 自定义输出实现
|
||||
// 并添加实现`int L_O_G_PRINTF_CUSTOM(const char *fmt, ...)`
|
||||
//
|
||||
// 3. 在库中使用时
|
||||
// 3.1. 替换`RPC_CORE_LOG`为库名
|
||||
// 3.2. 定义`RPC_CORE_LOG_IN_LIB`
|
||||
// 3.3. 可配置项
|
||||
// RPC_CORE_LOG_SHOW_DEBUG 开启RPC_CORE_LOGD的输出
|
||||
// RPC_CORE_LOG_SHOW_VERBOSE 显示RPC_CORE_LOGV的输出
|
||||
// RPC_CORE_LOG_DISABLE_ALL 关闭所有日志
|
||||
|
||||
#pragma once
|
||||
|
||||
// clang-format off
|
||||
|
||||
#define RPC_CORE_LOG_IN_LIB
|
||||
|
||||
#if defined(RPC_CORE_LOG_DISABLE_ALL) || defined(L_O_G_DISABLE_ALL)
|
||||
|
||||
#define RPC_CORE_LOG(fmt, ...) ((void)0)
|
||||
#define RPC_CORE_LOGT(tag, fmt, ...) ((void)0)
|
||||
#define RPC_CORE_LOGI(fmt, ...) ((void)0)
|
||||
#define RPC_CORE_LOGW(fmt, ...) ((void)0)
|
||||
#define RPC_CORE_LOGE(fmt, ...) ((void)0)
|
||||
#define RPC_CORE_LOGF(fmt, ...) ((void)0)
|
||||
#define RPC_CORE_LOGD(fmt, ...) ((void)0)
|
||||
#define RPC_CORE_LOGV(fmt, ...) ((void)0)
|
||||
|
||||
#else
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
#if __cplusplus >= 201103L
|
||||
|
||||
#if !defined(L_O_G_DISABLE_THREAD_SAFE) && !defined(L_O_G_ENABLE_THREAD_SAFE)
|
||||
#define L_O_G_ENABLE_THREAD_SAFE
|
||||
#endif
|
||||
|
||||
#if !defined(L_O_G_DISABLE_THREAD_ID) && !defined(L_O_G_ENABLE_THREAD_ID)
|
||||
#define L_O_G_ENABLE_THREAD_ID
|
||||
#endif
|
||||
|
||||
#if !defined(L_O_G_DISABLE_DATE_TIME) && !defined(L_O_G_ENABLE_DATE_TIME)
|
||||
#define L_O_G_ENABLE_DATE_TIME
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#else
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#ifdef L_O_G_LINE_END_CRLF
|
||||
#define RPC_CORE_LOG_LINE_END "\r\n"
|
||||
#else
|
||||
#define RPC_CORE_LOG_LINE_END "\n"
|
||||
#endif
|
||||
|
||||
#ifdef L_O_G_NOT_EXIT_ON_FATAL
|
||||
#define RPC_CORE_LOG_EXIT_PROGRAM()
|
||||
#else
|
||||
#ifdef L_O_G_FOR_MCU
|
||||
#define RPC_CORE_LOG_EXIT_PROGRAM() do{ for(;;); } while(0)
|
||||
#else
|
||||
#define RPC_CORE_LOG_EXIT_PROGRAM() exit(EXIT_FAILURE)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef L_O_G_SHOW_FULL_PATH
|
||||
#define RPC_CORE_LOG_BASE_FILENAME (__FILE__)
|
||||
#else
|
||||
#ifdef __FILE_NAME__
|
||||
#define RPC_CORE_LOG_BASE_FILENAME (__FILE_NAME__)
|
||||
#else
|
||||
#define RPC_CORE_LOG_BASE_FILENAME (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : strrchr(__FILE__, '\\') ? strrchr(__FILE__, '\\') + 1 : __FILE__)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define RPC_CORE_LOG_WITH_COLOR
|
||||
|
||||
#if defined(_WIN32) || (defined(__ANDROID__) && !defined(ANDROID_STANDALONE)) || defined(L_O_G_FOR_MCU)
|
||||
#undef RPC_CORE_LOG_WITH_COLOR
|
||||
#endif
|
||||
|
||||
#ifdef L_O_G_DISABLE_COLOR
|
||||
#undef RPC_CORE_LOG_WITH_COLOR
|
||||
#endif
|
||||
|
||||
#ifdef RPC_CORE_LOG_WITH_COLOR
|
||||
#define RPC_CORE_LOG_COLOR_RED "\033[31m"
|
||||
#define RPC_CORE_LOG_COLOR_GREEN "\033[32m"
|
||||
#define RPC_CORE_LOG_COLOR_YELLOW "\033[33m"
|
||||
#define RPC_CORE_LOG_COLOR_BLUE "\033[34m"
|
||||
#define RPC_CORE_LOG_COLOR_CARMINE "\033[35m"
|
||||
#define RPC_CORE_LOG_COLOR_CYAN "\033[36m"
|
||||
#define RPC_CORE_LOG_COLOR_DEFAULT
|
||||
#define RPC_CORE_LOG_COLOR_END "\033[m"
|
||||
#else
|
||||
#define RPC_CORE_LOG_COLOR_RED
|
||||
#define RPC_CORE_LOG_COLOR_GREEN
|
||||
#define RPC_CORE_LOG_COLOR_YELLOW
|
||||
#define RPC_CORE_LOG_COLOR_BLUE
|
||||
#define RPC_CORE_LOG_COLOR_CARMINE
|
||||
#define RPC_CORE_LOG_COLOR_CYAN
|
||||
#define RPC_CORE_LOG_COLOR_DEFAULT
|
||||
#define RPC_CORE_LOG_COLOR_END
|
||||
#endif
|
||||
|
||||
#define RPC_CORE_LOG_END RPC_CORE_LOG_COLOR_END RPC_CORE_LOG_LINE_END
|
||||
|
||||
#ifndef L_O_G_PRINTF
|
||||
#ifndef RPC_CORE_LOG_PRINTF_DEFAULT
|
||||
#if defined(__ANDROID__) && !defined(ANDROID_STANDALONE)
|
||||
#include <android/log.h>
|
||||
#define RPC_CORE_LOG_PRINTF_DEFAULT(...) __android_log_print(ANDROID_L##OG_DEBUG, "RPC_CORE_LOG", __VA_ARGS__)
|
||||
#else
|
||||
#define RPC_CORE_LOG_PRINTF_DEFAULT(...) printf(__VA_ARGS__)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef L_O_G_PRINTF_CUSTOM
|
||||
#ifdef __cplusplus
|
||||
#include <cstdio>
|
||||
#else
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
#ifdef L_O_G_ENABLE_THREAD_SAFE
|
||||
#ifndef L_O_G_NS_MUTEX
|
||||
#define L_O_G_NS_MUTEX L_O_G_NS_MUTEX
|
||||
#include <mutex>
|
||||
// 1. struct instead of namespace, ensure single instance
|
||||
struct L_O_G_NS_MUTEX {
|
||||
static std::mutex& mutex() {
|
||||
// 2. never delete, avoid destroy before user log
|
||||
// 3. static memory, avoid memory fragmentation
|
||||
static char memory[sizeof(std::mutex)];
|
||||
static std::mutex& mutex = *(new (memory) std::mutex());
|
||||
return mutex;
|
||||
}
|
||||
};
|
||||
#endif
|
||||
#define L_O_G_PRINTF(...) { \
|
||||
std::lock_guard<std::mutex> lock(L_O_G_NS_MUTEX::mutex()); \
|
||||
RPC_CORE_LOG_PRINTF_DEFAULT(__VA_ARGS__); \
|
||||
}
|
||||
#else
|
||||
#define L_O_G_PRINTF(...) RPC_CORE_LOG_PRINTF_DEFAULT(__VA_ARGS__)
|
||||
#endif
|
||||
#else
|
||||
extern int L_O_G_PRINTF_CUSTOM(const char *fmt, ...);
|
||||
#define L_O_G_PRINTF(...) L_O_G_PRINTF_CUSTOM(__VA_ARGS__)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef L_O_G_ENABLE_THREAD_ID
|
||||
#ifndef L_O_G_NS_GET_TID
|
||||
#define L_O_G_NS_GET_TID L_O_G_NS_GET_TID
|
||||
#include <cstdint>
|
||||
#ifdef L_O_G_GET_TID_CUSTOM
|
||||
extern uint32_t L_O_G_GET_TID_CUSTOM();
|
||||
#elif defined(_WIN32)
|
||||
#include <processthreadsapi.h>
|
||||
struct L_O_G_NS_GET_TID {
|
||||
static inline uint32_t get_tid() {
|
||||
return GetCurrentThreadId();
|
||||
}
|
||||
};
|
||||
#elif defined(__linux__)
|
||||
#include <sys/syscall.h>
|
||||
#include <unistd.h>
|
||||
struct L_O_G_NS_GET_TID {
|
||||
static inline uint32_t get_tid() {
|
||||
return syscall(SYS_gettid);
|
||||
}
|
||||
};
|
||||
#else /* for mac, bsd.. */
|
||||
#include <pthread.h>
|
||||
struct L_O_G_NS_GET_TID {
|
||||
static inline uint32_t get_tid() {
|
||||
uint64_t x;
|
||||
pthread_threadid_np(nullptr, &x);
|
||||
return (uint32_t)x;
|
||||
}
|
||||
};
|
||||
#endif
|
||||
#endif
|
||||
#ifdef L_O_G_GET_TID_CUSTOM
|
||||
#define RPC_CORE_LOG_THREAD_LABEL "%u "
|
||||
#define RPC_CORE_LOG_THREAD_VALUE ,L_O_G_GET_TID_CUSTOM()
|
||||
#else
|
||||
#define RPC_CORE_LOG_THREAD_LABEL "%u "
|
||||
#define RPC_CORE_LOG_THREAD_VALUE ,L_O_G_NS_GET_TID::get_tid()
|
||||
#endif
|
||||
#else
|
||||
#define RPC_CORE_LOG_THREAD_LABEL
|
||||
#define RPC_CORE_LOG_THREAD_VALUE
|
||||
#endif
|
||||
|
||||
#ifdef L_O_G_ENABLE_DATE_TIME
|
||||
#include <chrono>
|
||||
#include <sstream>
|
||||
#include <iomanip> // std::put_time
|
||||
#ifndef L_O_G_NS_GET_TIME
|
||||
#define L_O_G_NS_GET_TIME L_O_G_NS_GET_TIME
|
||||
struct L_O_G_NS_GET_TIME {
|
||||
static inline std::string get_time() {
|
||||
auto now = std::chrono::system_clock::now();
|
||||
std::time_t time = std::chrono::system_clock::to_time_t(now);
|
||||
auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()) % 1000;
|
||||
std::stringstream ss;
|
||||
ss << std::put_time(std::localtime(&time), "%Y-%m-%d %H:%M:%S") << '.' << std::setw(3) << std::setfill('0') << ms.count();
|
||||
return ss.str();
|
||||
}
|
||||
};
|
||||
#endif
|
||||
#define RPC_CORE_LOG_TIME_LABEL "%s "
|
||||
#define RPC_CORE_LOG_TIME_VALUE ,L_O_G_NS_GET_TIME::get_time().c_str()
|
||||
#else
|
||||
#define RPC_CORE_LOG_TIME_LABEL
|
||||
#define RPC_CORE_LOG_TIME_VALUE
|
||||
#endif
|
||||
|
||||
#define RPC_CORE_LOG(fmt, ...) do{ L_O_G_PRINTF(RPC_CORE_LOG_COLOR_GREEN RPC_CORE_LOG_TIME_LABEL RPC_CORE_LOG_THREAD_LABEL "[*]: %s:%d " fmt RPC_CORE_LOG_END RPC_CORE_LOG_TIME_VALUE RPC_CORE_LOG_THREAD_VALUE, RPC_CORE_LOG_BASE_FILENAME, __LINE__, ##__VA_ARGS__); } while(0)
|
||||
#define RPC_CORE_LOGT(tag, fmt, ...) do{ L_O_G_PRINTF(RPC_CORE_LOG_COLOR_BLUE RPC_CORE_LOG_TIME_LABEL RPC_CORE_LOG_THREAD_LABEL "[" tag "]: %s:%d " fmt RPC_CORE_LOG_END RPC_CORE_LOG_TIME_VALUE RPC_CORE_LOG_THREAD_VALUE, RPC_CORE_LOG_BASE_FILENAME, __LINE__, ##__VA_ARGS__); } while(0)
|
||||
#define RPC_CORE_LOGI(fmt, ...) do{ L_O_G_PRINTF(RPC_CORE_LOG_COLOR_YELLOW RPC_CORE_LOG_TIME_LABEL RPC_CORE_LOG_THREAD_LABEL "[I]: %s:%d " fmt RPC_CORE_LOG_END RPC_CORE_LOG_TIME_VALUE RPC_CORE_LOG_THREAD_VALUE, RPC_CORE_LOG_BASE_FILENAME, __LINE__, ##__VA_ARGS__); } while(0)
|
||||
#define RPC_CORE_LOGW(fmt, ...) do{ L_O_G_PRINTF(RPC_CORE_LOG_COLOR_CARMINE RPC_CORE_LOG_TIME_LABEL RPC_CORE_LOG_THREAD_LABEL "[W]: %s:%d [%s] " fmt RPC_CORE_LOG_END RPC_CORE_LOG_TIME_VALUE RPC_CORE_LOG_THREAD_VALUE, RPC_CORE_LOG_BASE_FILENAME, __LINE__, __func__, ##__VA_ARGS__); } while(0) // NOLINT(bugprone-lambda-function-name)
|
||||
#define RPC_CORE_LOGE(fmt, ...) do{ L_O_G_PRINTF(RPC_CORE_LOG_COLOR_RED RPC_CORE_LOG_TIME_LABEL RPC_CORE_LOG_THREAD_LABEL "[E]: %s:%d [%s] " fmt RPC_CORE_LOG_END RPC_CORE_LOG_TIME_VALUE RPC_CORE_LOG_THREAD_VALUE, RPC_CORE_LOG_BASE_FILENAME, __LINE__, __func__, ##__VA_ARGS__); } while(0) // NOLINT(bugprone-lambda-function-name)
|
||||
#define RPC_CORE_LOGF(fmt, ...) do{ L_O_G_PRINTF(RPC_CORE_LOG_COLOR_CYAN RPC_CORE_LOG_TIME_LABEL RPC_CORE_LOG_THREAD_LABEL "[!]: %s:%d [%s] " fmt RPC_CORE_LOG_END RPC_CORE_LOG_TIME_VALUE RPC_CORE_LOG_THREAD_VALUE, RPC_CORE_LOG_BASE_FILENAME, __LINE__, __func__, ##__VA_ARGS__); RPC_CORE_LOG_EXIT_PROGRAM(); } while(0) // NOLINT(bugprone-lambda-function-name)
|
||||
|
||||
#if defined(RPC_CORE_LOG_IN_LIB) && !defined(RPC_CORE_LOG_SHOW_DEBUG) && !defined(L_O_G_NDEBUG)
|
||||
#define RPC_CORE_LOG_NDEBUG
|
||||
#endif
|
||||
|
||||
#if defined(L_O_G_NDEBUG) && !defined(RPC_CORE_LOG_NDEBUG)
|
||||
#define RPC_CORE_LOG_NDEBUG
|
||||
#endif
|
||||
|
||||
#if (defined(NDEBUG) || defined(RPC_CORE_LOG_NDEBUG)) && !defined(L_O_G_SHOW_DEBUG)
|
||||
#define RPC_CORE_LOGD(fmt, ...) ((void)0)
|
||||
#else
|
||||
#define RPC_CORE_LOGD(fmt, ...) do{ L_O_G_PRINTF(RPC_CORE_LOG_COLOR_DEFAULT RPC_CORE_LOG_TIME_LABEL RPC_CORE_LOG_THREAD_LABEL "[D]: %s:%d " fmt RPC_CORE_LOG_END RPC_CORE_LOG_TIME_VALUE RPC_CORE_LOG_THREAD_VALUE, RPC_CORE_LOG_BASE_FILENAME, __LINE__, ##__VA_ARGS__); } while(0)
|
||||
#endif
|
||||
|
||||
#if defined(RPC_CORE_LOG_SHOW_VERBOSE)
|
||||
#define RPC_CORE_LOGV(fmt, ...) do{ L_O_G_PRINTF(RPC_CORE_LOG_COLOR_DEFAULT RPC_CORE_LOG_TIME_LABEL RPC_CORE_LOG_THREAD_LABEL "[V]: %s:%d " fmt RPC_CORE_LOG_END RPC_CORE_LOG_TIME_VALUE RPC_CORE_LOG_THREAD_VALUE, RPC_CORE_LOG_BASE_FILENAME, __LINE__, ##__VA_ARGS__); } while(0)
|
||||
#else
|
||||
#define RPC_CORE_LOGV(fmt, ...) ((void)0)
|
||||
#endif
|
||||
|
||||
#endif
|
168
3party/rpc_core/include/rpc_core/detail/msg_dispatcher.hpp
Normal file
168
3party/rpc_core/include/rpc_core/detail/msg_dispatcher.hpp
Normal file
@ -0,0 +1,168 @@
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
#include "../connection.hpp"
|
||||
#include "coder.hpp"
|
||||
#include "log.h"
|
||||
#include "noncopyable.hpp"
|
||||
|
||||
namespace rpc_core {
|
||||
namespace detail {
|
||||
|
||||
class msg_dispatcher : noncopyable {
|
||||
public:
|
||||
using cmd_handle = std::function<std::pair<bool, msg_wrapper>(msg_wrapper)>;
|
||||
using rsp_handle = std::function<bool(msg_wrapper)>;
|
||||
|
||||
using timeout_cb = std::function<void()>;
|
||||
using timer_impl = std::function<void(uint32_t ms, timeout_cb)>;
|
||||
|
||||
public:
|
||||
explicit msg_dispatcher(std::shared_ptr<connection> conn) : conn_(std::move(conn)) {
|
||||
auto alive = std::weak_ptr<void>(is_alive_);
|
||||
conn_->on_recv_package = ([this, RPC_CORE_MOVE_LAMBDA(alive)](const std::string& payload) {
|
||||
if (alive.expired()) {
|
||||
RPC_CORE_LOGD("msg_dispatcher expired");
|
||||
return;
|
||||
}
|
||||
bool success;
|
||||
auto msg = coder::deserialize(payload, success);
|
||||
if (success) {
|
||||
this->dispatch(std::move(msg));
|
||||
} else {
|
||||
RPC_CORE_LOGE("payload deserialize error");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private:
|
||||
void dispatch(msg_wrapper msg) {
|
||||
switch (msg.type & (msg_wrapper::command | msg_wrapper::response)) {
|
||||
case msg_wrapper::command: {
|
||||
// ping
|
||||
const bool is_ping = msg.type & msg_wrapper::ping;
|
||||
if (is_ping) {
|
||||
RPC_CORE_LOGD("<= seq:%u type:ping", msg.seq);
|
||||
msg.type = static_cast<msg_wrapper::msg_type>(msg_wrapper::response | msg_wrapper::pong);
|
||||
RPC_CORE_LOGD("=> seq:%u type:pong", msg.seq);
|
||||
conn_->send_package_impl(coder::serialize(msg));
|
||||
return;
|
||||
}
|
||||
|
||||
// command
|
||||
RPC_CORE_LOGD("<= seq:%u cmd:%s", msg.seq, msg.cmd.c_str());
|
||||
const auto& cmd = msg.cmd;
|
||||
auto it = cmd_handle_map_.find(cmd);
|
||||
if (it == cmd_handle_map_.cend()) {
|
||||
RPC_CORE_LOGD("not subscribe cmd for: %s", cmd.c_str());
|
||||
const bool need_rsp = msg.type & msg_wrapper::need_rsp;
|
||||
if (need_rsp) {
|
||||
RPC_CORE_LOGD("=> seq:%u type:rsp", msg.seq);
|
||||
msg_wrapper rsp;
|
||||
rsp.seq = msg.seq;
|
||||
rsp.type = static_cast<msg_wrapper::msg_type>(msg_wrapper::msg_type::response | msg_wrapper::msg_type::no_such_cmd);
|
||||
conn_->send_package_impl(coder::serialize(rsp));
|
||||
}
|
||||
return;
|
||||
}
|
||||
const auto& fn = it->second;
|
||||
const bool need_rsp = msg.type & msg_wrapper::need_rsp;
|
||||
auto resp = fn(msg);
|
||||
if (need_rsp && resp.first) {
|
||||
RPC_CORE_LOGD("=> seq:%u type:rsp", msg.seq);
|
||||
conn_->send_package_impl(coder::serialize(resp.second));
|
||||
}
|
||||
} break;
|
||||
|
||||
case msg_wrapper::response: {
|
||||
// pong or response
|
||||
const bool isPong = msg.type & msg_wrapper::pong;
|
||||
const auto handleMap = isPong ? &pong_handle_map_ : &rsp_handle_map_;
|
||||
|
||||
RPC_CORE_LOGD("<= seq:%u type:%s", msg.seq, (msg.type & detail::msg_wrapper::msg_type::pong) ? "pong" : "rsp");
|
||||
auto it = handleMap->find(msg.seq);
|
||||
if (it == handleMap->cend()) {
|
||||
RPC_CORE_LOGD("no rsp for seq:%u", msg.seq);
|
||||
break;
|
||||
}
|
||||
const auto& cb = it->second;
|
||||
if (not cb) {
|
||||
RPC_CORE_LOGE("rsp can not be null");
|
||||
return;
|
||||
}
|
||||
if (cb(std::move(msg))) {
|
||||
handleMap->erase(it);
|
||||
RPC_CORE_LOGV("handleMap->size=%zu", handleMap->size());
|
||||
} else {
|
||||
RPC_CORE_LOGE("may deserialize error");
|
||||
}
|
||||
} break;
|
||||
|
||||
default:
|
||||
RPC_CORE_LOGE("unknown type");
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
inline void subscribe_cmd(const cmd_type& cmd, cmd_handle handle) {
|
||||
RPC_CORE_LOGD("subscribe cmd:%s", cmd.c_str());
|
||||
cmd_handle_map_[cmd] = std::move(handle);
|
||||
}
|
||||
|
||||
void unsubscribe_cmd(const cmd_type& cmd) {
|
||||
auto it = cmd_handle_map_.find(cmd);
|
||||
if (it != cmd_handle_map_.cend()) {
|
||||
RPC_CORE_LOGD("erase cmd:%s", cmd.c_str());
|
||||
cmd_handle_map_.erase(it);
|
||||
} else {
|
||||
RPC_CORE_LOGD("not subscribe cmd for: %s", cmd.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void subscribe_rsp(seq_type seq, rsp_handle handle, RPC_CORE_MOVE_PARAM(timeout_cb) timeout_cb, uint32_t timeout_ms, bool is_ping) {
|
||||
RPC_CORE_LOGD("subscribe_rsp seq:%u", seq);
|
||||
if (handle == nullptr) return;
|
||||
const auto handleMap = is_ping ? &pong_handle_map_ : &rsp_handle_map_;
|
||||
|
||||
(*handleMap)[seq] = std::move(handle);
|
||||
|
||||
if (timer_impl_ == nullptr) {
|
||||
RPC_CORE_LOGW("no timeout will cause memory leak!");
|
||||
return;
|
||||
}
|
||||
|
||||
auto alive = std::weak_ptr<void>(is_alive_);
|
||||
timer_impl_(timeout_ms, [handleMap, seq, RPC_CORE_MOVE_LAMBDA(timeout_cb), RPC_CORE_MOVE_LAMBDA(alive)] {
|
||||
if (alive.expired()) {
|
||||
RPC_CORE_LOGD("seq:%u timeout after destroy", seq);
|
||||
return;
|
||||
}
|
||||
auto it = handleMap->find(seq);
|
||||
if (it != handleMap->cend()) {
|
||||
if (timeout_cb) {
|
||||
timeout_cb();
|
||||
}
|
||||
handleMap->erase(seq);
|
||||
RPC_CORE_LOGV("Timeout seq=%d, handleMap.size=%zu", seq, handleMap->size());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
inline void set_timer_impl(timer_impl timer_impl) {
|
||||
timer_impl_ = std::move(timer_impl);
|
||||
}
|
||||
|
||||
private:
|
||||
std::shared_ptr<connection> conn_;
|
||||
std::map<cmd_type, cmd_handle> cmd_handle_map_;
|
||||
std::map<seq_type, rsp_handle> rsp_handle_map_;
|
||||
std::map<seq_type, rsp_handle> pong_handle_map_;
|
||||
timer_impl timer_impl_;
|
||||
std::shared_ptr<void> is_alive_ = std::make_shared<uint8_t>();
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace rpc_core
|
59
3party/rpc_core/include/rpc_core/detail/msg_wrapper.hpp
Normal file
59
3party/rpc_core/include/rpc_core/detail/msg_wrapper.hpp
Normal file
@ -0,0 +1,59 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "../type.hpp"
|
||||
#include "copyable.hpp"
|
||||
#include "log.h"
|
||||
#include "msg_wrapper.hpp"
|
||||
|
||||
namespace rpc_core {
|
||||
namespace detail {
|
||||
|
||||
struct msg_wrapper : copyable { // NOLINT
|
||||
enum msg_type : uint8_t {
|
||||
command = 1 << 0,
|
||||
response = 1 << 1,
|
||||
need_rsp = 1 << 2,
|
||||
ping = 1 << 3,
|
||||
pong = 1 << 4,
|
||||
no_such_cmd = 1 << 5,
|
||||
};
|
||||
|
||||
seq_type seq;
|
||||
cmd_type cmd;
|
||||
msg_type type;
|
||||
std::string data;
|
||||
std::string* request_payload = nullptr;
|
||||
|
||||
std::string dump() const {
|
||||
char tmp[100];
|
||||
snprintf(tmp, 100, "seq:%u, type:%u, cmd:%s", seq, type, cmd.c_str());
|
||||
return tmp;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::pair<bool, T> unpack_as() const {
|
||||
T message;
|
||||
bool ok = deserialize(data, message);
|
||||
if (not ok) {
|
||||
RPC_CORE_LOGE("deserialize error, msg info:%s", dump().c_str());
|
||||
}
|
||||
return std::make_pair(ok, std::move(message));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static std::pair<bool, msg_wrapper> make_rsp(seq_type seq, T* t = nullptr, bool success = true) {
|
||||
msg_wrapper msg;
|
||||
msg.type = msg_wrapper::response;
|
||||
msg.seq = seq;
|
||||
if (success && t != nullptr) {
|
||||
msg.data = serialize(*t);
|
||||
}
|
||||
return std::make_pair(success, std::move(msg));
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace rpc_core
|
17
3party/rpc_core/include/rpc_core/detail/noncopyable.hpp
Normal file
17
3party/rpc_core/include/rpc_core/detail/noncopyable.hpp
Normal file
@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
namespace rpc_core {
|
||||
namespace detail {
|
||||
|
||||
class noncopyable {
|
||||
public:
|
||||
noncopyable(const noncopyable&) = delete;
|
||||
noncopyable& operator=(const noncopyable&) = delete;
|
||||
|
||||
protected:
|
||||
noncopyable() = default;
|
||||
~noncopyable() = default;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace rpc_core
|
26
3party/rpc_core/include/rpc_core/detail/string_view.hpp
Normal file
26
3party/rpc_core/include/rpc_core/detail/string_view.hpp
Normal file
@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
|
||||
namespace rpc_core {
|
||||
namespace detail {
|
||||
|
||||
class string_view {
|
||||
public:
|
||||
string_view(const char* data, size_t size) : data_(data), size_(size) {}
|
||||
string_view(const std::string& data) : data_(data.data()), size_(data.size()) {} // NOLINT
|
||||
const char* data() const {
|
||||
return data_;
|
||||
}
|
||||
size_t size() const {
|
||||
return size_;
|
||||
}
|
||||
|
||||
private:
|
||||
const char* data_;
|
||||
size_t size_;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace rpc_core
|
24
3party/rpc_core/include/rpc_core/detail/type_traits.hpp
Normal file
24
3party/rpc_core/include/rpc_core/detail/type_traits.hpp
Normal file
@ -0,0 +1,24 @@
|
||||
#pragma once
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
namespace rpc_core {
|
||||
namespace detail {
|
||||
|
||||
template <typename Base, typename T, typename... Args>
|
||||
struct all_base_of {
|
||||
static constexpr bool value = std::is_base_of<Base, T>::value && all_base_of<Base, Args...>::value;
|
||||
};
|
||||
|
||||
template <typename Base, typename T>
|
||||
struct all_base_of<Base, T> {
|
||||
static constexpr bool value = std::is_base_of<Base, T>::value;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
constexpr const T& min(const T& a, const T& b) {
|
||||
return a < b ? a : b;
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
} // namespace rpc_core
|
61
3party/rpc_core/include/rpc_core/dispose.hpp
Normal file
61
3party/rpc_core/include/rpc_core/dispose.hpp
Normal file
@ -0,0 +1,61 @@
|
||||
#pragma once
|
||||
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
// #define RPC_CORE_LOG_SHOW_VERBOSE
|
||||
|
||||
// config
|
||||
#include "config.hpp"
|
||||
|
||||
// include
|
||||
#include "detail/noncopyable.hpp"
|
||||
#include "request.hpp"
|
||||
|
||||
namespace rpc_core {
|
||||
|
||||
class dispose : detail::noncopyable, public request::dispose_proto {
|
||||
public:
|
||||
static std::shared_ptr<dispose> create() {
|
||||
return std::make_shared<dispose>();
|
||||
}
|
||||
|
||||
public:
|
||||
void add(const request_s& request) override {
|
||||
RPC_CORE_LOGV("add: ptr:%p", request.get());
|
||||
requests_.push_back(request_w{request});
|
||||
}
|
||||
|
||||
void remove(const request_s& request) override {
|
||||
RPC_CORE_LOGV("remove: ptr:%p", request.get());
|
||||
auto iter = std::remove_if(requests_.begin(), requests_.end(), [&](request_w& param) {
|
||||
auto r = param.lock();
|
||||
if (!r) return true;
|
||||
return r == request;
|
||||
});
|
||||
requests_.erase(iter);
|
||||
}
|
||||
|
||||
void dismiss() {
|
||||
for (const auto& item : requests_) {
|
||||
auto r = item.lock();
|
||||
if (r) {
|
||||
r->cancel();
|
||||
}
|
||||
}
|
||||
requests_.clear();
|
||||
}
|
||||
|
||||
~dispose() override {
|
||||
RPC_CORE_LOGD("~dispose: size:%zu", requests_.size());
|
||||
dismiss();
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<request_w> requests_;
|
||||
};
|
||||
|
||||
using dispose_s = std::shared_ptr<dispose>;
|
||||
|
||||
} // namespace rpc_core
|
35
3party/rpc_core/include/rpc_core/plugin/flatbuffers.hpp
Normal file
35
3party/rpc_core/include/rpc_core/plugin/flatbuffers.hpp
Normal file
@ -0,0 +1,35 @@
|
||||
#pragma once
|
||||
|
||||
#include "flatbuffers/flatbuffers.h"
|
||||
#include "rpc_core/serialize.hpp"
|
||||
|
||||
namespace rpc_core {
|
||||
|
||||
template <typename T, typename std::enable_if<std::is_base_of<::flatbuffers::NativeTable, T>::value, int>::type = 0>
|
||||
serialize_oarchive& operator>>(const T& t, serialize_oarchive& oa) {
|
||||
using TableType = typename T::TableType;
|
||||
|
||||
flatbuffers::FlatBufferBuilder fbb(1024);
|
||||
auto offset = TableType::Pack(fbb, &t);
|
||||
fbb.Finish(offset);
|
||||
auto data = fbb.GetBufferPointer();
|
||||
auto size = fbb.GetSize();
|
||||
oa.data.append((char*)data, size);
|
||||
return oa;
|
||||
}
|
||||
|
||||
template <typename T, typename std::enable_if<std::is_base_of<::flatbuffers::NativeTable, T>::value, int>::type = 0>
|
||||
serialize_iarchive& operator<<(T& t, serialize_iarchive& ia) {
|
||||
using TableType = typename T::TableType;
|
||||
|
||||
flatbuffers::Verifier verifier((uint8_t*)ia.data, ia.size);
|
||||
bool ok = verifier.VerifyBuffer<TableType>();
|
||||
if (!ok) {
|
||||
ia.error = true;
|
||||
return ia;
|
||||
}
|
||||
flatbuffers::GetRoot<TableType>(ia.data)->UnPackTo(&t);
|
||||
return ia;
|
||||
}
|
||||
|
||||
} // namespace rpc_core
|
26
3party/rpc_core/include/rpc_core/plugin/json.hpp
Normal file
26
3party/rpc_core/include/rpc_core/plugin/json.hpp
Normal file
@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
|
||||
#include "nlohmann/json.hpp"
|
||||
#include "rpc_core/detail/log.h"
|
||||
#include "rpc_core/serialize.hpp"
|
||||
|
||||
namespace rpc_core {
|
||||
|
||||
template <typename T, typename std::enable_if<std::is_same<nlohmann::json, T>::value, int>::type = 0>
|
||||
serialize_oarchive& operator>>(const T& t, serialize_oarchive& oa) {
|
||||
t.dump() >> oa;
|
||||
return oa;
|
||||
}
|
||||
|
||||
template <typename T, typename std::enable_if<std::is_same<nlohmann::json, T>::value, int>::type = 0>
|
||||
serialize_iarchive& operator<<(T& t, serialize_iarchive& ia) {
|
||||
try {
|
||||
nlohmann::json::parse(ia.data, ia.data + ia.size).swap(t);
|
||||
} catch (std::exception& e) {
|
||||
RPC_CORE_LOGE("deserialize: %s", e.what());
|
||||
ia.error = true;
|
||||
}
|
||||
return ia;
|
||||
}
|
||||
|
||||
} // namespace rpc_core
|
26
3party/rpc_core/include/rpc_core/plugin/json_msg.hpp
Normal file
26
3party/rpc_core/include/rpc_core/plugin/json_msg.hpp
Normal file
@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
|
||||
#include "nlohmann/json.hpp"
|
||||
#include "rpc_core/detail/log.h"
|
||||
#include "rpc_core/serialize.hpp"
|
||||
|
||||
#define RPC_CORE_DEFINE_TYPE_NLOHMANN_JSON(CLASS) \
|
||||
template <typename T, typename std::enable_if<std::is_same<CLASS, T>::value, int>::type = 0> \
|
||||
::rpc_core::serialize_oarchive& operator>>(const T& t, ::rpc_core::serialize_oarchive& oa) { \
|
||||
oa.data.append(nlohmann::json(t).dump(-1)); \
|
||||
return oa; \
|
||||
} \
|
||||
template <typename T, typename std::enable_if<std::is_same<CLASS, T>::value, int>::type = 0> \
|
||||
::rpc_core::serialize_iarchive& operator<<(T& t, ::rpc_core::serialize_iarchive& ia) { \
|
||||
try { \
|
||||
t = nlohmann::json::parse(ia.data, ia.data + ia.size).get<T>(); \
|
||||
} catch (std::exception & e) { \
|
||||
RPC_CORE_LOGE("deserialize: %s", e.what()); \
|
||||
ia.error = true; \
|
||||
} \
|
||||
return ia; \
|
||||
}
|
||||
|
||||
#define RPC_CORE_DEFINE_TYPE_JSON(Type, ...) \
|
||||
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Type, __VA_ARGS__) \
|
||||
RPC_CORE_DEFINE_TYPE_NLOHMANN_JSON(Type);
|
384
3party/rpc_core/include/rpc_core/request.hpp
Normal file
384
3party/rpc_core/include/rpc_core/request.hpp
Normal file
@ -0,0 +1,384 @@
|
||||
#pragma once
|
||||
|
||||
#include <cassert>
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
#ifndef RPC_CORE_FEATURE_DISABLE_FUTURE
|
||||
#include <future>
|
||||
#endif
|
||||
|
||||
// config
|
||||
#include "config.hpp"
|
||||
|
||||
// include
|
||||
#include "detail/callable/callable.hpp"
|
||||
#include "detail/msg_wrapper.hpp"
|
||||
#include "detail/noncopyable.hpp"
|
||||
#include "serialize.hpp"
|
||||
|
||||
namespace rpc_core {
|
||||
|
||||
class request : detail::noncopyable, public std::enable_shared_from_this<request> {
|
||||
friend class rpc;
|
||||
|
||||
public:
|
||||
using request_s = std::shared_ptr<request>;
|
||||
using request_w = std::weak_ptr<request>;
|
||||
|
||||
struct rpc_proto {
|
||||
virtual ~rpc_proto() = default;
|
||||
virtual seq_type make_seq() = 0;
|
||||
virtual void send_request(const request_s&) = 0;
|
||||
virtual bool is_ready() const = 0;
|
||||
};
|
||||
using send_proto_s = std::shared_ptr<rpc_proto>;
|
||||
using send_proto_w = std::weak_ptr<rpc_proto>;
|
||||
|
||||
struct dispose_proto {
|
||||
virtual ~dispose_proto() = default;
|
||||
virtual void add(const request_s& request) = 0;
|
||||
virtual void remove(const request_s& request) = 0;
|
||||
};
|
||||
|
||||
enum class finally_t : int {
|
||||
normal = 0,
|
||||
no_need_rsp = 1,
|
||||
timeout = 2,
|
||||
canceled = 3,
|
||||
rpc_expired = 4,
|
||||
rpc_not_ready = 5,
|
||||
rsp_serialize_error = 6,
|
||||
no_such_cmd = 7,
|
||||
};
|
||||
static inline const char* finally_t_str(finally_t t) {
|
||||
switch (t) {
|
||||
case finally_t::normal:
|
||||
return "normal";
|
||||
case finally_t::no_need_rsp:
|
||||
return "no_need_rsp";
|
||||
case finally_t::timeout:
|
||||
return "timeout";
|
||||
case finally_t::canceled:
|
||||
return "canceled";
|
||||
case finally_t::rpc_expired:
|
||||
return "rpc_expired";
|
||||
case finally_t::rpc_not_ready:
|
||||
return "rpc_not_ready";
|
||||
case finally_t::rsp_serialize_error:
|
||||
return "rsp_serialize_error";
|
||||
case finally_t::no_such_cmd:
|
||||
return "no_such_cmd";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
template <typename... Args>
|
||||
static request_s create(Args&&... args) {
|
||||
auto r = std::shared_ptr<request>(new request(std::forward<Args>(args)...), [](request* p) {
|
||||
delete p;
|
||||
});
|
||||
r->init();
|
||||
return r;
|
||||
}
|
||||
|
||||
public:
|
||||
std::shared_ptr<request> cmd(cmd_type cmd) {
|
||||
cmd_ = std::move(cmd);
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
request_s msg(T&& message) {
|
||||
this->payload_ = serialize(std::forward<T>(message));
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
template <typename F, typename std::enable_if<callable_traits<F>::argc, int>::type = 0>
|
||||
request_s rsp(RPC_CORE_MOVE_PARAM(F) cb) {
|
||||
using T = detail::remove_cvref_t<typename callable_traits<F>::template argument_type<0>>;
|
||||
|
||||
need_rsp_ = true;
|
||||
auto self = shared_from_this();
|
||||
this->rsp_handle_ = [this, RPC_CORE_MOVE_LAMBDA(cb)](detail::msg_wrapper msg) {
|
||||
if (canceled_) {
|
||||
on_finish(finally_t::canceled);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (msg.type & detail::msg_wrapper::msg_type::no_such_cmd) {
|
||||
on_finish(finally_t::no_such_cmd);
|
||||
return true;
|
||||
}
|
||||
|
||||
auto rsp = msg.unpack_as<T>();
|
||||
if (rsp.first) {
|
||||
cb(std::move(rsp.second));
|
||||
on_finish(finally_t::normal);
|
||||
return true;
|
||||
} else {
|
||||
on_finish(finally_t::rsp_serialize_error);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
return self;
|
||||
}
|
||||
|
||||
template <typename F, typename std::enable_if<!callable_traits<F>::argc, int>::type = 0>
|
||||
request_s rsp(RPC_CORE_MOVE_PARAM(F) cb) {
|
||||
need_rsp_ = true;
|
||||
auto self = shared_from_this();
|
||||
this->rsp_handle_ = [this, RPC_CORE_MOVE_LAMBDA(cb)](const detail::msg_wrapper& msg) {
|
||||
RPC_CORE_UNUSED(msg);
|
||||
if (canceled_) {
|
||||
on_finish(finally_t::canceled);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (msg.type & detail::msg_wrapper::msg_type::no_such_cmd) {
|
||||
on_finish(finally_t::no_such_cmd);
|
||||
return true;
|
||||
}
|
||||
|
||||
cb();
|
||||
on_finish(finally_t::normal);
|
||||
return true;
|
||||
};
|
||||
return self;
|
||||
}
|
||||
|
||||
/**
|
||||
* one call, one finally
|
||||
* @param finally
|
||||
* @return
|
||||
*/
|
||||
std::shared_ptr<request> finally(std::function<void(finally_t)> finally) {
|
||||
finally_ = std::move(finally);
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
std::shared_ptr<request> finally(RPC_CORE_MOVE_PARAM(std::function<void()>) finally) {
|
||||
finally_ = [RPC_CORE_MOVE_LAMBDA(finally)](finally_t t) {
|
||||
RPC_CORE_UNUSED(t);
|
||||
finally();
|
||||
};
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
void call(const send_proto_s& rpc = nullptr) {
|
||||
waiting_rsp_ = true;
|
||||
|
||||
if (canceled_) {
|
||||
on_finish(finally_t::canceled);
|
||||
return;
|
||||
}
|
||||
|
||||
self_keeper_ = shared_from_this();
|
||||
if (rpc) {
|
||||
rpc_ = rpc;
|
||||
} else if (rpc_.expired()) {
|
||||
on_finish(finally_t::rpc_expired);
|
||||
return;
|
||||
}
|
||||
|
||||
auto r = rpc_.lock();
|
||||
if (!r->is_ready()) {
|
||||
on_finish(finally_t::rpc_not_ready);
|
||||
return;
|
||||
}
|
||||
seq_ = r->make_seq();
|
||||
r->send_request(self_keeper_);
|
||||
if (!need_rsp_) {
|
||||
on_finish(finally_t::no_need_rsp);
|
||||
}
|
||||
}
|
||||
|
||||
request_s ping() {
|
||||
is_ping_ = true;
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
std::shared_ptr<request> timeout_ms(uint32_t timeout_ms) {
|
||||
timeout_ms_ = timeout_ms;
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
/**
|
||||
* timeout callback for wait `rsp`
|
||||
*/
|
||||
std::shared_ptr<request> timeout(RPC_CORE_MOVE_PARAM(std::function<void()>) timeout_cb) {
|
||||
timeout_cb_ = [this, RPC_CORE_MOVE_LAMBDA(timeout_cb)] {
|
||||
if (timeout_cb) {
|
||||
timeout_cb();
|
||||
}
|
||||
if (retry_count_ == -1) {
|
||||
call();
|
||||
} else if (retry_count_ > 0) {
|
||||
retry_count_--;
|
||||
call();
|
||||
} else {
|
||||
on_finish(finally_t::timeout);
|
||||
}
|
||||
};
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
request_s add_to(dispose_proto& dispose) {
|
||||
auto self = shared_from_this();
|
||||
dispose.add(self);
|
||||
return self;
|
||||
}
|
||||
|
||||
request_s cancel() {
|
||||
canceled(true);
|
||||
on_finish(finally_t::canceled);
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
request_s reset_cancel() {
|
||||
canceled(false);
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
/**
|
||||
* Automatic retry times after timeout
|
||||
* -1 means retry indefinitely, 0 means no retry, >0 means the number of retries.
|
||||
*/
|
||||
request_s retry(int count) {
|
||||
retry_count_ = count;
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
/**
|
||||
* Force to ignore `rsp` callback.
|
||||
*/
|
||||
request_s disable_rsp() {
|
||||
need_rsp_ = false;
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
std::shared_ptr<request> rpc(send_proto_w rpc) {
|
||||
rpc_ = std::move(rpc);
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
send_proto_w rpc() {
|
||||
return rpc_;
|
||||
}
|
||||
|
||||
bool canceled() const {
|
||||
return canceled_;
|
||||
}
|
||||
|
||||
std::shared_ptr<request> canceled(bool canceled) {
|
||||
canceled_ = canceled;
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
#ifndef RPC_CORE_FEATURE_DISABLE_FUTURE
|
||||
/**
|
||||
* Future pattern
|
||||
* It is not recommended to use blocking interfaces unless you are very clear about what you are doing, as it is easy to cause deadlock.
|
||||
*/
|
||||
template <typename T>
|
||||
struct future_ret;
|
||||
|
||||
template <typename R, typename std::enable_if<!std::is_same<R, void>::value, int>::type = 0>
|
||||
std::future<future_ret<R>> future(const send_proto_s& rpc = nullptr);
|
||||
|
||||
template <typename R, typename std::enable_if<std::is_same<R, void>::value, int>::type = 0>
|
||||
std::future<future_ret<void>> future(const send_proto_s& rpc = nullptr);
|
||||
#endif
|
||||
|
||||
private:
|
||||
explicit request(const send_proto_s& rpc = nullptr) : rpc_(rpc) {
|
||||
RPC_CORE_LOGD("request: %p", this);
|
||||
}
|
||||
~request() {
|
||||
RPC_CORE_LOGD("~request: %p", this);
|
||||
}
|
||||
|
||||
private:
|
||||
void init() {
|
||||
timeout(nullptr);
|
||||
}
|
||||
|
||||
void on_finish(finally_t type) {
|
||||
if (!waiting_rsp_) return;
|
||||
waiting_rsp_ = false;
|
||||
RPC_CORE_LOGD("on_finish: cmd:%s type:%s", cmd_.c_str(), finally_t_str(type));
|
||||
finally_type_ = type;
|
||||
if (finally_) {
|
||||
finally_(finally_type_);
|
||||
}
|
||||
self_keeper_ = nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
send_proto_w rpc_;
|
||||
request_s self_keeper_;
|
||||
seq_type seq_{};
|
||||
cmd_type cmd_;
|
||||
std::string payload_;
|
||||
bool need_rsp_ = false;
|
||||
bool canceled_ = false;
|
||||
std::function<bool(detail::msg_wrapper)> rsp_handle_;
|
||||
uint32_t timeout_ms_ = 3000;
|
||||
std::function<void()> timeout_cb_;
|
||||
finally_t finally_type_ = finally_t::no_need_rsp;
|
||||
std::function<void(finally_t)> finally_;
|
||||
int retry_count_ = 0;
|
||||
bool waiting_rsp_ = false;
|
||||
bool is_ping_ = false;
|
||||
};
|
||||
|
||||
#ifndef RPC_CORE_FEATURE_DISABLE_FUTURE
|
||||
template <typename T>
|
||||
struct request::future_ret {
|
||||
finally_t type;
|
||||
T data;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct request::future_ret<void> {
|
||||
finally_t type;
|
||||
};
|
||||
|
||||
template <typename R, typename std::enable_if<!std::is_same<R, void>::value, int>::type>
|
||||
std::future<request::future_ret<R>> request::future(const request::send_proto_s& rpc) {
|
||||
auto promise = std::make_shared<std::promise<future_ret<R>>>();
|
||||
rsp([promise](R r) {
|
||||
promise->set_value({finally_t::normal, std::move(r)});
|
||||
});
|
||||
finally([promise](finally_t type) {
|
||||
if (type != finally_t::normal) {
|
||||
promise->set_value({type, {}});
|
||||
}
|
||||
});
|
||||
call(rpc);
|
||||
return promise->get_future();
|
||||
}
|
||||
|
||||
template <typename R, typename std::enable_if<std::is_same<R, void>::value, int>::type>
|
||||
std::future<request::future_ret<void>> request::future(const request::send_proto_s& rpc) {
|
||||
auto promise = std::make_shared<std::promise<request::future_ret<void>>>();
|
||||
rsp([promise] {
|
||||
promise->set_value({request::finally_t::normal});
|
||||
});
|
||||
finally([promise](request::finally_t type) {
|
||||
if (type != request::finally_t::normal) {
|
||||
promise->set_value({type});
|
||||
}
|
||||
});
|
||||
call(rpc);
|
||||
return promise->get_future();
|
||||
}
|
||||
#endif
|
||||
|
||||
using request_s = request::request_s;
|
||||
using request_w = request::request_w;
|
||||
using finally_t = request::finally_t;
|
||||
|
||||
} // namespace rpc_core
|
165
3party/rpc_core/include/rpc_core/rpc.hpp
Normal file
165
3party/rpc_core/include/rpc_core/rpc.hpp
Normal file
@ -0,0 +1,165 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
// config
|
||||
#include "config.hpp"
|
||||
|
||||
// include
|
||||
#include "connection.hpp"
|
||||
#include "detail/callable/callable.hpp"
|
||||
#include "detail/msg_dispatcher.hpp"
|
||||
#include "detail/noncopyable.hpp"
|
||||
#include "request.hpp"
|
||||
|
||||
namespace rpc_core {
|
||||
|
||||
class rpc : detail::noncopyable, public std::enable_shared_from_this<rpc>, public request::rpc_proto {
|
||||
public:
|
||||
using timeout_cb = detail::msg_dispatcher::timeout_cb;
|
||||
|
||||
public:
|
||||
template <typename... Args>
|
||||
static std::shared_ptr<rpc> create(Args&&... args) {
|
||||
return std::shared_ptr<rpc>(new rpc(std::forward<Args>(args)...), [](rpc* p) {
|
||||
delete p;
|
||||
});
|
||||
}
|
||||
|
||||
private:
|
||||
explicit rpc(std::shared_ptr<connection> conn = std::make_shared<default_connection>()) : conn_(conn), dispatcher_(std::move(conn)) {
|
||||
RPC_CORE_LOGD("rpc: %p", this);
|
||||
}
|
||||
|
||||
~rpc() override {
|
||||
RPC_CORE_LOGD("~rpc: %p", this);
|
||||
};
|
||||
|
||||
public:
|
||||
inline std::shared_ptr<connection> get_connection() const {
|
||||
return conn_;
|
||||
}
|
||||
|
||||
inline void set_timer(detail::msg_dispatcher::timer_impl timer_impl) {
|
||||
dispatcher_.set_timer_impl(std::move(timer_impl));
|
||||
}
|
||||
|
||||
inline void set_ready(bool ready) {
|
||||
is_ready_ = ready;
|
||||
}
|
||||
|
||||
public:
|
||||
template <typename F>
|
||||
void subscribe(const cmd_type& cmd, RPC_CORE_MOVE_PARAM(F) handle) {
|
||||
constexpr bool F_ReturnIsEmpty = std::is_void<typename detail::callable_traits<F>::return_type>::value;
|
||||
constexpr bool F_ParamIsEmpty = detail::callable_traits<F>::argc == 0;
|
||||
subscribe_helper<F, F_ReturnIsEmpty, F_ParamIsEmpty>()(cmd, std::move(handle), &dispatcher_);
|
||||
}
|
||||
|
||||
inline void unsubscribe(const cmd_type& cmd) {
|
||||
dispatcher_.unsubscribe_cmd(cmd);
|
||||
}
|
||||
|
||||
public:
|
||||
inline request_s create_request() {
|
||||
return request::create(shared_from_this());
|
||||
}
|
||||
|
||||
inline request_s cmd(cmd_type cmd) {
|
||||
return create_request()->cmd(std::move(cmd));
|
||||
}
|
||||
|
||||
inline request_s ping(std::string payload = {}) { // NOLINT
|
||||
return create_request()->ping()->msg(std::move(payload));
|
||||
}
|
||||
|
||||
public:
|
||||
seq_type make_seq() override {
|
||||
return seq_++;
|
||||
}
|
||||
|
||||
void send_request(const request_s& request) override {
|
||||
if (request->need_rsp_) {
|
||||
dispatcher_.subscribe_rsp(request->seq_, request->rsp_handle_, request->timeout_cb_, request->timeout_ms_, request->is_ping_);
|
||||
}
|
||||
detail::msg_wrapper msg;
|
||||
msg.type = static_cast<detail::msg_wrapper::msg_type>(detail::msg_wrapper::command | (request->is_ping_ ? detail::msg_wrapper::ping : 0) |
|
||||
(request->need_rsp_ ? detail::msg_wrapper::need_rsp : 0));
|
||||
msg.cmd = request->cmd_;
|
||||
msg.seq = request->seq_;
|
||||
msg.request_payload = &request->payload_;
|
||||
RPC_CORE_LOGD("=> seq:%u type:%s %s", msg.seq, (msg.type & detail::msg_wrapper::msg_type::ping) ? "ping" : "cmd", msg.cmd.c_str());
|
||||
conn_->send_package_impl(detail::coder::serialize(msg));
|
||||
}
|
||||
|
||||
inline bool is_ready() const override {
|
||||
return is_ready_;
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename F, bool F_ReturnIsEmpty, bool F_ParamIsEmpty>
|
||||
struct subscribe_helper;
|
||||
|
||||
template <typename F>
|
||||
struct subscribe_helper<F, false, false> {
|
||||
void operator()(const cmd_type& cmd, RPC_CORE_MOVE_PARAM(F) handle, detail::msg_dispatcher* dispatcher) {
|
||||
dispatcher->subscribe_cmd(cmd, [RPC_CORE_MOVE_LAMBDA(handle)](const detail::msg_wrapper& msg) {
|
||||
using F_Param = detail::remove_cvref_t<typename detail::callable_traits<F>::template argument_type<0>>;
|
||||
using F_Return = detail::remove_cvref_t<typename detail::callable_traits<F>::return_type>;
|
||||
|
||||
auto r = msg.unpack_as<F_Param>();
|
||||
F_Return ret;
|
||||
if (r.first) {
|
||||
ret = handle(std::move(r.second));
|
||||
}
|
||||
return detail::msg_wrapper::make_rsp(msg.seq, &ret, r.first);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
template <typename F>
|
||||
struct subscribe_helper<F, true, false> {
|
||||
void operator()(const cmd_type& cmd, RPC_CORE_MOVE_PARAM(F) handle, detail::msg_dispatcher* dispatcher) {
|
||||
dispatcher->subscribe_cmd(cmd, [RPC_CORE_MOVE_LAMBDA(handle)](const detail::msg_wrapper& msg) {
|
||||
using F_Param = detail::remove_cvref_t<typename detail::callable_traits<F>::template argument_type<0>>;
|
||||
|
||||
auto r = msg.unpack_as<F_Param>();
|
||||
if (r.first) {
|
||||
handle(std::move(r.second));
|
||||
}
|
||||
return detail::msg_wrapper::make_rsp<uint8_t>(msg.seq, nullptr, r.first);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
template <typename F>
|
||||
struct subscribe_helper<F, false, true> {
|
||||
void operator()(const cmd_type& cmd, RPC_CORE_MOVE_PARAM(F) handle, detail::msg_dispatcher* dispatcher) {
|
||||
dispatcher->subscribe_cmd(cmd, [RPC_CORE_MOVE_LAMBDA(handle)](const detail::msg_wrapper& msg) {
|
||||
using F_Return = typename detail::callable_traits<F>::return_type;
|
||||
|
||||
F_Return ret = handle();
|
||||
return detail::msg_wrapper::make_rsp(msg.seq, &ret, true);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
template <typename F>
|
||||
struct subscribe_helper<F, true, true> {
|
||||
void operator()(const cmd_type& cmd, RPC_CORE_MOVE_PARAM(F) handle, detail::msg_dispatcher* dispatcher) {
|
||||
dispatcher->subscribe_cmd(cmd, [RPC_CORE_MOVE_LAMBDA(handle)](const detail::msg_wrapper& msg) {
|
||||
handle();
|
||||
return detail::msg_wrapper::make_rsp<uint8_t>(msg.seq, nullptr, true);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
private:
|
||||
std::shared_ptr<connection> conn_;
|
||||
detail::msg_dispatcher dispatcher_;
|
||||
seq_type seq_{0};
|
||||
bool is_ready_ = false;
|
||||
};
|
||||
|
||||
} // namespace rpc_core
|
34
3party/rpc_core/include/rpc_core/serialize.hpp
Normal file
34
3party/rpc_core/include/rpc_core/serialize.hpp
Normal file
@ -0,0 +1,34 @@
|
||||
#pragma once
|
||||
|
||||
// config
|
||||
#include "config.hpp"
|
||||
|
||||
// type traits
|
||||
#include "detail/type_traits.hpp"
|
||||
|
||||
// serialize type
|
||||
#include "serialize_type.hpp"
|
||||
|
||||
// raw type
|
||||
#include "serialize/type_raw.hpp"
|
||||
|
||||
// other types
|
||||
#include "serialize/binary_wrap.hpp"
|
||||
#include "serialize/std_array.hpp"
|
||||
#include "serialize/std_basic_string.hpp"
|
||||
#include "serialize/std_bitset.hpp"
|
||||
#include "serialize/std_chrono.hpp"
|
||||
#include "serialize/std_complex.hpp"
|
||||
#include "serialize/std_container_adaptors.hpp"
|
||||
#include "serialize/std_forward_list.hpp"
|
||||
#include "serialize/std_list_like.hpp"
|
||||
#include "serialize/std_map.hpp"
|
||||
#include "serialize/std_pair.hpp"
|
||||
#include "serialize/std_set.hpp"
|
||||
#include "serialize/std_shared_ptr.hpp"
|
||||
#include "serialize/std_tuple.hpp"
|
||||
#include "serialize/std_unique_ptr.hpp"
|
||||
#include "serialize/type_enum.hpp"
|
||||
#include "serialize/type_ptr.hpp"
|
||||
#include "serialize/type_struct.hpp"
|
||||
#include "serialize/type_void.hpp"
|
38
3party/rpc_core/include/rpc_core/serialize/binary_wrap.hpp
Normal file
38
3party/rpc_core/include/rpc_core/serialize/binary_wrap.hpp
Normal file
@ -0,0 +1,38 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
|
||||
namespace rpc_core {
|
||||
|
||||
struct binary_wrap {
|
||||
binary_wrap() = default;
|
||||
binary_wrap(void* data, size_t size) : data(data), size(size) {}
|
||||
void* data = nullptr;
|
||||
size_t size = 0;
|
||||
|
||||
// private:
|
||||
std::shared_ptr<uint8_t> _data_;
|
||||
};
|
||||
|
||||
template <typename T, typename std::enable_if<std::is_same<T, binary_wrap>::value, int>::type = 0>
|
||||
inline serialize_oarchive& operator>>(const T& t, serialize_oarchive& oa) {
|
||||
t.size >> oa;
|
||||
oa.data.append((char*)t.data, t.size);
|
||||
return oa;
|
||||
}
|
||||
|
||||
template <typename T, typename std::enable_if<std::is_same<T, binary_wrap>::value, int>::type = 0>
|
||||
inline serialize_iarchive& operator<<(T& t, serialize_iarchive& ia) {
|
||||
t.size << ia;
|
||||
t._data_ = std::shared_ptr<uint8_t>(new uint8_t[t.size], [](const uint8_t* p) {
|
||||
delete[] p;
|
||||
});
|
||||
t.data = t._data_.get();
|
||||
memcpy(t.data, ia.data, t.size);
|
||||
ia.data += t.size;
|
||||
ia.size -= t.size;
|
||||
return ia;
|
||||
}
|
||||
|
||||
} // namespace rpc_core
|
@ -0,0 +1,73 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
|
||||
namespace rpc_core {
|
||||
namespace detail {
|
||||
|
||||
template <typename int_impl_t>
|
||||
struct auto_size_type {
|
||||
explicit auto_size_type(int_impl_t value = 0) : value(value) {}
|
||||
|
||||
std::string serialize() const {
|
||||
if (value == 0) {
|
||||
return {(char*)&value, 1};
|
||||
}
|
||||
|
||||
uint8_t effective_bytes = sizeof(int_impl_t);
|
||||
auto value_tmp = value;
|
||||
if (value_tmp < 0) {
|
||||
value_tmp = -value_tmp;
|
||||
}
|
||||
for (int i = sizeof(int_impl_t) - 1; i >= 0; --i) {
|
||||
if ((value_tmp >> (i * 8)) & 0xff) {
|
||||
break;
|
||||
} else {
|
||||
--effective_bytes;
|
||||
}
|
||||
}
|
||||
|
||||
std::string ret;
|
||||
ret.resize(1 + effective_bytes);
|
||||
auto data = (uint8_t*)ret.data();
|
||||
data[0] = effective_bytes;
|
||||
memcpy(data + 1, &value_tmp, effective_bytes);
|
||||
if (value < 0) {
|
||||
data[0] |= 0x80;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int deserialize(const void* data) {
|
||||
auto p = (uint8_t*)data;
|
||||
uint8_t size_bytes = p[0];
|
||||
bool negative = false;
|
||||
if (size_bytes & 0x80) {
|
||||
negative = true;
|
||||
size_bytes &= 0x7f;
|
||||
}
|
||||
memcpy(&value, p + 1, size_bytes);
|
||||
if (negative) {
|
||||
value = -value;
|
||||
}
|
||||
return size_bytes + 1;
|
||||
}
|
||||
|
||||
int_impl_t value;
|
||||
};
|
||||
|
||||
using auto_size = auto_size_type<size_t>;
|
||||
using auto_intmax = auto_size_type<intmax_t>;
|
||||
using auto_uintmax = auto_size_type<uintmax_t>;
|
||||
|
||||
template <typename T>
|
||||
struct is_auto_size_type : std::false_type {};
|
||||
|
||||
template <typename T>
|
||||
struct is_auto_size_type<auto_size_type<T>> : std::true_type {};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace rpc_core
|
57
3party/rpc_core/include/rpc_core/serialize/std_array.hpp
Normal file
57
3party/rpc_core/include/rpc_core/serialize/std_array.hpp
Normal file
@ -0,0 +1,57 @@
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
|
||||
#include "../detail/callable/helpers.hpp"
|
||||
|
||||
namespace rpc_core {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <typename T>
|
||||
struct is_std_array : std::false_type {};
|
||||
|
||||
template <typename T, size_t Size>
|
||||
struct is_std_array<std::array<T, Size>> : std::true_type {};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <typename T, typename std::enable_if<detail::is_std_array<T>::value, int>::type = 0>
|
||||
serialize_oarchive& operator>>(const T& t, serialize_oarchive& oa) {
|
||||
detail::auto_size size(t.size());
|
||||
size >> oa;
|
||||
for (auto& item : t) {
|
||||
if (std::is_fundamental<detail::remove_cvref_t<decltype(item)>>::value) {
|
||||
item >> oa;
|
||||
} else {
|
||||
serialize_oarchive tmp;
|
||||
item >> tmp;
|
||||
tmp >> oa;
|
||||
}
|
||||
}
|
||||
return oa;
|
||||
}
|
||||
|
||||
template <typename T, typename std::enable_if<detail::is_std_array<T>::value, int>::type = 0>
|
||||
serialize_iarchive& operator<<(T& t, serialize_iarchive& ia) {
|
||||
detail::auto_size size;
|
||||
size << ia;
|
||||
for (size_t i = 0; i < size.value; ++i) {
|
||||
typename T::value_type item;
|
||||
if (std::is_fundamental<detail::remove_cvref_t<decltype(item)>>::value) {
|
||||
item << ia;
|
||||
} else {
|
||||
serialize_iarchive tmp;
|
||||
tmp << ia;
|
||||
item << tmp;
|
||||
if (tmp.error) {
|
||||
ia.error = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
t[i] = std::move(item);
|
||||
}
|
||||
return ia;
|
||||
}
|
||||
|
||||
} // namespace rpc_core
|
@ -0,0 +1,42 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace rpc_core {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <typename T>
|
||||
struct is_std_basic_string : std::false_type {};
|
||||
|
||||
template <typename... Args>
|
||||
struct is_std_basic_string<std::basic_string<Args...>> : std::true_type {};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <typename T, typename std::enable_if<detail::is_std_basic_string<T>::value, int>::type = 0>
|
||||
inline serialize_oarchive& operator>>(const T& t, serialize_oarchive& oa) {
|
||||
using VT = typename T::value_type;
|
||||
oa.data.append((char*)t.data(), t.size() * sizeof(VT));
|
||||
return oa;
|
||||
}
|
||||
|
||||
template <typename T, typename std::enable_if<detail::is_std_basic_string<T>::value, int>::type = 0>
|
||||
inline serialize_oarchive& operator>>(T&& t, serialize_oarchive& oa) {
|
||||
using VT = typename T::value_type;
|
||||
if (oa.data.empty()) {
|
||||
oa.data = std::forward<T>(t);
|
||||
} else {
|
||||
oa.data.append((char*)t.data(), t.size() * sizeof(VT));
|
||||
}
|
||||
return oa;
|
||||
}
|
||||
|
||||
template <typename T, typename std::enable_if<detail::is_std_basic_string<T>::value, int>::type = 0>
|
||||
inline serialize_iarchive& operator<<(T& t, serialize_iarchive& ia) {
|
||||
using VT = typename T::value_type;
|
||||
t = T((VT*)(ia.data), ia.size / sizeof(VT));
|
||||
return ia;
|
||||
}
|
||||
|
||||
} // namespace rpc_core
|
33
3party/rpc_core/include/rpc_core/serialize/std_bitset.hpp
Normal file
33
3party/rpc_core/include/rpc_core/serialize/std_bitset.hpp
Normal file
@ -0,0 +1,33 @@
|
||||
#pragma once
|
||||
|
||||
#include <bitset>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
|
||||
namespace rpc_core {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <typename T>
|
||||
struct is_std_bitset : std::false_type {};
|
||||
|
||||
template <std::size_t N>
|
||||
struct is_std_bitset<std::bitset<N>> : std::true_type {};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <typename T, typename std::enable_if<detail::is_std_bitset<T>::value, int>::type = 0>
|
||||
serialize_oarchive& operator>>(const T& t, serialize_oarchive& oa) {
|
||||
oa.data.append(t.to_string());
|
||||
return oa;
|
||||
}
|
||||
|
||||
template <typename T, typename std::enable_if<detail::is_std_bitset<T>::value, int>::type = 0>
|
||||
serialize_iarchive& operator<<(T& t, serialize_iarchive& ia) {
|
||||
std::string tmp;
|
||||
tmp << ia;
|
||||
t = T(std::move(tmp));
|
||||
return ia;
|
||||
}
|
||||
|
||||
} // namespace rpc_core
|
53
3party/rpc_core/include/rpc_core/serialize/std_chrono.hpp
Normal file
53
3party/rpc_core/include/rpc_core/serialize/std_chrono.hpp
Normal file
@ -0,0 +1,53 @@
|
||||
#pragma once
|
||||
|
||||
#include <chrono>
|
||||
#include <type_traits>
|
||||
|
||||
namespace rpc_core {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <typename T>
|
||||
struct is_std_chrono_duration : std::false_type {};
|
||||
|
||||
template <typename... Args>
|
||||
struct is_std_chrono_duration<std::chrono::duration<Args...>> : std::true_type {};
|
||||
|
||||
template <typename T>
|
||||
struct is_std_chrono_time_point : std::false_type {};
|
||||
|
||||
template <typename... Args>
|
||||
struct is_std_chrono_time_point<std::chrono::time_point<Args...>> : std::true_type {};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <typename T, typename std::enable_if<detail::is_std_chrono_duration<T>::value, int>::type = 0>
|
||||
serialize_oarchive& operator>>(const T& t, serialize_oarchive& oa) {
|
||||
detail::auto_intmax count(t.count());
|
||||
count >> oa;
|
||||
return oa;
|
||||
}
|
||||
|
||||
template <typename T, typename std::enable_if<detail::is_std_chrono_duration<T>::value, int>::type = 0>
|
||||
serialize_iarchive& operator<<(T& t, serialize_iarchive& ia) {
|
||||
detail::auto_intmax rep;
|
||||
rep << ia;
|
||||
t = T(rep.value);
|
||||
return ia;
|
||||
}
|
||||
|
||||
template <typename T, typename std::enable_if<detail::is_std_chrono_time_point<T>::value, int>::type = 0>
|
||||
serialize_oarchive& operator>>(const T& t, serialize_oarchive& oa) {
|
||||
t.time_since_epoch() >> oa;
|
||||
return oa;
|
||||
}
|
||||
|
||||
template <typename T, typename std::enable_if<detail::is_std_chrono_time_point<T>::value, int>::type = 0>
|
||||
serialize_iarchive& operator<<(T& t, serialize_iarchive& ia) {
|
||||
typename T::duration duration;
|
||||
duration << ia;
|
||||
t = T(duration);
|
||||
return ia;
|
||||
}
|
||||
|
||||
} // namespace rpc_core
|
52
3party/rpc_core/include/rpc_core/serialize/std_complex.hpp
Normal file
52
3party/rpc_core/include/rpc_core/serialize/std_complex.hpp
Normal file
@ -0,0 +1,52 @@
|
||||
#pragma once
|
||||
|
||||
#include <complex>
|
||||
#include <type_traits>
|
||||
|
||||
namespace rpc_core {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <typename T>
|
||||
struct is_std_complex : std::false_type {};
|
||||
|
||||
template <typename T>
|
||||
struct is_std_complex<std::complex<T>> : std::true_type {};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <typename T, typename std::enable_if<detail::is_std_complex<T>::value, int>::type = 0>
|
||||
serialize_oarchive& operator>>(const T& t, serialize_oarchive& oa) {
|
||||
using VT = typename T::value_type;
|
||||
if (std::is_fundamental<VT>::value) {
|
||||
t.real() >> oa;
|
||||
t.imag() >> oa;
|
||||
} else {
|
||||
oa & t.real();
|
||||
oa & t.imag();
|
||||
}
|
||||
return oa;
|
||||
}
|
||||
|
||||
template <typename T, typename std::enable_if<detail::is_std_complex<T>::value, int>::type = 0>
|
||||
serialize_iarchive& operator<<(T& t, serialize_iarchive& ia) {
|
||||
using VT = typename T::value_type;
|
||||
if (std::is_fundamental<VT>::value) {
|
||||
VT real;
|
||||
real << ia;
|
||||
t.real(real);
|
||||
VT imag;
|
||||
imag << ia;
|
||||
t.imag(imag);
|
||||
} else {
|
||||
VT real;
|
||||
ia & real;
|
||||
t.real(std::move(real));
|
||||
VT imag;
|
||||
ia & imag;
|
||||
t.imag(std::move(imag));
|
||||
}
|
||||
return ia;
|
||||
}
|
||||
|
||||
} // namespace rpc_core
|
@ -0,0 +1,36 @@
|
||||
#pragma once
|
||||
|
||||
#include <queue>
|
||||
#include <stack>
|
||||
|
||||
namespace rpc_core {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <typename T>
|
||||
struct is_std_stack : std::false_type {};
|
||||
|
||||
template <typename... Args>
|
||||
struct is_std_stack<std::stack<Args...>> : std::true_type {};
|
||||
|
||||
template <typename... Args>
|
||||
struct is_std_stack<std::queue<Args...>> : std::true_type {};
|
||||
|
||||
template <typename... Args>
|
||||
struct is_std_stack<std::priority_queue<Args...>> : std::true_type {};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <typename T, typename std::enable_if<detail::is_std_stack<T>::value, int>::type = 0>
|
||||
serialize_oarchive& operator>>(const T& t, serialize_oarchive& oa) {
|
||||
(typename T::container_type&)t >> oa;
|
||||
return oa;
|
||||
}
|
||||
|
||||
template <typename T, typename std::enable_if<detail::is_std_stack<T>::value, int>::type = 0>
|
||||
serialize_iarchive& operator<<(T& t, serialize_iarchive& ia) {
|
||||
(typename T::container_type&)t << ia;
|
||||
return ia;
|
||||
}
|
||||
|
||||
} // namespace rpc_core
|
@ -0,0 +1,58 @@
|
||||
#pragma once
|
||||
|
||||
#include <forward_list>
|
||||
|
||||
#include "../detail/callable/helpers.hpp"
|
||||
|
||||
namespace rpc_core {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <typename T>
|
||||
struct is_std_forward_list : std::false_type {};
|
||||
|
||||
template <typename... Args>
|
||||
struct is_std_forward_list<std::forward_list<Args...>> : std::true_type {};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <typename T, typename std::enable_if<detail::is_std_forward_list<T>::value, int>::type = 0>
|
||||
serialize_oarchive& operator>>(const T& t, serialize_oarchive& oa) {
|
||||
detail::auto_size size(std::distance(t.cbegin(), t.cend()));
|
||||
size >> oa;
|
||||
for (auto& item : t) {
|
||||
if (std::is_fundamental<detail::remove_cvref_t<decltype(item)>>::value) {
|
||||
item >> oa;
|
||||
} else {
|
||||
serialize_oarchive tmp;
|
||||
item >> tmp;
|
||||
tmp >> oa;
|
||||
}
|
||||
}
|
||||
return oa;
|
||||
}
|
||||
|
||||
template <typename T, typename std::enable_if<detail::is_std_forward_list<T>::value, int>::type = 0>
|
||||
serialize_iarchive& operator<<(T& t, serialize_iarchive& ia) {
|
||||
detail::auto_size size;
|
||||
size << ia;
|
||||
for (size_t i = 0; i < size.value; ++i) {
|
||||
typename T::value_type item;
|
||||
if (std::is_fundamental<detail::remove_cvref_t<decltype(item)>>::value) {
|
||||
item << ia;
|
||||
} else {
|
||||
serialize_iarchive tmp;
|
||||
tmp << ia;
|
||||
item << tmp;
|
||||
if (tmp.error) {
|
||||
ia.error = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
t.emplace_front(std::move(item));
|
||||
}
|
||||
t.reverse();
|
||||
return ia;
|
||||
}
|
||||
|
||||
} // namespace rpc_core
|
63
3party/rpc_core/include/rpc_core/serialize/std_list_like.hpp
Normal file
63
3party/rpc_core/include/rpc_core/serialize/std_list_like.hpp
Normal file
@ -0,0 +1,63 @@
|
||||
#pragma once
|
||||
|
||||
#include <deque>
|
||||
#include <list>
|
||||
#include <vector>
|
||||
|
||||
namespace rpc_core {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <typename T>
|
||||
struct is_std_list_like : std::false_type {};
|
||||
|
||||
template <typename... Args>
|
||||
struct is_std_list_like<std::vector<Args...>> : std::true_type {};
|
||||
|
||||
template <typename... Args>
|
||||
struct is_std_list_like<std::list<Args...>> : std::true_type {};
|
||||
|
||||
template <typename... Args>
|
||||
struct is_std_list_like<std::deque<Args...>> : std::true_type {};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <typename T, typename std::enable_if<detail::is_std_list_like<T>::value, int>::type = 0>
|
||||
serialize_oarchive& operator>>(const T& t, serialize_oarchive& oa) {
|
||||
detail::auto_size size(t.size());
|
||||
size >> oa;
|
||||
for (auto& item : t) {
|
||||
if (std::is_fundamental<detail::remove_cvref_t<decltype(item)>>::value) {
|
||||
item >> oa;
|
||||
} else {
|
||||
serialize_oarchive tmp;
|
||||
item >> tmp;
|
||||
tmp >> oa;
|
||||
}
|
||||
}
|
||||
return oa;
|
||||
}
|
||||
|
||||
template <typename T, typename std::enable_if<detail::is_std_list_like<T>::value, int>::type = 0>
|
||||
serialize_iarchive& operator<<(T& t, serialize_iarchive& ia) {
|
||||
detail::auto_size size;
|
||||
size << ia;
|
||||
for (size_t i = 0; i < size.value; ++i) {
|
||||
typename T::value_type item;
|
||||
if (std::is_fundamental<detail::remove_cvref_t<decltype(item)>>::value) {
|
||||
item << ia;
|
||||
} else {
|
||||
serialize_iarchive tmp;
|
||||
tmp << ia;
|
||||
item << tmp;
|
||||
if (tmp.error) {
|
||||
ia.error = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
t.emplace_back(std::move(item));
|
||||
}
|
||||
return ia;
|
||||
}
|
||||
|
||||
} // namespace rpc_core
|
57
3party/rpc_core/include/rpc_core/serialize/std_map.hpp
Normal file
57
3party/rpc_core/include/rpc_core/serialize/std_map.hpp
Normal file
@ -0,0 +1,57 @@
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace rpc_core {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <typename T>
|
||||
struct is_std_map_like : std::false_type {};
|
||||
|
||||
template <typename... Args>
|
||||
struct is_std_map_like<std::map<Args...>> : std::true_type {};
|
||||
|
||||
template <typename... Args>
|
||||
struct is_std_map_like<std::unordered_map<Args...>> : std::true_type {};
|
||||
|
||||
template <typename... Args>
|
||||
struct is_std_map_like<std::multimap<Args...>> : std::true_type {};
|
||||
|
||||
template <typename... Args>
|
||||
struct is_std_map_like<std::unordered_multimap<Args...>> : std::true_type {};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <typename T, typename std::enable_if<detail::is_std_map_like<T>::value, int>::type = 0>
|
||||
serialize_oarchive& operator>>(const T& t, serialize_oarchive& oa) {
|
||||
detail::auto_size size(t.size());
|
||||
size >> oa;
|
||||
for (auto& item : t) {
|
||||
serialize_oarchive tmp;
|
||||
item >> tmp;
|
||||
tmp >> oa;
|
||||
}
|
||||
return oa;
|
||||
}
|
||||
|
||||
template <typename T, typename std::enable_if<detail::is_std_map_like<T>::value, int>::type = 0>
|
||||
serialize_iarchive& operator<<(T& t, serialize_iarchive& ia) {
|
||||
detail::auto_size size;
|
||||
size << ia;
|
||||
for (size_t i = 0; i < size.value; ++i) {
|
||||
typename T::value_type item;
|
||||
serialize_iarchive tmp;
|
||||
tmp << ia;
|
||||
item << tmp;
|
||||
if (tmp.error) {
|
||||
ia.error = true;
|
||||
break;
|
||||
}
|
||||
t.emplace(std::move(item));
|
||||
}
|
||||
return ia;
|
||||
}
|
||||
|
||||
} // namespace rpc_core
|
34
3party/rpc_core/include/rpc_core/serialize/std_pair.hpp
Normal file
34
3party/rpc_core/include/rpc_core/serialize/std_pair.hpp
Normal file
@ -0,0 +1,34 @@
|
||||
#pragma once
|
||||
|
||||
#include <tuple>
|
||||
|
||||
namespace rpc_core {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <typename T>
|
||||
struct is_std_pair : std::false_type {};
|
||||
|
||||
template <typename... Args>
|
||||
struct is_std_pair<std::pair<Args...>> : std::true_type {};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <typename T, typename std::enable_if<detail::is_std_pair<T>::value, int>::type = 0>
|
||||
inline serialize_oarchive& operator>>(const T& t, serialize_oarchive& oa) {
|
||||
std::tie(t.first, t.second) >> oa;
|
||||
return oa;
|
||||
}
|
||||
|
||||
template <typename T, typename std::enable_if<detail::is_std_pair<T>::value, int>::type = 0>
|
||||
serialize_iarchive& operator<<(T& t, serialize_iarchive& ia) {
|
||||
using first_type = detail::remove_cvref_t<decltype(t.first)>;
|
||||
using second_type = detail::remove_cvref_t<decltype(t.second)>;
|
||||
auto& tt = (std::pair<first_type, second_type>&)t;
|
||||
std::tuple<first_type, second_type> tup;
|
||||
tup << ia;
|
||||
std::tie(tt.first, tt.second) = std::move(tup);
|
||||
return ia;
|
||||
}
|
||||
|
||||
} // namespace rpc_core
|
65
3party/rpc_core/include/rpc_core/serialize/std_set.hpp
Normal file
65
3party/rpc_core/include/rpc_core/serialize/std_set.hpp
Normal file
@ -0,0 +1,65 @@
|
||||
#pragma once
|
||||
|
||||
#include <set>
|
||||
#include <unordered_set>
|
||||
|
||||
namespace rpc_core {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <typename T>
|
||||
struct is_std_set_like : std::false_type {};
|
||||
|
||||
template <typename... Args>
|
||||
struct is_std_set_like<std::set<Args...>> : std::true_type {};
|
||||
|
||||
template <typename... Args>
|
||||
struct is_std_set_like<std::unordered_set<Args...>> : std::true_type {};
|
||||
|
||||
template <typename... Args>
|
||||
struct is_std_set_like<std::multiset<Args...>> : std::true_type {};
|
||||
|
||||
template <typename... Args>
|
||||
struct is_std_set_like<std::unordered_multiset<Args...>> : std::true_type {};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <typename T, typename std::enable_if<detail::is_std_set_like<T>::value, int>::type = 0>
|
||||
serialize_oarchive& operator>>(const T& t, serialize_oarchive& oa) {
|
||||
detail::auto_size size(t.size());
|
||||
size >> oa;
|
||||
for (auto& item : t) {
|
||||
if (std::is_fundamental<detail::remove_cvref_t<decltype(item)>>::value) {
|
||||
item >> oa;
|
||||
} else {
|
||||
serialize_oarchive tmp;
|
||||
item >> tmp;
|
||||
tmp >> oa;
|
||||
}
|
||||
}
|
||||
return oa;
|
||||
}
|
||||
|
||||
template <typename T, typename std::enable_if<detail::is_std_set_like<T>::value, int>::type = 0>
|
||||
serialize_iarchive& operator<<(T& t, serialize_iarchive& ia) {
|
||||
detail::auto_size size;
|
||||
size << ia;
|
||||
for (size_t i = 0; i < size.value; ++i) {
|
||||
typename T::value_type item;
|
||||
if (std::is_fundamental<detail::remove_cvref_t<decltype(item)>>::value) {
|
||||
item << ia;
|
||||
} else {
|
||||
serialize_iarchive tmp;
|
||||
tmp << ia;
|
||||
item << tmp;
|
||||
if (tmp.error) {
|
||||
ia.error = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
t.emplace(std::move(item));
|
||||
}
|
||||
return ia;
|
||||
}
|
||||
|
||||
} // namespace rpc_core
|
@ -0,0 +1,40 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace rpc_core {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <typename T>
|
||||
struct is_std_shared_ptr : std::false_type {};
|
||||
|
||||
template <typename... Args>
|
||||
struct is_std_shared_ptr<std::shared_ptr<Args...>> : std::true_type {};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <typename T, typename std::enable_if<detail::is_std_shared_ptr<T>::value, int>::type = 0>
|
||||
inline serialize_oarchive& operator>>(const T& t, serialize_oarchive& oa) {
|
||||
if (t != nullptr) {
|
||||
true >> oa;
|
||||
*t >> oa;
|
||||
} else {
|
||||
false >> oa;
|
||||
}
|
||||
return oa;
|
||||
}
|
||||
|
||||
template <typename T, typename std::enable_if<detail::is_std_shared_ptr<T>::value, int>::type = 0>
|
||||
inline serialize_iarchive& operator<<(T& t, serialize_iarchive& ia) {
|
||||
bool notnull;
|
||||
notnull << ia;
|
||||
if (notnull) {
|
||||
using Type = typename T::element_type;
|
||||
t = std::make_shared<Type>();
|
||||
*t << ia;
|
||||
}
|
||||
return ia;
|
||||
}
|
||||
|
||||
} // namespace rpc_core
|
147
3party/rpc_core/include/rpc_core/serialize/std_tuple.hpp
Normal file
147
3party/rpc_core/include/rpc_core/serialize/std_tuple.hpp
Normal file
@ -0,0 +1,147 @@
|
||||
#pragma once
|
||||
|
||||
#include <tuple>
|
||||
|
||||
#include "../detail/callable/helpers.hpp"
|
||||
|
||||
namespace rpc_core {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <std::size_t I, typename T>
|
||||
using tuple_element_t = detail::remove_cvref_t<typename std::tuple_element<I, detail::remove_cvref_t<T>>::type>;
|
||||
|
||||
template <typename T>
|
||||
struct is_tuple : std::false_type {};
|
||||
|
||||
template <typename... Args>
|
||||
struct is_tuple<std::tuple<Args...>> : std::true_type {};
|
||||
|
||||
template <typename T>
|
||||
struct is_std_ignore {
|
||||
static const bool value = std::is_same<detail::remove_cvref_t<decltype(std::ignore)>, T>::value;
|
||||
};
|
||||
|
||||
enum class tuple_serialize_type {
|
||||
Ignore,
|
||||
RawType,
|
||||
Normal,
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct tuple_serialize_type_check {
|
||||
static constexpr tuple_serialize_type value = std::is_fundamental<T>::value ? tuple_serialize_type::RawType
|
||||
: is_std_ignore<T>::value ? tuple_serialize_type::Ignore
|
||||
: tuple_serialize_type::Normal;
|
||||
};
|
||||
|
||||
template <typename Tuple, std::size_t I, tuple_serialize_type type>
|
||||
struct tuple_serialize_helper_impl;
|
||||
|
||||
template <typename Tuple, std::size_t I>
|
||||
struct tuple_serialize_helper_impl<Tuple, I, tuple_serialize_type::Normal> {
|
||||
static void serialize(const Tuple& t, serialize_oarchive& oa) {
|
||||
serialize_oarchive tmp;
|
||||
std::get<I>(t) >> tmp;
|
||||
tmp >> oa;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Tuple, std::size_t I>
|
||||
struct tuple_serialize_helper_impl<Tuple, I, tuple_serialize_type::RawType> {
|
||||
static void serialize(const Tuple& t, serialize_oarchive& oa) {
|
||||
std::get<I>(t) >> oa;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Tuple, std::size_t I>
|
||||
struct tuple_serialize_helper_impl<Tuple, I, tuple_serialize_type::Ignore> {
|
||||
static void serialize(const Tuple& t, serialize_oarchive& oa) {
|
||||
RPC_CORE_UNUSED(t);
|
||||
RPC_CORE_UNUSED(oa);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Tuple, std::size_t N>
|
||||
struct tuple_serialize_helper {
|
||||
static void serialize(const Tuple& t, serialize_oarchive& oa) {
|
||||
tuple_serialize_helper<Tuple, N - 1>::serialize(t, oa);
|
||||
tuple_serialize_helper_impl<Tuple, N - 1, tuple_serialize_type_check<tuple_element_t<N - 1, Tuple>>::value>::serialize(t, oa);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Tuple>
|
||||
struct tuple_serialize_helper<Tuple, 1> {
|
||||
static void serialize(const Tuple& t, serialize_oarchive& oa) {
|
||||
tuple_serialize_helper_impl<Tuple, 0, tuple_serialize_type_check<tuple_element_t<0, Tuple>>::value>::serialize(t, oa);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename... Args>
|
||||
void tuple_serialize(const std::tuple<Args...>& t, serialize_oarchive& oa) {
|
||||
tuple_serialize_helper<decltype(t), sizeof...(Args)>::serialize(t, oa);
|
||||
}
|
||||
|
||||
template <typename Tuple, std::size_t I, tuple_serialize_type type>
|
||||
struct tuple_de_serialize_helper_impl;
|
||||
|
||||
template <typename Tuple, std::size_t I>
|
||||
struct tuple_de_serialize_helper_impl<Tuple, I, tuple_serialize_type::Normal> {
|
||||
static void de_serialize(Tuple& t, serialize_iarchive& ia) {
|
||||
serialize_iarchive tmp;
|
||||
tmp << ia;
|
||||
std::get<I>(t) << tmp;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Tuple, std::size_t I>
|
||||
struct tuple_de_serialize_helper_impl<Tuple, I, tuple_serialize_type::RawType> {
|
||||
static void de_serialize(Tuple& t, serialize_iarchive& ia) {
|
||||
std::get<I>(t) << ia;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Tuple, std::size_t I>
|
||||
struct tuple_de_serialize_helper_impl<Tuple, I, tuple_serialize_type::Ignore> {
|
||||
static void de_serialize(Tuple& t, serialize_iarchive& ia) {
|
||||
RPC_CORE_UNUSED(t);
|
||||
RPC_CORE_UNUSED(ia);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Tuple, std::size_t N>
|
||||
struct tuple_de_serialize_helper {
|
||||
static void de_serialize(Tuple& t, serialize_iarchive& ia) {
|
||||
tuple_de_serialize_helper<Tuple, N - 1>::de_serialize(t, ia);
|
||||
if (ia.error) return;
|
||||
tuple_de_serialize_helper_impl<Tuple, N - 1, tuple_serialize_type_check<tuple_element_t<N - 1, Tuple>>::value>::de_serialize(t, ia);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Tuple>
|
||||
struct tuple_de_serialize_helper<Tuple, 1> {
|
||||
static void de_serialize(Tuple& t, serialize_iarchive& ia) {
|
||||
tuple_de_serialize_helper_impl<Tuple, 0, tuple_serialize_type_check<tuple_element_t<0, Tuple>>::value>::de_serialize(t, ia);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename... Args>
|
||||
void tuple_de_serialize(std::tuple<Args...>& t, serialize_iarchive& ia) {
|
||||
tuple_de_serialize_helper<decltype(t), sizeof...(Args)>::de_serialize(t, ia);
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <typename T, typename std::enable_if<detail::is_tuple<T>::value, int>::type = 0>
|
||||
serialize_oarchive& operator>>(const T& t, serialize_oarchive& oa) {
|
||||
detail::tuple_serialize(t, oa);
|
||||
return oa;
|
||||
}
|
||||
|
||||
template <typename T, typename std::enable_if<detail::is_tuple<T>::value, int>::type = 0>
|
||||
serialize_iarchive& operator<<(T& t, serialize_iarchive& ia) {
|
||||
detail::tuple_de_serialize(t, ia);
|
||||
return ia;
|
||||
}
|
||||
|
||||
} // namespace rpc_core
|
@ -0,0 +1,40 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace rpc_core {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <typename T>
|
||||
struct is_std_unique_ptr : std::false_type {};
|
||||
|
||||
template <typename... Args>
|
||||
struct is_std_unique_ptr<std::unique_ptr<Args...>> : std::true_type {};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <typename T, typename std::enable_if<detail::is_std_unique_ptr<T>::value, int>::type = 0>
|
||||
inline serialize_oarchive& operator>>(const T& t, serialize_oarchive& oa) {
|
||||
if (t != nullptr) {
|
||||
true >> oa;
|
||||
*t >> oa;
|
||||
} else {
|
||||
false >> oa;
|
||||
}
|
||||
return oa;
|
||||
}
|
||||
|
||||
template <typename T, typename std::enable_if<detail::is_std_unique_ptr<T>::value, int>::type = 0>
|
||||
inline serialize_iarchive& operator<<(T& t, serialize_iarchive& ia) {
|
||||
bool notnull;
|
||||
notnull << ia;
|
||||
if (notnull) {
|
||||
using Type = typename T::element_type;
|
||||
t = std::unique_ptr<Type>(new Type);
|
||||
*t << ia;
|
||||
}
|
||||
return ia;
|
||||
}
|
||||
|
||||
} // namespace rpc_core
|
20
3party/rpc_core/include/rpc_core/serialize/type_enum.hpp
Normal file
20
3party/rpc_core/include/rpc_core/serialize/type_enum.hpp
Normal file
@ -0,0 +1,20 @@
|
||||
#pragma once
|
||||
|
||||
namespace rpc_core {
|
||||
|
||||
template <typename T, typename std::enable_if<std::is_enum<T>::value, int>::type = 0>
|
||||
inline serialize_oarchive& operator>>(const T& t, serialize_oarchive& oa) {
|
||||
detail::auto_uintmax impl((uintmax_t)t);
|
||||
impl >> oa;
|
||||
return oa;
|
||||
}
|
||||
|
||||
template <typename T, typename std::enable_if<std::is_enum<T>::value, int>::type = 0>
|
||||
inline serialize_iarchive& operator<<(T& t, serialize_iarchive& ia) {
|
||||
detail::auto_uintmax impl;
|
||||
impl << ia;
|
||||
t = (T)impl.value;
|
||||
return ia;
|
||||
}
|
||||
|
||||
} // namespace rpc_core
|
22
3party/rpc_core/include/rpc_core/serialize/type_ptr.hpp
Normal file
22
3party/rpc_core/include/rpc_core/serialize/type_ptr.hpp
Normal file
@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace rpc_core {
|
||||
|
||||
template <typename T, typename std::enable_if<std::is_pointer<T>::value, int>::type = 0>
|
||||
inline serialize_oarchive& operator>>(const T& t, serialize_oarchive& oa) {
|
||||
auto ptr = (intptr_t)t;
|
||||
ptr >> oa;
|
||||
return oa;
|
||||
}
|
||||
|
||||
template <typename T, typename std::enable_if<std::is_pointer<T>::value, int>::type = 0>
|
||||
inline serialize_iarchive& operator<<(T& t, serialize_iarchive& ia) {
|
||||
intptr_t ptr;
|
||||
ptr << ia;
|
||||
t = (T)ptr;
|
||||
return ia;
|
||||
}
|
||||
|
||||
} // namespace rpc_core
|
54
3party/rpc_core/include/rpc_core/serialize/type_raw.hpp
Normal file
54
3party/rpc_core/include/rpc_core/serialize/type_raw.hpp
Normal file
@ -0,0 +1,54 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstring>
|
||||
#include <type_traits>
|
||||
|
||||
#include "detail/auto_size.hpp"
|
||||
|
||||
#define RPC_CORE_DETAIL_DEFINE_RAW_TYPE(type_raw, type_size) \
|
||||
static_assert(sizeof(type_raw) <= type_size, ""); \
|
||||
inline serialize_oarchive& operator>>(const type_raw& t, serialize_oarchive& oa) { \
|
||||
oa.data.append((char*)&t, type_size); \
|
||||
return oa; \
|
||||
} \
|
||||
inline serialize_iarchive& operator<<(type_raw& t, serialize_iarchive& ia) { \
|
||||
t = {}; \
|
||||
memcpy(&t, ia.data, detail::min<size_t>(sizeof(t), type_size)); \
|
||||
ia.data += type_size; \
|
||||
ia.size -= type_size; \
|
||||
return ia; \
|
||||
}
|
||||
|
||||
#define RPC_CORE_DETAIL_DEFINE_RAW_TYPE_AUTO_SIZE(type_raw, type_auto) \
|
||||
inline serialize_oarchive& operator>>(const type_raw& t, serialize_oarchive& oa) { \
|
||||
type_auto impl(t); \
|
||||
impl >> oa; \
|
||||
return oa; \
|
||||
} \
|
||||
inline serialize_iarchive& operator<<(type_raw& t, serialize_iarchive& ia) { \
|
||||
type_auto impl; \
|
||||
impl << ia; \
|
||||
t = impl.value; \
|
||||
return ia; \
|
||||
}
|
||||
|
||||
namespace rpc_core {
|
||||
|
||||
RPC_CORE_DETAIL_DEFINE_RAW_TYPE(bool, 1);
|
||||
RPC_CORE_DETAIL_DEFINE_RAW_TYPE(char, 1);
|
||||
RPC_CORE_DETAIL_DEFINE_RAW_TYPE(signed char, 1);
|
||||
RPC_CORE_DETAIL_DEFINE_RAW_TYPE(unsigned char, 1);
|
||||
RPC_CORE_DETAIL_DEFINE_RAW_TYPE(short, 2);
|
||||
RPC_CORE_DETAIL_DEFINE_RAW_TYPE(unsigned short, 2);
|
||||
RPC_CORE_DETAIL_DEFINE_RAW_TYPE_AUTO_SIZE(int, detail::auto_intmax);
|
||||
RPC_CORE_DETAIL_DEFINE_RAW_TYPE_AUTO_SIZE(unsigned int, detail::auto_uintmax);
|
||||
RPC_CORE_DETAIL_DEFINE_RAW_TYPE_AUTO_SIZE(long, detail::auto_intmax);
|
||||
RPC_CORE_DETAIL_DEFINE_RAW_TYPE_AUTO_SIZE(unsigned long, detail::auto_uintmax);
|
||||
RPC_CORE_DETAIL_DEFINE_RAW_TYPE_AUTO_SIZE(long long, detail::auto_intmax);
|
||||
RPC_CORE_DETAIL_DEFINE_RAW_TYPE_AUTO_SIZE(unsigned long long, detail::auto_uintmax);
|
||||
|
||||
RPC_CORE_DETAIL_DEFINE_RAW_TYPE(float, 4);
|
||||
RPC_CORE_DETAIL_DEFINE_RAW_TYPE(double, 8);
|
||||
RPC_CORE_DETAIL_DEFINE_RAW_TYPE(long double, 16);
|
||||
|
||||
} // namespace rpc_core
|
200
3party/rpc_core/include/rpc_core/serialize/type_struct.hpp
Normal file
200
3party/rpc_core/include/rpc_core/serialize/type_struct.hpp
Normal file
@ -0,0 +1,200 @@
|
||||
#pragma once
|
||||
|
||||
// clang-format off
|
||||
#define RPC_CORE_DETAIL_SERIALIZE_GET_MACRO(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, NAME,...) NAME
|
||||
#define RPC_CORE_DETAIL_SERIALIZE_PASTE(...) RPC_CORE_DETAIL_SERIALIZE_GET_MACRO(__VA_ARGS__, \
|
||||
RPC_CORE_DETAIL_SERIALIZE_PASTE64, \
|
||||
RPC_CORE_DETAIL_SERIALIZE_PASTE63, \
|
||||
RPC_CORE_DETAIL_SERIALIZE_PASTE62, \
|
||||
RPC_CORE_DETAIL_SERIALIZE_PASTE61, \
|
||||
RPC_CORE_DETAIL_SERIALIZE_PASTE60, \
|
||||
RPC_CORE_DETAIL_SERIALIZE_PASTE59, \
|
||||
RPC_CORE_DETAIL_SERIALIZE_PASTE58, \
|
||||
RPC_CORE_DETAIL_SERIALIZE_PASTE57, \
|
||||
RPC_CORE_DETAIL_SERIALIZE_PASTE56, \
|
||||
RPC_CORE_DETAIL_SERIALIZE_PASTE55, \
|
||||
RPC_CORE_DETAIL_SERIALIZE_PASTE54, \
|
||||
RPC_CORE_DETAIL_SERIALIZE_PASTE53, \
|
||||
RPC_CORE_DETAIL_SERIALIZE_PASTE52, \
|
||||
RPC_CORE_DETAIL_SERIALIZE_PASTE51, \
|
||||
RPC_CORE_DETAIL_SERIALIZE_PASTE50, \
|
||||
RPC_CORE_DETAIL_SERIALIZE_PASTE49, \
|
||||
RPC_CORE_DETAIL_SERIALIZE_PASTE48, \
|
||||
RPC_CORE_DETAIL_SERIALIZE_PASTE47, \
|
||||
RPC_CORE_DETAIL_SERIALIZE_PASTE46, \
|
||||
RPC_CORE_DETAIL_SERIALIZE_PASTE45, \
|
||||
RPC_CORE_DETAIL_SERIALIZE_PASTE44, \
|
||||
RPC_CORE_DETAIL_SERIALIZE_PASTE43, \
|
||||
RPC_CORE_DETAIL_SERIALIZE_PASTE42, \
|
||||
RPC_CORE_DETAIL_SERIALIZE_PASTE41, \
|
||||
RPC_CORE_DETAIL_SERIALIZE_PASTE40, \
|
||||
RPC_CORE_DETAIL_SERIALIZE_PASTE39, \
|
||||
RPC_CORE_DETAIL_SERIALIZE_PASTE38, \
|
||||
RPC_CORE_DETAIL_SERIALIZE_PASTE37, \
|
||||
RPC_CORE_DETAIL_SERIALIZE_PASTE36, \
|
||||
RPC_CORE_DETAIL_SERIALIZE_PASTE35, \
|
||||
RPC_CORE_DETAIL_SERIALIZE_PASTE34, \
|
||||
RPC_CORE_DETAIL_SERIALIZE_PASTE33, \
|
||||
RPC_CORE_DETAIL_SERIALIZE_PASTE32, \
|
||||
RPC_CORE_DETAIL_SERIALIZE_PASTE31, \
|
||||
RPC_CORE_DETAIL_SERIALIZE_PASTE30, \
|
||||
RPC_CORE_DETAIL_SERIALIZE_PASTE29, \
|
||||
RPC_CORE_DETAIL_SERIALIZE_PASTE28, \
|
||||
RPC_CORE_DETAIL_SERIALIZE_PASTE27, \
|
||||
RPC_CORE_DETAIL_SERIALIZE_PASTE26, \
|
||||
RPC_CORE_DETAIL_SERIALIZE_PASTE25, \
|
||||
RPC_CORE_DETAIL_SERIALIZE_PASTE24, \
|
||||
RPC_CORE_DETAIL_SERIALIZE_PASTE23, \
|
||||
RPC_CORE_DETAIL_SERIALIZE_PASTE22, \
|
||||
RPC_CORE_DETAIL_SERIALIZE_PASTE21, \
|
||||
RPC_CORE_DETAIL_SERIALIZE_PASTE20, \
|
||||
RPC_CORE_DETAIL_SERIALIZE_PASTE19, \
|
||||
RPC_CORE_DETAIL_SERIALIZE_PASTE18, \
|
||||
RPC_CORE_DETAIL_SERIALIZE_PASTE17, \
|
||||
RPC_CORE_DETAIL_SERIALIZE_PASTE16, \
|
||||
RPC_CORE_DETAIL_SERIALIZE_PASTE15, \
|
||||
RPC_CORE_DETAIL_SERIALIZE_PASTE14, \
|
||||
RPC_CORE_DETAIL_SERIALIZE_PASTE13, \
|
||||
RPC_CORE_DETAIL_SERIALIZE_PASTE12, \
|
||||
RPC_CORE_DETAIL_SERIALIZE_PASTE11, \
|
||||
RPC_CORE_DETAIL_SERIALIZE_PASTE10, \
|
||||
RPC_CORE_DETAIL_SERIALIZE_PASTE9, \
|
||||
RPC_CORE_DETAIL_SERIALIZE_PASTE8, \
|
||||
RPC_CORE_DETAIL_SERIALIZE_PASTE7, \
|
||||
RPC_CORE_DETAIL_SERIALIZE_PASTE6, \
|
||||
RPC_CORE_DETAIL_SERIALIZE_PASTE5, \
|
||||
RPC_CORE_DETAIL_SERIALIZE_PASTE4, \
|
||||
RPC_CORE_DETAIL_SERIALIZE_PASTE3, \
|
||||
RPC_CORE_DETAIL_SERIALIZE_PASTE2, \
|
||||
RPC_CORE_DETAIL_SERIALIZE_PASTE1)(__VA_ARGS__)
|
||||
#define RPC_CORE_DETAIL_SERIALIZE_PASTE2(func, v1) func(v1)
|
||||
#define RPC_CORE_DETAIL_SERIALIZE_PASTE3(func, v1, v2) RPC_CORE_DETAIL_SERIALIZE_PASTE2(func, v1) RPC_CORE_DETAIL_SERIALIZE_PASTE2(func, v2)
|
||||
#define RPC_CORE_DETAIL_SERIALIZE_PASTE4(func, v1, v2, v3) RPC_CORE_DETAIL_SERIALIZE_PASTE2(func, v1) RPC_CORE_DETAIL_SERIALIZE_PASTE3(func, v2, v3)
|
||||
#define RPC_CORE_DETAIL_SERIALIZE_PASTE5(func, v1, v2, v3, v4) RPC_CORE_DETAIL_SERIALIZE_PASTE2(func, v1) RPC_CORE_DETAIL_SERIALIZE_PASTE4(func, v2, v3, v4)
|
||||
#define RPC_CORE_DETAIL_SERIALIZE_PASTE6(func, v1, v2, v3, v4, v5) RPC_CORE_DETAIL_SERIALIZE_PASTE2(func, v1) RPC_CORE_DETAIL_SERIALIZE_PASTE5(func, v2, v3, v4, v5)
|
||||
#define RPC_CORE_DETAIL_SERIALIZE_PASTE7(func, v1, v2, v3, v4, v5, v6) RPC_CORE_DETAIL_SERIALIZE_PASTE2(func, v1) RPC_CORE_DETAIL_SERIALIZE_PASTE6(func, v2, v3, v4, v5, v6)
|
||||
#define RPC_CORE_DETAIL_SERIALIZE_PASTE8(func, v1, v2, v3, v4, v5, v6, v7) RPC_CORE_DETAIL_SERIALIZE_PASTE2(func, v1) RPC_CORE_DETAIL_SERIALIZE_PASTE7(func, v2, v3, v4, v5, v6, v7)
|
||||
#define RPC_CORE_DETAIL_SERIALIZE_PASTE9(func, v1, v2, v3, v4, v5, v6, v7, v8) RPC_CORE_DETAIL_SERIALIZE_PASTE2(func, v1) RPC_CORE_DETAIL_SERIALIZE_PASTE8(func, v2, v3, v4, v5, v6, v7, v8)
|
||||
#define RPC_CORE_DETAIL_SERIALIZE_PASTE10(func, v1, v2, v3, v4, v5, v6, v7, v8, v9) RPC_CORE_DETAIL_SERIALIZE_PASTE2(func, v1) RPC_CORE_DETAIL_SERIALIZE_PASTE9(func, v2, v3, v4, v5, v6, v7, v8, v9)
|
||||
#define RPC_CORE_DETAIL_SERIALIZE_PASTE11(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10) RPC_CORE_DETAIL_SERIALIZE_PASTE2(func, v1) RPC_CORE_DETAIL_SERIALIZE_PASTE10(func, v2, v3, v4, v5, v6, v7, v8, v9, v10)
|
||||
#define RPC_CORE_DETAIL_SERIALIZE_PASTE12(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11) RPC_CORE_DETAIL_SERIALIZE_PASTE2(func, v1) RPC_CORE_DETAIL_SERIALIZE_PASTE11(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11)
|
||||
#define RPC_CORE_DETAIL_SERIALIZE_PASTE13(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12) RPC_CORE_DETAIL_SERIALIZE_PASTE2(func, v1) RPC_CORE_DETAIL_SERIALIZE_PASTE12(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12)
|
||||
#define RPC_CORE_DETAIL_SERIALIZE_PASTE14(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13) RPC_CORE_DETAIL_SERIALIZE_PASTE2(func, v1) RPC_CORE_DETAIL_SERIALIZE_PASTE13(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13)
|
||||
#define RPC_CORE_DETAIL_SERIALIZE_PASTE15(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14) RPC_CORE_DETAIL_SERIALIZE_PASTE2(func, v1) RPC_CORE_DETAIL_SERIALIZE_PASTE14(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14)
|
||||
#define RPC_CORE_DETAIL_SERIALIZE_PASTE16(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) RPC_CORE_DETAIL_SERIALIZE_PASTE2(func, v1) RPC_CORE_DETAIL_SERIALIZE_PASTE15(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15)
|
||||
#define RPC_CORE_DETAIL_SERIALIZE_PASTE17(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16) RPC_CORE_DETAIL_SERIALIZE_PASTE2(func, v1) RPC_CORE_DETAIL_SERIALIZE_PASTE16(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16)
|
||||
#define RPC_CORE_DETAIL_SERIALIZE_PASTE18(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17) RPC_CORE_DETAIL_SERIALIZE_PASTE2(func, v1) RPC_CORE_DETAIL_SERIALIZE_PASTE17(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17)
|
||||
#define RPC_CORE_DETAIL_SERIALIZE_PASTE19(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18) RPC_CORE_DETAIL_SERIALIZE_PASTE2(func, v1) RPC_CORE_DETAIL_SERIALIZE_PASTE18(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18)
|
||||
#define RPC_CORE_DETAIL_SERIALIZE_PASTE20(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19) RPC_CORE_DETAIL_SERIALIZE_PASTE2(func, v1) RPC_CORE_DETAIL_SERIALIZE_PASTE19(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19)
|
||||
#define RPC_CORE_DETAIL_SERIALIZE_PASTE21(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20) RPC_CORE_DETAIL_SERIALIZE_PASTE2(func, v1) RPC_CORE_DETAIL_SERIALIZE_PASTE20(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20)
|
||||
#define RPC_CORE_DETAIL_SERIALIZE_PASTE22(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21) RPC_CORE_DETAIL_SERIALIZE_PASTE2(func, v1) RPC_CORE_DETAIL_SERIALIZE_PASTE21(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21)
|
||||
#define RPC_CORE_DETAIL_SERIALIZE_PASTE23(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22) RPC_CORE_DETAIL_SERIALIZE_PASTE2(func, v1) RPC_CORE_DETAIL_SERIALIZE_PASTE22(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22)
|
||||
#define RPC_CORE_DETAIL_SERIALIZE_PASTE24(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23) RPC_CORE_DETAIL_SERIALIZE_PASTE2(func, v1) RPC_CORE_DETAIL_SERIALIZE_PASTE23(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23)
|
||||
#define RPC_CORE_DETAIL_SERIALIZE_PASTE25(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24) RPC_CORE_DETAIL_SERIALIZE_PASTE2(func, v1) RPC_CORE_DETAIL_SERIALIZE_PASTE24(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24)
|
||||
#define RPC_CORE_DETAIL_SERIALIZE_PASTE26(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25) RPC_CORE_DETAIL_SERIALIZE_PASTE2(func, v1) RPC_CORE_DETAIL_SERIALIZE_PASTE25(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25)
|
||||
#define RPC_CORE_DETAIL_SERIALIZE_PASTE27(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26) RPC_CORE_DETAIL_SERIALIZE_PASTE2(func, v1) RPC_CORE_DETAIL_SERIALIZE_PASTE26(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26)
|
||||
#define RPC_CORE_DETAIL_SERIALIZE_PASTE28(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27) RPC_CORE_DETAIL_SERIALIZE_PASTE2(func, v1) RPC_CORE_DETAIL_SERIALIZE_PASTE27(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27)
|
||||
#define RPC_CORE_DETAIL_SERIALIZE_PASTE29(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28) RPC_CORE_DETAIL_SERIALIZE_PASTE2(func, v1) RPC_CORE_DETAIL_SERIALIZE_PASTE28(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28)
|
||||
#define RPC_CORE_DETAIL_SERIALIZE_PASTE30(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29) RPC_CORE_DETAIL_SERIALIZE_PASTE2(func, v1) RPC_CORE_DETAIL_SERIALIZE_PASTE29(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29)
|
||||
#define RPC_CORE_DETAIL_SERIALIZE_PASTE31(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30) RPC_CORE_DETAIL_SERIALIZE_PASTE2(func, v1) RPC_CORE_DETAIL_SERIALIZE_PASTE30(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30)
|
||||
#define RPC_CORE_DETAIL_SERIALIZE_PASTE32(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31) RPC_CORE_DETAIL_SERIALIZE_PASTE2(func, v1) RPC_CORE_DETAIL_SERIALIZE_PASTE31(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31)
|
||||
#define RPC_CORE_DETAIL_SERIALIZE_PASTE33(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32) RPC_CORE_DETAIL_SERIALIZE_PASTE2(func, v1) RPC_CORE_DETAIL_SERIALIZE_PASTE32(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32)
|
||||
#define RPC_CORE_DETAIL_SERIALIZE_PASTE34(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33) RPC_CORE_DETAIL_SERIALIZE_PASTE2(func, v1) RPC_CORE_DETAIL_SERIALIZE_PASTE33(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33)
|
||||
#define RPC_CORE_DETAIL_SERIALIZE_PASTE35(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34) RPC_CORE_DETAIL_SERIALIZE_PASTE2(func, v1) RPC_CORE_DETAIL_SERIALIZE_PASTE34(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34)
|
||||
#define RPC_CORE_DETAIL_SERIALIZE_PASTE36(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35) RPC_CORE_DETAIL_SERIALIZE_PASTE2(func, v1) RPC_CORE_DETAIL_SERIALIZE_PASTE35(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35)
|
||||
#define RPC_CORE_DETAIL_SERIALIZE_PASTE37(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36) RPC_CORE_DETAIL_SERIALIZE_PASTE2(func, v1) RPC_CORE_DETAIL_SERIALIZE_PASTE36(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36)
|
||||
#define RPC_CORE_DETAIL_SERIALIZE_PASTE38(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37) RPC_CORE_DETAIL_SERIALIZE_PASTE2(func, v1) RPC_CORE_DETAIL_SERIALIZE_PASTE37(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37)
|
||||
#define RPC_CORE_DETAIL_SERIALIZE_PASTE39(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38) RPC_CORE_DETAIL_SERIALIZE_PASTE2(func, v1) RPC_CORE_DETAIL_SERIALIZE_PASTE38(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38)
|
||||
#define RPC_CORE_DETAIL_SERIALIZE_PASTE40(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39) RPC_CORE_DETAIL_SERIALIZE_PASTE2(func, v1) RPC_CORE_DETAIL_SERIALIZE_PASTE39(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39)
|
||||
#define RPC_CORE_DETAIL_SERIALIZE_PASTE41(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40) RPC_CORE_DETAIL_SERIALIZE_PASTE2(func, v1) RPC_CORE_DETAIL_SERIALIZE_PASTE40(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40)
|
||||
#define RPC_CORE_DETAIL_SERIALIZE_PASTE42(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41) RPC_CORE_DETAIL_SERIALIZE_PASTE2(func, v1) RPC_CORE_DETAIL_SERIALIZE_PASTE41(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41)
|
||||
#define RPC_CORE_DETAIL_SERIALIZE_PASTE43(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42) RPC_CORE_DETAIL_SERIALIZE_PASTE2(func, v1) RPC_CORE_DETAIL_SERIALIZE_PASTE42(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42)
|
||||
#define RPC_CORE_DETAIL_SERIALIZE_PASTE44(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43) RPC_CORE_DETAIL_SERIALIZE_PASTE2(func, v1) RPC_CORE_DETAIL_SERIALIZE_PASTE43(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43)
|
||||
#define RPC_CORE_DETAIL_SERIALIZE_PASTE45(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44) RPC_CORE_DETAIL_SERIALIZE_PASTE2(func, v1) RPC_CORE_DETAIL_SERIALIZE_PASTE44(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44)
|
||||
#define RPC_CORE_DETAIL_SERIALIZE_PASTE46(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45) RPC_CORE_DETAIL_SERIALIZE_PASTE2(func, v1) RPC_CORE_DETAIL_SERIALIZE_PASTE45(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45)
|
||||
#define RPC_CORE_DETAIL_SERIALIZE_PASTE47(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46) RPC_CORE_DETAIL_SERIALIZE_PASTE2(func, v1) RPC_CORE_DETAIL_SERIALIZE_PASTE46(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46)
|
||||
#define RPC_CORE_DETAIL_SERIALIZE_PASTE48(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47) RPC_CORE_DETAIL_SERIALIZE_PASTE2(func, v1) RPC_CORE_DETAIL_SERIALIZE_PASTE47(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47)
|
||||
#define RPC_CORE_DETAIL_SERIALIZE_PASTE49(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48) RPC_CORE_DETAIL_SERIALIZE_PASTE2(func, v1) RPC_CORE_DETAIL_SERIALIZE_PASTE48(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48)
|
||||
#define RPC_CORE_DETAIL_SERIALIZE_PASTE50(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49) RPC_CORE_DETAIL_SERIALIZE_PASTE2(func, v1) RPC_CORE_DETAIL_SERIALIZE_PASTE49(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49)
|
||||
#define RPC_CORE_DETAIL_SERIALIZE_PASTE51(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50) RPC_CORE_DETAIL_SERIALIZE_PASTE2(func, v1) RPC_CORE_DETAIL_SERIALIZE_PASTE50(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50)
|
||||
#define RPC_CORE_DETAIL_SERIALIZE_PASTE52(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51) RPC_CORE_DETAIL_SERIALIZE_PASTE2(func, v1) RPC_CORE_DETAIL_SERIALIZE_PASTE51(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51)
|
||||
#define RPC_CORE_DETAIL_SERIALIZE_PASTE53(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52) RPC_CORE_DETAIL_SERIALIZE_PASTE2(func, v1) RPC_CORE_DETAIL_SERIALIZE_PASTE52(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52)
|
||||
#define RPC_CORE_DETAIL_SERIALIZE_PASTE54(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53) RPC_CORE_DETAIL_SERIALIZE_PASTE2(func, v1) RPC_CORE_DETAIL_SERIALIZE_PASTE53(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53)
|
||||
#define RPC_CORE_DETAIL_SERIALIZE_PASTE55(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54) RPC_CORE_DETAIL_SERIALIZE_PASTE2(func, v1) RPC_CORE_DETAIL_SERIALIZE_PASTE54(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54)
|
||||
#define RPC_CORE_DETAIL_SERIALIZE_PASTE56(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55) RPC_CORE_DETAIL_SERIALIZE_PASTE2(func, v1) RPC_CORE_DETAIL_SERIALIZE_PASTE55(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55)
|
||||
#define RPC_CORE_DETAIL_SERIALIZE_PASTE57(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56) RPC_CORE_DETAIL_SERIALIZE_PASTE2(func, v1) RPC_CORE_DETAIL_SERIALIZE_PASTE56(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56)
|
||||
#define RPC_CORE_DETAIL_SERIALIZE_PASTE58(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57) RPC_CORE_DETAIL_SERIALIZE_PASTE2(func, v1) RPC_CORE_DETAIL_SERIALIZE_PASTE57(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57)
|
||||
#define RPC_CORE_DETAIL_SERIALIZE_PASTE59(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58) RPC_CORE_DETAIL_SERIALIZE_PASTE2(func, v1) RPC_CORE_DETAIL_SERIALIZE_PASTE58(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58)
|
||||
#define RPC_CORE_DETAIL_SERIALIZE_PASTE60(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59) RPC_CORE_DETAIL_SERIALIZE_PASTE2(func, v1) RPC_CORE_DETAIL_SERIALIZE_PASTE59(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59)
|
||||
#define RPC_CORE_DETAIL_SERIALIZE_PASTE61(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60) RPC_CORE_DETAIL_SERIALIZE_PASTE2(func, v1) RPC_CORE_DETAIL_SERIALIZE_PASTE60(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60)
|
||||
#define RPC_CORE_DETAIL_SERIALIZE_PASTE62(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61) RPC_CORE_DETAIL_SERIALIZE_PASTE2(func, v1) RPC_CORE_DETAIL_SERIALIZE_PASTE61(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61)
|
||||
#define RPC_CORE_DETAIL_SERIALIZE_PASTE63(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62) RPC_CORE_DETAIL_SERIALIZE_PASTE2(func, v1) RPC_CORE_DETAIL_SERIALIZE_PASTE62(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62)
|
||||
#define RPC_CORE_DETAIL_SERIALIZE_PASTE64(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63) RPC_CORE_DETAIL_SERIALIZE_PASTE2(func, v1) RPC_CORE_DETAIL_SERIALIZE_PASTE63(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63)
|
||||
|
||||
#define RPC_CORE_DETAIL_SERIALIZE_FIELD(v1) ar & t.v1;
|
||||
#define RPC_CORE_DETAIL_SERIALIZE_FIELD_INNER(v1) ar & this->v1;
|
||||
// clang-format on
|
||||
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
|
||||
#include "../detail/noncopyable.hpp"
|
||||
#include "../detail/string_view.hpp"
|
||||
|
||||
namespace rpc_core {
|
||||
|
||||
template <typename T, typename std::enable_if<std::is_fundamental<T>::value, int>::type = 0>
|
||||
inline serialize_oarchive& operator&(serialize_oarchive& oa, const T& t) {
|
||||
t >> oa;
|
||||
return oa;
|
||||
}
|
||||
|
||||
template <typename T, typename std::enable_if<!std::is_fundamental<T>::value, int>::type = 0>
|
||||
inline serialize_oarchive& operator&(serialize_oarchive& oa, const T& t) {
|
||||
serialize_oarchive tmp;
|
||||
t >> tmp;
|
||||
tmp >> oa;
|
||||
return oa;
|
||||
}
|
||||
|
||||
template <typename T, typename std::enable_if<std::is_fundamental<T>::value, int>::type = 0>
|
||||
inline serialize_iarchive& operator&(serialize_iarchive& ia, T& t) {
|
||||
if (ia.error) return ia;
|
||||
t << ia;
|
||||
return ia;
|
||||
}
|
||||
|
||||
template <typename T, typename std::enable_if<!std::is_fundamental<T>::value, int>::type = 0>
|
||||
serialize_iarchive& operator&(serialize_iarchive& ia, T& t) {
|
||||
if (ia.error) return ia;
|
||||
detail::auto_size auto_size;
|
||||
int cost = auto_size.deserialize(ia.data);
|
||||
uint32_t size = auto_size.value;
|
||||
ia.data += cost;
|
||||
|
||||
serialize_iarchive tmp(detail::string_view(ia.data, size));
|
||||
t << tmp;
|
||||
ia.error = tmp.error;
|
||||
|
||||
ia.data += size;
|
||||
return ia;
|
||||
}
|
||||
|
||||
} // namespace rpc_core
|
||||
|
||||
#define RPC_CORE_DEFINE_TYPE(Type, ...) \
|
||||
inline void operator>>(const Type& t, ::rpc_core::serialize_oarchive& ar) { \
|
||||
RPC_CORE_DETAIL_SERIALIZE_PASTE(RPC_CORE_DETAIL_SERIALIZE_FIELD, __VA_ARGS__) \
|
||||
} \
|
||||
inline void operator<<(Type& t, ::rpc_core::serialize_iarchive& ar) { \
|
||||
RPC_CORE_DETAIL_SERIALIZE_PASTE(RPC_CORE_DETAIL_SERIALIZE_FIELD, __VA_ARGS__) \
|
||||
}
|
||||
|
||||
#define RPC_CORE_DEFINE_TYPE_INNER(...) \
|
||||
public: \
|
||||
void operator>>(::rpc_core::serialize_oarchive& ar) const { \
|
||||
RPC_CORE_DETAIL_SERIALIZE_PASTE(RPC_CORE_DETAIL_SERIALIZE_FIELD_INNER, __VA_ARGS__) \
|
||||
} \
|
||||
void operator<<(::rpc_core::serialize_iarchive& ar) { \
|
||||
RPC_CORE_DETAIL_SERIALIZE_PASTE(RPC_CORE_DETAIL_SERIALIZE_FIELD_INNER, __VA_ARGS__) \
|
||||
}
|
17
3party/rpc_core/include/rpc_core/serialize/type_void.hpp
Normal file
17
3party/rpc_core/include/rpc_core/serialize/type_void.hpp
Normal file
@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
namespace rpc_core {
|
||||
|
||||
template <typename T, typename std::enable_if<std::is_same<T, void>::value, int>::type = 0>
|
||||
inline serialize_oarchive& operator>>(const T& t, serialize_oarchive& oa) {
|
||||
RPC_CORE_UNUSED(t);
|
||||
return oa;
|
||||
}
|
||||
|
||||
template <typename T, typename std::enable_if<std::is_same<T, void>::value, int>::type = 0>
|
||||
inline serialize_iarchive& operator<<(T& t, serialize_iarchive& ia) {
|
||||
RPC_CORE_UNUSED(t);
|
||||
return ia;
|
||||
}
|
||||
|
||||
} // namespace rpc_core
|
82
3party/rpc_core/include/rpc_core/serialize_type.hpp
Normal file
82
3party/rpc_core/include/rpc_core/serialize_type.hpp
Normal file
@ -0,0 +1,82 @@
|
||||
#pragma once
|
||||
|
||||
// config
|
||||
#include "config.hpp"
|
||||
|
||||
// include
|
||||
#include "detail/noncopyable.hpp"
|
||||
#include "detail/string_view.hpp"
|
||||
#include "serialize/detail/auto_size.hpp"
|
||||
#include "type.hpp"
|
||||
|
||||
namespace rpc_core {
|
||||
|
||||
struct serialize_oarchive : detail::noncopyable {
|
||||
std::string data;
|
||||
};
|
||||
|
||||
inline serialize_oarchive& operator>>(const serialize_oarchive& t, serialize_oarchive& oa) {
|
||||
oa.data.append(detail::auto_size(t.data.size()).serialize());
|
||||
oa.data.append(t.data);
|
||||
return oa;
|
||||
}
|
||||
|
||||
inline serialize_oarchive& operator>>(serialize_oarchive&& t, serialize_oarchive& oa) {
|
||||
if (oa.data.empty()) {
|
||||
oa.data = std::move(t.data);
|
||||
return oa;
|
||||
}
|
||||
oa.data.append(detail::auto_size(t.data.size()).serialize());
|
||||
oa.data.append(t.data);
|
||||
return oa;
|
||||
}
|
||||
|
||||
struct serialize_iarchive : detail::noncopyable {
|
||||
serialize_iarchive() = default;
|
||||
serialize_iarchive(detail::string_view sv) : data((char*)sv.data()), size(sv.size()) {} // NOLINT(google-explicit-constructor)
|
||||
serialize_iarchive(const char* data, size_t size) : data((char*)data), size(size) {}
|
||||
char* data = nullptr;
|
||||
size_t size = 0;
|
||||
bool error = false;
|
||||
};
|
||||
|
||||
inline serialize_iarchive& operator<<(serialize_iarchive& t, serialize_iarchive& ia) {
|
||||
detail::auto_size size;
|
||||
int cost = size.deserialize(ia.data);
|
||||
ia.data += cost;
|
||||
t.data = ia.data;
|
||||
t.size = size.value;
|
||||
ia.data += size.value;
|
||||
ia.size -= cost + size.value;
|
||||
return ia;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline std::string serialize(T&& t) {
|
||||
serialize_oarchive ar;
|
||||
std::forward<T>(t) >> ar;
|
||||
return std::move(ar.data);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline bool deserialize(const detail::string_view& data, T& t) {
|
||||
serialize_iarchive ar(data);
|
||||
t << ar;
|
||||
return !ar.error;
|
||||
}
|
||||
|
||||
template <typename T, typename std::enable_if<detail::is_auto_size_type<T>::value, int>::type = 0>
|
||||
inline serialize_oarchive& operator>>(const T& t, serialize_oarchive& oa) {
|
||||
oa.data.append(t.serialize());
|
||||
return oa;
|
||||
}
|
||||
|
||||
template <typename T, typename std::enable_if<detail::is_auto_size_type<T>::value, int>::type = 0>
|
||||
inline serialize_iarchive& operator<<(T& t, serialize_iarchive& ia) {
|
||||
int cost = t.deserialize((uint8_t*)ia.data);
|
||||
ia.data += cost;
|
||||
ia.size -= cost;
|
||||
return ia;
|
||||
}
|
||||
|
||||
} // namespace rpc_core
|
25
3party/rpc_core/include/rpc_core/type.hpp
Normal file
25
3party/rpc_core/include/rpc_core/type.hpp
Normal file
@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
// config
|
||||
#include "config.hpp"
|
||||
|
||||
namespace rpc_core {
|
||||
|
||||
#if __cplusplus >= 201402L
|
||||
#define RPC_CORE_MOVE_LAMBDA(arg) arg = std::move(arg)
|
||||
#define RPC_CORE_MOVE_PARAM(arg) arg
|
||||
#else
|
||||
#define RPC_CORE_MOVE_LAMBDA(arg) arg
|
||||
#define RPC_CORE_MOVE_PARAM(arg) const arg&
|
||||
#endif
|
||||
|
||||
#define RPC_CORE_UNUSED(x) (void)x
|
||||
|
||||
using cmd_type = std::string;
|
||||
|
||||
using seq_type = uint32_t;
|
||||
|
||||
} // namespace rpc_core
|
8
3party/rpc_core/include/rpc_core/version.hpp
Normal file
8
3party/rpc_core/include/rpc_core/version.hpp
Normal file
@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#define RPC_CORE_VER_MAJOR 2
|
||||
#define RPC_CORE_VER_MINOR 0
|
||||
#define RPC_CORE_VER_PATCH 1
|
||||
|
||||
#define RPC_CORE_TO_VERSION(major, minor, patch) (major * 10000 + minor * 100 + patch)
|
||||
#define RPC_CORE_VERSION RPC_CORE_TO_VERSION(RPC_CORE_VER_MAJOR, RPC_CORE_VER_MINOR, RPC_CORE_VER_PATCH)
|
Reference in New Issue
Block a user