Skip to content

Commit 2d12bd7

Browse files
committed
buttonrpc 使用cpp14改写
0 parents  commit 2d12bd7

File tree

7 files changed

+2206
-0
lines changed

7 files changed

+2206
-0
lines changed

README.md

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
2+
# buttonrpc - a simple rpc framework for C++
3+
- ZeroMQ as the network layer.
4+
5+
## Features
6+
- 轻量级,跨平台,简单易用
7+
- 服务端可以绑定自由函数,类成员函数,std::function对象
8+
- 服务端可以绑定参数是任意自定义类型的函数
9+
- 客户端与服务端自动重连机制
10+
- 客户端调用超时选项
11+
12+
## Example
13+
server:
14+
15+
```c++
16+
#include "buttonrpc.hpp"
17+
18+
int foo(int age, int mm){
19+
return age + mm;
20+
}
21+
22+
int main()
23+
{
24+
buttonrpc server;
25+
server.as_server(5555);
26+
27+
server.bind("foo", foo);
28+
server.run();
29+
30+
return 0;
31+
}
32+
```
33+
34+
client:
35+
36+
```c++
37+
#include <iostream>
38+
#include "buttonrpc.hpp"
39+
40+
int main()
41+
{
42+
buttonrpc client;
43+
client.as_client("127.0.0.1", 5555);
44+
int a = client.call<int>("foo", 2, 3).val();
45+
std::cout << "call foo result: " << a << std::endl;
46+
system("pause");
47+
return 0;
48+
}
49+
50+
// output: call foo result: 5
51+
52+
```
53+
54+
## Dependences
55+
- [ZeroMQ](http://zguide.zeromq.org/page:all)
56+
57+
58+
## Building
59+
- vs2010 或者更高版本 (为了兼容vs2010没有用到可变模板参数)
60+
- gcc/g++ 支持部分c++11特性即可
61+
62+
## Usage
63+
64+
- 1: 更多例子在目录 example/ 下
65+

Serializer.hpp

Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
/**
2+
*
3+
* buttonrpc library
4+
* Copyright 2018-04-28 Button
5+
*
6+
*/
7+
8+
#pragma once
9+
#include <vector>
10+
#include <sstream>
11+
#include <algorithm>
12+
#include <cstdint>
13+
using namespace std;
14+
15+
class StreamBuffer : public vector<char>
16+
{
17+
public:
18+
StreamBuffer(){ m_curpos = 0; }
19+
StreamBuffer(const char* in, size_t len){
20+
m_curpos = 0;
21+
insert(begin(), in, in+len);
22+
}
23+
~StreamBuffer(){ };
24+
25+
void reset(){ m_curpos = 0; }
26+
const char* data(){ return &(*this)[0]; }
27+
const char* current(){ return&(*this)[m_curpos]; }
28+
void offset(int k){ m_curpos += k; }
29+
bool is_eof(){ return (m_curpos >= size()); }
30+
void input( char* in, size_t len){ insert(end(), in, in+len); }
31+
int findc(char c){
32+
iterator itr = find(begin()+m_curpos, end(), c);
33+
if (itr != end())
34+
{
35+
return itr - (begin()+m_curpos);
36+
}
37+
return -1;
38+
}
39+
40+
private:
41+
// 当前字节流位置
42+
unsigned int m_curpos;
43+
};
44+
45+
class Serializer
46+
{
47+
public:
48+
Serializer() { m_byteorder = LittleEndian; };
49+
~Serializer(){ };
50+
51+
Serializer(StreamBuffer dev, int byteorder=LittleEndian){
52+
m_byteorder = byteorder;
53+
m_iodevice = dev;
54+
}
55+
56+
public:
57+
enum ByteOrder {
58+
BigEndian,
59+
LittleEndian
60+
};
61+
62+
public:
63+
void reset(){
64+
m_iodevice.reset();
65+
}
66+
int size(){
67+
return m_iodevice.size();
68+
}
69+
void skip_raw_date(int k){
70+
m_iodevice.offset(k);
71+
}
72+
const char* data(){
73+
return m_iodevice.data();
74+
}
75+
void byte_orser(char* in, int len){
76+
if (m_byteorder == BigEndian){
77+
reverse(in, in+len);
78+
}
79+
}
80+
void write_raw_data(char* in, int len){
81+
m_iodevice.input(in, len);
82+
m_iodevice.offset(len);
83+
}
84+
const char* current(){
85+
return m_iodevice.current();
86+
}
87+
void clear(){
88+
m_iodevice.clear();
89+
reset();
90+
}
91+
92+
template<typename T>
93+
void output_type(T& t);
94+
95+
template<typename T>
96+
void input_type(T t);
97+
98+
// 直接给一个长度, 返回当前位置以后x个字节数据
99+
void get_length_mem(char* p, int len){
100+
memcpy(p, m_iodevice.current(), len);
101+
m_iodevice.offset(len);
102+
}
103+
104+
public:
105+
template<typename Tuple, std::size_t Id>
106+
void getv(Serializer& ds, Tuple& t) {
107+
ds >> std::get<Id>(t);
108+
}
109+
110+
template<typename Tuple, std::size_t... I>
111+
Tuple get_tuple(std::index_sequence<I...>) {
112+
Tuple t;
113+
initializer_list<int>{((getv<Tuple, I>(*this, t)), 0)...};
114+
return t;
115+
}
116+
117+
template<typename T>
118+
Serializer &operator >> (T& i){
119+
output_type(i);
120+
return *this;
121+
}
122+
123+
template<typename T>
124+
Serializer &operator << (T i){
125+
input_type(i);
126+
return *this;
127+
}
128+
129+
private:
130+
int m_byteorder;
131+
StreamBuffer m_iodevice;
132+
};
133+
134+
template<typename T>
135+
inline void Serializer::output_type(T& t)
136+
{
137+
int len = sizeof(T);
138+
char* d = new char[len];
139+
if (!m_iodevice.is_eof()){
140+
memcpy(d, m_iodevice.current(), len);
141+
m_iodevice.offset(len);
142+
byte_orser(d, len);
143+
t = *reinterpret_cast<T*>(&d[0]);
144+
}
145+
delete [] d;
146+
}
147+
148+
template<>
149+
inline void Serializer::output_type(std::string& in)
150+
{
151+
int marklen = sizeof(uint16_t);
152+
char* d = new char[marklen];
153+
memcpy(d, m_iodevice.current(), marklen);
154+
byte_orser(d, marklen);
155+
int len = *reinterpret_cast<uint16_t*>(&d[0]);
156+
m_iodevice.offset(marklen);
157+
delete [] d;
158+
if (len == 0) return;
159+
in.insert(in.begin(), m_iodevice.current(), m_iodevice.current() + len);
160+
m_iodevice.offset(len);
161+
}
162+
163+
template<typename T>
164+
inline void Serializer::input_type(T t)
165+
{
166+
int len = sizeof(T);
167+
char* d = new char[len];
168+
const char* p = reinterpret_cast<const char*>(&t);
169+
memcpy(d, p, len);
170+
byte_orser(d, len);
171+
m_iodevice.input(d, len);
172+
delete [] d;
173+
}
174+
175+
template<>
176+
inline void Serializer::input_type(std::string in)
177+
{
178+
// 先存入字符串长度
179+
uint16_t len = in.size();
180+
char* p = reinterpret_cast< char*>(&len);
181+
byte_orser(p, sizeof(uint16_t));
182+
m_iodevice.input(p, sizeof(uint16_t));
183+
184+
// 存入字符串
185+
if (len == 0) return;
186+
char* d = new char[len];
187+
memcpy(d, in.c_str(), len);
188+
m_iodevice.input(d, len);
189+
delete [] d;
190+
}
191+
192+
template<>
193+
inline void Serializer::input_type(const char* in)
194+
{
195+
input_type<std::string>(std::string(in));
196+
}

0 commit comments

Comments
 (0)