16 #ifndef hifi_ByteCountCoding_h
17 #define hifi_ByteCountCoding_h
29 #include "SharedUtil.h"
31 #include "NumericalConstants.h"
33 template<
typename T>
class ByteCountCoded {
36 ByteCountCoded(T input = 0) : data(input) {
38 assert(!std::numeric_limits<T>::is_signed && std::numeric_limits<T>::is_integer);
41 ByteCountCoded(
const QByteArray& fromEncoded) : data(0) { decode(fromEncoded); }
43 QByteArray encode()
const;
44 size_t decode(
const QByteArray& fromEncoded);
45 size_t decode(
const char* encodedBuffer,
int encodedSize);
47 bool operator==(
const ByteCountCoded& other)
const {
return data == other.data; }
48 bool operator!=(
const ByteCountCoded& other)
const {
return data != other.data; }
49 bool operator!()
const {
return data == 0; }
51 operator QByteArray()
const {
return encode(); };
52 operator T()
const {
return data; };
55 template<
typename T>
inline QByteArray& operator<<(QByteArray& out,
const ByteCountCoded<T>& value) {
59 template<
typename T>
inline QByteArray& operator>>(QByteArray& in, ByteCountCoded<T>& value) {
64 template<
typename T>
inline QByteArray ByteCountCoded<T>::encode()
const {
67 int totalBits =
sizeof(data) * BITS_IN_BYTE;
68 int valueBits = totalBits;
69 bool firstValueFound =
false;
71 T lastBitMask = (T)(1) << (totalBits - 1);
74 for (
int bitAt = 0; bitAt < totalBits; bitAt++) {
75 T bitValue = (temp & lastBitMask) == lastBitMask;
76 if (!firstValueFound) {
80 firstValueFound =
true;
89 int numberOfBytes = (valueBits / (BITS_IN_BYTE - 1)) + 1;
91 output.fill(0, numberOfBytes);
94 for(
int i = 0; i < numberOfBytes; i++) {
96 T bitValue = (i < (numberOfBytes - 1) ? 1 : 0);
97 char original = output.at(outputIndex / BITS_IN_BYTE);
98 int shiftBy = BITS_IN_BYTE - ((outputIndex % BITS_IN_BYTE) + 1);
99 char thisBit = ( bitValue << shiftBy);
100 output[i / BITS_IN_BYTE] = (original | thisBit);
105 for(
int i = numberOfBytes; i < (numberOfBytes + valueBits); i++) {
107 T bitValue = (temp & 1);
108 char original = output.at(outputIndex / BITS_IN_BYTE);
109 int shiftBy = BITS_IN_BYTE - ((outputIndex % BITS_IN_BYTE) + 1);
110 char thisBit = ( bitValue << shiftBy);
111 output[i / BITS_IN_BYTE] = (original | thisBit);
118 template<
typename T>
inline size_t ByteCountCoded<T>::decode(
const QByteArray& fromEncodedBytes) {
119 return decode(fromEncodedBytes.constData(), fromEncodedBytes.size());
122 template<
typename T>
inline size_t ByteCountCoded<T>::decode(
const char* encodedBuffer,
int encodedSize) {
124 size_t bytesConsumed = 0;
125 int bitCount = BITS_IN_BYTE * encodedSize;
127 int encodedByteCount = 1;
129 bool inLeadBits =
true;
131 int expectedBitCount;
132 int lastValueBit = 0;
135 for(
int byte = 0;
byte < encodedSize;
byte++) {
136 char originalByte = encodedBuffer[byte];
138 unsigned char maskBit = 128;
139 for(
int bit = 0; bit < BITS_IN_BYTE; bit++) {
140 bool bitIsSet = originalByte & maskBit;
149 expectedBitCount = (encodedByteCount * BITS_IN_BYTE) - leadBits;
150 lastValueBit = expectedBitCount + bitAt;
153 if (expectedBitCount > (bitCount - leadBits)) {
158 if (bitAt > lastValueBit) {
168 maskBit = maskBit >> 1;
170 if (!inLeadBits && bitAt > lastValueBit) {
174 return bytesConsumed;