-
Notifications
You must be signed in to change notification settings - Fork 0
/
BinaryStdOut.h
158 lines (135 loc) · 3.91 KB
/
BinaryStdOut.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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
#include <bits/stdc++.h>
using namespace std;
#ifndef COMPRESSION_LIBRARY_BINARYSTDOUT_H
#define COMPRESSION_LIBRARY_BINARYSTDOUT_H
class BinaryStdOut {
private:
std::string file;
ofstream out; // output stream (standard output)
char buffer; // 8-bit buffer of bits to write
char n; // number of bits remaining in buffer
bool isInitialized; // has BinaryStdOut been called for first time?
// initialize BinaryStdOut
void initialize() {
out = ofstream (file, std::ios::binary);
buffer = 0;
n = 0;
isInitialized = true;
}
/**
* Writes the specified bit to standard output.
*/
void writeBit(bool bit) {
if (!isInitialized) initialize();
// add bit to buffer
buffer <<= 1;
if (bit) buffer |= 1;
// if buffer is full (8 bits), write out as a single byte
n++;
if (n == 8) clearBuffer();
}
/**
* Writes the 8-bit byte to standard output.
*/
void writeByte( unsigned char x) {
if (!isInitialized) initialize();
// optimized if byte-aligned
if (n == 0) {
try {
out.write(reinterpret_cast<char*>(&x), sizeof(x));
}
catch (exception & e) {
std::cout << e.what();
}
return;
}
// otherwise write one bit at a time
for (int i = 0; i < 8; i++) {
bool bit = ((x >> (8 - i - 1)) & 1) == 1;
writeBit(bit);
}
}
// write out any remaining bits in buffer to standard output, padding with 0s
void clearBuffer() {
if (!isInitialized) initialize();
if (n == 0) return;
if (n > 0) buffer <<= (8 - n);
try {
out.write(reinterpret_cast<char*>(&buffer), sizeof(buffer));
}
catch (exception & e) {
std::cout << e.what();
}
n = 0;
buffer = 0;
}
public:
explicit BinaryStdOut(std::string file) : file(std::move(file)){
initialize();
}
void flush() {
clearBuffer();
try {
out.flush();
}
catch (exception & e) {
std:: cout << e.what();
}
}
void close() {
flush();
try {
out.close();
isInitialized = false;
}
catch (exception & e) {
std::cout << e.what();
}
}
void write(bool x) {
writeBit(x);
}
void write(unsigned char x) {
// if (x < 0 || x >= 256) throw exception();
writeByte(x);
}
void write(int x, int r) {
if (r == 32) {
write(x);
return;
}
if (r < 1 || r > 32) throw exception();
if (x < 0 || x >= (1 << r)) throw exception();
for (int i = 0; i < r; i++) {
bool bit = (static_cast<unsigned char>(x >> (r - i - 1)) & 1) == 1;
writeBit(bit);
}
}
void write(int x) {
writeByte((static_cast<unsigned char>(x >> 24)) & 0xff);
writeByte((static_cast<unsigned char>(x >> 16)) & 0xff);
writeByte((static_cast<unsigned char>(x >> 8)) & 0xff);
writeByte((static_cast<unsigned char>(x >> 0)) & 0xff);
}
void write(char x, int r) {
if (r == 8) {
write(x);
return;
}
if (r < 1 || r > 16) throw exception();
if (x >= (1 << r)) throw exception();
for (int i = 0; i < r; i++) {
bool bit = (static_cast<unsigned char>(x >> (r - i - 1)) & 1) == 1;
writeBit(bit);
}
}
void write(string s) {
for (int i = 0; i < s.length(); i++)
write((unsigned char)s[i]);
}
void write(string s, int r) {
for (int i = 0; i < s.length(); i++)
write(s[i], r);
}
};
#endif //COMPRESSION_LIBRARY_BINARYSTDOUT_H