kitaev@213: /* kitaev@213: * Copyright (c) 2010-2011 TMate Software Ltd kitaev@213: * kitaev@213: * This program is free software; you can redistribute it and/or modify kitaev@213: * it under the terms of the GNU General Public License as published by kitaev@213: * the Free Software Foundation; version 2 of the License. kitaev@213: * kitaev@213: * This program is distributed in the hope that it will be useful, kitaev@213: * but WITHOUT ANY WARRANTY; without even the implied warranty of kitaev@213: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the kitaev@213: * GNU General Public License for more details. kitaev@213: * kitaev@213: * For information on how to redistribute this software under kitaev@213: * the terms of a license other than GNU General Public License kitaev@213: * contact TMate Software at support@hg4j.com kitaev@213: */ kitaev@213: package org.tmatesoft.hg.internal; kitaev@213: kitaev@213: import java.io.BufferedInputStream; kitaev@213: import java.io.DataInput; kitaev@213: import java.io.DataInputStream; kitaev@213: import java.io.File; kitaev@213: import java.io.FileInputStream; kitaev@213: import java.math.BigInteger; kitaev@213: import java.util.zip.Inflater; kitaev@213: kitaev@213: /** kitaev@213: * Utility to test/debug/troubleshoot kitaev@213: * kitaev@213: * @author Artem Tikhomirov kitaev@213: * @author TMate Software Ltd. kitaev@213: */ kitaev@213: public class RevlogDump { kitaev@213: kitaev@213: /** kitaev@213: * Takes 3 command line arguments - kitaev@213: * repository path, kitaev@213: * path to index file (i.e. store/data/hello.c.i) in the repository (relative) kitaev@213: * and "dumpData" whether to print actual content or just revlog headers kitaev@213: */ kitaev@213: public static void main(String[] args) throws Exception { kitaev@213: String repo = "/temp/hg/hello/.hg/"; kitaev@213: String filename = "store/00changelog.i"; kitaev@213: // String filename = "store/data/hello.c.i"; kitaev@213: // String filename = "store/data/docs/readme.i"; kitaev@213: boolean dumpData = true; kitaev@213: if (args.length > 1) { kitaev@213: repo = args[0]; kitaev@213: filename = args[1]; kitaev@213: dumpData = args.length > 2 ? "dumpData".equals(args[2]) : false; kitaev@213: } kitaev@213: // kitaev@213: DataInputStream dis = new DataInputStream(new BufferedInputStream(new FileInputStream(new File(repo + filename)))); kitaev@213: DataInput di = dis; kitaev@213: dis.mark(10); kitaev@213: int versionField = di.readInt(); kitaev@213: dis.reset(); kitaev@213: final int INLINEDATA = 1 << 16; kitaev@213: kitaev@213: boolean inlineData = (versionField & INLINEDATA) != 0; kitaev@213: System.out.printf("%#8x, inline: %b\n", versionField, inlineData); kitaev@213: System.out.println("Index Offset Flags Packed Actual Base Rev Link Rev Parent1 Parent2 nodeid"); kitaev@213: int entryCount = 0; kitaev@213: while (dis.available() > 0) { kitaev@213: long l = di.readLong(); kitaev@213: long offset = l >>> 16; kitaev@213: int flags = (int) (l & 0X0FFFF); kitaev@213: int compressedLen = di.readInt(); kitaev@213: int actualLen = di.readInt(); kitaev@213: int baseRevision = di.readInt(); kitaev@213: int linkRevision = di.readInt(); kitaev@213: int parent1Revision = di.readInt(); kitaev@213: int parent2Revision = di.readInt(); kitaev@213: byte[] buf = new byte[32]; kitaev@213: di.readFully(buf, 12, 20); kitaev@213: dis.skipBytes(12); kitaev@213: // CAN'T USE skip() here without extra precautions. E.g. I ran into situation when kitaev@213: // buffer was 8192 and BufferedInputStream was at position 8182 before attempt to skip(12). kitaev@213: // BIS silently skips available bytes and leaves me two extra bytes that ruin the rest of the code. kitaev@213: System.out.printf("%4d:%14d %6X %10d %10d %10d %10d %8d %8d %040x\n", entryCount, offset, flags, compressedLen, actualLen, baseRevision, linkRevision, parent1Revision, parent2Revision, new BigInteger(buf)); kitaev@213: if (inlineData) { kitaev@213: String resultString; kitaev@213: byte[] data = new byte[compressedLen]; kitaev@213: di.readFully(data); kitaev@213: if (data[0] == 0x78 /* 'x' */) { kitaev@213: Inflater zlib = new Inflater(); kitaev@213: zlib.setInput(data, 0, compressedLen); kitaev@213: byte[] result = new byte[actualLen*2]; kitaev@213: int resultLen = zlib.inflate(result); kitaev@213: zlib.end(); kitaev@213: resultString = new String(result, 0, resultLen, "UTF-8"); kitaev@213: } else if (data[0] == 0x75 /* 'u' */) { kitaev@213: resultString = new String(data, 1, data.length - 1, "UTF-8"); kitaev@213: } else { kitaev@213: resultString = new String(data); kitaev@213: } kitaev@213: if (dumpData) { kitaev@213: System.out.println(resultString); kitaev@213: } kitaev@213: } kitaev@213: entryCount++; kitaev@213: } kitaev@213: dis.close(); kitaev@213: // kitaev@213: } kitaev@213: }