]> git.mxchange.org Git - flightgear.git/blob - src/MultiPlayer/tiny_xdr.hpp
Better cross platform compatibility.
[flightgear.git] / src / MultiPlayer / tiny_xdr.hpp
1 //////////////////////////////////////////////////////////////////////
2 //
3 //      Tiny XDR implementation for flightgear
4 //      written by Oliver Schroeder
5 //      released to the puiblic domain
6 //
7 //      This implementation is not complete, but implements
8 //      everything we need.
9 //
10 //      For further reading on XDR read RFC 1832.
11 //
12 //  NEW
13 //
14 //////////////////////////////////////////////////////////////////////
15
16 #ifndef TINY_XDR_HEADER
17 #define TINY_XDR_HEADER
18
19 #if defined HAVE_CONFIG_H
20 #   include <config.h>
21 #endif
22
23 #include <simgear/compiler.h>
24 #if defined HAVE_STDINT_H
25 #   include <stdint.h>
26 #endif
27
28 #include <plib/ul.h>
29
30 //////////////////////////////////////////////////////////////////////
31 //
32 //  There are many sick systems out there:
33 //
34 //  check for sizeof(float) and sizeof(double)
35 //  if sizeof(float) != 4 this code must be patched
36 //  if sizeof(double) != 8 this code must be patched
37 //
38 //  Those are comments I fetched out of glibc source:
39 //  - s390 is big-endian
40 //  - Sparc is big-endian, but v9 supports endian conversion
41 //    on loads/stores and GCC supports such a mode.  Be prepared.  
42 //  - The MIPS architecture has selectable endianness.
43 //  - x86_64 is little-endian.
44 //  - CRIS is little-endian.
45 //  - m68k is big-endian.
46 //  - Alpha is little-endian.
47 //  - PowerPC can be little or big endian.
48 //  - SH is bi-endian but with a big-endian FPU.
49 //  - hppa1.1 big-endian. 
50 //  - ARM is (usually) little-endian but with a big-endian FPU. 
51 //
52 //////////////////////////////////////////////////////////////////////
53 inline uint32_t bswap_32(unsigned int b) {
54     unsigned x = b;
55     ulEndianSwap(&x);
56     return x;
57 }
58
59 #if (SIZEOF_LONG_INT == 8)
60 inline uint64_t bswap_64(unsigned long int b) {
61     uint64_t x = b;
62     x = ((x >>  8) & 0x00FF00FF00FF00FFLL) | ((x <<  8) & 0xFF00FF00FF00FF00LL);
63     x = ((x >> 16) & 0x0000FFFF0000FFFFLL) | ((x << 16) & 0xFFFF0000FFFF0000LL);
64     x = (x >> 32) | (x << 32);
65     return x;
66 }
67 #else
68 inline uint64_t bswap_64(unsigned long long int b) {
69     union { 
70          uint64_t ll;
71          uint32_t l[2]; 
72      } w, r;
73      w.ll = b;
74      r.l[0] = bswap_32 (w.l[1]);
75      r.l[1] = bswap_32 (w.l[0]);
76      return r.ll;
77 }
78 #endif
79
80 #if BYTE_ORDER == BIG_ENDIAN
81 #   define SWAP32(arg) arg
82 #   define SWAP64(arg) arg
83 #   define LOW  0
84 #   define HIGH 1
85 #else
86 #   define SWAP32(arg) bswap_32(arg)
87 #   define SWAP64(arg) bswap_64(arg)
88 #   define LOW  1
89 #   define HIGH 0
90 #endif
91
92 #define XDR_BYTES_PER_UNIT  4
93
94 typedef uint32_t    xdr_data_t;      /* 4 Bytes */
95 typedef uint64_t    xdr_data2_t;     /* 8 Bytes */
96
97 /* XDR 8bit integers */
98 xdr_data_t      XDR_encode_int8     ( int8_t  n_Val );
99 xdr_data_t      XDR_encode_uint8    ( uint8_t n_Val );
100 int8_t          XDR_decode_int8     ( xdr_data_t n_Val );
101 uint8_t         XDR_decode_uint8    ( xdr_data_t n_Val );
102
103 /* XDR 16bit integers */
104 xdr_data_t      XDR_encode_int16    ( int16_t  n_Val );
105 xdr_data_t      XDR_encode_uint16   ( uint16_t n_Val );
106 int16_t         XDR_decode_int16    ( xdr_data_t n_Val );
107 uint16_t        XDR_decode_uint16   ( xdr_data_t n_Val );
108
109 /* XDR 32bit integers */
110 xdr_data_t      XDR_encode_int32    ( int32_t  n_Val );
111 xdr_data_t      XDR_encode_uint32   ( const uint32_t n_Val );
112 int32_t         XDR_decode_int32    ( xdr_data_t n_Val );
113 uint32_t        XDR_decode_uint32   ( const xdr_data_t n_Val );
114
115 /* XDR 64bit integers */
116 xdr_data2_t     XDR_encode_int64    ( int64_t n_Val );
117 xdr_data2_t     XDR_encode_uint64   ( uint64_t n_Val );
118 int64_t         XDR_decode_int64    ( xdr_data2_t n_Val );
119 uint64_t        XDR_decode_uint64   ( xdr_data2_t n_Val );
120
121 //////////////////////////////////////////////////
122 //
123 //  FIXME: #1 these funtions must be fixed for
124 //         none IEEE-encoding architecturs
125 //         (eg. vax, big suns etc)
126 //  FIXME: #2 some compilers return 'double'
127 //         regardless of return-type 'float'
128 //         this must be fixed, too
129 //  FIXME: #3 some machines may need to use a
130 //         different endianess for floats!
131 //
132 //////////////////////////////////////////////////
133 /* float */
134 xdr_data_t      XDR_encode_float    ( float f_Val );
135 float           XDR_decode_float    ( xdr_data_t f_Val );
136
137 /* double */
138 xdr_data2_t     XDR_encode_double   ( double d_Val );
139 double          XDR_decode_double   ( xdr_data2_t d_Val );
140
141 #endif