chromium/third_party/openscreen/src/util/big_endian.h

// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef UTIL_BIG_ENDIAN_H_
#define UTIL_BIG_ENDIAN_H_

#include <stdint.h>

#include <cstring>
#include <type_traits>

namespace openscreen {

////////////////////////////////////////////////////////////////////////////////
// Note: All of the functions here are defined inline, as any half-decent
// compiler will optimize them to a single integer constant or single
// instruction on most architectures.
////////////////////////////////////////////////////////////////////////////////

// Returns true if this code is running on a big-endian architecture.
inline bool IsBigEndianArchitecture() {}

namespace internal {

template <int size>
struct MakeSizedUnsignedInteger;

template <>
struct MakeSizedUnsignedInteger<1> {};

template <>
struct MakeSizedUnsignedInteger<2> {};

template <>
struct MakeSizedUnsignedInteger<4> {};

template <>
struct MakeSizedUnsignedInteger<8> {};

template <int size>
inline typename MakeSizedUnsignedInteger<size>::type ByteSwap(
    typename MakeSizedUnsignedInteger<size>::type x) {}

template <>
inline uint8_t ByteSwap<1>(uint8_t x) {}

#if defined(__clang__) || defined(__GNUC__)

template <>
inline uint64_t ByteSwap<8>(uint64_t x) {}
template <>
inline uint32_t ByteSwap<4>(uint32_t x) {}
template <>
inline uint16_t ByteSwap<2>(uint16_t x) {}

#elif defined(_MSC_VER)

template <>
inline uint64_t ByteSwap<8>(uint64_t x) {
  return _byteswap_uint64(x);
}
template <>
inline uint32_t ByteSwap<4>(uint32_t x) {
  return _byteswap_ulong(x);
}
template <>
inline uint16_t ByteSwap<2>(uint16_t x) {
  return _byteswap_ushort(x);
}

#else

#include <byteswap.h>

template <>
inline uint64_t ByteSwap<8>(uint64_t x) {
  return bswap_64(x);
}
template <>
inline uint32_t ByteSwap<4>(uint32_t x) {
  return bswap_32(x);
}
template <>
inline uint16_t ByteSwap<2>(uint16_t x) {
  return bswap_16(x);
}

#endif

}  // namespace internal

// Returns the bytes of |x| in reverse order. This is only defined for 16-, 32-,
// and 64-bit unsigned integers.
template <typename Integer>
inline std::enable_if_t<std::is_unsigned<Integer>::value, Integer> ByteSwap(
    Integer x) {}

// Read a POD integer from |src| in big-endian byte order, returning the integer
// in native byte order.
template <typename Integer>
inline Integer ReadBigEndian(const void* src) {}

// Write a POD integer |val| to |dest| in big-endian byte order.
template <typename Integer>
inline void WriteBigEndian(Integer val, void* dest) {}

template <class T>
class BigEndianBuffer {};

// TODO(mfoltz): Use ByteBuffer here instead of pointer-and-length.
class BigEndianReader : public BigEndianBuffer<const uint8_t> {};

class BigEndianWriter : public BigEndianBuffer<uint8_t> {};

}  // namespace openscreen

#endif  // UTIL_BIG_ENDIAN_H_