diff --git a/Readme.md b/Readme.md index 60a5db4..20e4186 100644 --- a/Readme.md +++ b/Readme.md @@ -17,7 +17,7 @@ See https://jitpack.io/#inwc3/JMPQ3/ Gradle Example: ```gradle dependencies { - compile 'com.github.inwc3:JMPQ3:1.5.6' + compile 'com.github.inwc3:JMPQ3:1.5.8' } allprojects { repositories { diff --git a/build.gradle b/build.gradle index 16b1ac5..3f3db63 100644 --- a/build.gradle +++ b/build.gradle @@ -9,7 +9,7 @@ plugins { } group 'systems.crigges' -version '1.5.7' +version '1.5.8' repositories { jcenter() @@ -28,7 +28,7 @@ dist.archiveName = "${jar.baseName}.${jar.extension}" dependencies { compile 'com.jcraft:jzlib:1.1.3' compile 'com.esotericsoftware.minlog:minlog:1.2' - testCompile 'org.testng:testng:6.1.1' + testCompile 'org.testng:testng:6.13.1' } test { diff --git a/src/main/java/systems/crigges/jmpq3/JMpqEditor.java b/src/main/java/systems/crigges/jmpq3/JMpqEditor.java index 5a32880..17a8775 100644 --- a/src/main/java/systems/crigges/jmpq3/JMpqEditor.java +++ b/src/main/java/systems/crigges/jmpq3/JMpqEditor.java @@ -599,7 +599,7 @@ public MpqFile getMpqFile(String name) throws IOException { * @param name of the file inside the mpq * @throws JMpqException if file is not found or access errors occur */ - public void deleteFile(String name) throws JMpqException { + public void deleteFile(String name) { if (!canWrite) { throw new NonWritableChannelException(); } @@ -607,6 +607,24 @@ public void deleteFile(String name) throws JMpqException { listFile.removeFile(name); } + /** + * Inserts the specified byte array into the mpq once you close the editor. + * + * @param name of the file inside the mpq + * @param input the input byte array + * @throws JMpqException if file is not found or access errors occur + */ + public void insertByteArray(String name, byte[] input) throws NonWritableChannelException { + if (!canWrite) { + throw new NonWritableChannelException(); + } + + listFile.addFile(name); + ByteBuffer data = ByteBuffer.wrap(input); + filesToAdd.add(data); + internalFilename.put(data, name); + } + /** * Inserts the specified file into the mpq once you close the editor. * @@ -616,7 +634,7 @@ public void deleteFile(String name) throws JMpqException { * further changes won't affect the resulting mpq * @throws JMpqException if file is not found or access errors occur */ - public void insertFile(String name, File file, boolean backupFile) throws JMpqException { + public void insertFile(String name, File file, boolean backupFile) throws IOException { if (!canWrite) { throw new NonWritableChannelException(); } diff --git a/src/main/java/systems/crigges/jmpq3/TestHelper.java b/src/main/java/systems/crigges/jmpq3/TestHelper.java new file mode 100644 index 0000000..2be470e --- /dev/null +++ b/src/main/java/systems/crigges/jmpq3/TestHelper.java @@ -0,0 +1,43 @@ +package systems.crigges.jmpq3; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.security.DigestInputStream; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +/** + * Created by Frotty on 11.06.2017. + */ +public class TestHelper { + // stolen from http://stackoverflow.com/a/304350/303637 + public static String md5(File f) { + try { + byte[] buf = new byte[1024]; + MessageDigest md = MessageDigest.getInstance("MD5"); + try (InputStream is = new FileInputStream(f); + DigestInputStream dis = new DigestInputStream(is, md);) { + while (dis.read(buf) >= 0); + } + byte[] digest = md.digest(); + return bytesToHex(digest); + } catch (NoSuchAlgorithmException | IOException e) { + throw new RuntimeException(e); + } + } + + // stolen from http://stackoverflow.com/a/9855338/303637 + final protected static char[] hexArray = "0123456789abcdef".toCharArray(); + public static String bytesToHex(byte[] bytes) { + char[] hexChars = new char[bytes.length * 2]; + int v; + for ( int j = 0; j < bytes.length; j++ ) { + v = bytes[j] & 0xFF; + hexChars[j * 2] = hexArray[v >>> 4]; + hexChars[j * 2 + 1] = hexArray[v & 0x0F]; + } + return new String(hexChars); + } +} diff --git a/src/test/java/systems/crigges/jmpq3test/MpqTests.java b/src/test/java/systems/crigges/jmpq3test/MpqTests.java index 7a3e994..cd42e84 100644 --- a/src/test/java/systems/crigges/jmpq3test/MpqTests.java +++ b/src/test/java/systems/crigges/jmpq3test/MpqTests.java @@ -154,6 +154,14 @@ public void testInsertDeleteRegularFile() throws IOException { } } + @Test + public void testInsertByteArray() throws IOException { + File[] mpqs = getMpqs(); + for (File mpq : mpqs) { + insertByteArrayAndVerify(mpq, "Example.txt"); + } + } + @Test public void testInsertDeleteZeroLengthFile() throws IOException { File[] mpqs = getMpqs(); @@ -186,26 +194,47 @@ public void testIncompressibleFile() throws IOException { } } - private void insertAndVerify(File mpq, String filename) throws IOException { + private void insertByteArrayAndVerify(File mpq, String filename) throws IOException { JMpqEditor mpqEditor = new JMpqEditor(mpq, MPQOpenOption.FORCE_V0); try { File file = getFile(filename); String hashBefore = TestHelper.md5(mpq); byte[] bytes = Files.readAllBytes(file.toPath()); - mpqEditor.insertFile(filename, getFile(filename), false); + mpqEditor.insertByteArray(filename, Files.readAllBytes(getFile(filename).toPath())); mpqEditor.close(); - String hashAfter = TestHelper.md5(mpq); - // If this fails, the mpq is not changed by the insert file command and something went wrong - Assert.assertNotEquals(hashBefore, hashAfter); + mpqEditor = verifyMpq(mpq, filename, hashBefore, bytes); + Assert.assertFalse(mpqEditor.hasFile(filename)); + } catch (NonWritableChannelException ignored) { + } + } - mpqEditor = new JMpqEditor(mpq, MPQOpenOption.FORCE_V0); - Assert.assertTrue(mpqEditor.hasFile(filename)); - byte[] bytes2 = mpqEditor.extractFileAsBytes(filename); - Assert.assertEquals(bytes, bytes2); - mpqEditor.deleteFile(filename); + private JMpqEditor verifyMpq(File mpq, String filename, String hashBefore, byte[] bytes) throws IOException { + JMpqEditor mpqEditor; + String hashAfter = TestHelper.md5(mpq); + // If this fails, the mpq is not changed by the insert file command and something went wrong + Assert.assertNotEquals(hashBefore, hashAfter); + + mpqEditor = new JMpqEditor(mpq, MPQOpenOption.FORCE_V0); + Assert.assertTrue(mpqEditor.hasFile(filename)); + byte[] bytes2 = mpqEditor.extractFileAsBytes(filename); + Assert.assertEquals(bytes, bytes2); + mpqEditor.deleteFile(filename); + mpqEditor.close(); + mpqEditor = new JMpqEditor(mpq, MPQOpenOption.READ_ONLY, MPQOpenOption.FORCE_V0); + return mpqEditor; + } + + private void insertAndVerify(File mpq, String filename) throws IOException { + JMpqEditor mpqEditor = new JMpqEditor(mpq, MPQOpenOption.FORCE_V0); + try { + File file = getFile(filename); + String hashBefore = TestHelper.md5(mpq); + byte[] bytes = Files.readAllBytes(file.toPath()); + mpqEditor.insertFile(filename, getFile(filename), false); mpqEditor.close(); - mpqEditor = new JMpqEditor(mpq, MPQOpenOption.READ_ONLY, MPQOpenOption.FORCE_V0); + + mpqEditor = verifyMpq(mpq, filename, hashBefore, bytes); Assert.assertFalse(mpqEditor.hasFile(filename)); } catch (NonWritableChannelException ignored) { }