C++与切换/CASE解析原BoFF消息(减少重复代码)

C++与切换/CASE解析原BoFF消息(减少重复代码),c++,protocol-buffers,code-duplication,C++,Protocol Buffers,Code Duplication,我正在尝试构建服务器应用程序来解析来自客户端的protobuf数据包 数据包处理代码如下所示: 在proto文件中 package protocol; message messageA { ... } message messageB { ... } message messageB { ... } ... 在代码文件中 enum { messageTypeA = 1, messageTypeB, messageTypeC, ...

我正在尝试构建服务器应用程序来解析来自客户端的protobuf数据包

数据包处理代码如下所示:

在proto文件中

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..
}
正如我们所看到的,当数据包种类增加时,会有很多重复的代码

如何减少重复代码


有什么方法可以同时映射protocolIDenum值、数据包类型和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
}

Will Robinson,希望您的日志记录过程能够在通用消息方面工作

Danger!sizeofpacketData==4或者可能是8——这是指针的大小,而不是指针指向的数据;但是,每个案例只有三行,我看不出messageTypeString的意义——它似乎携带与protocolID相同的信息。如果有可以通用和重用的代码,它可能隐藏在//类日志包过程后面。@IgorTandetnik Oops,我犯了一个sizeof错误。实际上,这是一种伪代码,可能代码中有一些漏洞。在我的真实代码中,该部分不会引起问题。@IgorTandetnik您是对的,重复的部分位于…//类似于日志数据包过程的部分。我认为那个部分可以移动到函数中,但我不知道怎么做。如果有办法映射枚举值和协议类型,比如messageTypeA和protocol::messageA,messageTypeB和messageB,等等,我只能将protocolID作为参数,代码会很短。这很有效!使用init list初始化映射会导致编译错误,所以我将其初始化为空,然后在initialize方法中插入数据。谢谢!