english
version "1.0"
identify "xyz"
#: Copyright (c) 1998-2007 by Wayne C. Gramlich.
#, All rights reserved.
#: This module provides an input stream interface to files, network
#, streams, pipes, strings, and filters.
#,
#, Eventually, this module needs to be implementated via a co-type
#, (polymorphic) interface; until then, a simple variant is used.
module input_stream
define input_stream #: Input stream of bytes/characters
variant kind input_stream_kind
closed null #: This input_stream is closed
file_input_stream file_input_stream #: A standard file input stream
generate address_get, allocate, erase, identical, print
define input_stream_kind #: The {input_stream
} types.
enumeration
closed #: A closed input stream
file_input_stream #: A file input stream
generate equal, print, unsigned_convert
define file_input_stream #: Input stream from a file
record
memory memory #: Memory buffer
done logical #: {true
} => no more data is available
file_set file_set #: {file_set
} polling object (or ??)
file_descriptor_number unsigned #: File descriptor number
file_name file_name #: File name
file_name_string string #: Associated file name as a {string
}
offset unsigned #: Offset to next valid byte
remaining unsigned #: Remaining valid bytes
generate allocate, erase, print
#: {input_stream
} routines:
procedure character_read@input_stream
takes
input_stream input_stream
returns character
#: This procedure will return the next character from {input_stream
}.
#, If there are no more characters to be had, the end-of-stream
#, character is returned (see {end_of_stream_character
}@{input_stream
}.
procedure close@input_stream
takes
input_stream input_stream
returns_nothing
#: This procedure will close {input_stream
}.
procedure create@input_stream
takes_nothing
returns input_stream
#: This procedure will return a new closed {input_stream
} object.
#, It is primarily intended for use by other types, like
#, {file_input_stream
}, that have open procedures that will
#, return an open {input_stream
} object.
procedure input_available@input_stream
takes
input_stream input_stream
returns logical
#: This procedure will return {true
}@{logical
} if there is at least
#, one byte of input avaiable from {input_stream
} and {false
}@{logical
}
#, otherwise. This procedure does not do read ahead, so it will not
#, block.
procedure end_of_stream_character@input_stream
takes_nothing
returns character
#: This procedure returns the end-of-stream character that gets returned
#, by {character_read
}@{input_stream
}() when there are no more characters
#, to be had.
procedure is_done@input_stream
takes
input_stream input_stream
returns logical
#: This procedure will return {true
}@{logical
}() if no more
#, bytes/characters can be read from {input_stream
}; otherwise,
#, {false
} is returned. Please note, this procedure will return
#, {true
} only until after at least one call is made to a read
#, procedure returns 0 (or the end-of-stream character for
#, {character_read
}@{input_stream
}().)
procedure is_open@input_stream
takes
input_stream input_stream
returns logical
#: This procedure will return {true
}@{logical
} if {input_stream
} is
#, still open and {false
} otherwise. Please note that having an
#, open {input_stream
} does not mean that any more data can be
#, successfully read from it; use {is_done
}@{input_stream
}() for that
#, purpose.
procedure memory_read@input_stream
takes
input_stream input_stream
memory memory
offset unsigned
amount_requested unsigned
returns unsigned
#: This procedure will read up to {amount_requested
} bytes from
#, {input_stream
} and store them into {memory
} starting at
#, {offset
}. The actual number of bytes read in is returned.
#, A return value of 0 means that there are no more bytes/characters
#, available from {input_stream
} and it can be closed via
#, {close
}@{input_stream
}().
#,
#, Please note that this procedure will only block if any internal
#, buffer associated with {input_stream
} is empty and the additional
#, data has not yet been delivered by the operating system. Thus,
#, you should expect the actual number of bytes returned will frequently
#, be less than {amount_requested
} even though even though the
#, operating system may eventually be able deliver more than
#, {amount_requested
} with subsequent calls. With this procedure
#, you should never assume that return value of less than
#, {amount_requested
} means that end of stream has been reached.
procedure memory_read_exact@input_stream
takes
input_stream input_stream
memory memory
offset unsigned
amount_requested unsigned
returns unsigned
#: This procedure will attempt to read exactly {amount_requested
}
#, bytes/characters from {input_stream
} and store the result into
#, {memory
} at starting it {offset
}. The actual number of bytes
#, read is returned. The only time the return value will not
#, be equal to {amount_requested
} is when an end of file/stream
#, condition has occured on {input_stream
}, in which case, the
#, remaining number of bytes/characters is returned.
procedure string_append@input_stream
takes
input_stream input_stream
buffer string
amount_requested unsigned
returns unsigned
#: This procedure will append up to {amount_requested
} characters
#, from {input_stream
} to {buffer
}. The actual number of characters
#, appended is returned. A return value of 0 means that there are
#, no more characters available from {input_stream
} and it can be
#, closed.
#,
#, Please note that this procedure will only block if any internal
#, buffer associated with {input_stream
} is empty and the additional
#, data has not yet been delivered by the operating system. Thus,
#, you should expect the actual number of bytes returned will frequently
#, be less than {amount_requested
} even though even though the
#, operating system may eventually be able deliver more than
#, {amount_requested
} with subsequent calls. With this procedure
#, you should never assume that return value of less than
#, {amount_requested
} means that end of stream has been reached.
procedure string_append_exact@input_stream
takes
input_stream input_stream
buffer string
amount_requested unsigned
returns unsigned
#: This procedure will append exactly {amount_requested
} bytes/characters
#, from {input_stream
} to {buffer
}. The total number of bytes/characters
#, actually appended is returned. The total number of bytes/characters
#, returned will always equal {amount_requested
} unless an end of
#, stream condition occurs before {amount_requested
} bytes/characters
#, can be read.
#: {file_input_stream
} routines:
procedure character_read@file_input_stream
takes
file_input_stream file_input_stream
returns character
#: This procedure will return the next character from {file_input_stream
}.
#, If there are no more characters to be had, the end-of-file character
#, is returned (see {end_of_stream_character
}@{file_input_stream
}.
procedure close@file_input_stream
takes
file_input_stream file_input_stream
returns_nothing
#: This procedure will close {file_input_stream
}.
procedure file_descriptor_bind@file_input_stream
takes
file_descriptor_number unsigned
buffer_size unsigned
file_name file_name
file_name_string string
returns input_stream
#: This procedure will create and return an {file_input_stream
}
#, object connected to {file_descriptor_number
} with a buffer that
#, contains {buffer_size
} bytes. {file_name
} and {file_name_string
}
#, are associated with the returned {file_input_stream
} object for
#, subsequent print out.
procedure fill@file_input_stream
takes
file_input_stream file_input_stream
maximum_requested unsigned
returns unsigned
#: This procedure will fill the {file_input_stream
} buffer with
#, up to {maximum_requested
} bytes/characters of data. The amount
#, of data remaining in the buffer is returned.
procedure input_available@file_input_stream
takes
file_input_stream file_input_stream
returns logical
#: This procedure will return {true
}@{logical
} if there is at least
#, one byte of input avaiable from {file_input_stream
} and
#, {false
}@{logical
} otherwise. This procedure does not do read
#, ahead, so it will not block.
procedure is_done@file_input_stream
takes
file_input_stream file_input_stream
returns logical
#: This procedure will return {true
} if no more characters can
#, be read from {file_input_stream
}.
procedure open@file_input_stream
takes
file_name file_name
returns input_stream
#: This procedure will return open {file_name
} and return an
#, associated {input_stream
} object.
procedure open_buffer@file_input_stream
takes
file_name file_name
buffer_size unsigned
returns input_stream
#: This procedure will return open {file_name
} for reading and return
#, an associated {input_stream
} object with a backing buffer of size
#, {buffer_size
}. ??@{input_stream
} is returned if the open failed.
#, An invocation to {status_get
}@{unix_system
} may give a more
#, diagnostic reason.
procedure memory_read@file_input_stream
takes
file_input_stream file_input_stream
to_memory memory
to_offset unsigned
amount_requested unsigned
returns unsigned
#: This procedure will read up to {amount_requested
} bytes
#, from {file_input_stream
} and store them into {to_memory
} starting
#, at {to_offset
}. This procedure will fail if {to_offset
}
#, greater than or equal to the size of {to_memory
}.
#, The actual number of bytes read in is returned. A return
#, value of 0 means that there are no more bytes/characters available
#, from {file_input_stream
} and it can be closed.
procedure string_append@file_input_stream
takes
file_input_stream file_input_stream
buffer string
amount_requested unsigned
returns unsigned
#: This procedure will append up to {amount_requested
} characters
#, from {file_input_stream
} to {buffer
}. The actual number of characters
#, appended is returned. A return value of 0 means that there are
#, no more characters available from {file_input_stream
} and it can be
#, closed.
# Polymorphic implementation using co-types:
#
#define input_stream[buffer]
# down_type input_stream
# needs
# procedure read
# takes buffer, unsigned, unsigned
# returns unsigned
# procedure close
# takes buffer
# returns_nothing
# record
# buffer buffer
# offset unsigned
# unread unsigned
# generate allocate, down_convert, erase, print, up_convert
#
#procedure create@input_stream[buffer]
# takes
# buffer buffer
# returns input_stream
#
# input_stream1 :@= new@input_stream1[buffer]()
# input_stream1.buffer :@= buffer
# input_stream :@= down_convert@(input_stream1)
# return input_stream
#
#procedure read@input_stream
# up_type input_stream[buffer]
# takes
# input_stream input_stream
# amount unsigned
# returns unsigned
#
# input_stream1 :@= up_convert@(input_stream)
# result :@= read@(input_stream1.buffer,
# input_stream.offset + input_stream.unread, offset)
# input_stream.unread :+= result
# return result
#
#procedure close@input_stream
# up_type input_stream[buffer]
# takes
# input_stream input_stream
# returns_nothing
#
# input_stream1 :@= up_convert@(input_stream)
# close@(input_stream)