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 "third_party/base/logging.h"
17 #include "third_party/build/build_config.h"
18
19 #if defined(COMPILER_MSVC)
20 #include <stdlib.h>
21 #endif
22
23 namespace pdfium {
24 namespace base {
25
26 // Returns a value with all bytes in |x| swapped, i.e. reverses the endianness.
ByteSwap(uint16_t x)27 inline uint16_t ByteSwap(uint16_t x) {
28 #if defined(COMPILER_MSVC)
29 return _byteswap_ushort(x);
30 #else
31 return __builtin_bswap16(x);
32 #endif
33 }
34
ByteSwap(uint32_t x)35 inline uint32_t ByteSwap(uint32_t x) {
36 #if defined(COMPILER_MSVC)
37 return _byteswap_ulong(x);
38 #else
39 return __builtin_bswap32(x);
40 #endif
41 }
42
ByteSwap(uint64_t x)43 inline uint64_t ByteSwap(uint64_t x) {
44 #if defined(COMPILER_MSVC)
45 return _byteswap_uint64(x);
46 #else
47 return __builtin_bswap64(x);
48 #endif
49 }
50
ByteSwapUintPtrT(uintptr_t x)51 inline uintptr_t ByteSwapUintPtrT(uintptr_t x) {
52 // We do it this way because some build configurations are ILP32 even when
53 // defined(ARCH_CPU_64_BITS). Unfortunately, we can't use sizeof in #ifs. But,
54 // because these conditionals are constexprs, the irrelevant branches will
55 // likely be optimized away, so this construction should not result in code
56 // bloat.
57 if (sizeof(uintptr_t) == 4) {
58 return ByteSwap(static_cast<uint32_t>(x));
59 } else if (sizeof(uintptr_t) == 8) {
60 return ByteSwap(static_cast<uint64_t>(x));
61 } else {
62 NOTREACHED();
63 }
64 }
65
66 // Converts the bytes in |x| from host order (endianness) to little endian, and
67 // returns the result.
ByteSwapToLE16(uint16_t x)68 inline uint16_t ByteSwapToLE16(uint16_t x) {
69 #if defined(ARCH_CPU_LITTLE_ENDIAN)
70 return x;
71 #else
72 return ByteSwap(x);
73 #endif
74 }
ByteSwapToLE32(uint32_t x)75 inline uint32_t ByteSwapToLE32(uint32_t x) {
76 #if defined(ARCH_CPU_LITTLE_ENDIAN)
77 return x;
78 #else
79 return ByteSwap(x);
80 #endif
81 }
ByteSwapToLE64(uint64_t x)82 inline uint64_t ByteSwapToLE64(uint64_t x) {
83 #if defined(ARCH_CPU_LITTLE_ENDIAN)
84 return x;
85 #else
86 return ByteSwap(x);
87 #endif
88 }
89
90 // Converts the bytes in |x| from network to host order (endianness), and
91 // returns the result.
NetToHost16(uint16_t x)92 inline uint16_t NetToHost16(uint16_t x) {
93 #if defined(ARCH_CPU_LITTLE_ENDIAN)
94 return ByteSwap(x);
95 #else
96 return x;
97 #endif
98 }
NetToHost32(uint32_t x)99 inline uint32_t NetToHost32(uint32_t x) {
100 #if defined(ARCH_CPU_LITTLE_ENDIAN)
101 return ByteSwap(x);
102 #else
103 return x;
104 #endif
105 }
NetToHost64(uint64_t x)106 inline uint64_t NetToHost64(uint64_t x) {
107 #if defined(ARCH_CPU_LITTLE_ENDIAN)
108 return ByteSwap(x);
109 #else
110 return x;
111 #endif
112 }
113
114 // Converts the bytes in |x| from host to network order (endianness), and
115 // returns the result.
HostToNet16(uint16_t x)116 inline uint16_t HostToNet16(uint16_t x) {
117 #if defined(ARCH_CPU_LITTLE_ENDIAN)
118 return ByteSwap(x);
119 #else
120 return x;
121 #endif
122 }
HostToNet32(uint32_t x)123 inline uint32_t HostToNet32(uint32_t x) {
124 #if defined(ARCH_CPU_LITTLE_ENDIAN)
125 return ByteSwap(x);
126 #else
127 return x;
128 #endif
129 }
HostToNet64(uint64_t x)130 inline uint64_t HostToNet64(uint64_t x) {
131 #if defined(ARCH_CPU_LITTLE_ENDIAN)
132 return ByteSwap(x);
133 #else
134 return x;
135 #endif
136 }
137
138 } // namespace base
139 } // namespace pdfium
140
141 #endif // BASE_SYS_BYTEORDER_H_
142