/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

/* Functions for reading and writing integers in various endiannesses. */

/*
 * The classes LittleEndian and BigEndian expose static methods for
 * reading and writing 16-, 32-, and 64-bit signed and unsigned integers
 * in their respective endianness.  The naming scheme is:
 *
 * {Little,Big}Endian::{read,write}{Uint,Int}<bitsize>
 *
 * For instance, LittleEndian::readInt32 will read a 32-bit signed
 * integer from memory in little endian format.  Similarly,
 * BigEndian::writeUint16 will write a 16-bit unsigned integer to memory
 * in big-endian format.
 *
 * The class NativeEndian exposes methods for conversion of existing
 * data to and from the native endianness.  These methods are intended
 * for cases where data needs to be transferred, serialized, etc.
 * swap{To,From}{Little,Big}Endian byteswap a single value if necessary.
 * Bulk conversion functions are also provided which optimize the
 * no-conversion-needed case:
 *
 * - copyAndSwap{To,From}{Little,Big}Endian;
 * - swap{To,From}{Little,Big}EndianInPlace.
 *
 * The *From* variants are intended to be used for reading data and the
 * *To* variants for writing data.
 *
 * Methods on NativeEndian work with integer data of any type.
 * Floating-point data is not supported.
 *
 * For clarity in networking code, "Network" may be used as a synonym
 * for "Big" in any of the above methods or class names.
 *
 * As an example, reading a file format header whose fields are stored
 * in big-endian format might look like:
 *
 * class ExampleHeader
 * {
 *   private:
 *     uint32_t magic;
 *     uint32_t length;
 *     uint32_t totalRecords;
 *     uint64_t checksum;
 *
 *   public:
 *     ExampleHeader(const void* data) {
 *       const uint8_t* ptr = static_cast<const uint8_t*>(data);
 *       magic = BigEndian::readUint32(ptr); ptr += sizeof(uint32_t);
 *       length = BigEndian::readUint32(ptr); ptr += sizeof(uint32_t);
 *       totalRecords = BigEndian::readUint32(ptr); ptr += sizeof(uint32_t);
 *       checksum = BigEndian::readUint64(ptr);
 *     }
 *     ...
 * };
 */

#ifndef mozilla_Endian_h_
#define mozilla_Endian_h_

#include "mozilla/Assertions.h"
#include "mozilla/Attributes.h"
#include "mozilla/Compiler.h"
#include "mozilla/DebugOnly.h"
#include "mozilla/StandardInteger.h"
#include "mozilla/TypeTraits.h"

#include <string.h>

#if defined(STARBOARD)
#include "starboard/byte_swap.h"
#endif

#if defined(_MSC_VER) && _MSC_VER >= 1300
#  include <stdlib.h>
#  pragma intrinsic(_byteswap_ushort)
#  pragma intrinsic(_byteswap_ulong)
#  pragma intrinsic(_byteswap_uint64)
#endif

#if defined(_WIN64)
#  if defined(_M_X64) || defined(_M_AMD64) || defined(_AMD64_)
#    define MOZ_LITTLE_ENDIAN 1
#  else
#    error "CPU type is unknown"
#  endif
#elif defined(_WIN32)
#  if defined(_M_IX86)
#    define MOZ_LITTLE_ENDIAN 1
#  else
#    error "CPU type is unknown"
#  endif
#elif defined(__APPLE__)
#  if __LITTLE_ENDIAN__
#    define MOZ_LITTLE_ENDIAN 1
#  elif __BIG_ENDIAN__
#    define MOZ_BIG_ENDIAN 1
#  endif
#elif defined(__GNUC__) && \
      defined(__BYTE_ORDER__) && \
      defined(__ORDER_LITTLE_ENDIAN__) && \
      defined(__ORDER_BIG_ENDIAN__)
   /*
    * Some versions of GCC provide architecture-independent macros for
    * this.  Yes, there are more than two values for __BYTE_ORDER__.
    */
