tudocomp
– The TU Dortmund Compression Framework
BitIStream.hpp
Go to the documentation of this file.
1 #pragma once
2 
3 #include <climits>
4 #include <cstdint>
5 #include <iostream>
6 #include <tudocomp/util.hpp>
7 
8 namespace tdc {
9 namespace io {
10 
16 class BitIStream {
17  InputStream m_stream;
18 
19  uint8_t m_current = 0;
20  uint8_t m_next = 0;
21 
22  bool m_is_final = false;
23  uint8_t m_final_bits = 0;
24 
25  uint8_t m_cursor = 0;
26 
27  inline void read_next() {
28  const uint8_t MSB = 7;
29 
30  m_current = m_next;
31  m_cursor = MSB;
32 
33  char c;
34  if(m_stream.get(c)) {
35  m_next = c;
36 
37  if(m_stream.get(c)) {
38  /*DLOG(INFO) << "read_next: ...";*/
39 
40  // stream still going
41  m_stream.unget();
42  } else {
43  // stream over after next, do some checks
44  m_final_bits = c;
45  m_final_bits &= 0x7;
46  if(m_final_bits >= 6) {
47  // special case - already final
48  m_is_final = true;
49  m_next = 0;
50  /*DLOG(INFO) << "read_next: EOF*" <<
51  ", m_final_bits := " << size_t(m_final_bits);*/
52  }
53  }
54  } else {
55  m_is_final = true;
56  m_final_bits = m_current & 0x7;
57 
58  m_next = 0;
59 
60  /*DLOG(INFO) << "read_next: EOF" <<
61  ", m_final_bits := " << size_t(m_final_bits);*/
62  }
63  }
64 
65 public:
69  inline BitIStream(InputStream&& input) : m_stream(std::move(input)) {
70  char c;
71  if(m_stream.get(c)) {
72  m_is_final = false;
73  m_next = c;
74 
75  read_next();
76  } else {
77  //empty stream
78  m_is_final = true;
79  m_final_bits = 0;
80  }
81  }
82 
86  inline BitIStream(Input& input) : BitIStream(input.as_stream()) {
87  }
88 
91  inline uint8_t read_bit() {
92  /*DLOG(INFO) <<"read_bit: " <<
93  "m_is_final = " << m_is_final <<
94  ", m_final_bits = " << size_t(m_final_bits) <<
95  ", m_cursor = " << size_t(m_cursor);*/
96 
97  if(!eof()) {
98  uint8_t bit = (m_current >> m_cursor) & 1;
99  if(m_cursor) {
100  --m_cursor;
101  } else {
102  read_next();
103  }
104 
105  return bit;
106  } else {
107  return 0; //EOF
108  }
109  }
110 
118  template<class T>
119  inline T read_int(size_t amount = sizeof(T) * CHAR_BIT) {
120  T value = 0;
121  for(size_t i = 0; i < amount; i++) {
122  value <<= 1;
123  value |= read_bit();
124  }
125  return value;
126  }
127 
128  template<typename value_t>
129  inline value_t read_unary() {
130  value_t v = 0;
131  while(!read_bit()) ++v;
132  return v;
133  }
134 
135  template<typename value_t>
136  inline value_t read_ternary() {
137  size_t mod = read_int<size_t>(2);
138  value_t v = 0;
139  if(mod < 3) {
140  size_t b = 1;
141  do {
142  v += mod * b;
143  b *= 3;
144  mod = read_int<size_t>(2);
145  } while(mod != 3);
146 
147  ++v;
148  }
149  return v;
150  }
151 
152  template<typename value_t>
153  inline value_t read_elias_gamma() {
154  auto bits = read_unary<size_t>();
155  return read_int<value_t>(bits);
156  }
157 
158  template<typename value_t>
159  inline value_t read_elias_delta() {
160  auto bits = read_elias_gamma<size_t>();
161  return read_int<value_t>(bits);
162  }
163 
174  template<typename T = size_t>
175  inline T read_compressed_int(size_t b = 7) {
176  DCHECK(b > 0);
177 
178  uint64_t value = 0;
179  size_t i = 0;
180 
181  bool has_next;
182  do {
183  has_next = read_bit();
184  value |= (read_int<size_t>(b) << (b * (i++)));
185  } while(has_next);
186 
187  return T(value);
188  }
189 
191  inline bool eof() const {
192  return m_is_final && m_cursor <= (7 - m_final_bits);
193  }
194 };
195 
196 }}
197 
T read_compressed_int(size_t b=7)
Reads a compressed integer from the input.
Definition: BitIStream.hpp:175
Contains the text compression and encoding framework.
Definition: namespaces.hpp:11
value_t read_elias_delta()
Definition: BitIStream.hpp:159
value_t read_elias_gamma()
Definition: BitIStream.hpp:153
value_t read_ternary()
Definition: BitIStream.hpp:136
Wrapper for input streams that provides bitwise reading functionality.
Definition: BitIStream.hpp:16
BitIStream(Input &input)
Constructs a bitwise input stream.
Definition: BitIStream.hpp:86
BitIStream(InputStream &&input)
Constructs a bitwise input stream.
Definition: BitIStream.hpp:69
Provides a character stream of the underlying input.
bool eof() const
TODO document.
Definition: BitIStream.hpp:191
uint8_t read_bit()
Reads the next single bit from the input.
Definition: BitIStream.hpp:91
T read_int(size_t amount=sizeof(T) *CHAR_BIT)
Reads the integer value of the next amount bits in MSB first order.
Definition: BitIStream.hpp:119
An abstraction layer for algorithm input.
Definition: Input.hpp:37