2025-09-02 12:22:20 +01:00
|
|
|
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;
|
2025-09-30 14:10:06 +01:00
|
|
|
private final OpenMode openMode;
|
2025-09-02 12:22:20 +01:00
|
|
|
|
2025-09-30 14:10:06 +01:00
|
|
|
public FilePieceAccess(NetworkFile networkFile, OpenMode openMode) throws IOException
|
2025-09-02 12:22:20 +01:00
|
|
|
{
|
|
|
|
this.networkFile = networkFile;
|
|
|
|
this.file = networkFile.getOrCreateLocalFile();
|
2025-09-30 14:10:06 +01:00
|
|
|
this.randomAccessFile = new RandomAccessFile(file,openMode == OpenMode.READ_WRITE ? "rw" : "r");
|
|
|
|
this.openMode = openMode;
|
|
|
|
if (openMode == OpenMode.READ_WRITE)
|
|
|
|
randomAccessFile.setLength(file.length());
|
2025-09-02 12:22:20 +01:00
|
|
|
}
|
|
|
|
|
2025-09-23 12:27:42 +01:00
|
|
|
public long getPieceOffset(int index)
|
2025-09-02 12:22:20 +01:00
|
|
|
{
|
2025-09-23 12:27:42 +01:00
|
|
|
return (index * networkFile.getPieceSize());
|
2025-09-02 12:22:20 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
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];
|
2025-09-23 12:27:42 +01:00
|
|
|
long pieceOffset = getPieceOffset(index);
|
2025-09-02 12:22:20 +01:00
|
|
|
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
|
|
|
|
{
|
2025-09-30 14:10:06 +01:00
|
|
|
if (openMode == OpenMode.READ_ONLY)
|
|
|
|
throw new IllegalStateException("File was opened read-only!");
|
|
|
|
else if (buffer.length != getPieceSize(index))
|
2025-09-02 12:22:20 +01:00
|
|
|
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();
|
|
|
|
}
|
2025-09-30 14:10:06 +01:00
|
|
|
|
|
|
|
public enum OpenMode
|
|
|
|
{
|
|
|
|
READ_ONLY,
|
|
|
|
READ_WRITE;
|
|
|
|
}
|
2025-09-02 12:22:20 +01:00
|
|
|
}
|