From 4f4e2e5dda8c899f6ea97d04c221380f989f8d5a Mon Sep 17 00:00:00 2001 From: Boris Timofeev Date: Tue, 24 Jan 2017 16:12:09 +0300 Subject: [PATCH] Refactoring: merged applyIPS and applyIPS32 --- .../org/emunix/unipatcher/patcher/IPS.java | 176 ++++-------------- app/src/test/resources/ips/extend_ips32.ips | Bin 226 -> 219 bytes .../test/resources/ips/extend_ips32_mod.bin | 2 +- 3 files changed, 40 insertions(+), 138 deletions(-) diff --git a/app/src/main/java/org/emunix/unipatcher/patcher/IPS.java b/app/src/main/java/org/emunix/unipatcher/patcher/IPS.java index c732fa9..23f69d8 100644 --- a/app/src/main/java/org/emunix/unipatcher/patcher/IPS.java +++ b/app/src/main/java/org/emunix/unipatcher/patcher/IPS.java @@ -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_IPS32 = {0x49, 0x50, 0x53, 0x33, 0x32}; // "IPS32" + private int mPatchType = NOT_IPS_PATCH; + public IPS(Context context, File patch, File rom, File output) { super(context, patch, rom, output); } @Override 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 patchStream = null; BufferedOutputStream outputStream = null; @@ -177,23 +66,33 @@ public class IPS extends Patcher { long offset; long size; - if (patchFile.length() < 16) { + if (patchFile.length() < 14) { throw new PatchException(context.getString(R.string.notify_error_patch_corrupted)); } byte[] magic = new byte[5]; 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)); + } while (true) { - offset = readOffset(patchStream, 4); + offset = readOffset(patchStream); if (offset < 0) throw new PatchException(context.getString(R.string.notify_error_patch_corrupted)); - if (offset == 0x45454f46) { // EEOF - // copy tail + if (checkEOF(offset)) { + // truncate file or copy tail 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); } break; @@ -237,7 +136,7 @@ public class IPS extends Patcher { if (offset <= romSize) { if (romPos + size > romSize) { - romPos = (int) romSize; + romPos = romSize; } else { byte[] buf = new byte[(int)size]; romStream.read(buf); @@ -252,27 +151,30 @@ public class IPS extends Patcher { } } - public int checkIPS(File file) throws PatchException, IOException { - FileInputStream stream = null; - try { - stream = new FileInputStream(file); - byte[] magic = new byte[5]; - int count = stream.read(magic); - 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); + private boolean checkEOF(long value) { + switch (mPatchType) { + case IPS_PATCH: + return value == 0x454f46; // "EOF" + case IPS32_PATCH: + return value == 0x45454f46; // "EEOF" } - 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; + 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) { int b = stream.read(); if (b == -1) diff --git a/app/src/test/resources/ips/extend_ips32.ips b/app/src/test/resources/ips/extend_ips32.ips index 1a5dccae6bc85173b1b2088f97bc901a45b7745f..49c8d415430080f303f9f8ff4827a94983ce845f 100644 GIT binary patch delta 9 QcmaFFc$;y8$3*|h02JB;3jhEB delta 14 Vcmcc3_=s_W2g^DJM%Rh1(*P%~1pEL1 diff --git a/app/src/test/resources/ips/extend_ips32_mod.bin b/app/src/test/resources/ips/extend_ips32_mod.bin index 87f7dcc..db58d59 100644 --- a/app/src/test/resources/ips/extend_ips32_mod.bin +++ b/app/src/test/resources/ips/extend_ips32_mod.bin @@ -1 +1 @@ -7Ie57P'9R0 #ur4 r222#rW9Eu 4u#rW C#B#u #C$2BP4G##r4 W 2G`tC TTeWFTFThFTeHFTteAgHTe#B4eAetFTWHtEcTyeEFWFThvTETeFCeAte$t25vF14eFCF5TvcQCVThFTeHFTeeGhCT5v5WFTeI \ No newline at end of file +7Ie57P'9R0 #ur4 r222#rW9Eu 4u#rW C#B#u #C$2BP4G##r4 W 2G`tC TTeWFTFThFTeHFTteAgHTe#B4eAetFTWHtEcTyeEFWFThvTeTeFCeAte$t25vF14eFCF5TvcQCVThFTeHFTeeGhCT5v5WFTeI \ No newline at end of file