mirror of
https://github.com/adamhathcock/sharpcompress.git
synced 2026-09-24 16:05:27 +00:00
First pass of trying tar
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using SharpCompress.Common;
|
||||
using SharpCompress.Readers;
|
||||
@@ -19,7 +20,7 @@ namespace SharpCompress.Archives
|
||||
|
||||
private bool disposed;
|
||||
|
||||
internal AbstractArchive(ArchiveType type, FileInfo fileInfo, ReaderOptions readerOptions)
|
||||
internal AbstractArchive(ArchiveType type, FileInfo fileInfo, ReaderOptions readerOptions, CancellationToken cancellationToken)
|
||||
{
|
||||
Type = type;
|
||||
if (!fileInfo.Exists)
|
||||
@@ -28,19 +29,19 @@ namespace SharpCompress.Archives
|
||||
}
|
||||
ReaderOptions = readerOptions;
|
||||
readerOptions.LeaveStreamOpen = false;
|
||||
lazyVolumes = new LazyReadOnlyCollection<TVolume>(LoadVolumes(fileInfo));
|
||||
lazyEntries = new LazyReadOnlyCollection<TEntry>(LoadEntries(Volumes));
|
||||
lazyVolumes = new LazyReadOnlyCollection<TVolume>(LoadVolumes(fileInfo, cancellationToken));
|
||||
lazyEntries = new LazyReadOnlyCollection<TEntry>(LoadEntries(Volumes, cancellationToken));
|
||||
}
|
||||
|
||||
|
||||
protected abstract IAsyncEnumerable<TVolume> LoadVolumes(FileInfo file);
|
||||
protected abstract IAsyncEnumerable<TVolume> LoadVolumes(FileInfo file, CancellationToken cancellationToken);
|
||||
|
||||
internal AbstractArchive(ArchiveType type, IAsyncEnumerable<Stream> streams, ReaderOptions readerOptions)
|
||||
internal AbstractArchive(ArchiveType type, IAsyncEnumerable<Stream> streams, ReaderOptions readerOptions, CancellationToken cancellationToken)
|
||||
{
|
||||
Type = type;
|
||||
ReaderOptions = readerOptions;
|
||||
lazyVolumes = new LazyReadOnlyCollection<TVolume>(LoadVolumes(streams.Select(CheckStreams)));
|
||||
lazyEntries = new LazyReadOnlyCollection<TEntry>(LoadEntries(Volumes));
|
||||
lazyVolumes = new LazyReadOnlyCollection<TVolume>(LoadVolumes(streams.Select(CheckStreams), cancellationToken));
|
||||
lazyEntries = new LazyReadOnlyCollection<TEntry>(LoadEntries(Volumes, cancellationToken));
|
||||
}
|
||||
|
||||
internal AbstractArchive(ArchiveType type)
|
||||
@@ -89,8 +90,8 @@ namespace SharpCompress.Archives
|
||||
return await Entries.AggregateAsync(0L, (total, cf) => total + cf.Size);
|
||||
}
|
||||
|
||||
protected abstract IAsyncEnumerable<TVolume> LoadVolumes(IAsyncEnumerable<Stream> streams);
|
||||
protected abstract IAsyncEnumerable<TEntry> LoadEntries(IAsyncEnumerable<TVolume> volumes);
|
||||
protected abstract IAsyncEnumerable<TVolume> LoadVolumes(IAsyncEnumerable<Stream> streams, CancellationToken cancellationToken);
|
||||
protected abstract IAsyncEnumerable<TEntry> LoadEntries(IAsyncEnumerable<TVolume> volumes, CancellationToken cancellationToken);
|
||||
|
||||
IAsyncEnumerable<IArchiveEntry> IArchive.Entries => Entries.Select(x => (IArchiveEntry)x);
|
||||
|
||||
|
||||
@@ -42,13 +42,15 @@ namespace SharpCompress.Archives
|
||||
{
|
||||
}
|
||||
|
||||
internal AbstractWritableArchive(ArchiveType type, Stream stream, ReaderOptions readerFactoryOptions)
|
||||
: base(type, stream.AsAsyncEnumerable(), readerFactoryOptions)
|
||||
internal AbstractWritableArchive(ArchiveType type, Stream stream, ReaderOptions readerFactoryOptions,
|
||||
CancellationToken cancellationToken)
|
||||
: base(type, stream.AsAsyncEnumerable(), readerFactoryOptions, cancellationToken)
|
||||
{
|
||||
}
|
||||
|
||||
internal AbstractWritableArchive(ArchiveType type, FileInfo fileInfo, ReaderOptions readerFactoryOptions)
|
||||
: base(type, fileInfo, readerFactoryOptions)
|
||||
internal AbstractWritableArchive(ArchiveType type, FileInfo fileInfo, ReaderOptions readerFactoryOptions,
|
||||
CancellationToken cancellationToken)
|
||||
: base(type, fileInfo, readerFactoryOptions, cancellationToken)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ using System.Threading.Tasks;
|
||||
using SharpCompress.Archives.GZip;
|
||||
//using SharpCompress.Archives.Rar;
|
||||
//using SharpCompress.Archives.SevenZip;
|
||||
//using SharpCompress.Archives.Tar;
|
||||
using SharpCompress.Archives.Tar;
|
||||
using SharpCompress.Archives.Zip;
|
||||
using SharpCompress.Common;
|
||||
using SharpCompress.Readers;
|
||||
@@ -51,12 +51,12 @@ namespace SharpCompress.Archives
|
||||
stream.Seek(0, SeekOrigin.Begin);
|
||||
return RarArchive.Open(stream, readerOptions);
|
||||
}
|
||||
stream.Seek(0, SeekOrigin.Begin);
|
||||
if (TarArchive.IsTarFile(stream))
|
||||
stream.Seek(0, SeekOrigin.Begin); */
|
||||
if (await TarArchive.IsTarFileAsync(stream, cancellationToken))
|
||||
{
|
||||
stream.Seek(0, SeekOrigin.Begin);
|
||||
return TarArchive.Open(stream, readerOptions);
|
||||
} */
|
||||
}
|
||||
throw new InvalidOperationException("Cannot determine compressed stream type. Supported Archive Formats: Zip, GZip, Tar, Rar, 7Zip, LZip");
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Buffers;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using SharpCompress.Common;
|
||||
@@ -32,10 +33,11 @@ namespace SharpCompress.Archives.GZip
|
||||
/// </summary>
|
||||
/// <param name="fileInfo"></param>
|
||||
/// <param name="readerOptions"></param>
|
||||
public static GZipArchive Open(FileInfo fileInfo, ReaderOptions? readerOptions = null)
|
||||
public static GZipArchive Open(FileInfo fileInfo, ReaderOptions? readerOptions = null,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
fileInfo.CheckNotNull(nameof(fileInfo));
|
||||
return new GZipArchive(fileInfo, readerOptions ?? new ReaderOptions());
|
||||
return new GZipArchive(fileInfo, readerOptions ?? new ReaderOptions(), cancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -43,10 +45,11 @@ namespace SharpCompress.Archives.GZip
|
||||
/// </summary>
|
||||
/// <param name="stream"></param>
|
||||
/// <param name="readerOptions"></param>
|
||||
public static GZipArchive Open(Stream stream, ReaderOptions? readerOptions = null)
|
||||
public static GZipArchive Open(Stream stream, ReaderOptions? readerOptions = null,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
stream.CheckNotNull(nameof(stream));
|
||||
return new GZipArchive(stream, readerOptions ?? new ReaderOptions());
|
||||
return new GZipArchive(stream, readerOptions ?? new ReaderOptions(), cancellationToken);
|
||||
}
|
||||
|
||||
public static GZipArchive Create()
|
||||
@@ -59,12 +62,14 @@ namespace SharpCompress.Archives.GZip
|
||||
/// </summary>
|
||||
/// <param name="fileInfo"></param>
|
||||
/// <param name="options"></param>
|
||||
internal GZipArchive(FileInfo fileInfo, ReaderOptions options)
|
||||
: base(ArchiveType.GZip, fileInfo, options)
|
||||
internal GZipArchive(FileInfo fileInfo, ReaderOptions options,
|
||||
CancellationToken cancellationToken)
|
||||
: base(ArchiveType.GZip, fileInfo, options, cancellationToken)
|
||||
{
|
||||
}
|
||||
|
||||
protected override IAsyncEnumerable<GZipVolume> LoadVolumes(FileInfo file)
|
||||
protected override IAsyncEnumerable<GZipVolume> LoadVolumes(FileInfo file,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
return new GZipVolume(file, ReaderOptions).AsAsyncEnumerable();
|
||||
}
|
||||
@@ -102,7 +107,7 @@ namespace SharpCompress.Archives.GZip
|
||||
using var header = MemoryPool<byte>.Shared.Rent(10);
|
||||
|
||||
// workitem 8501: handle edge case (decompress empty stream)
|
||||
if (!await stream.ReadFullyAsync(header.Memory, cancellationToken))
|
||||
if (!await stream.ReadFullyAsync(header.Memory.Slice(0, 10), cancellationToken))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -120,8 +125,9 @@ namespace SharpCompress.Archives.GZip
|
||||
/// </summary>
|
||||
/// <param name="stream"></param>
|
||||
/// <param name="options"></param>
|
||||
internal GZipArchive(Stream stream, ReaderOptions options)
|
||||
: base(ArchiveType.GZip, stream, options)
|
||||
internal GZipArchive(Stream stream, ReaderOptions options,
|
||||
CancellationToken cancellationToken)
|
||||
: base(ArchiveType.GZip, stream, options, cancellationToken)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -160,15 +166,19 @@ namespace SharpCompress.Archives.GZip
|
||||
}
|
||||
}
|
||||
|
||||
protected override async IAsyncEnumerable<GZipVolume> LoadVolumes(IAsyncEnumerable<Stream> streams)
|
||||
protected override async IAsyncEnumerable<GZipVolume> LoadVolumes(IAsyncEnumerable<Stream> streams,
|
||||
[EnumeratorCancellation]CancellationToken cancellationToken)
|
||||
{
|
||||
yield return new GZipVolume(await streams.FirstAsync(), ReaderOptions);
|
||||
yield return new GZipVolume(await streams.FirstAsync(cancellationToken: cancellationToken), ReaderOptions);
|
||||
}
|
||||
|
||||
protected override async IAsyncEnumerable<GZipArchiveEntry> LoadEntries(IAsyncEnumerable<GZipVolume> volumes)
|
||||
protected override async IAsyncEnumerable<GZipArchiveEntry> LoadEntries(IAsyncEnumerable<GZipVolume> volumes,
|
||||
[EnumeratorCancellation]CancellationToken cancellationToken)
|
||||
{
|
||||
Stream stream = (await volumes.SingleAsync()).Stream;
|
||||
yield return new GZipArchiveEntry(this, new GZipFilePart(stream, ReaderOptions.ArchiveEncoding));
|
||||
Stream stream = (await volumes.SingleAsync(cancellationToken: cancellationToken)).Stream;
|
||||
var part = new GZipFilePart(ReaderOptions.ArchiveEncoding);
|
||||
await part.Initialize(stream, cancellationToken);
|
||||
yield return new GZipArchiveEntry(this, part);
|
||||
}
|
||||
|
||||
protected override async ValueTask<IReader> CreateReaderForSolidExtraction()
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using SharpCompress.Common;
|
||||
@@ -33,10 +34,11 @@ namespace SharpCompress.Archives.Tar
|
||||
/// </summary>
|
||||
/// <param name="fileInfo"></param>
|
||||
/// <param name="readerOptions"></param>
|
||||
public static TarArchive Open(FileInfo fileInfo, ReaderOptions? readerOptions = null)
|
||||
public static TarArchive Open(FileInfo fileInfo, ReaderOptions? readerOptions = null,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
fileInfo.CheckNotNull(nameof(fileInfo));
|
||||
return new TarArchive(fileInfo, readerOptions ?? new ReaderOptions());
|
||||
return new TarArchive(fileInfo, readerOptions ?? new ReaderOptions(), cancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -44,34 +46,35 @@ namespace SharpCompress.Archives.Tar
|
||||
/// </summary>
|
||||
/// <param name="stream"></param>
|
||||
/// <param name="readerOptions"></param>
|
||||
public static TarArchive Open(Stream stream, ReaderOptions? readerOptions = null)
|
||||
public static TarArchive Open(Stream stream, ReaderOptions? readerOptions = null,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
stream.CheckNotNull(nameof(stream));
|
||||
return new TarArchive(stream, readerOptions ?? new ReaderOptions());
|
||||
return new TarArchive(stream, readerOptions ?? new ReaderOptions(), cancellationToken);
|
||||
}
|
||||
|
||||
public static bool IsTarFile(string filePath)
|
||||
public static ValueTask<bool> IsTarFileAsync(string filePath, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return IsTarFile(new FileInfo(filePath));
|
||||
return IsTarFileAsync(new FileInfo(filePath), cancellationToken);
|
||||
}
|
||||
|
||||
public static bool IsTarFile(FileInfo fileInfo)
|
||||
public static async ValueTask<bool> IsTarFileAsync(FileInfo fileInfo, CancellationToken cancellationToken = default)
|
||||
{
|
||||
if (!fileInfo.Exists)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
using Stream stream = fileInfo.OpenRead();
|
||||
return IsTarFile(stream);
|
||||
await using Stream stream = fileInfo.OpenRead();
|
||||
return await IsTarFileAsync(stream, cancellationToken);
|
||||
}
|
||||
|
||||
public static bool IsTarFile(Stream stream)
|
||||
public static async ValueTask<bool> IsTarFileAsync(Stream stream, CancellationToken cancellationToken = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
TarHeader tarHeader = new TarHeader(new ArchiveEncoding());
|
||||
bool readSucceeded = tarHeader.Read(new BinaryReader(stream));
|
||||
TarHeader tarHeader = new(new ArchiveEncoding());
|
||||
bool readSucceeded = await tarHeader.Read(stream, cancellationToken);
|
||||
bool isEmptyArchive = tarHeader.Name.Length == 0 && tarHeader.Size == 0 && Enum.IsDefined(typeof(EntryType), tarHeader.EntryType);
|
||||
return readSucceeded || isEmptyArchive;
|
||||
}
|
||||
@@ -86,14 +89,15 @@ namespace SharpCompress.Archives.Tar
|
||||
/// </summary>
|
||||
/// <param name="fileInfo"></param>
|
||||
/// <param name="readerOptions"></param>
|
||||
internal TarArchive(FileInfo fileInfo, ReaderOptions readerOptions)
|
||||
: base(ArchiveType.Tar, fileInfo, readerOptions)
|
||||
internal TarArchive(FileInfo fileInfo, ReaderOptions readerOptions,
|
||||
CancellationToken cancellationToken)
|
||||
: base(ArchiveType.Tar, fileInfo, readerOptions, cancellationToken)
|
||||
{
|
||||
}
|
||||
|
||||
protected override IEnumerable<TarVolume> LoadVolumes(FileInfo file)
|
||||
protected override IAsyncEnumerable<TarVolume> LoadVolumes(FileInfo file, CancellationToken cancellationToken)
|
||||
{
|
||||
return new TarVolume(file.OpenRead(), ReaderOptions).AsEnumerable();
|
||||
return new TarVolume(file.OpenRead(), ReaderOptions).AsAsyncEnumerable();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -101,8 +105,9 @@ namespace SharpCompress.Archives.Tar
|
||||
/// </summary>
|
||||
/// <param name="stream"></param>
|
||||
/// <param name="readerOptions"></param>
|
||||
internal TarArchive(Stream stream, ReaderOptions readerOptions)
|
||||
: base(ArchiveType.Tar, stream, readerOptions)
|
||||
internal TarArchive(Stream stream, ReaderOptions readerOptions,
|
||||
CancellationToken cancellationToken)
|
||||
: base(ArchiveType.Tar, stream, readerOptions, cancellationToken)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -111,16 +116,18 @@ namespace SharpCompress.Archives.Tar
|
||||
{
|
||||
}
|
||||
|
||||
protected override IEnumerable<TarVolume> LoadVolumes(IEnumerable<Stream> streams)
|
||||
protected override async IAsyncEnumerable<TarVolume> LoadVolumes(IAsyncEnumerable<Stream> streams,
|
||||
[EnumeratorCancellation]CancellationToken cancellationToken)
|
||||
{
|
||||
return new TarVolume(streams.First(), ReaderOptions).AsEnumerable();
|
||||
yield return new TarVolume(await streams.FirstAsync(cancellationToken: cancellationToken), ReaderOptions);
|
||||
}
|
||||
|
||||
protected override IEnumerable<TarArchiveEntry> LoadEntries(IEnumerable<TarVolume> volumes)
|
||||
protected override async IAsyncEnumerable<TarArchiveEntry> LoadEntries(IAsyncEnumerable<TarVolume> volumes,
|
||||
[EnumeratorCancellation]CancellationToken cancellationToken)
|
||||
{
|
||||
Stream stream = volumes.Single().Stream;
|
||||
Stream stream = (await volumes.SingleAsync(cancellationToken: cancellationToken)).Stream;
|
||||
TarHeader? previousHeader = null;
|
||||
foreach (TarHeader? header in TarHeaderFactory.ReadHeader(StreamingMode.Seekable, stream, ReaderOptions.ArchiveEncoding))
|
||||
await foreach (TarHeader? header in TarHeaderFactory.ReadHeader(StreamingMode.Seekable, stream, ReaderOptions.ArchiveEncoding, cancellationToken))
|
||||
{
|
||||
if (header != null)
|
||||
{
|
||||
@@ -161,35 +168,37 @@ namespace SharpCompress.Archives.Tar
|
||||
|
||||
public static TarArchive Create()
|
||||
{
|
||||
return new TarArchive();
|
||||
return new();
|
||||
}
|
||||
|
||||
protected override TarArchiveEntry CreateEntryInternal(string filePath, Stream source,
|
||||
long size, DateTime? modified, bool closeStream)
|
||||
protected override ValueTask<TarArchiveEntry> CreateEntryInternal(string filePath, Stream source,
|
||||
long size, DateTime? modified, bool closeStream,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
return new TarWritableArchiveEntry(this, source, CompressionType.Unknown, filePath, size, modified,
|
||||
closeStream);
|
||||
return new (new TarWritableArchiveEntry(this, source, CompressionType.Unknown, filePath, size, modified,
|
||||
closeStream));
|
||||
}
|
||||
|
||||
protected override async Task SaveToAsync(Stream stream, WriterOptions options,
|
||||
IEnumerable<TarArchiveEntry> oldEntries,
|
||||
IEnumerable<TarArchiveEntry> newEntries,
|
||||
CancellationToken cancellationToken = default)
|
||||
protected override async ValueTask SaveToAsync(Stream stream, WriterOptions options,
|
||||
IAsyncEnumerable<TarArchiveEntry> oldEntries,
|
||||
IAsyncEnumerable<TarArchiveEntry> newEntries,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
await using var writer = new TarWriter(stream, new TarWriterOptions(options));
|
||||
foreach (var entry in oldEntries.Concat(newEntries)
|
||||
.Where(x => !x.IsDirectory))
|
||||
await foreach (var entry in oldEntries.Concat(newEntries)
|
||||
.Where(x => !x.IsDirectory)
|
||||
.WithCancellation(cancellationToken))
|
||||
{
|
||||
await using var entryStream = entry.OpenEntryStream();
|
||||
await writer.WriteAsync(entry.Key, entryStream, entry.LastModifiedTime, cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
protected override IReader CreateReaderForSolidExtraction()
|
||||
protected override async ValueTask<IReader> CreateReaderForSolidExtraction()
|
||||
{
|
||||
var stream = Volumes.Single().Stream;
|
||||
var stream = (await Volumes.SingleAsync()).Stream;
|
||||
stream.Position = 0;
|
||||
return TarReader.Open(stream);
|
||||
return await TarReader.OpenAsync(stream);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using SharpCompress.Common;
|
||||
@@ -43,10 +44,11 @@ namespace SharpCompress.Archives.Zip
|
||||
/// </summary>
|
||||
/// <param name="fileInfo"></param>
|
||||
/// <param name="readerOptions"></param>
|
||||
public static ZipArchive Open(FileInfo fileInfo, ReaderOptions? readerOptions = null)
|
||||
public static ZipArchive Open(FileInfo fileInfo, ReaderOptions? readerOptions = null,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
fileInfo.CheckNotNull(nameof(fileInfo));
|
||||
return new ZipArchive(fileInfo, readerOptions ?? new ReaderOptions());
|
||||
return new ZipArchive(fileInfo, readerOptions ?? new ReaderOptions(), cancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -54,10 +56,11 @@ namespace SharpCompress.Archives.Zip
|
||||
/// </summary>
|
||||
/// <param name="stream"></param>
|
||||
/// <param name="readerOptions"></param>
|
||||
public static ZipArchive Open(Stream stream, ReaderOptions? readerOptions = null)
|
||||
public static ZipArchive Open(Stream stream, ReaderOptions? readerOptions = null,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
stream.CheckNotNull(nameof(stream));
|
||||
return new ZipArchive(stream, readerOptions ?? new ReaderOptions());
|
||||
return new ZipArchive(stream, readerOptions ?? new ReaderOptions(), cancellationToken);
|
||||
}
|
||||
|
||||
public static ValueTask<bool> IsZipFile(string filePath, string? password = null)
|
||||
@@ -112,13 +115,15 @@ namespace SharpCompress.Archives.Zip
|
||||
/// </summary>
|
||||
/// <param name="fileInfo"></param>
|
||||
/// <param name="readerOptions"></param>
|
||||
internal ZipArchive(FileInfo fileInfo, ReaderOptions readerOptions)
|
||||
: base(ArchiveType.Zip, fileInfo, readerOptions)
|
||||
internal ZipArchive(FileInfo fileInfo, ReaderOptions readerOptions,
|
||||
CancellationToken cancellationToken)
|
||||
: base(ArchiveType.Zip, fileInfo, readerOptions, cancellationToken)
|
||||
{
|
||||
headerFactory = new SeekableZipHeaderFactory(readerOptions.Password, readerOptions.ArchiveEncoding);
|
||||
}
|
||||
|
||||
protected override IAsyncEnumerable<ZipVolume> LoadVolumes(FileInfo file)
|
||||
protected override IAsyncEnumerable<ZipVolume> LoadVolumes(FileInfo file,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
return new ZipVolume(file.OpenRead(), ReaderOptions).AsAsyncEnumerable();
|
||||
}
|
||||
@@ -133,21 +138,24 @@ namespace SharpCompress.Archives.Zip
|
||||
/// </summary>
|
||||
/// <param name="stream"></param>
|
||||
/// <param name="readerOptions"></param>
|
||||
internal ZipArchive(Stream stream, ReaderOptions readerOptions)
|
||||
: base(ArchiveType.Zip, stream, readerOptions)
|
||||
internal ZipArchive(Stream stream, ReaderOptions readerOptions,
|
||||
CancellationToken cancellationToken)
|
||||
: base(ArchiveType.Zip, stream, readerOptions, cancellationToken)
|
||||
{
|
||||
headerFactory = new SeekableZipHeaderFactory(readerOptions.Password, readerOptions.ArchiveEncoding);
|
||||
}
|
||||
|
||||
protected override async IAsyncEnumerable<ZipVolume> LoadVolumes(IAsyncEnumerable<Stream> streams)
|
||||
protected override async IAsyncEnumerable<ZipVolume> LoadVolumes(IAsyncEnumerable<Stream> streams,
|
||||
[EnumeratorCancellation]CancellationToken cancellationToken)
|
||||
{
|
||||
yield return new ZipVolume(await streams.FirstAsync(), ReaderOptions);
|
||||
yield return new ZipVolume(await streams.FirstAsync(cancellationToken: cancellationToken), ReaderOptions);
|
||||
}
|
||||
|
||||
protected override async IAsyncEnumerable<ZipArchiveEntry> LoadEntries(IAsyncEnumerable<ZipVolume> volumes)
|
||||
protected override async IAsyncEnumerable<ZipArchiveEntry> LoadEntries(IAsyncEnumerable<ZipVolume> volumes,
|
||||
[EnumeratorCancellation]CancellationToken cancellationToken)
|
||||
{
|
||||
await Task.CompletedTask;
|
||||
var volume = await volumes.SingleAsync();
|
||||
var volume = await volumes.SingleAsync(cancellationToken: cancellationToken);
|
||||
Stream stream = volume.Stream;
|
||||
foreach (ZipHeader h in headerFactory.ReadSeekableHeader(stream))
|
||||
{
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using SharpCompress.Readers;
|
||||
|
||||
namespace SharpCompress.Common
|
||||
@@ -20,25 +22,29 @@ namespace SharpCompress.Common
|
||||
/// <summary>
|
||||
/// When reading a stream from OpenEntryStream, the stream must be completed so use this to finish reading the entire entry.
|
||||
/// </summary>
|
||||
public void SkipEntry()
|
||||
public async ValueTask SkipEntryAsync(CancellationToken cancellationToken = default)
|
||||
{
|
||||
this.Skip();
|
||||
await this.SkipAsync(cancellationToken);
|
||||
_completed = true;
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
public override async ValueTask DisposeAsync()
|
||||
{
|
||||
if (!(_completed || _reader.Cancelled))
|
||||
{
|
||||
SkipEntry();
|
||||
await SkipEntryAsync();
|
||||
}
|
||||
if (_isDisposed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
_isDisposed = true;
|
||||
base.Dispose(disposing);
|
||||
_stream.Dispose();
|
||||
await _stream.DisposeAsync();
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override bool CanRead => true;
|
||||
@@ -55,9 +61,9 @@ namespace SharpCompress.Common
|
||||
|
||||
public override long Position { get => throw new NotSupportedException(); set => throw new NotSupportedException(); }
|
||||
|
||||
public override int Read(byte[] buffer, int offset, int count)
|
||||
public override async ValueTask<int> ReadAsync(Memory<byte> buffer, CancellationToken cancellationToken = default)
|
||||
{
|
||||
int read = _stream.Read(buffer, offset, count);
|
||||
int read = await _stream.ReadAsync(buffer, cancellationToken);
|
||||
if (read <= 0)
|
||||
{
|
||||
_completed = true;
|
||||
@@ -65,14 +71,14 @@ namespace SharpCompress.Common
|
||||
return read;
|
||||
}
|
||||
|
||||
public override int Read(byte[] buffer, int offset, int count)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override int ReadByte()
|
||||
{
|
||||
int value = _stream.ReadByte();
|
||||
if (value == -1)
|
||||
{
|
||||
_completed = true;
|
||||
}
|
||||
return value;
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override long Seek(long offset, SeekOrigin origin)
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace SharpCompress.Common.GZip
|
||||
@@ -42,10 +44,12 @@ namespace SharpCompress.Common.GZip
|
||||
|
||||
internal override IEnumerable<FilePart> Parts => _filePart.AsEnumerable<FilePart>();
|
||||
|
||||
internal static async IAsyncEnumerable<GZipEntry> GetEntries(Stream stream, OptionsBase options)
|
||||
internal static async IAsyncEnumerable<GZipEntry> GetEntries(Stream stream, OptionsBase options,
|
||||
[EnumeratorCancellation] CancellationToken cancellationToken)
|
||||
{
|
||||
await Task.CompletedTask;
|
||||
yield return new GZipEntry(new GZipFilePart(stream, options.ArchiveEncoding));
|
||||
var part = new GZipFilePart(options.ArchiveEncoding);
|
||||
await part.Initialize(stream, cancellationToken);
|
||||
yield return new GZipEntry(part);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,8 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Threading;
|
||||
using SharpCompress.Common.Tar.Headers;
|
||||
using SharpCompress.IO;
|
||||
|
||||
@@ -46,10 +48,11 @@ namespace SharpCompress.Common.Tar
|
||||
|
||||
internal override IEnumerable<FilePart> Parts => _filePart.AsEnumerable<FilePart>();
|
||||
|
||||
internal static IEnumerable<TarEntry> GetEntries(StreamingMode mode, Stream stream,
|
||||
CompressionType compressionType, ArchiveEncoding archiveEncoding)
|
||||
internal static async IAsyncEnumerable<TarEntry> GetEntries(StreamingMode mode, Stream stream,
|
||||
CompressionType compressionType, ArchiveEncoding archiveEncoding,
|
||||
[EnumeratorCancellation]CancellationToken cancellationToken)
|
||||
{
|
||||
foreach (TarHeader h in TarHeaderFactory.ReadHeader(mode, stream, archiveEncoding))
|
||||
await foreach (TarHeader h in TarHeaderFactory.ReadHeader(mode, stream, archiveEncoding, cancellationToken))
|
||||
{
|
||||
if (h != null)
|
||||
{
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Threading;
|
||||
using SharpCompress.Common.Tar.Headers;
|
||||
using SharpCompress.IO;
|
||||
|
||||
@@ -7,17 +9,17 @@ namespace SharpCompress.Common.Tar
|
||||
{
|
||||
internal static class TarHeaderFactory
|
||||
{
|
||||
internal static IEnumerable<TarHeader?> ReadHeader(StreamingMode mode, Stream stream, ArchiveEncoding archiveEncoding)
|
||||
internal static async IAsyncEnumerable<TarHeader?> ReadHeader(StreamingMode mode, Stream stream, ArchiveEncoding archiveEncoding,
|
||||
[EnumeratorCancellation]CancellationToken cancellationToken)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
TarHeader? header = null;
|
||||
try
|
||||
{
|
||||
BinaryReader reader = new BinaryReader(stream);
|
||||
header = new TarHeader(archiveEncoding);
|
||||
|
||||
if (!header.Read(reader))
|
||||
if (!await header.Read(stream, cancellationToken))
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
@@ -25,10 +27,10 @@ namespace SharpCompress.Common.Tar
|
||||
{
|
||||
case StreamingMode.Seekable:
|
||||
{
|
||||
header.DataStartPosition = reader.BaseStream.Position;
|
||||
header.DataStartPosition = stream.Position;
|
||||
|
||||
//skip to nearest 512
|
||||
reader.BaseStream.Position += PadTo512(header.Size);
|
||||
stream.Position += PadTo512(header.Size);
|
||||
}
|
||||
break;
|
||||
case StreamingMode.Streaming:
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace SharpCompress.IO
|
||||
{
|
||||
@@ -13,6 +15,16 @@ namespace SharpCompress.IO
|
||||
|
||||
public bool ThrowOnDispose { get; set; }
|
||||
|
||||
public override ValueTask DisposeAsync()
|
||||
{
|
||||
if (ThrowOnDispose)
|
||||
{
|
||||
throw new InvalidOperationException($"Attempt to dispose of a {nameof(NonDisposingStream)} when {nameof(ThrowOnDispose)} is {ThrowOnDispose}");
|
||||
}
|
||||
|
||||
return base.DisposeAsync();
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (ThrowOnDispose)
|
||||
@@ -40,7 +52,17 @@ namespace SharpCompress.IO
|
||||
|
||||
public override int Read(byte[] buffer, int offset, int count)
|
||||
{
|
||||
return Stream.Read(buffer, offset, count);
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override ValueTask<int> ReadAsync(Memory<byte> buffer, CancellationToken cancellationToken = new CancellationToken())
|
||||
{
|
||||
return Stream.ReadAsync(buffer, cancellationToken);
|
||||
}
|
||||
|
||||
public override Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
|
||||
{
|
||||
return Stream.ReadAsync(buffer, offset, count, cancellationToken);
|
||||
}
|
||||
|
||||
public override long Seek(long offset, SeekOrigin origin)
|
||||
@@ -55,7 +77,17 @@ namespace SharpCompress.IO
|
||||
|
||||
public override void Write(byte[] buffer, int offset, int count)
|
||||
{
|
||||
Stream.Write(buffer, offset, count);
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override ValueTask WriteAsync(ReadOnlyMemory<byte> buffer, CancellationToken cancellationToken = new CancellationToken())
|
||||
{
|
||||
return Stream.WriteAsync(buffer, cancellationToken);
|
||||
}
|
||||
|
||||
#if !NET461 && !NETSTANDARD2_0
|
||||
|
||||
@@ -81,11 +81,12 @@ namespace SharpCompress.Readers
|
||||
}
|
||||
if (entriesForCurrentReadStream is null)
|
||||
{
|
||||
return await LoadStreamForReading(RequestInitialStream());
|
||||
//TODO: real token?
|
||||
return await LoadStreamForReading(RequestInitialStream(), CancellationToken.None);
|
||||
}
|
||||
if (!wroteCurrentEntry)
|
||||
{
|
||||
SkipEntry();
|
||||
await SkipEntry(CancellationToken.None);
|
||||
}
|
||||
wroteCurrentEntry = false;
|
||||
if (await NextEntryForCurrentStream())
|
||||
@@ -96,7 +97,7 @@ namespace SharpCompress.Readers
|
||||
return false;
|
||||
}
|
||||
|
||||
protected async Task<bool> LoadStreamForReading(Stream stream)
|
||||
protected async Task<bool> LoadStreamForReading(Stream stream, CancellationToken cancellationToken)
|
||||
{
|
||||
await (entriesForCurrentReadStream?.DisposeAsync() ?? new ValueTask(Task.CompletedTask));
|
||||
if (stream is null || !stream.CanRead)
|
||||
@@ -105,7 +106,7 @@ namespace SharpCompress.Readers
|
||||
+ (Entry?.Key ?? "unknown") +
|
||||
"'. A new readable stream is required. Use Cancel if it was intended.");
|
||||
}
|
||||
entriesForCurrentReadStream = GetEntries(stream).GetAsyncEnumerator();
|
||||
entriesForCurrentReadStream = GetEntries(stream, cancellationToken).GetAsyncEnumerator(cancellationToken);
|
||||
return await (entriesForCurrentReadStream?.MoveNextAsync() ?? new ValueTask<bool>(Task.FromResult(false)));
|
||||
}
|
||||
|
||||
@@ -119,19 +120,19 @@ namespace SharpCompress.Readers
|
||||
return await (entriesForCurrentReadStream?.MoveNextAsync() ?? new ValueTask<bool>(Task.FromResult(false)));
|
||||
}
|
||||
|
||||
protected abstract IAsyncEnumerable<TEntry> GetEntries(Stream stream);
|
||||
protected abstract IAsyncEnumerable<TEntry> GetEntries(Stream stream, CancellationToken cancellationToken);
|
||||
|
||||
#region Entry Skip/Write
|
||||
|
||||
private void SkipEntry()
|
||||
private async ValueTask SkipEntry(CancellationToken cancellationToken)
|
||||
{
|
||||
if (Entry?.IsDirectory == true)
|
||||
{
|
||||
Skip();
|
||||
await SkipAsync(cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
private void Skip()
|
||||
private async ValueTask SkipAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
if (Entry is null)
|
||||
{
|
||||
@@ -148,15 +149,15 @@ namespace SharpCompress.Readers
|
||||
if (rawStream != null)
|
||||
{
|
||||
var bytesToAdvance = Entry.CompressedSize;
|
||||
rawStream.Skip(bytesToAdvance);
|
||||
await rawStream.SkipAsync(bytesToAdvance, cancellationToken: cancellationToken);
|
||||
part.Skipped = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
//don't know the size so we have to try to decompress to skip
|
||||
using (var s = OpenEntryStream())
|
||||
await using (var s = OpenEntryStream())
|
||||
{
|
||||
s.Skip();
|
||||
await s.SkipAsync(cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using SharpCompress.Common;
|
||||
using SharpCompress.Common.GZip;
|
||||
|
||||
@@ -31,9 +32,9 @@ namespace SharpCompress.Readers.GZip
|
||||
|
||||
#endregion Open
|
||||
|
||||
protected override IAsyncEnumerable<GZipEntry> GetEntries(Stream stream)
|
||||
protected override IAsyncEnumerable<GZipEntry> GetEntries(Stream stream, CancellationToken cancellationToken)
|
||||
{
|
||||
return GZipEntry.GetEntries(stream, Options);
|
||||
return GZipEntry.GetEntries(stream, Options, cancellationToken);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using SharpCompress.Archives.GZip;
|
||||
//using SharpCompress.Archives.Rar;
|
||||
//using SharpCompress.Archives.Tar;
|
||||
using SharpCompress.Archives.Tar;
|
||||
using SharpCompress.Archives.Zip;
|
||||
using SharpCompress.Common;
|
||||
using SharpCompress.Compressors;
|
||||
@@ -12,7 +12,7 @@ using SharpCompress.Compressors.Deflate;
|
||||
using SharpCompress.IO;
|
||||
using SharpCompress.Readers.GZip;
|
||||
//using SharpCompress.Readers.Rar;
|
||||
//using SharpCompress.Readers.Tar;
|
||||
using SharpCompress.Readers.Tar;
|
||||
using SharpCompress.Readers.Zip;
|
||||
using SharpCompress.Compressors.LZMA;
|
||||
using SharpCompress.Compressors.Xz;
|
||||
@@ -45,12 +45,12 @@ namespace SharpCompress.Readers
|
||||
if (await GZipArchive.IsGZipFileAsync(rewindableStream))
|
||||
{
|
||||
rewindableStream.Rewind(false);
|
||||
/*GZipStream testStream = new GZipStream(rewindableStream, CompressionMode.Decompress);
|
||||
if (TarArchive.IsTarFile(testStream))
|
||||
GZipStream testStream = new GZipStream(rewindableStream, CompressionMode.Decompress);
|
||||
if (await TarArchive.IsTarFileAsync(testStream))
|
||||
{
|
||||
rewindableStream.Rewind(true);
|
||||
return new TarReader(rewindableStream, options, CompressionType.GZip);
|
||||
} */
|
||||
}
|
||||
rewindableStream.Rewind(true);
|
||||
return GZipReader.Open(rewindableStream, options);
|
||||
}
|
||||
@@ -59,38 +59,38 @@ namespace SharpCompress.Readers
|
||||
if (BZip2Stream.IsBZip2(rewindableStream))
|
||||
{
|
||||
rewindableStream.Rewind(false);
|
||||
/*BZip2Stream testStream = new BZip2Stream(new NonDisposingStream(rewindableStream), CompressionMode.Decompress, false);
|
||||
if (TarArchive.IsTarFile(testStream))
|
||||
BZip2Stream testStream = new BZip2Stream(new NonDisposingStream(rewindableStream), CompressionMode.Decompress, false);
|
||||
if (await TarArchive.IsTarFileAsync(testStream))
|
||||
{
|
||||
rewindableStream.Rewind(true);
|
||||
return new TarReader(rewindableStream, options, CompressionType.BZip2);
|
||||
} */
|
||||
}
|
||||
}
|
||||
|
||||
rewindableStream.Rewind(false);
|
||||
if (LZipStream.IsLZipFile(rewindableStream))
|
||||
{
|
||||
rewindableStream.Rewind(false);
|
||||
/* LZipStream testStream = new LZipStream(new NonDisposingStream(rewindableStream), CompressionMode.Decompress);
|
||||
if (TarArchive.IsTarFile(testStream))
|
||||
LZipStream testStream = new LZipStream(new NonDisposingStream(rewindableStream), CompressionMode.Decompress);
|
||||
if (await TarArchive.IsTarFileAsync(testStream))
|
||||
{
|
||||
rewindableStream.Rewind(true);
|
||||
return new TarReader(rewindableStream, options, CompressionType.LZip);
|
||||
} */
|
||||
}
|
||||
}
|
||||
rewindableStream.Rewind(false);
|
||||
/* if (RarArchive.IsRarFile(rewindableStream, options))
|
||||
{
|
||||
rewindableStream.Rewind(true);
|
||||
return RarReader.Open(rewindableStream, options);
|
||||
}
|
||||
} */
|
||||
|
||||
rewindableStream.Rewind(false);
|
||||
if (TarArchive.IsTarFile(rewindableStream))
|
||||
if (await TarArchive.IsTarFileAsync(rewindableStream))
|
||||
{
|
||||
rewindableStream.Rewind(true);
|
||||
return TarReader.Open(rewindableStream, options);
|
||||
} */
|
||||
return await TarReader.OpenAsync(rewindableStream, options);
|
||||
}
|
||||
rewindableStream.Rewind(false);
|
||||
if (XZStream.IsXZStream(rewindableStream))
|
||||
{
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using SharpCompress.Archives.GZip;
|
||||
using SharpCompress.Archives.Tar;
|
||||
using SharpCompress.Common;
|
||||
@@ -67,17 +69,17 @@ namespace SharpCompress.Readers.Tar
|
||||
/// <param name="stream"></param>
|
||||
/// <param name="options"></param>
|
||||
/// <returns></returns>
|
||||
public static TarReader Open(Stream stream, ReaderOptions? options = null)
|
||||
public static async ValueTask<TarReader> OpenAsync(Stream stream, ReaderOptions? options = null)
|
||||
{
|
||||
stream.CheckNotNull(nameof(stream));
|
||||
options = options ?? new ReaderOptions();
|
||||
RewindableStream rewindableStream = new RewindableStream(stream);
|
||||
rewindableStream.StartRecording();
|
||||
if (GZipArchive.IsGZipFile(rewindableStream))
|
||||
if (await GZipArchive.IsGZipFileAsync(rewindableStream))
|
||||
{
|
||||
rewindableStream.Rewind(false);
|
||||
GZipStream testStream = new GZipStream(rewindableStream, CompressionMode.Decompress);
|
||||
if (TarArchive.IsTarFile(testStream))
|
||||
if (await TarArchive.IsTarFileAsync(testStream))
|
||||
{
|
||||
rewindableStream.Rewind(true);
|
||||
return new TarReader(rewindableStream, options, CompressionType.GZip);
|
||||
@@ -90,7 +92,7 @@ namespace SharpCompress.Readers.Tar
|
||||
{
|
||||
rewindableStream.Rewind(false);
|
||||
BZip2Stream testStream = new BZip2Stream(rewindableStream, CompressionMode.Decompress, false);
|
||||
if (TarArchive.IsTarFile(testStream))
|
||||
if (await TarArchive.IsTarFileAsync(testStream))
|
||||
{
|
||||
rewindableStream.Rewind(true);
|
||||
return new TarReader(rewindableStream, options, CompressionType.BZip2);
|
||||
@@ -103,7 +105,7 @@ namespace SharpCompress.Readers.Tar
|
||||
{
|
||||
rewindableStream.Rewind(false);
|
||||
LZipStream testStream = new LZipStream(rewindableStream, CompressionMode.Decompress);
|
||||
if (TarArchive.IsTarFile(testStream))
|
||||
if (await TarArchive.IsTarFileAsync(testStream))
|
||||
{
|
||||
rewindableStream.Rewind(true);
|
||||
return new TarReader(rewindableStream, options, CompressionType.LZip);
|
||||
@@ -116,9 +118,9 @@ namespace SharpCompress.Readers.Tar
|
||||
|
||||
#endregion Open
|
||||
|
||||
protected override IEnumerable<TarEntry> GetEntries(Stream stream)
|
||||
protected override IAsyncEnumerable<TarEntry> GetEntries(Stream stream, CancellationToken cancellationToken)
|
||||
{
|
||||
return TarEntry.GetEntries(StreamingMode.Streaming, stream, compressionType, Options.ArchiveEncoding);
|
||||
return TarEntry.GetEntries(StreamingMode.Streaming, stream, compressionType, Options.ArchiveEncoding, cancellationToken);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using SharpCompress.Common;
|
||||
using SharpCompress.Common.Zip;
|
||||
using SharpCompress.Common.Zip.Headers;
|
||||
@@ -35,9 +38,9 @@ namespace SharpCompress.Readers.Zip
|
||||
|
||||
#endregion Open
|
||||
|
||||
protected override async IAsyncEnumerable<ZipEntry> GetEntries(Stream stream)
|
||||
protected override async IAsyncEnumerable<ZipEntry> GetEntries(Stream stream, [EnumeratorCancellation] CancellationToken cancellationToken)
|
||||
{
|
||||
await foreach (ZipHeader h in _headerFactory.ReadStreamHeader(stream))
|
||||
await foreach (ZipHeader h in _headerFactory.ReadStreamHeader(stream).WithCancellation(cancellationToken))
|
||||
{
|
||||
if (h != null)
|
||||
{
|
||||
|
||||
@@ -38,26 +38,16 @@
|
||||
<ItemGroup>
|
||||
<Compile Remove="Archives\SevenZip\**" />
|
||||
<Compile Remove="Archives\Rar\**" />
|
||||
<Compile Remove="Archives\Tar\**" />
|
||||
<Compile Remove="Readers\Rar\**" />
|
||||
<Compile Remove="Readers\Tar\**" />
|
||||
<Compile Remove="Writers\Tar\**" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Remove="Archives\SevenZip\**" />
|
||||
<EmbeddedResource Remove="Archives\Rar\**" />
|
||||
<EmbeddedResource Remove="Archives\Tar\**" />
|
||||
<EmbeddedResource Remove="Readers\Rar\**" />
|
||||
<EmbeddedResource Remove="Readers\Tar\**" />
|
||||
<EmbeddedResource Remove="Writers\Tar\**" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Remove="Archives\SevenZip\**" />
|
||||
<None Remove="Archives\Rar\**" />
|
||||
<None Remove="Archives\Tar\**" />
|
||||
<None Remove="Readers\Rar\**" />
|
||||
<None Remove="Readers\Tar\**" />
|
||||
<None Remove="Writers\Tar\**" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
using System.IO;
|
||||
using SharpCompress.Common;
|
||||
using SharpCompress.Writers.GZip;
|
||||
//using SharpCompress.Writers.Tar;
|
||||
using SharpCompress.Writers.Tar;
|
||||
using SharpCompress.Writers.Zip;
|
||||
|
||||
namespace SharpCompress.Writers
|
||||
@@ -27,8 +27,7 @@ namespace SharpCompress.Writers
|
||||
}
|
||||
case ArchiveType.Tar:
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
//return new TarWriter(stream, new TarWriterOptions(writerOptions));
|
||||
return new TarWriter(stream, new TarWriterOptions(writerOptions));
|
||||
}
|
||||
default:
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user