Пример #1
0
        /// <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;
            }
        }
Пример #2
0
        /// <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);
        }
Пример #3
0
        /// <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();
            }
        }
Пример #4
0
 /// <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;
 }