#  if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
#    define MOZ_LITTLE_ENDIAN 1
#  elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
#    define MOZ_BIG_ENDIAN 1
#  else
#    error "Can't handle mixed-endian architectures"
#  endif
/*
 * We can't include useful headers like <endian.h> or <sys/isa_defs.h>
 * here because they're not present on all platforms.  Instead we have
 * this big conditional that ideally will catch all the interesting
 * cases.
 */
#elif defined(__sparc) || defined(__sparc__) || \
      defined(_POWER) || defined(__powerpc__) || \
      defined(__ppc__) || defined(__hppa) || \
      defined(_MIPSEB) || defined(__ARMEB__) || \
      defined(__s390__) || \
      (defined(__sh__) && defined(__LITTLE_ENDIAN__)) || \
      (defined(__ia64) && defined(__BIG_ENDIAN__))
#  define MOZ_BIG_ENDIAN 1
#elif defined(__i386) || defined(__i386__) || \
      defined(__x86_64) || defined(__x86_64__) || \
      defined(_MIPSEL) || defined(__ARMEL__) || \
      defined(__alpha__) || \
      (defined(__sh__) && defined(__BIG_ENDIAN__)) || \
      (defined(__ia64) && !defined(__BIG_ENDIAN__))
#  define MOZ_LITTLE_ENDIAN 1
#endif

#if MOZ_BIG_ENDIAN
#  define MOZ_LITTLE_ENDIAN 0
#elif MOZ_LITTLE_ENDIAN
#  define MOZ_BIG_ENDIAN 0
#else
#  error "Cannot determine endianness"
#endif

#if defined(__clang__)
#  if __has_builtin(__builtin_bswap16)
#    define MOZ_HAVE_BUILTIN_BYTESWAP16 __builtin_bswap16
#  endif
#elif defined(__GNUC__)
#  if MOZ_GCC_VERSION_AT_LEAST(4, 8, 0)
#    define MOZ_HAVE_BUILTIN_BYTESWAP16 __builtin_bswap16
#  endif
#elif defined(_MSC_VER)
#    define MOZ_HAVE_BUILTIN_BYTESWAP16 _byteswap_ushort
#endif

#if defined(__clang__)
#  if __has_builtin(__builtin_bswap32)
#    define MOZ_HAVE_BUILTIN_BYTESWAP32 __builtin_bswap32
#  endif
#elif defined(__GNUC__)
#  if MOZ_GCC_VERSION_AT_LEAST(4, 5, 0)
#    define MOZ_HAVE_BUILTIN_BYTESWAP32 __builtin_bswap32
#  endif
#elif defined(_MSC_VER)
#    define MOZ_HAVE_BUILTIN_BYTESWAP32 _byteswap_ulong
#endif

#if defined(__clang__)
#  if __has_builtin(__builtin_bswap64)
#    define MOZ_HAVE_BUILTIN_BYTESWAP64 __builtin_bswap64
#  endif
#elif defined(__GNUC__)
#  if MOZ_GCC_VERSION_AT_LEAST(4, 5, 0)
#    define MOZ_HAVE_BUILTIN_BYTESWAP64 __builtin_bswap64
#  endif
#elif defined(_MSC_VER)
#    define MOZ_HAVE_BUILTIN_BYTESWAP64 _byteswap_uint64
#endif

