예제 #1
0
        public override Stream Add(long offset, Stream stream)
        {
            var cacheStream = new GitPackMemoryCacheStream(stream);

            this.cache.Add(offset, cacheStream);
            return(new GitPackMemoryCacheViewStream(cacheStream));
        }
예제 #2
0
 public GitPackMemoryCacheViewStream(GitPackMemoryCacheStream baseStream)
 {
     this.baseStream = baseStream ?? throw new ArgumentNullException(nameof(baseStream));
 }
예제 #3
0
        public static Stream GetObject(GitPack pack, Stream stream, long offset, string objectType, GitPackObjectType packObjectType)
        {
            if (pack is null)
            {
                throw new ArgumentNullException(nameof(pack));
            }

            if (stream is null)
            {
                throw new ArgumentNullException(nameof(stream));
            }

            // Read the signature
#if DEBUG
            stream.Seek(0, SeekOrigin.Begin);
            Span <byte> buffer = stackalloc byte[12];
            stream.ReadAll(buffer);

            Debug.Assert(buffer.Slice(0, 4).SequenceEqual(Signature));

            var versionNumber = BinaryPrimitives.ReadInt32BigEndian(buffer.Slice(4, 4));
            Debug.Assert(versionNumber == 2);

            var numberOfObjects = BinaryPrimitives.ReadInt32BigEndian(buffer.Slice(8, 4));
#endif

            stream.Seek(offset, SeekOrigin.Begin);

            var(type, decompressedSize) = ReadObjectHeader(stream);

            if (type == GitPackObjectType.OBJ_OFS_DELTA)
            {
                var  baseObjectRelativeOffset = ReadVariableLengthInteger(stream);
                long baseObjectOffset         = offset - baseObjectRelativeOffset;

                var deltaStream      = new ZLibStream(stream, decompressedSize);
                var baseObjectStream = pack.GetObject(baseObjectOffset, objectType);

                return(new GitPackDeltafiedStream(baseObjectStream, deltaStream));
            }
            else if (type == GitPackObjectType.OBJ_REF_DELTA)
            {
                Span <byte> baseObjectId = stackalloc byte[20];
                stream.ReadAll(baseObjectId);

                Stream baseObject         = pack.GetObjectFromRepository(GitObjectId.Parse(baseObjectId), objectType) !;
                var    seekableBaseObject = new GitPackMemoryCacheStream(baseObject);

                var deltaStream = new ZLibStream(stream, decompressedSize);

                return(new GitPackDeltafiedStream(seekableBaseObject, deltaStream));
            }

            // Tips for handling deltas: https://github.com/choffmeister/gitnet/blob/4d907623d5ce2d79a8875aee82e718c12a8aad0b/src/GitNet/GitPack.cs
            if (type != packObjectType)
            {
                throw new GitException($"An object of type {objectType} could not be located at offset {offset}.")
                      {
                          ErrorCode = GitException.ErrorCodes.ObjectNotFound
                      };
            }

            return(new ZLibStream(stream, decompressedSize));
        }