Fix transmission of float and double values in generic protocol
gcc -Wall -Werror turned up some problems with the type-punning of pointers used to write the message buffer; it turns out that truncated ints were being written to the message buffer when values needed to be swapped to network byte order.
This commit is contained in:
parent
0a64405cad
commit
62620177aa
1 changed files with 25 additions and 10 deletions
|
@ -97,6 +97,15 @@ FGGeneric::FGGeneric(vector<string> tokens) : exitOnError(false)
|
||||||
FGGeneric::~FGGeneric() {
|
FGGeneric::~FGGeneric() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
union u32 {
|
||||||
|
uint32_t intVal;
|
||||||
|
float floatVal;
|
||||||
|
};
|
||||||
|
|
||||||
|
union u64 {
|
||||||
|
uint64_t longVal;
|
||||||
|
double doubleVal;
|
||||||
|
};
|
||||||
|
|
||||||
// generate the message
|
// generate the message
|
||||||
bool FGGeneric::gen_message_binary() {
|
bool FGGeneric::gen_message_binary() {
|
||||||
|
@ -146,9 +155,11 @@ bool FGGeneric::gen_message_binary() {
|
||||||
if (binary_byte_order == BYTE_ORDER_MATCHES_NETWORK_ORDER) {
|
if (binary_byte_order == BYTE_ORDER_MATCHES_NETWORK_ORDER) {
|
||||||
*((float*)&buf[length]) = val;
|
*((float*)&buf[length]) = val;
|
||||||
} else {
|
} else {
|
||||||
*((float*)&buf[length]) = sg_bswap_32(*(uint32_t*)&val);
|
u32 tmpun32;
|
||||||
|
tmpun32.floatVal = static_cast<float>(val);
|
||||||
|
*((uint32_t*)&buf[length]) = sg_bswap_32(tmpun32.intVal);
|
||||||
}
|
}
|
||||||
length += sizeof(int32_t);
|
length += sizeof(uint32_t);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FG_DOUBLE:
|
case FG_DOUBLE:
|
||||||
|
@ -158,7 +169,9 @@ bool FGGeneric::gen_message_binary() {
|
||||||
if (binary_byte_order == BYTE_ORDER_MATCHES_NETWORK_ORDER) {
|
if (binary_byte_order == BYTE_ORDER_MATCHES_NETWORK_ORDER) {
|
||||||
*((double*)&buf[length]) = val;
|
*((double*)&buf[length]) = val;
|
||||||
} else {
|
} else {
|
||||||
*((double*)&buf[length]) = sg_bswap_64(*(uint64_t*)&val);
|
u64 tmpun64;
|
||||||
|
tmpun64.doubleVal = val;
|
||||||
|
*((uint64_t*)&buf[length]) = sg_bswap_64(tmpun64.longVal);
|
||||||
}
|
}
|
||||||
length += sizeof(int64_t);
|
length += sizeof(int64_t);
|
||||||
break;
|
break;
|
||||||
|
@ -195,6 +208,7 @@ bool FGGeneric::gen_message_binary() {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FOOTER_MAGIC:
|
case FOOTER_MAGIC:
|
||||||
|
case FOOTER_NONE:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -282,7 +296,6 @@ bool FGGeneric::gen_message() {
|
||||||
bool FGGeneric::parse_message_binary() {
|
bool FGGeneric::parse_message_binary() {
|
||||||
char *p2, *p1 = buf;
|
char *p2, *p1 = buf;
|
||||||
int32_t tmp32;
|
int32_t tmp32;
|
||||||
int64_t tmp64;
|
|
||||||
double val;
|
double val;
|
||||||
int i = -1;
|
int i = -1;
|
||||||
|
|
||||||
|
@ -323,28 +336,30 @@ bool FGGeneric::parse_message_binary() {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FG_FLOAT:
|
case FG_FLOAT:
|
||||||
|
u32 tmpun32;
|
||||||
if (binary_byte_order == BYTE_ORDER_NEEDS_CONVERSION) {
|
if (binary_byte_order == BYTE_ORDER_NEEDS_CONVERSION) {
|
||||||
tmp32 = sg_bswap_32(*(int32_t *)p1);
|
tmpun32.intVal = sg_bswap_32(*(uint32_t *)p1);
|
||||||
} else {
|
} else {
|
||||||
tmp32 = *(int32_t *)p1;
|
tmpun32.floatVal = *(float *)p1;
|
||||||
}
|
}
|
||||||
|
|
||||||
val = _in_message[i].offset +
|
val = _in_message[i].offset +
|
||||||
*(float *)&tmp32 * _in_message[i].factor;
|
tmpun32.floatVal * _in_message[i].factor;
|
||||||
|
|
||||||
_in_message[i].prop->setFloatValue(val);
|
_in_message[i].prop->setFloatValue(val);
|
||||||
p1 += sizeof(int32_t);
|
p1 += sizeof(int32_t);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FG_DOUBLE:
|
case FG_DOUBLE:
|
||||||
|
u64 tmpun64;
|
||||||
if (binary_byte_order == BYTE_ORDER_NEEDS_CONVERSION) {
|
if (binary_byte_order == BYTE_ORDER_NEEDS_CONVERSION) {
|
||||||
tmp64 = sg_bswap_64(*(int64_t *)p1);
|
tmpun64.longVal = sg_bswap_64(*(uint64_t *)p1);
|
||||||
} else {
|
} else {
|
||||||
tmp64 = *(int64_t *)p1;
|
tmpun64.doubleVal = *(double *)p1;
|
||||||
}
|
}
|
||||||
|
|
||||||
val = _in_message[i].offset +
|
val = _in_message[i].offset +
|
||||||
*(double *)&tmp64 * _in_message[i].factor;
|
tmpun64.doubleVal * _in_message[i].factor;
|
||||||
|
|
||||||
_in_message[i].prop->setDoubleValue(val);
|
_in_message[i].prop->setDoubleValue(val);
|
||||||
p1 += sizeof(int64_t);
|
p1 += sizeof(int64_t);
|
||||||
|
|
Loading…
Add table
Reference in a new issue