/*
* Copyright (C) 2008 Universidade Federal de Campina Grande
*
* This file is part of OurGrid.
*
* OurGrid is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser 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 Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package org.ourgrid.common.specification.io;
import java.io.FileReader;
import java.io.IOException;
import java.io.PushbackReader;
/**
* This is a util Character reader that can read and unread characters and
* ignore lines.
*/
public class CharReader {
public static final String UNIX_LINE_SEPARATOR = "\n";
private final int FIRST_LINE = 1;
public static final char EOF_CHAR = (char) -1;
public static final int MAX_UNREAD_CHAR_NUMBER = 1000;
private char next;
private PushbackReader reader;
private FileReader fReader;
private int actualLine;
/**
* Constructor of a character reader that uses the name of the file do be
* read.
*
* @param file the name of the file to be read
* @throws IOException If the file could not be found.
*/
public CharReader( String file ) throws IOException {
this.fReader = new FileReader( file );
this.reader = new PushbackReader( fReader, MAX_UNREAD_CHAR_NUMBER );
actualLine = FIRST_LINE;
}
/**
* Read a unique character at a time, including all the spetial structural
* character. Obs.: Ignores the special character '\r' to turn windows
* edited files compatible.
*
* @return the read character.
*/
public char readChar() throws IOException {
next = (char) reader.read();
if ( next == '\r' ) {
next = (char) reader.read();
}
if ( String.valueOf( next ).equals( UNIX_LINE_SEPARATOR ) ) {
actualLine++;
}
return next;
}
/**
* Read only non blank characters ignoring all "Character.isWhitespace()"
* excepts EOF and this.UNIX_LINE_SEPARATOR
*
* @return the non blank read character
* @throws IOException if happens any reading problem.
*/
public char readNonBlankChar() throws IOException {
next = readChar();
while ( Character.isWhitespace( next ) && (next != EOF_CHAR) && (next != UNIX_LINE_SEPARATOR.charAt( 0 )) ) {
next = readChar();
}
return next;
}
/**
* Ignores from the actual position all the characters until the end of line
* (including it).
*
* @throws IOException if happens any reading problem.
*/
public void readLine() throws IOException {
next = (char) reader.read();
while ( !(String.valueOf( next ).equals( UNIX_LINE_SEPARATOR ) || (next == EOF_CHAR)) ) {
next = (char) reader.read();
}
actualLine++;
}
/**
* Unread a pre-defined ( this.MAX_UNREAD_CHAR_NUMBER ) number of read
* characters.
*
* @param unwishedChar the temporary unwished char to be inserted back at
* the reading queue.
* @throws IOException if this method is called more then the maximum times
* permited (without any character be read)
*/
public void unreadChar( char unwishedChar ) throws IOException {
reader.unread( unwishedChar );
if ( String.valueOf( unwishedChar ).equals( UNIX_LINE_SEPARATOR ) ) {
actualLine--;
next = '\t'; // This character is just to be different from \n
// (to be considered at the getActualLine() method)
}
}
/**
* Closes the reader properlly.
*
* @throws IOException if any problem related with the closing action
* happens.
*/
public void closeStreams() throws IOException {
reader.close();
fReader.close();
}
/**
* @return returns the number of the line where the reader is now at the
* file.
*/
public int getActualLine() {
if ( next == '\n' ) {
return actualLine - 1;
}
return actualLine;
}
}