[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

38. Lstreams

An lstream is an internal Lisp object that provides a generic buffering stream implementation. Conceptually, you send data to the stream or read data from the stream, not caring what’s on the other end of the stream. The other end could be another stream, a file descriptor, a stdio stream, a fixed block of memory, a reallocating block of memory, etc. The main purpose of the stream is to provide a standard interface and to do buffering. Macros are defined to read or write characters, so the calling functions do not have to worry about blocking data together in order to achieve efficiency.

Lstreams seem to be similar to Python 2.5 generators/coroutines. David Beasley’s tutorials on generators and coroutines are an excellent resource.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

38.1 Creating an Lstream

Lstreams come in different types, depending on what is being interfaced to. Although the primitive for creating new lstreams is Lstream_new(), generally you do not call this directly. Instead, you call some type-specific creation function, which creates the lstream and initializes it as appropriate for the particular type.

All lstream creation functions take a mode argument, specifying what mode the lstream should be opened as. This controls whether the lstream is for input and output, and optionally whether data should be blocked up in units of MULE characters. Note that some types of lstreams can only be opened for input; others only for output; and others can be opened either way. #### Richard Mlynarik thinks that there should be a strict separation between input and output streams, and he’s probably right.

mode is a string, one of


Open for reading.


Open for writing.


Open for reading, but “read” never returns partial MULE characters.


Open for writing, but never writes partial MULE characters.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

38.2 Lstream Types


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

38.3 Lstream Functions

Function: Lstream * Lstream_new (Lstream_implementation *imp, const char *mode)

Allocate and return a new Lstream. This function is not really meant to be called directly; rather, each stream type should provide its own stream creation function, which creates the stream and does any other necessary creation stuff (e.g. opening a file).

Function: void Lstream_set_buffering (Lstream *lstr, Lstream_buffering buffering, int buffering_size)

Change the buffering of a stream. See ‘lstream.h’. By default the buffering is STREAM_BLOCK_BUFFERED.

Function: int Lstream_flush (Lstream *lstr)

Flush out any pending unwritten data in the stream. Clear any buffered input data. Returns 0 on success, -1 on error.

Macro: int Lstream_putc (Lstream *stream, int c)

Write out one byte to the stream. This is a macro and so it is very efficient. The c argument is only evaluated once but the stream argument is evaluated more than once. Returns 0 on success, -1 on error.

Macro: int Lstream_getc (Lstream *stream)

Read one byte from the stream. This is a macro and so it is very efficient. The stream argument is evaluated more than once. Return value is -1 for EOF or error.

Macro: void Lstream_ungetc (Lstream *stream, int c)

Push one byte back onto the input queue. This will be the next byte read from the stream. Any number of bytes can be pushed back and will be read in the reverse order they were pushed back—most recent first. (This is necessary for consistency—if there are a number of bytes that have been unread and I read and unread a byte, it needs to be the first to be read again.) This is a macro and so it is very efficient. The c argument is only evaluated once but the stream argument is evaluated more than once.

Function: int Lstream_fputc (Lstream *stream, int c)
Function: int Lstream_fgetc (Lstream *stream)
Function: void Lstream_fungetc (Lstream *stream, int c)

Function equivalents of the above macros.

Function: Bytecount Lstream_read (Lstream *stream, void *data, Bytecount size)

Read size bytes of data from the stream. Return the number of bytes read. 0 means EOF. -1 means an error occurred and no bytes were read.

Function: Bytecount Lstream_write (Lstream *stream, void *data, Bytecount size)

Write size bytes of data to the stream. Return the number of bytes written. -1 means an error occurred and no bytes were written.

Function: void Lstream_unread (Lstream *stream, void *data, Bytecount size)

Push back size bytes of data onto the input queue. The next call to Lstream_read() with the same size will read the same bytes back. Note that this will be the case even if there is other pending unread data.

Function: int Lstream_close (Lstream *stream)

Close the stream. All data will be flushed out.

Function: void Lstream_reopen (Lstream *stream)

Reopen a closed stream. This enables I/O on it again. This is not meant to be called except from a wrapper routine that reinitializes variables and such—the close routine may well have freed some necessary storage structures, for example.

Function: void Lstream_rewind (Lstream *stream)

Rewind the stream to the beginning.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

38.4 Lstream Methods

Lstream Method: Bytecount reader (Lstream *stream, unsigned char *data, Bytecount size)

Read some data from the stream’s end and store it into data, which can hold size bytes. Return the number of bytes read. A return value of 0 means no bytes can be read at this time. This may be because of an EOF, or because there is a granularity greater than one byte that the stream imposes on the returned data, and size is less than this granularity. (This will happen frequently for streams that need to return whole characters, because Lstream_read() calls the reader function repeatedly until it has the number of bytes it wants or until 0 is returned.) The lstream functions do not treat a 0 return as EOF or do anything special; however, the calling function will interpret any 0 it gets back as EOF. This will normally not happen unless the caller calls Lstream_read() with a very small size.

This function can be NULL if the stream is output-only.

Lstream Method: Bytecount writer (Lstream *stream, const unsigned char *data, Bytecount size)

Send some data to the stream’s end. Data to be sent is in data and is size bytes. Return the number of bytes sent. This function can send and return fewer bytes than is passed in; in that case, the function will just be called again until there is no data left or 0 is returned. A return value of 0 means that no more data can be currently stored, but there is no error; the data will be squirreled away until the writer can accept data. (This is useful, e.g., if you’re dealing with a non-blocking file descriptor and are getting EWOULDBLOCK errors.) This function can be NULL if the stream is input-only.

Lstream Method: int rewinder (Lstream *stream)

Rewind the stream. If this is NULL, the stream is not seekable.

Lstream Method: int seekable_p (Lstream *stream)

Indicate whether this stream is seekable—i.e. it can be rewound. This method is ignored if the stream does not have a rewind method. If this method is not present, the result is determined by whether a rewind method is present.

Lstream Method: int flusher (Lstream *stream)

Perform any additional operations necessary to flush the data in this stream.

Lstream Method: int pseudo_closer (Lstream *stream)
Lstream Method: int closer (Lstream *stream)

Perform any additional operations necessary to close this stream down. May be NULL. This function is called when Lstream_close() is called or when the stream is garbage-collected. When this function is called, all pending data in the stream will already have been written out.

Lstream Method: Lisp_Object marker (Lisp_Object lstream, void (*markfun) (Lisp_Object))

Mark this object for garbage collection. Same semantics as a standard Lisp_Object marker. This function can be NULL.

[ << ] [ >> ]           [Top] [Contents] [Index] [ ? ]

This document was generated by Aidan Kehoe on December 27, 2016 using texi2html 1.82.