Add and use Stream.Write(ReadOnlySpan<byte> buffer) polyfill

This commit is contained in:
Jason Nelson
2020-07-30 17:29:33 -07:00
parent 7750ed7106
commit 6973436b94
7 changed files with 88 additions and 22 deletions

View File

@@ -77,10 +77,9 @@ namespace SharpCompress.Archives.GZip
{
return false;
}
using (Stream stream = fileInfo.OpenRead())
{
return IsGZipFile(stream);
}
using Stream stream = fileInfo.OpenRead();
return IsGZipFile(stream);
}
public void SaveTo(string filePath)

View File

@@ -1,8 +1,9 @@
using System.IO;
using System;
using System.IO;
namespace SharpCompress.Compressors.BZip2
{
public class BZip2Stream : Stream
public sealed class BZip2Stream : Stream
{
private readonly Stream stream;
private bool isDisposed;
@@ -82,6 +83,20 @@ namespace SharpCompress.Compressors.BZip2
stream.SetLength(value);
}
#if NETSTANDARD2_1
public override int Read(Span<byte> buffer)
{
return stream.Read(buffer);
}
public override void Write(ReadOnlySpan<byte> buffer)
{
stream.Write(buffer);
}
#endif
public override void Write(byte[] buffer, int offset, int count)
{
stream.Write(buffer, offset, count);

View File

@@ -228,12 +228,12 @@ namespace SharpCompress.Compressors.Deflate
if (_wantCompress)
{
// Emit the GZIP trailer: CRC32 and size mod 2^32
byte[] intBuf = new byte[4];
Span<byte> intBuf = stackalloc byte[4];
BinaryPrimitives.WriteInt32LittleEndian(intBuf, crc.Crc32Result);
_stream.Write(intBuf, 0, 4);
int c2 = (Int32)(crc.TotalBytesRead & 0x00000000FFFFFFFF);
_stream.Write(intBuf);
int c2 = (int)(crc.TotalBytesRead & 0x00000000FFFFFFFF);
BinaryPrimitives.WriteInt32LittleEndian(intBuf, c2);
_stream.Write(intBuf, 0, 4);
_stream.Write(intBuf);
}
else
{

View File

@@ -117,6 +117,23 @@ namespace SharpCompress.Compressors.LZMA
public override void SetLength(long value) => throw new NotImplementedException();
#if NETSTANDARD2_1
public override int Read(Span<byte> buffer)
{
return _stream.Read(buffer);
}
public override void Write(ReadOnlySpan<byte> buffer)
{
_stream.Write(buffer);
_writeCount += buffer.Length;
}
#endif
public override void Write(byte[] buffer, int offset, int count)
{
_stream.Write(buffer, offset, count);

View File

@@ -42,10 +42,20 @@ namespace SharpCompress.Crypto
public override void SetLength(long value) => throw new NotSupportedException();
#if NETSTANDARD2_1
public override void Write(ReadOnlySpan<byte> buffer)
{
stream.Write(buffer);
hash = CalculateCrc(table, hash, buffer);
}
#endif
public override void Write(byte[] buffer, int offset, int count)
{
stream.Write(buffer, offset, count);
hash = CalculateCrc(table, hash, buffer, offset, count);
hash = CalculateCrc(table, hash, buffer.AsSpan(offset, count));
}
public override void WriteByte(byte value)
@@ -72,9 +82,9 @@ namespace SharpCompress.Crypto
return Compute(DefaultPolynomial, seed, buffer);
}
public static uint Compute(uint polynomial, uint seed, byte[] buffer)
public static uint Compute(uint polynomial, uint seed, ReadOnlySpan<byte> buffer)
{
return ~CalculateCrc(InitializeTable(polynomial), seed, buffer, 0, buffer.Length);
return ~CalculateCrc(InitializeTable(polynomial), seed, buffer);
}
private static uint[] InitializeTable(uint polynomial)
@@ -111,11 +121,11 @@ namespace SharpCompress.Crypto
return createTable;
}
private static uint CalculateCrc(uint[] table, uint crc, byte[] buffer, int offset, int count)
private static uint CalculateCrc(uint[] table, uint crc, ReadOnlySpan<byte> buffer)
{
unchecked
{
for (int i = offset, end = offset + count; i < end; i++)
for (int i = 0; i < buffer.Length; i++)
{
crc = CalculateCrc(table, crc, buffer[i]);
}

View File

@@ -0,0 +1,25 @@
#if !NETSTANDARD2_1
using System.Buffers;
namespace System.IO
{
public static class StreamExtensions
{
public static void Write(this Stream stream, ReadOnlySpan<byte> buffer)
{
var temp = ArrayPool<byte>.Shared.Rent(buffer.Length);
try
{
stream.Write(temp, 0, buffer.Length);
}
finally
{
ArrayPool<byte>.Shared.Return(temp);
}
}
}
}
#endif

View File

@@ -170,16 +170,16 @@ namespace SharpCompress.Writers.Zip
{
if (OutputStream.CanSeek && useZip64)
{
OutputStream.Write(new byte[] { 45, 0 }, 0, 2); //smallest allowed version for zip64
OutputStream.Write(stackalloc byte[] { 45, 0 }); //smallest allowed version for zip64
}
else
{
OutputStream.Write(new byte[] { 20, 0 }, 0, 2); //older version which is more compatible
OutputStream.Write(stackalloc byte[] { 20, 0 }); //older version which is more compatible
}
}
else
{
OutputStream.Write(new byte[] { 63, 0 }, 0, 2); //version says we used PPMd or LZMA
OutputStream.Write(stackalloc byte[] { 63, 0 }); //version says we used PPMd or LZMA
}
HeaderFlags flags = Equals(WriterOptions.ArchiveEncoding.GetEncoding(), Encoding.UTF8) ? HeaderFlags.Efs : 0;
if (!OutputStream.CanSeek)
@@ -200,7 +200,7 @@ namespace SharpCompress.Writers.Zip
OutputStream.Write(intBuf, 0, 4);
// zipping date and time
OutputStream.Write(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0, 12);
OutputStream.Write(stackalloc byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 });
// unused CRC, un/compressed size, updated later
BinaryPrimitives.WriteUInt16LittleEndian(intBuf, (ushort)encodedFilename.Length);
@@ -250,7 +250,7 @@ namespace SharpCompress.Writers.Zip
var recordlen = 2 + 2 + 4 + 4 + 8 + 8 + 8 + 8;
// Write zip64 end of central directory record
OutputStream.Write(new byte[] { 80, 75, 6, 6 }, 0, 4);
OutputStream.Write(stackalloc byte[] { 80, 75, 6, 6 });
BinaryPrimitives.WriteUInt64LittleEndian(intBuf, (ulong)recordlen);
OutputStream.Write(intBuf, 0, 8); // Size of zip64 end of central directory record
@@ -273,7 +273,7 @@ namespace SharpCompress.Writers.Zip
OutputStream.Write(intBuf, 0, 8); // Disk offset
// Write zip64 end of central directory locator
OutputStream.Write(new byte[] { 80, 75, 6, 7 }, 0, 4);
OutputStream.Write(stackalloc byte[] { 80, 75, 6, 7 });
BinaryPrimitives.WriteUInt32LittleEndian(intBuf, 0);
OutputStream.Write(intBuf, 0, 4); // Entry disk
@@ -287,7 +287,7 @@ namespace SharpCompress.Writers.Zip
}
// Write normal end of central directory record
OutputStream.Write(new byte[] { 80, 75, 5, 6, 0, 0, 0, 0 }, 0, 8);
OutputStream.Write(stackalloc byte[] { 80, 75, 5, 6, 0, 0, 0, 0 });
BinaryPrimitives.WriteUInt16LittleEndian(intBuf, (ushort)entries.Count);
OutputStream.Write(intBuf, 0, 2);
OutputStream.Write(intBuf, 0, 2);