1 /*
2 * Copyright 2004 The WebRTC Project Authors. All rights reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 #ifndef RTC_BASE_BYTE_ORDER_H_
12 #define RTC_BASE_BYTE_ORDER_H_
13
14 #include <stdint.h>
15
16 #include <cstring>
17
18 #if defined(WEBRTC_POSIX) && !defined(__native_client__)
19 #include <arpa/inet.h>
20 #endif
21
22 #include "rtc_base/system/arch.h"
23
24 #if defined(WEBRTC_MAC)
25 #include <libkern/OSByteOrder.h>
26
27 #define htobe16(v) OSSwapHostToBigInt16(v)
28 #define htobe32(v) OSSwapHostToBigInt32(v)
29 #define htobe64(v) OSSwapHostToBigInt64(v)
30 #define be16toh(v) OSSwapBigToHostInt16(v)
31 #define be32toh(v) OSSwapBigToHostInt32(v)
32 #define be64toh(v) OSSwapBigToHostInt64(v)
33
34 #define htole16(v) OSSwapHostToLittleInt16(v)
35 #define htole32(v) OSSwapHostToLittleInt32(v)
36 #define htole64(v) OSSwapHostToLittleInt64(v)
37 #define le16toh(v) OSSwapLittleToHostInt16(v)
38 #define le32toh(v) OSSwapLittleToHostInt32(v)
39 #define le64toh(v) OSSwapLittleToHostInt64(v)
40
41 #elif defined(WEBRTC_WIN) || defined(__native_client__)
42
43 #if defined(WEBRTC_WIN)
44 #include <stdlib.h>
45 #include <winsock2.h>
46 #else
47 #include <netinet/in.h>
48 #endif // defined(WEBRTC_WIN)
49
50 #if defined(WEBRTC_ARCH_LITTLE_ENDIAN)
51 #define htobe16(v) htons(v)
52 #define htobe32(v) htonl(v)
53 #define be16toh(v) ntohs(v)
54 #define be32toh(v) ntohl(v)
55 #define htole16(v) (v)
56 #define htole32(v) (v)
57 #define htole64(v) (v)
58 #define le16toh(v) (v)
59 #define le32toh(v) (v)
60 #define le64toh(v) (v)
61 #if defined(WEBRTC_WIN)
62 #define htobe64(v) _byteswap_uint64(v)
63 #define be64toh(v) _byteswap_uint64(v)
64 #endif // defined(WEBRTC_WIN)
65 #if defined(__native_client__)
66 #define htobe64(v) __builtin_bswap64(v)
67 #define be64toh(v) __builtin_bswap64(v)
68 #endif // defined(__native_client__)
69
70 #elif defined(WEBRTC_ARCH_BIG_ENDIAN)
71 #define htobe16(v) (v)
72 #define htobe32(v) (v)
73 #define be16toh(v) (v)
74 #define be32toh(v) (v)
75 #define htole16(v) __builtin_bswap16(v)
76 #define htole32(v) __builtin_bswap32(v)
77 #define htole64(v) __builtin_bswap64(v)
78 #define le16toh(v) __builtin_bswap16(v)
79 #define le32toh(v) __builtin_bswap32(v)
80 #define le64toh(v) __builtin_bswap64(v)
81 #if defined(WEBRTC_WIN)
82 #define htobe64(v) (v)
83 #define be64toh(v) (v)
84 #endif // defined(WEBRTC_WIN)
85 #if defined(__native_client__)
86 #define htobe64(v) (v)
87 #define be64toh(v) (v)
88 #endif // defined(__native_client__)
89 #else
90 #error WEBRTC_ARCH_BIG_ENDIAN or WEBRTC_ARCH_LITTLE_ENDIAN must be defined.
91 #endif // defined(WEBRTC_ARCH_LITTLE_ENDIAN)
92
93 #elif defined(WEBRTC_POSIX)
94 #include <endian.h>
95 #else
96 #error "Missing byte order functions for this arch."
97 #endif // defined(WEBRTC_MAC)
98
99 namespace rtc {
100
101 // Reading and writing of little and big-endian numbers from memory
102
Set8(void * memory,size_t offset,uint8_t v)103 inline void Set8(void* memory, size_t offset, uint8_t v) {
104 static_cast<uint8_t*>(memory)[offset] = v;
105 }
106
Get8(const void * memory,size_t offset)107 inline uint8_t Get8(const void* memory, size_t offset) {
108 return static_cast<const uint8_t*>(memory)[offset];
109 }
110
SetBE16(void * memory,uint16_t v)111 inline void SetBE16(void* memory, uint16_t v) {
112 uint16_t val = htobe16(v);
113 memcpy(memory, &val, sizeof(val));
114 }
115
SetBE32(void * memory,uint32_t v)116 inline void SetBE32(void* memory, uint32_t v) {
117 uint32_t val = htobe32(v);
118 memcpy(memory, &val, sizeof(val));
119 }
120
SetBE64(void * memory,uint64_t v)121 inline void SetBE64(void* memory, uint64_t v) {
122 uint64_t val = htobe64(v);
123 memcpy(memory, &val, sizeof(val));
124 }
125
GetBE16(const void * memory)126 inline uint16_t GetBE16(const void* memory) {
127 uint16_t val;
128 memcpy(&val, memory, sizeof(val));
129 return be16toh(val);
130 }
131
GetBE32(const void * memory)132 inline uint32_t GetBE32(const void* memory) {
133 uint32_t val;
134 memcpy(&val, memory, sizeof(val));
135 return be32toh(val);
136 }
137
GetBE64(const void * memory)138 inline uint64_t GetBE64(const void* memory) {
139 uint64_t val;
140 memcpy(&val, memory, sizeof(val));
141 return be64toh(val);
142 }
143
SetLE16(void * memory,uint16_t v)144 inline void SetLE16(void* memory, uint16_t v) {
145 uint16_t val = htole16(v);
146 memcpy(memory, &val, sizeof(val));
147 }
148
SetLE32(void * memory,uint32_t v)149 inline void SetLE32(void* memory, uint32_t v) {
150 uint32_t val = htole32(v);
151 memcpy(memory, &val, sizeof(val));
152 }
153
SetLE64(void * memory,uint64_t v)154 inline void SetLE64(void* memory, uint64_t v) {
155 uint64_t val = htole64(v);
156 memcpy(memory, &val, sizeof(val));
157 }
158
GetLE16(const void * memory)159 inline uint16_t GetLE16(const void* memory) {
160 uint16_t val;
161 memcpy(&val, memory, sizeof(val));
162 return le16toh(val);
163 }
164
GetLE32(const void * memory)165 inline uint32_t GetLE32(const void* memory) {
166 uint32_t val;
167 memcpy(&val, memory, sizeof(val));
168 return le32toh(val);
169 }
170
GetLE64(const void * memory)171 inline uint64_t GetLE64(const void* memory) {
172 uint64_t val;
173 memcpy(&val, memory, sizeof(val));
174 return le64toh(val);
175 }
176
177 // Check if the current host is big endian.
IsHostBigEndian()178 inline bool IsHostBigEndian() {
179 #if defined(WEBRTC_ARCH_BIG_ENDIAN)
180 return true;
181 #else
182 return false;
183 #endif
184 }
185
HostToNetwork16(uint16_t n)186 inline uint16_t HostToNetwork16(uint16_t n) {
187 return htobe16(n);
188 }
189
HostToNetwork32(uint32_t n)190 inline uint32_t HostToNetwork32(uint32_t n) {
191 return htobe32(n);
192 }
193
HostToNetwork64(uint64_t n)194 inline uint64_t HostToNetwork64(uint64_t n) {
195 return htobe64(n);
196 }
197
NetworkToHost16(uint16_t n)198 inline uint16_t NetworkToHost16(uint16_t n) {
199 return be16toh(n);
200 }
201
NetworkToHost32(uint32_t n)202 inline uint32_t NetworkToHost32(uint32_t n) {
203 return be32toh(n);
204 }
205
NetworkToHost64(uint64_t n)206 inline uint64_t NetworkToHost64(uint64_t n) {
207 return be64toh(n);
208 }
209
210 } // namespace rtc
211
212 #endif // RTC_BASE_BYTE_ORDER_H_
213