mirror of
https://github.com/adamhathcock/sharpcompress.git
synced 2026-09-23 07:25:11 +00:00
move static methods on SCStream
This commit is contained in:
@@ -72,9 +72,9 @@ internal sealed partial class StreamingZipHeaderFactory
|
||||
)
|
||||
{
|
||||
_headerFactory = headerFactory;
|
||||
// Use EnsureSeekable to avoid double-wrapping if stream is already a SharpCompressStream,
|
||||
// Use Create to avoid double-wrapping if stream is already a SharpCompressStream,
|
||||
// and to preserve seekability for DataDescriptorStream which needs to seek backward
|
||||
_sharpCompressStream = SharpCompressStream.EnsureSeekable(stream);
|
||||
_sharpCompressStream = SharpCompressStream.Create(stream);
|
||||
_reader = new AsyncBinaryReader(_sharpCompressStream, leaveOpen: true);
|
||||
_cancellationToken = cancellationToken;
|
||||
}
|
||||
|
||||
@@ -20,9 +20,9 @@ internal partial class StreamingZipHeaderFactory : ZipHeaderFactory
|
||||
|
||||
internal IEnumerable<ZipHeader> ReadStreamHeader(Stream stream)
|
||||
{
|
||||
// Use EnsureSeekable to avoid double-wrapping if stream is already a SharpCompressStream,
|
||||
// Use Create to avoid double-wrapping if stream is already a SharpCompressStream,
|
||||
// and to preserve seekability for DataDescriptorStream which needs to seek backward
|
||||
var sharpCompressStream = SharpCompressStream.EnsureSeekable(stream);
|
||||
var sharpCompressStream = SharpCompressStream.Create(stream);
|
||||
var reader = new BinaryReader(
|
||||
sharpCompressStream,
|
||||
System.Text.Encoding.Default,
|
||||
|
||||
65
src/SharpCompress/IO/SharpCompressStream.Create.cs
Normal file
65
src/SharpCompress/IO/SharpCompressStream.Create.cs
Normal file
@@ -0,0 +1,65 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using SharpCompress.Common;
|
||||
|
||||
namespace SharpCompress.IO;
|
||||
|
||||
internal partial class SharpCompressStream
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a SharpCompressStream that acts as a passthrough wrapper.
|
||||
/// No buffering is performed; CanSeek delegates to the underlying stream.
|
||||
/// The underlying stream will not be disposed when this stream is disposed.
|
||||
/// </summary>
|
||||
public static SharpCompressStream CreateNonDisposing(Stream stream) =>
|
||||
new(stream, leaveStreamOpen: true, passthrough: true);
|
||||
|
||||
public static SharpCompressStream Create(
|
||||
Stream stream,
|
||||
int? rewindableBufferSize = null
|
||||
)
|
||||
{
|
||||
int bufferSize = rewindableBufferSize ?? Constants.RewindableBufferSize;
|
||||
|
||||
// If it's a passthrough SharpCompressStream, unwrap it and create proper seekable wrapper
|
||||
if (stream is SharpCompressStream sharpCompressStream)
|
||||
{
|
||||
if (sharpCompressStream._isPassthrough)
|
||||
{
|
||||
// Unwrap the passthrough and create appropriate wrapper
|
||||
var underlying = sharpCompressStream.stream;
|
||||
if (underlying.CanSeek)
|
||||
{
|
||||
// Create SeekableSharpCompressStream that preserves LeaveStreamOpen
|
||||
return new SeekableSharpCompressStream(underlying)
|
||||
{
|
||||
LeaveStreamOpen = true, // Preserve non-disposing behavior
|
||||
};
|
||||
}
|
||||
// Non-seekable underlying stream - wrap with rolling buffer
|
||||
return new SharpCompressStream(underlying, bufferSize) { LeaveStreamOpen = true };
|
||||
}
|
||||
// Not passthrough - return as-is
|
||||
return sharpCompressStream;
|
||||
}
|
||||
|
||||
// Check if stream is wrapping a SharpCompressStream (e.g., via IStreamStack)
|
||||
if (stream is IStreamStack streamStack)
|
||||
{
|
||||
var underlying = streamStack.GetStream<SharpCompressStream>();
|
||||
if (underlying is not null)
|
||||
{
|
||||
return underlying;
|
||||
}
|
||||
}
|
||||
|
||||
if (stream.CanSeek)
|
||||
{
|
||||
return new SeekableSharpCompressStream(stream);
|
||||
}
|
||||
|
||||
// For non-seekable streams, create a SharpCompressStream with rolling buffer
|
||||
// to allow limited backward seeking (required by decompressors that over-read)
|
||||
return new SharpCompressStream(stream, bufferSize);
|
||||
}
|
||||
}
|
||||
@@ -76,14 +76,6 @@ internal partial class SharpCompressStream : Stream, IStreamStack
|
||||
_logicalPosition = 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a SharpCompressStream that acts as a passthrough wrapper.
|
||||
/// No buffering is performed; CanSeek delegates to the underlying stream.
|
||||
/// The underlying stream will not be disposed when this stream is disposed.
|
||||
/// </summary>
|
||||
public static SharpCompressStream CreateNonDisposing(Stream stream) =>
|
||||
new(stream, leaveStreamOpen: true, passthrough: true);
|
||||
|
||||
/// <summary>
|
||||
/// Gets whether the stream is actively recording reads to the ring buffer.
|
||||
/// </summary>
|
||||
@@ -121,7 +113,7 @@ internal partial class SharpCompressStream : Stream, IStreamStack
|
||||
if (_isPassthrough)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
"Rewind cannot be called on a passthrough stream. Use EnsureSeekable() first."
|
||||
"Rewind cannot be called on a passthrough stream. Use Create() first."
|
||||
);
|
||||
}
|
||||
|
||||
@@ -160,7 +152,7 @@ internal partial class SharpCompressStream : Stream, IStreamStack
|
||||
if (_isPassthrough)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
"StopRecording cannot be called on a passthrough stream. Use EnsureSeekable() first."
|
||||
"StopRecording cannot be called on a passthrough stream. Use Create() first."
|
||||
);
|
||||
}
|
||||
if (!IsRecording)
|
||||
@@ -180,61 +172,12 @@ internal partial class SharpCompressStream : Stream, IStreamStack
|
||||
// (frozen recording mode) until Rewind(stopRecording: true) is called
|
||||
}
|
||||
|
||||
public static SharpCompressStream EnsureSeekable(
|
||||
Stream stream,
|
||||
int? rewindableBufferSize = null
|
||||
)
|
||||
{
|
||||
int bufferSize = rewindableBufferSize ?? Constants.RewindableBufferSize;
|
||||
|
||||
// If it's a passthrough SharpCompressStream, unwrap it and create proper seekable wrapper
|
||||
if (stream is SharpCompressStream sharpCompressStream)
|
||||
{
|
||||
if (sharpCompressStream._isPassthrough)
|
||||
{
|
||||
// Unwrap the passthrough and create appropriate wrapper
|
||||
var underlying = sharpCompressStream.stream;
|
||||
if (underlying.CanSeek)
|
||||
{
|
||||
// Create SeekableSharpCompressStream that preserves LeaveStreamOpen
|
||||
return new SeekableSharpCompressStream(underlying)
|
||||
{
|
||||
LeaveStreamOpen = true, // Preserve non-disposing behavior
|
||||
};
|
||||
}
|
||||
// Non-seekable underlying stream - wrap with rolling buffer
|
||||
return new SharpCompressStream(underlying, bufferSize) { LeaveStreamOpen = true };
|
||||
}
|
||||
// Not passthrough - return as-is
|
||||
return sharpCompressStream;
|
||||
}
|
||||
|
||||
// Check if stream is wrapping a SharpCompressStream (e.g., via IStreamStack)
|
||||
if (stream is IStreamStack streamStack)
|
||||
{
|
||||
var underlying = streamStack.GetStream<SharpCompressStream>();
|
||||
if (underlying is not null)
|
||||
{
|
||||
return underlying;
|
||||
}
|
||||
}
|
||||
|
||||
if (stream.CanSeek)
|
||||
{
|
||||
return new SeekableSharpCompressStream(stream);
|
||||
}
|
||||
|
||||
// For non-seekable streams, create a SharpCompressStream with rolling buffer
|
||||
// to allow limited backward seeking (required by decompressors that over-read)
|
||||
return new SharpCompressStream(stream, bufferSize);
|
||||
}
|
||||
|
||||
public virtual void StartRecording()
|
||||
{
|
||||
if (_isPassthrough)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
"StartRecording cannot be called on a passthrough stream. Use EnsureSeekable() first."
|
||||
"StartRecording cannot be called on a passthrough stream. Use Create() first."
|
||||
);
|
||||
}
|
||||
if (IsRecording)
|
||||
|
||||
@@ -54,7 +54,7 @@ public static partial class ReaderFactory
|
||||
stream.NotNull(nameof(stream));
|
||||
options ??= new ReaderOptions() { LeaveStreamOpen = false };
|
||||
|
||||
var sharpCompressStream = SharpCompressStream.EnsureSeekable(
|
||||
var sharpCompressStream = SharpCompressStream.Create(
|
||||
stream,
|
||||
options.RewindableBufferSize
|
||||
);
|
||||
|
||||
@@ -34,7 +34,7 @@ public static partial class ReaderFactory
|
||||
stream.NotNull(nameof(stream));
|
||||
options ??= new ReaderOptions() { LeaveStreamOpen = false };
|
||||
|
||||
var sharpCompressStream = SharpCompressStream.EnsureSeekable(
|
||||
var sharpCompressStream = SharpCompressStream.Create(
|
||||
stream,
|
||||
options.RewindableBufferSize
|
||||
);
|
||||
|
||||
@@ -57,7 +57,7 @@ public partial class TarReader : AbstractReader<TarEntry, TarVolume>
|
||||
{
|
||||
stream.NotNull(nameof(stream));
|
||||
options = options ?? new ReaderOptions();
|
||||
var sharpCompressStream = SharpCompressStream.EnsureSeekable(
|
||||
var sharpCompressStream = SharpCompressStream.Create(
|
||||
stream,
|
||||
options.RewindableBufferSize
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user