1

I create my RPC Protocol with PB like:

enum EMessages {
  E_MSG_METHOD_CONNECT = 0x8001,
  E_MSG_EVENT_CONNECT  = 0xA001,
 ...
}

struct MsgHeader {
  required int32  sessionRef    = 1;
  required int32  transactionId = 2;
  required int32  status        = 3;
}

struct MSG_METHOD_CONNECT {
  optional Messages    opCode  = 1 [default = E_MSG_METHOD_CONNECT];
  required MsgHeader   header  = 2;
  .. other fields ..
}

Now, I defined an interface and a template class to add a level of indirection:

class IMessage {
  virtual INT     getOpCode() = 0;
  virtual STRING  getName() = 0;
  virtual size_t  getSize() = 0;
  virtual INT     SerializeToString(STRING& out) = 0;
  virtual INT     ParseFromString(STRING& in) = 0;
  ....
}

template<class MESSAGE>
class IMessageImpl : public IMessage {
  protected:
    MESSAGE   m_Message;  ///< The Message Implementation
  public:
    virtual MESSAGE&  getMessage() = 0;
};

And I will use it as:

IMessageImpl<MSG_METHOD_CONNECT> MsgConnect;

Now, when I receive the data from an endpoint I need, of course, to deserialize it according with the message opCode.
Reading this article I'm thinking to use a type map like boost::mpl::map but, since I never use it, I'm searching for some suggestions.

<< ------------------------ [EDIT] ------------------------ >>

Regarding the code above, I try to code it in the following way:

template<class MESSAGE>
class PBMessage : public IMessageImpl<MESSAGE>
{
public:
  PBMessage() {};
  /* ... other methods ... */
};


// Map of types. The key is the Message opCode
typedef typename mpl::map< mpl::pair<mpl::int_[100], PBMessage<MSG_METHOD_CONNECT> >, 
                           mpl::pair<mpl::int_[101], PBMessage<MSG_EVENT_CONNECT> >,
                         > TMessageMap;

// The Message type
template < typename MessageMap, int opCode >
typedef typename mpl::at<MessageMap, mpl::int_<opCode> >::type::value  TMessage;

And, to create a message from a received buffer I try to code (take it as pseudo-code):

  class PBMessageFactory : public IMessageFactory {
  public:
    IMessage* createMessage(CHAR* buff, UINT size) {
      int opCode = buff[0]; 
      TMessage<TMessageMap, opCode> msg;
      msg.ParseFromString( STRING(buff) );
    }        
  };

But with no success...Is there someone could give me some suggestions how to retrieve types from a mpl::map?

Thanks,
Daniele.

Barzo
  • 1,039
  • 1
  • 11
  • 37
  • I think the "horribleness" of [the first method that author posted](http://blog.florindinu.ro/posts/message-dispatching-in-c-part-0-problem.html) is overrated. You need to read a blog post to understand his version, whereas even a beginning programmer will understand the big `switch` statement. – japreiss Feb 12 '13 at 14:46
  • Hi @japreiss, I agree with you. But maybe there is a better way to implements it? Maybe simply to build a map like: boost::mpl::map > ? – Barzo Feb 12 '13 at 14:58

0 Answers0