package jo.sm.ent.cmd; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import jo.sm.logic.StarMadeLogic; import jo.sm.logic.utils.ByteUtils; import jo.sm.logic.utils.FileUtils; public class CompareEntityFiles { private final File mModifiedDir; private final File mOriginalDir; private final Map<Byte, List<DiffReport>> mDiffs; public CompareEntityFiles() { mModifiedDir = new File(StarMadeLogic.getInstance().getBaseDir(), "/server-database"); mOriginalDir = new File(StarMadeLogic.getInstance().getBaseDir(), "/tmp"); mDiffs = new HashMap<>(); } public void run() throws IOException { for (File f1 : mModifiedDir.listFiles()) { if (!f1.getName().endsWith(".ent")) { continue; } File f2 = new File(mOriginalDir, f1.getName()); if (!f2.exists()) { continue; } byte[] data1 = FileUtils.readFile(f1.toString()); byte[] data2 = FileUtils.readFile(f2.toString()); System.out.println(f1.getName() + ":"); compare(data1, data2); } System.out.println(); System.out.println("Difference Report"); System.out.println(); for (Byte header : mDiffs.keySet()) { System.out.println("HEADER: " + Integer.toHexString(header)); List<DiffReport> reps = mDiffs.get(header); for (DiffReport rep : reps) { System.out.println("\t" + rep.mOriginalLen + "\t" + rep.mModifiedLen); } System.out.println(); } } private void compare(byte[] data1, byte[] data2) { int start; for (start = 0; start < data1.length; start++) { if (start >= data2.length) { System.out.println("Modified longer than original"); return; } if (data1[start] != data2[start]) { break; } } if (start == data1.length) { if (start == data2.length) { System.out.println("Files identical"); } else { System.out.println("Original longer than modified"); } return; } int end1 = -1; int end2 = -1; for (int maxReach = 1; maxReach < 256; maxReach++) { for (int altReach = 0; altReach < maxReach; altReach++) { if (equals(data1, start + maxReach, data2, start + altReach, 32)) { end1 = start + maxReach; end2 = start + altReach; break; } if (equals(data1, start + altReach, data2, start + maxReach, 32)) { end1 = start + altReach; end2 = start + maxReach; break; } } if (end1 >= 0) { break; } } if (end1 < 0) { System.out.println("Don't know where end is!"); return; } if (start >= 32) { System.out.println("Before:\n" + ByteUtils.toStringDump(data1, start - 32, 32)); } else { System.out.println("Before:\n" + ByteUtils.toStringDump(data1, 0, start)); } System.out.println("Modified:\n" + ByteUtils.toStringDump(data1, start, end1 - start)); System.out.println("Original:\n" + ByteUtils.toStringDump(data2, start, end2 - start)); System.out.println("After:\n" + ByteUtils.toStringDump(data1, end1, 32)); DiffReport r = new DiffReport(); r.mHeader = data1[start]; r.mModifiedLen = end1 - start; r.mOriginalLen = end2 - start; addReport(r); } private void addReport(DiffReport r) { List<DiffReport> diffs = mDiffs.get(r.mHeader); if (diffs == null) { diffs = new ArrayList<>(); mDiffs.put(r.mHeader, diffs); } diffs.add(r); } private boolean equals(byte[] data1, int o1, byte[] data2, int o2, int len) { if (o1 + len > data1.length) { return false; } if (o2 + len > data2.length) { return false; } for (int i = 0; i < len; i++) { if (data1[o1 + i] != data2[o2 + i]) { return false; } } return true; } /** * @param args */ public static void main(String[] args) { CompareEntityFiles app = new CompareEntityFiles(); try { app.run(); } catch (IOException e) { e.printStackTrace(); } } class DiffReport { byte mHeader; int mModifiedLen; int mOriginalLen; } }