JNUSLib/src/de/mas/wiiu/jnus/implementations/wud/reader/WUDDiscReaderSplitted.java

99 lines
3.3 KiB
Java
Raw Normal View History

package de.mas.wiiu.jnus.implementations.wud.reader;
2016-12-12 21:01:12 +01:00
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.io.RandomAccessFile;
import java.util.Arrays;
import de.mas.wiiu.jnus.implementations.wud.WUDImage;
import lombok.extern.java.Log;
@Log
public class WUDDiscReaderSplitted extends WUDDiscReader {
public static long WUD_SPLITTED_FILE_SIZE = 0x100000L * 0x800L;
public static long NUMBER_OF_FILES = 12;
public static String WUD_SPLITTED_DEFAULT_FILEPATTERN = "game_part%d.wud";
2016-12-12 21:01:12 +01:00
public WUDDiscReaderSplitted(WUDImage image) {
super(image);
}
2016-12-12 21:01:12 +01:00
@Override
protected void readEncryptedToOutputStream(OutputStream outputStream, long offset, long size) throws IOException {
RandomAccessFile input = getFileByOffset(offset);
2016-12-12 21:01:12 +01:00
int bufferSize = 0x8000;
byte[] buffer = new byte[bufferSize];
long totalread = 0;
long curOffset = offset;
2016-12-12 21:01:12 +01:00
int part = getFilePartByOffset(offset);
long offsetInFile = getOffsetInFilePart(part, curOffset);
do {
2016-12-12 21:01:12 +01:00
offsetInFile = getOffsetInFilePart(part, curOffset);
int curReadSize = bufferSize;
if ((offsetInFile + bufferSize) >= WUD_SPLITTED_FILE_SIZE) { // Will we read above the part?
long toRead = WUD_SPLITTED_FILE_SIZE - offsetInFile;
if (toRead == 0) { // just load the new file
2016-12-12 21:01:12 +01:00
input.close();
input = getFileByOffset(curOffset);
part++;
offsetInFile = getOffsetInFilePart(part, curOffset);
} else {
curReadSize = (int) toRead; // And first only read until the part ends
2016-12-12 21:01:12 +01:00
}
}
int read = input.read(buffer, 0, curReadSize);
if (read < 0) break;
if (totalread + read > size) {
2016-12-12 21:01:12 +01:00
read = (int) (size - totalread);
}
try {
2016-12-12 21:01:12 +01:00
outputStream.write(Arrays.copyOfRange(buffer, 0, read));
} catch (IOException e) {
if (e.getMessage().equals("Pipe closed")) {
2016-12-12 21:01:12 +01:00
break;
} else {
2016-12-12 21:01:12 +01:00
input.close();
throw e;
}
}
totalread += read;
curOffset += read;
} while (totalread < size);
2016-12-12 21:01:12 +01:00
input.close();
outputStream.close();
}
private int getFilePartByOffset(long offset) {
return (int) (offset / WUD_SPLITTED_FILE_SIZE) + 1;
2016-12-12 21:01:12 +01:00
}
private long getOffsetInFilePart(int part, long offset) {
return offset - ((long) (part - 1) * WUD_SPLITTED_FILE_SIZE);
2016-12-12 21:01:12 +01:00
}
private RandomAccessFile getFileByOffset(long offset) throws IOException {
File filehandlePart1 = getImage().getFileHandle();
2016-12-12 21:01:12 +01:00
String pathToFiles = filehandlePart1.getParentFile().getAbsolutePath();
2016-12-12 21:01:12 +01:00
int filePart = getFilePartByOffset(offset);
2016-12-12 21:01:12 +01:00
String filePartPath = pathToFiles + File.separator + String.format(WUD_SPLITTED_DEFAULT_FILEPATTERN, filePart);
2016-12-12 21:01:12 +01:00
File part = new File(filePartPath);
if (!part.exists()) {
log.info("File does not exist");
2016-12-12 21:01:12 +01:00
return null;
}
RandomAccessFile result = new RandomAccessFile(part, "r");
2016-12-12 21:01:12 +01:00
result.seek(getOffsetInFilePart(filePart, offset));
return result;
}
}