-
Notifications
You must be signed in to change notification settings - Fork 0
/
bitio.cc
87 lines (71 loc) · 2.24 KB
/
bitio.cc
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
/*
* A simple class to perform stream I/O on individual bits.
*/
#include "bitio.hh"
#include <cassert>
#include <climits>
// Construct with one of either an input stream or output (the other null)
BitIO::BitIO(std::ostream* os, std::istream* is){
//Assertion that only 1 argument is nullptr
assert((os == nullptr || is == nullptr) && !(os == nullptr && is == nullptr));
is_ = is;
os_ = os;
bit_index = 0;
buffer_ = 0;
}
// Flushes out any remaining output bits and trailing zeros, if any:
BitIO::~BitIO(){
if(os_){
if(0<bit_index){
// The output_bit function guarantees that buffer_ will have 0s
// in bits not yet written.
(*os_).put(buffer_);
}
}
}
// Output a single bit (buffered)
void BitIO::output_bit(bool bit){
// Assert that object is for writing
assert(is_ == nullptr);
// Clear the buffer from bits to prevent potential accidents if first 8 calls are 0
// and clear buffer_ every byte cycle.
if (bit_index == 0){
buffer_ = 0;
}
// case true is for writing bit in correct position
// case false is for the general action of incrementing index
switch (bit){
case true:{ buffer_ |= (1<<bit_index);
[[fallthrough]];
}
case false: ++bit_index;
}
// if a byte is complete, output it to the stream
// resetting buffer is delegated to the next call of the function.
if (bit_index == CHAR_BIT){
/* for debugging
std::string binary = std::bitset<CHAR_BIT>(buffer_).to_string();
std::cout<<"buffer_: " << binary << " , sent to os\n";
*/
(*os_).put(buffer_);
bit_index = 0;
}
}
// Read a single bit (or trailing zero)
bool BitIO::input_bit(){
// Assert that object is for reading
assert(os_ == nullptr);
// bit_index when function is called will be 0 only in the first call
if(bit_index == CHAR_BIT || bit_index == 0){
bit_index = 0;
(*is_).get(buffer_);
}
// post-increment index and return the bit
return (buffer_>>bit_index++) & 1;
}
// Check if EOF is reached
bool BitIO::reached_eof() {
// Assert that object is for reading
assert(os_ == nullptr);
return (*is_).eof();
}