c++ 使用 switch/case 解析 protobuf 消息(减少重复代码)
c++ parsing protobuf messages with switch/case (reducing duplicate code)
我正在尝试构建服务器应用程序来解析来自客户端的 protobuf 数据包。
数据包处理代码如下:
在原型文件中,
package protocol;
message messageA
{
...
}
message messageB
{
...
}
message messageB
{
...
}
...
在代码文件中,
enum {
messageTypeA = 1,
messageTypeB,
messageTypeC,
...
}
void ProcessPacket(int protocolID, char* packetData)
{
string messageTypeString = "";
switch(protocolID)
{
case messageTypeA :
protocol::messageA packet;
packet.ParseFromArray(packetData, sizeof(padketData));
messageTypeString = "messageA";
... //kind of logging packet procedure
break;
case messageTypeB :
protocol::messageB packet;
packet.ParseFromArray(packetData, sizeof(padketData));
messageTypeString = "messageB";
... //kind of logging packet procedure
break;
case messageTypeC :
protocol::messageC packet;
packet.ParseFromArray(packetData, sizeof(padketData));
messageTypeString = "messageC";
... //kind of logging packet procedure
break;
}
//using messageTypeString and so on..
}
正如我们所看到的,当数据包种类增加时,就会有很多重复代码。
如何减少重复代码?
有什么方法可以同时映射 protocolID(enum value)
、类型 packet
和 messageTypeString
?
我想你可以按照这些思路做一些事情:
std::map<int, std::unique_ptr<google::protobuf::Message>> protocols = {
{messageTypeA, std::make_unique<protocol::messageA>()},
{messageTypeB, std::make_unique<protocol::messageB>()},
{messageTypeC, std::make_unique<protocol::messageC>()}
};
void ProcessPacket(int protocolID, char* packetData, int packetSize) {
auto it = protocols.find(protocolID);
assert(it != protocols.end());
std::unique_ptr<google::protobuf::Message> packet{it->second->New()};
packet->ParseFromArray(packetData, packetSize);
std::string messageTypeString = packet->GetTypeName();
//kind of logging packet procedure goes here
}
希望您的 "kind of logging procedure" 可以在通用 Message
方面发挥作用
我正在尝试构建服务器应用程序来解析来自客户端的 protobuf 数据包。
数据包处理代码如下:
在原型文件中,
package protocol;
message messageA
{
...
}
message messageB
{
...
}
message messageB
{
...
}
...
在代码文件中,
enum {
messageTypeA = 1,
messageTypeB,
messageTypeC,
...
}
void ProcessPacket(int protocolID, char* packetData)
{
string messageTypeString = "";
switch(protocolID)
{
case messageTypeA :
protocol::messageA packet;
packet.ParseFromArray(packetData, sizeof(padketData));
messageTypeString = "messageA";
... //kind of logging packet procedure
break;
case messageTypeB :
protocol::messageB packet;
packet.ParseFromArray(packetData, sizeof(padketData));
messageTypeString = "messageB";
... //kind of logging packet procedure
break;
case messageTypeC :
protocol::messageC packet;
packet.ParseFromArray(packetData, sizeof(padketData));
messageTypeString = "messageC";
... //kind of logging packet procedure
break;
}
//using messageTypeString and so on..
}
正如我们所看到的,当数据包种类增加时,就会有很多重复代码。
如何减少重复代码?
有什么方法可以同时映射 protocolID(enum value)
、类型 packet
和 messageTypeString
?
我想你可以按照这些思路做一些事情:
std::map<int, std::unique_ptr<google::protobuf::Message>> protocols = {
{messageTypeA, std::make_unique<protocol::messageA>()},
{messageTypeB, std::make_unique<protocol::messageB>()},
{messageTypeC, std::make_unique<protocol::messageC>()}
};
void ProcessPacket(int protocolID, char* packetData, int packetSize) {
auto it = protocols.find(protocolID);
assert(it != protocols.end());
std::unique_ptr<google::protobuf::Message> packet{it->second->New()};
packet->ParseFromArray(packetData, packetSize);
std::string messageTypeString = packet->GetTypeName();
//kind of logging packet procedure goes here
}
希望您的 "kind of logging procedure" 可以在通用 Message