2012-02-08 13 views
6

Mi è stato consegnato un documento che definisce un insieme di messaggi che vengono trasmessi e ricevuti su un canale di comunicazione seriale. Mi piacerebbe prendere i messaggi in arrivo e deserializzare in oggetti, e serializzare anche i miei messaggi in uscita. La codifica sopra il filo è stabilito e non modificabile, e si compone di vari campi di bit nell'intestazione e payload variabile, ad esempio,Serializzazione e deserializzazione di un campo di bit

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

ho preso un'occhiata a utilizzare protobufs, ma sembra che il loro metodo varint di codifica stabilito. Ho anche guardato allo boost-serialization, ma basandomi su ciò che ho letto finora, come viene eseguita la codifica non è del tutto chiaro.

Così, alcune domande:

  • Posso utilizzare Boost-serializzazione di convertire il mio bytestream agli oggetti?
  • Con un obiettivo di non dover rollare le mie routine per la serializzazione (un pasticcio di manutenzione), c'è un meccanismo preferito per portare a termine il mio compito (ad esempio, un archivio boost-serializzazione personalizzato, un altro metodo che non ho scoperto
+0

significa "int msg_num: 7" significa che il campo è un intero a 7 bit ? – grieve

+0

Sì. Il ": num" indica la lunghezza del bitfield – jdt141

+0

Trovo difficile rispondere a questa domanda, poiché viene mostrata solo la rappresentazione compressa ma non gli oggetti messaggio decompresso che si desidera serializzare e deserializzare. –

risposta

1

Penso che non troverai un serializzatore facile da usare che corrisponda al protocollo personalizzato che stai guardando. Ma sembra che il set di primitive che hai (int, bool + size) siano abbastanza semplici da essere in grado di scrivere il tuo decodificatore/codificatore. Semplicemente generando codice C/C++ in base al messaggio ricevuto. Dovrebbe essere un compito abbastanza semplice generare un codice compilabile prendendo tale descrizione. Dovrebbe essere una generazione automatizzata fatta in fase di compilazione - simile a ciò che protobuf/Corba stanno facendo.

Esempio: dalla specifica:

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

il convertitore potrebbe scrivere una funzione con corpo simile a (notazione astratta e supponendo 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 
    } 
} 
.... 

Questo dovrebbe essere abbastanza facile da generare e il modo più semplice per assicurarsi che la codifica sia personalizzata.

+0

AFAIK lo standard non impone all'implementazione di utilizzare alcun tipo diverso da int per i campi bit (anche se si scrive nel codice un tipo diverso, ad esempio char o bool) e lo standard lascia anche all'implementazione se i campi bit sono ordinato in memoria MSB in LSB o viceversa. A causa di questo serializzazione byte per byte può essere problematico con i campi di bit. – selalerer

+1

Sicuro. La mia risposta era più un esempio che una soluzione: a seconda di come esattamente i byte dovrebbero essere inviati sul filo, l'esatta implementazione dovrebbe riflettere il protocollo. Era più per mostrare l'idea di come si potesse fare: generare il codice di conversione dovrebbe fare il lavoro. –

0

Nel caso in cui siate limitati alla sola piattaforma (vale a dire con un ordine a byte singolo) e Tipo di messaggio POD, è possibile dichiarare il messaggio come primitive.

In caso contrario, in caso di boost.serialization almeno, sarà necessario scrivere codice, ad esempio "routine per la serializzazione". Esso supporta la conversione di ordine di byte, almeno

[Edit] sbagliato, non è primitive, mi sono perso nelle profondità della documentazione serializzazione

Problemi correlati