Browse Source

More tests and remove old stream

pull/1574/head
James Jackson-South 6 years ago
parent
commit
ceab655ce5
  1. 69
      src/ImageSharp/IO/FixedCapacityPooledMemoryStream.cs
  2. 3
      src/ImageSharp/Memory/MemoryAllocatorExtensions.cs
  3. 53
      tests/ImageSharp.Tests/IO/ChunkedMemoryStreamTests.cs
  4. 42
      tests/ImageSharp.Tests/IO/FixedCapacityPooledMemoryStreamTests.cs

69
src/ImageSharp/IO/FixedCapacityPooledMemoryStream.cs

@ -1,69 +0,0 @@
// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
using System;
using System.Buffers;
using System.IO;
using SixLabors.ImageSharp.Memory;
namespace SixLabors.ImageSharp.IO
{
/// <summary>
/// A memory stream constructed from a pooled buffer of known length.
/// </summary>
internal sealed class FixedCapacityPooledMemoryStream : MemoryStream
{
private readonly IManagedByteBuffer buffer;
private bool isDisposed;
/// <summary>
/// Initializes a new instance of the <see cref="FixedCapacityPooledMemoryStream"/> class.
/// </summary>
/// <param name="length">The length of the stream buffer to rent.</param>
/// <param name="allocator">The allocator to rent the buffer from.</param>
public FixedCapacityPooledMemoryStream(long length, MemoryAllocator allocator)
: this(RentBuffer(length, allocator)) => this.Length = length;
private FixedCapacityPooledMemoryStream(IManagedByteBuffer buffer)
: base(buffer.Array) => this.buffer = buffer;
/// <inheritdoc/>
public override long Length { get; }
/// <inheritdoc/>
public override bool TryGetBuffer(out ArraySegment<byte> buffer)
{
if (this.isDisposed)
{
throw new ObjectDisposedException(this.GetType().Name);
}
buffer = new ArraySegment<byte>(this.buffer.Array, 0, this.buffer.Length());
return true;
}
/// <inheritdoc/>
protected override void Dispose(bool disposing)
{
if (!this.isDisposed)
{
this.isDisposed = true;
if (disposing)
{
this.buffer.Dispose();
}
base.Dispose(disposing);
}
}
// In the extrememly unlikely event someone ever gives us a stream
// with length longer than int.MaxValue then we'll use something else.
private static IManagedByteBuffer RentBuffer(long length, MemoryAllocator allocator)
{
Guard.MustBeBetweenOrEqualTo(length, 0, int.MaxValue, nameof(length));
return allocator.AllocateManagedByteBuffer((int)length);
}
}
}

3
src/ImageSharp/Memory/MemoryAllocatorExtensions.cs

@ -100,8 +100,5 @@ namespace SixLabors.ImageSharp.Memory
AllocationOptions options = AllocationOptions.None) AllocationOptions options = AllocationOptions.None)
where T : struct where T : struct
=> MemoryGroup<T>.Allocate(memoryAllocator, totalLength, bufferAlignment, options); => MemoryGroup<T>.Allocate(memoryAllocator, totalLength, bufferAlignment, options);
internal static MemoryStream AllocateFixedCapacityMemoryStream(this MemoryAllocator allocator, long length) =>
new FixedCapacityPooledMemoryStream(length, allocator);
} }
} }

53
tests/ImageSharp.Tests/IO/ChunkedMemoryStreamTests.cs

@ -30,7 +30,7 @@ namespace SixLabors.ImageSharp.Tests.IO
} }
[Fact] [Fact]
public void ChunkedPooledMemoryStream_GetPositionTest_Negative() public void MemoryStream_GetPositionTest_Negative()
{ {
using var ms = new ChunkedMemoryStream(this.allocator); using var ms = new ChunkedMemoryStream(this.allocator);
long iCurrentPos = ms.Position; long iCurrentPos = ms.Position;
@ -57,6 +57,48 @@ namespace SixLabors.ImageSharp.Tests.IO
Assert.Throws<ObjectDisposedException>(() => ms2.Read(new byte[] { 1 }, 0, 1)); Assert.Throws<ObjectDisposedException>(() => ms2.Read(new byte[] { 1 }, 0, 1));
} }
[Theory]
[InlineData(1024)]
[InlineData(1024 * 4)]
[InlineData(1024 * 6)]
[InlineData(1024 * 8)]
public void MemoryStream_ReadByteTest(int length)
{
using MemoryStream ms = this.CreateTestStream(length);
using var cms = new ChunkedMemoryStream(this.allocator);
ms.CopyTo(cms);
cms.Position = 0;
var expected = ms.ToArray();
for (int i = 0; i < expected.Length; i++)
{
Assert.Equal(expected[i], cms.ReadByte());
}
}
[Theory]
[InlineData(1024)]
[InlineData(1024 * 4)]
[InlineData(1024 * 6)]
[InlineData(1024 * 8)]
public void MemoryStream_ReadByteBufferTest(int length)
{
using MemoryStream ms = this.CreateTestStream(length);
using var cms = new ChunkedMemoryStream(this.allocator);
ms.CopyTo(cms);
cms.Position = 0;
var expected = ms.ToArray();
var buffer = new byte[2];
for (int i = 0; i < expected.Length; i += 2)
{
cms.Read(buffer);
Assert.Equal(expected[i], buffer[0]);
Assert.Equal(expected[i + 1], buffer[1]);
}
}
[Fact] [Fact]
public void MemoryStream_WriteToTests() public void MemoryStream_WriteToTests()
{ {
@ -179,5 +221,14 @@ namespace SixLabors.ImageSharp.Tests.IO
yield return new object[] { stream3, Array.Empty<byte>() }; yield return new object[] { stream3, Array.Empty<byte>() };
} }
private MemoryStream CreateTestStream(int length)
{
var buffer = new byte[length];
var random = new Random();
random.NextBytes(buffer);
return new MemoryStream(buffer);
}
} }
} }

42
tests/ImageSharp.Tests/IO/FixedCapacityPooledMemoryStreamTests.cs

@ -1,42 +0,0 @@
// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
using System;
using System.IO;
using System.Linq;
using SixLabors.ImageSharp.Memory;
using SixLabors.ImageSharp.Tests.Memory;
using Xunit;
namespace SixLabors.ImageSharp.Tests.IO
{
public class FixedCapacityPooledMemoryStreamTests
{
private readonly TestMemoryAllocator memoryAllocator = new TestMemoryAllocator();
[Theory]
[InlineData(1)]
[InlineData(512)]
public void RentsManagedBuffer(int length)
{
MemoryStream ms = this.memoryAllocator.AllocateFixedCapacityMemoryStream(length);
Assert.Equal(length, this.memoryAllocator.AllocationLog.Single().Length);
ms.Dispose();
Assert.Equal(1, this.memoryAllocator.ReturnLog.Count);
}
[Theory]
[InlineData(42)]
[InlineData(2999)]
public void UsesRentedBuffer(int length)
{
using MemoryStream ms = this.memoryAllocator.AllocateFixedCapacityMemoryStream(length);
ms.TryGetBuffer(out ArraySegment<byte> buffer);
byte[] array = buffer.Array;
Assert.Equal(array.GetHashCode(), this.memoryAllocator.AllocationLog.Single().HashCodeOfBuffer);
ms.Write(new byte[] { 123 });
Assert.Equal(123, array[0]);
}
}
}
Loading…
Cancel
Save