#include "proto_msg.h" #include #include using namespace std; using namespace google::protobuf; // 4 byte total msg len, including this 4 bytes // 4 byte name len // name string not null ended // protobuf data ProtoMessage *ProtoMsgCodec::decode(unsigned char* buf, size_t size) { if (size < 8) { return nullptr; } char *p = (char *)buf; uint32_t msglen = *(uint32_t *)buf; uint32_t namelen = *(uint32_t *)(buf + 4); if (size < msglen || size < 4 + namelen) { return nullptr; } string typeName(p + 8, namelen); ProtoMessage *msg = NULL; const ProtoDescriptor *des = DescriptorPool::generated_pool()->FindMessageTypeByName(typeName); if (des) { const ProtoMessage *proto = MessageFactory::generated_factory()->GetPrototype(des); if (proto) { msg = proto->New(); } } if (msg == NULL) { return nullptr; } int r = msg->ParseFromArray(p + 8 + namelen, msglen - 8 - namelen); if (!r) { delete msg; return nullptr; } return msg; } unsigned char* ProtoMsgCodec::encode(ProtoMessage *msg, size_t& msgSize) { if (!msg) return nullptr; const string &typeName = msg->GetDescriptor()->full_name(); uint32_t buf_size = 4 + 4 + typeName.size() + msg->ByteSize(); unsigned char* buf = new unsigned char[buf_size]; if (!buf) return nullptr; *(uint32_t*)buf = buf_size; size_t offset = 4; *(uint32_t*)(buf + offset) = typeName.size(); offset += 4; memcpy_s(buf + offset, buf_size, typeName.data(), typeName.size()); offset += typeName.size(); msg->SerializeToArray(buf + offset, msg->ByteSize()); msgSize = buf_size; return buf; }