109299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org/*
209299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
309299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org *
409299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org *  Use of this source code is governed by a BSD-style license
509299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org *  that can be found in the LICENSE file in the root of the source
609299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org *  tree. An additional intellectual property rights grant can be found
709299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org *  in the file PATENTS.  All contributing project authors may
809299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org *  be found in the AUTHORS file in the root of the source tree.
909299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org */
1009299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org
1109299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org#ifndef WEBRTC_MODULES_RTP_RTCP_SOURCE_BYTE_IO_H_
1209299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org#define WEBRTC_MODULES_RTP_RTCP_SOURCE_BYTE_IO_H_
1309299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org
1409299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org
1509299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org// This file contains classes for reading and writing integer types from/to
1609299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org// byte array representations. Signed/unsigned, partial (whole byte) sizes,
1709299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org// and big/little endian byte order is all supported.
1809299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org//
1909299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org// Usage examples:
2009299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org//
2109299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org// uint8_t* buffer = ...;
2209299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org//
2309299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org// // Read an unsigned 4 byte integer in big endian format
2409299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org// uint32_t val = ByteReader<uint32_t>::ReadBigEndian(buffer);
2509299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org//
2609299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org// // Read a signed 24-bit (3 byte) integer in little endian format
2709299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org// int32_t val = ByteReader<int32_t, 3>::ReadLittle(buffer);
2809299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org//
2909299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org// // Write an unsigned 8 byte integer in little endian format
3009299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org// ByteWriter<uint64_t>::WriteLittleEndian(buffer, val);
3109299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org//
3209299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org// Write an unsigned 40-bit (5 byte) integer in big endian format
3309299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org// ByteWriter<uint64_t, 5>::WriteBigEndian(buffer, val);
3409299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org//
3509299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org// These classes are implemented as recursive templetizations, inteded to make
3609299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org// it easy for the compiler to completely inline the reading/writing.
3709299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org
3809299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org
3909299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org#include <limits>
4009299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org
4109299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org#include "webrtc/typedefs.h"
4209299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org
4309299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.orgnamespace webrtc {
4409299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org
4509299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org// Class for reading integers from a sequence of bytes.
4609299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org// T = type of integer, B = bytes to read, is_signed = true if signed integer
4709299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org// If is_signed is true and B < sizeof(T), sign extension might be needed
4809299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.orgtemplate<typename T, unsigned int B = sizeof(T),
4909299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org    bool is_signed = std::numeric_limits<T>::is_signed>
5009299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.orgclass ByteReader {
5109299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org public:
5209299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org  static T ReadBigEndian(uint8_t* data) {
5309299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org    if (is_signed && B < sizeof(T)) {
5409299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org      return SignExtend(InternalReadBigEndian(data));
5509299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org    }
5609299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org    return InternalReadBigEndian(data);
5709299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org  }
5809299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org
5909299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org  static T ReadLittleEndian(uint8_t* data) {
6009299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org    if (is_signed && B < sizeof(T)) {
6109299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org      return SignExtend(InternalReadLittleEndian(data));
6209299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org    }
6309299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org    return InternalReadLittleEndian(data);
6409299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org  }
6509299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org
6609299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org private:
6709299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org  static T InternalReadBigEndian(uint8_t* data) {
6809299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org    T val(0);
6909299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org    for (unsigned int i = 0; i < B; ++i) {
7009299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org      val |= static_cast<T>(data[i]) << ((B - 1 - i) * 8);
7109299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org    }
7209299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org    return val;
7309299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org  }
7409299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org
7509299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org  static T InternalReadLittleEndian(uint8_t* data) {
7609299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org    T val(0);
7709299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org    for (unsigned int i = 0; i < B; ++i) {
7809299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org      val |= static_cast<T>(data[i]) << (i * 8);
7909299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org    }
8009299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org    return val;
8109299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org  }
8209299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org
8309299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org  // If number of bytes is less than native data type (eg 24 bit, in int32_t),
8409299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org  // and the most significant bit of the actual data is set, we must sign
8509299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org  // extend the remaining byte(s) with ones so that the correct negative
8609299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org  // number is retained.
8709299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org  // Ex: 0x810A0B -> 0xFF810A0B, but 0x710A0B -> 0x00710A0B
8809299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org  static T SignExtend(T val) {
8909299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org    uint8_t msb = static_cast<uint8_t>(val >> ((B - 1) * 8));
9009299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org    if (msb & 0x80) {
9109299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org      // Sign extension is -1 (all ones) shifted left B bytes.
9209299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org      // The "B % sizeof(T)"-part is there to avoid compiler warning for
9309299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org      // shifting the whole size of the data type.
9409299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org      T sign_extend = (sizeof(T) == B ? 0 :
9509299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org          (static_cast<T>(-1L) << ((B % sizeof(T)) * 8)));
9609299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org
9709299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org      return val | sign_extend;
9809299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org    }
9909299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org    return val;
10009299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org  }
10109299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org};
10209299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org
10309299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org// Class for writing integers to a sequence of bytes
10409299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org// T = type of integer, B = bytes to write
10509299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.orgtemplate<typename T, unsigned int B = sizeof(T)>
10609299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.orgclass ByteWriter {
10709299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org public:
10809299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org  static void WriteBigEndian(uint8_t* data, T val) {
10909299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org    for (unsigned int i = 0; i < B; ++i) {
11009299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org      data[i] = val >> ((B - 1 - i) * 8);
11109299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org    }
11209299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org  }
11309299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org
11409299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org  static void WriteLittleEndian(uint8_t* data, T val) {
11509299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org    for (unsigned int i = 0; i < B; ++i) {
11609299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org      data[i] = val >> (i * 8);
11709299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org    }
11809299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org  }
11909299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org};
12009299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org
12109299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org
12209299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org// -------- Below follows specializations for B in { 2, 4, 8 } --------
12309299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org
12409299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org
12509299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org// Specializations for two byte words
12609299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.orgtemplate<typename T, bool is_signed>
12709299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.orgclass ByteReader<T, 2, is_signed> {
12809299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org public:
12909299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org  static T ReadBigEndian(uint8_t* data) {
13009299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org    return (data[0] << 8) | data[1];
13109299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org  }
13209299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org
13309299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org  static T ReadLittleEndian(uint8_t* data) {
13409299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org    return data[0] | (data[1] << 8);
13509299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org  }
13609299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org};
13709299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org
13809299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.orgtemplate<typename T>
13909299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.orgclass ByteWriter<T, 2> {
14009299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org public:
14109299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org  static void WriteBigEndian(uint8_t* data, T val) {
14209299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org    data[0] = val >> 8;
14309299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org    data[1] = val;
14409299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org  }
14509299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org
14609299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org  static void WriteLittleEndian(uint8_t* data, T val) {
14709299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org    data[0] = val;
14809299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org    data[1] = val >> 8;
14909299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org  }
15009299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org};
15109299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org
15209299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org// Specializations for four byte words.
15309299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.orgtemplate<typename T, bool is_signed>
15409299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.orgclass ByteReader<T, 4, is_signed> {
15509299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org public:
15609299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org  static T ReadBigEndian(uint8_t* data) {
15709299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org    return (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3];
15809299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org  }
15909299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org
16009299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org  static T ReadLittleEndian(uint8_t* data) {
16109299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org    return data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24);
16209299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org  }
16309299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org};
16409299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org
16509299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org// Specializations for four byte words.
16609299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.orgtemplate<typename T>
16709299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.orgclass ByteWriter<T, 4> {
16809299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org public:
16909299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org  static void WriteBigEndian(uint8_t* data, T val) {
17009299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org    data[0] = val >> 24;
17109299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org    data[1] = val >> 16;
17209299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org    data[2] = val >> 8;
17309299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org    data[3] = val;
17409299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org  }
17509299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org
17609299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org  static void WriteLittleEndian(uint8_t* data, T val) {
17709299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org    data[0] = val;
17809299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org    data[1] = val >> 8;
17909299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org    data[2] = val >> 16;
18009299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org    data[3] = val >> 24;
18109299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org  }
18209299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org};
18309299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org
18409299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org// Specializations for eight byte words.
18509299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.orgtemplate<typename T, bool is_signed>
18609299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.orgclass ByteReader<T, 8, is_signed> {
18709299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org public:
18809299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org  static T ReadBigEndian(uint8_t* data) {
18909299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org    return
19009299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org        (Get(data, 0) << 56) | (Get(data, 1) << 48) |
19109299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org        (Get(data, 2) << 40) | (Get(data, 3) << 32) |
19209299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org        (Get(data, 4) << 24) | (Get(data, 5) << 16) |
19309299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org        (Get(data, 6) << 8)  |  Get(data, 7);
19409299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org  }
19509299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org
19609299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org  static T ReadLittleEndian(uint8_t* data) {
19709299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org    return
19809299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org         Get(data, 0)        | (Get(data, 1) << 8)  |
19909299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org        (Get(data, 2) << 16) | (Get(data, 3) << 24) |
20009299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org        (Get(data, 4) << 32) | (Get(data, 5) << 40) |
20109299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org        (Get(data, 6) << 48) | (Get(data, 7) << 56);
20209299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org  }
20309299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org
20409299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org private:
20509299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org  inline static T Get(uint8_t* data, unsigned int index) {
20609299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org    return static_cast<T>(data[index]);
20709299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org  }
20809299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org};
20909299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org
21009299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.orgtemplate<typename T>
21109299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.orgclass ByteWriter<T, 8> {
21209299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org public:
21309299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org  static void WriteBigEndian(uint8_t* data, T val) {
21409299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org    data[0] = val >> 56;
21509299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org    data[1] = val >> 48;
21609299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org    data[2] = val >> 40;
21709299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org    data[3] = val >> 32;
21809299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org    data[4] = val >> 24;
21909299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org    data[5] = val >> 16;
22009299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org    data[6] = val >> 8;
22109299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org    data[7] = val;
22209299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org  }
22309299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org
22409299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org  static void WriteLittleEndian(uint8_t* data, T val) {
22509299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org    data[0] = val;
22609299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org    data[1] = val >> 8;
22709299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org    data[2] = val >> 16;
22809299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org    data[3] = val >> 24;
22909299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org    data[4] = val >> 32;
23009299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org    data[5] = val >> 40;
23109299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org    data[6] = val >> 48;
23209299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org    data[7] = val >> 56;
23309299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org  }
23409299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org};
23509299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org
23609299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org}  // namespace webrtc
23709299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org
23809299b047d842ef0e4cb866979f1885b0176ba8bsprang@webrtc.org#endif  // WEBRTC_MODULES_RTP_RTCP_SOURCE_BYTE_IO_H_
239