| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
gauche.vport - Virtual ports Virtual ports, or procedural ports, are the ports whose behavior can be programmed in Scheme.
This module provides two kinds of virtual ports: Fully virtual ports, in which every I/O operation invokes user-provided procedures, and virtual buffered ports, in which I/O operations are done on an internal buffer and user-provided procedures are called only when the buffer needs to be filled or flushed.
This module also provides virtual buffered ports backed up by a uniform vector, as an example of the feature.
This type of virtual ports are realized by classes
<virtual-input-port> and <virtual-output-port>.
You can customize the port behavior by setting
appropriate slots with procedures.
An instance of this class can be used as an input port. The behavior of the port depends on the settings of the instance slot values.
To work as a meaningful input port, at least either one of
getb or getc slot must be set. Otherwise,
the port returns EOF for all input requests.
If set, the value must be a procedure that takes no arguments. Every time binary input is required, the procedure is called.
The procedure must return an exact integer between 0 and 255
inclusive, or #f or an EOF object. If it returns an
integer, it becomes the value read from the port. If it returns
other values, the port returns EOF.
If the port is requested a character input and it doesn't have
the getc procedure, the port calls this procedure, possibly
multiple times, to construct a whole character.
If set, the value must be a procedure that takes no arguments. Every time character input is required, the procedure is called.
The procedure must return a character,
#f or an EOF object. If it returns a character,
it becomes the value read from the port. If it returns
other values, the port returns EOF.
If the port is requested a binary input and it doesn't have
the getb procedure, the port calls this procedure, then converts
a character into a byte sequence, and use it as the binary
value(s) read from the port.
If set, the value must be a procedure that takes one argument,
a positive exact integer. It is called when the block binary
input, such as read-block, is requested.
It must return a (maybe incomplete) string up to the specified size,
or #f or EOF object. If it returns a null string, #f
or EOF object,
the port thinks it reached EOF. If it returns other string,
it is used as the result of block read.
It shouldn't return a string larger than the given size
(Note: you must count size (bytes), not the number of characters).
The reason of this procedure is efficiency; if this procedure
is not provided, the port calls getb procedure repeatedly
to prepare the block of data. In some cases, providing block input
can be much more efficient (e.g. suppose you're reading from
a block of memory chunk).
You can leave this slot unset if you don't need to take such advantage.
If set, the value must be a procedure that takes one boolean argument.
It is called when char-ready? or byte-ready? is
called on the port. The value returned from your procedure will
be the result of these procedures.
The boolean argument is #t if
char-ready? is called, or #f if byte-ready? is called.
If unset, char-ready? and byte-ready?
always return #t on the port
If set, the value must be a procedure that takes no arguments. It is called when the port is closed. Return value is discarded. You can leave this unset if you don't need to take an action when the port is closed.
This procedure may be called from a finalizer, so you have to be careful to write it. See the note on finalization below.
If set, the value must be a procedure that takes two arguments,
offset and whence. The meaning of them is the same as the arguments
to port-seek (See section Common port operations).
The procedure must adjust the port's internal read pointer
so that the next read begins from the new pointer.
It should return the updated pointer (the byte offset from the
beginning of the port).
If unset, call of port-seek and port-tell on this
port will return #f.
Note that this procedure may be called for the purpose of merely
querying the current position, with 0 as offset and SEEK_CUR
as whence. If your port knows the read pointer but cannot move it,
you can still provide this procedure, which returns the current pointer
position for such queries and returns #f for other arguments.
An instance of this class can be used as an output port. The behavior of the port depends on the settings of the instance slot values.
To work as an output port, at least either one of putb or
putc slot has to be set.
If set, the value must be a procedure that takes one argument, a byte value (exact integer between 0 and 255, inclusive). Every time binary output is required, the procedure is called. The return value of the procedure is ignored.
If this slot is not set and binary output is requested,
the port may signal an <io-unit-error> error.
If set, the value must be a procedure that takes one argument, a character. Every time character output is required, the procedure is called. The return value of the procedure is ignored.
If this slot is not set but putb slot is set,
the virtual port decomposes the character into a sequence of bytes
then calls putb procedures.
If set, the value must be a procedure that takes a (possibly incomplete) string. The return value of the procedure is ignored.
This is for efficiency. If this slot is not set, the virtual port
calls putb or putc repeatedly to output a chunk of data.
But if your code can perform chunked output efficiently,
you can provide this procedure.
If set, the value must be a procedure that takes no arguments.
It is called when flushing a port is required (e.g. flush
is called on the port, or the port is being closed).
This procedure is useful that your port does some sort of buffering, or needs to keep some state. If your port doesn't do stateful operation, you can leave this unset.
This procedure may be called from a finalizer, and needs a special care. See notes on finalizers below.
The same as <virtual-input-port>'s close slot.
The same as <virtual-input-port>'s seek slot.
This type of virtual ports are realized by classes
<buffered-input-port> and <buffered-output-port>.
You can customize the port behavior by setting
appropriate slots with procedures.
Those ports have internal buffer and only calls Scheme procedures when the buffer needs to be filled or flushed. Generally it is far more efficient than calling Scheme procedures for every I/O operation. Actually, the internal buffering mechanism is the same as Gauche's file I/O ports.
These ports uses u8vector as a buffer. See gauche.uvector - Uniform vectors
for the details.
An instance of this class behaves as an input port.
It has the following instance slots. For a meaningful input
port, you have to set at least fill slot.
If set, it must be a procedure that takes one argument,
a u8vector. It must fill the data from the
beginning of the vector. It doesn't need to fill the entire
vector if there's not so many data. However, if there are remaining
data, it must fill at least one byte; if the data isn't readily
available, it has to wait until some data becomes available.
The procedure must return a number of bytes it actually filled. It may return 0 or an EOF object to indicate the port has reached EOF.
If set, it must be a procedure that takes no arguments.
The procedure must return a true value if there are some data
readily available to read, or #f otherwise.
Unlike fully virtual ports, you don't need to distinguish
binary and character I/O.
If this slot is not set, the port is regarded as it always has data ready.
If set, it must be a procedure that takes no arguments. The procedure is called when the virtual buffered port is closed. You don't need to set this slot unless you need some cleaning up when the port is closed.
This procedure may be called from a finalizer, and needs special care. See the note on finalization below.
If set, it must be a procedure that returns underlying
file descriptor number (exact nonnegative integer).
The procedure is called when port-file-number is called
on the port.
If there's no such underlying file descriptor, you can
return #f, or you can leave this slot unset.
If set, it must be a procedure that takes two arguments,
offset and whence.
It works the same way as <virtual-input-port>'s seek procedure;
see above.
This procedure may be called from a finalizer, and needs special care. See the note on finalization below.
Besides those slot values, you can pass an exact nonnegative integer
as the :buffer-size keyword argument to the make method
to set the size of the port's internal buffer. If :buffer-size
is omitted, or zero is passed, the system's default buffer size
(something like 8K) is used. :buffer-size is not an instance
slot and you cannot set it after the instance of the buffered port
is created. The following example specifies the buffered port
to use a buffer of size 64K:
(make <buffered-input-port> :buffer-size 65536 :fill my-filler) |
An instance of this class behaves as an output port.
It has the following instance slots.
You have to set at least flush slot.
If set, it must be a procedure that takes two arguments,
an u8vector buffer and a flag.
The procedure must output data in the buffer to somewhere,
and returns the number of bytes actually output.
If the flag is false, the procedure may output less than entire buffer (but at least one byte). If the flag is true, the procedure must output entire buffer.
Same as <buffered-input-port>'s close slot.
Same as <buffered-input-port>'s filenum slot.
Same as <buffered-input-port>'s seek slot.
Besides those slot values, you can pass an exact nonnegative integer
as the :buffer-size keyword argument to the make method
to set the size of the port's internal buffer. See the description
of <buffered-input-port> above for the details.
The following two procedures returns a buffered input/output port
backed up by a uniform vector. The source or destination vector
can be any type of uniform vector, but they are aliased
to u8vector (see uvector-alias in
Uvector conversion operations).
If used together with pack/unpack
(see binary.pack - Packing Binary Data), it is useful to parse
or construct binary data structure. It is also an
example of using virtual ports; read ‘gauche/vport.scm’
(or ‘ext/vport/vport.scm’ in the source tree) if you're
curious about the implementation.
Returns an input port that reads the content of the given uniform vector uvector from its beginning. If reading operation reaches the end of uvector, EOF is returned. Seek operation is also implemented.
Returns an output port that fills the given uvector by the data output to the port. If uvector is completely filled, more data are silently discarded. Seek operation is also implemented.
If an unclosed virtual port is garbage collected, its close procedure is called (in case of virtual buffered ports, its flush procedure may also be called before close procedure). It is done by a finalizer of the port. Since it is a part of garbage-collection process (although the Scheme procedure itself is called outside of the garbage collector main part), it requires special care.
flush procedure sends its output to
Y. However, if flush procedure can be called from a
finalizer, it may be possible that Y's finalizer has already been
called and Y is closed. So X's flush procedure
has to check if Y has not been closed.
close or flush of virtual ports
need to lock or access the global resource, it needs to take
extra care of avoiding dead lock or conflict of access.
Even in single thread programs, the finalizer can run anywhere in Scheme programs, so effectively it should be considered as running in a different thread.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] |
This document was generated by Shiro Kawai on October, 7 2008 using texi2html 1.78.