A new stream is created using Snew().
Before we can create a stream we must create a function block of type IOFUNCTIONS
that provide function pointers for the basic operations on the stream.
This type is defined as follows:
typedef struct io_functions
{ Sread_function read; /* fill the buffer */
Swrite_function write; /* empty the buffer */
Sseek_function seek; /* seek to position */
Sclose_function close; /* close stream */
Scontrol_function control; /* Info/control */
Sseek64_function seek64; /* seek to position (large files) */
} IOFUNCTIONS;
- ssize_t (*Sread_function)(void
*handle, char *buf, size_t bufsize)
- Read new data into buf that has size bufsize,
return the number of bytes read or -1. Note that this is the same
interface as the POSIX read() API. See section
12.9.4 for raising errors.
- ssize_t (*Swrite_function)(void
*handle, char *buf, size_t bufsize)
- Write the bytes from buf with contains bufsize
bytes and return the number of bytes written or -1. The number of bytes
written may be less than bufsize. Bytes that were not written
remain in the stream's output buffer. Note that this is the same
interface as the POSIX write() API. See section
12.9.4 for raising errors.
- long (*Sseek_function)(void
*handle, long pos, int whence)
- int64_t (*Sseek64_function)(void
*handle, int64_t pos, int whence)
- Reposition the file pointer. These functions may be
NULL
if
repositioning is not possible on this type or they may return -1 and set
errno
to EPIPE
if the pointer cannot be
repositioned on this instance. The function returns the new file
position. See Sseek()
for details on how repositioning is implemented. See
section 12.9.4
for raising errors.
- int (*Sclose_function)(void
*handle)
- Close the stream. This is used by Sclose().
Note that buffered output is first written using the Swrite_function().
See section 12.9.4
for raising errors.
- int (*Scontrol_function)(void
*handle, int action, void *arg)
- Obtain information about the stream or modify the stream. The function
should return 0 on success and -1 on failure. If some action is not
implemented the function should return -1;
SIO_GETPENDING
, size_t*
- Return the number of bytes that may be written without blocking. Used by Spending().
SIO_LASTERROR
, char*
- Called after an error is raised on a stream. May return a C string that
sets error details using Sseterr().
SIO_SETENCODING
, IOENC*
- Called by Ssetenc()
to change the encoding of the stream. If the call does not return 0 the
encoding is not changed.
SIO_FLUSHOUTPUT
, NULL
- Called by Sflush()
after flushing the stream's output buffer. Note that this is only called
on an explicit flush using Sflush()
or flush_output/1.
An implicit flush because the output buffer is full does not
call this hook.
SIO_GETSIZE
, int64_t*
- Get the size of the underlying object in bytes. Used by Ssize().
SIO_GETFILENO
, int*
- If the stream is associated with an OS file handle, return this handle.
Used by Sfileno().
SIO_GETWINSOCK
, SOCKET*
- Windows only. If the stream is associated to a Windows socket return
this handle. Used by Swinsock().
Given an IOFUNCTIONS
block we can create a new stream
from a
handle using Snew():
- IOSTREAM* Snew(void
*handle, int flags, IOFUNCTIONS *functions)
- Create an
IOSTREAM*
from a handle, flags and a block of
callback functions. The flags argument is a bitwise or of
SIO_* flags. Flags that control the creation are:
SIO_INPUT
SIO_OUTPUT
- One of these flags mut be present to indicate whether this is an input
or output stream.
SIO_NBUF
SIO_LBUF
SIO_FBUF
- One of these flags must be present to select the buffering as one of
unbuffered (
SIO_NBUF
), line buffered (SIO_LBUF
)
or fully buffered (SIO_FBUF
)
SIO_TEXT
- If given, this is a text stream and the encoding is set to the default
encoding (see the Prolog flag encoding).
Otherwise this is a binary stream and the encoding is set to
ENC_OCTET
.
SIO_RECORDPOS
- If given, enable position maintenance on the stream. This is used by Stell(), Sseek(), stream_property/2
using the
position
property and related predicates.
SIO_NOMUTEX
- Used internally to create a stream that cannot be owned or locked.
If the stream is associated with an OS file handle the system
initializes the SIO_ISATTY
flag (on POSIX systems) and if
possible tells the OS not to inherit this stream to child processes.
The symbol Sfilefunctions
is a IOFUNCTIONS
struct that contains the callbacks for accessing a regular file. After
opening an file using the POSIX open() API we can create a stream to
this file using Snew():
int fno = open(path, O_RDONLY);
IOSTREAM *s;
if ( fno >= 0 )
s = Snew((void*)fno,
SIO_INPUT|SIO_FBUF|SIO_RECORDPOS|SIO_TEXT,
&Sfilefunctions);
...
Snew() can
only fail if there is not enough memory. In that case the return value
is NULL
and errno is set to ENOMEM
.
- IOSTREAM* Sopen_pipe(const
char *command, const char *type)
- Start a process from command and connect the input or output
to the returned stream. This wraps the POSIX popen() API. The type
string starts with
r
or w
and may be followed
by b
to create a binary stream. The default is to
create a text stream using the platform conventions and locale.
- IOSTREAM* Sopenmem(char
**buffer, size_t *sizep, const char *mode)
- Open a memory area as a stream. Output streams are automatically resized
using realloc() if *size = 0 or the stream is opened with
mode
"wa"
. If the buffer is allocated or enlarged, this is
achieved using malloc() or realloc(). In this case the returned buffer
should be freed by the caller when done. Example:
{ char buf[1024]; // don't allocate for small stuff
char *s = buf;
IOSTREAM *fd;
size_t size = sizeof(buf);
fd = Sopenmem(&s, &size, "w");
...
Sclose(fd);
...
if ( s != buf ) // appearently moved
Sfree(s);
}
The mode is "r"
or "w"
. The mode "rF"
calls
PL_free(buffer)
when closed.
Note: Its is not allowed to access streams created
with this call from multiple threads. This is ok for all usage inside
Prolog itself. This call is intended to use Sfprintf()
and other output functions to create strings.
- void Sfree(void
*ptr)
- This function must be used to free objects that are allocated by the
stream interface. Currently this only applies to strings allocated by Sopenmem().
A stream can be made accessible from Prolog using PL_unify_stream():
- int PL_unify_stream(term_t
t, IOSTREAM *s)
- Unify t with a blob that points at s.
Note that a blob provides a unique and reliable reference to a stream.
Blobs are subject to atom garbage collection. If an open stream
is garbage collected the behaviour depends on the Prolog flag
agc_close_streams.
See also Sgcclose().