FriendCloudProto/src/main/java/moe/nekojimi/friendcloud/FilePieceAccess.java

87 lines
2.6 KiB
Java

package moe.nekojimi.friendcloud;
import moe.nekojimi.friendcloud.objects.NetworkFile;
import java.io.Closeable;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
public class FilePieceAccess implements Closeable
{
private final NetworkFile networkFile;
private final File file;
private final RandomAccessFile randomAccessFile;
private final OpenMode openMode;
public FilePieceAccess(NetworkFile networkFile, OpenMode openMode) throws IOException
{
this.networkFile = networkFile;
this.file = networkFile.getOrCreateLocalFile();
this.randomAccessFile = new RandomAccessFile(file,openMode == OpenMode.READ_WRITE ? "rw" : "r");
this.openMode = openMode;
if (openMode == OpenMode.READ_WRITE)
randomAccessFile.setLength(file.length());
}
public long getPieceOffset(int index)
{
return (index * networkFile.getPieceSize());
}
public int getPieceSize(int index)
{
if (index != networkFile.getPieceCount()-1)
return Math.toIntExact(networkFile.getPieceSize());
int ret = Math.toIntExact(networkFile.getSize() % networkFile.getPieceSize());
if (ret == 0)
ret = Math.toIntExact(networkFile.getPieceSize());
return ret;
}
public byte[] readPiece(int index) throws IOException
{
if (index >= networkFile.getPieceCount())
throw new IllegalArgumentException("Piece index out of range!!");
if (index < 0)
throw new IllegalArgumentException("Piece index is negative!!");
if (!networkFile.hasPiece(index))
return null;
int pieceSize = getPieceSize(index);
byte[] buffer = new byte[pieceSize];
long pieceOffset = getPieceOffset(index);
System.out.println("Reading piece " + index + " from file " + file.getName() + " (offset=" + pieceOffset + ", size=" + pieceSize + ")");
randomAccessFile.seek(pieceOffset);
randomAccessFile.read(buffer);
return buffer;
}
public void writePiece(int index, byte[] buffer) throws IOException
{
if (openMode == OpenMode.READ_ONLY)
throw new IllegalStateException("File was opened read-only!");
else if (buffer.length != getPieceSize(index))
throw new IllegalArgumentException("Received a file piece that's the wrong size!! Length = " + buffer.length + " != Piece Size = " + getPieceSize(index));
else if (index >= networkFile.getPieceCount())
throw new IllegalArgumentException("Received a file piece with an index past the end of the file!!");
randomAccessFile.seek(getPieceOffset(index));
randomAccessFile.write(buffer);
networkFile.setHasPiece(index, true);
}
@Override
public void close() throws IOException
{
randomAccessFile.close();
}
public enum OpenMode
{
READ_ONLY,
READ_WRITE;
}
}