If you were to use operating system's header, you have the ntohs
and htons
function that can swap the bytes.
Else, it's trivial to add:
template <T> T swap_endianness(T in) {
unsigned char array[sizeof(in)] = {};
std::memcpy(array, &in, sizeof(in));
// Byte swap now
for (size_t i = 0; i < sizeof(in)/2; i++)
std::swap(array[i], array[sizeof(in) - i - 1]);
std::memcpy(&in, array, sizeof(in));
return in;
}
Usage is:
uint16_t *res= (uint16_t*)(data); // This is undefined behavior. Use memcpy instead.
res[0] = swap_endianness(res[0]); // and so on
This only works for Plain Old Data type, such as uint64
, uint32
, uint16
, int64
, int32
, int16
, float
, double
.
As @KamilCuk pointed out, the like (uint16_t *)(data)
might lead to issues if data
happens not to be aligned at 16-bit boundary and will likely cause a memory access error when you'll dereference it on platfrom like ARM. The correct solution is to use memcpy
like this:
uint16_t res[2];
std::memcpy(res, data, sizeof(res));
res[0] = swap_endianness(res[0]);
res[1] = swap_endianness(res[1]);