blob: 93210a37ee019579cd3151e88bb1b9217f49e8b1 [file] [log] [blame]
// 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.
#if defined(__APPLE__)
#include <libkern/OSByteOrder.h>
#define le16toh(x) OSSwapLittleToHostInt16(x)
#define le32toh(x) OSSwapLittleToHostInt32(x)
#define le64toh(x) OSSwapLittleToHostInt64(x)
#include <endian.h>
namespace fidlcat {
namespace internal {
// These are convenience functions for reading little endian (i.e., FIDL wire
// format encoded) bits.
template <typename T>
class LeToHost {
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) {
"MemoryFrom can only be used on pointers");
using U = typename std::conditional<std::is_integral<T>::value,
union {
U uval;
T tval;
} u;
u.uval = LeToHost<U>::le_to_host(reinterpret_cast<const U*>(bytes));
return u.tval;
} // namespace internal
} // namespace fidlcat