2017-06-16 54 views
0

我想构建服务器应用程序解析来自客户端的protobuf数据包。C++解析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),类型packetmessageTypeString

+0

危险,威尔鲁滨逊! sizeof(packetData)== 4'(或可能是8) - 它是指针的大小,而不是它指向的数据。 –

+0

那么,你所展示的代码中没有太多可以分解的东西;但是,每个案例只有三行(并且我没有看到“messageTypeString” - 它似乎携带与protocolID相同的信息)。如果有代码可以被广义化和重用,它可能隐藏在'//类型的日志包过程'后面。 –

+0

@IgorTandetnik糟糕,我犯了'sizeof'错误。实际上,这是一种伪代码,也许是代码中的一些漏洞。在我的真实代码中,该部分不会导致问题。 – furyhunter

回答

1

你可以做这些方针的东西,我想:

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 
} 

希望,你的“之类的记录过程的”可在条件一般的工作Message

+0

它的工作原理!使用init列表初始化映射会导致编译错误,所以我将它初始化为空并在稍后的initialize方法中插入数据。 非常感谢! – furyhunter