private void WriteEntry(GitPackIndexEntry last, GitPackIndexEntry entry) { Console.WriteLine( "\t{0} [{1}-{2}] (Len: {3})", BitConverter.ToString(last.Hash).Replace("-", "").ToLower(), last.Offset.ToString("X10"), entry == null ? "<EOF>" : entry.Offset.ToString("X10"), entry == null ? "<Rest Of File>" : FormatSize(entry.Offset - last.Offset)); }
private DatabaseObject GetObjectCore(long objectOffset, Stream packFile, bool recursing) { long size = 0; DatabaseObjectType type = DatabaseObjectType.Null; using (BinaryReader rdr = new BinaryReader(packFile, Encoding.UTF8, leaveOpen: true)) { packFile.Seek(objectOffset, SeekOrigin.Begin); // ==01234567== // | 1TTTSSSS | // ============ // T = Type // S = Size Start var sizeAndType = rdr.ReadVarInteger(3); type = InterpretType(sizeAndType.Item1); size = sizeAndType.Item2; long deltaOffset = -1; if (type == DatabaseObjectType.OffsetDelta) { // This isn't _quite_ a var-integer as ReadVarInteger supports byte read = rdr.ReadByte(); long offset = read & 0x7F; while ((read & 0x80) == 0x80) { offset += 1; offset <<= 7; read = rdr.ReadByte(); offset += (read & 0x7F); } deltaOffset = objectOffset - offset; } else if (type == DatabaseObjectType.HashDelta) { byte[] hash = rdr.ReadBytes(20); GitPackIndexEntry entry = Index.GetEntry(hash); deltaOffset = entry.Offset; } byte[] data = Compression.WrapStreamForDecompression(packFile) .ReadBytes(size); if (deltaOffset >= 0) { DatabaseObject source = GetObjectCore(deltaOffset, packFile, recursing: true); return(ConstructFromDelta(source, data)); } else { return(new DatabaseObject(type, data)); } } }
public virtual DatabaseObject GetObject(string hash) { // Look up the object in the index byte[] hashData = BitUtils.FromHexString(hash); GitPackIndexEntry entry = Index.GetEntry(hashData); if (entry == null) { return(null); } // Open the pack file and read the object out Stream packFile = FileSystem.Open(PackFileName, FileAccess.Read, create: false); return(GetObjectCore(entry.Offset, packFile, recursing: false)); }