home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
AmigActive 3
/
AACD03.BIN
/
AACD
/
Programming
/
sofa
/
archive
/
SmallEiffel.lha
/
SmallEiffel
/
lib_std
/
input_stream.e
< prev
next >
Wrap
Text File
|
1999-06-05
|
12KB
|
427 lines
-- This file is free software, which comes along with SmallEiffel. This
-- software is distributed in the hope that it will be useful, but WITHOUT
-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-- FITNESS FOR A PARTICULAR PURPOSE. You can modify it as you want, provided
-- this header is kept unaltered, and a notification of the changes is added.
-- You are allowed to redistribute it and sell it, alone or as a part of
-- another product.
-- Copyright (C) 1994-98 LORIA - UHP - CRIN - INRIA - FRANCE
-- Dominique COLNET and Suzanne COLLIN - colnet@loria.fr
-- http://SmallEiffel.loria.fr
--
deferred class INPUT_STREAM
--
-- This abstract class is the superclass of all classes
-- representing an input stream of bytes.
--
feature -- State of the stream :
is_connected: BOOLEAN is
-- True when the corresponding stream is connected
-- to some physical input device.
deferred
end;
end_of_input: BOOLEAN is
-- Has end-of-input been reached ?
-- True when the last character has been read.
require
is_connected
deferred
end;
feature -- To read one character at a time :
read_character is
-- Read a character and assign it to `last_character'.
require
not end_of_input
deferred
ensure
not push_back_flag
end;
last_character: CHARACTER is
-- Last character read with `read_character'.
require
is_connected
deferred
end;
push_back_flag: BOOLEAN;
-- True in one char is already pushed back.
unread_character is
-- Un-read the last character read.
--
require
not push_back_flag
deferred
ensure
push_back_flag
end;
feature -- Skipping separators :
skip_separators is
-- Stop doing `read_character' as soon as `end_of_file' is reached
-- or as soon as `last_character' is not `is_separator'.
-- When first character is already not `is_separator' nothing
-- is done.
do
from
until
end_of_input or else
not last_character.is_separator
loop
read_character;
end;
end;
skip_separators_using(separators:STRING) is
-- Same job as `skip_separators' using `separators'.
require
separators /= void
do
-- Implemented by : Lars Brueckner
-- (larsbruk@rbg.informatik.th-darmstadt.de)
from
until
end_of_input or else
not separators.has(last_character)
loop
read_character;
end;
end;
feature -- To read one number at a time :
read_integer is
-- Read an integer according to the Eiffel syntax.
-- Make result available in `last_integer'.
-- Heading separators are automatically skipped using
-- `is_separator' of class CHARACTER.
-- Trailing separators are not skipped.
require
not end_of_input
local
state: INTEGER;
sign: BOOLEAN;
-- state = 0 : waiting sign or first digit.
-- state = 1 : sign read, waiting first digit.
-- state = 2 : in the number.
-- state = 3 : end state.
-- state = 4 : error state.
do
from
until
state > 2
loop
read_character;
inspect
state
when 0 then
if last_character.is_separator then
elseif last_character.is_digit then
last_integer := last_character.value;
state := 2;
elseif last_character = '-' then
sign := true;
state := 1;
elseif last_character = '+' then
state := 1;
else
state := 4;
end;
when 1 then
if last_character.is_separator then
elseif last_character.is_digit then
last_integer := last_character.value;
state := 2;
else
state := 4;
end;
else -- 2
if last_character.is_digit then
last_integer := (last_integer * 10) + last_character.value;
else
state := 3;
end;
end;
if end_of_input then
inspect
state
when 0 .. 1 then
state := 4;
when 2 .. 3 then
state := 3;
else -- 4
end;
end;
end;
if not end_of_input then
unread_character;
end;
debug
if state = 4 then
std_error.put_string("Error in INPUT_STREAM.read_integer.%N");
crash;
end;
end;
if sign then
last_integer := - last_integer;
end;
end;
last_integer: INTEGER;
-- Last integer read using `read_integer'.
read_real is
-- Read a REAL and make the result available in `last_real'
-- and in `last_double'.
-- The integral part is available in `last_integer'.
require
not end_of_input
do
read_double;
last_real := last_double.to_real;
end;
last_real: REAL;
-- Last real read with `read_real'.
read_double is
-- Read a DOUBLE and make the result available in
-- `last_double'.
require
not end_of_input
local
state: INTEGER;
sign: BOOLEAN;
ip, i: INTEGER;
-- state = 0 : waiting sign or first digit.
-- state = 1 : sign read, waiting first digit.
-- state = 2 : in the integral part.
-- state = 3 : in the fractional part.
-- state = 4 : end state.
-- state = 5 : error state.
do
from
tmp_read_double.clear;
until
state >= 4
loop
read_character;
inspect
state
when 0 then
if last_character.is_separator then
elseif last_character.is_digit then
ip := last_character.value;
state := 2;
elseif last_character = '-' then
sign := true;
state := 1;
elseif last_character = '+' then
state := 1;
elseif last_character = '.' then
state := 3;
else
state := 5;
end;
when 1 then
if last_character.is_separator then
elseif last_character.is_digit then
ip := last_character.value;
state := 2;
else
state := 5;
end;
when 2 then
if last_character.is_digit then
ip := (ip * 10) + last_character.value;
elseif last_character = '.' then
state := 3;
else
state := 4;
end;
else -- 3
if last_character.is_digit then
tmp_read_double.extend(last_character);
else
state := 4;
end;
end;
if end_of_input then
inspect
state
when 2 .. 4 then
state := 4;
else
state := 5;
end;
end;
end;
if not end_of_input then
unread_character;
end;
debug
if state = 5 then
std_error.put_string("Error in STD_FILE.read_double.%N");
crash;
end;
end;
from
last_double := 0;
i := tmp_read_double.count;
until
i = 0
loop
last_double := (last_double + tmp_read_double.item(i).value) / 10;
i := i - 1;
end;
last_double := last_double + ip;
if sign then
last_double := - last_double;
end;
end;
last_double: DOUBLE;
-- Last double read with `read_double'.
feature -- To read one line or one word at a time :
last_string: STRING is
-- Access to a unique STRING to get the result computed
-- with `read_line', `read_word' or `newline'.
-- No new STRING is allocated.
once
!!Result.make(256);
end;
read_line is
-- Read a complete line ended by '%N' or `end_of_input'.
-- Make the result available in `last_string'.
-- Character '%N' is not added in `last_string'.
--
-- NOTE: the result is available in `last_string' without any
-- memory allocation.
require
not end_of_input
do
last_string.clear;
read_line_in(last_string);
end;
read_word is
-- Read a word using `is_separator' of class CHARACTER.
-- Result is available in `last_string' (no allocation
-- of memory).
-- Heading separators are automatically skipped.
-- Trailing separators are not skipped (`last_character' is
-- left on the first one).
-- If `end_of_input' is encountered, Result can be the
-- empty string.
require
not end_of_input
do
skip_separators;
from
last_string.clear;
until
end_of_input or else
last_character.is_separator
loop
last_string.extend(last_character);
read_character;
end;
end;
newline is
-- Consume input until newline ('%N') is found.
-- Corresponding STRING is stored in `last_string'.
local
stop: BOOLEAN;
do
from
last_string.clear;
stop := end_of_input;
until
stop
loop
read_character;
if end_of_input or else last_character = '%N' then
stop := true;
else
last_string.extend(last_character);
end;
end;
end;
feature -- Other features :
read_line_in(str: STRING) is
-- Same jobs as `read_line' but storage is directly done in `str'.
--
require
not end_of_input
deferred
end;
read_word_using(separators: STRING) is
-- Same jobs as `read_word' using `separators'.
require
not end_of_input;
separators /= void
do
-- Implemented by : Lars Brueckner
-- (larsbruk@rbg.informatik.th-darmstadt.de)
skip_separators_using(separators);
from
last_string.clear;
until
end_of_input or else
separators.has(last_character)
loop
last_string.extend(last_character);
read_character;
end;
end;
read_tail_in(str: STRING) is
-- Read all remaining character of the file in `str'.
require
str /= Void
do
from
until
end_of_input
loop
read_character;
if not end_of_input then
str.extend(last_character);
end;
end;
ensure
end_of_input
end;
feature {NONE}
eof_code: INTEGER is
external "SmallEiffel"
end;
read_byte(stream_pointer : POINTER): INTEGER is
external "SmallEiffel"
end;
tmp_read_double: STRING is
once
!!Result.make(12);
end;
end -- INPUT_STREAM