namespace mozilla {

namespace detail {

/*
 * We need wrappers here because free functions with default template
 * arguments and/or partial specialization of function templates are not
 * supported by all the compilers we use.
 */
template<typename T, size_t Size = sizeof(T)>
struct Swapper;

template<typename T>
struct Swapper<T, 2>
{
  static T swap(T value)
  {
#if defined(MOZ_HAVE_BUILTIN_BYTESWAP16)
    return MOZ_HAVE_BUILTIN_BYTESWAP16(value);
#else
    return T(((value & 0x00ff) << 8) | ((value & 0xff00) >> 8));
#endif
  }
};

template<typename T>
struct Swapper<T, 4>
{
  static T swap(T value)
  {
#if defined(STARBOARD)
    return static_cast<T>(SbByteSwapU32(value));
#elif defined(MOZ_HAVE_BUILTIN_BYTESWAP32)
    return MOZ_HAVE_BUILTIN_BYTESWAP32(value);
#else
    return T(((value & 0x000000ffU) << 24) |
             ((value & 0x0000ff00U) << 8) |
             ((value & 0x00ff0000U) >> 8) |
             ((value & 0xff000000U) >> 24));
#endif
  }
};

template<typename T>
struct Swapper<T, 8>
{
  static inline T swap(T value)
  {
#if defined(STARBOARD)
    return static_cast<T>(SbByteSwapU64(value));
#elif defined(MOZ_HAVE_BUILTIN_BYTESWAP64)
    return MOZ_HAVE_BUILTIN_BYTESWAP64(value);
#else
    return T(((value & 0x00000000000000ffULL) << 56) |
             ((value & 0x000000000000ff00ULL) << 40) |
             ((value & 0x0000000000ff0000ULL) << 24) |
             ((value & 0x00000000ff000000ULL) << 8) |
             ((value & 0x000000ff00000000ULL) >> 8) |
             ((value & 0x0000ff0000000000ULL) >> 24) |
             ((value & 0x00ff000000000000ULL) >> 40) |
             ((value & 0xff00000000000000ULL) >> 56));
#endif
  }
};

enum Endianness { Little, Big };

#if MOZ_BIG_ENDIAN
#  define MOZ_NATIVE_ENDIANNESS detail::Big
#else
#  define MOZ_NATIVE_ENDIANNESS detail::Little
#endif

class EndianUtils
{
    /**
     * Assert that the memory regions [dest, dest+count) and [src, src+count]
     * do not overlap.  count is given in bytes.
     */
    static void assertNoOverlap(const void* dest, const void* src, size_t count)
    {
      DebugOnly<const uint8_t*> byteDestPtr = static_cast<const uint8_t*>(dest);
      DebugOnly<const uint8_t*> byteSrcPtr = static_cast<const uint8_t*>(src);
      MOZ_ASSERT((byteDestPtr < byteSrcPtr &&
                  byteDestPtr + count <= byteSrcPtr) ||
                 (byteSrcPtr < byteDestPtr &&
                  byteSrcPtr + count <= byteDestPtr));
    }

    template<typename T>
    static void assertAligned(T* ptr)
    {
      MOZ_ASSERT((uintptr_t(ptr) % sizeof(T)) == 0, "Unaligned pointer!");
    }

  protected:
    /**
     * Return |value| converted from SourceEndian encoding to DestEndian
     * encoding.
     */
    template<Endianness SourceEndian, Endianness DestEndian, typename T>
    static inline T maybeSwap(T value)
    {
      if (SourceEndian == DestEndian)
        return value;

      return Swapper<T>::swap(value);
    }

    /**
     * Convert |count| elements at |ptr| from SourceEndian encoding to
     * DestEndian encoding.
     */
    template<Endianness SourceEndian, Endianness DestEndian, typename T>
    static inline void maybeSwapInPlace(T* ptr, size_t count)
    {
      assertAligned(ptr);

      if (SourceEndian == DestEndian)
        return;

      for (size_t i = 0; i < count; i++)
        ptr[i] = Swapper<T>::swap(ptr[i]);
    }

