Previous: C Port Interface, Up: I/O Extensions


5.12.10.2 Port Implementation

This section describes how to implement a new port type in C.

As described in the previous section, a port type object (ptob) is a structure of type scm_ptob_descriptor. A ptob is created by calling scm_make_port_type.

All of the elements of the ptob, apart from name, are procedures which collectively implement the port behaviour. Creating a new port type mostly involves writing these procedures.

scm_make_port_type initializes three elements of the structure (name, fill_input and write) from its arguments. The remaining elements are initialized with default values and can be set later if required.

name
A pointer to a NUL terminated string: the name of the port type. This is the only element of scm_ptob_descriptor which is not a procedure. Set via the first argument to scm_make_port_type.
mark
Called during garbage collection to mark any SCM objects that a port object may contain. It doesn't need to be set unless the port has SCM components. Set using scm_set_port_mark.
free
Called when the port is collected during gc. It should free any resources used by the port. Set using scm_set_port_free.
print
Called when write is called on the port object, to print a port description. e.g., for an fport it may produce something like: #<input: /etc/passwd 3>. Set using scm_set_port_print.
equalp
Not used at present. Set using scm_set_port_equalp.
close
Called when the port is closed, unless it was collected during gc. It should free any resources used by the port. Set using scm_set_port_close.
write
Accept data which is to be written using the port. The port implementation may choose to buffer the data instead of processing it directly. Set via the third argument to scm_make_port_type.
flush
Complete the processing of buffered output data. Reset the value of rw_active to SCM_PORT_NEITHER. Set using scm_set_port_flush.
end_input
Perform any synchronization required when switching from input to output on the port. Reset the value of rw_active to SCM_PORT_NEITHER. Set using scm_set_port_end_input.
fill_input
Read new data into the read buffer and return the first character. It can be assumed that the read buffer is empty when this procedure is called. Set via the second argument to scm_make_port_type.
input_waiting
Return a lower bound on the number of bytes that could be read from the port without blocking. It can be assumed that the current state of rw_active is SCM_PORT_NEITHER. Set using scm_set_port_input_waiting.
seek
Set the current position of the port. The procedure can not make any assumptions about the value of rw_active when it's called. It can reset the buffers first if desired by using something like:
                if (pt->rw_active == SCM_PORT_READ)
          	scm_end_input (object);
                else if (pt->rw_active == SCM_PORT_WRITE)
          	ptob->flush (object);
     

However note that this will have the side effect of discarding any data in the unread-char buffer, in addition to any side effects from the end_input and flush ptob procedures. This is undesirable when seek is called to measure the current position of the port, i.e., (seek p 0 SEEK_CUR). The libguile fport and string port implementations take care to avoid this problem.

The procedure is set using scm_set_port_seek.

truncate
Truncate the port data to be specified length. It can be assumed that the current state of rw_active is SCM_PORT_NEITHER. Set using scm_set_port_truncate.