-
Notifications
You must be signed in to change notification settings - Fork 8
/
rpc.h
188 lines (142 loc) · 4.99 KB
/
rpc.h
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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
// rpc.h
#pragma once
#include <string>
#include <vector>
#include <stdint.h>
#include "config.h"
#include "rpc_io.h"
#include "rpc_error.h"
#ifdef ENABLE_RPC_PROFILING
#define RPC_PROFILING PROFILING
#else
#define RPC_PROFILING
#endif
#ifdef ENABLE_MULTITHREADING
#include <boost/thread.hpp>
#define RPC_THREAD boost::mutex m_sync;
#define RPC_THREAD_LOCK boost::lock_guard<boost::mutex> lock(m_sync);
#define RPC_THREAD_UNLOCK
#else
#define RPC_THREAD
#define RPC_THREAD_LOCK
#define RPC_THREAD_UNLOCK
#endif
using namespace std;
#define RPC_DTB_VERSION 0x0200
#define RPC_TYPE_ATB 0x8F
#define RPC_TYPE_DTB 0xC0
#define RPC_TYPE_DTB_DATA 0xC2
#define RPC_TYPE_DTB_DATA_OLD 0xC1
#define RPC_EXPORT
extern const char rpc_timestamp[];
#define RPC_DEFS \
CRpcIo *rpc_io; \
static const char rpc_timestamp[]; \
static const unsigned int rpc_cmdListSize; \
static const char *rpc_cmdName[]; \
int *rpc_cmdId; \
void rpc_Clear() { for ( unsigned int i=2; i<rpc_cmdListSize; i++) rpc_cmdId[i] = -1; rpc_cmdId[0] = 0; rpc_cmdId[1] = 1; } \
void rpc_Connect(CRpcIo &port) { rpc_io = &port; rpc_Clear(); } \
uint16_t rpc_GetCallId(uint16_t x) \
{ \
int id = rpc_cmdId[x]; \
if (id >= 0) return id; \
string name(rpc_cmdName[x]); \
rpc_cmdId[x] = id = GetRpcCallId(name); \
if (id >= 0) return id; \
throw CRpcError(CRpcError::UNKNOWN_CMD); \
} \
friend class CRpcError;
#define RPC_INIT rpc_io = &RpcIoNull; rpc_cmdId = new int[rpc_cmdListSize]; rpc_Clear();
#define RPC_EXIT delete[] rpc_cmdId;
#define RPC_EXPORT
extern CRpcIoNull RpcIoNull;
class CBuffer
{
uint8_t *p;
public:
CBuffer(uint16_t size) { p = new uint8_t[size]; }
~CBuffer() { delete[] p; }
uint8_t* operator&() { return p; }
};
// === message ==============================================================
class rpcMessage
{
uint8_t m_pos;
uint8_t m_type;
uint16_t m_cmd;
uint8_t m_size;
uint8_t m_par[256];
public:
uint16_t GetCmd() { return m_cmd; }
uint16_t GetCheckedCmd(uint16_t cmdCnt)
{ if (m_cmd < cmdCnt) return m_cmd; throw CRpcError(CRpcError::UNKNOWN_CMD); }
void Create(uint16_t cmd);
void Put_INT8(int8_t x) { m_par[m_pos++] = int8_t(x); m_size++; }
void Put_UINT8(uint8_t x) { m_par[m_pos++] = x; m_size++; }
void Put_BOOL(bool x) { Put_UINT8(x ? 1 : 0); }
void Put_INT16(int16_t x) { Put_UINT8(uint8_t(x)); Put_UINT8(uint8_t(x>>8)); }
void Put_UINT16(uint16_t x) { Put_UINT8(uint8_t(x)); Put_UINT8(uint8_t(x>>8)); }
void Put_INT32(int32_t x) { Put_UINT16(uint16_t(x)); Put_UINT16(uint16_t(x>>16)); }
void Put_UINT32(int32_t x) { Put_UINT16(uint16_t(x)); Put_UINT16(uint16_t(x>>16)); }
void Put_INT64(int64_t x) { Put_UINT32(uint32_t(x)); Put_UINT32(uint32_t(x>>32)); }
void Put_UINT64(uint64_t x) { Put_UINT32(uint32_t(x)); Put_UINT32(uint32_t(x>>32)); }
void Send(CRpcIo &rpc_io);
void Receive(CRpcIo &rpc_io);
void Check(uint16_t cmd, uint8_t size)
{
if (m_cmd != cmd) throw CRpcError(CRpcError::UNKNOWN_CMD);
if (m_size != size) throw CRpcError(CRpcError::CMD_PAR_SIZE);
return;
}
void CheckSize(uint8_t size) { if (m_size != size) throw CRpcError(CRpcError::CMD_PAR_SIZE); }
int8_t Get_INT8() { return int8_t(m_par[m_pos++]); }
uint8_t Get_UINT8() { return uint8_t(m_par[m_pos++]); }
bool Get_BOOL() { return Get_UINT8() != 0; }
int16_t Get_INT16() { int16_t x = Get_UINT8(); x += (uint16_t)Get_UINT8() << 8; return x; }
uint16_t Get_UINT16() { uint16_t x = Get_UINT8(); x += (uint16_t)Get_UINT8() << 8; return x; }
int32_t Get_INT32() { int32_t x = Get_UINT16(); x += (uint32_t)Get_UINT16() << 16; return x; }
uint32_t Get_UINT32() { uint32_t x = Get_UINT16(); x += (uint32_t)Get_UINT16() << 16; return x; }
int64_t Get_INT64() { int64_t x = Get_UINT32(); x += (uint64_t)Get_UINT32() << 32; return x; }
uint64_t Get_UINT64() { uint64_t x = Get_UINT32(); x = (uint64_t)Get_UINT32() << 32; return x; }
};
// === data =================================================================
#define vectorR vector
#define HWvectorR vector
#define stringR string
class CDataHeader
{
public:
uint8_t m_type;
uint32_t m_size;
void RecvHeader(CRpcIo &rpc_io);
void RecvRaw(CRpcIo &rpc_io, void *x)
{ if (m_size) rpc_io.Read(x, m_size); }
};
void rpc_SendRaw(CRpcIo &rpc_io, const void *x, uint32_t size);
void rpc_DataSink(CRpcIo &rpc_io, uint32_t size);
template <class T>
inline void rpc_Send(CRpcIo &rpc_io, const vector<T> &x)
{
rpc_SendRaw(rpc_io, &(x[0]), sizeof(T)*x.size());
}
template <class T>
void rpc_Receive(CRpcIo &rpc_io, vector<T> &x)
{
CDataHeader msg;
msg.RecvHeader(rpc_io);
if ((msg.m_size % sizeof(T)) != 0)
{
rpc_DataSink(rpc_io, msg.m_size);
throw CRpcError(CRpcError::WRONG_DATA_SIZE);
}
x.assign(msg.m_size/sizeof(T), 0);
if (x.size() != 0) rpc_io.Read(&(x[0]), msg.m_size);
}
inline void rpc_Send(CRpcIo &rpc_io, const string &x)
{
rpc_SendRaw(rpc_io, x.c_str(), x.length());
}
void rpc_Receive(CRpcIo &rpc_io, string &x);
// === tools ================================================================
void rpc_TranslateCallName(const string &in, string &out);