    /**
     * Write |count| elements to the unaligned address |dest| in DestEndian
     * format, using elements found at |src| in SourceEndian format.
     */
    template<Endianness SourceEndian, Endianness DestEndian, typename T>
    static void copyAndSwapTo(void* dest, const T* src, size_t count)
    {
      assertNoOverlap(dest, src, count * sizeof(T));
      assertAligned(src);

      if (SourceEndian == DestEndian) {
        memcpy(dest, src, count * sizeof(T));
        return;
      }

      uint8_t* byteDestPtr = static_cast<uint8_t*>(dest);
      for (size_t i = 0; i < count; ++i) {
        union {
          T val;
          uint8_t buffer[sizeof(T)];
        } u;
        u.val = maybeSwap<SourceEndian, DestEndian>(src[i]);
        memcpy(byteDestPtr, u.buffer, sizeof(T));
        byteDestPtr += sizeof(T);
      }
    }

    /**
     * Write |count| elements to |dest| in DestEndian format, using elements
     * found at the unaligned address |src| in SourceEndian format.
     */
    template<Endianness SourceEndian, Endianness DestEndian, typename T>
    static void copyAndSwapFrom(T* dest, const void* src, size_t count)
    {
      assertNoOverlap(dest, src, count * sizeof(T));
      assertAligned(dest);

      if (SourceEndian == DestEndian) {
        memcpy(dest, src, count * sizeof(T));
        return;
      }

      const uint8_t* byteSrcPtr = static_cast<const uint8_t*>(src);
      for (size_t i = 0; i < count; ++i) {
        union {
          T val;
          uint8_t buffer[sizeof(T)];
        } u;
        memcpy(u.buffer, byteSrcPtr, sizeof(T));
        dest[i] = maybeSwap<SourceEndian, DestEndian>(u.val);
        byteSrcPtr += sizeof(T);
      }
    }
};

template<Endianness ThisEndian>
class Endian : private EndianUtils
{
  protected:
    /** Read a uint16_t in ThisEndian endianness from |p| and return it. */
    static MOZ_WARN_UNUSED_RESULT uint16_t readUint16(const void* p) {
      return read<uint16_t>(p);
    }

    /** Read a uint32_t in ThisEndian endianness from |p| and return it. */
    static MOZ_WARN_UNUSED_RESULT uint32_t readUint32(const void* p) {
      return read<uint32_t>(p);
    }

    /** Read a uint64_t in ThisEndian endianness from |p| and return it. */
    static MOZ_WARN_UNUSED_RESULT uint64_t readUint64(const void* p) {
      return read<uint64_t>(p);
    }

    /** Read an int16_t in ThisEndian endianness from |p| and return it. */
    static MOZ_WARN_UNUSED_RESULT int16_t readInt16(const void* p) {
      return read<int16_t>(p);
    }

    /** Read an int32_t in ThisEndian endianness from |p| and return it. */
    static MOZ_WARN_UNUSED_RESULT int32_t readInt32(const void* p) {
      return read<uint32_t>(p);
    }

    /** Read an int64_t in ThisEndian endianness from |p| and return it. */
    static MOZ_WARN_UNUSED_RESULT int64_t readInt64(const void* p) {
      return read<int64_t>(p);
    }

    /** Write |val| to |p| using ThisEndian endianness. */
    static void writeUint16(void* p, uint16_t val) {
      write(p, val);
    }
    /** Write |val| to |p| using ThisEndian endianness. */
    static void writeUint32(void* p, uint32_t val) {
      write(p, val);
    }
    /** Write |val| to |p| using ThisEndian endianness. */
    static void writeUint64(void* p, uint64_t val) {
      write(p, val);
    }

    /** Write |val| to |p| using ThisEndian endianness. */
    static void writeInt16(void* p, int16_t val) {
      write(p, val);
    }
    /** Write |val| to |p| using ThisEndian endianness. */
    static void writeInt32(void* p, int32_t val) {
      write(p, val);
    }
    /** Write |val| to |p| using ThisEndian endianness. */
    static void writeInt64(void* p, int64_t val) {
      write(p, val);
    }

