english
version "1.0"
identify "xyz"

#: Copyright (c) 1995, 2002 by Wayne C. Gramlich.
#, All rights reserved.
#,
#, Permission to use, copy, modify, distribute, and sell this software
#, for any purpose is hereby granted without fee provided that the above
#, copyright notice and this permission are retained.  The author makes
#, no representations about the suitability of this software for any purpose.
#, It is provided "as is" without express or implied warranty.

module data_io

#: This module implements the {data_in_stream} and {data_out_stream} types.

define data_in_stream			#: Delta input stream object
    record
	buffer string			#: Temporary buffer
	errors errors			#: {errors} object to output errors to
	file_name file_name		#: {file_name} object for stream
	hash unsigned			#: Hash value for file
	in_stream in_stream		#: {in_stream} object
	project project			#: {project{ for stream
	resources resources		#: Parent {resources} object
    generate address_get, allocate, erase, identical, print

define data_out_stream			#: Delta output stream object
    record
	buffer string			#: Temporary buffer
	errors errors			#: Error output
	final_file_name file_name	#: Final file name for data file
	hash unsigned			#: Hash value for data
	new_line string			#: New-line sequence for out stream
	offset unsigned			#: Total characters output
	out_stream out_stream		#: {out_stream} object
	resources resources		#: Parent {resources} object
	side_file_name file_name	#: Temporary file name for data file
    generate address_get, allocate, erase, identical, print

define data_out_delay			#: Delayed output file renaming
    record
	side_file_name file_name	#: Side file name (prior to rename)
	final_file_name file_name	#: Final file name (after rename)
    generate address_get, allocate, erase, identical, print

define data_out_delays			#: List of delayed output files
    record
	debug_stream out_stream		#: A debugging stream
	delays vector[data_out_delay]	#: The list of delays
	file_name file_name		#: File name for temporary storage
    generate address_get, allocate, erase, identical, print



#: {data_in_stream} procedures:

procedure xallocate@data_in_stream
    takes
	resources resources
    returns data_in_stream

    #: This procedure will return an unitinialized {data_in_stream} object
    #, for reading a data file.


procedure bytes_read@data_in_stream
    takes
	data_in_stream data_in_stream
	bytes string
    returns_nothing

    #: This procedure will read in a sequence of bytes that was previously
    #, written using {bytes_write}@{data_out_stream}.  The read in bytes
    #, are appended to {bytes}.


procedure character_check@data_in_stream
    takes
	data_in_stream data_in_stream
	character character
    returns_nothing

    #: This procedure will read in on character from {data_in_stream}
    #, and verify that it matches {character}.


procedure character_read@data_in_stream
    takes
	data_in_stream data_in_stream
    returns character

    #: This procedure will read in one character from {data_in_stream}
    #, that was written with {character_write}@{data_out_stream}().


procedure close@data_in_stream
    takes
	data_in_stream data_in_stream
    returns unsigned

    #: This procedure will close {data_in_stream} and return the computed
    #, hash value.


procedure deallocate@data_in_stream
    takes
	data_in_stream data_in_stream
    returns_nothing

    #: This procedure will deallocate {data_in_stream} and make it
    #, available for subsequent reallocation.


procedure eof_get@data_in_stream
    takes
	data_in_stream data_in_stream
    returns logical

    #: This procedure will return {true} if {data_in_stream} is at
    #, an end of file and {false} otherwise.


procedure file_name_read@data_in_stream
    takes
	data_in_stream data_in_stream
    returns file_name

    #: This procedure will read in a {file_name} forom {data_in_stream}.


procedure hash_read@data_in_stream
    takes
	data_in_stream data_in_stream
    returns unsigned

    #: This procedure will write out {hash} to {data_out_stream}.


procedure header_read@data_in_stream
    takes
	data_in_stream data_in_stream
	tag character
	file_type string
	major unsigned
	minor unsigned
    returns logical

    #: This procedure will read in a header line from {data_in_stream}.


procedure logical_read@data_in_stream
    takes
	data_in_stream data_in_stream
    returns logical


procedure new_line_read@data_in_stream
    takes
	data_in_stream data_in_stream
    returns_nothing

    #: This procedure will read skip over a new-line sequence in
    #, {data_in_stream}.


