Reading Objects from Files

Thus far, we have only considered the default behaviour of a ChannelChannel in reading and writing Objects through a program's standard input and output streams. We will now consider how to access Objects stored in files more directly.

The simple approach is to use the SinkFileSinkFile and SourceFileSourceFile attributes of the Channel. For instance, the following will read a pair of Objects from a text file called “fred.txt”:


\begin{terminalv}
astSet( channel, ''SourceFile=fred.txt'' );
obj1 = astRead( ch...
...
obj2 = astRead( channel );
astClear( channel, ''SourceFile'' );
\end{terminalv}

Note, the act of clearing the attribute tells AST that no more Objects are to be read from the file and so the file is then closed. If the attribute is not cleared, the file will remain open and further Objects can be read from it. The file will always be closed when the Channel is deleted.

This simple approach will normally be sufficient. However, because the AST library is designed to be used from more than one language, it has to be a little careful about reading and writing to files. This is due to incompatibilities that may exist between the file I/O facilities provided by different languages. If such incompatibilities prevent the above simple system being used, we need to adopt a system that off-loads all file I/O to external code.

What this means in practice is that if the above simple approach cannot be used, you must instead provide some simple C functions that perform the actual transfer of data to and from files and similar external data stores. The functions you provide are supplied as the source and/or sink function arguments to astChannelastChannel when you create a Channel (ยง15.2). An example is the best way to illustrate this.

Consider the following simple function called Source. It reads a single line of text from a C input stream and returns a pointer to it, or NULL if there is no more input:


\begin{terminalv}
...

Note that the input stream is a static variable which we will also access from our main program. This might look something like this (omitting error checking for brevity):


\begin{terminalv}
/* Open the input file. */
input_stream = fopen( ''infile.ast'...
...*/
channel = astAnnul( channel );
(void) fclose( input_stream );
\end{terminalv}

Here, we first open the required input file, saving the resulting FILE pointer. We then pass a pointer to our Source function as the first argument to astChannel when creating a new Channel. When we read an ObjectObject from this Channel with astReadastRead, the Source function will be called to obtain the textual data from the file, the end-of-file being detected when this function returns NULL.

Note, if a value is set for the SourceFile attribute, the astRead function will ignore any source function specified when the Channel was created.