/*
 *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#ifndef MODULES_RTP_RTCP_SOURCE_BYTE_IO_H_
#define MODULES_RTP_RTCP_SOURCE_BYTE_IO_H_

// This file contains classes for reading and writing integer types from/to
// byte array representations. Signed/unsigned, partial (whole byte) sizes,
// and big/little endian byte order is all supported.
//
// Usage examples:
//
// uint8_t* buffer = ...;
//
// // Read an unsigned 4 byte integer in big endian format
// uint32_t val = ByteReader<uint32_t>::ReadBigEndian(buffer);
//
// // Read a signed 24-bit (3 byte) integer in little endian format
// int32_t val = ByteReader<int32_t, 3>::ReadLittle(buffer);
//
// // Write an unsigned 8 byte integer in little endian format
// ByteWriter<uint64_t>::WriteLittleEndian(buffer, val);
//
// Write an unsigned 40-bit (5 byte) integer in big endian format
// ByteWriter<uint64_t, 5>::WriteBigEndian(buffer, val);
//
// These classes are implemented as recursive templetizations, inteded to make
// it easy for the compiler to completely inline the reading/writing.

#include <stdint.h>

#include <limits>

namespace webrtc {

// According to ISO C standard ISO/IEC 9899, section 6.2.6.2 (2), the three
// representations of signed integers allowed are two's complement, one's
// complement and sign/magnitude. We can detect which is used by looking at
// the two last bits of -1, which will be 11 in two's complement, 10 in one's
// complement and 01 in sign/magnitude.
// TODO(sprang): In the unlikely event that we actually need to support a
// platform that doesn't use two's complement, implement conversion to/from
// wire format.

// Assume the if any one signed integer type is two's complement, then all
// other will be too.
static_assert(
    (-1 & 0x03) == 0x03,
    "Only two's complement representation of signed integers supported.");

// Plain const char* won't work for static_assert, use #define instead.
#define kSizeErrorMsg "Byte size must be less than or equal to data type size."

// Utility class for getting the unsigned equivalent of a signed type.
template <typename T>
struct UnsignedOf;

// Class for reading integers from a sequence of bytes.
// T = type of integer, B = bytes to read, is_signed = true if signed integer.
// If is_signed is true and B < sizeof(T), sign extension might be needed.
template <typename T,
          unsigned int B = sizeof(T),
          bool is_signed = std::numeric_limits<T>::is_signed>
class ByteReader;

// Specialization of ByteReader for unsigned types.
template <typename T, unsigned int B>
class ByteReader<T, B, false> {
 public:
  static T ReadBigEndian(const uint8_t* data) {
    static_assert(B <= sizeof(T), kSizeErrorMsg);
    return InternalReadBigEndian(data);
  }

  static T ReadLittleEndian(const uint8_t* data) {
    static_assert(B <= sizeof(T), kSizeErrorMsg);
    return InternalReadLittleEndian(data);
  }

 private:
  static T InternalReadBigEndian(const uint8_t* data) {
    T val(0);
    for (unsigned int i = 0; i < B; ++i)
      val |= static_cast<T>(data[i]) << ((B - 1 - i) * 8);
    return val;
  }

  static T InternalReadLittleEndian(const uint8_t* data) {
    T val(0);
    for (unsigned int i = 0; i < B; ++i)
      val |= static_cast<T>(data[i]) << (i * 8);
    return val;
  }
};

// Specialization of ByteReader for signed types.
template <typename T, unsigned int B>
class ByteReader<T, B, true> {
 public:
  typedef typename UnsignedOf<T>::Type U;

  static T ReadBigEndian(const uint8_t* data) {
    U unsigned_val = ByteReader<T, B, false>::ReadBigEndian(data);
    if (B < sizeof(T))
      unsigned_val = SignExtend(unsigned_val);
    return ReinterpretAsSigned(unsigned_val);
  }

  static T ReadLittleEndian(const uint8_t* data) {
    U unsigned_val = ByteReader<T, B, false>::ReadLittleEndian(data);
    if (B < sizeof(T))
      unsigned_val = SignExtend(unsigned_val);
    return ReinterpretAsSigned(unsigned_val);
  }

 private:
  // As a hack to avoid implementation-specific or undefined behavior when
  // bit-shifting or casting signed integers, read as a signed equivalent
  // instead and convert to signed. This is safe since we have asserted that
  // two's complement for is used.
  static T ReinterpretAsSigned(U unsigned_val) {
    // An unsigned value with only the highest order bit set (ex 0x80).
    const U kUnsignedHighestBitMask = static_cast<U>(1)
                                      << ((sizeof(U) * 8) - 1);
    // A signed value with only the highest bit set. Since this is two's
    // complement form, we can use the min value from std::numeric_limits.
    const T kSignedHighestBitMask = std::numeric_limits<T>::min();

    T val;
    if ((unsigned_val & kUnsignedHighestBitMask) != 0) {
      // Casting is only safe when unsigned value can be represented in the
      // signed target type, so mask out highest bit and mask it back manually.
      val = static_cast<T>(unsigned_val & ~kUnsignedHighestBitMask);
      val |= kSignedHighestBitMask;
    } else {
      val = static_cast<T>(unsigned_val);
    }
    return val;
  }

  // If number of bytes is less than native data type (eg 24 bit, in int32_t),
  // and the most significant bit of the actual data is set, we must sign
  // extend the remaining byte(s) with ones so that the correct negative
  // number is retained.
  // Ex: 0x810A0B -> 0xFF810A0B, but 0x710A0B -> 0x00710A0B
  static U SignExtend(const U val) {
    const uint8_t kMsb = static_cast<uint8_t>(val >> ((B - 1) * 8));
    if ((kMsb & 0x80) != 0) {
      // Create a mask where all bits used by the B bytes are set to one,
      // for instance 0x00FFFFFF for B = 3. Bit-wise invert that mask (to
      // (0xFF000000 in the example above) and add it to the input value.
      // The "B % sizeof(T)" is a workaround to undefined values warnings for
      // B == sizeof(T), in which case this code won't be called anyway.
      const U kUsedBitsMask = (1 << ((B % sizeof(T)) * 8)) - 1;
      return ~kUsedBitsMask | val;
    }
    return val;
  }
};

// Class for writing integers to a sequence of bytes
// T = type of integer, B = bytes to write
template <typename T,
          unsigned int B = sizeof(T),
          bool is_signed = std::numeric_limits<T>::is_signed>
class ByteWriter;

// Specialization of ByteWriter for unsigned types.
template <typename T, unsigned int B>
class ByteWriter<T, B, false> {
 public:
  static void WriteBigEndian(uint8_t* data, T val) {
    static_assert(B <= sizeof(T), kSizeErrorMsg);
    for (unsigned int i = 0; i < B; ++i) {
      data[i] = val >> ((B - 1 - i) * 8);
    }
  }

  static void WriteLittleEndian(uint8_t* data, T val) {
    static_assert(B <= sizeof(T), kSizeErrorMsg);
    for (unsigned int i = 0; i < B; ++i) {
      data[i] = val >> (i * 8);
    }
  }
};

// Specialization of ByteWriter for signed types.
template <typename T, unsigned int B>
class ByteWriter<T, B, true> {
 public:
  typedef typename UnsignedOf<T>::Type U;

  static void WriteBigEndian(uint8_t* data, T val) {
    ByteWriter<U, B, false>::WriteBigEndian(data, ReinterpretAsUnsigned(val));
  }

  static void WriteLittleEndian(uint8_t* data, T val) {
    ByteWriter<U, B, false>::WriteLittleEndian(data,
                                               ReinterpretAsUnsigned(val));
  }

 private:
  static U ReinterpretAsUnsigned(T val) {
    // According to ISO C standard ISO/IEC 9899, section 6.3.1.3 (1, 2) a
    // conversion from signed to unsigned keeps the value if the new type can
    // represent it, and otherwise adds one more than the max value of T until
    // the value is in range. For two's complement, this fortunately means
    // that the bit-wise value will be intact. Thus, since we have asserted that
    // two's complement form is actually used, a simple cast is sufficient.
    return static_cast<U>(val);
  }
};

// ----- Below follows specializations of UnsignedOf utility class -----

template <>
struct UnsignedOf<int8_t> {
  typedef uint8_t Type;
};
template <>
struct UnsignedOf<int16_t> {
  typedef uint16_t Type;
};
template <>
struct UnsignedOf<int32_t> {
  typedef uint32_t Type;
};
template <>
struct UnsignedOf<int64_t> {
  typedef uint64_t Type;
};

// ----- Below follows specializations for unsigned, B in { 1, 2, 4, 8 } -----

// TODO(sprang): Check if these actually help or if generic cases will be
// unrolled to and optimized to similar performance.

// Specializations for single bytes
template <typename T>
class ByteReader<T, 1, false> {
 public:
  static T ReadBigEndian(const uint8_t* data) {
    static_assert(sizeof(T) == 1, kSizeErrorMsg);
    return data[0];
  }

  static T ReadLittleEndian(const uint8_t* data) {
    static_assert(sizeof(T) == 1, kSizeErrorMsg);
    return data[0];
  }
};

template <typename T>
class ByteWriter<T, 1, false> {
 public:
  static void WriteBigEndian(uint8_t* data, T val) {
    static_assert(sizeof(T) == 1, kSizeErrorMsg);
    data[0] = val;
  }

  static void WriteLittleEndian(uint8_t* data, T val) {
    static_assert(sizeof(T) == 1, kSizeErrorMsg);
    data[0] = val;
  }
};

// Specializations for two byte words
template <typename T>
class ByteReader<T, 2, false> {
 public:
  static T ReadBigEndian(const uint8_t* data) {
    static_assert(sizeof(T) >= 2, kSizeErrorMsg);
    return (data[0] << 8) | data[1];
  }

  static T ReadLittleEndian(const uint8_t* data) {
    static_assert(sizeof(T) >= 2, kSizeErrorMsg);
    return data[0] | (data[1] << 8);
  }
};

template <typename T>
class ByteWriter<T, 2, false> {
 public:
  static void WriteBigEndian(uint8_t* data, T val) {
    static_assert(sizeof(T) >= 2, kSizeErrorMsg);
    data[0] = val >> 8;
    data[1] = val;
  }

  static void WriteLittleEndian(uint8_t* data, T val) {
    static_assert(sizeof(T) >= 2, kSizeErrorMsg);
    data[0] = val;
    data[1] = val >> 8;
  }
};

// Specializations for four byte words.
template <typename T>
class ByteReader<T, 4, false> {
 public:
  static T ReadBigEndian(const uint8_t* data) {
    static_assert(sizeof(T) >= 4, kSizeErrorMsg);
    return (Get(data, 0) << 24) | (Get(data, 1) << 16) | (Get(data, 2) << 8) |
           Get(data, 3);
  }

  static T ReadLittleEndian(const uint8_t* data) {
    static_assert(sizeof(T) >= 4, kSizeErrorMsg);
    return Get(data, 0) | (Get(data, 1) << 8) | (Get(data, 2) << 16) |
           (Get(data, 3) << 24);
  }

 private:
  inline static T Get(const uint8_t* data, unsigned int index) {
    return static_cast<T>(data[index]);
  }
};

// Specializations for four byte words.
template <typename T>
class ByteWriter<T, 4, false> {
 public:
  static void WriteBigEndian(uint8_t* data, T val) {
    static_assert(sizeof(T) >= 4, kSizeErrorMsg);
    data[0] = val >> 24;
    data[1] = val >> 16;
    data[2] = val >> 8;
    data[3] = val;
  }

  static void WriteLittleEndian(uint8_t* data, T val) {
    static_assert(sizeof(T) >= 4, kSizeErrorMsg);
    data[0] = val;
    data[1] = val >> 8;
    data[2] = val >> 16;
    data[3] = val >> 24;
  }
};

// Specializations for eight byte words.
template <typename T>
class ByteReader<T, 8, false> {
 public:
  static T ReadBigEndian(const uint8_t* data) {
    static_assert(sizeof(T) >= 8, kSizeErrorMsg);
    return (Get(data, 0) << 56) | (Get(data, 1) << 48) | (Get(data, 2) << 40) |
           (Get(data, 3) << 32) | (Get(data, 4) << 24) | (Get(data, 5) << 16) |
           (Get(data, 6) << 8) | Get(data, 7);
  }

  static T ReadLittleEndian(const uint8_t* data) {
    static_assert(sizeof(T) >= 8, kSizeErrorMsg);
    return Get(data, 0) | (Get(data, 1) << 8) | (Get(data, 2) << 16) |
           (Get(data, 3) << 24) | (Get(data, 4) << 32) | (Get(data, 5) << 40) |
           (Get(data, 6) << 48) | (Get(data, 7) << 56);
  }

 private:
  inline static T Get(const uint8_t* data, unsigned int index) {
    return static_cast<T>(data[index]);
  }
};

template <typename T>
class ByteWriter<T, 8, false> {
 public:
  static void WriteBigEndian(uint8_t* data, T val) {
    static_assert(sizeof(T) >= 8, kSizeErrorMsg);
    data[0] = val >> 56;
    data[1] = val >> 48;
    data[2] = val >> 40;
    data[3] = val >> 32;
    data[4] = val >> 24;
    data[5] = val >> 16;
    data[6] = val >> 8;
    data[7] = val;
  }

  static void WriteLittleEndian(uint8_t* data, T val) {
    static_assert(sizeof(T) >= 8, kSizeErrorMsg);
    data[0] = val;
    data[1] = val >> 8;
    data[2] = val >> 16;
    data[3] = val >> 24;
    data[4] = val >> 32;
    data[5] = val >> 40;
    data[6] = val >> 48;
    data[7] = val >> 56;
  }
};

}  // namespace webrtc

#endif  // MODULES_RTP_RTCP_SOURCE_BYTE_IO_H_
