tudocomp
– The TU Dortmund Compression Framework
BitOStream.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 #include <tudocomp/io/Output.hpp>
8 
9 namespace tdc {
10 namespace io {
11 
17 class BitOStream {
18  OutputStream m_stream;
19 
20  bool m_dirty;
21  uint8_t m_next;
22  int m_cursor;
23 
24  inline void reset() {
25  const int MSB = 7;
26 
27  m_next = 0;
28  m_cursor = MSB;
29  m_dirty = false;
30  }
31 
32  inline void write_next() {
33  if (m_dirty) {
34  m_stream.put(char(m_next));
35  reset();
36  }
37  }
38 
39 public:
43  inline BitOStream(OutputStream&& output) : m_stream(std::move(output)) {
44  reset();
45  }
46 
50  inline BitOStream(Output& output) : BitOStream(output.as_stream()) {
51  }
52 
54  char set = 7 - m_cursor;
55  if(m_cursor >= 2) {
56  m_next |= set;
57  } else {
58  write_next();
59  m_next = set;
60  }
61 
62  m_dirty = true;
63  write_next();
64  }
65 
73  inline auto tellp() -> decltype(m_stream.tellp()) {
74  return m_stream.tellp();
75  }
76 
79  inline void write_bit(bool set) {
80  if (set) {
81  m_next |= (1 << m_cursor);
82  }
83 
84  m_dirty = true;
85  if (--m_cursor < 0) {
86  write_next();
87  }
88  }
89 
97  template<class T>
98  inline void write_int(T value, size_t bits = sizeof(T) * CHAR_BIT) {
99  for (int i = bits - 1; i >= 0; i--) {
100  write_bit((value & T(T(1) << i)) != T(0));
101  }
102  }
103 
104  template<typename value_t>
105  inline void write_unary(value_t v) {
106  while(v--) {
107  write_bit(0);
108  }
109 
110  write_bit(1);
111  }
112 
113  template<typename value_t>
114  inline void write_ternary(value_t v) {
115  if(v) {
116  --v;
117  do {
118  write_int(v % 3, 2); // 0 -> 00, 1 -> 01, 2 -> 10
119  v /= 3;
120  } while(v);
121  }
122  write_int(3, 2); // terminator -> 11
123  }
124 
125  template<typename value_t>
126  inline void write_elias_gamma(value_t v) {
127  write_unary(bits_for(v));
128  write_int(v, bits_for(v));
129  }
130 
131  template<typename value_t>
132  inline void write_elias_delta(value_t v) {
134  write_int(v, bits_for(v));
135  }
136 
150  template<typename T>
151  inline void write_compressed_int(T v, size_t b = 7) {
152  DCHECK(b > 0);
153 
154  uint64_t u = uint64_t(v);
155  uint64_t mask = (u << b) - 1;
156  do {
157  uint64_t current = v & mask;
158  v >>= b;
159 
160  write_bit(v > 0);
161  write_int(current, b);
162  } while(v > 0);
163  }
164 };
165 
166 }}
167 
auto tellp() -> decltype(m_stream.tellp())
Returns the output position indicator of the underlying stream, which should equal the amount of byte...
Definition: BitOStream.hpp:73
Contains the text compression and encoding framework.
Definition: namespaces.hpp:11
void write_ternary(value_t v)
Definition: BitOStream.hpp:114
constexpr uint_fast8_t bits_for(size_t n)
Computes the number of bits required to store the given integer value.
Provides a character stream to the underlying output.
void write_bit(bool set)
Writes a single bit to the output.
Definition: BitOStream.hpp:79
void write_elias_gamma(value_t v)
Definition: BitOStream.hpp:126
void write_unary(value_t v)
Definition: BitOStream.hpp:105
BitOStream(OutputStream &&output)
Constructs a bitwise output stream.
Definition: BitOStream.hpp:43
std::streampos tellp()
Wrapper for output streams that provides bitwise writing functionality.
Definition: BitOStream.hpp:17
An abstraction layer for algorithm output.
Definition: Output.hpp:23
void write_compressed_int(T v, size_t b=7)
Writes a compressed integer to the input.
Definition: BitOStream.hpp:151
void write_elias_delta(value_t v)
Definition: BitOStream.hpp:132
void write_int(T value, size_t bits=sizeof(T) *CHAR_BIT)
Writes the bit representation of an integer in MSB first order to the output.
Definition: BitOStream.hpp:98
BitOStream(Output &output)
Constructs a bitwise output stream.
Definition: BitOStream.hpp:50