Don't allocate arrays when copying streams (#1510)
- Use the array pool - Use Span to copy native memory - Fixes #1509
This commit is contained in:
Родитель
2019706296
Коммит
61b71d6e48
|
@ -1,8 +1,5 @@
|
|||
using System;
|
||||
using System.Buffers;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
namespace SkiaSharp
|
||||
{
|
||||
|
@ -90,18 +87,25 @@ namespace SkiaSharp
|
|||
|
||||
private IntPtr OnReadManagedStream (IntPtr buffer, IntPtr size)
|
||||
{
|
||||
byte[] managedBuffer;
|
||||
using (var reader = new BinaryReader (stream, Encoding.UTF8, true)) {
|
||||
managedBuffer = reader.ReadBytes ((int)size);
|
||||
}
|
||||
var result = managedBuffer.Length;
|
||||
if (buffer != IntPtr.Zero) {
|
||||
Marshal.Copy (managedBuffer, 0, buffer, result);
|
||||
}
|
||||
if (!stream.CanSeek && (int)size > 0 && result <= (int)size) {
|
||||
if (buffer == IntPtr.Zero)
|
||||
throw new ArgumentNullException (nameof (buffer));
|
||||
if ((int)size < 0)
|
||||
throw new ArgumentOutOfRangeException (nameof (size));
|
||||
|
||||
if (size == IntPtr.Zero)
|
||||
return IntPtr.Zero;
|
||||
|
||||
using var managedBuffer = Utils.RentArray<byte> ((int)size);
|
||||
var len = stream.Read (managedBuffer.Array, 0, managedBuffer.Length);
|
||||
|
||||
var src = managedBuffer.Span.Slice (0, len);
|
||||
var dst = buffer.AsSpan (managedBuffer.Length);
|
||||
src.CopyTo (dst);
|
||||
|
||||
if (!stream.CanSeek && (int)size > 0 && len <= (int)size)
|
||||
isAsEnd = true;
|
||||
}
|
||||
return (IntPtr)result;
|
||||
|
||||
return (IntPtr)len;
|
||||
}
|
||||
|
||||
protected override IntPtr OnRead (IntPtr buffer, IntPtr size)
|
||||
|
|
Двоичные данные
samples/AppStoreCertificates/SkiaSharpSample_TemporaryKey.pfx
Двоичные данные
samples/AppStoreCertificates/SkiaSharpSample_TemporaryKey.pfx
Двоичный файл не отображается.
|
@ -17,7 +17,7 @@
|
|||
<FileAlignment>512</FileAlignment>
|
||||
<ProjectTypeGuids>{A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
<PackageCertificateKeyFile>..\..\..\AppStoreCertificates\SkiaSharpSample_TemporaryKey.pfx</PackageCertificateKeyFile>
|
||||
<PackageCertificateThumbprint>D3578B78019FED6AEE572B23C1723D44951E0BF9</PackageCertificateThumbprint>
|
||||
<PackageCertificateThumbprint>5FC604ABEDFB78C8B4E57214FEB937949F44ABE4</PackageCertificateThumbprint>
|
||||
<RestoreProjectStyle>PackageReference</RestoreProjectStyle>
|
||||
<LangVersion>8.0</LangVersion>
|
||||
</PropertyGroup>
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
<FileAlignment>512</FileAlignment>
|
||||
<ProjectTypeGuids>{A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
<PackageCertificateKeyFile>..\..\..\AppStoreCertificates\SkiaSharpSample_TemporaryKey.pfx</PackageCertificateKeyFile>
|
||||
<PackageCertificateThumbprint>D3578B78019FED6AEE572B23C1723D44951E0BF9</PackageCertificateThumbprint>
|
||||
<PackageCertificateThumbprint>5FC604ABEDFB78C8B4E57214FEB937949F44ABE4</PackageCertificateThumbprint>
|
||||
<RestoreProjectStyle>PackageReference</RestoreProjectStyle>
|
||||
<LangVersion>8.0</LangVersion>
|
||||
</PropertyGroup>
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
<FileAlignment>512</FileAlignment>
|
||||
<ProjectTypeGuids>{A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
<PackageCertificateKeyFile>..\..\..\AppStoreCertificates\SkiaSharpSample_TemporaryKey.pfx</PackageCertificateKeyFile>
|
||||
<PackageCertificateThumbprint>D3578B78019FED6AEE572B23C1723D44951E0BF9</PackageCertificateThumbprint>
|
||||
<PackageCertificateThumbprint>5FC604ABEDFB78C8B4E57214FEB937949F44ABE4</PackageCertificateThumbprint>
|
||||
<RestoreProjectStyle>PackageReference</RestoreProjectStyle>
|
||||
<LangVersion>8.0</LangVersion>
|
||||
</PropertyGroup>
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
<FileAlignment>512</FileAlignment>
|
||||
<ProjectTypeGuids>{A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
<PackageCertificateKeyFile>..\..\..\AppStoreCertificates\SkiaSharpSample_TemporaryKey.pfx</PackageCertificateKeyFile>
|
||||
<PackageCertificateThumbprint>D3578B78019FED6AEE572B23C1723D44951E0BF9</PackageCertificateThumbprint>
|
||||
<PackageCertificateThumbprint>5FC604ABEDFB78C8B4E57214FEB937949F44ABE4</PackageCertificateThumbprint>
|
||||
<RestoreProjectStyle>PackageReference</RestoreProjectStyle>
|
||||
<LangVersion>8.0</LangVersion>
|
||||
</PropertyGroup>
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
<FileAlignment>512</FileAlignment>
|
||||
<ProjectTypeGuids>{A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
<PackageCertificateKeyFile>..\..\..\AppStoreCertificates\SkiaSharpSample_TemporaryKey.pfx</PackageCertificateKeyFile>
|
||||
<PackageCertificateThumbprint>D3578B78019FED6AEE572B23C1723D44951E0BF9</PackageCertificateThumbprint>
|
||||
<PackageCertificateThumbprint>5FC604ABEDFB78C8B4E57214FEB937949F44ABE4</PackageCertificateThumbprint>
|
||||
<RestoreProjectStyle>PackageReference</RestoreProjectStyle>
|
||||
<LangVersion>8.0</LangVersion>
|
||||
</PropertyGroup>
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
<FileAlignment>512</FileAlignment>
|
||||
<ProjectTypeGuids>{A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
<PackageCertificateKeyFile>..\..\..\AppStoreCertificates\SkiaSharpSample_TemporaryKey.pfx</PackageCertificateKeyFile>
|
||||
<PackageCertificateThumbprint>D3578B78019FED6AEE572B23C1723D44951E0BF9</PackageCertificateThumbprint>
|
||||
<PackageCertificateThumbprint>5FC604ABEDFB78C8B4E57214FEB937949F44ABE4</PackageCertificateThumbprint>
|
||||
<RestoreProjectStyle>PackageReference</RestoreProjectStyle>
|
||||
<LangVersion>8.0</LangVersion>
|
||||
</PropertyGroup>
|
||||
|
|
|
@ -124,6 +124,34 @@ namespace SkiaSharp.Tests
|
|||
}
|
||||
}
|
||||
|
||||
[SkippableTheory]
|
||||
[InlineData(1024, 0, 0, 0)]
|
||||
[InlineData(1024, 1, 1, 1)]
|
||||
[InlineData(1024, 10, 10, 10)]
|
||||
[InlineData(1024, 100, 100, 100)]
|
||||
[InlineData(1024, 1000, 1000, 1000)]
|
||||
[InlineData(1024, 10000, 1024, 1024)]
|
||||
public void ReadIsCorrect(int dataSize, int readSize, int finalPos, int expectedReadSize)
|
||||
{
|
||||
var data = new byte[dataSize];
|
||||
for (var i = 0; i < data.Length; i++)
|
||||
{
|
||||
data[i] = (byte)(i % byte.MaxValue);
|
||||
}
|
||||
|
||||
var stream = new MemoryStream(data);
|
||||
var managedStream = new SKManagedStream(stream);
|
||||
|
||||
var buffer = new byte[dataSize * 2];
|
||||
|
||||
var actualReadSize = managedStream.Read(buffer, readSize);
|
||||
|
||||
Assert.Equal(expectedReadSize, actualReadSize);
|
||||
Assert.Equal(finalPos, managedStream.Position);
|
||||
Assert.Equal(data.Take(readSize), buffer.Take(actualReadSize));
|
||||
Assert.All(buffer.Skip(actualReadSize), i => Assert.Equal(0, i));
|
||||
}
|
||||
|
||||
[SkippableFact]
|
||||
public void ManagedStreamReadsChunkCorrectly()
|
||||
{
|
||||
|
|
Загрузка…
Ссылка в новой задаче