GrpcPrint/PrintS/Remote/bak/proto_msg.cc

61 lines
1.7 KiB
C++
Raw Normal View History

2024-03-26 10:33:00 +08:00
#include "proto_msg.h"
#include <google/protobuf/descriptor.h>
#include <string>
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;
}