public Stream GetObjectByPath(GitObjectId sha, string objectType, bool seekable) { sha.CreateUnicodeString(0, 1, this.objectPathBuffer.AsSpan(this.objectDirLength + 2, 4)); sha.CreateUnicodeString(1, 19, this.objectPathBuffer.AsSpan(this.objectDirLength + 2 + 4 + 2)); if (!FileHelpers.TryOpen(this.objectPathBuffer, out Stream compressedFile)) { return(null); } var file = GitObjectStream.Create(compressedFile, -1); file.ReadObjectTypeAndLength(objectType); if (string.CompareOrdinal(file.ObjectType, objectType) != 0) { throw new GitException(); } if (seekable) { return(new GitPackMemoryCacheStream(file)); } else { return(file); } }
public Stream GetObjectByPath(string path, string objectType) { string fullPath = Path.Combine(this.ObjectDirectory, path); if (!FileHelpers.TryOpen(fullPath, out Stream compressedFile)) { return(null); } var file = GitObjectStream.Create(compressedFile, -1); file.ReadObjectTypeAndLength(); if (string.CompareOrdinal(file.ObjectType, objectType) != 0) { throw new GitException(); } return(file); }
public static Stream GetObject(GitPack pack, Stream stream, long offset, string objectType, GitPackObjectType packObjectType) { if (pack == null) { throw new ArgumentNullException(nameof(pack)); } if (stream == 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); var baseObjectOffset = (long)(offset - baseObjectRelativeOffset); var deltaStream = GitObjectStream.Create(stream, decompressedSize); int baseObjectlength = ReadMbsInt(deltaStream); int targetLength = ReadMbsInt(deltaStream); var baseObjectStream = pack.GetObject(baseObjectOffset, objectType); return(new GitPackDeltafiedStream(baseObjectStream, deltaStream, targetLength)); } else if (type == GitPackObjectType.OBJ_REF_DELTA) { Span <byte> baseObjectId = stackalloc byte[20]; stream.ReadAll(baseObjectId); Stream baseObject = pack.Repository.GetObjectBySha(GitObjectId.Parse(baseObjectId), objectType, seekable: true); var deltaStream = GitObjectStream.Create(stream, decompressedSize); int baseObjectlength = ReadMbsInt(deltaStream); int targetLength = ReadMbsInt(deltaStream); return(new GitPackDeltafiedStream(baseObject, deltaStream, targetLength)); } // Tips for handling deltas: https://github.com/choffmeister/gitnet/blob/4d907623d5ce2d79a8875aee82e718c12a8aad0b/src/GitNet/GitPack.cs if (type != packObjectType) { throw new GitException(); } return(GitObjectStream.Create(stream, decompressedSize)); }