/*******************************************************************************
* This file is part of RedReader.
*
* RedReader 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.
*
* RedReader 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 RedReader. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
package org.quantumbadger.redreader.cache;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
final class CachingInputStream extends InputStream {
private final InputStream in;
private final OutputStream out;
private long bytesRead = 0;
private final BytesReadListener listener;
private boolean stillRunning = true;
public CachingInputStream(final InputStream in, final OutputStream out, final BytesReadListener listener) {
this.in = in;
this.out = out;
this.listener = listener;
}
public interface BytesReadListener {
void onBytesRead(long total);
}
private void notifyOnBytesRead() {
if(listener != null) listener.onBytesRead(bytesRead);
}
@Override
public void close() throws IOException {
if(stillRunning) {
in.close();
throw new RuntimeException("Closing CachingInputStream before the input stream has ended");
}
}
@Override
public int read() throws IOException {
final int byteRead = in.read();
if(byteRead >= 0) {
out.write(byteRead);
bytesRead++;
notifyOnBytesRead();
} else {
terminate();
}
return byteRead;
}
@Override
public int read(final byte[] buffer, final int offset, final int length) throws IOException {
final int result = in.read(buffer, offset, length);
if(result > 0) {
out.write(buffer, offset, result);
bytesRead += result;
notifyOnBytesRead();
} else {
terminate();
}
return result;
}
private void terminate() throws IOException {
if(stillRunning) {
stillRunning = false;
out.flush();
out.close();
in.close();
}
}
}