package net.sf.beanlib.util;
import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.util.Iterator;
import java.util.NoSuchElementException;
import net.jcip.annotations.NotThreadSafe;
/**
* @author Hanson Char
*/
@NotThreadSafe
class LineIterator implements Iterator<String>, Closeable {
private boolean hasNextExecuted;
private String line;
private LineNumberReader lnr;
private final TextIterable textIterable;
private final boolean returnNullUponEof;
LineIterator(TextIterable textIterable, InputStream is, boolean returnNullUponEof, Charset charset) {
this.textIterable = textIterable;
this.returnNullUponEof = returnNullUponEof;
InputStreamReader isr = null;
try {
isr = charset == null ? new InputStreamReader(is) : new InputStreamReader(is, charset);
lnr = new LineNumberReader(isr);
} catch (Exception ex) {
try {
if (lnr != null)
lnr.close();
else if (isr != null)
isr.close();
else if (is != null)
is.close();
} catch (Throwable ignore) {}
}
}
LineIterator(TextIterable textIterable, InputStream is, boolean returnNullUponEof, CharsetDecoder decoder) {
this.textIterable = textIterable;
this.returnNullUponEof = returnNullUponEof;
InputStreamReader isr = null;
try {
isr = new InputStreamReader(is, decoder);
lnr = new LineNumberReader(isr);
} catch (Exception ex) {
try {
if (lnr != null)
lnr.close();
else if (isr != null)
isr.close();
else if (is != null)
is.close();
} catch (Throwable ignore) {}
}
}
@Override
public boolean hasNext() {
if (hasNextExecuted)
return line != null;
try {
hasNextExecuted = true;
if (lnr != null) {
line = lnr.readLine();
if (line == null)
close();
}
return line != null;
} catch (IOException e) {
throw new IllegalStateException(e);
}
}
@Override
public String next() {
if (hasNextExecuted) {
hasNextExecuted = false;
return line == null ? eof() : line;
}
return hasNext() ? next() : eof();
}
private String eof() {
if (returnNullUponEof)
return null;
throw new NoSuchElementException();
}
@Override
public void close() {
if (lnr != null) {
textIterable.removeLineIterator(this);
closeInPrivate();
}
}
public int getLineNumber() {
return lnr == null ? -1 : lnr.getLineNumber();
}
void closeInPrivate() {
if (lnr != null) {
try {
lnr.close();
} catch (IOException ignore) {}
line = null;
lnr = null;
}
}
@Override
public void remove() {
throw new UnsupportedOperationException("remove not supported");
}
@Override
public void finalize() {
try {
super.finalize();
} catch (Throwable ex) {}
close();
}
}