Mercurial > jhg
comparison src/com/tmate/hgkit/console/Main.java @ 0:dbd663faec1f
Basic changelog parsing
| author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
|---|---|
| date | Fri, 17 Dec 2010 19:05:59 +0100 |
| parents | |
| children | 08db726a0fb7 |
comparison
equal
deleted
inserted
replaced
| -1:000000000000 | 0:dbd663faec1f |
|---|---|
| 1 package com.tmate.hgkit.console; | |
| 2 | |
| 3 import java.io.BufferedInputStream; | |
| 4 import java.io.DataInput; | |
| 5 import java.io.DataInputStream; | |
| 6 import java.io.File; | |
| 7 import java.io.FileInputStream; | |
| 8 import java.math.BigInteger; | |
| 9 import java.util.ArrayList; | |
| 10 import java.util.Collections; | |
| 11 import java.util.Iterator; | |
| 12 import java.util.LinkedList; | |
| 13 import java.util.List; | |
| 14 import java.util.zip.Deflater; | |
| 15 import java.util.zip.Inflater; | |
| 16 | |
| 17 import com.tmate.hgkit.ll.Changeset; | |
| 18 | |
| 19 /** | |
| 20 * | |
| 21 * @author artem | |
| 22 */ | |
| 23 public class Main { | |
| 24 | |
| 25 public static void main(String[] args) throws Exception { | |
| 26 Deflater zip1 = new Deflater(6, true); | |
| 27 final byte[] input = "Abstractions are valueless".getBytes(); | |
| 28 zip1.setInput(input); | |
| 29 zip1.finish(); | |
| 30 byte[] result1 = new byte[100]; | |
| 31 int resLen1 = zip1.deflate(result1); | |
| 32 System.out.printf("%3d:", resLen1); | |
| 33 for (int i = 0; i < resLen1; i++) { | |
| 34 System.out.printf("%02X", result1[i]); | |
| 35 } | |
| 36 System.out.println(); | |
| 37 // | |
| 38 Deflater zip2 = new Deflater(6, false); | |
| 39 zip2.setInput(input); | |
| 40 zip2.finish(); | |
| 41 byte[] result2 = new byte[100]; | |
| 42 int resLen2 = zip2.deflate(result2); | |
| 43 System.out.printf("%3d:", resLen2); | |
| 44 for (int i = 0; i < resLen2; i++) { | |
| 45 System.out.printf("%02X", result2[i]); | |
| 46 } | |
| 47 System.out.println(); | |
| 48 // | |
| 49 LinkedList<Changeset> changelog = new LinkedList<Changeset>(); | |
| 50 // | |
| 51 DataInputStream dis = new DataInputStream(new BufferedInputStream(new FileInputStream(new File("/temp/hg/hello/" + ".hg/store/00changelog.i")))); | |
| 52 DataInput di = dis; | |
| 53 dis.mark(10); | |
| 54 int versionField = di.readInt(); | |
| 55 dis.reset(); | |
| 56 final int INLINEDATA = 1 << 16; | |
| 57 | |
| 58 boolean inlineData = (versionField & INLINEDATA) != 0; | |
| 59 System.out.printf("%#8x, inline: %b\n", versionField, inlineData); | |
| 60 System.out.println("\tOffset\tFlags\tPacked\t Actual\tBase Rev Link Rev\tParent1\tParent2\tnodeid"); | |
| 61 int entryCount = 0; | |
| 62 while (dis.available() > 0) { | |
| 63 long l = di.readLong(); | |
| 64 long offset = l >>> 16; | |
| 65 int flags = (int) (l & 0X0FFFF); | |
| 66 int compressedLen = di.readInt(); | |
| 67 int actualLen = di.readInt(); | |
| 68 int baseRevision = di.readInt(); | |
| 69 int linkRevision = di.readInt(); | |
| 70 int parent1Revision = di.readInt(); | |
| 71 int parent2Revision = di.readInt(); | |
| 72 byte[] buf = new byte[32]; | |
| 73 di.readFully(buf, 12, 20); | |
| 74 dis.skip(12); | |
| 75 System.out.printf("%14d %6X %10d %10d %10d %10d %8d %8d %040x\n", offset, flags, compressedLen, actualLen, baseRevision, linkRevision, parent1Revision, parent2Revision, new BigInteger(buf)); | |
| 76 if (inlineData) { | |
| 77 byte[] data = new byte[compressedLen]; | |
| 78 di.readFully(data); | |
| 79 if (data[0] == 0x78 /* 'x' */) { | |
| 80 Inflater zlib = new Inflater(); | |
| 81 zlib.setInput(data, 0, compressedLen); | |
| 82 byte[] result = new byte[actualLen*2]; | |
| 83 int resultLen = zlib.inflate(result); | |
| 84 zlib.end(); | |
| 85 if (resultLen != actualLen) { | |
| 86 System.err.printf("Expected:%d, decomressed to:%d bytes\n", actualLen, resultLen); | |
| 87 } | |
| 88 String resultString; | |
| 89 if (baseRevision != entryCount) { | |
| 90 // this is a patch | |
| 91 byte[] baseRevContent = changelog.get(baseRevision).rawData; | |
| 92 LinkedList<PatchRecord> bins = new LinkedList<PatchRecord>(); | |
| 93 int p1, p2, len, patchElementIndex = 0; | |
| 94 do { | |
| 95 final int x = patchElementIndex; | |
| 96 p1 = (result[x] << 24) | (result[x+1] << 16) | (result[x+2] << 8) | result[x+3]; | |
| 97 p2 = (result[x+4] << 24) | (result[x+5] << 16) | (result[x+6] << 8) | result[x+7]; | |
| 98 len = (result[x+8] << 24) | (result[x+9] << 16) | (result[x+10] << 8) | result[x+11]; | |
| 99 System.out.printf("%4d %4d %4d\n", p1, p2, len); | |
| 100 patchElementIndex += 12 + len; | |
| 101 bins.add(new PatchRecord(p1, p2, len, result, x+12)); | |
| 102 } while (patchElementIndex < resultLen); | |
| 103 // | |
| 104 result = apply(baseRevContent, bins); | |
| 105 resultLen = result.length; | |
| 106 } | |
| 107 resultString = new String(result, 0, resultLen, "UTF-8"); | |
| 108 System.out.println(resultString); | |
| 109 entryCount++; | |
| 110 Changeset changeset = new Changeset(); | |
| 111 changeset.read(result, 0, resultLen); | |
| 112 changelog.add(changeset); | |
| 113 } // TODO else if uncompressed | |
| 114 } | |
| 115 } | |
| 116 dis.close(); | |
| 117 // | |
| 118 System.out.println("\n\n"); | |
| 119 System.out.println("====================>"); | |
| 120 for (Changeset cset : changelog) { | |
| 121 System.out.println(">"); | |
| 122 cset.dump(); | |
| 123 System.out.println("<"); | |
| 124 } | |
| 125 } | |
| 126 | |
| 127 | |
| 128 // mpatch.c : apply() | |
| 129 private static byte[] apply(byte[] baseRevisionContent, List<PatchRecord> patch) { | |
| 130 byte[] tempBuf = new byte[512]; // XXX | |
| 131 int last = 0, destIndex = 0; | |
| 132 for (PatchRecord pr : patch) { | |
| 133 System.arraycopy(baseRevisionContent, last, tempBuf, destIndex, pr.start-last); | |
| 134 destIndex += pr.start - last; | |
| 135 System.arraycopy(pr.data, 0, tempBuf, destIndex, pr.data.length); | |
| 136 destIndex += pr.data.length; | |
| 137 last = pr.end; | |
| 138 } | |
| 139 System.arraycopy(baseRevisionContent, last, tempBuf, destIndex, baseRevisionContent.length - last); | |
| 140 destIndex += baseRevisionContent.length - last; // total length | |
| 141 byte[] rv = new byte[destIndex]; | |
| 142 System.arraycopy(tempBuf, 0, rv, 0, destIndex); | |
| 143 return rv; | |
| 144 } | |
| 145 | |
| 146 static class PatchRecord { // copy of struct frag from mpatch.c | |
| 147 int start, end, len; | |
| 148 byte[] data; | |
| 149 | |
| 150 public PatchRecord(int p1, int p2, int len, byte[] src, int srcOffset) { | |
| 151 start = p1; | |
| 152 end = p2; | |
| 153 this.len = len; | |
| 154 data = new byte[len]; | |
| 155 System.arraycopy(src, srcOffset, data, 0, len); | |
| 156 } | |
| 157 } | |
| 158 } |
