2017-05-17 19:20:42 +02:00
|
|
|
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;
|
|
|
|
|
2017-05-17 19:20:42 +02:00
|
|
|
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);
|
|
|
|
}
|
2017-05-17 19:20:42 +02:00
|
|
|
|
2016-12-12 21:01:12 +01:00
|
|
|
@Override
|
|
|
|
protected void readEncryptedToOutputStream(OutputStream outputStream, long offset, long size) throws IOException {
|
|
|
|
RandomAccessFile input = getFileByOffset(offset);
|
2017-05-17 19:20:42 +02:00
|
|
|
|
2016-12-12 21:01:12 +01:00
|
|
|
int bufferSize = 0x8000;
|
|
|
|
byte[] buffer = new byte[bufferSize];
|
|
|
|
long totalread = 0;
|
|
|
|
long curOffset = offset;
|
2017-05-17 19:20:42 +02:00
|
|
|
|
2016-12-12 21:01:12 +01:00
|
|
|
int part = getFilePartByOffset(offset);
|
|
|
|
long offsetInFile = getOffsetInFilePart(part, curOffset);
|
2017-05-17 19:20:42 +02:00
|
|
|
|
|
|
|
do {
|
2016-12-12 21:01:12 +01:00
|
|
|
offsetInFile = getOffsetInFilePart(part, curOffset);
|
|
|
|
int curReadSize = bufferSize;
|
2017-05-17 19:20:42 +02:00
|
|
|
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);
|
2017-05-17 19:20:42 +02:00
|
|
|
} else {
|
|
|
|
curReadSize = (int) toRead; // And first only read until the part ends
|
2016-12-12 21:01:12 +01:00
|
|
|
}
|
|
|
|
}
|
2017-05-17 19:20:42 +02: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);
|
|
|
|
}
|
2017-05-17 19:20:42 +02:00
|
|
|
try {
|
2016-12-12 21:01:12 +01:00
|
|
|
outputStream.write(Arrays.copyOfRange(buffer, 0, read));
|
2017-05-17 19:20:42 +02:00
|
|
|
} catch (IOException e) {
|
|
|
|
if (e.getMessage().equals("Pipe closed")) {
|
2016-12-12 21:01:12 +01:00
|
|
|
break;
|
2017-05-17 19:20:42 +02:00
|
|
|
} else {
|
2016-12-12 21:01:12 +01:00
|
|
|
input.close();
|
|
|
|
throw e;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
totalread += read;
|
|
|
|
curOffset += read;
|
2017-05-17 19:20:42 +02:00
|
|
|
} while (totalread < size);
|
|
|
|
|
2016-12-12 21:01:12 +01:00
|
|
|
input.close();
|
|
|
|
outputStream.close();
|
|
|
|
}
|
2017-05-17 19:20:42 +02:00
|
|
|
|
|
|
|
private int getFilePartByOffset(long offset) {
|
|
|
|
return (int) (offset / WUD_SPLITTED_FILE_SIZE) + 1;
|
2016-12-12 21:01:12 +01:00
|
|
|
}
|
2017-05-17 19:20:42 +02: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
|
|
|
}
|
2017-05-17 19:20:42 +02: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();
|
2017-05-17 19:20:42 +02:00
|
|
|
|
2016-12-12 21:01:12 +01:00
|
|
|
int filePart = getFilePartByOffset(offset);
|
2017-05-17 19:20:42 +02:00
|
|
|
|
2016-12-12 21:01:12 +01:00
|
|
|
String filePartPath = pathToFiles + File.separator + String.format(WUD_SPLITTED_DEFAULT_FILEPATTERN, filePart);
|
2017-05-17 19:20:42 +02:00
|
|
|
|
2016-12-12 21:01:12 +01:00
|
|
|
File part = new File(filePartPath);
|
2017-05-17 19:20:42 +02:00
|
|
|
|
|
|
|
if (!part.exists()) {
|
|
|
|
log.info("File does not exist");
|
2016-12-12 21:01:12 +01:00
|
|
|
return null;
|
|
|
|
}
|
2017-05-17 19:20:42 +02:00
|
|
|
RandomAccessFile result = new RandomAccessFile(part, "r");
|
2016-12-12 21:01:12 +01:00
|
|
|
result.seek(getOffsetInFilePart(filePart, offset));
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
}
|