Flutter Engine
The Flutter Engine
endianness.h
Go to the documentation of this file.
1// Copyright 2013 The Flutter 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#ifndef FLUTTER_FML_ENDIANNESS_H_
6#define FLUTTER_FML_ENDIANNESS_H_
7
8#include <cstdint>
9#include <type_traits>
10#if defined(_MSC_VER)
11#include "intrin.h"
12#endif
13
14#include "flutter/fml/build_config.h"
15
16// Compiler intrinsics for flipping endianness.
17#if defined(_MSC_VER)
18#define FML_BYTESWAP_16(n) _byteswap_ushort(n)
19#define FML_BYTESWAP_32(n) _byteswap_ulong(n)
20#define FML_BYTESWAP_64(n) _byteswap_uint64(n)
21#else
22#define FML_BYTESWAP_16(n) __builtin_bswap16(n)
23#define FML_BYTESWAP_32(n) __builtin_bswap32(n)
24#define FML_BYTESWAP_64(n) __builtin_bswap64(n)
25#endif
26
27namespace fml {
28
29template <typename T>
31 : public std::
32 integral_constant<bool, std::is_integral_v<T> || std::is_enum_v<T>> {
33};
34template <typename T>
36
37/// @brief Flips the endianness of the given value.
38/// The given value must be an integral type of size 1, 2, 4, or 8.
39template <typename T, class = std::enable_if_t<kIsByteSwappableV<T>>>
40constexpr T ByteSwap(T n) {
41 if constexpr (sizeof(T) == 1) {
42 return n;
43 } else if constexpr (sizeof(T) == 2) {
44 return (T)FML_BYTESWAP_16((uint16_t)n);
45 } else if constexpr (sizeof(T) == 4) {
46 return (T)FML_BYTESWAP_32((uint32_t)n);
47 } else if constexpr (sizeof(T) == 8) {
48 return (T)FML_BYTESWAP_64((uint64_t)n);
49 } else {
50 static_assert(!sizeof(T), "Unsupported size");
51 }
52}
53
54/// @brief Convert a known big endian value to match the endianness of the
55/// current architecture. This is effectively a cross platform
56/// ntohl/ntohs (as network byte order is always Big Endian).
57/// The given value must be an integral type of size 1, 2, 4, or 8.
58template <typename T, class = std::enable_if_t<kIsByteSwappableV<T>>>
59constexpr T BigEndianToArch(T n) {
60#if FML_ARCH_CPU_LITTLE_ENDIAN
61 return ByteSwap<T>(n);
62#else
63 return n;
64#endif
65}
66
67/// @brief Convert a known little endian value to match the endianness of the
68/// current architecture.
69/// The given value must be an integral type of size 1, 2, 4, or 8.
70template <typename T, class = std::enable_if_t<kIsByteSwappableV<T>>>
71constexpr T LittleEndianToArch(T n) {
72#if !FML_ARCH_CPU_LITTLE_ENDIAN
73 return ByteSwap<T>(n);
74#else
75 return n;
76#endif
77}
78
79} // namespace fml
80
81#endif // FLUTTER_FML_ENDIANNESS_H_
#define FML_BYTESWAP_64(n)
Definition: endianness.h:24
#define FML_BYTESWAP_16(n)
Definition: endianness.h:22
#define FML_BYTESWAP_32(n)
Definition: endianness.h:23
Definition: ascii_trie.cc:9
constexpr bool kIsByteSwappableV
Definition: endianness.h:35
constexpr T BigEndianToArch(T n)
Convert a known big endian value to match the endianness of the current architecture....
Definition: endianness.h:59
constexpr T ByteSwap(T n)
Flips the endianness of the given value. The given value must be an integral type of size 1,...
Definition: endianness.h:40
constexpr T LittleEndianToArch(T n)
Convert a known little endian value to match the endianness of the current architecture....
Definition: endianness.h:71
Definition: ref_ptr.h:256
#define T
Definition: precompiler.cc:65