procedure open@data_in_stream
    takes
	data_in_stream data_in_stream
	file_name file_name
	project project
	errors errors
    returns logical

    #: This procedure will open {file_name} for reading.  If any errors
    #, occur, an error message is output to {error_stream} and {true}
    #, is returned; otherwise, {false} is returned.


procedure space_read@data_in_stream
    takes
	data_in_stream data_in_stream
    returns_nothing

    #: This procedure will read in a space from {data_in_stream}.


procedure status_mode_read@data_in_stream
    takes
	data_in_stream data_in_stream
    returns status_mode

    #: This procedure will read in and return a {status_mode} value from
    #, {data_in_stream}.


procedure string_read@data_in_stream
    takes
	data_in_stream data_in_stream
	buffer string
    returns_nothing

    #: This procedure will read in a sequence of bytes that was previously
    #, written using {line_write}@{data_out_stream}.  The read in bytes
    #, are appended to {bytes}.


procedure tag_check@data_in_stream
    takes
	data_in_stream data_in_stream
	tag character
    returns_nothing

    #: This procedure will read in a tag character from {data_in_stream}
    #, and verify that it matches {tag}.


procedure tag_read@data_in_stream
    takes
	data_in_stream data_in_stream
    returns character

    #: This procedure will read in and return a tag charater from
    #, {data_in_stream{ that was written by {tag_write}@{data_out_stream}().


procedure timestamp_read@data_in_stream
    takes
	data_in_stream data_in_stream
    returns unsigned

    #: This procedure will return a timestamp read from {data_in_stream}
    #, that was written by {timestamp_write}@{data_out_stream}().


procedure unsigned_fixed_read@data_in_stream
    takes
	data_in_stream data_in_stream
	width unsigned
    returns unsigned

    #: This procedure will read in {width} decimal digits
    #, from {data_in_stream} that were written by
    #, {unsigned_fixed_write}@{data_in_stream}().


procedure unsigned_read@data_in_stream
    takes
	data_in_stream data_in_stream
    returns unsigned

    #: This procedure will read in and return an {unsigned}
    #, number from {data_in_stream} that was written via
    #, {unsigned_write}@{data_in_stream}().


procedure unsigned_read_helper@data_in_stream
    takes
	data_in_stream data_in_stream
	terminator character
    returns unsigned

    #: This procedure will read in number from {data_in_stream} until
    #, {terminator} is encountered.


#: {data_out_delay} procedures:

procedure create@data_out_delay
    takes
	side_file_name file_name
	final_file_name file_name
    returns data_out_delay

    #: This procedure will create and return a new {data_out_delay} object
    #, containing {side_file_name} and {final_file_name}.


#: {data_out_delays} procedures:

procedure abort@data_out_delays
    takes
	data_out_delays data_out_delays
    returns_nothing

    #: This procedure will delete all of the side files in {data_out_delays}.


procedure append@data_out_delays
    takes
	data_out_delays data_out_delays
	side_file_name file_name
	final_file_name file_name
    returns_nothing

    #: This procedure will append a new {data_out_delay} object containing
    #, {side_file_name} and {final_file_name} to {data_out_delays}.


procedure commit@data_out_delays
    takes
	data_out_delays data_out_delays
	errors errors
    returns_nothing

    #: This procedure will rename all of the side files in {data_out_delays}
    #, to their appropriate final file names


procedure create@data_out_delays
    takes
	file_name file_name
	debug_stream out_stream
    returns data_out_delays

    #: This procedure will create and return an empty {data_out_delays} object.
    #, {file_name} specifies a temporary file for keeping track of what
    #, files need to be deleted.

    #: Eventually we will use

#: {data_out_stream} procedures:

procedure xallocate@data_out_stream
    takes
	resources resources
    returns data_out_stream

    #: This procedure will return an unitinialized {data_out_stream} object
    #, for reading a data file.


procedure bytes_write@data_out_stream
    takes
	data_out_stream data_out_stream
	bytes string
    returns_nothing

    #: This procedure will write {bytes} out to {data_out_stream}
    #, as a sequence of hexadecimal numbers.  This can easily be
    #, read back in via a call to {bytes_read}@{data_in_stream}().


