• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2019 The PDFium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef CORE_FXCRT_BYTEORDER_H_
6 #define CORE_FXCRT_BYTEORDER_H_
7 
8 #include <stdint.h>
9 
10 #include "build/build_config.h"
11 #include "core/fxcrt/span.h"
12 
13 #if defined(COMPILER_MSVC)
14 #include <stdlib.h>
15 #endif
16 
17 namespace fxcrt {
18 
19 namespace internal {
20 
21 #if defined(COMPILER_MSVC) && !defined(__clang__)
22 // TODO(thestig): See
23 // https://developercommunity.visualstudio.com/t/Mark-some-built-in-functions-as-constexp/362558
24 // https://developercommunity.visualstudio.com/t/constexpr-byte-swapping-optimization/983963
25 #define FXCRT_BYTESWAPS_CONSTEXPR
26 #else
27 #define FXCRT_BYTESWAPS_CONSTEXPR constexpr
28 #endif
29 
30 // Returns a value with all bytes in |x| swapped, i.e. reverses the endianness.
31 // TODO(thestig): Once C++23 is available, replace with std::byteswap.
ByteSwap(uint16_t x)32 inline FXCRT_BYTESWAPS_CONSTEXPR uint16_t ByteSwap(uint16_t x) {
33 #if defined(COMPILER_MSVC) && !defined(__clang__)
34   return _byteswap_ushort(x);
35 #else
36   return __builtin_bswap16(x);
37 #endif
38 }
39 
ByteSwap(uint32_t x)40 inline FXCRT_BYTESWAPS_CONSTEXPR uint32_t ByteSwap(uint32_t x) {
41 #if defined(COMPILER_MSVC) && !defined(__clang__)
42   return _byteswap_ulong(x);
43 #else
44   return __builtin_bswap32(x);
45 #endif
46 }
47 
48 #undef FXCRT_BYTESWAPS_CONSTEXPR
49 
50 }  // namespace internal
51 
52 // NOTE: Prefer From*() methods when data is known to be aligned.
53 
54 // Converts the bytes in |x| from host order (endianness) to little endian, and
55 // returns the result.
FromLE16(uint16_t x)56 inline uint16_t FromLE16(uint16_t x) {
57 #if defined(ARCH_CPU_LITTLE_ENDIAN)
58   return x;
59 #else
60   return internal::ByteSwap(x);
61 #endif
62 }
63 
FromLE32(uint32_t x)64 inline uint32_t FromLE32(uint32_t x) {
65 #if defined(ARCH_CPU_LITTLE_ENDIAN)
66   return x;
67 #else
68   return internal::ByteSwap(x);
69 #endif
70 }
71 
72 // Converts the bytes in |x| from host order (endianness) to big endian, and
73 // returns the result.
FromBE16(uint16_t x)74 inline uint16_t FromBE16(uint16_t x) {
75 #if defined(ARCH_CPU_LITTLE_ENDIAN)
76   return internal::ByteSwap(x);
77 #else
78   return x;
79 #endif
80 }
81 
FromBE32(uint32_t x)82 inline uint32_t FromBE32(uint32_t x) {
83 #if defined(ARCH_CPU_LITTLE_ENDIAN)
84   return internal::ByteSwap(x);
85 #else
86   return x;
87 #endif
88 }
89 
90 // Transfer to/from spans irrespective of alignments.
GetUInt16MSBFirst(pdfium::span<const uint8_t,2> span)91 inline uint16_t GetUInt16MSBFirst(pdfium::span<const uint8_t, 2> span) {
92   return (static_cast<uint32_t>(span[0]) << 8) | static_cast<uint32_t>(span[1]);
93 }
94 
GetUInt32MSBFirst(pdfium::span<const uint8_t,4> span)95 inline uint32_t GetUInt32MSBFirst(pdfium::span<const uint8_t, 4> span) {
96   return (static_cast<uint32_t>(span[0]) << 24) |
97          (static_cast<uint32_t>(span[1]) << 16) |
98          (static_cast<uint32_t>(span[2]) << 8) | static_cast<uint32_t>(span[3]);
99 }
100 
GetUInt16LSBFirst(pdfium::span<const uint8_t,2> span)101 inline uint16_t GetUInt16LSBFirst(pdfium::span<const uint8_t, 2> span) {
102   return (static_cast<uint32_t>(span[1]) << 8) | static_cast<uint32_t>(span[0]);
103 }
104 
GetUInt32LSBFirst(pdfium::span<const uint8_t,4> span)105 inline uint32_t GetUInt32LSBFirst(pdfium::span<const uint8_t, 4> span) {
106   return (static_cast<uint32_t>(span[3]) << 24) |
107          (static_cast<uint32_t>(span[2]) << 16) |
108          (static_cast<uint32_t>(span[1]) << 8) | static_cast<uint32_t>(span[0]);
109 }
110 
PutUInt16MSBFirst(uint16_t value,pdfium::span<uint8_t,2> span)111 inline void PutUInt16MSBFirst(uint16_t value, pdfium::span<uint8_t, 2> span) {
112   span[0] = value >> 8;
113   span[1] = value & 0xff;
114 }
115 
PutUInt32MSBFirst(uint32_t value,pdfium::span<uint8_t,4> span)116 inline void PutUInt32MSBFirst(uint32_t value, pdfium::span<uint8_t, 4> span) {
117   span[0] = value >> 24;
118   span[1] = (value >> 16) & 0xff;
119   span[2] = (value >> 8) & 0xff;
120   span[3] = value & 0xff;
121 }
122 
PutUInt16LSBFirst(uint16_t value,pdfium::span<uint8_t,2> span)123 inline void PutUInt16LSBFirst(uint16_t value, pdfium::span<uint8_t, 2> span) {
124   span[1] = value >> 8;
125   span[0] = value & 0xff;
126 }
127 
PutUInt32LSBFirst(uint32_t value,pdfium::span<uint8_t,4> span)128 inline void PutUInt32LSBFirst(uint32_t value, pdfium::span<uint8_t, 4> span) {
129   span[3] = value >> 24;
130   span[2] = (value >> 16) & 0xff;
131   span[1] = (value >> 8) & 0xff;
132   span[0] = value & 0xff;
133 }
134 
135 }  // namespace fxcrt
136 
137 #endif  // CORE_FXCRT_BYTEORDER_H_
138