ns-usbloader/src/main/java/nsusbloader/COM/Helpers/NSSplitReader.java

109 lines
3.9 KiB
Java

/*
Copyright 2019-2020 Dmitry Isaenko
This file is part of NS-USBloader.
NS-USBloader 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.
NS-USBloader 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 NS-USBloader. If not, see <https://www.gnu.org/licenses/>.
*/
package nsusbloader.COM.Helpers;
import java.io.*;
/**
* Handle Split files
* */
public class NSSplitReader implements Closeable {
private final String splitFileDir;
private final long referenceSplitChunkSize;
private byte subFileNum;
private long curPosition;
private BufferedInputStream biStream;
public NSSplitReader(File file, long seekToPosition) throws IOException, NullPointerException {
this.splitFileDir = file.getAbsolutePath()+File.separator;
File subFile = new File(file.getAbsolutePath()+File.separator+"00");
if (! file.exists())
throw new FileNotFoundException("File not found on "+file.getAbsolutePath()+File.separator+"00");
this.referenceSplitChunkSize = subFile.length();
this.subFileNum = (byte) (seekToPosition / referenceSplitChunkSize);
this.biStream = new BufferedInputStream(new FileInputStream(splitFileDir + String.format("%02d", subFileNum)));
this.curPosition = seekToPosition;
seekToPosition -= referenceSplitChunkSize * subFileNum;
if (seekToPosition != biStream.skip(seekToPosition))
throw new IOException("Unable to seek to requested position of "+seekToPosition+" for file "+splitFileDir+String.format("%02d", subFileNum));
}
public long seek(long position) throws IOException{
byte subFileRequested = (byte) (position / referenceSplitChunkSize);
if ((subFileRequested != this.subFileNum) || (curPosition > position)) {
biStream.close();
biStream = new BufferedInputStream(new FileInputStream(splitFileDir + String.format("%02d", subFileRequested)));
this.subFileNum = subFileRequested;
this.curPosition = referenceSplitChunkSize * subFileRequested;
}
long retVal = biStream.skip(position - curPosition);
retVal += curPosition;
this.curPosition = position;
return retVal;
}
public int read(byte[] readBuffer) throws IOException, NullPointerException {
final int requested = readBuffer.length;
int readPrtOne;
if ( (curPosition + requested) <= (referenceSplitChunkSize * (subFileNum+1))) {
if ((readPrtOne = biStream.read(readBuffer)) < 0 )
return readPrtOne;
curPosition += readPrtOne;
return readPrtOne;
}
int partOne = (int) (referenceSplitChunkSize * (subFileNum+1) - curPosition);
int partTwo = requested - partOne;
int readPrtTwo;
if ( (readPrtOne = biStream.read(readBuffer, 0, partOne)) < 0)
return readPrtOne;
curPosition += readPrtOne;
if (readPrtOne != partOne)
return readPrtOne;
biStream.close();
subFileNum += 1;
biStream = new BufferedInputStream(new FileInputStream(splitFileDir + String.format("%02d", subFileNum)));
if ( (readPrtTwo = biStream.read(readBuffer, partOne, partTwo) ) < 0)
return readPrtTwo;
curPosition += readPrtTwo;
return readPrtOne + readPrtTwo;
}
@Override
public void close() throws IOException {
if (biStream != null)
biStream.close();
}
}