private PackParser.UnresolvedDelta FirstChildOf(PackedObjectInfo oe) { PackParser.UnresolvedDelta a = Reverse(RemoveBaseById(oe)); PackParser.UnresolvedDelta b = Reverse(baseByPos.Remove(oe.GetOffset())); if (a == null) { return b; } if (b == null) { return a; } PackParser.UnresolvedDelta first = null; PackParser.UnresolvedDelta last = null; while (a != null || b != null) { PackParser.UnresolvedDelta curr; if (b == null || (a != null && a.position < b.position)) { curr = a; a = a.next; } else { curr = b; b = b.next; } if (last != null) { last.next = curr; } else { first = curr; } last = curr; curr.next = null; } return first; }
/// <exception cref="System.IO.IOException"></exception> private void ResolveDeltas(PackedObjectInfo oe, ProgressMonitor progress) { PackParser.UnresolvedDelta children = FirstChildOf(oe); if (children == null) { return; } PackParser.DeltaVisit visit = new PackParser.DeltaVisit(); visit.nextChild = children; PackParser.ObjectTypeAndSize info = OpenDatabase(oe, new PackParser.ObjectTypeAndSize ()); switch (info.type) { case Constants.OBJ_COMMIT: case Constants.OBJ_TREE: case Constants.OBJ_BLOB: case Constants.OBJ_TAG: { visit.data = InflateAndReturn(PackParser.Source.DATABASE, info.size); visit.id = oe; break; } default: { throw new IOException(MessageFormat.Format(JGitText.Get().unknownObjectType, Sharpen.Extensions.ValueOf (info.type))); } } if (!CheckCRC(oe.GetCRC())) { throw new IOException(MessageFormat.Format(JGitText.Get().corruptionDetectedReReadingAt , Sharpen.Extensions.ValueOf(oe.GetOffset()))); } ResolveDeltas(visit.Next(), info.type, info, progress); }
internal static bool CanStore(PackedObjectInfo oe) { // We are limited to 4 GB per pack as offset is 32 bit unsigned int. // return (long)(((ulong)oe.GetOffset()) >> 1) < int.MaxValue; }
/// <exception cref="System.IO.IOException"></exception> protected internal override PackParser.ObjectTypeAndSize SeekDatabase(PackedObjectInfo obj, PackParser.ObjectTypeAndSize info) { @out.Seek(obj.GetOffset()); crc.Reset(); return ReadObjectHeader(info); }
/// <exception cref="System.IO.IOException"></exception> private void FixThinPack(ProgressMonitor progress) { GrowEntries(); if (needBaseObjectIds) { baseObjectIds = new ObjectIdSubclassMap<ObjectId>(); } packDigest.Reset(); originalEOF = packOut.Length() - 20; Deflater def = new Deflater(Deflater.DEFAULT_COMPRESSION, false); IList<IndexPack.DeltaChain> missing = new AList<IndexPack.DeltaChain>(64); long end = originalEOF; foreach (IndexPack.DeltaChain baseId in baseById) { if (baseId.head == null) { continue; } if (needBaseObjectIds) { baseObjectIds.Add(baseId); } ObjectLoader ldr; try { ldr = readCurs.Open(baseId); } catch (MissingObjectException) { missing.AddItem(baseId); continue; } byte[] data = ldr.GetCachedBytes(int.MaxValue); int typeCode = ldr.GetType(); PackedObjectInfo oe; crc.Reset(); packOut.Seek(end); WriteWhole(def, typeCode, data); oe = new PackedObjectInfo(end, (int)crc.GetValue(), baseId); entries[entryCount++] = oe; end = packOut.GetFilePointer(); ResolveChildDeltas(oe.GetOffset(), typeCode, data, oe); if (progress.IsCancelled()) { throw new IOException(JGitText.Get().downloadCancelledDuringIndexing); } } def.Finish(); foreach (IndexPack.DeltaChain @base in missing) { if (@base.head != null) { throw new MissingObjectException(@base, "delta base"); } } if (end - originalEOF < 20) { // Ugly corner case; if what we appended on to complete deltas // doesn't completely cover the SHA-1 we have to truncate off // we need to shorten the file, otherwise we will include part // of the old footer as object content. packOut.SetLength(end); } FixHeaderFooter(packcsum, packDigest.Digest()); }
/// <exception cref="System.IO.IOException"></exception> private void ResolveDeltas(PackedObjectInfo oe) { int oldCRC = oe.GetCRC(); if (baseById.Get(oe) != null || baseByPos.ContainsKey(oe.GetOffset())) { ResolveDeltas(oe.GetOffset(), oldCRC, Constants.OBJ_BAD, null, oe); } }