Byte order conversion is done using the four functions (macros really) called htons, ntohs, htonl, and ntohl that may be found in inet/arpa.h on any Unix system. So of course I included that file and went happily on with my coding. But... when I tried to compile my new version of Presence under Windows I realized that inet/arpa.h does not exist on Windows. It probably resides in winsock.h I guess, but I _really_ do not want to have platform specific code in my project, so I decided to implement them myself instead :-)
Using Qt you can ask for your systems endianness by using the QSysInfo class, so a portable implementation of the needed functions is easy to do:
#define BYTE_SWAP4(x) \
(((x & 0xFF000000) >> 24) | \
((x & 0x00FF0000) >> 8) | \
((x & 0x0000FF00) << 8) | \
((x & 0x000000FF) << 24))
#define BYTE_SWAP2(x) \
(((x & 0xFF00) >> 8) | \
((x & 0x00FF) << 8))
quint16 _htons(quint16 x) {
if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
return x;
}
else {
return BYTE_SWAP2(x);
}
}
quint16 _ntohs(quint16 x) {
if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
return x;
}
else {
return BYTE_SWAP2(x);
}
}
quint32 _htonl(quint32 x) {
if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
return x;
}
else {
return BYTE_SWAP4(x);
}
}
quint32 _ntohl(quint32 x) {
if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
return x;
}
else {
return BYTE_SWAP4(x);
}
}
Note that the functions have a '_' prepended - otherwise some compilers may get confused.
Using these functions I do not need to have any platform specific code in my project. This comes at the cost of actually doing a function call when byte order conversion is needed, as opposed to simply using a macro. So if your code is very performance critical you should not use this code - but then again, if your code is that performance critical you should probably not be using C++ ;-)
I know this is old af but you literally saved me hours of shit with qt networking. Thanks!
ReplyDelete