    /*
     * Converts a value of type T to little-endian format.
     *
     * This function is intended for cases where you have data in your
     * native-endian format and you need it to appear in little-endian
     * format for transmission.
     */
    template<typename T>
    MOZ_WARN_UNUSED_RESULT static T swapToLittleEndian(T value) {
      return maybeSwap<ThisEndian, Little>(value);
    }
    /*
     * Copies count values of type T starting at src to dest, converting
     * them to little-endian format if ThisEndian is Big.
     * As with memcpy, dest and src must not overlap.
     */
    template<typename T>
    static void copyAndSwapToLittleEndian(void* dest, const T* src,
                                          size_t count) {
      copyAndSwapTo<ThisEndian, Little>(dest, src, count);
    }
    /*
     * Likewise, but converts values in place.
     */
    template<typename T>
    static void swapToLittleEndianInPlace(T* p, size_t count) {
      maybeSwapInPlace<ThisEndian, Little>(p, count);
    }

    /*
     * Converts a value of type T to big-endian format.
     */
    template<typename T>
    MOZ_WARN_UNUSED_RESULT static T swapToBigEndian(T value) {
      return maybeSwap<ThisEndian, Big>(value);
    }
    /*
     * Copies count values of type T starting at src to dest, converting
     * them to big-endian format if ThisEndian is Little.
     * As with memcpy, dest and src must not overlap.
     */
    template<typename T>
    static void copyAndSwapToBigEndian(void* dest, const T* src, size_t count) {
      copyAndSwapTo<ThisEndian, Big>(dest, src, count);
    }
    /*
     * Likewise, but converts values in place.
     */
    template<typename T>
    static void swapToBigEndianInPlace(T* p, size_t count) {
      maybeSwapInPlace<ThisEndian, Big>(p, count);
    }

    /*
     * Synonyms for the big-endian functions, for better readability
     * in network code.
     */
    template<typename T>
    MOZ_WARN_UNUSED_RESULT static T swapToNetworkOrder(T value) {
      return swapToBigEndian(value);
    }
    template<typename T>
    static void
    copyAndSwapToNetworkOrder(void* dest, const T* src, size_t count) {
      copyAndSwapToBigEndian(dest, src, count);
    }
    template<typename T>
    static void
    swapToNetworkOrderInPlace(T* p, size_t count) {
      swapToBigEndianInPlace(p, count);
    }

    /*
     * Converts a value of type T from little-endian format.
     */
    template<typename T>
    MOZ_WARN_UNUSED_RESULT static T swapFromLittleEndian(T value) {
      return maybeSwap<Little, ThisEndian>(value);
    }
    /*
     * Copies count values of type T starting at src to dest, converting
     * them to little-endian format if ThisEndian is Big.
     * As with memcpy, dest and src must not overlap.
     */
    template<typename T>
    static void copyAndSwapFromLittleEndian(T* dest, const void* src,
                                            size_t count) {
      copyAndSwapFrom<Little, ThisEndian>(dest, src, count);
    }
    /*
     * Likewise, but converts values in place.
     */
    template<typename T>
    static void swapFromLittleEndianInPlace(T* p, size_t count) {
      maybeSwapInPlace<Little, ThisEndian>(p, count);
    }

    /*
     * Converts a value of type T from big-endian format.
     */
    template<typename T>
    MOZ_WARN_UNUSED_RESULT static T swapFromBigEndian(T value) {
      return maybeSwap<Big, ThisEndian>(value);
    }
    /*
     * Copies count values of type T starting at src to dest, converting
     * them to big-endian format if ThisEndian is Little.
     * As with memcpy, dest and src must not overlap.
     */
    template<typename T>
    static void copyAndSwapFromBigEndian(T* dest, const void* src,
                                         size_t count) {
      copyAndSwapFrom<Big, ThisEndian>(dest, src, count);
    }
    /*
     * Likewise, but converts values in place.
     */
    template<typename T>
    static void swapFromBigEndianInPlace(T* p, size_t count) {
      maybeSwapInPlace<Big, ThisEndian>(p, count);
    }

