3 #ifndef LLVM_EXECUTIONENGINE_ORC_RPCCHANNEL_H
4 #define LLVM_EXECUTIONENGINE_ORC_RPCCHANNEL_H
7 #include "llvm/ADT/ArrayRef.h"
8 #include "llvm/Support/Endian.h"
10 #include <system_error>
16 /// Interface for byte-streams to be used with RPC.
19 virtual ~RPCChannel() {}
21 /// Read Size bytes from the stream into *Dst.
22 virtual std::error_code readBytes(char *Dst, unsigned Size) = 0;
24 /// Read size bytes from *Src and append them to the stream.
25 virtual std::error_code appendBytes(const char *Src, unsigned Size) = 0;
27 /// Flush the stream if possible.
28 virtual std::error_code send() = 0;
31 /// RPC channel serialization for a variadic list of arguments.
32 template <typename T, typename... Ts>
33 std::error_code serialize_seq(RPCChannel &C, const T &Arg, const Ts &... Args) {
34 if (auto EC = serialize(C, Arg))
36 return serialize_seq(C, Args...);
39 /// RPC channel serialization for an (empty) variadic list of arguments.
40 inline std::error_code serialize_seq(RPCChannel &C) {
41 return std::error_code();
44 /// RPC channel deserialization for a variadic list of arguments.
45 template <typename T, typename... Ts>
46 std::error_code deserialize_seq(RPCChannel &C, T &Arg, Ts &... Args) {
47 if (auto EC = deserialize(C, Arg))
49 return deserialize_seq(C, Args...);
52 /// RPC channel serialization for an (empty) variadic list of arguments.
53 inline std::error_code deserialize_seq(RPCChannel &C) {
54 return std::error_code();
57 /// RPC channel serialization for integer primitives.
59 typename std::enable_if<
60 std::is_same<T, uint64_t>::value || std::is_same<T, int64_t>::value ||
61 std::is_same<T, uint32_t>::value || std::is_same<T, int32_t>::value ||
62 std::is_same<T, uint16_t>::value || std::is_same<T, int16_t>::value ||
63 std::is_same<T, uint8_t>::value || std::is_same<T, int8_t>::value,
64 std::error_code>::type
65 serialize(RPCChannel &C, T V) {
66 support::endian::byte_swap<T, support::big>(V);
67 return C.appendBytes(reinterpret_cast<const char *>(&V), sizeof(T));
70 /// RPC channel deserialization for integer primitives.
72 typename std::enable_if<
73 std::is_same<T, uint64_t>::value || std::is_same<T, int64_t>::value ||
74 std::is_same<T, uint32_t>::value || std::is_same<T, int32_t>::value ||
75 std::is_same<T, uint16_t>::value || std::is_same<T, int16_t>::value ||
76 std::is_same<T, uint8_t>::value || std::is_same<T, int8_t>::value,
77 std::error_code>::type
78 deserialize(RPCChannel &C, T &V) {
79 if (auto EC = C.readBytes(reinterpret_cast<char *>(&V), sizeof(T)))
81 support::endian::byte_swap<T, support::big>(V);
82 return std::error_code();
85 /// RPC channel serialization for enums.
87 typename std::enable_if<std::is_enum<T>::value, std::error_code>::type
88 serialize(RPCChannel &C, T V) {
89 return serialize(C, static_cast<typename std::underlying_type<T>::type>(V));
92 /// RPC channel deserialization for enums.
94 typename std::enable_if<std::is_enum<T>::value, std::error_code>::type
95 deserialize(RPCChannel &C, T &V) {
96 typename std::underlying_type<T>::type Tmp;
97 std::error_code EC = deserialize(C, Tmp);
98 V = static_cast<T>(Tmp);
102 /// RPC channel serialization for bools.
103 inline std::error_code serialize(RPCChannel &C, bool V) {
104 uint8_t VN = V ? 1 : 0;
105 return C.appendBytes(reinterpret_cast<const char *>(&VN), 1);
108 /// RPC channel deserialization for bools.
109 inline std::error_code deserialize(RPCChannel &C, bool &V) {
111 if (auto EC = C.readBytes(reinterpret_cast<char *>(&VN), 1))
114 V = (VN != 0) ? true : false;
115 return std::error_code();
118 /// RPC channel serialization for StringRefs.
119 /// Note: There is no corresponding deseralization for this, as StringRef
120 /// doesn't own its memory and so can't hold the deserialized data.
121 inline std::error_code serialize(RPCChannel &C, StringRef S) {
122 if (auto EC = serialize(C, static_cast<uint64_t>(S.size())))
124 return C.appendBytes((const char *)S.bytes_begin(), S.size());
127 /// RPC channel serialization for std::strings.
128 inline std::error_code serialize(RPCChannel &C, const std::string &S) {
129 return serialize(C, StringRef(S));
132 /// RPC channel deserialization for std::strings.
133 inline std::error_code deserialize(RPCChannel &C, std::string &S) {
135 if (auto EC = deserialize(C, Count))
138 return C.readBytes(&S[0], Count);
141 /// RPC channel serialization for ArrayRef<T>.
142 template <typename T>
143 std::error_code serialize(RPCChannel &C, const ArrayRef<T> &A) {
144 if (auto EC = serialize(C, static_cast<uint64_t>(A.size())))
147 for (const auto &E : A)
148 if (auto EC = serialize(C, E))
151 return std::error_code();
154 /// RPC channel serialization for std::array<T>.
155 template <typename T>
156 std::error_code serialize(RPCChannel &C, const std::vector<T> &V) {
157 return serialize(C, ArrayRef<T>(V));
160 /// RPC channel deserialization for std::array<T>.
161 template <typename T>
162 std::error_code deserialize(RPCChannel &C, std::vector<T> &V) {
164 if (auto EC = deserialize(C, Count))
169 if (auto EC = deserialize(C, E))
172 return std::error_code();
175 } // end namespace remote
176 } // end namespace orc
177 } // end namespace llvm