OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2004 The WebRTC Project Authors. All rights reserved. | 2 * Copyright 2004 The WebRTC Project Authors. All rights reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
11 #ifndef WEBRTC_BASE_BYTEORDER_H_ | 11 #ifndef WEBRTC_BASE_BYTEORDER_H_ |
12 #define WEBRTC_BASE_BYTEORDER_H_ | 12 #define WEBRTC_BASE_BYTEORDER_H_ |
13 | 13 |
14 #if defined(WEBRTC_POSIX) && !defined(__native_client__) | 14 #if defined(WEBRTC_POSIX) && !defined(__native_client__) |
15 #include <arpa/inet.h> | 15 #include <arpa/inet.h> |
16 #endif | 16 #endif |
17 | 17 |
| 18 #if defined(WEBRTC_WIN) |
| 19 #include <stdlib.h> |
| 20 #endif |
| 21 |
18 #include "webrtc/base/basictypes.h" | 22 #include "webrtc/base/basictypes.h" |
19 | 23 |
20 #if defined(WEBRTC_MAC) | |
21 #include <libkern/OSByteOrder.h> | |
22 | |
23 #define htobe16(v) OSSwapHostToBigInt16(v) | |
24 #define htobe32(v) OSSwapHostToBigInt32(v) | |
25 #define htobe64(v) OSSwapHostToBigInt64(v) | |
26 #define be16toh(v) OSSwapBigToHostInt16(v) | |
27 #define be32toh(v) OSSwapBigToHostInt32(v) | |
28 #define be64toh(v) OSSwapBigToHostInt64(v) | |
29 | |
30 #define htole16(v) OSSwapHostToLittleInt16(v) | |
31 #define htole32(v) OSSwapHostToLittleInt32(v) | |
32 #define htole64(v) OSSwapHostToLittleInt64(v) | |
33 #define le16toh(v) OSSwapLittleToHostInt16(v) | |
34 #define le32toh(v) OSSwapLittleToHostInt32(v) | |
35 #define le64toh(v) OSSwapLittleToHostInt64(v) | |
36 #elif defined(WEBRTC_WIN) || defined(__native_client__) | |
37 | |
38 #if defined(WEBRTC_WIN) | |
39 #include <stdlib.h> | |
40 #include <winsock2.h> | |
41 #else | |
42 #include <netinet/in.h> | |
43 #endif | |
44 | |
45 #define htobe16(v) htons(v) | |
46 #define htobe32(v) htonl(v) | |
47 #define be16toh(v) ntohs(v) | |
48 #define be32toh(v) ntohl(v) | |
49 #if defined(WEBRTC_WIN) | |
50 #define htobe64(v) htonll(v) | |
51 #define be64toh(v) ntohll(v) | |
52 #endif | |
53 | |
54 #if defined(RTC_ARCH_CPU_LITTLE_ENDIAN) | |
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(__native_client__) | |
62 #define htobe64(v) __builtin_bswap64(v) | |
63 #define be64toh(v) __builtin_bswap64(v) | |
64 #endif | |
65 #elif defined(RTC_ARCH_CPU_BIG_ENDIAN) | |
66 #define htole16(v) __builtin_bswap16(v) | |
67 #define htole32(v) __builtin_bswap32(v) | |
68 #define htole64(v) __builtin_bswap64(v) | |
69 #define le16toh(v) __builtin_bswap16(v) | |
70 #define le32toh(v) __builtin_bswap32(v) | |
71 #define le64toh(v) __builtin_bswap64(v) | |
72 #if defined(__native_client__) | |
73 #define htobe64(v) (v) | |
74 #define be64toh(v) (v) | |
75 #endif | |
76 #else | |
77 #error RTC_ARCH_CPU_BIG_ENDIAN or RTC_ARCH_CPU_LITTLE_ENDIAN must be defined. | |
78 #endif // defined(RTC_ARCH_CPU_LITTLE_ENDIAN) | |
79 #elif defined(WEBRTC_POSIX) | |
80 #include <endian.h> | |
81 #endif | |
82 | |
83 namespace rtc { | 24 namespace rtc { |
84 | 25 |
85 // Reading and writing of little and big-endian numbers from memory | 26 // Reading and writing of little and big-endian numbers from memory |
| 27 // TODO: Optimized versions, with direct read/writes of |
| 28 // integers in host-endian format, when the platform supports it. |
86 | 29 |
87 inline void Set8(void* memory, size_t offset, uint8_t v) { | 30 inline void Set8(void* memory, size_t offset, uint8_t v) { |
88 static_cast<uint8_t*>(memory)[offset] = v; | 31 static_cast<uint8_t*>(memory)[offset] = v; |
89 } | 32 } |
90 | 33 |
91 inline uint8_t Get8(const void* memory, size_t offset) { | 34 inline uint8_t Get8(const void* memory, size_t offset) { |
92 return static_cast<const uint8_t*>(memory)[offset]; | 35 return static_cast<const uint8_t*>(memory)[offset]; |
93 } | 36 } |
94 | 37 |
95 inline void SetBE16(void* memory, uint16_t v) { | 38 inline void SetBE16(void* memory, uint16_t v) { |
96 *static_cast<uint16_t*>(memory) = htobe16(v); | 39 Set8(memory, 0, static_cast<uint8_t>(v >> 8)); |
| 40 Set8(memory, 1, static_cast<uint8_t>(v >> 0)); |
97 } | 41 } |
98 | 42 |
99 inline void SetBE32(void* memory, uint32_t v) { | 43 inline void SetBE32(void* memory, uint32_t v) { |
100 *static_cast<uint32_t*>(memory) = htobe32(v); | 44 Set8(memory, 0, static_cast<uint8_t>(v >> 24)); |
| 45 Set8(memory, 1, static_cast<uint8_t>(v >> 16)); |
| 46 Set8(memory, 2, static_cast<uint8_t>(v >> 8)); |
| 47 Set8(memory, 3, static_cast<uint8_t>(v >> 0)); |
101 } | 48 } |
102 | 49 |
103 inline void SetBE64(void* memory, uint64_t v) { | 50 inline void SetBE64(void* memory, uint64_t v) { |
104 *static_cast<uint64_t*>(memory) = htobe64(v); | 51 Set8(memory, 0, static_cast<uint8_t>(v >> 56)); |
| 52 Set8(memory, 1, static_cast<uint8_t>(v >> 48)); |
| 53 Set8(memory, 2, static_cast<uint8_t>(v >> 40)); |
| 54 Set8(memory, 3, static_cast<uint8_t>(v >> 32)); |
| 55 Set8(memory, 4, static_cast<uint8_t>(v >> 24)); |
| 56 Set8(memory, 5, static_cast<uint8_t>(v >> 16)); |
| 57 Set8(memory, 6, static_cast<uint8_t>(v >> 8)); |
| 58 Set8(memory, 7, static_cast<uint8_t>(v >> 0)); |
105 } | 59 } |
106 | 60 |
107 inline uint16_t GetBE16(const void* memory) { | 61 inline uint16_t GetBE16(const void* memory) { |
108 return be16toh(*static_cast<const uint16_t*>(memory)); | 62 return static_cast<uint16_t>((Get8(memory, 0) << 8) | (Get8(memory, 1) << 0)); |
109 } | 63 } |
110 | 64 |
111 inline uint32_t GetBE32(const void* memory) { | 65 inline uint32_t GetBE32(const void* memory) { |
112 return be32toh(*static_cast<const uint32_t*>(memory)); | 66 return (static_cast<uint32_t>(Get8(memory, 0)) << 24) | |
| 67 (static_cast<uint32_t>(Get8(memory, 1)) << 16) | |
| 68 (static_cast<uint32_t>(Get8(memory, 2)) << 8) | |
| 69 (static_cast<uint32_t>(Get8(memory, 3)) << 0); |
113 } | 70 } |
114 | 71 |
115 inline uint64_t GetBE64(const void* memory) { | 72 inline uint64_t GetBE64(const void* memory) { |
116 return be64toh(*static_cast<const uint64_t*>(memory)); | 73 return (static_cast<uint64_t>(Get8(memory, 0)) << 56) | |
| 74 (static_cast<uint64_t>(Get8(memory, 1)) << 48) | |
| 75 (static_cast<uint64_t>(Get8(memory, 2)) << 40) | |
| 76 (static_cast<uint64_t>(Get8(memory, 3)) << 32) | |
| 77 (static_cast<uint64_t>(Get8(memory, 4)) << 24) | |
| 78 (static_cast<uint64_t>(Get8(memory, 5)) << 16) | |
| 79 (static_cast<uint64_t>(Get8(memory, 6)) << 8) | |
| 80 (static_cast<uint64_t>(Get8(memory, 7)) << 0); |
117 } | 81 } |
118 | 82 |
119 inline void SetLE16(void* memory, uint16_t v) { | 83 inline void SetLE16(void* memory, uint16_t v) { |
120 *static_cast<uint16_t*>(memory) = htole16(v); | 84 Set8(memory, 0, static_cast<uint8_t>(v >> 0)); |
| 85 Set8(memory, 1, static_cast<uint8_t>(v >> 8)); |
121 } | 86 } |
122 | 87 |
123 inline void SetLE32(void* memory, uint32_t v) { | 88 inline void SetLE32(void* memory, uint32_t v) { |
124 *static_cast<uint32_t*>(memory) = htole32(v); | 89 Set8(memory, 0, static_cast<uint8_t>(v >> 0)); |
| 90 Set8(memory, 1, static_cast<uint8_t>(v >> 8)); |
| 91 Set8(memory, 2, static_cast<uint8_t>(v >> 16)); |
| 92 Set8(memory, 3, static_cast<uint8_t>(v >> 24)); |
125 } | 93 } |
126 | 94 |
127 inline void SetLE64(void* memory, uint64_t v) { | 95 inline void SetLE64(void* memory, uint64_t v) { |
128 *static_cast<uint64_t*>(memory) = htole64(v); | 96 Set8(memory, 0, static_cast<uint8_t>(v >> 0)); |
| 97 Set8(memory, 1, static_cast<uint8_t>(v >> 8)); |
| 98 Set8(memory, 2, static_cast<uint8_t>(v >> 16)); |
| 99 Set8(memory, 3, static_cast<uint8_t>(v >> 24)); |
| 100 Set8(memory, 4, static_cast<uint8_t>(v >> 32)); |
| 101 Set8(memory, 5, static_cast<uint8_t>(v >> 40)); |
| 102 Set8(memory, 6, static_cast<uint8_t>(v >> 48)); |
| 103 Set8(memory, 7, static_cast<uint8_t>(v >> 56)); |
129 } | 104 } |
130 | 105 |
131 inline uint16_t GetLE16(const void* memory) { | 106 inline uint16_t GetLE16(const void* memory) { |
132 return le16toh(*static_cast<const uint16_t*>(memory)); | 107 return static_cast<uint16_t>((Get8(memory, 0) << 0) | (Get8(memory, 1) << 8)); |
133 } | 108 } |
134 | 109 |
135 inline uint32_t GetLE32(const void* memory) { | 110 inline uint32_t GetLE32(const void* memory) { |
136 return le32toh(*static_cast<const uint32_t*>(memory)); | 111 return (static_cast<uint32_t>(Get8(memory, 0)) << 0) | |
| 112 (static_cast<uint32_t>(Get8(memory, 1)) << 8) | |
| 113 (static_cast<uint32_t>(Get8(memory, 2)) << 16) | |
| 114 (static_cast<uint32_t>(Get8(memory, 3)) << 24); |
137 } | 115 } |
138 | 116 |
139 inline uint64_t GetLE64(const void* memory) { | 117 inline uint64_t GetLE64(const void* memory) { |
140 return le64toh(*static_cast<const uint64_t*>(memory)); | 118 return (static_cast<uint64_t>(Get8(memory, 0)) << 0) | |
| 119 (static_cast<uint64_t>(Get8(memory, 1)) << 8) | |
| 120 (static_cast<uint64_t>(Get8(memory, 2)) << 16) | |
| 121 (static_cast<uint64_t>(Get8(memory, 3)) << 24) | |
| 122 (static_cast<uint64_t>(Get8(memory, 4)) << 32) | |
| 123 (static_cast<uint64_t>(Get8(memory, 5)) << 40) | |
| 124 (static_cast<uint64_t>(Get8(memory, 6)) << 48) | |
| 125 (static_cast<uint64_t>(Get8(memory, 7)) << 56); |
141 } | 126 } |
142 | 127 |
143 // Check if the current host is big endian. | 128 // Check if the current host is big endian. |
144 inline bool IsHostBigEndian() { | 129 inline bool IsHostBigEndian() { |
145 #if defined(RTC_ARCH_CPU_BIG_ENDIAN) | 130 static const int number = 1; |
146 return true; | 131 return 0 == *reinterpret_cast<const char*>(&number); |
147 #else | |
148 return false; | |
149 #endif | |
150 } | 132 } |
151 | 133 |
152 inline uint16_t HostToNetwork16(uint16_t n) { | 134 inline uint16_t HostToNetwork16(uint16_t n) { |
153 return htobe16(n); | 135 uint16_t result; |
| 136 SetBE16(&result, n); |
| 137 return result; |
154 } | 138 } |
155 | 139 |
156 inline uint32_t HostToNetwork32(uint32_t n) { | 140 inline uint32_t HostToNetwork32(uint32_t n) { |
157 return htobe32(n); | 141 uint32_t result; |
| 142 SetBE32(&result, n); |
| 143 return result; |
158 } | 144 } |
159 | 145 |
160 inline uint64_t HostToNetwork64(uint64_t n) { | 146 inline uint64_t HostToNetwork64(uint64_t n) { |
161 return htobe64(n); | 147 uint64_t result; |
| 148 SetBE64(&result, n); |
| 149 return result; |
162 } | 150 } |
163 | 151 |
164 inline uint16_t NetworkToHost16(uint16_t n) { | 152 inline uint16_t NetworkToHost16(uint16_t n) { |
165 return be16toh(n); | 153 return GetBE16(&n); |
166 } | 154 } |
167 | 155 |
168 inline uint32_t NetworkToHost32(uint32_t n) { | 156 inline uint32_t NetworkToHost32(uint32_t n) { |
169 return be32toh(n); | 157 return GetBE32(&n); |
170 } | 158 } |
171 | 159 |
172 inline uint64_t NetworkToHost64(uint64_t n) { | 160 inline uint64_t NetworkToHost64(uint64_t n) { |
173 return be64toh(n); | 161 return GetBE64(&n); |
174 } | 162 } |
175 | 163 |
176 } // namespace rtc | 164 } // namespace rtc |
177 | 165 |
178 #endif // WEBRTC_BASE_BYTEORDER_H_ | 166 #endif // WEBRTC_BASE_BYTEORDER_H_ |
OLD | NEW |