endian.h
Go to the documentation of this file.
00001 // Copyright 2017 The Abseil Authors.
00002 //
00003 // Licensed under the Apache License, Version 2.0 (the "License");
00004 // you may not use this file except in compliance with the License.
00005 // You may obtain a copy of the License at
00006 //
00007 //      https://www.apache.org/licenses/LICENSE-2.0
00008 //
00009 // Unless required by applicable law or agreed to in writing, software
00010 // distributed under the License is distributed on an "AS IS" BASIS,
00011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00012 // See the License for the specific language governing permissions and
00013 // limitations under the License.
00014 //
00015 
00016 #ifndef ABSL_BASE_INTERNAL_ENDIAN_H_
00017 #define ABSL_BASE_INTERNAL_ENDIAN_H_
00018 
00019 // The following guarantees declaration of the byte swap functions
00020 #ifdef _MSC_VER
00021 #include <stdlib.h>  // NOLINT(build/include)
00022 #elif defined(__APPLE__)
00023 // Mac OS X / Darwin features
00024 #include <libkern/OSByteOrder.h>
00025 #elif defined(__FreeBSD__)
00026 #include <sys/endian.h>
00027 #elif defined(__GLIBC__)
00028 #include <byteswap.h>  // IWYU pragma: export
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 // Use compiler byte-swapping intrinsics if they are available.  32-bit
00039 // and 64-bit versions are available in Clang and GCC as of GCC 4.3.0.
00040 // The 16-bit version is available in Clang and GCC only as of GCC 4.8.0.
00041 // For simplicity, we enable them all only for GCC 4.8.0 or later.
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   // Adapted from /usr/include/byteswap.h.  Not available on Mac.
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 // Definitions for ntohl etc. that don't require us to include
00121 // netinet/in.h. We wrap gbswap_32 and gbswap_16 in functions rather
00122 // than just #defining them because in debug mode, gcc doesn't
00123 // correctly handle the (rather involved) definitions of bswap_32.
00124 // gcc guarantees that inline functions are as fast as macros, so
00125 // this isn't a performance hit.
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 // These definitions are simpler on big-endian machines
00133 // These are functions instead of macros to avoid self-assignment warnings
00134 // on calls such as "i = ghtnol(i);".  This also provides type checking.
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 // Utilities to convert numbers between the current hosts's native byte
00150 // order and little-endian byte order
00151 //
00152 // Load/Store methods are alignment safe
00153 namespace little_endian {
00154 // Conversion functions.
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 /* ENDIAN */
00182 
00183 // Functions to do unaligned loads and stores in little-endian order.
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 }  // namespace little_endian
00209 
00210 // Utilities to convert numbers between the current hosts's native byte
00211 // order and big-endian byte order (same as network byte order)
00212 //
00213 // Load/Store methods are alignment safe
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 /* ENDIAN */
00242 
00243 // Functions to do unaligned loads and stores in big-endian order.
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 }  // namespace big_endian
00269 
00270 }  // namespace absl
00271 
00272 #endif  // ABSL_BASE_INTERNAL_ENDIAN_H_


abseil_cpp
Author(s):
autogenerated on Wed Jun 19 2019 19:42:14