| // Copyright 2019 The Fuchsia Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| #ifndef SRC_LIB_FIDL_CODEC_MEMORY_HELPERS_H_ | |
| #define SRC_LIB_FIDL_CODEC_MEMORY_HELPERS_H_ | |
| #if defined(__APPLE__) | |
| #include <libkern/OSByteOrder.h> | |
| #define le16toh(x) OSSwapLittleToHostInt16(x) | |
| #define le32toh(x) OSSwapLittleToHostInt32(x) | |
| #define le64toh(x) OSSwapLittleToHostInt64(x) | |
| #else | |
| #include <endian.h> | |
| #endif | |
| namespace fidl_codec { | |
| namespace internal { | |
| // These are convenience functions for reading little endian (i.e., FIDL wire | |
| // format encoded) bits. | |
| template <typename T> | |
| class LeToHost { | |
| public: | |
| static T le_to_host(const T* ts); | |
| }; | |
| template <typename T> | |
| T LeToHost<T>::le_to_host(const T* bytes) { | |
| if constexpr (std::is_same<T, uint8_t>::value) { | |
| return *bytes; | |
| } else if constexpr (std::is_same<T, uint16_t>::value) { | |
| return le16toh(*bytes); | |
| } else if constexpr (std::is_same<T, uint32_t>::value) { | |
| return le32toh(*bytes); | |
| } else if constexpr (std::is_same<T, uint64_t>::value) { | |
| return le64toh(*bytes); | |
| } else if constexpr (std::is_same<T, uintptr_t>::value && sizeof(T) == sizeof(uint64_t)) { | |
| // NB: On Darwin, uintptr_t and uint64_t are different things. | |
| return le64toh(*bytes); | |
| } | |
| } | |
| template <typename T> | |
| struct GetUnsigned { | |
| using type = typename std::conditional<std::is_same<float, T>::value, uint32_t, uint64_t>::type; | |
| }; | |
| template <typename T, typename P> | |
| T MemoryFrom(P bytes) { | |
| static_assert(std::is_pointer<P>::value, "MemoryFrom can only be used on pointers"); | |
| using U = typename std::conditional<std::is_integral<T>::value, std::make_unsigned<T>, | |
| GetUnsigned<T>>::type::type; | |
| union { | |
| U uval; | |
| T tval; | |
| } u; | |
| u.uval = LeToHost<U>::le_to_host(reinterpret_cast<const U*>(bytes)); | |
| return u.tval; | |
| } | |
| } // namespace internal | |
| } // namespace fidl_codec | |
| #endif // SRC_LIB_FIDL_CODEC_MEMORY_HELPERS_H_ |