recording isn't great here but it works better

This commit is contained in:
Adam Hathcock
2026-01-31 17:42:32 +00:00
parent 0e2f8068a6
commit 6112b2d1d9
2 changed files with 50 additions and 12 deletions

View File

@@ -236,8 +236,13 @@ internal sealed partial class StreamingZipHeaderFactory
{
lastEntryHeader.DataStartPosition = pos - lastEntryHeader.CompressedSize;
// For SeekableRewindableStream, seek back to just after the local header signature.
// Plain RewindableStream cannot seek to arbitrary positions, so we skip this.
// 4 = First 4 bytes of the entry header (i.e. 50 4B 03 04)
_rewindableStream.Position = pos.Value + 4;
if (_rewindableStream is SeekableRewindableStream)
{
_rewindableStream.Position = pos.Value + 4;
}
}
}
else
@@ -299,12 +304,27 @@ internal sealed partial class StreamingZipHeaderFactory
}
else
{
_rewindableStream.StartRecording();
var nextHeaderBytes = await _reader
.ReadUInt32Async(_cancellationToken)
.ConfigureAwait(false);
_rewindableStream.Rewind(true);
header.HasData = !IsHeader(nextHeaderBytes);
// Only start recording if not already recording.
// The stream may already be recording if it was created by ReaderFactory.
if (!_rewindableStream.IsRecording)
{
_rewindableStream.StartRecording();
var nextHeaderBytes = await _reader
.ReadUInt32Async(_cancellationToken)
.ConfigureAwait(false);
_rewindableStream.Rewind(true);
header.HasData = !IsHeader(nextHeaderBytes);
}
else
{
// If already recording, save position and restore after peek
var savedPosition = _rewindableStream.Position;
var nextHeaderBytes = await _reader
.ReadUInt32Async(_cancellationToken)
.ConfigureAwait(false);
_rewindableStream.Position = savedPosition;
header.HasData = !IsHeader(nextHeaderBytes);
}
}
}
else // We are not streaming and compressed size is 0, we have no data

View File

@@ -134,8 +134,13 @@ internal sealed partial class StreamingZipHeaderFactory : ZipHeaderFactory
{
_lastEntryHeader.DataStartPosition = pos - _lastEntryHeader.CompressedSize;
// For SeekableRewindableStream, seek back to just after the local header signature.
// Plain RewindableStream cannot seek to arbitrary positions, so we skip this.
// 4 = First 4 bytes of the entry header (i.e. 50 4B 03 04)
rewindableStream.Position = pos.Value + 4;
if (rewindableStream is SeekableRewindableStream)
{
rewindableStream.Position = pos.Value + 4;
}
}
}
else
@@ -190,10 +195,23 @@ internal sealed partial class StreamingZipHeaderFactory : ZipHeaderFactory
}
else
{
rewindableStream.StartRecording();
var nextHeaderBytes = reader.ReadUInt32();
rewindableStream.Rewind(true);
header.HasData = !IsHeader(nextHeaderBytes);
// Only start recording if not already recording.
// The stream may already be recording if it was created by ReaderFactory.
if (!rewindableStream.IsRecording)
{
rewindableStream.StartRecording();
var nextHeaderBytes = reader.ReadUInt32();
rewindableStream.Rewind(true);
header.HasData = !IsHeader(nextHeaderBytes);
}
else
{
// If already recording, save position and restore after peek
var savedPosition = rewindableStream.Position;
var nextHeaderBytes = reader.ReadUInt32();
rewindableStream.Position = savedPosition;
header.HasData = !IsHeader(nextHeaderBytes);
}
}
}
else // We are not streaming and compressed size is 0, we have no data