/*
Copyright (C) 1997 Quinn Snell
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program 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. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package es.uvigo.darwin.jmodeltest.io;
import java.io.BufferedReader;
import java.io.EOFException;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
public class TextInputStream {
private BufferedReader stdin;
char missed, currchar;
boolean EOF;
public TextInputStream() {
stdin = new BufferedReader(new InputStreamReader(System.in));
missed = '\0';
currchar = '\0';
EOF = false;
}
/**
* Constructs a TextInputStream for input from a text file
*
* @param s
* the text filename
*/
public TextInputStream(String s) throws FileNotFoundException {
stdin = new BufferedReader(
new InputStreamReader(new FileInputStream(s)));
missed = '\0';
currchar = '\0';
EOF = false;
}
int readIntString(char[] s) throws IOException {
int i;
int state = 0;
s[0] = missed;
// Skip Whitespace
while (Character.isWhitespace(s[0]) || s[0] == '\0') {
s[0] = readChar();
if (EOF)
throw new EOFException();
}
// Use a finite automaton to check the integer number
for (i = 1; !Character.isWhitespace(s[i - 1]); i++) {
switch (s[i - 1]) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
switch (state) {
case 0:
case 1:
case 2:
case 3:
state = 3;
break;
default:
throw new IOException("Integer format:Bad Start");
}
break;
case '+':
switch (state) {
case 0:
i--; // Throw away the + sign
state = 1;
break;
default:
throw new IOException("Integer format:+ sign wrong");
}
break;
case '-':
switch (state) {
case 0:
state = 2;
break;
default:
throw new IOException("Integer format:- sign wrong");
}
break;
default:
throw new IOException("Integer format error");
}
s[i] = readChar();
}
missed = s[i - 1];
return i - 1;
}
int readFloatString(char[] s) throws IOException {
int i;
int state = 0;
s[0] = missed;
// Skip Whitespace
while (Character.isWhitespace(s[0]) || s[0] == '\0') {
s[0] = readChar();
if (EOF)
throw new EOFException();
}
// Use a finite automaton to check the floating point number
for (i = 1; !Character.isWhitespace(s[i - 1]); i++) {
switch (s[i - 1]) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
switch (state) {
case 0:
case 1:
case 2:
case 4:
state = 4;
break;
case 3:
case 5:
state = 5;
break;
case 6:
case 7:
case 8:
case 9:
state = 9;
break;
default:
throw new IOException("Floating point format error1");
}
break;
case '+':
switch (state) {
case 0:
i--; // Throw away the initial + sign
state = 1;
break;
case 6:
state = 8;
break;
default:
throw new IOException("Floating point format error2");
}
break;
case '-':
switch (state) {
case 0:
state = 2;
break;
case 6:
state = 7;
break;
default:
throw new IOException("Floating point format error3");
}
break;
case '.':
switch (state) {
case 0:
case 1:
case 2:
case 4:
state = 3;
break;
default:
throw new IOException("Floating point format error4");
}
break;
case 'e':
switch (state) {
case 4:
case 5:
state = 6;
break;
default:
throw new IOException("Floating point format error5");
}
break;
default:
throw new IOException("Floating point format error6");
}
s[i] = readChar();
}
missed = s[i - 1];
return i - 1;
}
/**
* Reads and returns the next integer in the stream
*
* @return the integer
*/
public int readInt() {
char[] s = new char[255];
int length;
try {
length = readIntString(s);
return Integer.valueOf(String.valueOf(s, 0, length)).intValue();
} catch (IOException e) {/* System.err.println("Caught " + e); */
}
return Integer.MIN_VALUE;
}
/**
* Reads and returns the next float in the stream
*
* @return the float
*/
public float readFloat() {
char[] s = new char[255];
int length;
try {
length = readFloatString(s);
return Float.valueOf(String.valueOf(s, 0, length)).floatValue();
} catch (IOException e) {
;
}
return Float.NaN;
}
/**
* Reads and returns the next double in the stream
*
* @return the double
*/
public double readDouble() {
char[] s = new char[255];
int length;
try {
length = readFloatString(s);
return Double.valueOf(String.valueOf(s, 0, length)).doubleValue();
} catch (IOException e) {
;
}
return Double.NaN;
}
/**
* Reads and returns the next double in the stream
*
* @return the double
*/
public char readChar() {
char[] s = new char[2];
if (missed == '\0') {
try {
if (stdin.read(s, 0, 1) == -1)
EOF = true;
} catch (IOException e) {
;
}
} else {
s[0] = missed;
missed = '\0';
}
currchar = s[0];
return s[0];
}
/**
* Reads and returns the next word in the stream
*
* @return the word as a String
*/
public String readWord() {
char[] s = new char[255];
int i;
s[0] = missed;
// Skip Whitespace
while (Character.isWhitespace(s[0]) || s[0] == '\0') {
s[0] = readChar();
if (EOF)
return null;
}
for (i = 1; !Character.isWhitespace(s[i - 1]); i++)
s[i] = readChar();
missed = s[i - 1];
return String.valueOf(s, 0, i - 1);
}
/**
* Reads and returns the next line in the stream
*
* @return the line as a String without the return character
*/
public String readLine() {
try {
String s = stdin.readLine();
missed = '\0';
if (s == null) {
EOF = true;
// throw new EOFException();
}
return s;
} catch (IOException e) {
return null;
}
}
/**
* Returns true if the end of the file has been reached, false otherwise.
*/
public boolean EOF() {
return (EOF);
}
/**
* Closes the input stream
*/
public void close() {
try {
stdin.close();
} catch (IOException e) {
;
}
}
}