| File: GitDataReader\GitRefTableReader.Diagnostics.cs | Web Access |
| Project: src\sourcelink\src\Microsoft.Build.Tasks.Git\Microsoft.Build.Tasks.Git.csproj (Microsoft.Build.Tasks.Git) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. #if DEBUG using System.Collections.Generic; using System.IO; namespace Microsoft.Build.Tasks.Git; // Utilities for diagnosing reader issues. internal sealed partial class GitRefTableReader { public record Block( char Type, long Position, int UnalignedSize, List<RefRecord> RefRecords, List<RefIndexRecord> IndexRecords, List<int> RestartOffsets) { public override string ToString() => $"Type: '{Type}', Position: {Position}, UnalignedSize: {UnalignedSize}, Records: {RefRecords.Count + IndexRecords.Count}, RestartOffsets: {RestartOffsets.Count}"; } /// <summary> /// Returns all ref-blocks and ref-index-blocks. /// </summary> public List<Block> GetBlocks() { var footer = ReadHeaderAndFooter(); var blocks = new List<Block>(); Position = footer.Header.Size; var blockStartPosition = 0L; while (Position < footer.Position) { var blockType = ReadByte(); var unalignedSize = ReadUInt24BE(); var refRecords = new List<RefRecord>(); var indexRecords = new List<RefIndexRecord>(); var restartOffsets = new List<int>(); if (blockType is not (BlockTypeRef or BlockTypeIndex)) { break; } var firstRecordPosition = Position; Position = blockStartPosition + unalignedSize - sizeof(ushort); var restartCount = ReadUInt16BE(); Position = firstRecordPosition; var endOfRecords = blockStartPosition + unalignedSize - restartCount * SizeOfUInt24 - sizeof(ushort); while (Position < endOfRecords) { if (blockType == BlockTypeRef) { refRecords.Add(ReadRefRecord(footer.Header, priorName: null)); } else { indexRecords.Add(ReadRefIndexRecord(priorName: null)); } } for (var i = 0; i < restartCount; i++) { restartOffsets.Add(ReadUInt24BE()); } // restart_count _ = ReadUInt16BE(); blocks.Add(new Block((char)blockType, blockStartPosition, unalignedSize, refRecords, indexRecords, restartOffsets)); // If the file is unaligned the next block starts at the end of the current block, // otherwise the current block is padded to block size and the next block starts after the padding. blockStartPosition = footer.Header.BlockSize > 0 ? blockStartPosition + footer.Header.BlockSize : Position; while (Position < blockStartPosition) { var padding = ReadByte(); if (padding != 0) { throw new InvalidDataException($"Unexpected non-zero padding byte: 0x{padding:X2}."); } } } return blocks; } } #endif