Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #ifndef ABSL_BASE_INTERNAL_ENDIAN_H_
00017 #define ABSL_BASE_INTERNAL_ENDIAN_H_
00018
00019
00020 #ifdef _MSC_VER
00021 #include <stdlib.h>
00022 #elif defined(__APPLE__)
00023
00024 #include <libkern/OSByteOrder.h>
00025 #elif defined(__FreeBSD__)
00026 #include <sys/endian.h>
00027 #elif defined(__GLIBC__)
00028 #include <byteswap.h>
00029 #endif
00030
00031 #include <cstdint>
00032 #include "absl/base/config.h"
00033 #include "absl/base/internal/unaligned_access.h"
00034 #include "absl/base/port.h"
00035
00036 namespace absl {
00037
00038
00039
00040
00041
00042 #if defined(__clang__) || \
00043 (defined(__GNUC__) && \
00044 ((__GNUC__ == 4 && __GNUC_MINOR__ >= 8) || __GNUC__ >= 5))
00045 inline uint64_t gbswap_64(uint64_t host_int) {
00046 return __builtin_bswap64(host_int);
00047 }
00048 inline uint32_t gbswap_32(uint32_t host_int) {
00049 return __builtin_bswap32(host_int);
00050 }
00051 inline uint16_t gbswap_16(uint16_t host_int) {
00052 return __builtin_bswap16(host_int);
00053 }
00054
00055 #elif defined(_MSC_VER)
00056 inline uint64_t gbswap_64(uint64_t host_int) {
00057 return _byteswap_uint64(host_int);
00058 }
00059 inline uint32_t gbswap_32(uint32_t host_int) {
00060 return _byteswap_ulong(host_int);
00061 }
00062 inline uint16_t gbswap_16(uint16_t host_int) {
00063 return _byteswap_ushort(host_int);
00064 }
00065
00066 #elif defined(__APPLE__)
00067 inline uint64_t gbswap_64(uint64_t host_int) { return OSSwapInt16(host_int); }
00068 inline uint32_t gbswap_32(uint32_t host_int) { return OSSwapInt32(host_int); }
00069 inline uint16_t gbswap_16(uint16_t host_int) { return OSSwapInt64(host_int); }
00070
00071 #else
00072 inline uint64_t gbswap_64(uint64_t host_int) {
00073 #if defined(__GNUC__) && defined(__x86_64__) && !defined(__APPLE__)
00074
00075 if (__builtin_constant_p(host_int)) {
00076 return __bswap_constant_64(host_int);
00077 } else {
00078 uint64_t result;
00079 __asm__("bswap %0" : "=r"(result) : "0"(host_int));
00080 return result;
00081 }
00082 #elif defined(__GLIBC__)
00083 return bswap_64(host_int);
00084 #else
00085 return (((host_int & uint64_t{0xFF}) << 56) |
00086 ((host_int & uint64_t{0xFF00}) << 40) |
00087 ((host_int & uint64_t{0xFF0000}) << 24) |
00088 ((host_int & uint64_t{0xFF000000}) << 8) |
00089 ((host_int & uint64_t{0xFF00000000}) >> 8) |
00090 ((host_int & uint64_t{0xFF0000000000}) >> 24) |
00091 ((host_int & uint64_t{0xFF000000000000}) >> 40) |
00092 ((host_int & uint64_t{0xFF00000000000000}) >> 56));
00093 #endif // bswap_64
00094 }
00095
00096 inline uint32_t gbswap_32(uint32_t host_int) {
00097 #if defined(__GLIBC__)
00098 return bswap_32(host_int);
00099 #else
00100 return (((host_int & uint32_t{0xFF}) << 24) |
00101 ((host_int & uint32_t{0xFF00}) << 8) |
00102 ((host_int & uint32_t{0xFF0000}) >> 8) |
00103 ((host_int & uint32_t{0xFF000000}) >> 24));
00104 #endif
00105 }
00106
00107 inline uint16_t gbswap_16(uint16_t host_int) {
00108 #if defined(__GLIBC__)
00109 return bswap_16(host_int);
00110 #else
00111 return (((host_int & uint16_t{0xFF}) << 8) |
00112 ((host_int & uint16_t{0xFF00}) >> 8));
00113 #endif
00114 }
00115
00116 #endif // intrinics available
00117
00118 #ifdef ABSL_IS_LITTLE_ENDIAN
00119
00120
00121
00122
00123
00124
00125
00126 inline uint16_t ghtons(uint16_t x) { return gbswap_16(x); }
00127 inline uint32_t ghtonl(uint32_t x) { return gbswap_32(x); }
00128 inline uint64_t ghtonll(uint64_t x) { return gbswap_64(x); }
00129
00130 #elif defined ABSL_IS_BIG_ENDIAN
00131
00132
00133
00134
00135 inline uint16_t ghtons(uint16_t x) { return x; }
00136 inline uint32_t ghtonl(uint32_t x) { return x; }
00137 inline uint64_t ghtonll(uint64_t x) { return x; }
00138
00139 #else
00140 #error \
00141 "Unsupported byte order: Either ABSL_IS_BIG_ENDIAN or " \
00142 "ABSL_IS_LITTLE_ENDIAN must be defined"
00143 #endif // byte order
00144
00145 inline uint16_t gntohs(uint16_t x) { return ghtons(x); }
00146 inline uint32_t gntohl(uint32_t x) { return ghtonl(x); }
00147 inline uint64_t gntohll(uint64_t x) { return ghtonll(x); }
00148
00149
00150
00151
00152
00153 namespace little_endian {
00154
00155 #ifdef ABSL_IS_LITTLE_ENDIAN
00156
00157 inline uint16_t FromHost16(uint16_t x) { return x; }
00158 inline uint16_t ToHost16(uint16_t x) { return x; }
00159
00160 inline uint32_t FromHost32(uint32_t x) { return x; }
00161 inline uint32_t ToHost32(uint32_t x) { return x; }
00162
00163 inline uint64_t FromHost64(uint64_t x) { return x; }
00164 inline uint64_t ToHost64(uint64_t x) { return x; }
00165
00166 inline constexpr bool IsLittleEndian() { return true; }
00167
00168 #elif defined ABSL_IS_BIG_ENDIAN
00169
00170 inline uint16_t FromHost16(uint16_t x) { return gbswap_16(x); }
00171 inline uint16_t ToHost16(uint16_t x) { return gbswap_16(x); }
00172
00173 inline uint32_t FromHost32(uint32_t x) { return gbswap_32(x); }
00174 inline uint32_t ToHost32(uint32_t x) { return gbswap_32(x); }
00175
00176 inline uint64_t FromHost64(uint64_t x) { return gbswap_64(x); }
00177 inline uint64_t ToHost64(uint64_t x) { return gbswap_64(x); }
00178
00179 inline constexpr bool IsLittleEndian() { return false; }
00180
00181 #endif
00182
00183
00184 inline uint16_t Load16(const void *p) {
00185 return ToHost16(ABSL_INTERNAL_UNALIGNED_LOAD16(p));
00186 }
00187
00188 inline void Store16(void *p, uint16_t v) {
00189 ABSL_INTERNAL_UNALIGNED_STORE16(p, FromHost16(v));
00190 }
00191
00192 inline uint32_t Load32(const void *p) {
00193 return ToHost32(ABSL_INTERNAL_UNALIGNED_LOAD32(p));
00194 }
00195
00196 inline void Store32(void *p, uint32_t v) {
00197 ABSL_INTERNAL_UNALIGNED_STORE32(p, FromHost32(v));
00198 }
00199
00200 inline uint64_t Load64(const void *p) {
00201 return ToHost64(ABSL_INTERNAL_UNALIGNED_LOAD64(p));
00202 }
00203
00204 inline void Store64(void *p, uint64_t v) {
00205 ABSL_INTERNAL_UNALIGNED_STORE64(p, FromHost64(v));
00206 }
00207
00208 }
00209
00210
00211
00212
00213
00214 namespace big_endian {
00215 #ifdef ABSL_IS_LITTLE_ENDIAN
00216
00217 inline uint16_t FromHost16(uint16_t x) { return gbswap_16(x); }
00218 inline uint16_t ToHost16(uint16_t x) { return gbswap_16(x); }
00219
00220 inline uint32_t FromHost32(uint32_t x) { return gbswap_32(x); }
00221 inline uint32_t ToHost32(uint32_t x) { return gbswap_32(x); }
00222
00223 inline uint64_t FromHost64(uint64_t x) { return gbswap_64(x); }
00224 inline uint64_t ToHost64(uint64_t x) { return gbswap_64(x); }
00225
00226 inline constexpr bool IsLittleEndian() { return true; }
00227
00228 #elif defined ABSL_IS_BIG_ENDIAN
00229
00230 inline uint16_t FromHost16(uint16_t x) { return x; }
00231 inline uint16_t ToHost16(uint16_t x) { return x; }
00232
00233 inline uint32_t FromHost32(uint32_t x) { return x; }
00234 inline uint32_t ToHost32(uint32_t x) { return x; }
00235
00236 inline uint64_t FromHost64(uint64_t x) { return x; }
00237 inline uint64_t ToHost64(uint64_t x) { return x; }
00238
00239 inline constexpr bool IsLittleEndian() { return false; }
00240
00241 #endif
00242
00243
00244 inline uint16_t Load16(const void *p) {
00245 return ToHost16(ABSL_INTERNAL_UNALIGNED_LOAD16(p));
00246 }
00247
00248 inline void Store16(void *p, uint16_t v) {
00249 ABSL_INTERNAL_UNALIGNED_STORE16(p, FromHost16(v));
00250 }
00251
00252 inline uint32_t Load32(const void *p) {
00253 return ToHost32(ABSL_INTERNAL_UNALIGNED_LOAD32(p));
00254 }
00255
00256 inline void Store32(void *p, uint32_t v) {
00257 ABSL_INTERNAL_UNALIGNED_STORE32(p, FromHost32(v));
00258 }
00259
00260 inline uint64_t Load64(const void *p) {
00261 return ToHost64(ABSL_INTERNAL_UNALIGNED_LOAD64(p));
00262 }
00263
00264 inline void Store64(void *p, uint64_t v) {
00265 ABSL_INTERNAL_UNALIGNED_STORE64(p, FromHost64(v));
00266 }
00267
00268 }
00269
00270 }
00271
00272 #endif // ABSL_BASE_INTERNAL_ENDIAN_H_