chromium/third_party/webrtc/modules/rtp_rtcp/source/byte_io.h

/*
 *  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, intended 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;

// Plain const char* won't work for static_assert, use #define instead.
#define kSizeErrorMsg

// 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.
ByteReader<T, B, false>;

// Specialization of ByteReader for signed types.
ByteReader<T, B, true>;

// 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.
ByteWriter<T, B, false>;

// Specialization of ByteWriter for signed types.
ByteWriter<T, B, true>;

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

template <>
struct UnsignedOf<int8_t> {};
template <>
struct UnsignedOf<int16_t> {};
template <>
struct UnsignedOf<int32_t> {};
template <>
struct UnsignedOf<int64_t> {};

// ----- 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
ByteReader<T, 1, false>;

ByteWriter<T, 1, false>;

// Specializations for two byte words
ByteReader<T, 2, false>;

ByteWriter<T, 2, false>;

// Specializations for four byte words.
ByteReader<T, 4, false>;

// Specializations for four byte words.
ByteWriter<T, 4, false>;

// Specializations for eight byte words.
ByteReader<T, 8, false>;

ByteWriter<T, 8, false>;

}  // namespace webrtc

#endif  // MODULES_RTP_RTCP_SOURCE_BYTE_IO_H_