/* 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) { ; } } }