1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 // This header defines cross-platform ByteSwap() implementations for 16, 32 and 6 // 64-bit values, and NetToHostXX() / HostToNextXX() functions equivalent to 7 // the traditional ntohX() and htonX() functions. 8 // Use the functions defined here rather than using the platform-specific 9 // functions directly. 10 11 #ifndef BASE_SYS_BYTEORDER_H_ 12 #define BASE_SYS_BYTEORDER_H_ 13 14 #include <stdint.h> 15 16 #include "base/logging.h" 17 #include "build/build_config.h" 18 19 #if defined(COMPILER_MSVC) 20 #include <stdlib.h> 21 #endif 22 23 namespace base { 24 25 // Returns a value with all bytes in |x| swapped, i.e. reverses the endianness. 26 inline uint16_t ByteSwap(uint16_t x) { 27 #if defined(COMPILER_MSVC) 28 return _byteswap_ushort(x); 29 #else 30 return __builtin_bswap16(x); 31 #endif 32 } 33 34 inline uint32_t ByteSwap(uint32_t x) { 35 #if defined(COMPILER_MSVC) 36 return _byteswap_ulong(x); 37 #else 38 return __builtin_bswap32(x); 39 #endif 40 } 41 42 inline uint64_t ByteSwap(uint64_t x) { 43 #if defined(COMPILER_MSVC) 44 return _byteswap_uint64(x); 45 #else 46 return __builtin_bswap64(x); 47 #endif 48 } 49 50 inline uintptr_t ByteSwapUintPtrT(uintptr_t x) { 51 // We do it this way because some build configurations are ILP32 even when 52 // defined(ARCH_CPU_64_BITS). Unfortunately, we can't use sizeof in #ifs. But, 53 // because these conditionals are constexprs, the irrelevant branches will 54 // likely be optimized away, so this construction should not result in code 55 // bloat. 56 if (sizeof(uintptr_t) == 4) { 57 return ByteSwap(static_cast<uint32_t>(x)); 58 } else if (sizeof(uintptr_t) == 8) { 59 return ByteSwap(static_cast<uint64_t>(x)); 60 } else { 61 NOTREACHED(); 62 } 63 } 64 65 // Converts the bytes in |x| from host order (endianness) to little endian, and 66 // returns the result. 67 inline uint16_t ByteSwapToLE16(uint16_t x) { 68 #if defined(ARCH_CPU_LITTLE_ENDIAN) 69 return x; 70 #else 71 return ByteSwap(x); 72 #endif 73 } 74 inline uint32_t ByteSwapToLE32(uint32_t x) { 75 #if defined(ARCH_CPU_LITTLE_ENDIAN) 76 return x; 77 #else 78 return ByteSwap(x); 79 #endif 80 } 81 inline uint64_t ByteSwapToLE64(uint64_t x) { 82 #if defined(ARCH_CPU_LITTLE_ENDIAN) 83 return x; 84 #else 85 return ByteSwap(x); 86 #endif 87 } 88 89 // Converts the bytes in |x| from network to host order (endianness), and 90 // returns the result. 91 inline uint16_t NetToHost16(uint16_t x) { 92 #if defined(ARCH_CPU_LITTLE_ENDIAN) 93 return ByteSwap(x); 94 #else 95 return x; 96 #endif 97 } 98 inline uint32_t NetToHost32(uint32_t x) { 99 #if defined(ARCH_CPU_LITTLE_ENDIAN) 100 return ByteSwap(x); 101 #else 102 return x; 103 #endif 104 } 105 inline uint64_t NetToHost64(uint64_t x) { 106 #if defined(ARCH_CPU_LITTLE_ENDIAN) 107 return ByteSwap(x); 108 #else 109 return x; 110 #endif 111 } 112 113 // Converts the bytes in |x| from host to network order (endianness), and 114 // returns the result. 115 inline uint16_t HostToNet16(uint16_t x) { 116 #if defined(ARCH_CPU_LITTLE_ENDIAN) 117 return ByteSwap(x); 118 #else 119 return x; 120 #endif 121 } 122 inline uint32_t HostToNet32(uint32_t x) { 123 #if defined(ARCH_CPU_LITTLE_ENDIAN) 124 return ByteSwap(x); 125 #else 126 return x; 127 #endif 128 } 129 inline uint64_t HostToNet64(uint64_t x) { 130 #if defined(ARCH_CPU_LITTLE_ENDIAN) 131 return ByteSwap(x); 132 #else 133 return x; 134 #endif 135 } 136 137 } // namespace base 138 139 #endif // BASE_SYS_BYTEORDER_H_ 140