private static Entry ReadEntryStream(RepositoryReader reader, string hash, Stream stream, Stream entryStream, long offset, ObjectType type, long length, Func <Stream> streamProvider) { switch (type) { case ObjectType.Commit: return(CommitReader.Read(reader, hash, entryStream)); case ObjectType.Tree: return(TreeReader.Read(reader, hash, entryStream, length)); case ObjectType.Blob: return(BlobReader.Read(reader, hash, entryStream, streamProvider)); case ObjectType.OfsDelta: var(undeltifiedData, undeltifiedLength, baseType) = OfsDeltaReader.Read( stream, offset, length, (off, len, pool) => ReadEntryData(reader, hash, stream, off, isNestedDelta: true), isNestedDelta: false); using (var undeltifiedStream = new MemoryStream(undeltifiedData)) { return(ReadEntryStream(reader, hash, stream, undeltifiedStream, 0L, baseType, undeltifiedLength, streamProvider)); } default: throw new NotImplementedException(); } }
private static (byte[] Data, ObjectType Type) ReadEntryData(RepositoryReader reader, string hash, Stream stream, long offset, bool isNestedDelta) { var(type, length) = ReadEntryInformation(stream, offset); byte[] result; switch (type) { case ObjectType.Commit: case ObjectType.Tree: using (var deflateStream = stream.DeflateForZlibData()) { result = isNestedDelta ? OfsDeltaReader._arrayPool.Rent((int)length) : new byte[length]; deflateStream.Read(result, 0, (int)length); } break; case ObjectType.Blob: result = isNestedDelta ? OfsDeltaReader._arrayPool.Rent((int)length) : new byte[length]; stream.Read(result, 0, (int)length); break; case ObjectType.OfsDelta: (result, _, type) = OfsDeltaReader.Read(stream, offset, length, (off, len, pool) => ReadEntryData(reader, hash, stream, off, isNestedDelta), isNestedDelta); break; default: throw new NotImplementedException(); } return(result, type); }