Délisson Junio
Délisson Junio

Reputation: 1308

Good library for parsing binary protocols with C++

I'm having to interface my code with some binary protocol coming from an application I cannot control. So far, I have been writing manual parsing from the data, as in:

char *data = ...
MovementPacket pkt;
pkt.x = data[0] | data[1] << 8;
pkt.y = data[2] | data[3] << 8;

It's obvious that this process is very error-prone and tedious. I remember doing it in Java as in:

pkt.x = stream.readShort();
pkt.y = stream.readShort();

Is there some kind of library that enables me to do this, taking into account endianness?

I've looked into protobuf and cap'n'proto but while both seem great when I can define both sides of the protocol, I'm not sure they would play well if I had to parse a specific protocol. Is that correct or did I just read the wrong resources? Are there alternatives more suited to the task?

The protocol itself is a simple TCP message-oriented format: The handling from TCP stream into messages is already done, I want something to parse the messages themselves. All the messages start with a two-byte identification field, which tells the message's type, followed by message data. An example, for a movement packet:

0x00 0x01 0x00 0x00 0x00 0x01 0x00 0x00 0x00 0x02

[Msg. Id] [int32 X value] [int32 Y value]

I was looking for some library which could, given a message structure, parse it into a struct, taking into account endianness, without having to write manual parsing code.

Upvotes: 0

Views: 2091

Answers (1)

Steve Townsend
Steve Townsend

Reputation: 54178

Be warned that this falls firmly under "advanced topics", but Boost.Spirit has support for endian-specific binary parsing via Qi. There may be something there that assists you to complete all or part of your task, if you are adventurous enough to dig into the source.

The protocol description is somewhat helpful. If the primitive types are all int32 this problem is pretty tractable. However, it seems to me unlikely you are going to find this Holy Grail of zero parsing code since this is a custom, if simple, protocol. Perhaps you can reduce the problem to one of parsing only certain types - then a simple parser that calls a series of parse(primitiveTypeValue) functions to append to std::vector<primitiveType> for each primitive might be feasible.

Upvotes: 2

Related Questions