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

#ifndef LIBIPP_IPP_ENCODING_H_
#define LIBIPP_IPP_ENCODING_H_

#include <cstddef>
#include <cstdint>
#include <limits>
#include <type_traits>

// Internal constants and functions used during parsing & building IPP frames.
// You probably do not want to use it directly. See ipp.h for information how to
// use this library.

namespace ipp {

// Some constants from the IPP specification [rfc8010] (section 3.2).
// begin-attribute-group-tag is from the range 0x00-0x0f without 0x03.
// value-tag is from the range 0x10-0xff.
constexpr uint8_t end_of_attributes_tag = 0x03;
constexpr uint8_t max_begin_attribute_group_tag = 0x0f;
constexpr uint8_t begCollection_value_tag = 0x34;
constexpr uint8_t endCollection_value_tag = 0x37;
constexpr uint8_t memberAttrName_value_tag = 0x4a;

// Helper to match signed integer type basing on number of bytes.
template <size_t BytesCount>
struct IntegerBySize;
template <>
struct IntegerBySize<1> {
  typedef int8_t type;
};
template <>
struct IntegerBySize<2> {
  typedef int16_t type;
};
template <>
struct IntegerBySize<4> {
  typedef int32_t type;
};

// Helper for reading unsigned integer from given address.
template <typename UnsignedInt>
inline UnsignedInt ReadAsBytes(const uint8_t* ptr) {
  UnsignedInt uval = 0;
  for (auto ptr_end = ptr + sizeof(UnsignedInt); ptr < ptr_end; ++ptr) {
    uval <<= 8;
    uval += *ptr;
  }
  return uval;
}
template <>
inline uint8_t ReadAsBytes<uint8_t>(const uint8_t* ptr) {
  return *ptr;
}

// Reads signed integer saved on sizeof(Integer) bytes at position ptr with
// two's-complement binary encoding and returns it.
// The following types can be set as Integer: int8_t, int16_t, int32_t, int64_t.
// Input parameter cannot be nullptr.
template <typename Integer>
Integer ReadInteger(const uint8_t* const ptr) {
  // given type must by signed integer
  static_assert(std::is_integral<Integer>::value, "integral expected");
  static_assert(std::is_signed<Integer>::value, "signed integral expected");
  // finds corresponding unsigned type
  typedef typename std::make_unsigned<Integer>::type UnsignedInteger;
  // parse two's-complement binary encoding
  UnsignedInteger uval = ReadAsBytes<UnsignedInteger>(ptr);
  if ((*ptr >> 7) == 0) {
    // first bit = 0: positive value or zero
    return static_cast<Integer>(uval);
  } else if ((uval << 1) == 0) {
    // first bit = 1 and the rest are zeroes: minimal possible value
    return std::numeric_limits<Integer>::min();
  } else {
    // first bit = 1 and at least one other 1: decode from two complement
    // conversion
    --uval;
    return -(static_cast<Integer>(~uval));
  }
}

// Parses signed integer saved on BytesCount bytes at position ptr and saves it
// to given variable. The pointer ptr is shifted by BytesCount.
// Two's-complement binary encoding is assumed.
// Allowed values of BytesCount: 1, 2, 4.
// Input parameters cannot be nullptr.
template <size_t BytesCount, typename OutInt>
void ParseSignedInteger(const uint8_t** ptr, OutInt* out_val) {
  // output type must by integer and must be long enough
  static_assert(std::is_integral<OutInt>::value, "integral expected");
  static_assert(std::is_signed<OutInt>::value, "signed integral expected");
  static_assert(BytesCount <= sizeof(OutInt), "given variable is too short");
  // parse, verify and return
  typedef typename IntegerBySize<BytesCount>::type Integer;
  *out_val = ReadInteger<Integer>(*ptr);
  *ptr += BytesCount;
}

// Parses unsigned integer saved on BytesCount bytes at position ptr and saves
// it to given variable. The pointer ptr is shifted by BytesCount. If parsed
// value is negative, no changes are made to out_val.
// Two's-complement binary encoding is assumed.
// returns false <=> parsed value is negative (ptr is shifted anyway)
// returns true <=> parsed value is >= 0
// Allowed values of BytesCount: 1, 2, 4.
// Input parameters cannot be nullptr.
template <size_t BytesCount, typename OutInt>
bool ParseUnsignedInteger(const uint8_t** ptr, OutInt* out_val) {
  // output type must by integer and must be long enough
  static_assert(std::is_integral<OutInt>::value, "integral expected");
  static_assert(BytesCount <= sizeof(OutInt), "given variable is too short");
  // parse, verify and return
  typedef typename IntegerBySize<BytesCount>::type Integer;
  const Integer val = ReadInteger<Integer>(*ptr);
  *ptr += BytesCount;
  if (val < 0)
    return false;
  *out_val = val;
  return true;
}

// Write unsigned integer to next BytesCount bytes with the most
// significant byte coming first and shifts |ptr| accordingly.
// BytesCount must equal sizeof(Integer).
// Integer must be one of the following: uint8_t, uint16_t, uint32_t,
// uint64_t.
template <size_t BytesCount, typename Integer>
inline void WriteUnsigned(uint8_t** ptr, Integer uval) {
  // given type must by unsigned integer
  static_assert(std::is_integral<Integer>::value, "integral expected");
  static_assert(std::is_unsigned<Integer>::value, "unsigned integral expected");
  static_assert(sizeof(Integer) == BytesCount, "invalid size of integer");
  // save as a sequence of bytes starting from the last one
  for (auto ptr2 = *ptr + sizeof(Integer) - 1; ptr2 >= *ptr; --ptr2) {
    *ptr2 = uval & 0xffu;
    uval >>= 8;
  }
  // move the pointer
  *ptr += sizeof(Integer);
}
template <>
inline void WriteUnsigned<1, uint8_t>(uint8_t** ptr, uint8_t uval) {
  **ptr = uval;
  ++*ptr;
}

// Write signed integer to next BytesCount bytes with two's-complement
// binary encoding and shifts |ptr| accordingly.
// BytesCount must equal sizeof(Integer).
// Integer must be one of the following: int8_t, int16_t, int32_t, int64_t.
template <size_t BytesCount, typename Integer>
void WriteInteger(uint8_t** ptr, Integer val) {
  // given type must by signed integer
  static_assert(std::is_integral<Integer>::value, "integral expected");
  static_assert(std::is_signed<Integer>::value, "signed integral expected");
  static_assert(sizeof(Integer) == BytesCount, "invalid size of integer");
  // finds corresponding unsigned type
  typedef typename std::make_unsigned<Integer>::type UnsignedInteger;
  // save as two's-complement binary encoding
  UnsignedInteger uval;
  if (val >= 0) {
    uval = val;
  } else if (val == std::numeric_limits<Integer>::min()) {
    // minimal possible value: first bit = 1 and the rest are zeroes
    uval = 1;
    uval <<= (8 * sizeof(Integer) - 1);
  } else {
    // decode from two complement conversion
    uval = -val;
    uval = ~uval;
    ++uval;
  }
  // write value starting from the last byte
  WriteUnsigned<BytesCount>(ptr, uval);
}

}  // namespace ipp

#endif  //  LIBIPP_IPP_ENCODING_H_
