Updates for merge

This commit is contained in:
Adam Hathcock
2021-02-14 13:52:55 +00:00
parent be34fe2056
commit 5c11075d36
7 changed files with 23 additions and 37 deletions

View File

@@ -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;
}

View File

@@ -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.");
}

View File

@@ -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)

View File

@@ -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;

View File

@@ -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)

View File

@@ -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)
{

View File

@@ -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);
}
}