blob: 9ee1827e1e6d8ae8ea0dbf2a6d30cefb953dd4d3 [file] [log] [blame]
wez@chromium.org31745282012-03-29 05:19:31 +09001// Copyright (c) 2012 The Chromium Authors. All rights reserved.
isherman@chromium.org333d7fd2011-12-29 08:18:21 +09002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
wez@chromium.orgcd68c022012-04-06 13:32:28 +09005// 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.
isherman@chromium.org333d7fd2011-12-29 08:18:21 +090010
11#ifndef BASE_SYS_BYTEORDER_H_
12#define BASE_SYS_BYTEORDER_H_
13
avia6a6a682015-12-27 07:15:14 +090014#include <stdint.h>
15
palmer841e3772016-12-14 18:40:38 +090016#include "base/logging.h"
isherman@chromium.org333d7fd2011-12-29 08:18:21 +090017#include "build/build_config.h"
18
robert.bradford5a044462016-06-18 08:26:11 +090019#if defined(COMPILER_MSVC)
20#include <stdlib.h>
21#endif
22
isherman@chromium.org333d7fd2011-12-29 08:18:21 +090023namespace base {
24
25// Returns a value with all bytes in |x| swapped, i.e. reverses the endianness.
avia6a6a682015-12-27 07:15:14 +090026inline uint16_t ByteSwap(uint16_t x) {
robert.bradford5a044462016-06-18 08:26:11 +090027#if defined(COMPILER_MSVC)
28 return _byteswap_ushort(x);
29#else
30 return __builtin_bswap16(x);
31#endif
wez@chromium.org31745282012-03-29 05:19:31 +090032}
sergeyu@chromium.orgb9b28472013-12-23 13:02:49 +090033
avia6a6a682015-12-27 07:15:14 +090034inline uint32_t ByteSwap(uint32_t x) {
robert.bradford5a044462016-06-18 08:26:11 +090035#if defined(COMPILER_MSVC)
36 return _byteswap_ulong(x);
37#else
38 return __builtin_bswap32(x);
39#endif
wez@chromium.org31745282012-03-29 05:19:31 +090040}
sergeyu@chromium.orgb9b28472013-12-23 13:02:49 +090041
avia6a6a682015-12-27 07:15:14 +090042inline uint64_t ByteSwap(uint64_t x) {
robert.bradford5a044462016-06-18 08:26:11 +090043#if defined(COMPILER_MSVC)
44 return _byteswap_uint64(x);
45#else
46 return __builtin_bswap64(x);
47#endif
isherman@chromium.org333d7fd2011-12-29 08:18:21 +090048}
49
palmer841e3772016-12-14 18:40:38 +090050inline 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
jwd@chromium.orgd0dab472012-04-17 00:29:27 +090065// Converts the bytes in |x| from host order (endianness) to little endian, and
66// returns the result.
avia6a6a682015-12-27 07:15:14 +090067inline uint16_t ByteSwapToLE16(uint16_t x) {
jwd@chromium.orgd0dab472012-04-17 00:29:27 +090068#if defined(ARCH_CPU_LITTLE_ENDIAN)
69 return x;
70#else
71 return ByteSwap(x);
72#endif
73}
avia6a6a682015-12-27 07:15:14 +090074inline uint32_t ByteSwapToLE32(uint32_t x) {
jwd@chromium.orgd0dab472012-04-17 00:29:27 +090075#if defined(ARCH_CPU_LITTLE_ENDIAN)
76 return x;
77#else
78 return ByteSwap(x);
79#endif
80}
avia6a6a682015-12-27 07:15:14 +090081inline uint64_t ByteSwapToLE64(uint64_t x) {
jwd@chromium.orgd0dab472012-04-17 00:29:27 +090082#if defined(ARCH_CPU_LITTLE_ENDIAN)
83 return x;
84#else
85 return ByteSwap(x);
86#endif
87}
88
isherman@chromium.org333d7fd2011-12-29 08:18:21 +090089// Converts the bytes in |x| from network to host order (endianness), and
90// returns the result.
avia6a6a682015-12-27 07:15:14 +090091inline uint16_t NetToHost16(uint16_t x) {
wez@chromium.org31745282012-03-29 05:19:31 +090092#if defined(ARCH_CPU_LITTLE_ENDIAN)
93 return ByteSwap(x);
94#else
95 return x;
96#endif
97}
avia6a6a682015-12-27 07:15:14 +090098inline uint32_t NetToHost32(uint32_t x) {
wez@chromium.org31745282012-03-29 05:19:31 +090099#if defined(ARCH_CPU_LITTLE_ENDIAN)
100 return ByteSwap(x);
101#else
102 return x;
103#endif
104}
avia6a6a682015-12-27 07:15:14 +0900105inline uint64_t NetToHost64(uint64_t x) {
isherman@chromium.org333d7fd2011-12-29 08:18:21 +0900106#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.
avia6a6a682015-12-27 07:15:14 +0900115inline uint16_t HostToNet16(uint16_t x) {
wez@chromium.org31745282012-03-29 05:19:31 +0900116#if defined(ARCH_CPU_LITTLE_ENDIAN)
117 return ByteSwap(x);
118#else
119 return x;
120#endif
121}
avia6a6a682015-12-27 07:15:14 +0900122inline uint32_t HostToNet32(uint32_t x) {
wez@chromium.org31745282012-03-29 05:19:31 +0900123#if defined(ARCH_CPU_LITTLE_ENDIAN)
124 return ByteSwap(x);
125#else
126 return x;
127#endif
128}
avia6a6a682015-12-27 07:15:14 +0900129inline uint64_t HostToNet64(uint64_t x) {
isherman@chromium.org333d7fd2011-12-29 08:18:21 +0900130#if defined(ARCH_CPU_LITTLE_ENDIAN)
131 return ByteSwap(x);
132#else
133 return x;
134#endif
135}
136
137} // namespace base
138
isherman@chromium.org333d7fd2011-12-29 08:18:21 +0900139#endif // BASE_SYS_BYTEORDER_H_