/* * Copyright (c) 2005 (Mike) Maurice Kienenberger (mkienenb@gmail.com) * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ package org.gamenet.application.mm8leveleditor; import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.PrintStream; import java.io.RandomAccessFile; public class BinaryFileCompare { public static void compare(PrintStream out, byte data1[], byte data2[]) { ByteArrayInputStream inputStream1 = new ByteArrayInputStream(data1); ByteArrayInputStream inputStream2 = new ByteArrayInputStream(data1); int inputLength1 = data1.length; int inputLength2 = data2.length; int minSize = (inputLength1 > inputLength2) ? inputLength2 : inputLength1; for (long i = 0; i < minSize; ++i) { int firstData = inputStream1.read(); int secondData = inputStream2.read(); if (firstData != secondData) { out.println(String.valueOf(i) + ": " + toDisplayString(inputStream1, i) + " - " + "data1"); out.println(String.valueOf(i) + ": " + toDisplayString(inputStream2, i) + " - " + "data2"); out.println(); } } if (inputLength1 >= minSize) { for (long i = minSize; i < inputLength1; ++i) { int firstData = inputStream1.read(); out.println(String.valueOf(i) + ": " + toDisplayString(inputStream1, i) + " - " + "data1"); out.println(String.valueOf(i) + ": null" + " - " + "data2"); out.println(); } } if (inputLength2 >= minSize) { for (long i = minSize; i < inputLength2; ++i) { int secondData = inputStream2.read(); out.println(String.valueOf(i) + ": null" + " - " + "data1"); out.println(String.valueOf(i) + ": " + toDisplayString(inputStream2, i) + " - " + "data2"); out.println(); } } } public static void main(String[] strings) throws IOException { File firstFile = new File(strings[0]); File secondFile = new File(strings[1]); System.out.println("Comparing " + firstFile + " and " + secondFile); System.out.println(); RandomAccessFile firstRandomAccessFile = null; try { firstRandomAccessFile = new RandomAccessFile(firstFile, "r"); } catch (FileNotFoundException e) { e.printStackTrace(); System.err.println("File Not Found: " + firstFile.getName()); } RandomAccessFile secondRandomAccessFile = null; try { secondRandomAccessFile = new RandomAccessFile(secondFile, "r"); } catch (FileNotFoundException e) { e.printStackTrace(); System.err.println("File Not Found: " + secondFile.getName()); } long firstRandomAccessFileLength = firstRandomAccessFile.length(); long secondRandomAccessFileLength = secondRandomAccessFile.length(); long minSize = (firstRandomAccessFileLength > secondRandomAccessFileLength) ? secondRandomAccessFileLength : firstRandomAccessFileLength; for (long i = 0; i < minSize; ++i) { int firstData = firstRandomAccessFile.read(); int secondData = secondRandomAccessFile.read(); if (firstData != secondData) { System.err.println(String.valueOf(i) + ": " + toDisplayString(firstRandomAccessFile, i) + " - " + firstFile.getName()); System.err.println(String.valueOf(i) + ": " + toDisplayString(secondRandomAccessFile, i) + " - " + secondFile.getName()); System.err.println(); } } if (firstRandomAccessFileLength >= minSize) { for (long i = minSize; i < firstRandomAccessFileLength; ++i) { int firstData = firstRandomAccessFile.read(); System.err.println(String.valueOf(i) + ": " + toDisplayString(firstRandomAccessFile, i) + " - " + firstFile.getName()); System.err.println(String.valueOf(i) + ": null" + " - " + secondFile.getName()); System.err.println(); } } if (secondRandomAccessFileLength >= minSize) { for (long i = minSize; i < secondRandomAccessFileLength; ++i) { int secondData = secondRandomAccessFile.read(); System.err.println(String.valueOf(i) + ": null" + " - " + firstFile.getName()); System.err.println(String.valueOf(i) + ": " + toDisplayString(secondRandomAccessFile, i) + " - " + secondFile.getName()); System.err.println(); } } } static public String toDisplayString(RandomAccessFile aFile, long position) { byte byteArray[] = new byte[4]; int index = 0; int bytesRead = 0; try { long originalPos = aFile.getFilePointer(); aFile.seek(position); bytesRead = aFile.read(byteArray, 0, 4); if (-1 == bytesRead) throw new IOException("Unexpected end of file."); aFile.seek(originalPos); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return toDisplayString(byteArray, bytesRead); } static public String toDisplayString(InputStream inputStream, long position) { byte byteArray[] = new byte[4]; int bytesRead = 0; try { inputStream.mark(4); bytesRead = inputStream.read(byteArray, 0, 4); if (4 != bytesRead) throw new IOException("Unexpected end of stream."); inputStream.reset(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return toDisplayString(byteArray, bytesRead); } static public String toDisplayString(byte byteArray[], int bytesRead) { int index = 0; // Byte values byte aByte = byteArray[index]; int anUnsignedInt1 = aByte >= 0 ? aByte : (256 + ((int)aByte)); String byteString = Integer.toHexString(anUnsignedInt1); while (byteString.length() < 2) byteString = "0" + byteString; String unsignedIntString = String.valueOf(anUnsignedInt1); while (unsignedIntString.length() < 3) unsignedIntString = " " + unsignedIntString; int aSignedInt1 = aByte; String signedIntString = String.valueOf(aSignedInt1); while (signedIntString.length() < 4) signedIntString = " " + signedIntString; String charString = (new Character((char)anUnsignedInt1)).toString(); if (0 == anUnsignedInt1) charString = ""; // 0 messes up cut-and-paste if ((index + 1) < bytesRead) { // short values byte aByte2 = byteArray[index + 1]; int anInt2 = aByte2 >= 0 ? aByte2 : (256 + ((int)aByte2)); int shortInt = anUnsignedInt1 + (anInt2 << 8); String shortByteString = Integer.toHexString(shortInt); while (shortByteString.length() < 4) shortByteString = "0" + shortByteString; String unsignedShortIntString = String.valueOf(shortInt); while (unsignedShortIntString.length() < 5) unsignedShortIntString = " " + unsignedShortIntString; int aSignedShortInt = shortInt <= Short.MAX_VALUE ? shortInt : shortInt - ((Short.MAX_VALUE * 2) + 2); String signedShortIntString = String.valueOf(aSignedShortInt); while (signedShortIntString.length() < 6) signedShortIntString = " " + signedShortIntString; if ((index + 3) < bytesRead) { // short values byte aByte3 = byteArray[index + 2]; byte aByte4 = byteArray[index + 3]; int anInt3 = aByte3 >= 0 ? aByte3 : (256 + ((int)aByte3)); int anInt4 = aByte4 >= 0 ? aByte4 : (256 + ((int)aByte4)); long longInt = ((long)shortInt) + (((long)anInt3) << 16) + (((long)anInt4) << 24); String longByteString = Long.toHexString(longInt); // truncate leading FFs until we only have 8 bytes in the case of a negative // if (longByteString.length() > 8) longByteString = longByteString.substring(longByteString.length() - 8); while (longByteString.length() < 8) longByteString = "0" + longByteString; String unsignedLongIntString = String.valueOf(longInt); while (unsignedLongIntString.length() < 11) unsignedLongIntString = " " + unsignedLongIntString; long aSignedLongInt = longInt <= Integer.MAX_VALUE ? longInt : longInt - ((((long)Integer.MAX_VALUE) * 2L) + 2L); String signedLongIntString = String.valueOf(aSignedLongInt); while (signedLongIntString.length() < 11) signedLongIntString = " " + signedLongIntString; return "0x" + byteString + "," + unsignedIntString + "," + signedIntString + " " + "0x" + shortByteString + "," + unsignedShortIntString + "," + signedShortIntString + " " + "0x" + longByteString + "," + unsignedLongIntString + "," + signedLongIntString + " [" + charString + "]"; } return "0x" + byteString + "," + unsignedIntString + "," + signedIntString + "," + charString + " " + "0x" + shortByteString + "," + unsignedShortIntString + "," + signedShortIntString + " [" + charString + "]"; } return "0x" + byteString + "," + unsignedIntString + "," + signedIntString + " [" + charString + "]"; } }