procedure close@data_out_stream
    takes
	data_out_stream data_out_stream
	data_out_delays data_out_delays
    returns unsigned
 
    #: This procedure will close {data_out_stream}.  The hash value
    #, for {data_out_stream} is returned.


procedure character_write@data_out_stream
    takes
	data_out_stream data_out_stream
	character character
    returns_nothing

    #: This procedure will write {character} to {data_out_stream} such
    #, that it can be read back in by {character_read}@{data_in_stream}().


procedure deallocate@data_out_stream
    takes
	data_out_stream data_out_stream
    returns_nothing

    #: This procedure will deallocate {data_out_stream} and make it
    #, available for subsequent reallocation.


procedure file_name_write@data_out_stream
    takes
	data_out_stream data_out_stream
	file_name file_name
    returns_nothing

    #: This procedure will write {file_name} out to {data_out_stream} such
    #, that it can be easily read by {file_name_read}@{data_in_stream}().
    #, ??@{file_name} is a legal value.


procedure hash_write@data_out_stream
    takes
	data_out_stream data_out_stream
	number unsigned
    returns_nothing

    #: This procedure will write {hash} out to {data_out_stream}
    #, such that it can be easily read by {hash_read}@{data_in_stream}().


procedure header_write@data_out_stream
    takes
	data_out_stream data_out_stream
	tag character
	file_type string
	major unsigned
	minor unsigned
    returns_nothing


procedure logical_write@data_out_stream
    takes
	data_out_stream data_out_stream
	value logical
    returns_nothing

    #: This procedure will write {value} to {data_out_stream} such that
    #, it can be read back in by {logica_read}@{data_in_stream}().


procedure new_line_write@data_out_stream
    takes
	data_out_stream data_out_stream
    returns_nothing

    #: This procedure will write out a new-line sequence to {data_out_stream}
    #, such that it can be read back in by {new_line_read}@{data_in_stream}().


procedure open@data_out_stream
    takes
	final_file_name file_name
	resources resources
	errors errors
    returns data_out_stream

    #: This procedure will open and return a {data_out_stream} object
    #, that ultimately writes to {final_file_name}.  If any error
    #, occurs, an error message is output to {errors} and
    #, ??@{data_out_stream} is returned.


procedure space_write@data_out_stream
    takes
	data_out_stream data_out_stream
    returns_nothing

    #: This procedure will write a space out to {data_out_stream} such
    #, that it can be read back in by {space_read}@{data_in_stream}().


procedure status_mode_write@data_out_stream
    takes
	data_out_stream data_out_stream
	status_mode status_mode
    returns_nothing

    #: This procedure will write {status_mode} out to {data_out_stream} such
    #, that it can be read back in by {status_mode_read}@{data_in_stream}().


procedure string_write@data_out_stream
    takes
	data_out_stream data_out_stream
	line string
    returns_nothing

    #: This procedure will write {bytes} out to {data_out_stream}
    #, as a sequence of charactes and escaped hexadecimal numbers.
    #, This can easily be read back in via a call to
    #, {line_read}@{data_in_stream}().


procedure tag_write@data_out_stream
    takes
	data_out_stream data_out_stream
	tag character
    returns_nothing

    #: This procedure will write out {tag} to {data_out_stream} so that
    #, it can easily be read back in by {tag_read}@{data_in_stream}().


procedure timestamp_write@data_out_stream
    takes
	data_out_stream data_out_stream
	timestamp unsigned
    returns_nothing

    #: This procedure will interpret {timestamp} as an date measured in
    #, seconds since January 1, 1970 and write it to {data_out_stream}
    #, using the format yyyy/mm/dd@hh:mm:ss-GMT.


procedure unsigned_write@data_out_stream
    takes
	data_out_stream data_out_stream
	number unsigned
    returns_nothing

    #: This procedure will write {number} out to {data_out_stream}
    #, such that it can be easily read by {unsigned_read}@{data_in_stream}().


procedure unsigned_write_helper@data_out_stream
    takes
	data_out_stream data_out_stream
	number unsigned
    returns_nothing

    #: This procedure will write {number} to {data_out_stream}
    #, as a decimal number.