public static bool CanStore(PackedObjectInfo objectInfo) { // We are limited to 4 GB per pack as offset is 32 bit unsigned int. // return objectInfo.Offset.UnsignedRightShift(1) < int.MaxValue; }
private void ResolveDeltas(long pos, int oldCrc, int type, byte[] data, PackedObjectInfo oe) { _crc.Reset(); Position(pos); int c = ReadFromFile(); int typecode = (c >> 4) & 7; long sz = c & 15; int shift = 4; while ((c & 0x80) != 0) { c = ReadFromFile(); sz += (c & 0x7f) << shift; shift += 7; } switch (typecode) { case Constants.OBJ_COMMIT: case Constants.OBJ_TREE: case Constants.OBJ_BLOB: case Constants.OBJ_TAG: type = typecode; data = InflateFromFile((int)sz); break; case Constants.OBJ_OFS_DELTA: c = ReadFromFile() & 0xff; while ((c & 128) != 0) { c = ReadFromFile() & 0xff; } data = BinaryDelta.Apply(data, InflateFromFile((int)sz)); break; case Constants.OBJ_REF_DELTA: _crc.Update(_buffer, FillFromFile(20), 20); Use(20); data = BinaryDelta.Apply(data, InflateFromFile((int)sz)); break; default: throw new IOException("Unknown object type " + typecode + "."); } var crc32 = (int)_crc.Value; if (oldCrc != crc32) { throw new IOException("Corruption detected re-reading at " + pos); } if (oe == null) { _objectDigest.Update(Constants.encodedTypeString(type)); _objectDigest.Update((byte)' '); _objectDigest.Update(Constants.encodeASCII(data.Length)); _objectDigest.Update(0); _objectDigest.Update(data); _tempObjectId.FromRaw(_objectDigest.Digest(), 0); VerifySafeObject(_tempObjectId, type, data); oe = new PackedObjectInfo(pos, crc32, _tempObjectId); _entries[_entryCount++] = oe; } ResolveChildDeltas(pos, type, data, oe); }
private void ResolveDeltas(PackedObjectInfo objectInfo) { if (_baseById.Get(objectInfo) != null || _baseByPos.ContainsKey(objectInfo.Offset)) { int oldCrc = objectInfo.CRC; ResolveDeltas(objectInfo.Offset, oldCrc, Constants.OBJ_BAD, null, objectInfo); } }
private void GrowEntries() { var newEntries = new PackedObjectInfo[(int)_objectCount + _baseById.Count]; Array.Copy(_entries, 0, newEntries, 0, _entryCount); _entries = newEntries; }
private void FixThinPack(ProgressMonitor progress) { GrowEntries(); _packDigest.Reset(); _originalEof = _packOut.Length - 20; var def = new Deflater(Deflater.DEFAULT_COMPRESSION, false); var missing = new List<DeltaChain>(64); long end = _originalEof; foreach (DeltaChain baseId in _baseById) { if (baseId.Head == null) { missing.Add(baseId); continue; } ObjectLoader ldr = _repo.OpenObject(_windowCursor, baseId); if (ldr == null) { missing.Add(baseId); continue; } byte[] data = ldr.CachedBytes; int typeCode = ldr.Type; _crc.Reset(); _packOut.Seek(end, SeekOrigin.Begin); WriteWhole(def, typeCode, data); var oe = new PackedObjectInfo(end, (int)_crc.Value, baseId); _entries[_entryCount++] = oe; end = _packOut.Position; ResolveChildDeltas(oe.Offset, typeCode, data, oe); if (progress.IsCancelled) { throw new IOException("Download cancelled during indexing"); } } def.Finish(); foreach (DeltaChain baseDeltaChain in missing) { if (baseDeltaChain.Head != null) { throw new MissingObjectException(baseDeltaChain, "delta base"); } } FixHeaderFooter(_packcsum, _packDigest.Digest()); }
private void Whole(int type, long pos, long sz) { byte[] data = InflateFromInput((int)sz); _objectDigest.Update(Constants.encodedTypeString(type)); _objectDigest.Update((byte)' '); _objectDigest.Update(Constants.encodeASCII(sz)); _objectDigest.Update(0); _objectDigest.Update(data); _tempObjectId.FromRaw(_objectDigest.Digest(), 0); VerifySafeObject(_tempObjectId, type, data); var crc32 = (int)_crc.Value; _entries[_entryCount++] = new PackedObjectInfo(pos, crc32, _tempObjectId); }