Пример #1
0
 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;
 }
Пример #2
0
        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);
        }
Пример #3
0
 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);
     }
 }
Пример #4
0
 private void GrowEntries()
 {
     var newEntries = new PackedObjectInfo[(int)_objectCount + _baseById.Count];
     Array.Copy(_entries, 0, newEntries, 0, _entryCount);
     _entries = newEntries;
 }
Пример #5
0
        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());
        }
Пример #6
0
        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);
        }