forked from yedf2/handy
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathproto_msg.cc
68 lines (63 loc) · 2.01 KB
/
proto_msg.cc
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
#include "proto_msg.h"
#include <string>
#include <google/protobuf/descriptor.h>
using namespace std;
using namespace google::protobuf;
namespace handy {
void ProtoMsgDispatcher::handle(TcpConnPtr con, Message* msg) {
auto p = protocbs_.find(msg->GetDescriptor());
if (p != protocbs_.end()) {
p->second(con, msg);
} else {
error("unknown message type %s", msg->GetTypeName().c_str());
}
}
// 4 byte total msg len, including this 4 bytes
// 4 byte name len
// name string not null ended
// protobuf data
Message* ProtoMsgCodec::decode(Buffer& s){
if (s.size() < 8) {
error("buffer is too small size: %lu", s.size());
return NULL;
}
char* p = s.data();
uint32_t msglen = *(uint32_t*)p;
uint32_t namelen = *(uint32_t*)(p+4);
if (s.size() < msglen || s.size() < 4 + namelen) {
error("buf format error size %lu msglen %d namelen %d",
s.size(), msglen, namelen);
return NULL;
}
string typeName(p + 8, namelen);
Message* msg = NULL;
const Descriptor* des = DescriptorPool::generated_pool()->FindMessageTypeByName(typeName);
if (des) {
const Message* proto = MessageFactory::generated_factory()->GetPrototype(des);
if (proto) {
msg = proto->New();
}
}
if (msg == NULL) {
error("cannot create Message for %s", typeName.c_str());
return NULL;
}
int r = msg->ParseFromArray(p + 8 + namelen, msglen - 8 - namelen);
if (!r) {
error("bad msg for protobuf");
delete msg;
return NULL;
}
s.consume(msglen);
return msg;
}
void ProtoMsgCodec::encode(Message* msg, Buffer& buf) {
size_t offset = buf.size();
buf.appendValue((uint32_t)0);
const string& typeName = msg->GetDescriptor()->full_name();
buf.appendValue((uint32_t)typeName.size());
buf.append(typeName.data(), typeName.size());
msg->SerializeToArray(buf.allocRoom(msg->ByteSize()), msg->ByteSize());
*(uint32_t*)(buf.begin()+offset) = buf.size() - offset;
}
}