2012-02-08 18 views
6

Se me ha entregado un documento que define un conjunto de mensajes que se transmiten y reciben a través de un canal de comunicaciones en serie. Me gustaría tomar los mensajes entrantes y deserializarlos en objetos, y serializar mis mensajes salientes también. La codificación sobre el alambre se establece y no se puede cambiar, y se compone de varios campos de bits en el encabezado y diferentes cargas útiles, por ejemplo,Serialización y deserialización de un campo de bit

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

Me tomó un vistazo en el uso de protobufs, pero parece que su método varint de codificación es establecido. También miré boost-serialization, pero en base a lo que he leído hasta ahora, no está del todo claro cómo se realiza la codificación.

Así, algunas preguntas:

  • ¿Puedo utilizar la serialización impulso para convertir mi bytestream a objetos?
  • con un objetivo de no tener que pasar mis propias rutinas de serialización (un lío de mantenimiento), ¿hay un mecanismo preferido para llevar a cabo mi tarea (por ejemplo, un archivo personalizado de refuerzo de serialización, otro método que no he descubierto)
+0

significa "int msg_num: 7" significa que el campo es un número entero de 7 bits ? – grieve

+0

Sí. El ": num" indica la longitud del campo de bits – jdt141

+0

Me resulta difícil responder a esta pregunta, ya que solo se muestra la representación empaquetada pero no los objetos de mensaje desempaquetados que desea serializar y deserializar. –

Respuesta

1

Creo que no encontrará un serializador fácil de usar que coincida con el protocolo personalizado que está mirando. Pero parece que el conjunto de primitivos que tiene (int, bool + size) son lo suficientemente simples como para poder escribir su propio decodificador/codificador. Simplemente generando un código C/C++ basado en el mensaje recibido. Debería ser una tarea bastante simple generar un código compilable tomando dicha descripción. Debe ser una generación automatizada realizada en el momento de la compilación, similar a lo que están haciendo protobuf/Corba.

Ejemplo: a partir de la especificación:

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

el convertidor podría escribir una función con el cuerpo similar a (notación abstracta y suponiendo 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 
    } 
} 
.... 

Eso debería ser bastante fácil de generar y la forma más simple de asegurarse de que la codificación sea personalizada.

+0

AFAIK el estándar no obliga a la implementación a usar ningún tipo diferente de int para campos de bits (incluso si escribe en su código un tipo diferente, por ejemplo, char o bool) y el estándar también deja la implementación si los campos de bit son ordenado en la memoria MSB a LSB o al revés. Debido a eso, la serialización de byte por byte puede ser problemática con los campos de bit. – selalerer

+1

Claro. Mi respuesta fue más un ejemplo que una solución: dependiendo de cómo se envían exactamente los bytes por cable, la implementación exacta debería reflejar el protocolo. Fue más para mostrar la idea de cómo se podría hacer: generar el código de conversión debería hacer el trabajo. –

0

En caso de que esté limitado solo a una plataforma (es decir, limitado con el orden de un solo byte), y Mensaje es tipo POD, puede declarar su mensaje como primitive.

De lo contrario, en caso de boost.serialization al menos, tendrá que escribir el código, es decir, 'rutinas para la serialización'. Soporta conversiones de orden de bytes, al menos

[Editar] incorrecto, no es primitive, estoy perdido en las profundidades de documentos de serialización

Cuestiones relacionadas