// Copyright (c) 2026 Timofey Solomko // Licensed under MIT License // // See LICENSE for license information import Foundation import BitByteData // While it is tempting to make the parser conform to `IteratorProtocol` and `Sequence` protocols, it is in fact // impossible to do so, since `TarHeader.init(_)` is throwing and `IteratorProtocol.next()` cannot be throwing. struct TarParser { enum ParsingResult { case truncated case eofMarker case finished case specialEntry(TarHeader.SpecialEntryType) case entryInfo(TarEntryInfo, Int, TarContainer.Format) } private let reader: LittleEndianByteReader private var lastGlobalExtendedHeader: TarExtendedHeader? private var lastLocalExtendedHeader: TarExtendedHeader? private var longLinkName: String? private var longName: String? init(_ data: Data) { self.reader = LittleEndianByteReader(data: data) self.lastGlobalExtendedHeader = nil self.lastLocalExtendedHeader = nil self.longLinkName = nil self.longName = nil } mutating func next() throws -> ParsingResult { if reader.isFinished { return .finished } else if reader.bytesLeft >= 1024 && reader.data[reader.offset..= 0) let dataStartIndex = header.blockStartIndex + 512 if case .special(let specialEntryType) = header.type { switch specialEntryType { case .globalExtendedHeader: let dataEndIndex = dataStartIndex + header.size lastGlobalExtendedHeader = try TarExtendedHeader(reader.data[dataStartIndex..