private const string UstarPrefixFormat = "{0}/{1}"; // "prefix/name" // Attempts to read all the fields of the next header. // Throws if end of stream is reached or if any data type conversion fails. // Returns true if all the attributes were read successfully, false otherwise. internal bool TryGetNextHeader(Stream archiveStream, bool copyData) { // The four supported formats have a header that fits in the default record size byte[] rented = ArrayPool <byte> .Shared.Rent(minimumLength : TarHelpers.RecordSize); Span <byte> buffer = rented.AsSpan(0, TarHelpers.RecordSize); // minimumLength means the array could've been larger buffer.Clear(); // Rented arrays aren't clean TarHelpers.ReadOrThrow(archiveStream, buffer); try { // Confirms if v7 or pax, or tentatively selects ustar if (!TryReadCommonAttributes(buffer)) { return(false); } // Confirms if gnu, or tentatively selects ustar ReadMagicAttribute(buffer); if (_format != TarFormat.V7) { // Confirms if gnu ReadVersionAttribute(buffer); // Fields that ustar, pax and gnu share identically ReadPosixAndGnuSharedAttributes(buffer); Debug.Assert(_format is TarFormat.Ustar or TarFormat.Pax or TarFormat.Gnu); if (_format == TarFormat.Ustar) { ReadUstarAttributes(buffer); } else if (_format == TarFormat.Gnu) { ReadGnuAttributes(buffer); } // In PAX, there is nothing to read in this section (empty space) } ProcessDataBlock(archiveStream, copyData); return(true); } finally { ArrayPool <byte> .Shared.Return(rented); } }