blob: a22466d5c5da4ce575a1e9745724460de12d012a [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2003, 2008 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.osgi.framework.internal.reliablefile;
import java.io.*;
/**
* A ReliableFile FileInputStream replacement class.
* This class can be used just like FileInputStream. The class
* is in partnership with ReliableFileOutputStream to avoid losing
* file data by using multiple files.
*
* @see ReliableFileOutputStream
*/
public class ReliableFileInputStream extends FilterInputStream {
/**
* ReliableFile object for this file.
*/
private ReliableFile reliable;
/**
* size of crc and signature
*/
private int sigSize;
/**
* current position reading from file
*/
private int readPos;
/**
* total file length available for reading
*/
private int length;
/**
* Constructs a new ReliableFileInputStream on the file named <code>name</code>. If the
* file does not exist, the <code>FileNotFoundException</code> is thrown.
* The <code>name</code> may be absolute or relative
* to the System property <code>"user.dir"</code>.
*
* @param name the file on which to stream reads.
* @exception java.io.IOException If an error occurs opening the file.
*/
public ReliableFileInputStream(String name) throws IOException {
this(ReliableFile.getReliableFile(name), ReliableFile.GENERATION_LATEST, ReliableFile.OPEN_BEST_AVAILABLE);
}
/**
* Constructs a new ReliableFileInputStream on the File <code>file</code>. If the
* file does not exist, the <code>FileNotFoundException</code> is thrown.
*
* @param file the File on which to stream reads.
* @exception java.io.IOException If an error occurs opening the file.
*/
public ReliableFileInputStream(File file) throws IOException {
this(ReliableFile.getReliableFile(file), ReliableFile.GENERATION_LATEST, ReliableFile.OPEN_BEST_AVAILABLE);
}
/**
* Constructs a new ReliableFileInputStream on the File <code>file</code>. If the
* file does not exist, the <code>FileNotFoundException</code> is thrown.
*
* @param file the File on which to stream reads.
* @param generation a specific generation requested.
* @param openMask mask used to open data.
* are invalid (corrupt, missing, etc).
* @exception java.io.IOException If an error occurs opening the file.
*/
public ReliableFileInputStream(File file, int generation, int openMask) throws IOException {
this(ReliableFile.getReliableFile(file), generation, openMask);
}
/**
*
* @param reliable The ReliableFile on which to read.
* @param generation a specific generation requested.
* @param openMask mask used to open data.
* are invalid (corrupt, missing, etc).
* @throws IOException If an error occurs opening the file.
*/
private ReliableFileInputStream(ReliableFile reliable, int generation, int openMask) throws IOException {
super(reliable.getInputStream(generation, openMask));
this.reliable = reliable;
sigSize = reliable.getSignatureSize();
readPos = 0;
length = super.available();
if (sigSize > length)
length = 0; // shouldn't ever happen
else
length -= sigSize;
}
/**
* Closes this input stream and releases any system resources associated
* with the stream.
*
* @exception java.io.IOException If an error occurs closing the file.
*/
public synchronized void close() throws IOException {
if (reliable != null) {
try {
super.close();
} finally {
reliable.closeInputFile();
reliable = null;
}
}
}
/**
* Override default FilterInputStream method.
* @see FilterInputStream#read(byte[], int, int)
*/
public synchronized int read(byte b[], int off, int len) throws IOException {
if (readPos >= length) {
return -1;
}
int num = super.read(b, off, len);
if (num != -1) {
if (num + readPos > length) {
num = length - readPos;
}
readPos += num;
}
return num;
}
/**
* Override default FilterInputStream method.
* @see FilterInputStream#read(byte[])
*/
public synchronized int read(byte b[]) throws IOException {
return read(b, 0, b.length);
}
/**
* Override default FilterInputStream method.
* @see FilterInputStream#read()
*/
public synchronized int read() throws IOException {
if (readPos >= length) {
return -1;
}
int num = super.read();
if (num != -1) {
readPos++;
}
return num;
}
/**
* Override default available method.
* @see FilterInputStream#available()
*/
public synchronized int available() throws IOException {
if (readPos < length) // just in case
return (length - readPos);
return 0;
}
/**
* Override default skip method.
* @see FilterInputStream#skip(long)
*/
public synchronized long skip(long n) throws IOException {
long len = super.skip(n);
if (readPos + len > length)
len = length - readPos;
readPos += len;
return len;
}
/**
* Override default markSupported method.
* @see FilterInputStream#markSupported()
*/
public boolean markSupported() {
return false;
}
/**
* Override default mark method.
* @see FilterInputStream#mark(int)
*/
public void mark(int readlimit) {
//ignore
}
/**
* Override default reset method.
* @see FilterInputStream#reset()
*/
public void reset() throws IOException {
throw new IOException("reset not supported."); //$NON-NLS-1$
}
}