<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->
<!-- %% -->
<!-- %W  streams.msk               GAP documentation              Frank Celler -->
<!-- %W                                                       Martin Schönert -->
<!-- %W                                                         & Steve Linton -->
<!-- %% -->
<!-- %H  @(#)<M>Id: streams.msk,v 1.18 2006/07/02 12:01:48 gap Exp </M> -->
<!-- %% -->
<!-- %Y  Copyright 1997,  Lehrstuhl D für Mathematik,  RWTH Aachen,   Germany -->
<!-- %Y  Copyright 2000,  St Andrews -->
<!-- %% -->
<!-- %%  This file contains the description of streams. -->
<!-- %% -->


<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->
<Chapter Label="Streams">
<Heading>Streams</Heading>

<#Include Label="[1]{streams}">

<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->
<Section Label="Categories for Streams and the StreamsFamily">
<Heading>Categories for Streams and the StreamsFamily</Heading>

<#Include Label="IsStream">
<#Include Label="IsClosedStream">
<#Include Label="IsInputStream">
<#Include Label="IsInputTextStream">
<#Include Label="IsInputTextNone">
<#Include Label="IsOutputStream">
<#Include Label="IsOutputTextStream">
<#Include Label="IsOutputTextNone">
<#Include Label="StreamsFamily">

</Section>


<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->
<Section Label="Operations applicable to All Streams">
<Heading>Operations applicable to All Streams</Heading>

<#Include Label="CloseStream">
<#Include Label="FileDescriptorOfStream">

<ManSection>
<Func Name="UNIXSelect"
 Arg='inlist, outlist, exclist, timeoutsec, timeoutusec'/>

<Description>
makes the UNIX C-library function <C>select</C> accessible from &GAP;
for streams. The functionality is as described in the man page (see

UNIX file descriptors (integers) for streams. They can be obtained via
<Ref Func="FileDescriptorOfStream"/> for streams
to local processes and to local files. The argument <A>timeoutsec</A> is a
timeout in seconds as in the <C>struct timeval</C> on the C level. The argument
<A>timeoutusec</A> is
analogously in microseconds. The total timeout is the sum of both. If
one of those timeout arguments is not a small integer then no timeout is
applicable (<K>fail</K> is allowed for the timeout arguments).
<P/>
The return value is the number of streams that are ready, this may be
0 if a timeout was specified. All file descriptors in the three lists
that are not yet ready are replaced by <K>fail</K> in this function. So 
the lists are changed!
<P/>
This function is not available on the Macintosh architecture and is
only available if your operating system has <C>select</C>, which is detected
during compilation of &GAP;.
</Description>
</ManSection>

</Section>


<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->
<Section Label="Operations for Input Streams">
<Heading>Operations for Input Streams</Heading>

Three operations normally used to read files: <Ref Oper="Read"/>, 
<Ref Oper="ReadAsFunction"/> and <Ref Oper="ReadTest"/>
can also be used to read &GAP; input from a
stream. The input is immediately parsed and executed. When reading
from a stream <A>str</A>, the &GAP; kernel generates calls to
<C>ReadLine(<A>str</A>)</C> to supply text to the parser. 
<P/>
Three further operations: <Ref Oper="ReadByte"/>, <Ref Oper="ReadLine"/> 
and <Ref Oper="ReadAll"/>, support
reading characters from an input stream without parsing them. This can be
used to read data in any format and process it in &GAP;.
<P/>
Additional operations for input streams support detection of end of
stream, and (for those streams for which it is appropriate) random access 
to the data.
<P/>

<ManSection>
<Oper Name="Read" Arg='input-text-stream' Label="for streams"/>

<Description>
reads the input-text-stream as  input  until <C>end-of-stream</C> occurs.  See
<Ref Sect="File Operations"/> for details.
</Description>
</ManSection>


<ManSection>
<Oper Name="ReadAsFunction" Arg='input-text-stream' Label="for streams"/>

<Description>
reads the input-text-stream as function and returns this function. See
<Ref Sect="File Operations"/> for details.

<Example><![CDATA[
gap> # a function with local `a' does not change the global one
gap> a := 1;;
gap> i := InputTextString( "local a; a := 10; return a*10;" );;
gap> ReadAsFunction(i)();
100
gap> a;
1
gap> # reading it via `Read' does
gap> i := InputTextString( "a := 10;" );;
gap> Read(i);
gap> a;
10
]]></Example>
</Description>
</ManSection>


<ManSection>
<Oper Name="ReadTest" Arg='input-text-stream' Label="for streams"/>

<Description>
reads the input-text-stream as  test input until <C>end-of-stream</C> occurs.
See <Ref Sect="File Operations"/> for details.
</Description>
</ManSection>

<#Include Label="ReadByte">
<#Include Label="ReadLine">
<#Include Label="ReadAll">
<#Include Label="IsEndOfStream">
<#Include Label="PositionStream">
<#Include Label="RewindStream">
<#Include Label="SeekPositionStream">

</Section>


<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->
<Section Label="Operations for Output Streams">
<Heading>Operations for Output Streams</Heading>

<#Include Label="WriteByte">
<#Include Label="WriteLine">
<#Include Label="WriteAll">

<ManSection>
<Heading>PrintTo and AppendTo (for streams)</Heading>
<Func Name="PrintTo" Arg='output-stream, arg1, ...' Label="for streams"/>
<Func Name="AppendTo" Arg='output-stream, arg1, ...' Label="for streams"/>

<Description>
These functions work like <Ref Func="Print"/>, except that the output is
appended to the output stream <A>output-stream</A>.
<P/>
<Example><![CDATA[
gap> str := "";; a := OutputTextString(str,true);;
gap> AppendTo( a, (1,2,3), ":", Z(3) );
gap> CloseStream(a);
gap> Print( str, "\n" );
(1,2,3):Z(3)
]]></Example>
</Description>
</ManSection>

<#Include Label="LogTo">
<#Include Label="InputLogTo">
<#Include Label="OutputLogTo">
<#Include Label="SetPrintFormattingStatus">

</Section>


<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->
<Section Label="File Streams">
<Heading>File Streams</Heading>

File streams  are  streams associated with  files.  An  input file stream
reads  the characters  it delivers from  a  file,  an output  file stream
prints the characters it receives to a file.  The following functions can
be used to create such streams.  They return <K>fail</K> if an error occurred,
in this case <Ref Func="LastSystemError"/> can be used to get
information about the error.

<#Include Label="InputTextFile">
<#Include Label="OutputTextFile">

</Section>


<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->
<Section Label="User Streams">
<Heading>User Streams</Heading>

The commands described in this section create streams which accept characters
from, or deliver characters to, the user, via the keyboard or the &GAP; session
display.

<#Include Label="InputTextUser">
<#Include Label="OutputTextUser">
<#Include Label="InputFromUser">

</Section>


<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->
<Section Label="String Streams">
<Heading>String Streams</Heading>

String streams   are streams associated  with   strings.  An input string
stream reads  the characters it delivers  from a string, an output string
stream  appends the characters  it receives  to  a string.  The following
functions can be used to create such streams.

<#Include Label="InputTextString">
<#Include Label="OutputTextString">

</Section>


<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->
<Section Label="Input-Output Streams">
<Heading>Input-Output Streams</Heading>

<#Include Label="[2]{streams}">
<#Include Label="IsInputOutputStream">
<#Include Label="InputOutputLocalProcess">
<#Include Label="ReadAllLine">

</Section>


<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->
<Section Label="Dummy Streams">
<Heading>Dummy Streams</Heading>

The following  two commands create  dummy streams  which will consume all
characters and never deliver one.

<#Include Label="InputTextNone">
<#Include Label="OutputTextNone">

</Section>


<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->
<Section Label="Handling of Streams in the Background">
<Heading>Handling of Streams in the Background</Heading>

This section describes a feature of the &GAP; kernel that can be used
to handle pending streams somehow <Q>in the background</Q>. This is currently
not available on the Macintosh architecture and only on operating
systems that have <C>select</C>.
<P/>
Right before &GAP; reads a keypress from the keyboard it calls a little
subroutine that can handle streams that are ready to be read or ready to
be written. This means that &GAP; can handle these streams during
user input on the command line. Note that this does not work when &GAP;
is in the middle of some calculation.
<P/>
This feature is used in the following way. One can install handler
functions for reading or writing streams via
<Ref Func="InstallCharReadHookFunc"/>.
Handlers can be removed via
<Ref Func="UnInstallCharReadHookFunc"/>
<P/>
Note that handler functions must not return anything and get one integer
argument, which refers to an index in one of the following arrays
(according to whether the function was installed for input, output or
exceptions on the stream). Handler functions usually should not output
anything on the standard output because this ruins the command line
during command line editing.

<#Include Label="InstallCharReadHookFunc">
<#Include Label="UnInstallCharReadHookFunc">

</Section>


<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->
<Section Label="Comma separated files">
<Heading>Comma separated files</Heading>
<Index>Spreadsheet</Index>
<Index>Excel</Index>

In some situations it can be desirable to process data given in the form of
a spreadsheet (such as Excel). &GAP; can do this using the CSV (comma
separated values) format, which spreadsheet programs can usually read in or
write out.
<P/>
The first line of the spreadsheet is used as labels of record components,
each subsequent line then corresponds to a record. Entries enclosed in
double quotes are considered as strings and are permitted to contain the
separation character (usually a comma).

<#Include Label="ReadCSV">
<#Include Label="PrintCSV">

</Section>
</Chapter>

<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->
<!-- %% -->
<!-- %E -->

