Refactoring: merged applyIPS and applyIPS32
This commit is contained in:
parent
22543f0710
commit
4f4e2e5dda
3 changed files with 40 additions and 138 deletions
|
@ -43,125 +43,14 @@ public class IPS extends Patcher {
|
||||||
private static final byte[] MAGIC_NUMBER_IPS = {0x50, 0x41, 0x54, 0x43, 0x48}; // "PATCH"
|
private static final byte[] MAGIC_NUMBER_IPS = {0x50, 0x41, 0x54, 0x43, 0x48}; // "PATCH"
|
||||||
private static final byte[] MAGIC_NUMBER_IPS32 = {0x49, 0x50, 0x53, 0x33, 0x32}; // "IPS32"
|
private static final byte[] MAGIC_NUMBER_IPS32 = {0x49, 0x50, 0x53, 0x33, 0x32}; // "IPS32"
|
||||||
|
|
||||||
|
private int mPatchType = NOT_IPS_PATCH;
|
||||||
|
|
||||||
public IPS(Context context, File patch, File rom, File output) {
|
public IPS(Context context, File patch, File rom, File output) {
|
||||||
super(context, patch, rom, output);
|
super(context, patch, rom, output);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void apply() throws PatchException, IOException {
|
public void apply() throws PatchException, IOException {
|
||||||
switch (checkIPS(patchFile)) {
|
|
||||||
case IPS_PATCH:
|
|
||||||
applyIPS();
|
|
||||||
break;
|
|
||||||
case IPS32_PATCH:
|
|
||||||
applyIPS32();
|
|
||||||
break;
|
|
||||||
case NOT_IPS_PATCH:
|
|
||||||
throw new PatchException(context.getString(R.string.notify_error_not_ips_patch));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void applyIPS() throws PatchException, IOException {
|
|
||||||
|
|
||||||
BufferedInputStream romStream = null;
|
|
||||||
BufferedInputStream patchStream = null;
|
|
||||||
BufferedOutputStream outputStream = null;
|
|
||||||
|
|
||||||
try {
|
|
||||||
romStream = new BufferedInputStream(new FileInputStream(romFile));
|
|
||||||
patchStream = new BufferedInputStream(new FileInputStream(patchFile));
|
|
||||||
outputStream = new BufferedOutputStream(new FileOutputStream(outputFile));
|
|
||||||
|
|
||||||
long romSize = romFile.length();
|
|
||||||
int romPos = 0;
|
|
||||||
int outPos = 0;
|
|
||||||
int offset;
|
|
||||||
int size;
|
|
||||||
|
|
||||||
if (patchFile.length() < 14) {
|
|
||||||
throw new PatchException(context.getString(R.string.notify_error_patch_corrupted));
|
|
||||||
}
|
|
||||||
|
|
||||||
// check magic string
|
|
||||||
byte[] magic = new byte[5];
|
|
||||||
size = patchStream.read(magic);
|
|
||||||
if (size != 5 || !Arrays.equals(magic, MAGIC_NUMBER_IPS))
|
|
||||||
throw new PatchException(context.getString(R.string.notify_error_not_ips_patch));
|
|
||||||
|
|
||||||
while (true) {
|
|
||||||
offset = (int)readOffset(patchStream, 3);
|
|
||||||
if (offset < 0)
|
|
||||||
throw new PatchException(context.getString(R.string.notify_error_patch_corrupted));
|
|
||||||
if (offset == 0x454f46) { // EOF
|
|
||||||
// truncate file or copy tail
|
|
||||||
if (romPos < romSize) {
|
|
||||||
offset = (int)readOffset(patchStream, 3);
|
|
||||||
if (offset != -1 && offset >= romPos) {
|
|
||||||
size = offset - romPos;
|
|
||||||
} else {
|
|
||||||
size = (int) romSize - romPos;
|
|
||||||
}
|
|
||||||
Utils.copy(romStream, outputStream, size);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (offset <= romSize) {
|
|
||||||
if (outPos < offset) {
|
|
||||||
size = offset - outPos;
|
|
||||||
Utils.copy(romStream, outputStream, size);
|
|
||||||
romPos += size;
|
|
||||||
outPos += size;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (outPos < romSize) {
|
|
||||||
size = (int) romSize - outPos;
|
|
||||||
Utils.copy(romStream, outputStream, size);
|
|
||||||
romPos += size;
|
|
||||||
outPos += size;
|
|
||||||
}
|
|
||||||
if (outPos < offset) {
|
|
||||||
size = offset - outPos;
|
|
||||||
Utils.copy(size, (byte) 0x0, outputStream);
|
|
||||||
outPos += size;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
size = (patchStream.read() << 8) + patchStream.read();
|
|
||||||
if (size != 0) {
|
|
||||||
byte[] data = new byte[size];
|
|
||||||
patchStream.read(data);
|
|
||||||
outputStream.write(data);
|
|
||||||
outPos += size;
|
|
||||||
} else { // RLE
|
|
||||||
size = (patchStream.read() << 8) + patchStream.read();
|
|
||||||
byte val = (byte) patchStream.read();
|
|
||||||
byte[] data = new byte[size];
|
|
||||||
Arrays.fill(data, val);
|
|
||||||
outputStream.write(data);
|
|
||||||
outPos += size;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (offset <= romSize) {
|
|
||||||
if (romPos + size > romSize) {
|
|
||||||
romPos = (int) romSize;
|
|
||||||
} else {
|
|
||||||
// Не используй romStream.skip(size), оно по какой-то причине не всегда пропускает байты.
|
|
||||||
byte[] buf = new byte[size];
|
|
||||||
romStream.read(buf);
|
|
||||||
romPos += size;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
IOUtils.closeQuietly(romStream);
|
|
||||||
IOUtils.closeQuietly(patchStream);
|
|
||||||
IOUtils.closeQuietly(outputStream);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void applyIPS32() throws PatchException, IOException {
|
|
||||||
|
|
||||||
BufferedInputStream romStream = null;
|
BufferedInputStream romStream = null;
|
||||||
BufferedInputStream patchStream = null;
|
BufferedInputStream patchStream = null;
|
||||||
BufferedOutputStream outputStream = null;
|
BufferedOutputStream outputStream = null;
|
||||||
|
@ -177,23 +66,33 @@ public class IPS extends Patcher {
|
||||||
long offset;
|
long offset;
|
||||||
long size;
|
long size;
|
||||||
|
|
||||||
if (patchFile.length() < 16) {
|
if (patchFile.length() < 14) {
|
||||||
throw new PatchException(context.getString(R.string.notify_error_patch_corrupted));
|
throw new PatchException(context.getString(R.string.notify_error_patch_corrupted));
|
||||||
}
|
}
|
||||||
|
|
||||||
byte[] magic = new byte[5];
|
byte[] magic = new byte[5];
|
||||||
size = patchStream.read(magic);
|
size = patchStream.read(magic);
|
||||||
if (size != 5 || !Arrays.equals(magic, MAGIC_NUMBER_IPS32))
|
if (Arrays.equals(magic, MAGIC_NUMBER_IPS)) {
|
||||||
|
mPatchType = IPS_PATCH;
|
||||||
|
} else if (Arrays.equals(magic, MAGIC_NUMBER_IPS32)) {
|
||||||
|
mPatchType = IPS32_PATCH;
|
||||||
|
} else {
|
||||||
throw new PatchException(context.getString(R.string.notify_error_not_ips_patch));
|
throw new PatchException(context.getString(R.string.notify_error_not_ips_patch));
|
||||||
|
}
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
offset = readOffset(patchStream, 4);
|
offset = readOffset(patchStream);
|
||||||
if (offset < 0)
|
if (offset < 0)
|
||||||
throw new PatchException(context.getString(R.string.notify_error_patch_corrupted));
|
throw new PatchException(context.getString(R.string.notify_error_patch_corrupted));
|
||||||
if (offset == 0x45454f46) { // EEOF
|
if (checkEOF(offset)) {
|
||||||
// copy tail
|
// truncate file or copy tail
|
||||||
if (romPos < romSize) {
|
if (romPos < romSize) {
|
||||||
size = romSize - romPos;
|
offset = readOffset(patchStream);
|
||||||
|
if (offset != -1 && offset >= romPos) {
|
||||||
|
size = offset - romPos;
|
||||||
|
} else {
|
||||||
|
size = romSize - romPos;
|
||||||
|
}
|
||||||
Utils.copy(romStream, outputStream, size);
|
Utils.copy(romStream, outputStream, size);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -237,7 +136,7 @@ public class IPS extends Patcher {
|
||||||
|
|
||||||
if (offset <= romSize) {
|
if (offset <= romSize) {
|
||||||
if (romPos + size > romSize) {
|
if (romPos + size > romSize) {
|
||||||
romPos = (int) romSize;
|
romPos = romSize;
|
||||||
} else {
|
} else {
|
||||||
byte[] buf = new byte[(int)size];
|
byte[] buf = new byte[(int)size];
|
||||||
romStream.read(buf);
|
romStream.read(buf);
|
||||||
|
@ -252,27 +151,30 @@ public class IPS extends Patcher {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int checkIPS(File file) throws PatchException, IOException {
|
private boolean checkEOF(long value) {
|
||||||
FileInputStream stream = null;
|
switch (mPatchType) {
|
||||||
try {
|
case IPS_PATCH:
|
||||||
stream = new FileInputStream(file);
|
return value == 0x454f46; // "EOF"
|
||||||
byte[] magic = new byte[5];
|
case IPS32_PATCH:
|
||||||
int count = stream.read(magic);
|
return value == 0x45454f46; // "EEOF"
|
||||||
if (count < 5)
|
|
||||||
throw new PatchException(context.getString(R.string.notify_error_not_ips_patch));
|
|
||||||
if (Arrays.equals(magic, MAGIC_NUMBER_IPS)) {
|
|
||||||
return IPS_PATCH;
|
|
||||||
} else if (Arrays.equals(magic, MAGIC_NUMBER_IPS32)) {
|
|
||||||
return IPS32_PATCH;
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
IOUtils.closeQuietly(stream);
|
|
||||||
}
|
}
|
||||||
return NOT_IPS_PATCH;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private long readOffset(InputStream stream, int numBytes) throws IOException {
|
private long readOffset(InputStream stream) throws IOException {
|
||||||
long offset = 0;
|
long offset = 0;
|
||||||
|
int numBytes;
|
||||||
|
switch (mPatchType) {
|
||||||
|
case IPS_PATCH:
|
||||||
|
numBytes = 3;
|
||||||
|
break;
|
||||||
|
case IPS32_PATCH:
|
||||||
|
numBytes = 4;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new IOException("Internal IPS error");
|
||||||
|
}
|
||||||
|
|
||||||
while (numBytes-- != 0) {
|
while (numBytes-- != 0) {
|
||||||
int b = stream.read();
|
int b = stream.read();
|
||||||
if (b == -1)
|
if (b == -1)
|
||||||
|
|
Binary file not shown.
|
@ -1 +1 @@
|
||||||
7Ie5‚7P‰'9R0˙—… #u€–r4… r222#—rW9E’˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙u 4u‘#…rW <20>C…#B#u #C$2B—P’4…G#…—#•r4 W 2G`’t—‚C TTeWFT‡FThFT„eHFTteAgHTe#B4eAet<65>FTWHtEcT<63>yeEFWFThv†TETeFCeA<EFBFBD>te$<24>t25v‡F14eFC‡F5Tv„cQCVThFTeHFTe˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙ö”eGhCT„5„v5WFTeI‡
|
7Ie5‚7P‰'9R0˙—… #u€–r4… r222#—rW9E’˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙u 4u‘#…rW <20>C…#B#u #C$2B—P’4…G#…—#•r4 W 2G`’t—‚C TTeWFT‡FThFT„eHFTteAgHTe#B4eAet<65>FTWHtEcT<63>yeEFWFThv†TeTeFCeA<EFBFBD>te$<24>t25v‡F14eFC‡F5Tv„cQCVThFTeHFTe˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙ö”eGhCT„5„v5WFTeI‡
|
Loading…
Add table
Reference in a new issue