Top |
#define | filemode_Write |
#define | filemode_Read |
#define | filemode_ReadWrite |
#define | filemode_WriteAppend |
All character output in Glk is done through streams. Every window has an output stream associated with it. You can also write to files on disk; every open file is represented by an output stream as well.
There are also input streams; these are used for reading from files on disk. It is possible for a stream to be both an input and an output stream.
Player input is done through line and character input events, not streams. This is a small inelegance in theory. In practice, player input is slow and things can interrupt it, whereas file input is immediate. If a network extension to Glk were proposed, it would probably use events and not streams, since network communication is not immediate.
It is also possible to create a stream that reads or writes to a buffer in memory.
Finally, there may be platform-specific types of streams, which are created before your program starts running.
For example, a program running under Unix may have access to standard input as a stream, even though there is no Glk call to explicitly open standard input. On the Mac, data in a Mac resource may be available through a resource-reading stream.
You do not need to worry about the origin of such streams; just read or write them as usual. For information about how platform-specific streams come to be, see Startup Options.
A stream is opened with a particular file mode, see the filemode_
constants
below.
In the stdio library, using fopen()
, filemode_Write
would be mode
"w"
; filemode_Read
would be mode "r"
;
filemode_ReadWrite
would be mode "r+"
. Confusingly,
filemode_WriteAppend
cannot be mode "a"
, because the stdio
spec says that when you open a file with mode "a"
, then
fseek()
doesn't work. So we have to use mode "r+"
for
appending. Then we run into the other stdio problem,
which is that "r+"
never creates a new file. So
filemode_WriteAppend
has to first open the file with
"a"
, close it, reopen with "r+"
, and then
fseek()
to the end of the file. For filemode_ReadWrite
, the process is
the same, except without the fseek()
— we begin at the beginning of
the file.
We must also obey an obscure geas of ANSI C "r+"
files: you
can't switch from reading to writing without doing an fseek()
in between.
Switching from writing to reading has the same restriction, except that an
fflush()
also works.
For information on opening streams, see the discussion of each specific type
of stream in The Types of Streams.
Remember that it is always possible that opening a stream will fail, in which
case the creation function will return NULL
.
Each stream remembers two character counts, the number of characters printed
to and read from that stream. The write-count is exactly one per
glk_put_char()
call; it is figured before any platform-dependent character
cookery.
For example, if a newline character is converted to linefeed-plus-carriage-return, the stream's count still only goes up by one; similarly if an accented character is displayed as two characters.
The read-count is exactly one per glk_get_char_stream()
call, as long as the
call returns an actual character (as opposed to an end-of-file token.)
Glk has a notion of the “current (output) stream”.
If you print text without specifying a stream, it goes to the current output
stream.
The current output stream may be NULL
, meaning that there isn't one.
It is illegal to print text to stream NULL
, or to print to the current
stream when there isn't one.
If the stream which is the current stream is closed, the current stream
becomes NULL
.
void
glk_stream_set_current (strid_t str
);
Sets the current stream to str
, which must be an output stream. You may set
the current stream to NULL
, which means the current stream is not set to
anything.
#define filemode_Write (0x01)
An output stream.
Corresponds to mode "w"
in the stdio library, using fopen()
.
#define filemode_Read (0x02)
An input stream.
Corresponds to mode "r"
in the stdio library, using fopen()
.
#define filemode_ReadWrite (0x03)
Both an input and an output stream.
Corresponds to mode "r+"
in the stdio library, using fopen()
.
#define filemode_WriteAppend (0x05)
An output stream, but the data will added to the end of whatever already existed in the destination, instead of replacing it.
Confusingly, filemode_WriteAppend
cannot be mode "a"
, because
the stdio spec says that when you open a file with mode "a"
,
then fseek()
doesn't work. So we have to use mode "r+"
for
appending. Then we run into the other stdio problem,
which is that "r+"
never creates a new file. So
filemode_WriteAppend
has to first open the file with
"a"
, close it, reopen with "r+"
, and then fseek()
to the end of the file. For filemode_ReadWrite
, the process is the same,
except without the fseek()
— we begin at the beginning of the file.