/// <summary> /// Releases unmanaged and - optionally - managed resources. /// </summary> /// <param name="disposing"> /// <c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only /// unmanaged resources. /// </param> private void Dispose(bool disposing) { _disposed = true; if (disposing) { _activeEntryStream?.Dispose(); _activeEntryStream = null; _stream = null; } }
/// <summary> /// Returns the next entry in the archive. /// </summary> /// <returns>The next entry in the archive or null when there are no more remaining entries.</returns> public TarEntryStream Next() { AssertNotDisposed(); if (_finished) { return(null); } CloseActiveEntryStream(); var header = TarHeader.Deserialize(_stream); if (header == null) { _finished = true; return(null); } // Compile a header with all additional annotations found. var headerBag = new TarHeaderBag(); var annotationStream = new TarEntryStream(new ReadOnlyTarHeader(header), _stream); // Keep adding the stream to the header bag while they are annotations. while (headerBag.Add(annotationStream)) { // Re-align the input stream to the 512 blocks and close the annotation stream. MoveToEndOfStream(annotationStream); annotationStream.Dispose(); header = TarHeader.Deserialize(_stream); // The annotation appears to be the last entry in the archive. Throwing an exception seems little crude // since the rest of the archive was just fine. if (header == null) { _finished = true; return(null); } // Create a new annotation stream for the next round of checks. annotationStream = new TarEntryStream(new ReadOnlyTarHeader(header), _stream); } // The annotation is not used at this point - skip it. annotationStream.Dispose(); _activeEntryStream = new TarEntryStream(headerBag.ApplyTo(header), _stream); return(_activeEntryStream); }
/// <summary> /// Moves the <see cref="_stream" /> to the end of the specified <paramref name="entryStream" />. /// </summary> /// <param name="entryStream">The entry stream.</param> private void MoveToEndOfStream(TarEntryStream entryStream) { // If previous stream isset, move past it's contents. if (entryStream == null) { return; } var length = entryStream.Header.Size ?? 0; var padding = TarBlock.RemainingBlockSize(length); var remaining = length - entryStream.PositionInternal + padding; // Skip remainder and re-align to 512 blocks for (; remaining > 0; remaining--) { _stream.ReadByte(); } }
/// <summary> /// Closes the active entry stream and moves <see cref="_stream" /> to the end of the entry. /// </summary> private void CloseActiveEntryStream() { MoveToEndOfStream(_activeEntryStream); _activeEntryStream?.Dispose(); _activeEntryStream = null; }