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