Serialization and deserialization of the bit field

I was presented with a document that defines a set of messages that are transmitted and received via a serial communication channel. I would like to accept incoming messages and deserialize them into objects, as well as serialize my outgoing messages. The wire encoding is set and does not change and consists of various bitfields in the header and various payloads, for example,

class Message{ int msg_num : 7 int dest_addr : 4 bool SRR : 1 bool IDE : 1 int source_addr : 6 //... and so on... } 

I took a look at using protobufs , but it looks like their varint encoding method is installed. I also looked at boost-serialization , but based on what I have read so far how encoding is done, it's not entirely clear

So a few questions:

  • Can I use boost-serialization to convert my stream stream to objects?
  • In order not to run my own procedures for serialization (a mess for maintenance), is there a preferred mechanism for performing my task (for example, my own archive with extended serialization, another method that I did not find)
+6
source share
2 answers

I think you will not find an easy to use serializer that matches the custom protocol you are looking at. But it looks like a set of primitives that you have (int, bool + size) are simple enough to be able to write your own decoder / encoder. It simply generates C / C ++ code based on the received message. It should be a fairly simple task to generate compilation code with such a description. This should be an automatic generation performed at compile time, similar to what protobuf / Corba does.

Example: from specification:

 class Message{ int msg_num : 7 int dest_addr : 4 bool SRR : 1 bool IDE : 1 int source_addr : 6 //... and so on... } 

the converter could write a function with a body similar (abstract notation and assuming MSB):

Decoder:

 m = new Message() { long long val = 0 for(int i=0; i<7; i++) { val <<= 8 val += nextByte() } m.msg_num = val } { long long val = 0 for(int i=0; i<4; i++) { val <<= 8 val += nextByte() } m.dest_addr = val } { int val = nextByte() m.SRR = val } { int val = nextByte() m.IDE = val } { long long val = 0 for(int i=0; i<6; i++) { val <<= 8 val += nextByte() } m.source_addr = val } // and so on 

encoder:

 { long long val = m.msg_num for(int i=0;i<7;i++) { writeByte(val & 0xFF) val >>= 8 } } { long long val = m.dest_addr for(int i=0;i<4;i++) { writeByte(val & 0xFF) val >>= 8 } } .... 

This is pretty easy to create and the easiest way to make sure the encoding is normal.

+1
source

If you are limited to only one platform (i.e., limited to one byte order), and Message is a POD type, you can declare your message as primitive .

Otherwise, in the case of boost.serialization, at least you have to write code, i.e. "routines for serialization." It supports byte order conversions, at least

[Edit] False, this is not primitive , I am lost in the depths of a serialization document

0
source

Source: https://habr.com/ru/post/907989/


All Articles