[go: nahoru, domu]

blob: df3b1e55f7169da9e40dbad75ad19bba283aa7b2 [file] [log] [blame]
wez@chromium.org9eb7b112012-03-28 20:19:311// Copyright (c) 2012 The Chromium Authors. All rights reserved.
isherman@chromium.org0e6f6192011-12-28 23:18:212// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
wez@chromium.orgeda78e62012-04-06 04:32:285// 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.org0e6f6192011-12-28 23:18:2110
11#ifndef BASE_SYS_BYTEORDER_H_
12#define BASE_SYS_BYTEORDER_H_
13
avi9b6f42932015-12-26 22:15:1414#include <stdint.h>
15
isherman@chromium.org0e6f6192011-12-28 23:18:2116#include "build/build_config.h"
17
robert.bradford1a09b1772016-06-17 23:26:1118#if defined(COMPILER_MSVC)
19#include <stdlib.h>
20#endif
21
Peter Kasting64c67dd2022-05-12 18:11:5122#if defined(COMPILER_MSVC) && !defined(__clang__)
23// TODO(pkasting): See
24// https://developercommunity.visualstudio.com/t/Mark-some-built-in-functions-as-constexp/362558
25// https://developercommunity.visualstudio.com/t/constexpr-byte-swapping-optimization/983963
26#define BASE_BYTESWAPS_CONSTEXPR
27#else
28#define BASE_BYTESWAPS_CONSTEXPR constexpr
29#endif
30
isherman@chromium.org0e6f6192011-12-28 23:18:2131namespace base {
32
33// Returns a value with all bytes in |x| swapped, i.e. reverses the endianness.
Peter Kasting64c67dd2022-05-12 18:11:5134// TODO(pkasting): Once C++23 is available, replace with std::byteswap.
35inline BASE_BYTESWAPS_CONSTEXPR uint16_t ByteSwap(uint16_t x) {
Benoit Lize63ce1152021-02-04 17:44:5336#if defined(COMPILER_MSVC) && !defined(__clang__)
robert.bradford1a09b1772016-06-17 23:26:1137 return _byteswap_ushort(x);
38#else
39 return __builtin_bswap16(x);
40#endif
wez@chromium.org9eb7b112012-03-28 20:19:3141}
sergeyu@chromium.org2090c522013-12-23 04:02:4942
Peter Kasting64c67dd2022-05-12 18:11:5143inline BASE_BYTESWAPS_CONSTEXPR uint32_t ByteSwap(uint32_t x) {
Benoit Lize63ce1152021-02-04 17:44:5344#if defined(COMPILER_MSVC) && !defined(__clang__)
robert.bradford1a09b1772016-06-17 23:26:1145 return _byteswap_ulong(x);
46#else
47 return __builtin_bswap32(x);
48#endif
wez@chromium.org9eb7b112012-03-28 20:19:3149}
sergeyu@chromium.org2090c522013-12-23 04:02:4950
Peter Kasting64c67dd2022-05-12 18:11:5151inline BASE_BYTESWAPS_CONSTEXPR uint64_t ByteSwap(uint64_t x) {
Benoit Lize63ce1152021-02-04 17:44:5352 // Per build/build_config.h, clang masquerades as MSVC on Windows. If we are
53 // actually using clang, we can rely on the builtin.
54 //
55 // This matters in practice, because on x86(_64), this is a single "bswap"
56 // instruction. MSVC correctly replaces the call with an inlined bswap at /O2
57 // as of 2021, but clang as we use it in Chromium doesn't, keeping a function
58 // call for a single instruction.
59#if defined(COMPILER_MSVC) && !defined(__clang__)
robert.bradford1a09b1772016-06-17 23:26:1160 return _byteswap_uint64(x);
61#else
62 return __builtin_bswap64(x);
63#endif
isherman@chromium.org0e6f6192011-12-28 23:18:2164}
65
Peter Kasting64c67dd2022-05-12 18:11:5166inline BASE_BYTESWAPS_CONSTEXPR uintptr_t ByteSwapUintPtrT(uintptr_t x) {
palmera988c502016-12-14 09:40:3867 // We do it this way because some build configurations are ILP32 even when
68 // defined(ARCH_CPU_64_BITS). Unfortunately, we can't use sizeof in #ifs. But,
69 // because these conditionals are constexprs, the irrelevant branches will
70 // likely be optimized away, so this construction should not result in code
71 // bloat.
Lei Zhang5bf451c2020-01-06 20:49:4272 static_assert(sizeof(uintptr_t) == 4 || sizeof(uintptr_t) == 8,
73 "Unsupported uintptr_t size");
74 if (sizeof(uintptr_t) == 4)
palmera988c502016-12-14 09:40:3875 return ByteSwap(static_cast<uint32_t>(x));
Lei Zhang5bf451c2020-01-06 20:49:4276 return ByteSwap(static_cast<uint64_t>(x));
palmera988c502016-12-14 09:40:3877}
78
jwd@chromium.org7f8ce3d92012-04-16 15:29:2779// Converts the bytes in |x| from host order (endianness) to little endian, and
80// returns the result.
Peter Kasting64c67dd2022-05-12 18:11:5181inline BASE_BYTESWAPS_CONSTEXPR uint16_t ByteSwapToLE16(uint16_t x) {
jwd@chromium.org7f8ce3d92012-04-16 15:29:2782#if defined(ARCH_CPU_LITTLE_ENDIAN)
83 return x;
84#else
85 return ByteSwap(x);
86#endif
87}
Peter Kasting64c67dd2022-05-12 18:11:5188inline BASE_BYTESWAPS_CONSTEXPR uint32_t ByteSwapToLE32(uint32_t x) {
jwd@chromium.org7f8ce3d92012-04-16 15:29:2789#if defined(ARCH_CPU_LITTLE_ENDIAN)
90 return x;
91#else
92 return ByteSwap(x);
93#endif
94}
Peter Kasting64c67dd2022-05-12 18:11:5195inline BASE_BYTESWAPS_CONSTEXPR uint64_t ByteSwapToLE64(uint64_t x) {
jwd@chromium.org7f8ce3d92012-04-16 15:29:2796#if defined(ARCH_CPU_LITTLE_ENDIAN)
97 return x;
98#else
99 return ByteSwap(x);
100#endif
101}
102
isherman@chromium.org0e6f6192011-12-28 23:18:21103// Converts the bytes in |x| from network to host order (endianness), and
104// returns the result.
Peter Kasting64c67dd2022-05-12 18:11:51105inline BASE_BYTESWAPS_CONSTEXPR uint16_t NetToHost16(uint16_t x) {
wez@chromium.org9eb7b112012-03-28 20:19:31106#if defined(ARCH_CPU_LITTLE_ENDIAN)
107 return ByteSwap(x);
108#else
109 return x;
110#endif
111}
Peter Kasting64c67dd2022-05-12 18:11:51112inline BASE_BYTESWAPS_CONSTEXPR uint32_t NetToHost32(uint32_t x) {
wez@chromium.org9eb7b112012-03-28 20:19:31113#if defined(ARCH_CPU_LITTLE_ENDIAN)
114 return ByteSwap(x);
115#else
116 return x;
117#endif
118}
Peter Kasting64c67dd2022-05-12 18:11:51119inline BASE_BYTESWAPS_CONSTEXPR uint64_t NetToHost64(uint64_t x) {
isherman@chromium.org0e6f6192011-12-28 23:18:21120#if defined(ARCH_CPU_LITTLE_ENDIAN)
121 return ByteSwap(x);
122#else
123 return x;
124#endif
125}
126
127// Converts the bytes in |x| from host to network order (endianness), and
128// returns the result.
Peter Kasting64c67dd2022-05-12 18:11:51129inline BASE_BYTESWAPS_CONSTEXPR uint16_t HostToNet16(uint16_t x) {
wez@chromium.org9eb7b112012-03-28 20:19:31130#if defined(ARCH_CPU_LITTLE_ENDIAN)
131 return ByteSwap(x);
132#else
133 return x;
134#endif
135}
Peter Kasting64c67dd2022-05-12 18:11:51136inline BASE_BYTESWAPS_CONSTEXPR uint32_t HostToNet32(uint32_t x) {
wez@chromium.org9eb7b112012-03-28 20:19:31137#if defined(ARCH_CPU_LITTLE_ENDIAN)
138 return ByteSwap(x);
139#else
140 return x;
141#endif
142}
Peter Kasting64c67dd2022-05-12 18:11:51143inline BASE_BYTESWAPS_CONSTEXPR uint64_t HostToNet64(uint64_t x) {
isherman@chromium.org0e6f6192011-12-28 23:18:21144#if defined(ARCH_CPU_LITTLE_ENDIAN)
145 return ByteSwap(x);
146#else
147 return x;
148#endif
149}
150
151} // namespace base
152
Peter Kasting64c67dd2022-05-12 18:11:51153#undef BASE_BYTESWAPS_CONSTEXPR
154
isherman@chromium.org0e6f6192011-12-28 23:18:21155#endif // BASE_SYS_BYTEORDER_H_