From c6ad744ce22fd94cdf83ff876ed31e83af94cc41 Mon Sep 17 00:00:00 2001 From: curt Date: Thu, 5 Apr 2001 21:51:32 +0000 Subject: [PATCH] Added support for byte swapping based on endianess. Note the assumption is that files are stored in little endian order so if reads or writes are done from a big endian machine, the contents must be byte swapped. --- simgear/io/lowlevel.cxx | 371 +++++++++++++++++++++++++++++++--------- simgear/io/lowlevel.hxx | 5 + simgear/io/socktest.cxx | 17 ++ 3 files changed, 308 insertions(+), 85 deletions(-) diff --git a/simgear/io/lowlevel.cxx b/simgear/io/lowlevel.cxx index 87478e14..638b0666 100644 --- a/simgear/io/lowlevel.cxx +++ b/simgear/io/lowlevel.cxx @@ -33,193 +33,346 @@ void sgClearWriteError() { write_error = false; } int sgReadError() { return read_error ; } int sgWriteError() { return write_error ; } - +static const int sgEndianTest = 1; +#define sgIsLittleEndian (*((char *) &sgEndianTest ) != 0) +#define sgIsBigEndian (*((char *) &sgEndianTest ) == 0) + +static inline void sgEndianSwap(unsigned short *x) { + *x = + (( *x >> 8 ) & 0x00FF ) | + (( *x << 8 ) & 0xFF00 ) ; +} + +static inline void sgEndianSwap(unsigned int *x) { + *x = + (( *x >> 24 ) & 0x000000FF ) | + (( *x >> 8 ) & 0x0000FF00 ) | + (( *x << 8 ) & 0x00FF0000 ) | + (( *x << 24 ) & 0xFF000000 ) ; +} + +static inline void sgEndianSwap(unsigned long long *x) { + *x = + (( *x >> 56 ) & 0x00000000000000FFULL ) | + (( *x >> 40 ) & 0x000000000000FF00ULL ) | + (( *x >> 24 ) & 0x0000000000FF0000ULL ) | + (( *x >> 8 ) & 0x00000000FF000000ULL ) | + (( *x << 8 ) & 0x000000FF00000000ULL ) | + (( *x << 24 ) & 0x0000FF0000000000ULL ) | + (( *x << 40 ) & 0x00FF000000000000ULL ) | + (( *x << 56 ) & 0xFF00000000000000ULL ) ; +} + void sgReadChar ( gzFile fd, char *var ) { - if ( gzread ( fd, var, sizeof(char) ) == sizeof(char) ) return ; - read_error = true ; + if ( gzread ( fd, var, sizeof(char) ) != sizeof(char) ) { + read_error = true ; + } } void sgWriteChar ( gzFile fd, const char var ) { - if ( gzwrite ( fd, (void *)(&var), sizeof(char) ) == sizeof(char) ) return ; - write_error = true ; + if ( gzwrite ( fd, (void *)(&var), sizeof(char) ) != sizeof(char) ) { + write_error = true ; + } } void sgReadFloat ( gzFile fd, float *var ) { - if ( gzread ( fd, var, sizeof(float) ) == sizeof(float) ) return ; - read_error = true ; + if ( gzread ( fd, var, sizeof(float) ) != sizeof(float) ) { + read_error = true ; + } + if ( sgIsBigEndian ) { + sgEndianSwap( (unsigned int*)var); + } } void sgWriteFloat ( gzFile fd, const float var ) { - if ( gzwrite ( fd, (void *)(&var), sizeof(float) ) == sizeof(float) ) - return ; - write_error = true ; + if ( sgIsBigEndian ) { + sgEndianSwap( (unsigned int*)&var); + } + if ( gzwrite ( fd, (void *)(&var), sizeof(float) ) != sizeof(float) ) { + write_error = true ; + } } void sgReadDouble ( gzFile fd, double *var ) { - if ( gzread ( fd, var, sizeof(double) ) == sizeof(double) ) return ; - read_error = true ; + if ( gzread ( fd, var, sizeof(double) ) != sizeof(double) ) { + read_error = true ; + } + if ( sgIsBigEndian ) { + sgEndianSwap( (unsigned long long*)var); + } } void sgWriteDouble ( gzFile fd, const double var ) { - if ( gzwrite ( fd, (void *)(&var), sizeof(double) ) == sizeof(double) ) - return ; - write_error = true ; + if ( sgIsBigEndian ) { + sgEndianSwap( (unsigned long long*)&var); + } + if ( gzwrite ( fd, (void *)(&var), sizeof(double) ) != sizeof(double) ) { + write_error = true ; + } } void sgReadUInt ( gzFile fd, unsigned int *var ) { - if ( gzread ( fd, var, sizeof(unsigned int) ) == sizeof(unsigned int) ) - return ; - read_error = true ; + if ( gzread ( fd, var, sizeof(unsigned int) ) != sizeof(unsigned int) ) { + read_error = true ; + } + if ( sgIsBigEndian ) { + sgEndianSwap( (unsigned int*)var); + } } void sgWriteUInt ( gzFile fd, const unsigned int var ) { + if ( sgIsBigEndian ) { + sgEndianSwap( (unsigned int*)&var); + } if ( gzwrite ( fd, (void *)(&var), sizeof(unsigned int) ) - == sizeof(unsigned int) ) - return ; - write_error = true ; + != sizeof(unsigned int) ) + { + write_error = true ; + } } void sgReadInt ( gzFile fd, int *var ) { - if ( gzread ( fd, var, sizeof(int) ) == sizeof(int) ) return ; - read_error = true ; + if ( gzread ( fd, var, sizeof(int) ) != sizeof(int) ) { + read_error = true ; + } + if ( sgIsBigEndian ) { + sgEndianSwap( (unsigned int*)var); + } } void sgWriteInt ( gzFile fd, const int var ) { - if ( gzwrite ( fd, (void *)(&var), sizeof(int) ) == sizeof(int) ) return ; - write_error = true ; + if ( sgIsBigEndian ) { + sgEndianSwap( (unsigned int*)&var); + } + if ( gzwrite ( fd, (void *)(&var), sizeof(int) ) != sizeof(int) ) { + write_error = true ; + } } void sgReadLong ( gzFile fd, long int *var ) { - if ( gzread ( fd, var, sizeof(long int) ) == sizeof(long int) ) return ; - read_error = true ; + if ( gzread ( fd, var, sizeof(long int) ) != sizeof(long int) ) { + read_error = true ; + } + if ( sgIsBigEndian ) { + sgEndianSwap( (unsigned int*)var); + } } void sgWriteLong ( gzFile fd, const long int var ) { - if ( gzwrite ( fd, (void *)(&var), sizeof(long int) ) == sizeof(long int) ) - return ; - write_error = true ; + if ( sgIsBigEndian ) { + sgEndianSwap( (unsigned int*)&var); + } + if ( gzwrite ( fd, (void *)(&var), sizeof(long int) ) + != sizeof(long int) ) + { + write_error = true ; + } +} + + +void sgReadLongLong ( gzFile fd, long long int *var ) +{ + if ( gzread ( fd, var, sizeof(long long int) ) != sizeof(long long int) ) { + read_error = true ; + } + if ( sgIsBigEndian ) { + sgEndianSwap( (unsigned long long int*)var); + } +} + + +void sgWriteLongLong ( gzFile fd, const long long int var ) +{ + if ( sgIsBigEndian ) { + sgEndianSwap( (unsigned long long*)&var); + } + if ( gzwrite ( fd, (void *)(&var), sizeof(long long int) ) + != sizeof(long long int) ) + { + write_error = true ; + } } void sgReadUShort ( gzFile fd, unsigned short *var ) { - if ( gzread ( fd, var, sizeof(unsigned short) ) == sizeof(unsigned short) ) - return ; - read_error = true ; + if ( gzread ( fd, var, sizeof(unsigned short) ) != sizeof(unsigned short) ){ + read_error = true ; + } + if ( sgIsBigEndian ) { + sgEndianSwap( (unsigned short int*)var); + } } void sgWriteUShort ( gzFile fd, const unsigned short var ) { + if ( sgIsBigEndian ) { + sgEndianSwap( (unsigned short*)&var); + } if ( gzwrite ( fd, (void *)(&var), sizeof(unsigned short) ) - == sizeof(unsigned short) ) - return ; - write_error = true ; + != sizeof(unsigned short) ) + { + write_error = true ; + } } void sgReadShort ( gzFile fd, short *var ) { - if ( gzread ( fd, var, sizeof(short) ) == sizeof(short) ) return ; - read_error = true ; + if ( gzread ( fd, var, sizeof(short) ) != sizeof(short) ) { + read_error = true ; + } + if ( sgIsBigEndian ) { + sgEndianSwap( (unsigned short int*)var); + } } void sgWriteShort ( gzFile fd, const short var ) { - if ( gzwrite ( fd, (void *)(&var), sizeof(short) ) == sizeof(short) ) return ; - write_error = true ; + if ( sgIsBigEndian ) { + sgEndianSwap( (unsigned short*)&var); + } + if ( gzwrite ( fd, (void *)(&var), sizeof(short) ) != sizeof(short) ) { + write_error = true ; + } } void sgReadFloat ( gzFile fd, const unsigned int n, float *var ) { - if ( gzread ( fd, var, sizeof(float) * n ) == (int)(sizeof(float) * n) ) - return ; - read_error = true ; + if ( gzread ( fd, var, sizeof(float) * n ) != (int)(sizeof(float) * n) ) { + read_error = true ; + } + if ( sgIsBigEndian ) { + for ( unsigned int i = 0; i < n; ++i ) { + sgEndianSwap( (unsigned int*)var++); + } + } } void sgWriteFloat ( gzFile fd, const unsigned int n, const float *var ) { + if ( sgIsBigEndian ) { + float *swab = new float[n]; + float *ptr = swab; + memcpy( swab, var, sizeof(float) * n ); + for ( unsigned int i = 0; i < n; ++i ) { + sgEndianSwap( (unsigned int*)ptr++); + } + var = swab; + } if ( gzwrite ( fd, (void *)var, sizeof(float) * n ) - == (int)(sizeof(float) * n) ) - return ; - write_error = true ; + != (int)(sizeof(float) * n) ) + { + write_error = true ; + } } void sgReadDouble ( gzFile fd, const unsigned int n, double *var ) { - if ( gzread ( fd, var, sizeof(double) * n ) == (int)(sizeof(double) * n) ) - return ; - read_error = true ; + if ( gzread ( fd, var, sizeof(double) * n ) != (int)(sizeof(double) * n) ) { + read_error = true ; + } + if ( sgIsBigEndian ) { + for ( unsigned int i = 0; i < n; ++i ) { + sgEndianSwap( (unsigned long long*)var++); + } + } } void sgWriteDouble ( gzFile fd, const unsigned int n, const double *var ) { + if ( sgIsBigEndian ) { + double *swab = new double[n]; + double *ptr = swab; + memcpy( swab, var, sizeof(double) * n ); + for ( unsigned int i = 0; i < n; ++i ) { + sgEndianSwap( (unsigned long long*)ptr++); + } + var = swab; + } if ( gzwrite ( fd, (void *)var, sizeof(double) * n ) - == (int)(sizeof(double) * n) ) return ; - write_error = true ; + != (int)(sizeof(double) * n) ) + { + write_error = true ; + } } void sgReadBytes ( gzFile fd, const unsigned int n, void *var ) { - if ( n == 0) - return; - if ( gzread ( fd, var, n ) == (int)n ) - return ; - read_error = true ; + if ( n == 0) return; + if ( gzread ( fd, var, n ) != (int)n ) { + read_error = true ; + } } void sgWriteBytes ( gzFile fd, const unsigned int n, const void *var ) { - if ( n == 0) - return; - if ( gzwrite ( fd, (void *)var, n ) == (int)n ) - return ; - write_error = true ; + if ( n == 0) return; + if ( gzwrite ( fd, (void *)var, n ) != (int)n ) { + write_error = true ; + } } void sgReadUShort ( gzFile fd, const unsigned int n, unsigned short *var ) { if ( gzread ( fd, var, sizeof(unsigned short) * n ) - == (int)(sizeof(unsigned short) * n) ) - return ; - read_error = true ; + != (int)(sizeof(unsigned short) * n) ) + { + read_error = true ; + } + if ( sgIsBigEndian ) { + for ( unsigned int i = 0; i < n; ++i ) { + sgEndianSwap( (unsigned short int*)var++); + } + } } void sgWriteUShort ( gzFile fd, const unsigned int n, const unsigned short *var ) { + if ( sgIsBigEndian ) { + unsigned short *swab = new unsigned short[n]; + unsigned short *ptr = swab; + memcpy( swab, var, sizeof(unsigned short) * n ); + for ( unsigned int i = 0; i < n; ++i ) { + sgEndianSwap( (unsigned short*)ptr++); + } + var = swab; + } if ( gzwrite ( fd, (void *)var, sizeof(unsigned short) * n ) - == (int)(sizeof(unsigned short) * n) ) - return ; - write_error = true ; + != (int)(sizeof(unsigned short) * n) ) + { + write_error = true ; + } } @@ -227,36 +380,68 @@ void sgWriteUShort ( gzFile fd, const unsigned int n, const unsigned short *var void sgReadShort ( gzFile fd, const unsigned int n, short *var ) { if ( gzread ( fd, var, sizeof(short) * n ) - == (int)(sizeof(short) * n) ) - return ; - read_error = true ; + != (int)(sizeof(short) * n) ) + { + read_error = true ; + } + if ( sgIsBigEndian ) { + for ( unsigned int i = 0; i < n; ++i ) { + sgEndianSwap( (unsigned short int*)var++); + } + } } void sgWriteShort ( gzFile fd, const unsigned int n, const short *var ) { + if ( sgIsBigEndian ) { + short *swab = new short[n]; + short *ptr = swab; + memcpy( swab, var, sizeof(short) * n ); + for ( unsigned int i = 0; i < n; ++i ) { + sgEndianSwap( (unsigned short*)ptr++); + } + var = swab; + } if ( gzwrite ( fd, (void *)var, sizeof(short) * n ) - == (int)(sizeof(short) * n) ) - return ; - write_error = true ; + != (int)(sizeof(short) * n) ) + { + write_error = true ; + } } void sgReadUInt ( gzFile fd, const unsigned int n, unsigned int *var ) { if ( gzread ( fd, var, sizeof(unsigned int) * n ) - == (int)(sizeof(unsigned int) * n) ) - return ; - read_error = true ; + != (int)(sizeof(unsigned int) * n) ) + { + read_error = true ; + } + if ( sgIsBigEndian ) { + for ( unsigned int i = 0; i < n; ++i ) { + sgEndianSwap( (unsigned int*)var++); + } + } } void sgWriteUInt ( gzFile fd, const unsigned int n, const unsigned int *var ) { + if ( sgIsBigEndian ) { + unsigned int *swab = new unsigned int[n]; + unsigned int *ptr = swab; + memcpy( swab, var, sizeof(unsigned int) * n ); + for ( unsigned int i = 0; i < n; ++i ) { + sgEndianSwap( (unsigned int*)ptr++); + } + var = swab; + } if ( gzwrite ( fd, (void *)var, sizeof(unsigned int) * n ) - == (int)(sizeof(unsigned int) * n) ) - return ; - write_error = true ; + != (int)(sizeof(unsigned int) * n) ) + { + write_error = true ; + } } @@ -264,18 +449,34 @@ void sgWriteUInt ( gzFile fd, const unsigned int n, const unsigned int *var ) void sgReadInt ( gzFile fd, const unsigned int n, int *var ) { if ( gzread ( fd, var, sizeof(int) * n ) - == (int)(sizeof(int) * n) ) - return ; - read_error = true ; + != (int)(sizeof(int) * n) ) + { + read_error = true ; + } + if ( sgIsBigEndian ) { + for ( unsigned int i = 0; i < n; ++i ) { + sgEndianSwap( (unsigned int*)var++); + } + } } void sgWriteInt ( gzFile fd, const unsigned int n, const int *var ) { + if ( sgIsBigEndian ) { + int *swab = new int[n]; + int *ptr = swab; + memcpy( swab, var, sizeof(int) * n ); + for ( unsigned int i = 0; i < n; ++i ) { + sgEndianSwap( (unsigned int*)ptr++); + } + var = swab; + } if ( gzwrite ( fd, (void *)var, sizeof(int) * n ) - == (int)(sizeof(int) * n) ) - return ; - write_error = true ; + != (int)(sizeof(int) * n) ) + { + write_error = true ; + } } diff --git a/simgear/io/lowlevel.hxx b/simgear/io/lowlevel.hxx index 0bc84aa9..979f243b 100644 --- a/simgear/io/lowlevel.hxx +++ b/simgear/io/lowlevel.hxx @@ -39,6 +39,9 @@ #include +// Note that output is written in little endian form (and converted as +// necessary) + void sgReadChar ( gzFile fd, char *var ) ; void sgWriteChar ( gzFile fd, const char var ) ; void sgReadFloat ( gzFile fd, float *var ) ; @@ -51,6 +54,8 @@ void sgReadInt ( gzFile fd, int *var ) ; void sgWriteInt ( gzFile fd, const int var ) ; void sgReadLong ( gzFile fd, long int *var ) ; void sgWriteLong ( gzFile fd, const long int var ) ; +void sgReadLongLong ( gzFile fd, long long int *var ) ; +void sgWriteLongLong ( gzFile fd, const long long int var ) ; void sgReadUShort ( gzFile fd, unsigned short *var ) ; void sgWriteUShort ( gzFile fd, const unsigned short var ) ; void sgReadShort ( gzFile fd, short *var ) ; diff --git a/simgear/io/socktest.cxx b/simgear/io/socktest.cxx index 76ce67e5..471f0ad6 100644 --- a/simgear/io/socktest.cxx +++ b/simgear/io/socktest.cxx @@ -1,9 +1,26 @@ #include #include "sg_socket.hxx" +#include "lowlevel.hxx" + +static const int sgEndianTest = 1; +#define sgIsLittleEndian (*((char *) &sgEndianTest ) != 0) +#define sgIsBigEndian (*((char *) &sgEndianTest ) == 0) int main() { + if ( sgIsLittleEndian ) { + cout << "this machine is little endian\n"; + } + + if ( sgIsBigEndian ) { + cout << "this machine is big endian\n"; + } + + cout << "short = " << sizeof(unsigned short) << endl; + cout << "int = " << sizeof(unsigned int) << endl; + cout << "long long = " << sizeof(long long) << endl; + SGSocket s( "", "5500", "tcp" ); if ( !s.open( SG_IO_BI ) ) { -- 2.39.5