mirror of
https://github.com/adamhathcock/sharpcompress.git
synced 2026-11-15 17:02:03 +00:00
Updates for merge
This commit is contained in:
@@ -108,7 +108,7 @@ namespace SharpCompress.Archives.GZip
|
||||
var slice = header.Memory.Slice(0, 10);
|
||||
|
||||
// workitem 8501: handle edge case (decompress empty stream)
|
||||
if (!await stream.ReadFullyAsync(, cancellationToken))
|
||||
if (await stream.ReadAsync(slice, cancellationToken) != 10)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -96,7 +96,7 @@ namespace SharpCompress.Common.GZip
|
||||
short extraLength = (short)(header.Memory.Span[0] + header.Memory.Span[1] * 256);
|
||||
|
||||
using var extra = MemoryPool<byte>.Shared.Rent(extraLength);
|
||||
if (!await _stream.ReadFullyAsync(extra.Memory.Slice(0, extraLength), cancellationToken))
|
||||
if (await _stream.ReadAsync(extra.Memory.Slice(0, extraLength), cancellationToken) != extraLength)
|
||||
{
|
||||
throw new ZlibException("Unexpected end-of-file reading GZIP header.");
|
||||
}
|
||||
|
||||
@@ -109,7 +109,7 @@ namespace SharpCompress.Common.Tar.Headers
|
||||
internal async ValueTask<bool> Read(Stream stream, CancellationToken cancellationToken)
|
||||
{
|
||||
var block = MemoryPool<byte>.Shared.Rent(BLOCK_SIZE);
|
||||
bool readFullyAsync = await stream.ReadFullyAsync(block.Memory.Slice(0, BLOCK_SIZE), cancellationToken);
|
||||
bool readFullyAsync = await stream.ReadAsync(block.Memory.Slice(0, BLOCK_SIZE), cancellationToken) == BLOCK_SIZE;
|
||||
if (readFullyAsync is false)
|
||||
{
|
||||
return false;
|
||||
@@ -124,7 +124,7 @@ namespace SharpCompress.Common.Tar.Headers
|
||||
if (ReadEntryType(block.Memory.Span) == EntryType.LongName)
|
||||
{
|
||||
Name = await ReadLongName(stream, block.Memory.Slice(0,BLOCK_SIZE), cancellationToken);
|
||||
readFullyAsync = await stream.ReadFullyAsync(block.Memory.Slice(0, BLOCK_SIZE), cancellationToken);
|
||||
readFullyAsync = await stream.ReadAsync(block.Memory.Slice(0, BLOCK_SIZE), cancellationToken) == BLOCK_SIZE;
|
||||
if (readFullyAsync is false)
|
||||
{
|
||||
return false;
|
||||
@@ -168,17 +168,18 @@ namespace SharpCompress.Common.Tar.Headers
|
||||
{
|
||||
var size = ReadSize(buffer);
|
||||
var nameLength = (int)size;
|
||||
using var nameBytes = MemoryPool<byte>.Shared.Rent(nameLength);
|
||||
await reader.ReadFullyAsync(nameBytes.Memory.Slice(0, nameLength), cancellationToken);
|
||||
using var rented = MemoryPool<byte>.Shared.Rent(nameLength);
|
||||
var nameBytes = rented.Memory.Slice(0, nameLength);
|
||||
await reader.ReadAsync(nameBytes, cancellationToken);
|
||||
var remainingBytesToRead = BLOCK_SIZE - (nameLength % BLOCK_SIZE);
|
||||
|
||||
// Read the rest of the block and discard the data
|
||||
if (remainingBytesToRead < BLOCK_SIZE)
|
||||
{
|
||||
using var remaining = MemoryPool<byte>.Shared.Rent(remainingBytesToRead);
|
||||
await reader.ReadFullyAsync(remaining.Memory.Slice(0, remainingBytesToRead), cancellationToken);
|
||||
await reader.ReadAsync(remaining.Memory.Slice(0, remainingBytesToRead), cancellationToken);
|
||||
}
|
||||
return ArchiveEncoding.Decode(nameBytes.Memory.Span.Slice(0, nameLength)).TrimNulls();
|
||||
return ArchiveEncoding.Decode(nameBytes.Span).TrimNulls();
|
||||
}
|
||||
|
||||
private static EntryType ReadEntryType(Span<byte> buffer)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Buffers;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Runtime.CompilerServices;
|
||||
@@ -25,9 +26,7 @@ namespace SharpCompress.Common.Zip
|
||||
|
||||
internal async IAsyncEnumerable<ZipHeader> ReadSeekableHeader(Stream stream, [EnumeratorCancellation]CancellationToken cancellationToken)
|
||||
{
|
||||
var reader = new BinaryReader(stream);
|
||||
|
||||
SeekBackToHeader(stream, reader);
|
||||
await SeekBackToHeaderAsync(stream);
|
||||
|
||||
var eocd_location = stream.Position;
|
||||
var entry = new DirectoryEndHeader();
|
||||
@@ -39,7 +38,7 @@ namespace SharpCompress.Common.Zip
|
||||
|
||||
// ZIP64_END_OF_CENTRAL_DIRECTORY_LOCATOR should be before the EOCD
|
||||
stream.Seek(eocd_location - ZIP64_EOCD_LENGTH - 4, SeekOrigin.Begin);
|
||||
uint zip64_locator = reader.ReadUInt32();
|
||||
uint zip64_locator = await stream.ReadUInt32(cancellationToken);
|
||||
if( zip64_locator != ZIP64_END_OF_CENTRAL_DIRECTORY_LOCATOR )
|
||||
{
|
||||
throw new ArchiveException("Failed to locate the Zip64 Directory Locator");
|
||||
@@ -90,7 +89,7 @@ namespace SharpCompress.Common.Zip
|
||||
}
|
||||
}
|
||||
|
||||
private static bool IsMatch( byte[] haystack, int position, byte[] needle)
|
||||
private static bool IsMatch (Span<byte> haystack, int position, byte[] needle)
|
||||
{
|
||||
for( int i = 0; i < needle.Length; i++ )
|
||||
{
|
||||
@@ -102,7 +101,7 @@ namespace SharpCompress.Common.Zip
|
||||
|
||||
return true;
|
||||
}
|
||||
private static void SeekBackToHeader(Stream stream, BinaryReader reader)
|
||||
private static async ValueTask SeekBackToHeaderAsync(Stream stream)
|
||||
{
|
||||
// Minimum EOCD length
|
||||
if (stream.Length < MINIMUM_EOCD_LENGTH)
|
||||
@@ -116,16 +115,18 @@ namespace SharpCompress.Common.Zip
|
||||
|
||||
stream.Seek(-len, SeekOrigin.End);
|
||||
|
||||
byte[] seek = reader.ReadBytes(len);
|
||||
using var rented = MemoryPool<byte>.Shared.Rent(len);
|
||||
var buffer = rented.Memory.Slice(0, len);
|
||||
await stream.ReadAsync(buffer);
|
||||
|
||||
// Search in reverse
|
||||
Array.Reverse(seek);
|
||||
buffer.Span.Reverse();
|
||||
|
||||
var max_search_area = len - MINIMUM_EOCD_LENGTH;
|
||||
|
||||
for( int pos_from_end = 0; pos_from_end < max_search_area; ++pos_from_end)
|
||||
{
|
||||
if( IsMatch(seek, pos_from_end, needle) )
|
||||
if( IsMatch( buffer.Span, pos_from_end, needle) )
|
||||
{
|
||||
stream.Seek(-pos_from_end, SeekOrigin.End);
|
||||
return;
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace SharpCompress.Compressors.Xz
|
||||
|
||||
public static UInt32 Compute(UInt32 polynomial, UInt32 seed, ReadOnlyMemory<byte> buffer)
|
||||
{
|
||||
return ~CalculateHash(InitializeTable(polynomial), seed, buffer);
|
||||
return ~CalculateHash(InitializeTable(polynomial), seed, buffer.Span);
|
||||
}
|
||||
|
||||
private static UInt32[] InitializeTable(UInt32 polynomial)
|
||||
|
||||
@@ -392,21 +392,6 @@ namespace SharpCompress
|
||||
}
|
||||
return (total >= buffer.Length);
|
||||
}
|
||||
|
||||
public static async ValueTask<bool> ReadFullyAsync(this Stream stream, Memory<byte> buffer, CancellationToken cancellationToken)
|
||||
{
|
||||
int total = 0;
|
||||
int read;
|
||||
while ((read = await stream.ReadAsync(buffer, cancellationToken)) > 0)
|
||||
{
|
||||
total += read;
|
||||
if (total >= buffer.Length)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return (total >= buffer.Length);
|
||||
}
|
||||
|
||||
public static string TrimNulls(this string source)
|
||||
{
|
||||
|
||||
@@ -548,7 +548,6 @@ namespace SharpCompress.Test.Zip
|
||||
await using (ZipArchive za = ZipArchive.Open(zipPath))
|
||||
{
|
||||
var firstEntry = await za.Entries.FirstAsync(x => x.Key == "first.txt");
|
||||
var buffer = new byte[4096];
|
||||
|
||||
await using (var memoryStream = new MemoryStream())
|
||||
await using (var firstStream = await firstEntry.OpenEntryStreamAsync())
|
||||
@@ -560,13 +559,13 @@ namespace SharpCompress.Test.Zip
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Zip_LongComment_Read()
|
||||
public async Task Zip_LongComment_Read()
|
||||
{
|
||||
string zipPath = Path.Combine(TEST_ARCHIVES_PATH, "Zip.LongComment.zip");
|
||||
|
||||
using(ZipArchive za = ZipArchive.Open(zipPath))
|
||||
await using(ZipArchive za = ZipArchive.Open(zipPath))
|
||||
{
|
||||
var count = za.Entries.Count;
|
||||
var count = await za.Entries.CountAsync();
|
||||
Assert.Equal(1, count);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user