modules/ims_qos: added patch for flow-description bug when request originates from...
[sip-router] / src / core / endianness.h
1 /* 
2  * Copyright (C) 2008 iptelorg GmbH
3  *
4  * Permission to use, copy, modify, and distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15  */
16
17 /** @file
18  *  Kamailio core :: endianness compile and runtime  tests
19  *  @author andrei
20  *  @ingroup core
21  * 
22  *
23  * Defines:
24  *  -  __IS_LITTLE_ENDIAN if the system is little endian and
25  *  -  __IS_BIG_ENDIAN    if it's big endian
26  * Function/macros:
27  *  -   is_big_endian()  - runtime test for big endian
28  *  -   is_little_endian() - runtime test for little endian
29  *  -   endianness_sanity_check() - returns 0 if the compile time
30  *                                  detected endianness corresponds to
31  *                                  the runtime detected one and -1 on 
32  *                                  error (recommended action: bail out)
33  *  -   bswap16() - 16 bit byte swap
34  *  -   bswap32() - 32 bit byte swap
35  *
36  * Implementation notes:
37  * Endian macro names/tests for different OSes:
38  * linux:  __BYTE_ORDER == __LITTLE_ENDIAN | __BIG_ENDIAN
39  *           BYTE_ORDER == LITTLE_ENDIAN | BIG_ENDIAN
40  * bsd:     _BYTE_ORDER == _LITTLE_ENDIAN | _BIG_ENDIAN
41  *           BYTE_ORDER == LITTLE_ENDIAN | BIG_ENDIAN
42  * solaris: _LITTLE_ENDIAN | _BIG_ENDIAN
43  *
44  * Include file for the endian macros:
45  * linux: <endian.h> (glibc), <sys/param.h>
46  * bsd:   <sys/param.h>, <sys/endian.h>
47  * solaris: <sys/param.h>
48  *
49  * Note: BIG_ENDIAN, LITTLE_ENDIAN, _BIG_ENDIAN, _LITTLE_ENDIAN cannot be 
50  *       used always,  some OSes define both of them for BYTE_ORDER use
51  *       (e.g. linux defines both BIG_ENDIAN & LITTLE_ENDIAN, bsds define
52  *          _BIG_ENDIAN, _LITTLE_ENDIAN, BIG_ENDIAN, LITTLE_ENDIAN)
53  *
54  */
55
56
57 #ifndef _endianness_h
58 #define _endianness_h
59
60 /* use bsd includes: they work everywhere */
61 #include <sys/types.h>
62 #include <sys/param.h>
63
64
65
66 extern int _endian_test_int;
67
68 /* returns 1 for little endian, 0 for big endian */
69 #define endian_test()           (*(char*)&_endian_test_int==1)
70 #define is_big_endian()         (!endian_test())
71 #define is_little_endian()      endian_test()
72
73
74 extern int endianness_sanity_check(void);
75
76 /* detect compile time endianess */
77 #if defined __BYTE_ORDER && defined __LITTLE_ENDIAN && defined __BIG_ENDIAN
78 /* linux */
79 #if __BYTE_ORDER == __LITTLE_ENDIAN && ! defined __IS_LITTLE_ENDIAN
80         #define __IS_LITTLE_ENDIAN 0x01020304
81 #endif
82 #if __BYTE_ORDER == __BIG_ENDIAN && ! defined __IS_BIG_ENDIAN
83         #define __IS_BIG_ENDIAN 0x01020304
84 #endif
85 #elif defined _BYTE_ORDER && defined _LITTLE_ENDIAN && defined _BIG_ENDIAN
86 /* bsd */
87 #if _BYTE_ORDER == _LITTLE_ENDIAN && ! defined __IS_LITTLE_ENDIAN
88         #define __IS_LITTLE_ENDIAN 0x01020304
89 #endif
90 #if _BYTE_ORDER == _BIG_ENDIAN && ! defined __IS_BIG_ENDIAN
91         #define __IS_BIG_ENDIAN 0x01020304
92 #endif
93 #elif defined BYTE_ORDER && defined LITTLE_ENDIAN && defined BIG_ENDIAN
94 /* bsd old/deprecated */
95 #if BYTE_ORDER == LITTLE_ENDIAN && ! defined __IS_LITTLE_ENDIAN
96         #define __IS_LITTLE_ENDIAN 0x01020304
97 #endif
98 #if BYTE_ORDER == BIG_ENDIAN && ! defined __IS_BIG_ENDIAN
99         #define __IS_BIG_ENDIAN 0x01020304
100 #endif
101 #elif !(defined _LITTLE_ENDIAN && defined _BIG_ENDIAN) && \
102                 (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN)
103 /* OSes that don't define BYTE_ORDER (sanity check above makes sure
104  *   little & big endian are not defined in the same time )*/
105 /* solaris */
106 #if defined _LITTLE_ENDIAN && !defined __IS_LITTLE_ENDIAN
107         #define __IS_LITTLE_ENDIAN 0x01020304
108 #endif
109 #if defined _BIG_ENDIAN && !defined __IS_BIG_ENDIAN
110         #define __IS_BIG_ENDIAN 0x04030201
111 #endif
112 #elif !(defined LITTLE_ENDIAN && defined BIG_ENDIAN) && \
113                 (defined LITTLE_ENDIAN || defined BIG_ENDIAN)
114 /* OSes that don't define BYTE_ORDER (sanity check above makes sure
115  *   little & big endian are not defined in the same time )*/
116 #if defined LITTLE_ENDIAN && !defined __IS_LITTLE_ENDIAN
117         #define __IS_LITTLE_ENDIAN 0x01020304
118 #endif
119 #if defined BIG_ENDIAN && !defined __IS_BIG_ENDIAN
120         #define __IS_BIG_ENDIAN 0x04030201
121 #endif
122
123 #else
124 #error could not detect endianess
125 #endif
126
127 #if !defined __IS_LITTLE_ENDIAN && !defined __IS_BIG_ENDIAN
128 #error BUG: could not detect endianess
129 #endif
130
131 #if defined __IS_LITTLE_ENDIAN && defined __IS_BIG_ENDIAN
132 #error BUG: both little & big endian detected in the same time
133 #endif
134
135 #if defined __IS_LITTLE_ENDIAN
136 #include <arpa/inet.h>
137 #define bswap16(x) ntohs(x)
138 #define bswap32(x) ntohl(x)
139 #else /* !__IS_LITTLE_ENDIAN */
140 #include <stdint.h>
141 #if defined __GNUC__ && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8))
142 /* need at least GCC 4.8 for __builtin_bswap16 on all archs */
143 #define bswap16(x)      ((uint16_t)__builtin_bswap16(x))
144 #else
145 #define bswap16(x)      (((uint16_t)(x) >> 8) | \
146                         ((uint16_t)(x) << 8))
147 #endif
148 #if defined __GNUC__ && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))
149 /* GCC >= 4.3 provides __builtin_bswap32 */
150 #define bswap32(x)      ((uint32_t)__builtin_bswap32(x))
151 #else
152 #define bswap32(x)      (((uint32_t)(x) << 24) | \
153                         (((uint32_t)(x) << 8) & 0xff0000) | \
154                         (((uint32_t)(x) >> 8) & 0xff00) | \
155                         ((uint32_t)(x)  >> 24))
156 #endif
157 #endif /* !__IS_LITTLE_ENDIAN */
158
159 #endif /* _endianness_h */
160