/work/obj-fuzz/dist/include/mozilla/EndianUtils.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
2 | | /* vim: set ts=8 sts=2 et sw=2 tw=80: */ |
3 | | /* This Source Code Form is subject to the terms of the Mozilla Public |
4 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
5 | | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
6 | | |
7 | | /* Functions for reading and writing integers in various endiannesses. */ |
8 | | |
9 | | /* |
10 | | * The classes LittleEndian and BigEndian expose static methods for |
11 | | * reading and writing 16-, 32-, and 64-bit signed and unsigned integers |
12 | | * in their respective endianness. The addresses read from or written |
13 | | * to may be misaligned (although misaligned accesses may incur |
14 | | * architecture-specific performance costs). The naming scheme is: |
15 | | * |
16 | | * {Little,Big}Endian::{read,write}{Uint,Int}<bitsize> |
17 | | * |
18 | | * For instance, LittleEndian::readInt32 will read a 32-bit signed |
19 | | * integer from memory in little endian format. Similarly, |
20 | | * BigEndian::writeUint16 will write a 16-bit unsigned integer to memory |
21 | | * in big-endian format. |
22 | | * |
23 | | * The class NativeEndian exposes methods for conversion of existing |
24 | | * data to and from the native endianness. These methods are intended |
25 | | * for cases where data needs to be transferred, serialized, etc. |
26 | | * swap{To,From}{Little,Big}Endian byteswap a single value if necessary. |
27 | | * Bulk conversion functions are also provided which optimize the |
28 | | * no-conversion-needed case: |
29 | | * |
30 | | * - copyAndSwap{To,From}{Little,Big}Endian; |
31 | | * - swap{To,From}{Little,Big}EndianInPlace. |
32 | | * |
33 | | * The *From* variants are intended to be used for reading data and the |
34 | | * *To* variants for writing data. |
35 | | * |
36 | | * Methods on NativeEndian work with integer data of any type. |
37 | | * Floating-point data is not supported. |
38 | | * |
39 | | * For clarity in networking code, "Network" may be used as a synonym |
40 | | * for "Big" in any of the above methods or class names. |
41 | | * |
42 | | * As an example, reading a file format header whose fields are stored |
43 | | * in big-endian format might look like: |
44 | | * |
45 | | * class ExampleHeader |
46 | | * { |
47 | | * private: |
48 | | * uint32_t mMagic; |
49 | | * uint32_t mLength; |
50 | | * uint32_t mTotalRecords; |
51 | | * uint64_t mChecksum; |
52 | | * |
53 | | * public: |
54 | | * ExampleHeader(const void* data) |
55 | | * { |
56 | | * const uint8_t* ptr = static_cast<const uint8_t*>(data); |
57 | | * mMagic = BigEndian::readUint32(ptr); ptr += sizeof(uint32_t); |
58 | | * mLength = BigEndian::readUint32(ptr); ptr += sizeof(uint32_t); |
59 | | * mTotalRecords = BigEndian::readUint32(ptr); ptr += sizeof(uint32_t); |
60 | | * mChecksum = BigEndian::readUint64(ptr); |
61 | | * } |
62 | | * ... |
63 | | * }; |
64 | | */ |
65 | | |
66 | | #ifndef mozilla_EndianUtils_h |
67 | | #define mozilla_EndianUtils_h |
68 | | |
69 | | #include "mozilla/Assertions.h" |
70 | | #include "mozilla/Attributes.h" |
71 | | #include "mozilla/Compiler.h" |
72 | | #include "mozilla/DebugOnly.h" |
73 | | #include "mozilla/TypeTraits.h" |
74 | | |
75 | | #include <stdint.h> |
76 | | #include <string.h> |
77 | | |
78 | | #if defined(_MSC_VER) |
79 | | # include <stdlib.h> |
80 | | # pragma intrinsic(_byteswap_ushort) |
81 | | # pragma intrinsic(_byteswap_ulong) |
82 | | # pragma intrinsic(_byteswap_uint64) |
83 | | #endif |
84 | | |
85 | | #if defined(_WIN64) |
86 | | # if defined(_M_X64) || defined(_M_AMD64) || defined(_AMD64_) |
87 | | # define MOZ_LITTLE_ENDIAN 1 |
88 | | # elif defined(_M_ARM64) |
89 | | # define MOZ_LITTLE_ENDIAN 1 |
90 | | # else |
91 | | # error "CPU type is unknown" |
92 | | # endif |
93 | | #elif defined(_WIN32) |
94 | | # if defined(_M_IX86) |
95 | | # define MOZ_LITTLE_ENDIAN 1 |
96 | | # elif defined(_M_ARM) |
97 | | # define MOZ_LITTLE_ENDIAN 1 |
98 | | # else |
99 | | # error "CPU type is unknown" |
100 | | # endif |
101 | | #elif defined(__APPLE__) || defined(__powerpc__) || defined(__ppc__) |
102 | | # if __LITTLE_ENDIAN__ |
103 | | # define MOZ_LITTLE_ENDIAN 1 |
104 | | # elif __BIG_ENDIAN__ |
105 | | # define MOZ_BIG_ENDIAN 1 |
106 | | # endif |
107 | | #elif defined(__GNUC__) && \ |
108 | | defined(__BYTE_ORDER__) && \ |
109 | | defined(__ORDER_LITTLE_ENDIAN__) && \ |
110 | | defined(__ORDER_BIG_ENDIAN__) |
111 | | /* |
112 | | * Some versions of GCC provide architecture-independent macros for |
113 | | * this. Yes, there are more than two values for __BYTE_ORDER__. |
114 | | */ |
115 | | # if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ |
116 | | # define MOZ_LITTLE_ENDIAN 1 |
117 | | # elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ |
118 | | # define MOZ_BIG_ENDIAN 1 |
119 | | # else |
120 | | # error "Can't handle mixed-endian architectures" |
121 | | # endif |
122 | | /* |
123 | | * We can't include useful headers like <endian.h> or <sys/isa_defs.h> |
124 | | * here because they're not present on all platforms. Instead we have |
125 | | * this big conditional that ideally will catch all the interesting |
126 | | * cases. |
127 | | */ |
128 | | #elif defined(__sparc) || defined(__sparc__) || \ |
129 | | defined(_POWER) || defined(__hppa) || \ |
130 | | defined(_MIPSEB) || defined(__ARMEB__) || \ |
131 | | defined(__s390__) || defined(__AARCH64EB__) || \ |
132 | | (defined(__sh__) && defined(__LITTLE_ENDIAN__)) || \ |
133 | | (defined(__ia64) && defined(__BIG_ENDIAN__)) |
134 | | # define MOZ_BIG_ENDIAN 1 |
135 | | #elif defined(__i386) || defined(__i386__) || \ |
136 | | defined(__x86_64) || defined(__x86_64__) || \ |
137 | | defined(_MIPSEL) || defined(__ARMEL__) || \ |
138 | | defined(__alpha__) || defined(__AARCH64EL__) || \ |
139 | | (defined(__sh__) && defined(__BIG_ENDIAN__)) || \ |
140 | | (defined(__ia64) && !defined(__BIG_ENDIAN__)) |
141 | | # define MOZ_LITTLE_ENDIAN 1 |
142 | | #endif |
143 | | |
144 | | #if MOZ_BIG_ENDIAN |
145 | | # define MOZ_LITTLE_ENDIAN 0 |
146 | | #elif MOZ_LITTLE_ENDIAN |
147 | 0 | # define MOZ_BIG_ENDIAN 0 |
148 | | #else |
149 | | # error "Cannot determine endianness" |
150 | | #endif |
151 | | |
152 | | #if defined(__clang__) |
153 | | # if __has_builtin(__builtin_bswap16) |
154 | 39 | # define MOZ_HAVE_BUILTIN_BYTESWAP16 __builtin_bswap16 |
155 | | # endif |
156 | | #elif defined(__GNUC__) |
157 | | # define MOZ_HAVE_BUILTIN_BYTESWAP16 __builtin_bswap16 |
158 | | #elif defined(_MSC_VER) |
159 | | # define MOZ_HAVE_BUILTIN_BYTESWAP16 _byteswap_ushort |
160 | | #endif |
161 | | |
162 | | namespace mozilla { |
163 | | |
164 | | namespace detail { |
165 | | |
166 | | /* |
167 | | * We need wrappers here because free functions with default template |
168 | | * arguments and/or partial specialization of function templates are not |
169 | | * supported by all the compilers we use. |
170 | | */ |
171 | | template<typename T, size_t Size = sizeof(T)> |
172 | | struct Swapper; |
173 | | |
174 | | template<typename T> |
175 | | struct Swapper<T, 2> |
176 | | { |
177 | | static T swap(T aValue) |
178 | 39 | { |
179 | 39 | #if defined(MOZ_HAVE_BUILTIN_BYTESWAP16) |
180 | 39 | return MOZ_HAVE_BUILTIN_BYTESWAP16(aValue); |
181 | | #else |
182 | | return T(((aValue & 0x00ff) << 8) | ((aValue & 0xff00) >> 8)); |
183 | | #endif |
184 | | } Unexecuted instantiation: mozilla::detail::Swapper<char16_t, 2ul>::swap(char16_t) mozilla::detail::Swapper<unsigned short, 2ul>::swap(unsigned short) Line | Count | Source | 178 | 39 | { | 179 | 39 | #if defined(MOZ_HAVE_BUILTIN_BYTESWAP16) | 180 | 39 | return MOZ_HAVE_BUILTIN_BYTESWAP16(aValue); | 181 | | #else | 182 | | return T(((aValue & 0x00ff) << 8) | ((aValue & 0xff00) >> 8)); | 183 | | #endif | 184 | | } |
Unexecuted instantiation: mozilla::detail::Swapper<short, 2ul>::swap(short) |
185 | | }; |
186 | | |
187 | | template<typename T> |
188 | | struct Swapper<T, 4> |
189 | | { |
190 | | static T swap(T aValue) |
191 | 3.99k | { |
192 | 3.99k | #if defined(__clang__) || defined(__GNUC__) |
193 | 3.99k | return T(__builtin_bswap32(aValue)); |
194 | | #elif defined(_MSC_VER) |
195 | | return T(_byteswap_ulong(aValue)); |
196 | | #else |
197 | | return T(((aValue & 0x000000ffU) << 24) | |
198 | | ((aValue & 0x0000ff00U) << 8) | |
199 | | ((aValue & 0x00ff0000U) >> 8) | |
200 | | ((aValue & 0xff000000U) >> 24)); |
201 | | #endif |
202 | | } mozilla::detail::Swapper<unsigned int, 4ul>::swap(unsigned int) Line | Count | Source | 191 | 3.99k | { | 192 | 3.99k | #if defined(__clang__) || defined(__GNUC__) | 193 | 3.99k | return T(__builtin_bswap32(aValue)); | 194 | | #elif defined(_MSC_VER) | 195 | | return T(_byteswap_ulong(aValue)); | 196 | | #else | 197 | | return T(((aValue & 0x000000ffU) << 24) | | 198 | | ((aValue & 0x0000ff00U) << 8) | | 199 | | ((aValue & 0x00ff0000U) >> 8) | | 200 | | ((aValue & 0xff000000U) >> 24)); | 201 | | #endif | 202 | | } |
Unexecuted instantiation: mozilla::detail::Swapper<int, 4ul>::swap(int) |
203 | | }; |
204 | | |
205 | | template<typename T> |
206 | | struct Swapper<T, 8> |
207 | | { |
208 | | static inline T swap(T aValue) |
209 | 0 | { |
210 | 0 | #if defined(__clang__) || defined(__GNUC__) |
211 | 0 | return T(__builtin_bswap64(aValue)); |
212 | | #elif defined(_MSC_VER) |
213 | | return T(_byteswap_uint64(aValue)); |
214 | | #else |
215 | | return T(((aValue & 0x00000000000000ffULL) << 56) | |
216 | | ((aValue & 0x000000000000ff00ULL) << 40) | |
217 | | ((aValue & 0x0000000000ff0000ULL) << 24) | |
218 | | ((aValue & 0x00000000ff000000ULL) << 8) | |
219 | | ((aValue & 0x000000ff00000000ULL) >> 8) | |
220 | | ((aValue & 0x0000ff0000000000ULL) >> 24) | |
221 | | ((aValue & 0x00ff000000000000ULL) >> 40) | |
222 | | ((aValue & 0xff00000000000000ULL) >> 56)); |
223 | | #endif |
224 | | } Unexecuted instantiation: mozilla::detail::Swapper<unsigned long, 8ul>::swap(unsigned long) Unexecuted instantiation: mozilla::detail::Swapper<long, 8ul>::swap(long) |
225 | | }; |
226 | | |
227 | | enum Endianness { Little, Big }; |
228 | | |
229 | | #if MOZ_BIG_ENDIAN |
230 | | # define MOZ_NATIVE_ENDIANNESS detail::Big |
231 | | #else |
232 | | # define MOZ_NATIVE_ENDIANNESS detail::Little |
233 | | #endif |
234 | | |
235 | | class EndianUtils |
236 | | { |
237 | | /** |
238 | | * Assert that the memory regions [aDest, aDest+aCount) and |
239 | | * [aSrc, aSrc+aCount] do not overlap. aCount is given in bytes. |
240 | | */ |
241 | | static void assertNoOverlap(const void* aDest, const void* aSrc, |
242 | | size_t aCount) |
243 | 0 | { |
244 | 0 | DebugOnly<const uint8_t*> byteDestPtr = static_cast<const uint8_t*>(aDest); |
245 | 0 | DebugOnly<const uint8_t*> byteSrcPtr = static_cast<const uint8_t*>(aSrc); |
246 | 0 | MOZ_ASSERT((byteDestPtr <= byteSrcPtr && |
247 | 0 | byteDestPtr + aCount <= byteSrcPtr) || |
248 | 0 | (byteSrcPtr <= byteDestPtr && |
249 | 0 | byteSrcPtr + aCount <= byteDestPtr)); |
250 | 0 | } Unexecuted instantiation: mozilla::detail::EndianUtils::assertNoOverlap(void const*, void const*, unsigned long) Unexecuted instantiation: mozilla::detail::EndianUtils::assertNoOverlap(void const*, void const*, unsigned long) |
251 | | |
252 | | template<typename T> |
253 | | static void assertAligned(T* aPtr) |
254 | 0 | { |
255 | 0 | MOZ_ASSERT((uintptr_t(aPtr) % sizeof(T)) == 0, "Unaligned pointer!"); |
256 | 0 | } Unexecuted instantiation: void mozilla::detail::EndianUtils::assertAligned<char16_t>(char16_t*) Unexecuted instantiation: void mozilla::detail::EndianUtils::assertAligned<char16_t const>(char16_t const*) Unexecuted instantiation: void mozilla::detail::EndianUtils::assertAligned<unsigned int>(unsigned int*) Unexecuted instantiation: void mozilla::detail::EndianUtils::assertAligned<unsigned short>(unsigned short*) Unexecuted instantiation: void mozilla::detail::EndianUtils::assertAligned<int>(int*) Unexecuted instantiation: void mozilla::detail::EndianUtils::assertAligned<unsigned int const>(unsigned int const*) Unexecuted instantiation: void mozilla::detail::EndianUtils::assertAligned<unsigned long>(unsigned long*) |
257 | | |
258 | | protected: |
259 | | /** |
260 | | * Return |aValue| converted from SourceEndian encoding to DestEndian |
261 | | * encoding. |
262 | | */ |
263 | | template<Endianness SourceEndian, Endianness DestEndian, typename T> |
264 | | static inline T maybeSwap(T aValue) |
265 | 9.17k | { |
266 | 9.17k | if (SourceEndian == DestEndian) { |
267 | 5.14k | return aValue; |
268 | 5.14k | } |
269 | 4.02k | return Swapper<T>::swap(aValue); |
270 | 4.02k | } unsigned int mozilla::detail::EndianUtils::maybeSwap<(mozilla::detail::Endianness)0, (mozilla::detail::Endianness)1, unsigned int>(unsigned int) Line | Count | Source | 265 | 3.99k | { | 266 | 3.99k | if (SourceEndian == DestEndian) { | 267 | 0 | return aValue; | 268 | 0 | } | 269 | 3.99k | return Swapper<T>::swap(aValue); | 270 | 3.99k | } |
unsigned int mozilla::detail::EndianUtils::maybeSwap<(mozilla::detail::Endianness)0, (mozilla::detail::Endianness)0, unsigned int>(unsigned int) Line | Count | Source | 265 | 4.45k | { | 266 | 4.45k | if (SourceEndian == DestEndian) { | 267 | 4.45k | return aValue; | 268 | 4.45k | } | 269 | 0 | return Swapper<T>::swap(aValue); | 270 | 0 | } |
unsigned short mozilla::detail::EndianUtils::maybeSwap<(mozilla::detail::Endianness)0, (mozilla::detail::Endianness)1, unsigned short>(unsigned short) Line | Count | Source | 265 | 39 | { | 266 | 39 | if (SourceEndian == DestEndian) { | 267 | 0 | return aValue; | 268 | 0 | } | 269 | 39 | return Swapper<T>::swap(aValue); | 270 | 39 | } |
Unexecuted instantiation: unsigned long mozilla::detail::EndianUtils::maybeSwap<(mozilla::detail::Endianness)0, (mozilla::detail::Endianness)1, unsigned long>(unsigned long) Unexecuted instantiation: char16_t mozilla::detail::EndianUtils::maybeSwap<(mozilla::detail::Endianness)0, (mozilla::detail::Endianness)1, char16_t>(char16_t) Unexecuted instantiation: unsigned short mozilla::detail::EndianUtils::maybeSwap<(mozilla::detail::Endianness)1, (mozilla::detail::Endianness)0, unsigned short>(unsigned short) Unexecuted instantiation: unsigned int mozilla::detail::EndianUtils::maybeSwap<(mozilla::detail::Endianness)1, (mozilla::detail::Endianness)0, unsigned int>(unsigned int) Unexecuted instantiation: unsigned long mozilla::detail::EndianUtils::maybeSwap<(mozilla::detail::Endianness)1, (mozilla::detail::Endianness)0, unsigned long>(unsigned long) Unexecuted instantiation: short mozilla::detail::EndianUtils::maybeSwap<(mozilla::detail::Endianness)0, (mozilla::detail::Endianness)1, short>(short) Unexecuted instantiation: short mozilla::detail::EndianUtils::maybeSwap<(mozilla::detail::Endianness)1, (mozilla::detail::Endianness)0, short>(short) Unexecuted instantiation: int mozilla::detail::EndianUtils::maybeSwap<(mozilla::detail::Endianness)0, (mozilla::detail::Endianness)1, int>(int) Unexecuted instantiation: int mozilla::detail::EndianUtils::maybeSwap<(mozilla::detail::Endianness)1, (mozilla::detail::Endianness)0, int>(int) Unexecuted instantiation: long mozilla::detail::EndianUtils::maybeSwap<(mozilla::detail::Endianness)1, (mozilla::detail::Endianness)0, long>(long) unsigned short mozilla::detail::EndianUtils::maybeSwap<(mozilla::detail::Endianness)0, (mozilla::detail::Endianness)0, unsigned short>(unsigned short) Line | Count | Source | 265 | 130 | { | 266 | 130 | if (SourceEndian == DestEndian) { | 267 | 130 | return aValue; | 268 | 130 | } | 269 | 0 | return Swapper<T>::swap(aValue); | 270 | 0 | } |
Unexecuted instantiation: char16_t mozilla::detail::EndianUtils::maybeSwap<(mozilla::detail::Endianness)1, (mozilla::detail::Endianness)0, char16_t>(char16_t) Unexecuted instantiation: short mozilla::detail::EndianUtils::maybeSwap<(mozilla::detail::Endianness)0, (mozilla::detail::Endianness)0, short>(short) Unexecuted instantiation: long mozilla::detail::EndianUtils::maybeSwap<(mozilla::detail::Endianness)0, (mozilla::detail::Endianness)0, long>(long) Unexecuted instantiation: long mozilla::detail::EndianUtils::maybeSwap<(mozilla::detail::Endianness)0, (mozilla::detail::Endianness)1, long>(long) unsigned long mozilla::detail::EndianUtils::maybeSwap<(mozilla::detail::Endianness)0, (mozilla::detail::Endianness)0, unsigned long>(unsigned long) Line | Count | Source | 265 | 560 | { | 266 | 560 | if (SourceEndian == DestEndian) { | 267 | 560 | return aValue; | 268 | 560 | } | 269 | 0 | return Swapper<T>::swap(aValue); | 270 | 0 | } |
Unexecuted instantiation: char16_t mozilla::detail::EndianUtils::maybeSwap<(mozilla::detail::Endianness)0, (mozilla::detail::Endianness)0, char16_t>(char16_t) |
271 | | |
272 | | /** |
273 | | * Convert |aCount| elements at |aPtr| from SourceEndian encoding to |
274 | | * DestEndian encoding. |
275 | | */ |
276 | | template<Endianness SourceEndian, Endianness DestEndian, typename T> |
277 | | static inline void maybeSwapInPlace(T* aPtr, size_t aCount) |
278 | 0 | { |
279 | 0 | assertAligned(aPtr); |
280 | 0 |
|
281 | 0 | if (SourceEndian == DestEndian) { |
282 | 0 | return; |
283 | 0 | } |
284 | 0 | for (size_t i = 0; i < aCount; i++) { |
285 | 0 | aPtr[i] = Swapper<T>::swap(aPtr[i]); |
286 | 0 | } |
287 | 0 | } Unexecuted instantiation: void mozilla::detail::EndianUtils::maybeSwapInPlace<(mozilla::detail::Endianness)0, (mozilla::detail::Endianness)1, char16_t>(char16_t*, unsigned long) Unexecuted instantiation: void mozilla::detail::EndianUtils::maybeSwapInPlace<(mozilla::detail::Endianness)0, (mozilla::detail::Endianness)0, unsigned int>(unsigned int*, unsigned long) Unexecuted instantiation: void mozilla::detail::EndianUtils::maybeSwapInPlace<(mozilla::detail::Endianness)0, (mozilla::detail::Endianness)0, unsigned short>(unsigned short*, unsigned long) Unexecuted instantiation: void mozilla::detail::EndianUtils::maybeSwapInPlace<(mozilla::detail::Endianness)0, (mozilla::detail::Endianness)0, int>(int*, unsigned long) Unexecuted instantiation: void mozilla::detail::EndianUtils::maybeSwapInPlace<(mozilla::detail::Endianness)0, (mozilla::detail::Endianness)0, unsigned long>(unsigned long*, unsigned long) |
288 | | |
289 | | /** |
290 | | * Write |aCount| elements to the unaligned address |aDest| in DestEndian |
291 | | * format, using elements found at |aSrc| in SourceEndian format. |
292 | | */ |
293 | | template<Endianness SourceEndian, Endianness DestEndian, typename T> |
294 | | static void copyAndSwapTo(void* aDest, const T* aSrc, size_t aCount) |
295 | 0 | { |
296 | 0 | assertNoOverlap(aDest, aSrc, aCount * sizeof(T)); |
297 | 0 | assertAligned(aSrc); |
298 | 0 |
|
299 | 0 | if (SourceEndian == DestEndian) { |
300 | 0 | memcpy(aDest, aSrc, aCount * sizeof(T)); |
301 | 0 | return; |
302 | 0 | } |
303 | 0 | |
304 | 0 | uint8_t* byteDestPtr = static_cast<uint8_t*>(aDest); |
305 | 0 | for (size_t i = 0; i < aCount; ++i) { |
306 | 0 | union |
307 | 0 | { |
308 | 0 | T mVal; |
309 | 0 | uint8_t mBuffer[sizeof(T)]; |
310 | 0 | } u; |
311 | 0 | u.mVal = maybeSwap<SourceEndian, DestEndian>(aSrc[i]); |
312 | 0 | memcpy(byteDestPtr, u.mBuffer, sizeof(T)); |
313 | 0 | byteDestPtr += sizeof(T); |
314 | 0 | } |
315 | 0 | } Unexecuted instantiation: void mozilla::detail::EndianUtils::copyAndSwapTo<(mozilla::detail::Endianness)0, (mozilla::detail::Endianness)1, char16_t>(void*, char16_t const*, unsigned long) Unexecuted instantiation: void mozilla::detail::EndianUtils::copyAndSwapTo<(mozilla::detail::Endianness)0, (mozilla::detail::Endianness)0, unsigned int>(void*, unsigned int const*, unsigned long) Unexecuted instantiation: void mozilla::detail::EndianUtils::copyAndSwapTo<(mozilla::detail::Endianness)0, (mozilla::detail::Endianness)1, unsigned int>(void*, unsigned int const*, unsigned long) Unexecuted instantiation: void mozilla::detail::EndianUtils::copyAndSwapTo<(mozilla::detail::Endianness)0, (mozilla::detail::Endianness)0, char16_t>(void*, char16_t const*, unsigned long) |
316 | | |
317 | | /** |
318 | | * Write |aCount| elements to |aDest| in DestEndian format, using elements |
319 | | * found at the unaligned address |aSrc| in SourceEndian format. |
320 | | */ |
321 | | template<Endianness SourceEndian, Endianness DestEndian, typename T> |
322 | | static void copyAndSwapFrom(T* aDest, const void* aSrc, size_t aCount) |
323 | 0 | { |
324 | 0 | assertNoOverlap(aDest, aSrc, aCount * sizeof(T)); |
325 | 0 | assertAligned(aDest); |
326 | 0 |
|
327 | 0 | if (SourceEndian == DestEndian) { |
328 | 0 | memcpy(aDest, aSrc, aCount * sizeof(T)); |
329 | 0 | return; |
330 | 0 | } |
331 | 0 | |
332 | 0 | const uint8_t* byteSrcPtr = static_cast<const uint8_t*>(aSrc); |
333 | 0 | for (size_t i = 0; i < aCount; ++i) { |
334 | 0 | union |
335 | 0 | { |
336 | 0 | T mVal; |
337 | 0 | uint8_t mBuffer[sizeof(T)]; |
338 | 0 | } u; |
339 | 0 | memcpy(u.mBuffer, byteSrcPtr, sizeof(T)); |
340 | 0 | aDest[i] = maybeSwap<SourceEndian, DestEndian>(u.mVal); |
341 | 0 | byteSrcPtr += sizeof(T); |
342 | 0 | } |
343 | 0 | } Unexecuted instantiation: void mozilla::detail::EndianUtils::copyAndSwapFrom<(mozilla::detail::Endianness)1, (mozilla::detail::Endianness)0, char16_t>(char16_t*, void const*, unsigned long) Unexecuted instantiation: void mozilla::detail::EndianUtils::copyAndSwapFrom<(mozilla::detail::Endianness)0, (mozilla::detail::Endianness)0, char16_t>(char16_t*, void const*, unsigned long) |
344 | | }; |
345 | | |
346 | | template<Endianness ThisEndian> |
347 | | class Endian : private EndianUtils |
348 | | { |
349 | | protected: |
350 | | /** Read a uint16_t in ThisEndian endianness from |aPtr| and return it. */ |
351 | | static MOZ_MUST_USE uint16_t readUint16(const void* aPtr) |
352 | 0 | { |
353 | 0 | return read<uint16_t>(aPtr); |
354 | 0 | } Unexecuted instantiation: mozilla::detail::Endian<(mozilla::detail::Endianness)1>::readUint16(void const*) Unexecuted instantiation: mozilla::detail::Endian<(mozilla::detail::Endianness)0>::readUint16(void const*) |
355 | | |
356 | | /** Read a uint32_t in ThisEndian endianness from |aPtr| and return it. */ |
357 | | static MOZ_MUST_USE uint32_t readUint32(const void* aPtr) |
358 | 0 | { |
359 | 0 | return read<uint32_t>(aPtr); |
360 | 0 | } Unexecuted instantiation: mozilla::detail::Endian<(mozilla::detail::Endianness)0>::readUint32(void const*) Unexecuted instantiation: mozilla::detail::Endian<(mozilla::detail::Endianness)1>::readUint32(void const*) |
361 | | |
362 | | /** Read a uint64_t in ThisEndian endianness from |aPtr| and return it. */ |
363 | | static MOZ_MUST_USE uint64_t readUint64(const void* aPtr) |
364 | 0 | { |
365 | 0 | return read<uint64_t>(aPtr); |
366 | 0 | } Unexecuted instantiation: mozilla::detail::Endian<(mozilla::detail::Endianness)1>::readUint64(void const*) Unexecuted instantiation: mozilla::detail::Endian<(mozilla::detail::Endianness)0>::readUint64(void const*) |
367 | | |
368 | | /** Read a uintptr_t in ThisEndian endianness from |aPtr| and return it. */ |
369 | | static MOZ_MUST_USE uintptr_t readUintptr(const void* aPtr) |
370 | | { |
371 | | return read<uintptr_t>(aPtr); |
372 | | } |
373 | | |
374 | | /** Read an int16_t in ThisEndian endianness from |aPtr| and return it. */ |
375 | | static MOZ_MUST_USE int16_t readInt16(const void* aPtr) |
376 | 0 | { |
377 | 0 | return read<int16_t>(aPtr); |
378 | 0 | } |
379 | | |
380 | | /** Read an int32_t in ThisEndian endianness from |aPtr| and return it. */ |
381 | | static MOZ_MUST_USE int32_t readInt32(const void* aPtr) |
382 | 0 | { |
383 | 0 | return read<uint32_t>(aPtr); |
384 | 0 | } |
385 | | |
386 | | /** Read an int64_t in ThisEndian endianness from |aPtr| and return it. */ |
387 | | static MOZ_MUST_USE int64_t readInt64(const void* aPtr) |
388 | 0 | { |
389 | 0 | return read<int64_t>(aPtr); |
390 | 0 | } Unexecuted instantiation: mozilla::detail::Endian<(mozilla::detail::Endianness)1>::readInt64(void const*) Unexecuted instantiation: mozilla::detail::Endian<(mozilla::detail::Endianness)0>::readInt64(void const*) |
391 | | |
392 | | /** Read an intptr_t in ThisEndian endianness from |aPtr| and return it. */ |
393 | | static MOZ_MUST_USE intptr_t readIntptr(const void* aPtr) |
394 | | { |
395 | | return read<intptr_t>(aPtr); |
396 | | } |
397 | | |
398 | | /** Write |aValue| to |aPtr| using ThisEndian endianness. */ |
399 | | static void writeUint16(void* aPtr, uint16_t aValue) |
400 | 130 | { |
401 | 130 | write(aPtr, aValue); |
402 | 130 | } Unexecuted instantiation: mozilla::detail::Endian<(mozilla::detail::Endianness)1>::writeUint16(void*, unsigned short) mozilla::detail::Endian<(mozilla::detail::Endianness)0>::writeUint16(void*, unsigned short) Line | Count | Source | 400 | 130 | { | 401 | 130 | write(aPtr, aValue); | 402 | 130 | } |
|
403 | | |
404 | | /** Write |aValue| to |aPtr| using ThisEndian endianness. */ |
405 | | static void writeUint32(void* aPtr, uint32_t aValue) |
406 | 8.44k | { |
407 | 8.44k | write(aPtr, aValue); |
408 | 8.44k | } mozilla::detail::Endian<(mozilla::detail::Endianness)0>::writeUint32(void*, unsigned int) Line | Count | Source | 406 | 4.45k | { | 407 | 4.45k | write(aPtr, aValue); | 408 | 4.45k | } |
mozilla::detail::Endian<(mozilla::detail::Endianness)1>::writeUint32(void*, unsigned int) Line | Count | Source | 406 | 3.99k | { | 407 | 3.99k | write(aPtr, aValue); | 408 | 3.99k | } |
|
409 | | |
410 | | /** Write |aValue| to |aPtr| using ThisEndian endianness. */ |
411 | | static void writeUint64(void* aPtr, uint64_t aValue) |
412 | 6 | { |
413 | 6 | write(aPtr, aValue); |
414 | 6 | } Unexecuted instantiation: mozilla::detail::Endian<(mozilla::detail::Endianness)1>::writeUint64(void*, unsigned long) mozilla::detail::Endian<(mozilla::detail::Endianness)0>::writeUint64(void*, unsigned long) Line | Count | Source | 412 | 6 | { | 413 | 6 | write(aPtr, aValue); | 414 | 6 | } |
|
415 | | |
416 | | /** Write |aValue| to |aPtr| using ThisEndian endianness. */ |
417 | | static void writeUintptr(void* aPtr, uintptr_t aValue) |
418 | 530 | { |
419 | 530 | write(aPtr, aValue); |
420 | 530 | } |
421 | | |
422 | | /** Write |aValue| to |aPtr| using ThisEndian endianness. */ |
423 | | static void writeInt16(void* aPtr, int16_t aValue) |
424 | | { |
425 | | write(aPtr, aValue); |
426 | | } |
427 | | |
428 | | /** Write |aValue| to |aPtr| using ThisEndian endianness. */ |
429 | | static void writeInt32(void* aPtr, int32_t aValue) |
430 | 0 | { |
431 | 0 | write(aPtr, aValue); |
432 | 0 | } |
433 | | |
434 | | /** Write |aValue| to |aPtr| using ThisEndian endianness. */ |
435 | | static void writeInt64(void* aPtr, int64_t aValue) |
436 | 0 | { |
437 | 0 | write(aPtr, aValue); |
438 | 0 | } |
439 | | |
440 | | /** Write |aValue| to |aPtr| using ThisEndian endianness. */ |
441 | | static void writeIntptr(void* aPtr, intptr_t aValue) |
442 | | { |
443 | | write(aPtr, aValue); |
444 | | } |
445 | | |
446 | | /* |
447 | | * Converts a value of type T to little-endian format. |
448 | | * |
449 | | * This function is intended for cases where you have data in your |
450 | | * native-endian format and you need it to appear in little-endian |
451 | | * format for transmission. |
452 | | */ |
453 | | template<typename T> |
454 | | MOZ_MUST_USE static T swapToLittleEndian(T aValue) |
455 | 6 | { |
456 | 6 | return maybeSwap<ThisEndian, Little>(aValue); |
457 | 6 | } Unexecuted instantiation: unsigned int mozilla::detail::Endian<(mozilla::detail::Endianness)0>::swapToLittleEndian<unsigned int>(unsigned int) unsigned long mozilla::detail::Endian<(mozilla::detail::Endianness)0>::swapToLittleEndian<unsigned long>(unsigned long) Line | Count | Source | 455 | 6 | { | 456 | 6 | return maybeSwap<ThisEndian, Little>(aValue); | 457 | 6 | } |
Unexecuted instantiation: long mozilla::detail::Endian<(mozilla::detail::Endianness)0>::swapToLittleEndian<long>(long) Unexecuted instantiation: unsigned short mozilla::detail::Endian<(mozilla::detail::Endianness)0>::swapToLittleEndian<unsigned short>(unsigned short) |
458 | | |
459 | | /* |
460 | | * Copies |aCount| values of type T starting at |aSrc| to |aDest|, converting |
461 | | * them to little-endian format if ThisEndian is Big. |
462 | | * As with memcpy, |aDest| and |aSrc| must not overlap. |
463 | | */ |
464 | | template<typename T> |
465 | | static void copyAndSwapToLittleEndian(void* aDest, const T* aSrc, |
466 | | size_t aCount) |
467 | 0 | { |
468 | 0 | copyAndSwapTo<ThisEndian, Little>(aDest, aSrc, aCount); |
469 | 0 | } Unexecuted instantiation: void mozilla::detail::Endian<(mozilla::detail::Endianness)0>::copyAndSwapToLittleEndian<unsigned int>(void*, unsigned int const*, unsigned long) Unexecuted instantiation: void mozilla::detail::Endian<(mozilla::detail::Endianness)0>::copyAndSwapToLittleEndian<char16_t>(void*, char16_t const*, unsigned long) |
470 | | |
471 | | /* |
472 | | * Likewise, but converts values in place. |
473 | | */ |
474 | | template<typename T> |
475 | | static void swapToLittleEndianInPlace(T* aPtr, size_t aCount) |
476 | 0 | { |
477 | 0 | maybeSwapInPlace<ThisEndian, Little>(aPtr, aCount); |
478 | 0 | } Unexecuted instantiation: void mozilla::detail::Endian<(mozilla::detail::Endianness)0>::swapToLittleEndianInPlace<unsigned int>(unsigned int*, unsigned long) Unexecuted instantiation: void mozilla::detail::Endian<(mozilla::detail::Endianness)0>::swapToLittleEndianInPlace<unsigned short>(unsigned short*, unsigned long) Unexecuted instantiation: void mozilla::detail::Endian<(mozilla::detail::Endianness)0>::swapToLittleEndianInPlace<int>(int*, unsigned long) |
479 | | |
480 | | /* |
481 | | * Converts a value of type T to big-endian format. |
482 | | */ |
483 | | template<typename T> |
484 | | MOZ_MUST_USE static T swapToBigEndian(T aValue) |
485 | 39 | { |
486 | 39 | return maybeSwap<ThisEndian, Big>(aValue); |
487 | 39 | } Unexecuted instantiation: unsigned int mozilla::detail::Endian<(mozilla::detail::Endianness)0>::swapToBigEndian<unsigned int>(unsigned int) unsigned short mozilla::detail::Endian<(mozilla::detail::Endianness)0>::swapToBigEndian<unsigned short>(unsigned short) Line | Count | Source | 485 | 39 | { | 486 | 39 | return maybeSwap<ThisEndian, Big>(aValue); | 487 | 39 | } |
Unexecuted instantiation: unsigned long mozilla::detail::Endian<(mozilla::detail::Endianness)0>::swapToBigEndian<unsigned long>(unsigned long) Unexecuted instantiation: short mozilla::detail::Endian<(mozilla::detail::Endianness)0>::swapToBigEndian<short>(short) Unexecuted instantiation: int mozilla::detail::Endian<(mozilla::detail::Endianness)0>::swapToBigEndian<int>(int) |
488 | | |
489 | | /* |
490 | | * Copies |aCount| values of type T starting at |aSrc| to |aDest|, converting |
491 | | * them to big-endian format if ThisEndian is Little. |
492 | | * As with memcpy, |aDest| and |aSrc| must not overlap. |
493 | | */ |
494 | | template<typename T> |
495 | | static void copyAndSwapToBigEndian(void* aDest, const T* aSrc, |
496 | | size_t aCount) |
497 | 0 | { |
498 | 0 | copyAndSwapTo<ThisEndian, Big>(aDest, aSrc, aCount); |
499 | 0 | } Unexecuted instantiation: void mozilla::detail::Endian<(mozilla::detail::Endianness)0>::copyAndSwapToBigEndian<char16_t>(void*, char16_t const*, unsigned long) Unexecuted instantiation: void mozilla::detail::Endian<(mozilla::detail::Endianness)0>::copyAndSwapToBigEndian<unsigned int>(void*, unsigned int const*, unsigned long) |
500 | | |
501 | | /* |
502 | | * Likewise, but converts values in place. |
503 | | */ |
504 | | template<typename T> |
505 | | static void swapToBigEndianInPlace(T* aPtr, size_t aCount) |
506 | 0 | { |
507 | 0 | maybeSwapInPlace<ThisEndian, Big>(aPtr, aCount); |
508 | 0 | } |
509 | | |
510 | | /* |
511 | | * Synonyms for the big-endian functions, for better readability |
512 | | * in network code. |
513 | | */ |
514 | | |
515 | | template<typename T> |
516 | | MOZ_MUST_USE static T swapToNetworkOrder(T aValue) |
517 | | { |
518 | | return swapToBigEndian(aValue); |
519 | | } |
520 | | |
521 | | template<typename T> |
522 | | static void |
523 | | copyAndSwapToNetworkOrder(void* aDest, const T* aSrc, size_t aCount) |
524 | | { |
525 | | copyAndSwapToBigEndian(aDest, aSrc, aCount); |
526 | | } |
527 | | |
528 | | template<typename T> |
529 | | static void |
530 | | swapToNetworkOrderInPlace(T* aPtr, size_t aCount) |
531 | | { |
532 | | swapToBigEndianInPlace(aPtr, aCount); |
533 | | } |
534 | | |
535 | | /* |
536 | | * Converts a value of type T from little-endian format. |
537 | | */ |
538 | | template<typename T> |
539 | | MOZ_MUST_USE static T swapFromLittleEndian(T aValue) |
540 | 18 | { |
541 | 18 | return maybeSwap<Little, ThisEndian>(aValue); |
542 | 18 | } Unexecuted instantiation: unsigned int mozilla::detail::Endian<(mozilla::detail::Endianness)0>::swapFromLittleEndian<unsigned int>(unsigned int) unsigned long mozilla::detail::Endian<(mozilla::detail::Endianness)0>::swapFromLittleEndian<unsigned long>(unsigned long) Line | Count | Source | 540 | 18 | { | 541 | 18 | return maybeSwap<Little, ThisEndian>(aValue); | 542 | 18 | } |
Unexecuted instantiation: long mozilla::detail::Endian<(mozilla::detail::Endianness)0>::swapFromLittleEndian<long>(long) |
543 | | |
544 | | /* |
545 | | * Copies |aCount| values of type T starting at |aSrc| to |aDest|, converting |
546 | | * them to little-endian format if ThisEndian is Big. |
547 | | * As with memcpy, |aDest| and |aSrc| must not overlap. |
548 | | */ |
549 | | template<typename T> |
550 | | static void copyAndSwapFromLittleEndian(T* aDest, const void* aSrc, |
551 | | size_t aCount) |
552 | 0 | { |
553 | 0 | copyAndSwapFrom<Little, ThisEndian>(aDest, aSrc, aCount); |
554 | 0 | } |
555 | | |
556 | | /* |
557 | | * Likewise, but converts values in place. |
558 | | */ |
559 | | template<typename T> |
560 | | static void swapFromLittleEndianInPlace(T* aPtr, size_t aCount) |
561 | 0 | { |
562 | 0 | maybeSwapInPlace<Little, ThisEndian>(aPtr, aCount); |
563 | 0 | } Unexecuted instantiation: void mozilla::detail::Endian<(mozilla::detail::Endianness)0>::swapFromLittleEndianInPlace<unsigned short>(unsigned short*, unsigned long) Unexecuted instantiation: void mozilla::detail::Endian<(mozilla::detail::Endianness)0>::swapFromLittleEndianInPlace<unsigned int>(unsigned int*, unsigned long) Unexecuted instantiation: void mozilla::detail::Endian<(mozilla::detail::Endianness)0>::swapFromLittleEndianInPlace<unsigned long>(unsigned long*, unsigned long) |
564 | | |
565 | | /* |
566 | | * Converts a value of type T from big-endian format. |
567 | | */ |
568 | | template<typename T> |
569 | | MOZ_MUST_USE static T swapFromBigEndian(T aValue) |
570 | 0 | { |
571 | 0 | return maybeSwap<Big, ThisEndian>(aValue); |
572 | 0 | } Unexecuted instantiation: unsigned short mozilla::detail::Endian<(mozilla::detail::Endianness)0>::swapFromBigEndian<unsigned short>(unsigned short) Unexecuted instantiation: unsigned int mozilla::detail::Endian<(mozilla::detail::Endianness)0>::swapFromBigEndian<unsigned int>(unsigned int) Unexecuted instantiation: unsigned long mozilla::detail::Endian<(mozilla::detail::Endianness)0>::swapFromBigEndian<unsigned long>(unsigned long) Unexecuted instantiation: short mozilla::detail::Endian<(mozilla::detail::Endianness)0>::swapFromBigEndian<short>(short) Unexecuted instantiation: int mozilla::detail::Endian<(mozilla::detail::Endianness)0>::swapFromBigEndian<int>(int) |
573 | | |
574 | | /* |
575 | | * Copies |aCount| values of type T starting at |aSrc| to |aDest|, converting |
576 | | * them to big-endian format if ThisEndian is Little. |
577 | | * As with memcpy, |aDest| and |aSrc| must not overlap. |
578 | | */ |
579 | | template<typename T> |
580 | | static void copyAndSwapFromBigEndian(T* aDest, const void* aSrc, |
581 | | size_t aCount) |
582 | 0 | { |
583 | 0 | copyAndSwapFrom<Big, ThisEndian>(aDest, aSrc, aCount); |
584 | 0 | } |
585 | | |
586 | | /* |
587 | | * Likewise, but converts values in place. |
588 | | */ |
589 | | template<typename T> |
590 | | static void swapFromBigEndianInPlace(T* aPtr, size_t aCount) |
591 | | { |
592 | | maybeSwapInPlace<Big, ThisEndian>(aPtr, aCount); |
593 | | } |
594 | | |
595 | | /* |
596 | | * Synonyms for the big-endian functions, for better readability |
597 | | * in network code. |
598 | | */ |
599 | | template<typename T> |
600 | | MOZ_MUST_USE static T swapFromNetworkOrder(T aValue) |
601 | | { |
602 | | return swapFromBigEndian(aValue); |
603 | | } |
604 | | |
605 | | template<typename T> |
606 | | static void copyAndSwapFromNetworkOrder(T* aDest, const void* aSrc, |
607 | | size_t aCount) |
608 | | { |
609 | | copyAndSwapFromBigEndian(aDest, aSrc, aCount); |
610 | | } |
611 | | |
612 | | template<typename T> |
613 | | static void swapFromNetworkOrderInPlace(T* aPtr, size_t aCount) |
614 | | { |
615 | | swapFromBigEndianInPlace(aPtr, aCount); |
616 | | } |
617 | | |
618 | | private: |
619 | | /** |
620 | | * Read a value of type T, encoded in endianness ThisEndian from |aPtr|. |
621 | | * Return that value encoded in native endianness. |
622 | | */ |
623 | | template<typename T> |
624 | | static T read(const void* aPtr) |
625 | 0 | { |
626 | 0 | union |
627 | 0 | { |
628 | 0 | T mVal; |
629 | 0 | uint8_t mBuffer[sizeof(T)]; |
630 | 0 | } u; |
631 | 0 | memcpy(u.mBuffer, aPtr, sizeof(T)); |
632 | 0 | return maybeSwap<ThisEndian, MOZ_NATIVE_ENDIANNESS>(u.mVal); |
633 | 0 | } Unexecuted instantiation: unsigned int mozilla::detail::Endian<(mozilla::detail::Endianness)0>::read<unsigned int>(void const*) Unexecuted instantiation: unsigned short mozilla::detail::Endian<(mozilla::detail::Endianness)1>::read<unsigned short>(void const*) Unexecuted instantiation: unsigned int mozilla::detail::Endian<(mozilla::detail::Endianness)1>::read<unsigned int>(void const*) Unexecuted instantiation: unsigned long mozilla::detail::Endian<(mozilla::detail::Endianness)1>::read<unsigned long>(void const*) Unexecuted instantiation: long mozilla::detail::Endian<(mozilla::detail::Endianness)1>::read<long>(void const*) Unexecuted instantiation: unsigned short mozilla::detail::Endian<(mozilla::detail::Endianness)0>::read<unsigned short>(void const*) Unexecuted instantiation: short mozilla::detail::Endian<(mozilla::detail::Endianness)0>::read<short>(void const*) Unexecuted instantiation: long mozilla::detail::Endian<(mozilla::detail::Endianness)0>::read<long>(void const*) Unexecuted instantiation: unsigned long mozilla::detail::Endian<(mozilla::detail::Endianness)0>::read<unsigned long>(void const*) |
634 | | |
635 | | /** |
636 | | * Write a value of type T, in native endianness, to |aPtr|, in ThisEndian |
637 | | * endianness. |
638 | | */ |
639 | | template<typename T> |
640 | | static void write(void* aPtr, T aValue) |
641 | 9.11k | { |
642 | 9.11k | T tmp = maybeSwap<MOZ_NATIVE_ENDIANNESS, ThisEndian>(aValue); |
643 | 9.11k | memcpy(aPtr, &tmp, sizeof(T)); |
644 | 9.11k | } void mozilla::detail::Endian<(mozilla::detail::Endianness)0>::write<unsigned int>(void*, unsigned int) Line | Count | Source | 641 | 4.45k | { | 642 | 4.45k | T tmp = maybeSwap<MOZ_NATIVE_ENDIANNESS, ThisEndian>(aValue); | 643 | 4.45k | memcpy(aPtr, &tmp, sizeof(T)); | 644 | 4.45k | } |
void mozilla::detail::Endian<(mozilla::detail::Endianness)1>::write<unsigned int>(void*, unsigned int) Line | Count | Source | 641 | 3.99k | { | 642 | 3.99k | T tmp = maybeSwap<MOZ_NATIVE_ENDIANNESS, ThisEndian>(aValue); | 643 | 3.99k | memcpy(aPtr, &tmp, sizeof(T)); | 644 | 3.99k | } |
Unexecuted instantiation: void mozilla::detail::Endian<(mozilla::detail::Endianness)1>::write<unsigned long>(void*, unsigned long) Unexecuted instantiation: void mozilla::detail::Endian<(mozilla::detail::Endianness)1>::write<unsigned short>(void*, unsigned short) void mozilla::detail::Endian<(mozilla::detail::Endianness)0>::write<unsigned short>(void*, unsigned short) Line | Count | Source | 641 | 130 | { | 642 | 130 | T tmp = maybeSwap<MOZ_NATIVE_ENDIANNESS, ThisEndian>(aValue); | 643 | 130 | memcpy(aPtr, &tmp, sizeof(T)); | 644 | 130 | } |
Unexecuted instantiation: void mozilla::detail::Endian<(mozilla::detail::Endianness)1>::write<int>(void*, int) Unexecuted instantiation: void mozilla::detail::Endian<(mozilla::detail::Endianness)1>::write<long>(void*, long) void mozilla::detail::Endian<(mozilla::detail::Endianness)0>::write<unsigned long>(void*, unsigned long) Line | Count | Source | 641 | 536 | { | 642 | 536 | T tmp = maybeSwap<MOZ_NATIVE_ENDIANNESS, ThisEndian>(aValue); | 643 | 536 | memcpy(aPtr, &tmp, sizeof(T)); | 644 | 536 | } |
|
645 | | |
646 | | Endian() = delete; |
647 | | Endian(const Endian& aTther) = delete; |
648 | | void operator=(const Endian& aOther) = delete; |
649 | | }; |
650 | | |
651 | | template<Endianness ThisEndian> |
652 | | class EndianReadWrite : public Endian<ThisEndian> |
653 | | { |
654 | | private: |
655 | | typedef Endian<ThisEndian> super; |
656 | | |
657 | | public: |
658 | | using super::readUint16; |
659 | | using super::readUint32; |
660 | | using super::readUint64; |
661 | | using super::readUintptr; |
662 | | using super::readInt16; |
663 | | using super::readInt32; |
664 | | using super::readInt64; |
665 | | using super::readIntptr; |
666 | | using super::writeUint16; |
667 | | using super::writeUint32; |
668 | | using super::writeUint64; |
669 | | using super::writeUintptr; |
670 | | using super::writeInt16; |
671 | | using super::writeInt32; |
672 | | using super::writeInt64; |
673 | | using super::writeIntptr; |
674 | | }; |
675 | | |
676 | | } /* namespace detail */ |
677 | | |
678 | | class LittleEndian final : public detail::EndianReadWrite<detail::Little> |
679 | | {}; |
680 | | |
681 | | class BigEndian final : public detail::EndianReadWrite<detail::Big> |
682 | | {}; |
683 | | |
684 | | typedef BigEndian NetworkEndian; |
685 | | |
686 | | class NativeEndian final : public detail::Endian<MOZ_NATIVE_ENDIANNESS> |
687 | | { |
688 | | private: |
689 | | typedef detail::Endian<MOZ_NATIVE_ENDIANNESS> super; |
690 | | |
691 | | public: |
692 | | /* |
693 | | * These functions are intended for cases where you have data in your |
694 | | * native-endian format and you need the data to appear in the appropriate |
695 | | * endianness for transmission, serialization, etc. |
696 | | */ |
697 | | using super::swapToLittleEndian; |
698 | | using super::copyAndSwapToLittleEndian; |
699 | | using super::swapToLittleEndianInPlace; |
700 | | using super::swapToBigEndian; |
701 | | using super::copyAndSwapToBigEndian; |
702 | | using super::swapToBigEndianInPlace; |
703 | | using super::swapToNetworkOrder; |
704 | | using super::copyAndSwapToNetworkOrder; |
705 | | using super::swapToNetworkOrderInPlace; |
706 | | |
707 | | /* |
708 | | * These functions are intended for cases where you have data in the |
709 | | * given endianness (e.g. reading from disk or a file-format) and you |
710 | | * need the data to appear in native-endian format for processing. |
711 | | */ |
712 | | using super::swapFromLittleEndian; |
713 | | using super::copyAndSwapFromLittleEndian; |
714 | | using super::swapFromLittleEndianInPlace; |
715 | | using super::swapFromBigEndian; |
716 | | using super::copyAndSwapFromBigEndian; |
717 | | using super::swapFromBigEndianInPlace; |
718 | | using super::swapFromNetworkOrder; |
719 | | using super::copyAndSwapFromNetworkOrder; |
720 | | using super::swapFromNetworkOrderInPlace; |
721 | | }; |
722 | | |
723 | | #undef MOZ_NATIVE_ENDIANNESS |
724 | | |
725 | | } /* namespace mozilla */ |
726 | | |
727 | | #endif /* mozilla_EndianUtils_h */ |