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
|
#include "impl.h"
struct bufio·Writer
{
io·Writer w;
Buffer buf;
};
// Constructor/destructor.
bufio·Writer*
bufio·newwriter(io·Writer w)
{
bufio·Writer* bw = newbuffer(offsetof(bufio·Writer, buf), 0);
bw->w = w;
bw->buf.pos = bw->buf.base;
return bw;
}
error
bufio·freewriter(bufio·Writer* w)
{
free(w);
return 0;
}
// Write will write n bytes from the input buffer into the storage buffer.
// Returns the actual number of bytes written.
int
bufio·write(bufio·Writer* w, byte* buf, int count)
{
int remain = count;
byte* wtr = buf;
int n, nw;
while (remain > 0) {
int bdiff = w->buf.end - w->buf.pos;
n = (bdiff > remain) ? remain : bdiff;
if (!n) {
if (w->buf.eof) break;
nw = w->w.write(w->w.impl, buf, count);
if (nw < w->buf.size) {
w->buf.eof = 1;
return BUF·err;
}
w->buf.off += nw;
w->buf.pos = w->buf.base;
}
memmove(w->buf.pos, wtr, n);
wtr += n;
w->buf.pos += n;
remain -= n;
}
return count - remain;
}
error
bufio·put(bufio·Writer* w, byte c)
{
int diff;
putbyte:
diff = w->buf.end - w->buf.pos;
if (diff) {
*w->buf.pos++ = c;
return 0;
}
if (bufio·flush(w) != BUF·err) goto putbyte;
return BUF·err;
}
error
bufio·flush(bufio·Writer* w)
{
int active = (w->buf.eof == 0);
int n, nw;
if (active && w) {
n = w->buf.pos - w->buf.base;
if (!n) return 0;
nw = w->w.write(w->w.impl, w->buf.base, n);
if (nw == n) {
w->buf.off += n;
return 0;
}
w->buf.eof = 1;
w->buf.pos = w->buf.end;
}
return BUF·err;
}
|