tikhomirov@0: package com.tmate.hgkit.console; tikhomirov@0: tikhomirov@0: import java.io.BufferedInputStream; tikhomirov@0: import java.io.DataInput; tikhomirov@0: import java.io.DataInputStream; tikhomirov@0: import java.io.File; tikhomirov@0: import java.io.FileInputStream; tikhomirov@0: import java.math.BigInteger; tikhomirov@0: import java.util.ArrayList; tikhomirov@0: import java.util.Collections; tikhomirov@0: import java.util.Iterator; tikhomirov@0: import java.util.LinkedList; tikhomirov@0: import java.util.List; tikhomirov@0: import java.util.zip.Deflater; tikhomirov@0: import java.util.zip.Inflater; tikhomirov@0: tikhomirov@0: import com.tmate.hgkit.ll.Changeset; tikhomirov@0: tikhomirov@0: /** tikhomirov@0: * tikhomirov@0: * @author artem tikhomirov@0: */ tikhomirov@0: public class Main { tikhomirov@0: tikhomirov@0: public static void main(String[] args) throws Exception { tikhomirov@0: Deflater zip1 = new Deflater(6, true); tikhomirov@0: final byte[] input = "Abstractions are valueless".getBytes(); tikhomirov@0: zip1.setInput(input); tikhomirov@0: zip1.finish(); tikhomirov@0: byte[] result1 = new byte[100]; tikhomirov@0: int resLen1 = zip1.deflate(result1); tikhomirov@0: System.out.printf("%3d:", resLen1); tikhomirov@0: for (int i = 0; i < resLen1; i++) { tikhomirov@0: System.out.printf("%02X", result1[i]); tikhomirov@0: } tikhomirov@0: System.out.println(); tikhomirov@0: // tikhomirov@0: Deflater zip2 = new Deflater(6, false); tikhomirov@0: zip2.setInput(input); tikhomirov@0: zip2.finish(); tikhomirov@0: byte[] result2 = new byte[100]; tikhomirov@0: int resLen2 = zip2.deflate(result2); tikhomirov@0: System.out.printf("%3d:", resLen2); tikhomirov@0: for (int i = 0; i < resLen2; i++) { tikhomirov@0: System.out.printf("%02X", result2[i]); tikhomirov@0: } tikhomirov@0: System.out.println(); tikhomirov@0: // tikhomirov@0: LinkedList changelog = new LinkedList(); tikhomirov@0: // tikhomirov@0: DataInputStream dis = new DataInputStream(new BufferedInputStream(new FileInputStream(new File("/temp/hg/hello/" + ".hg/store/00changelog.i")))); tikhomirov@0: DataInput di = dis; tikhomirov@0: dis.mark(10); tikhomirov@0: int versionField = di.readInt(); tikhomirov@0: dis.reset(); tikhomirov@0: final int INLINEDATA = 1 << 16; tikhomirov@0: tikhomirov@0: boolean inlineData = (versionField & INLINEDATA) != 0; tikhomirov@0: System.out.printf("%#8x, inline: %b\n", versionField, inlineData); tikhomirov@0: System.out.println("\tOffset\tFlags\tPacked\t Actual\tBase Rev Link Rev\tParent1\tParent2\tnodeid"); tikhomirov@0: int entryCount = 0; tikhomirov@0: while (dis.available() > 0) { tikhomirov@0: long l = di.readLong(); tikhomirov@0: long offset = l >>> 16; tikhomirov@0: int flags = (int) (l & 0X0FFFF); tikhomirov@0: int compressedLen = di.readInt(); tikhomirov@0: int actualLen = di.readInt(); tikhomirov@0: int baseRevision = di.readInt(); tikhomirov@0: int linkRevision = di.readInt(); tikhomirov@0: int parent1Revision = di.readInt(); tikhomirov@0: int parent2Revision = di.readInt(); tikhomirov@0: byte[] buf = new byte[32]; tikhomirov@0: di.readFully(buf, 12, 20); tikhomirov@0: dis.skip(12); tikhomirov@0: System.out.printf("%14d %6X %10d %10d %10d %10d %8d %8d %040x\n", offset, flags, compressedLen, actualLen, baseRevision, linkRevision, parent1Revision, parent2Revision, new BigInteger(buf)); tikhomirov@0: if (inlineData) { tikhomirov@0: byte[] data = new byte[compressedLen]; tikhomirov@0: di.readFully(data); tikhomirov@0: if (data[0] == 0x78 /* 'x' */) { tikhomirov@0: Inflater zlib = new Inflater(); tikhomirov@0: zlib.setInput(data, 0, compressedLen); tikhomirov@0: byte[] result = new byte[actualLen*2]; tikhomirov@0: int resultLen = zlib.inflate(result); tikhomirov@0: zlib.end(); tikhomirov@0: if (resultLen != actualLen) { tikhomirov@0: System.err.printf("Expected:%d, decomressed to:%d bytes\n", actualLen, resultLen); tikhomirov@0: } tikhomirov@0: String resultString; tikhomirov@0: if (baseRevision != entryCount) { tikhomirov@0: // this is a patch tikhomirov@0: byte[] baseRevContent = changelog.get(baseRevision).rawData; tikhomirov@0: LinkedList bins = new LinkedList(); tikhomirov@0: int p1, p2, len, patchElementIndex = 0; tikhomirov@0: do { tikhomirov@0: final int x = patchElementIndex; tikhomirov@0: p1 = (result[x] << 24) | (result[x+1] << 16) | (result[x+2] << 8) | result[x+3]; tikhomirov@0: p2 = (result[x+4] << 24) | (result[x+5] << 16) | (result[x+6] << 8) | result[x+7]; tikhomirov@0: len = (result[x+8] << 24) | (result[x+9] << 16) | (result[x+10] << 8) | result[x+11]; tikhomirov@0: System.out.printf("%4d %4d %4d\n", p1, p2, len); tikhomirov@0: patchElementIndex += 12 + len; tikhomirov@0: bins.add(new PatchRecord(p1, p2, len, result, x+12)); tikhomirov@0: } while (patchElementIndex < resultLen); tikhomirov@0: // tikhomirov@0: result = apply(baseRevContent, bins); tikhomirov@0: resultLen = result.length; tikhomirov@0: } tikhomirov@0: resultString = new String(result, 0, resultLen, "UTF-8"); tikhomirov@0: System.out.println(resultString); tikhomirov@0: entryCount++; tikhomirov@0: Changeset changeset = new Changeset(); tikhomirov@0: changeset.read(result, 0, resultLen); tikhomirov@0: changelog.add(changeset); tikhomirov@0: } // TODO else if uncompressed tikhomirov@0: } tikhomirov@0: } tikhomirov@0: dis.close(); tikhomirov@0: // tikhomirov@0: System.out.println("\n\n"); tikhomirov@0: System.out.println("====================>"); tikhomirov@0: for (Changeset cset : changelog) { tikhomirov@0: System.out.println(">"); tikhomirov@0: cset.dump(); tikhomirov@0: System.out.println("<"); tikhomirov@0: } tikhomirov@0: } tikhomirov@0: tikhomirov@0: tikhomirov@0: // mpatch.c : apply() tikhomirov@0: private static byte[] apply(byte[] baseRevisionContent, List patch) { tikhomirov@0: byte[] tempBuf = new byte[512]; // XXX tikhomirov@0: int last = 0, destIndex = 0; tikhomirov@0: for (PatchRecord pr : patch) { tikhomirov@0: System.arraycopy(baseRevisionContent, last, tempBuf, destIndex, pr.start-last); tikhomirov@0: destIndex += pr.start - last; tikhomirov@0: System.arraycopy(pr.data, 0, tempBuf, destIndex, pr.data.length); tikhomirov@0: destIndex += pr.data.length; tikhomirov@0: last = pr.end; tikhomirov@0: } tikhomirov@0: System.arraycopy(baseRevisionContent, last, tempBuf, destIndex, baseRevisionContent.length - last); tikhomirov@0: destIndex += baseRevisionContent.length - last; // total length tikhomirov@0: byte[] rv = new byte[destIndex]; tikhomirov@0: System.arraycopy(tempBuf, 0, rv, 0, destIndex); tikhomirov@0: return rv; tikhomirov@0: } tikhomirov@0: tikhomirov@0: static class PatchRecord { // copy of struct frag from mpatch.c tikhomirov@0: int start, end, len; tikhomirov@0: byte[] data; tikhomirov@0: tikhomirov@0: public PatchRecord(int p1, int p2, int len, byte[] src, int srcOffset) { tikhomirov@0: start = p1; tikhomirov@0: end = p2; tikhomirov@0: this.len = len; tikhomirov@0: data = new byte[len]; tikhomirov@0: System.arraycopy(src, srcOffset, data, 0, len); tikhomirov@0: } tikhomirov@0: } tikhomirov@0: }