-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathbitinterface.h
127 lines (103 loc) · 2.9 KB
/
bitinterface.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#ifndef JWUTIL_BITITERATOR_H
#define JWUTIL_BITITERATOR_H
#include "huffmanmodel.h"
namespace jw_util
{
template <typename DataType = unsigned int>
class BitInterface
{
public:
BitInterface()
{}
BitInterface(DataType *data)
: data(data)
, cur_bit(0)
{}
template <typename NumberType>
NumberType read_number_raw(unsigned int bits)
{
static_assert(std::is_integral<NumberType>::value, "Unexpected template type, must be integral");
static_assert(std::is_unsigned<NumberType>::value, "Unexpected template type, must be unsigned");
NumberType num = 0;
for (unsigned int i = 0; i < bits; i++)
{
num |= static_cast<NumberType>(read_bit()) << i;
}
return num;
}
template <unsigned int options>
unsigned int read_number_huffman(const HuffmanModel<options> &model)
{
typename HuffmanModel<options>::Reader reader(model);
while (reader.needs_bit())
{
reader.recv_bit(read_bit());
}
return reader.get_result();
}
bool read_bit()
{
load_word();
bool val = (*data >> cur_bit) & 1;
cur_bit++;
return val;
}
template <typename NumberType>
void write_number_raw(NumberType num, unsigned int bits)
{
static_assert(std::is_integral<NumberType>::value, "Unexpected template type, must be integral");
static_assert(std::is_unsigned<NumberType>::value, "Unexpected template type, must be unsigned");
for (unsigned int i = 0; i < bits; i++)
{
write_bit(num & 1);
num >>= 1;
}
}
template <unsigned int options>
void write_number_huffman(const HuffmanModel<options> &model, unsigned int num)
{
write_number_huffman(HuffmanModel<options>::Writer(model, num));
}
template <unsigned int options>
void write_number_huffman(typename HuffmanModel<options>::Writer writer)
{
while (writer.has_bit())
{
write_bit(writer.get_bit());
writer.next_bit();
}
}
void write_bit(bool bit)
{
load_word();
*data |= bit << cur_bit;
cur_bit++;
}
void advance_bits(unsigned int bits) const
{
data += bits / bits_per_element;
cur_bit = bits % bits_per_element;
}
unsigned int get_element_delta(const DataType *start) const
{
return data - start + (cur_bit ? 1 : 0);
}
unsigned int get_bit_delta(const DataType *start) const
{
return (data - start) * bits_per_element + cur_bit;
}
private:
static constexpr unsigned int bits_per_element = sizeof(DataType) * CHAR_BIT;
DataType *data;
unsigned int cur_bit;
void load_word()
{
if (cur_bit == bits_per_element)
{
data++;
cur_bit = 0;
}
}
};
}
#endif // JWUTIL_BITITERATOR_H