diff --git a/src/ImageSharp/IO/BufferedReadStream.cs b/src/ImageSharp/IO/BufferedReadStream.cs index dfc05e62fa..ae733a88ed 100644 --- a/src/ImageSharp/IO/BufferedReadStream.cs +++ b/src/ImageSharp/IO/BufferedReadStream.cs @@ -21,8 +21,6 @@ namespace SixLabors.ImageSharp.IO private const int MaxBufferIndex = BufferLength - 1; - private readonly Stream stream; - private readonly byte[] readBuffer; private MemoryHandle readBufferHandle; @@ -54,7 +52,7 @@ namespace SixLabors.ImageSharp.IO stream.Flush(); } - this.stream = stream; + this.BaseStream = stream; this.Position = (int)stream.Position; this.Length = stream.Length; @@ -88,7 +86,7 @@ namespace SixLabors.ImageSharp.IO else { // Base stream seek will throw for us if invalid. - this.stream.Seek(value, SeekOrigin.Begin); + this.BaseStream.Seek(value, SeekOrigin.Begin); this.readerPosition = value; this.readBufferIndex = BufferLength; } @@ -104,6 +102,15 @@ namespace SixLabors.ImageSharp.IO /// public override bool CanWrite { get; } = false; + /// + /// Gets the underlying stream. + /// + public Stream BaseStream + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get; + } + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public override int ReadByte() @@ -148,10 +155,10 @@ namespace SixLabors.ImageSharp.IO public override void Flush() { // Reset the stream position to match reader position. - if (this.readerPosition != this.stream.Position) + if (this.readerPosition != this.BaseStream.Position) { - this.stream.Seek(this.readerPosition, SeekOrigin.Begin); - this.readerPosition = (int)this.stream.Position; + this.BaseStream.Seek(this.readerPosition, SeekOrigin.Begin); + this.readerPosition = (int)this.BaseStream.Position; } // Reset to trigger full read on next attempt. @@ -218,9 +225,9 @@ namespace SixLabors.ImageSharp.IO [MethodImpl(MethodImplOptions.NoInlining)] private void FillReadBuffer() { - if (this.readerPosition != this.stream.Position) + if (this.readerPosition != this.BaseStream.Position) { - this.stream.Seek(this.readerPosition, SeekOrigin.Begin); + this.BaseStream.Seek(this.readerPosition, SeekOrigin.Begin); } // Read doesn't always guarantee the full returned length so read a byte @@ -229,7 +236,7 @@ namespace SixLabors.ImageSharp.IO int i; do { - i = this.stream.Read(this.readBuffer, n, BufferLength - n); + i = this.BaseStream.Read(this.readBuffer, n, BufferLength - n); n += i; } while (n < BufferLength && i > 0); @@ -262,9 +269,9 @@ namespace SixLabors.ImageSharp.IO private int ReadToBufferDirectSlow(byte[] buffer, int offset, int count) { // Read to target but don't copy to our read buffer. - if (this.readerPosition != this.stream.Position) + if (this.readerPosition != this.BaseStream.Position) { - this.stream.Seek(this.readerPosition, SeekOrigin.Begin); + this.BaseStream.Seek(this.readerPosition, SeekOrigin.Begin); } // Read doesn't always guarantee the full returned length so read a byte @@ -273,7 +280,7 @@ namespace SixLabors.ImageSharp.IO int i; do { - i = this.stream.Read(buffer, n, count - n); + i = this.BaseStream.Read(buffer, n, count - n); n += i; } while (n < count && i > 0); diff --git a/tests/ImageSharp.Tests/Image/ImageTests.Load_FileSystemPath_PassLocalConfiguration.cs b/tests/ImageSharp.Tests/Image/ImageTests.Load_FileSystemPath_PassLocalConfiguration.cs index ed355364a3..813c68d4cf 100644 --- a/tests/ImageSharp.Tests/Image/ImageTests.Load_FileSystemPath_PassLocalConfiguration.cs +++ b/tests/ImageSharp.Tests/Image/ImageTests.Load_FileSystemPath_PassLocalConfiguration.cs @@ -2,8 +2,10 @@ // Licensed under the Apache License, Version 2.0. using System; - +using System.IO; +using Moq; using SixLabors.ImageSharp.Formats; +using SixLabors.ImageSharp.IO; using SixLabors.ImageSharp.PixelFormats; using Xunit; @@ -36,22 +38,29 @@ namespace SixLabors.ImageSharp.Tests this.TestFormat.VerifyAgnosticDecodeCall(this.Marker, this.TopLevelConfiguration); } - [Fact(Skip = "TODO: Enable when someone tells me how this mocking stuff works.")] + [Fact] public void Configuration_Path_Decoder_Specific() { var img = Image.Load(this.TopLevelConfiguration, this.MockFilePath, this.localDecoder.Object); Assert.NotNull(img); - this.localDecoder.Verify(x => x.Decode(this.TopLevelConfiguration, this.DataStream)); + this.localDecoder + .Verify( + x => x.Decode( + this.TopLevelConfiguration, + It.Is(x => ((BufferedReadStream)x).BaseStream == this.DataStream))); } - [Fact(Skip = "TODO: Enable when someone tells me how this mocking stuff works.")] + [Fact] public void Configuration_Path_Decoder_Agnostic() { var img = Image.Load(this.TopLevelConfiguration, this.MockFilePath, this.localDecoder.Object); Assert.NotNull(img); - this.localDecoder.Verify(x => x.Decode(this.TopLevelConfiguration, this.DataStream)); + this.localDecoder.Verify( + x => x.Decode( + this.TopLevelConfiguration, + It.Is(x => ((BufferedReadStream)x).BaseStream == this.DataStream))); } [Fact] diff --git a/tests/ImageSharp.Tests/Image/ImageTests.Load_FromStream_PassLocalConfiguration.cs b/tests/ImageSharp.Tests/Image/ImageTests.Load_FromStream_PassLocalConfiguration.cs index 149a6e4732..aa3d50eae2 100644 --- a/tests/ImageSharp.Tests/Image/ImageTests.Load_FromStream_PassLocalConfiguration.cs +++ b/tests/ImageSharp.Tests/Image/ImageTests.Load_FromStream_PassLocalConfiguration.cs @@ -2,7 +2,7 @@ // Licensed under the Apache License, Version 2.0. using System.IO; - +using Moq; using SixLabors.ImageSharp.Formats; using SixLabors.ImageSharp.IO; using SixLabors.ImageSharp.PixelFormats; @@ -48,24 +48,30 @@ namespace SixLabors.ImageSharp.Tests this.TestFormat.VerifySpecificDecodeCall(this.Marker, this.TopLevelConfiguration); } - [Fact(Skip = "TODO: Enable when someone tells me how this mocking stuff works.")] + [Fact] public void Configuration_Stream_Decoder_Specific() { var stream = new MemoryStream(); var img = Image.Load(this.TopLevelConfiguration, stream, this.localDecoder.Object); Assert.NotNull(img); - this.localDecoder.Verify(x => x.Decode(this.TopLevelConfiguration, stream)); + this.localDecoder.Verify( + x => x.Decode( + this.TopLevelConfiguration, + It.Is(x => ((BufferedReadStream)x).BaseStream == stream))); } - [Fact(Skip = "TODO: Enable when someone tells me how this mocking stuff works.")] + [Fact] public void Configuration_Stream_Decoder_Agnostic() { var stream = new MemoryStream(); var img = Image.Load(this.TopLevelConfiguration, stream, this.localDecoder.Object); Assert.NotNull(img); - this.localDecoder.Verify(x => x.Decode(this.TopLevelConfiguration, stream)); + this.localDecoder.Verify( + x => x.Decode( + this.TopLevelConfiguration, + It.Is(x => ((BufferedReadStream)x).BaseStream == stream))); } [Fact]