regexps.com
These functions allow you to perform buffered I/O on descriptors using the VU functions. (See A Virtual Unix File-System Interface.)
Each buffered file is associated with these values:
t_uchar * buffer; Storage for buffered characters. The location of the buffer in memory may change over time.
long bufsize The size of the buffer.
t_uchar * read_write_position; The read/write position, within the buffer. This corresponds to the file offset returned by: vu_lseek (&errn, fd, 0, SEEK_CUR)
long buffered; The number of buffered characters relative to the read/write position.
All bytes between `buffer' and `read_write_position + buffered' are buffered.
Note that `buffered' may be negative if the `read_write_position' is beyond the current end of the file.
Normal I/O functions like vu_read
and vu_write
operate
in the expected way: they buffer characters or read characters
from the buffer, flushing or refilling it as needed.
For high-performance I/O, there is assistance for performing buffered I/O without copying characters to and from the buffer:
vfdbuf_getbuf vfdbuf_takebuf vfdbuf_set_buffer vfdbuf_more vfdbuf_advance
which are documented later in this chapter.
Buffers can be designated dont_flush
-- which means that the buffer
grows rather than writing to an underlying file. In combination with
pseudo-descriptors (see reserv_pseudo), dont_flush
buffers
can be used to implement in-core files (files which are actually
strings).
Buffers can be designated zero_byte
-- which means that an extra
byte is added to the buffer (at buffer + bufsize
) and that byte
is initialized to 0
.
int vfdbuf_buffer_fd (int * errn, int fd, long bufsize, int flags, int buffer_flags);
Arrange to buffer I/O on descriptor fd
.
fd
is the descriptor to buffer.
bufsize
is the initial size of the buffer or 0
to use a buffer of
the default size.
flags
indicates whether to buffer for input (O_RDONLY
),
output (O_WRONLY
) or both (O_RDWR
).
WARNING: I am fairly sure that there are bugs in the
buffering code, especially for O_RDWR
files. Some
comprehensive unit tests are needed for this module.
buffer_flags
is a combination (|
) of any of the bits:
vfdbuf_add_zero_byte vfdbuf_auto_shift
If vfdbuf_add_zero_byte
is set, the actual buffer size for this
descriptor is one byte larger than bufsize
(even if the buffer is
reallocated). The extra byte is initialized to 0
.
If vfdbuf_auto_shift
is set, the behavior of vfdbuf_more
is
modified. See vfdbuf_more.
If fd
is already buffered, this function attempts to reset the
buffer size, flags, and buffer flags. If more than bufsize
characters are already buffered, the resulting buffer will be
larger than bufsize
.
Return 0
on success, -1
(and set *errn
) on error.
int vfdbuf_set_buffer (int * errn, int fd, t_uchar * buffer, long bufsize, long read_write_pos, long buffered, int add_zero_byte, void (*free_buffer)(t_uchar * buf, void * closure), void * free_buffer_closure)
Establish a specific region of memory as the buffer for fd
.
See Buffered File Descriptors and vfdbuf_buffer_fd.
int vfdbuf_is_buffered (int fd);
Return 1
if fd has a (vfdbuf) buffer, 0
otherwise.
Function
vfdbuf_set_dont_flush
int vfdbuf_set_dont_flush (int * errn, int fd, int setting);
Activate or deactivate buffer flushing for descriptor fd
.
setting
is 0
to deactivate and any other value to activate
flushing.
If flushing is deactivated, writes may cause the size of the buffer
to be increased and calls to vfdbuf_flush
have no effect.
Return -1
and EINVAL if fd
is not buffered, 0
otherwise.
See also vfdbuf_is_dont_flush.
int vfdbuf_is_dont_flush (int * errn, int fd);
Return 0
if fd is buffered and flushing is enabled,
a positive value if fd is buffered and flushing is disabled.
Return -1
and EINVAL if fd is not buffered.
Function
vfdbuf_set_auto_shift
int vfdbuf_set_auto_shift (int * errn, int fd, int setting);
Activate or deactivate buffer auto-shift for descriptor fd
.
setting
is 0
to deactivate and any other value to activate
auto-shift.
See vfdbuf_more.
Return -1
and EINVAL if fd
is not buffered, 0
otherwise.
See also vfdbuf_is_auto_shift.
int vfdbuf_is_auto_shift (int * errn, int fd);
Return 0
if fd is buffered and auto-shift is disabled,
a positive value if fd is buffered and auto-shift is enabled.
Return -1
and EINVAL if fd is not buffered.
int vfdbuf_getbuf (int * errn, t_uchar ** buffer, long * bufsize, t_uchar ** read_write_position, long * buffered, int fd);
Return the address and size of the buffer and the address (within
that buffer) and number of buffered characters beyond the
read/write position for descriptor fd
.
Upon return, *buf
is the read/write position and *buffered
is
the number of buffered characters beyond that position. If
*buffered
is less than 0
, then the characters between *buffer
and *buffer - *buffered
are not yet part of the file (the read/write
position is beyond the end of the file).
Any of buffer
, bufsize
, read_write_pos
or buffered
may be
0
.
Return -1
and EINVAL if fd
is not buffered, 0
otherwise.
int vfdbuf_takebuf (int * errn, t_uchar ** bufbase, long * bufsize, t_uchar ** read_write_pos, long * buffered, int fd, void (*free_buffer)(t_uchar * buf, void * closure), void * free_buffer_closure);
Return the address of and size of the buffer for fd
. Also return
the address of and number of buffered characters beyond the
read/write position. (See vfdbuf_getbuf
.)
Responsibility for freeing the buffer returned (allocated by
must_malloc
) rests with the caller. vfdbuf
functions will continue
to use the buffer. When the vfdbuf
functions no longer require
the buffer, they call free_buffer
:
free_buffer (buffer, free_buffer_closure)
Subsequent calls to vfdbuf_takebuf
, made before free_buffer
is
called will return the same buffer if the same values are passed
for free_buffer
and free_buffer_closure
and a newly allocated
buffer otherwise.
int vfdbuf_shift (int * errn, int fd, long amt);
WARNING: there is a note in the code that says documentation for this function is out of date.
Discard amt
leading characters from a buffer, shifting any
remaining characters to make room at the end of the buffer.
If the
don't flush
flag is set for this buffer, this call will
increase the size of the buffer by amt
characters and leave existing
characters untouched.
If amt
is larger than the number of buffered characters that
preceed the read/write position, or if amt
is -1
, the effect is
the same as if amt
were exactly the number of buffered characters
that preceed the read/write position.
If the buffer is being used for output, this call will first flush
shifted characters that are currently part of the file. If there
are characters in the buffer beyond the end of the file, however, they
are not flushed by this function. The effect is that this function
will not make a file larger. (See vfdbuf_buffer_to_position
.)
Return 0
upon success, -1
upon error. This function can fail for a
descriptor opened for writing if it was necessary to flush
characters from the buffer, but the flush operation failed.
One useful post-condition of this function is that there is room
for amt
more characters beyond the read/write position after a
call to this function than were available before.
Another useful post-condition is that the read/write position
within the file is not changed by this function. (See
vfdbuf_advance
.)
int vfdbuf_advance (int * errn, int fd, long amt);
Advance the read/write position of a buffered descriptor.
If amt
is larger than the number of buffered characters beyond
the read/write position, the size of the buffer is increased, and
the new characters initialized to 0
, but no new characters are read
from the descriptor.
One or more calls this function are commonly followed by a call
to vfdbuf_shift
to discard the advanced-over characters from the
buffer. A good time to make such a call is before a call to
vfdbuf_more
, if it is safe to discard characters from the buffer
at that time.
Return -1
and EINVAL if fd
is not buffered, 0
otherwise.
int vfdbuf_flush (int * errn, int fd);
Write buffered characters prior to the read/write position to disk.
This function has no effect if descriptor fd
is not buffered, or
if the
don't flush
flag is set for this descriptor. (See
vfdbuf_set_dont_flush
.)
Flushed characters are removed from the buffer.
The read/write position may be past the last character of the file.
In that case, only the characters in the file are flushed to disk.
(See vfdbuf_buffer_to_position
.)
Return 0
upon success, -1
upon error.
int vfdbuf_return (int * errn, int fd, t_uchar * str, long len);
Add characters to the buffer for descriptor fd
.
Characters are inserted immediately after the read/write position
so that subsequent reads on this descriptor return those characters
first and subsequent writes overwrite them. Subsequent flushes of
a writable descriptor will ignore these characters unless the
read/write position is first advanced by a write or by
vfdbuf_advance
.
If fd
is a read-only descriptor, buffered characters prior to
the read/write position may be overwritten.
The read/write position of the descriptor is unchanged relative to the beginning of the file by calls to this function.
int vfdbuf_more (int * errn, t_uchar ** buffer, long * bufsize, t_uchar ** read_write_pos, long * buffered, int fd, long opt_amt);
Buffer (by reading) additional characters for descriptor fd
.
Return the address of and number of buffered unread characters
(including previously buffered but unread characters).
opt_amt
is the number of additional characters to read or 0
to
read a default number of additional characters.
Ordinarily, no characters are discarded from the buffer by this
function. (See vfdbuf_advance
and vfdbuf_shift
.)
If the buffer was created with the flag vfdbuf_auto_shift
,
opt_amt
is 0
, and the last buffered character is more than 3/4 of
the way through the buffer's allocated memory, then vfdbuf_more
will call vfdbuf_shift
before doing anything else. This is the
only circumstance under which vfdbuf_more
will discard characters
from a buffer.
The read/write position is not changed by this function.
Return -1
upon error, the number of characters read upon success.
int vfdbuf_is_eof (int * errn, int fd);
Return 1
value if the end of file has been reached while
reading from buffered descriptor fd
, 0
otherwise.
Return -1
and EINVAL if fd
is not a buffered descriptor.
void vfdbuf_clear_eof (int * errn, int fd);
Clear the eof flag for buffered file descriptor fd
.
Return -1
and EINVAL if fd
is not a buffered descriptor.
regexps.com