Cómo deshacerse de los bytes de relleno entre los miembros de datos de una estructura
Tengo un archivo binario con "mensajes" y estoy tratando de ajustar los bytes dentro de la variable correcta usando structs. En mi ejemplo utilicé dos tipos de mensajes: Tmessage y Amessage.
#include <iostream>
#include <fstream>
#include <stdlib.h>
#include <string>
#include <iomanip>
using namespace std;
struct Tmessage
{
unsigned short int Length;
char MessageType;
unsigned int Second;
};
struct Amessage
{
unsigned short int Length;
char MessageType;
unsigned int Timestamp;
unsigned long long int OrderReferenceNumber;
char BuySellIndicator;
unsigned int Shares;
char Stock[6];
unsigned int Price;
};
int main(int argc, char* argv[])
{
const char* filename = argv[1];
fstream file(filename, ios::in | ios::binary);
unsigned long long int pi = 0;
if(file.is_open()){ cout << filename << " OPENED" << endl; }
else { cout << "FILE NOT OPENED" << endl; }
unsigned char* memblock;
memblock = new unsigned char[128];
file.read((char *)memblock, 128);
cout << "BINARY DATA" << endl;
while (pi < 128)
{
cout << setw(2) << hex << static_cast<unsigned int>(memblock[pi]) << " ";
pi++;
if((pi%16)==0) cout << endl;
}
unsigned int poi = 0;
Tmessage *Trecord;
Trecord = (Tmessage *)memblock;
cout << "Length: " << hex << (*Trecord).Length << endl;
cout << "Message type: " << hex << (*Trecord).MessageType << endl;
cout << "Second: " << hex << (*Trecord).Second << endl;
poi = poi + 7; cout << endl;
Amessage *Arecord;
Arecord = (Amessage *)(memblock+poi);
cout << "Length: " << hex << (*Arecord).Length << endl;
cout << "Message type: " << hex << (*Arecord).MessageType << endl;
cout << "Timestamp: " << hex << (*Arecord).Timestamp << endl;
cout << "OrderReferenceNumber: " << hex << (*Arecord).OrderReferenceNumber << endl;
cout << "BuySellIndicator: " << hex << (*Arecord).BuySellIndicator << endl;
cout << "Shares: " << hex << (*Arecord).Shares << endl;
cout << "Stock: " << hex << (*Arecord).Stock << endl;
cout << "Price: " << hex << (*Arecord).Price << endl;
delete memblock;
file.close();
cout << endl << "THE END" << endl;
return 0;
}
La salida cuando ejecuto el programa:
stream OPENED
BINARY DATA
0 5 54 0 0 62 72 0 1c 41 0 f 42 40 0 0
0 0 0 4 2f 76 53 0 0 3 e8 53 50 59 20 20
20 0 11 5 d0 0 1c 41 0 f 42 40 0 0 0 0
0 4 2f 78 42 0 0 3 e8 53 50 59 20 20 20 0
10 f7 5c 0 1c 41 0 f 42 40 0 0 0 0 0 4
2f 90 53 0 0 1 2c 53 50 59 20 20 20 0 11 2
b0 0 5 54 0 0 62 76 0 d 44 14 25 78 80 0
0 0 0 0 4 2f 90 0 d 44 14 25 78 80 0 0
Length: 500
Message type: T
Second: 726200
Length: 1c00
Message type: A
Timestamp: 40420f
OrderReferenceNumber: 53762f0400000000
BuySellIndicator:
Shares: 20595053
Stock:
Price: 420f0041
THE END
El programa coloca los bytes dentro de la estructura Tmessage correctamente. (0 5 54 0 0 62 72)
Sin embargo, algo ocurre mientras analiza Amessage.
(0 1c 41 0 f 42 40 0 0 0 0 0 4 2f 76 53 0 0 3 e8 53 50 59 20 20 20 0 11 5 d0)
La longitud, el tipo de mensaje y la marca de tiempo son correctos, pero OrderReferenceNumber contiene el byte "53" que pertenece a BuySellIndicator y la otra variable es incorrecta.
La salida correcta del mensaje A debe ser:
Longitud: 1c 0
Tipo de mensaje: 41
Marca de tiempo: 40 42 f 0
OrderReferenceNumber: 76 2f 4 0 0 0 0 0
BuySellIndicator: 53
Acciones: e8 3 0 0
Stock: 53 50 59 20 20 20
Precio: d0 5 11 0
Las 2 preguntas: a) ¿Por qué OrderReferenceNumber contiene el byte "53"? b) Creo que "char Stock [6]" no funciona, porque entre los bytes de Share y de Price hay más de 6 bytes. ¿Cómo puedo ajustar los 6 bytes en el vector o cadena de caracteres?
Nota: Soy consciente de que tengo que cambiar los bytes porque los datos binarios vienen en big-endian. Es por eso que "Stock" no debe intercambiarse. ¡Muchas gracias por su ayuda! Saludos cordiales,