2012-02-08 3 views
6

Мне вручен документ, который определяет набор сообщений, которые передаются и принимаются по последовательному каналу связи. Я хотел бы принимать входящие сообщения и десериализовывать их в объекты, а также сериализовывать и исходящие сообщения. Кодирование по проводам устанавливается и не может быть изменен, и состоит из различных битовых полей в заголовке и различных полезных нагрузок, например,Сериализация и десериализация поля бит

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

Я посмотрел на использование protobufs, но это, кажется, что их метод varint кодирования является установлено. Я также посмотрел на boost-serialization, но, основываясь на том, что я читал до сих пор, как делается кодировка там, не совсем ясно.

Итак, несколько вопросов:

  • Может ли я использовать наддув-сериализацию конвертировать мои потоковый к объектам?
  • С целью не, вынуждены сворачивать мои собственные процедуры для сериализации (беспорядок обслуживания), есть ли предпочтительный механизм для выполнения моей задачи (например, собственный архив с форсированной сериализацией, другой метод, который я не обнаружил)
+0

«ИНТ msg_num: 7» Значит ли поле является 7-битное целое ? – grieve

+0

Да. «: Num» указывает длину битового поля – jdt141

+0

Я нахожу, что этот вопрос трудно ответить, поскольку отображается только упакованное представление, но не объекты распакованного сообщения, которые вы хотели бы сериализовать и десериализовать. –

ответ

1

Я думаю, вы не найдете простой в использовании сериализатор, который будет соответствовать настраиваемому протоколу, на который вы смотрите. Но он выглядит как набор примитивов, которые у вас есть (int, bool + size), достаточно просты, чтобы иметь возможность писать собственный декодер/кодировщик. Просто генерирует код C/C++ на основе полученного сообщения. Должна быть довольно простая задача генерировать компилятивный код с таким описанием. Это должно быть автоматическое поколение, выполненное во время компиляции, подобно тому, что делают protobuf/Corba.

Пример: из спецификации:

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

преобразователь может написать функцию с телом, аналогичным (абстрактное обозначением и предполагая MSB):

Декодер:

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 

Кодера:

{ 
    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 
    } 
} 
.... 

Это должно быть довольно легко создать и простейший способ убедиться, что кодировка является обычным.

+0

AFAIK стандарт не принуждает реализацию использовать любой тип, отличный от int для битных полей (даже если вы записываете в свой код другой тип, например char или bool), а стандарт также оставляет его до реализации, являются ли битовые поля упорядочен в памяти MSB на LSB или наоборот. Из-за этого последовательный байтовый байт может быть проблематичным с битовыми полями. – selalerer

+1

Несомненно. Мой ответ был скорее примером, чем решением - в зависимости от того, как именно байты должны быть отправлены по проводу, точная реализация должна отражать протокол. Это было больше, чтобы показать, как это можно сделать: генерация кода преобразования должна выполнять эту работу. –

0

Если вы ограничены только одной платформой (т. Е. Ограничены порядком одного байта), а Message - это тип POD, вы можете объявить свое сообщение как primitive.

В противном случае, в случае повышения. Сериализация, по крайней мере, вам придется писать код, то есть «подпрограммы для сериализации». Он поддерживает преобразование порядка байтов, по крайней мере,

[Редактировать] Неправильно, это не primitive, я потерял в глубине сериализации документации

Смежные вопросы