-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathio.c
More file actions
168 lines (145 loc) · 3.86 KB
/
io.c
File metadata and controls
168 lines (145 loc) · 3.86 KB
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
159
160
161
162
163
164
165
166
167
168
#include "io.h"
#include "defines.h"
#include "io_extnd.h"
#include <fcntl.h> // open and close
#include <stdio.h> // Printing
#include <unistd.h> // read and write
// global
uint64_t bytes_read = 0; // total bytes read
uint64_t bytes_written = 0; // total bytes written
// private
uint8_t buf_code[BLOCK];
uint64_t buf_code_idx = 0;
uint8_t buf_code_idx_bit = 0;
//
// Read bytes from a file
//
// infile: file to read from
// buf: a pointer to a buffer
// nbytes: number of bytes to read
//
int read_bytes(int infile, uint8_t *buf, int nbytes) {
int b_read = 0; // bytes read so far
int last_read = 0; // bytes read on last
while ((b_read += read(infile, buf, nbytes - b_read)) < nbytes) {
if (last_read == b_read) { // if no bytes read
break;
}
last_read = b_read;
}
bytes_read += (uint64_t) b_read;
return b_read;
}
//
// Write bytes to a file
//
// infile: file to write to
// buf: a pointer to a buffer
// nbytes: number of bytes to write
//
int write_bytes(int outfile, uint8_t *buf, int nbytes) {
int b_written = 0; // bytes written so far
int last_written = 0; // bytes written on last
while ((b_written += write(outfile, buf, nbytes - b_written)) < nbytes) {
if (last_written == b_written) { // if no bytes written
break;
}
last_written = b_written;
}
bytes_written += (uint64_t) b_written;
return b_written;
}
//
// Write a Header to a file
//
// infile: file to write to
// h: a pointer to the Header
//
int read_header(int infile, Header *h) {
uint64_t b_read = 0; // bytes read so far
uint64_t last_read = 0; // bytes read on last
while ((b_read += read(infile, h, sizeof(Header) - b_read)) < sizeof(Header)) {
if (last_read == b_read) { // if no bytes read
break;
}
last_read = b_read;
}
bytes_read += b_read;
return b_read;
}
//
// Reads a Header to a file
//
// infile: file to write to
// h: a pointer to the Header
//
int write_header(int outfile, Header *h) {
uint64_t b_written = 0; // bytes written so far
uint64_t last_written = 0; // bytes written on last
while ((b_written += write(outfile, h, sizeof(Header) - b_written)) < sizeof(Header)) {
if (last_written == b_written) { // if no bytes written
break;
}
last_written = b_written;
}
bytes_written += b_written;
return bytes_written;
}
//
// Read bit by bit from a file
//
// infile: file to read from
// bit: buffer to store bit
//
bool read_bit(int infile, uint8_t *bit) {
static uint8_t buf[BLOCK];
static uint64_t b_read = 0;
static uint64_t buf_idx = 1;
static uint8_t buf_bit = 0;
if (buf_idx >= b_read) {
if ((b_read = read_bytes(infile, buf, BLOCK)) == 0) {
return false;
}
buf_bit = 0;
buf_idx = 0;
}
*bit = 1 & (buf[buf_idx] >> buf_bit++);
if (buf_bit > 7) {
buf_bit = 0;
buf_idx++;
}
return true;
}
//
// Write a Code to a file
//
// outfile: file to write top
// c: an address to a code to write
//
void write_code(int outfile, Code *c) {
for (uint64_t i = 0; i < code_size(c); i++) {
if (buf_code_idx_bit == 0) {
buf_code[buf_code_idx] = 0;
}
buf_code[buf_code_idx] |= ((c->bits[i / 8] >> i % 8) & 1) << buf_code_idx_bit++;
if (buf_code_idx_bit >= 8) {
buf_code_idx++;
buf_code_idx_bit = 0;
}
if (buf_code_idx > BLOCK) {
write_bytes(outfile, buf_code, buf_code_idx + (buf_code_idx_bit == 0 ? 0 : 1));
buf_code_idx_bit = 0;
buf_code_idx = 0;
}
}
return;
}
//
// Write any codes still in buffer
//
// outfile: file to write to
//
void flush_codes(int outfile) {
write_bytes(outfile, buf_code, buf_code_idx + (buf_code_idx_bit == 0 ? 0 : 1));
return;
}