    /*
     * Synonyms for the big-endian functions, for better readability
     * in network code.
     */
    template<typename T>
    MOZ_WARN_UNUSED_RESULT static T swapFromNetworkOrder(T value) {
      return swapFromBigEndian(value);
    }
    template<typename T>
    static void copyAndSwapFromNetworkOrder(T* dest, const void* src,
                                            size_t count) {
      copyAndSwapFromBigEndian(dest, src, count);
    }
    template<typename T>
    static void swapFromNetworkOrderInPlace(T* p, size_t count) {
      swapFromBigEndianInPlace(p, count);
    }

  private:
    /**
     * Read a value of type T, encoded in endianness ThisEndian from |p|.
     * Return that value encoded in native endianness.
     */
    template<typename T>
    static T read(const void* p) {
      union {
        T val;
        uint8_t buffer[sizeof(T)];
      } u;
      memcpy(u.buffer, p, sizeof(T));
      return maybeSwap<ThisEndian, MOZ_NATIVE_ENDIANNESS>(u.val);
    }

    /**
     * Write a value of type T, in native endianness, to |p|, in ThisEndian
     * endianness.
     */
    template<typename T>
    static void write(void* p, T value) {
      T tmp = maybeSwap<MOZ_NATIVE_ENDIANNESS, ThisEndian>(value);
      memcpy(p, &tmp, sizeof(T));
    }

    Endian() MOZ_DELETE;
    Endian(const Endian& other) MOZ_DELETE;
    void operator=(const Endian& other) MOZ_DELETE;
};

template<Endianness ThisEndian>
class EndianReadWrite : public Endian<ThisEndian>
{
  private:
    typedef Endian<ThisEndian> super;

  public:
    using super::readUint16;
    using super::readUint32;
    using super::readUint64;
    using super::readInt16;
    using super::readInt32;
    using super::readInt64;
    using super::writeUint16;
    using super::writeUint32;
    using super::writeUint64;
    using super::writeInt16;
    using super::writeInt32;
    using super::writeInt64;
};

} /* namespace detail */

class LittleEndian MOZ_FINAL : public detail::EndianReadWrite<detail::Little>
{};

class BigEndian MOZ_FINAL : public detail::EndianReadWrite<detail::Big>
{};

typedef BigEndian NetworkEndian;

class NativeEndian MOZ_FINAL : public detail::Endian<MOZ_NATIVE_ENDIANNESS>
{
  private:
    typedef detail::Endian<MOZ_NATIVE_ENDIANNESS> super;

  public:
    /*
     * These functions are intended for cases where you have data in your
     * native-endian format and you need the data to appear in the appropriate
     * endianness for transmission, serialization, etc.
     */
    using super::swapToLittleEndian;
    using super::copyAndSwapToLittleEndian;
    using super::swapToLittleEndianInPlace;
    using super::swapToBigEndian;
    using super::copyAndSwapToBigEndian;
    using super::swapToBigEndianInPlace;
    using super::swapToNetworkOrder;
    using super::copyAndSwapToNetworkOrder;
    using super::swapToNetworkOrderInPlace;

    /*
     * These functions are intended for cases where you have data in the
     * given endianness (e.g. reading from disk or a file-format) and you
     * need the data to appear in native-endian format for processing.
     */
    using super::swapFromLittleEndian;
    using super::copyAndSwapFromLittleEndian;
    using super::swapFromLittleEndianInPlace;
    using super::swapFromBigEndian;
    using super::copyAndSwapFromBigEndian;
    using super::swapFromBigEndianInPlace;
    using super::swapFromNetworkOrder;
    using super::copyAndSwapFromNetworkOrder;
    using super::swapFromNetworkOrderInPlace;
};

#undef MOZ_NATIVE_ENDIANNESS

} /* namespace mozilla */

#endif /* mozilla_Endian_h_ */
