summaryrefslogtreecommitdiff
path: root/man/buffer.3
blob: 2d4d0d2d5860bf733188bd607551d32fe2ba95d3 (plain)
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
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
.TH buffer 3
.SH NAME
buffer \- generic read/write buffering
.SH SYNTAX
.B #include \(dqbuffer.h\(dq

buffer* buffer_0;   /* like stdio's stdin */
.br
buffer* buffer_1;   /* like stdio's stdout */
.br
buffer* buffer_2;   /* like stdio's stderr */

void \fBbuffer_init\fR(buffer &\fIb\fR,ssize_t (*\fIop\fR)(int,char *,size_t),
                int \fIfd\fR, char *\fIy\fR, size_t \fIylen\fR);
.br
ssize_t \fBbuffer_get\fP(buffer *\fIb\fR,char *\fIx\fR,size_t \fIlen\fR);

int \fBbuffer_put\fP(buffer *\fIb\fR,const char *\fIx\fR,size_t \fIlen\fR);
.br
int \fBbuffer_puts\fP(buffer *\fIb\fR,const char *\fIx\fR);
.br
int \fBbuffer_putalign\fP(buffer *\fIb\fR,char *\fIx\fR,unsigned int \fIlen\fR);
.br
int \fBbuffer_putsalign\fP(buffer *\fIb\fR,char *\fIx\fR);

int \fBbuffer_putflush\fP(buffer *\fIb\fR,char *\fIx\fR,unsigned int \fIlen\fR);
.br
int \fBbuffer_putsflush\fP(buffer *\fIb\fR,char *\fIx\fR);

int \fBbuffer_flush\fP(buffer *\fIb\fR);
.br
int \fBbuffer_copy\fP(buffer *\fIbo\fR,buffer *\fIbi\fR);

int \fBbuffer_unixread\fP(int \fIfd\fR,char *\fIbuf\fR,size_t \fIlen\fR);
.br
int \fBbuffer_unixwrite\fP(int \fIfd\fR,char *\fIbuf\fR,size_t \fIlen\fR);
.SH DESCRIPTION
.B buffer.h 
describes a generic buffer interface that can be used for
read and write buffering. Buffers must be initialized with
\fBbuffer_init\fR.

A buffer can only be used for reading or writing at the same time, not
both.

Unlike 
.BR stdio ,
these write buffers are not flushed automatically at
program termination; you must manually call \fBbuffer_flush\fR,
\fBbuffer_putflush\fR, or \fBbuffer_putsflush\fR.

.B buffer_init 
prepares \fIb\fR to store a string in \fIy\fR[0], \fIy\fR[1], ...,
\fIy\fR[\fIylen\fR-1].  Initially the string is empty.

.B buffer_init 
also prepares \fIb\fR to use the read/write operation specified by
\fIop\fR and \fIfd\fR.

You can use

  buffer \fIb\fR = BUFFER_INIT(\fIop\fR,\fIfd\fR,\fIy\fR,\fIylen\fR);

to initialize \fIb\fR statically if \fIop\fR, \fIfd\fR, \fIy\fR, and \fIylen\fR
are compile-time constants.

You can call 
.B buffer_init 
again at any time. Note that this discards the currently buffered string.

.B buffer_get 
copies data to \fIx\fR[0], \fIx\fR[1], ...,
\fIx\fR[\fIlen\fR-1] from the beginning of a string stored in
preallocated space; removes these \fIlen\fR bytes from the string; and
returns \fIlen\fR.

If, however, the string has fewer than \fIlen\fR (but more than 0)
bytes, 
.I buffer_get 
copies only that many bytes, and returns that number.

If the string is empty, 
.B buffer_get 
first uses a \fBread operation\fR to
feed data into the string. The \fBread operation\fR may indicate end of
input.

The preallocated space and the \fBread operation\fR are specified by
\fIb\fR. You must initialize \fBb\fR using 
.B buffer_init 
before calling
.B buffer_get 
(or use the pre-initialized \fIbuffer_0\fR).

.B buffer_put 
writes \fIlen\fR bytes from \fIx\fR to \fIb\fR.

The difference to 
.B buffer_putalign 
is that, when there isn't enough space
for new data, 
.B buffer_put 
calls 
.B buffer_flush 
before copying any data, while 
.B buffer_putalign 
fills all available space with data before calling
.B buffer_flush.

.B buffer_copy
copies one buffer to other one. 
The output buffer needs to have at least the 
preallocated size of the input buffer.
.B buffer_unixread
and
.B buffer_unixwrite
perform the same operation like standard Unix
.B read
or 
.BR write.
.SH MACROS
Apart from this basic usage, some helpful macro 
definitions are provided:
.B BUFFER_INIT(op,fd,buf,len)
uses 
.I op
function to operate (read/write) on
.I buf
with 
.I len 
to file descriptor
.IR fd .
.B buffer_GETC(buf,c) 
returns the upmost position of character
.I c
within buffer
.I buf 
or 0.
.B buffer_PUTC(buf,c)
adds character
.I c
to buffer
.IR buf.
.SH EXAMPLE
  #include <buffer.h>
  #include <open.h>

  char buf[BUFFER_INSIZE]; // defined in buffer.h
  int fd = open_read("/etc/services");
  buffer input;

  if (fd >= 0) {
    char x;
    buffer_init(&input,read,fd,buf,sizeof buf);
    while (buffer_get(&input,&x,1) == 1) {
      buffer_put(buffer_1,&x,1);
      if (x == '\\n') break;
    }
    buffer_flush(buffer_1);
  }
.SH "RETURN CODES"
.B buffer_put 
and 
.B buffer_get
return
.I 0 
if everything was fine, 
.IR -1 ,
on error (setting \fIerrno\fR).
.B buffer_copy
returns
.IR -2 ,
if the input buffer can't be read, and
.IR -3 ,
if the data can't successfully copied 
to the output buffer. On success
.B buffer_copy 
returns 
.IR 0 .
.SH "REFERENCES"
https://cr.yp.to/lib/buffer_get.html

https://cr.yp.to/lib/buffer_put.html
.SH "SEE ALSO"
stdio(3)