D. J. Bernstein

The buffer_get library interface

Buffered input

     #include <buffer.h>

     r = buffer_get(&b,x,len);

     buffer b;
     char *x;
     unsigned int len;
     int r;
Normally buffer_get copies data to x[0], x[1], ..., x[len-1] from the beginning of a string stored in preallocated space; removes these len bytes from the string; and returns len.

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

If the string is empty, buffer_get first uses a read operation to feed data into the string. The read operation may indicate end of input, in which case buffer_get returns 0; or a read error, in which case buffer_get returns -1, setting errno approporiately.

The preallocated space and the read operation are specified by b. You must initialize b as described below before calling buffer_get.

Initialization

     #include <buffer.h>

     buffer_init(&b,op,fd,y,ylen);

     buffer b;
     int (*op)(int,char *,int);
     int fd;
     char *y;
     unsigned int ylen;
buffer_init prepares b to store a string in y[0], y[1], ..., y[ylen-1]. Initially the string is empty.

buffer_init also prepares b to use the read operation specified by op and fd. buffer_flush obtains data d[0], d[1], ..., d[dlen-1] from the read operation by calling

     op(fd,d,dlen)
If op successfully reads one or more bytes into d, it must return the number of bytes read. If op encounters end of input, it must return 0. If op does not successfully read any bytes, does not encounter end of input, and does not encounter a read error, it must return -1 with errno set to error_intr; buffer_get will immediately call op again. If op encounters a read error, it must return -1 with errno set to something other than error_intr; buffer_get will pass the error to the caller.

You can use

     buffer b = BUFFER_INIT(op,fd,y,ylen);
to initialize b statically if op, fd, y, and ylen are compile-time constants.

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

Low-level input

     #include <buffer.h>

     r = buffer_feed(&b);
     x = buffer_peek(&b);
     buffer_seek(&b,r);

     buffer b;
     char *x;
     int r;
buffer_feed, buffer_peek, and buffer_seek are low-level components of buffer_get.

If the string is nonempty, buffer_feed returns the length of the string. If the string is empty, buffer_feed uses the read operation to feed data into the string; it then returns the new length of the string, or 0 for end of input, or -1 for error.

buffer_peek returns a pointer to the first byte of the string.

buffer_seek removes r bytes from the beginning of the string. r must be at least 0 and at most the current length of the string.

These functions can be used for efficient reading loops, nearly the same speed as calling op directly:

     for (;;) {
       r = buffer_feed(&b);
       if (r <= 0) return r;
       x = buffer_peek(&b);
       dosomething(x,r);
       buffer_seek(&b,r);
     }