Exemplo n.º 1
0
        public async Task ShouldAlwaysFlushUnderlyingStreamIfWritable(bool underlyingCanRead, bool underlyingCanSeek)
        {
            var underlying = new DelegateStream(
                canReadFunc: () => underlyingCanRead,
                canWriteFunc: () => true,
                canSeekFunc: () => underlyingCanSeek,
                readFunc: (_, __, ___) => 123,
                writeFunc: (_, __, ___) => { },
                seekFunc: (_, __) => 123L
            );

            var wrapper = new CallTrackingStream(underlying);

            var buffered = new BufferedStream(wrapper);
            
            buffered.Flush();
            Assert.Equal(1, wrapper.TimesCalled(nameof(wrapper.Flush)));

            await buffered.FlushAsync();
            Assert.Equal(1, wrapper.TimesCalled(nameof(wrapper.FlushAsync)));

            buffered.WriteByte(0);
            
            buffered.Flush();
            Assert.Equal(2, wrapper.TimesCalled(nameof(wrapper.Flush)));

            await buffered.FlushAsync();
            Assert.Equal(2, wrapper.TimesCalled(nameof(wrapper.FlushAsync)));
        }
Exemplo n.º 2
0
        public async Task ReadAsyncMemory_WrapsArray_DelegatesToReadAsyncArray_Success()
        {
            bool readInvoked = false;
            var  s           = new DelegateStream(
                canReadFunc: () => true,
                readAsyncFunc: (array, offset, count, cancellationToken) =>
            {
                readInvoked = true;
                Assert.NotNull(array);
                Assert.Equal(5, offset);
                Assert.Equal(20, count);

                for (int i = 0; i < 10; i++)
                {
                    array[offset + i] = (byte)i;
                }
                return(Task.FromResult(10));
            });

            Memory <byte> totalMemory  = new byte[30];
            Memory <byte> targetMemory = totalMemory.Slice(5, 20);

            Assert.Equal(10, await s.ReadAsync(targetMemory));
            Assert.True(readInvoked);
            for (int i = 0; i < 10; i++)
            {
                Assert.Equal(i, targetMemory.Span[i]);
            }
            for (int i = 10; i < 20; i++)
            {
                Assert.Equal(0, targetMemory.Span[i]);
            }
            readInvoked = false;
        }
Exemplo n.º 3
0
        public async Task ShouldNotFlushUnderlyingStreamIfReadOnly(bool underlyingCanSeek)
        {
            var underlying = new DelegateStream(
                canReadFunc: () => true,
                canWriteFunc: () => false,
                canSeekFunc: () => underlyingCanSeek,
                readFunc: (_, __, ___) => 123,
                writeFunc: (_, __, ___) =>
                {
                    throw new NotSupportedException();
                },
                seekFunc: (_, __) => 123L
            );

            var wrapper = new CallTrackingStream(underlying);

            var buffered = new BufferedStream(wrapper);
            buffered.ReadByte();

            buffered.Flush();
            Assert.Equal(0, wrapper.TimesCalled(nameof(wrapper.Flush)));

            await buffered.FlushAsync();
            Assert.Equal(0, wrapper.TimesCalled(nameof(wrapper.FlushAsync)));
        }
Exemplo n.º 4
0
        public async Task WriteAsyncMemory_WrapsNative_DelegatesToWrite_Success()
        {
            bool writeInvoked = false;
            var  s            = new DelegateStream(
                canWriteFunc: () => true,
                writeAsyncFunc: (array, offset, count, cancellationToken) =>
            {
                writeInvoked = true;
                Assert.NotNull(array);
                Assert.Equal(0, offset);
                Assert.Equal(3, count);

                for (int i = 0; i < count; i++)
                {
                    Assert.Equal(i, array[i]);
                }

                return(Task.CompletedTask);
            });

            using (var nativeMemory = new NativeOwnedMemory(10))
            {
                Memory <byte> memory = nativeMemory.Memory;
                memory.Span[2] = 0;
                memory.Span[3] = 1;
                memory.Span[4] = 2;
                await s.WriteAsync(memory.Slice(2, 3));

                Assert.True(writeInvoked);
                writeInvoked = false;
            }
        }
Exemplo n.º 5
0
        public void WriteSpan_DelegatesToWrite_Success()
        {
            bool writeInvoked = false;
            var  s            = new DelegateStream(
                canWriteFunc: () => true,
                writeFunc: (array, offset, count) =>
            {
                writeInvoked = true;
                Assert.NotNull(array);
                Assert.Equal(0, offset);
                Assert.Equal(3, count);

                for (int i = 0; i < count; i++)
                {
                    Assert.Equal(i, array[offset + i]);
                }
            });

            Span <byte> span = new byte[10];

            span[3] = 1;
            span[4] = 2;
            s.Write(span.Slice(2, 3));
            Assert.True(writeInvoked);
            writeInvoked = false;
        }
Exemplo n.º 6
0
        public async Task ShouldNotFlushUnderlyingStreamIfReadOnly(bool underlyingCanSeek)
        {
            var underlying = new DelegateStream(
                canReadFunc: () => true,
                canWriteFunc: () => false,
                canSeekFunc: () => underlyingCanSeek,
                readFunc: (_, __, ___) => 123,
                writeFunc: (_, __, ___) =>
            {
                throw new NotSupportedException();
            },
                seekFunc: (_, __) => 123L
                );

            var wrapper = new CallTrackingStream(underlying);

            var buffered = new BufferedStream(wrapper);

            buffered.ReadByte();

            buffered.Flush();
            Assert.Equal(0, wrapper.TimesCalled(nameof(wrapper.Flush)));

            await buffered.FlushAsync();

            Assert.Equal(0, wrapper.TimesCalled(nameof(wrapper.FlushAsync)));
        }
Exemplo n.º 7
0
        public void ReadSpan_DelegatesToRead_Success()
        {
            bool readInvoked = false;
            var  s           = new DelegateStream(
                canReadFunc: () => true,
                readFunc: (array, offset, count) =>
            {
                readInvoked = true;
                Assert.NotNull(array);
                Assert.Equal(0, offset);
                Assert.Equal(20, count);

                for (int i = 0; i < 10; i++)
                {
                    array[offset + i] = (byte)i;
                }
                return(10);
            });

            Span <byte> totalSpan  = new byte[30];
            Span <byte> targetSpan = totalSpan.Slice(5, 20);

            Assert.Equal(10, s.Read(targetSpan));
            Assert.True(readInvoked);
            for (int i = 0; i < 10; i++)
            {
                Assert.Equal(i, targetSpan[i]);
            }
            for (int i = 10; i < 20; i++)
            {
                Assert.Equal(0, targetSpan[i]);
            }
            readInvoked = false;
        }
Exemplo n.º 8
0
        public async Task ShouldAlwaysFlushUnderlyingStreamIfWritable(bool underlyingCanRead, bool underlyingCanSeek)
        {
            var underlying = new DelegateStream(
                canReadFunc: () => underlyingCanRead,
                canWriteFunc: () => true,
                canSeekFunc: () => underlyingCanSeek,
                readFunc: (_, __, ___) => 123,
                writeFunc: (_, __, ___) => { },
                seekFunc: (_, __) => 123L
                );

            var wrapper = new CallTrackingStream(underlying);

            var buffered = new BufferedStream(wrapper);

            buffered.Flush();
            Assert.Equal(1, wrapper.TimesCalled(nameof(wrapper.Flush)));

            await buffered.FlushAsync();

            Assert.Equal(1, wrapper.TimesCalled(nameof(wrapper.FlushAsync)));

            buffered.WriteByte(0);

            buffered.Flush();
            Assert.Equal(2, wrapper.TimesCalled(nameof(wrapper.Flush)));

            await buffered.FlushAsync();

            Assert.Equal(2, wrapper.TimesCalled(nameof(wrapper.FlushAsync)));
        }
        public void IfLengthMinusPositionPositiveOverflowsBufferSizeShouldStillBePositive(long length, long position)
        {
            // The new implementation of Stream.CopyTo calculates the bytes left
            // in the Stream by calling Length - Position. This can overflow to a
            // negative number, so this tests that if that happens we don't send
            // in a negative bufferSize.

            var baseStream = new DelegateStream(
                canReadFunc: () => true,
                canSeekFunc: () => true,
                lengthFunc: () => length,
                positionGetFunc: () => position,
                readFunc: (buffer, offset, count) => 0);
            var trackingStream = new CallTrackingStream(baseStream);

            var dest = Stream.Null;

            trackingStream.CopyTo(dest);

            // CopyTo is not virtual, so we can't override it in
            // CallTrackingStream and record the arguments directly.
            // Instead, validate the arguments passed to Read.

            Assert.Equal(1, trackingStream.TimesCalled(nameof(trackingStream.Read)));

            byte[] outerBuffer = trackingStream.ReadBuffer;
            int    outerOffset = trackingStream.ReadOffset;
            int    outerCount  = trackingStream.ReadCount;

            Assert.NotNull(outerBuffer);
            Assert.InRange(outerOffset, 0, outerBuffer.Length - outerCount);
            Assert.InRange(outerCount, 1, int.MaxValue);
        }
        public void IfCanSeekIsFalseLengthAndPositionShouldNotBeCalled()
        {
            var baseStream = new DelegateStream(
                canReadFunc: () => true,
                canSeekFunc: () => false,
                readFunc: (buffer, offset, count) => 0);
            var trackingStream = new CallTrackingStream(baseStream);

            var dest = Stream.Null;

            trackingStream.CopyTo(dest);

            Assert.InRange(trackingStream.TimesCalled(nameof(trackingStream.CanSeek)), 0, 1);
            Assert.Equal(0, trackingStream.TimesCalled(nameof(trackingStream.Length)));
            Assert.Equal(0, trackingStream.TimesCalled(nameof(trackingStream.Position)));
            // We can't override CopyTo since it's not virtual, so checking TimesCalled
            // for CopyTo will result in 0. Instead, we check that Read was called,
            // and validate the parameters passed there.
            Assert.Equal(1, trackingStream.TimesCalled(nameof(trackingStream.Read)));

            byte[] outerBuffer = trackingStream.ReadBuffer;
            int    outerOffset = trackingStream.ReadOffset;
            int    outerCount  = trackingStream.ReadCount;

            Assert.NotNull(outerBuffer);
            Assert.InRange(outerOffset, 0, outerBuffer.Length - outerCount);
            Assert.InRange(outerCount, 1, int.MaxValue); // the buffer can't be size 0
        }
Exemplo n.º 11
0
        public void IfCanSeekIsFalseLengthAndPositionShouldNotBeCalled()
        {
            var baseStream = new DelegateStream(
                canReadFunc: () => true,
                canSeekFunc: () => false,
                readFunc: (buffer, offset, count) => 0);
            var trackingStream = new CallTrackingStream(baseStream);

            var dest = Stream.Null;
            trackingStream.CopyTo(dest);

            Assert.InRange(trackingStream.TimesCalled(nameof(trackingStream.CanSeek)), 0, 1);
            Assert.Equal(0, trackingStream.TimesCalled(nameof(trackingStream.Length)));
            Assert.Equal(0, trackingStream.TimesCalled(nameof(trackingStream.Position)));
            // We can't override CopyTo since it's not virtual, so checking TimesCalled
            // for CopyTo will result in 0. Instead, we check that Read was called,
            // and validate the parameters passed there.
            Assert.Equal(1, trackingStream.TimesCalled(nameof(trackingStream.Read)));

            byte[] outerBuffer = trackingStream.ReadBuffer;
            int outerOffset = trackingStream.ReadOffset;
            int outerCount = trackingStream.ReadCount;

            Assert.NotNull(outerBuffer);
            Assert.InRange(outerOffset, 0, outerBuffer.Length - outerCount);
            Assert.InRange(outerCount, 1, int.MaxValue); // the buffer can't be size 0
        }
Exemplo n.º 12
0
        public void IfLengthIsLessThanOrEqualToPositionCopyToShouldStillBeCalledWithAPositiveBufferSize(long length, long position)
        {
            // Streams with their Lengths <= their Positions, e.g.
            // new MemoryStream { Position = 3 }.SetLength(1)
            // should still be called CopyTo{Async} on with a
            // bufferSize of at least 1.

            var baseStream = new DelegateStream(
                canReadFunc: () => true,
                canSeekFunc: () => true,
                lengthFunc: () => length,
                positionGetFunc: () => position,
                readFunc: (buffer, offset, count) => 0);
            var trackingStream = new CallTrackingStream(baseStream);

            var dest = Stream.Null;

            trackingStream.CopyTo(dest);

            // CopyTo is not virtual, so we can't override it in
            // CallTrackingStream and record the arguments directly.
            // Instead, validate the arguments passed to Read.

            Assert.Equal(1, trackingStream.TimesCalled(nameof(trackingStream.Read)));

            byte[] outerBuffer = trackingStream.ReadBuffer;
            int    outerOffset = trackingStream.ReadOffset;
            int    outerCount  = trackingStream.ReadCount;

            Assert.NotNull(outerBuffer);
            Assert.InRange(outerOffset, 0, outerBuffer.Length - outerCount);
            Assert.InRange(outerCount, 1, int.MaxValue);
        }
Exemplo n.º 13
0
        public async Task ReadMoreThanMinimumBytes(bool async)
        {
            int readInvokedCount = 0;
            var s = new DelegateStream(
                canReadFunc: () => true,
                readFunc: (array, offset, count) =>
            {
                readInvokedCount++;

                int byteCount = Math.Min(count, 10);
                for (int i = 0; i < byteCount; i++)
                {
                    array[offset + i] = (byte)i;
                }
                return(byteCount);
            });

            // first try with a buffer that doesn't fill 3 full pages
            byte[] buffer = new byte[28];

            Assert.Equal(28, async ? await s.ReadAtLeastAsync(buffer, 22) : s.ReadAtLeast(buffer, 22));
            Assert.Equal(3, readInvokedCount);
            for (int i = 0; i < 10; i++)
            {
                Assert.Equal(i, buffer[i]);
            }
            for (int i = 10; i < 20; i++)
            {
                Assert.Equal(i - 10, buffer[i]);
            }
            for (int i = 20; i < 28; i++)
            {
                Assert.Equal(i - 20, buffer[i]);
            }

            // now try with a buffer that is bigger than 3 pages
            readInvokedCount = 0;
            buffer           = new byte[32];

            Assert.Equal(30, async ? await s.ReadAtLeastAsync(buffer, 22) : s.ReadAtLeast(buffer, 22));
            Assert.Equal(3, readInvokedCount);
            for (int i = 0; i < 10; i++)
            {
                Assert.Equal(i, buffer[i]);
            }
            for (int i = 10; i < 20; i++)
            {
                Assert.Equal(i - 10, buffer[i]);
            }
            for (int i = 20; i < 30; i++)
            {
                Assert.Equal(i - 20, buffer[i]);
            }
            for (int i = 30; i < 32; i++)
            {
                Assert.Equal(0, buffer[i]);
            }
        }
        public void DisposeAsync_InvokesDisposeSynchronously()
        {
            int  id      = Environment.CurrentManagedThreadId;
            bool invoked = false;
            var  s       = new DelegateStream(disposeFunc: disposing =>
            {
                invoked = true;
                Assert.Equal(id, Environment.CurrentManagedThreadId);
            });

            Assert.True(s.DisposeAsync().IsCompletedSuccessfully);
            Assert.True(invoked);
        }
Exemplo n.º 15
0
        public async Task ReadBlockAsync_RepeatsReadsUntilReadDesiredAmount()
        {
            char[] data = "hello world".ToCharArray();
            var    ms   = new MemoryStream(Encoding.UTF8.GetBytes(data));
            var    s    = new DelegateStream(
                canReadFunc: () => true,
                readAsyncFunc: (buffer, offset, count, cancellationToken) => ms.ReadAsync(buffer, offset, 1)); // do actual reads a byte at a time

            using (var r = new StreamReader(s, Encoding.UTF8, false, 2))
            {
                var result = new char[data.Length];
                Assert.Equal(data.Length, await r.ReadBlockAsync((Memory <char>)result));
                Assert.Equal <char>(data, result);
            }
        }
Exemplo n.º 16
0
        public async Task HandleEndOfStream(bool async)
        {
            int readInvokedCount = 0;
            var s = new DelegateStream(
                canReadFunc: () => true,
                readFunc: (array, offset, count) =>
            {
                readInvokedCount++;

                if (readInvokedCount == 1)
                {
                    int byteCount = Math.Min(count, 10);
                    for (int i = 0; i < byteCount; i++)
                    {
                        array[offset + i] = (byte)i;
                    }
                    return(byteCount);
                }
                else
                {
                    return(0);
                }
            });

            byte[] buffer = new byte[20];
            if (async)
            {
                await Assert.ThrowsAsync <EndOfStreamException>(async() => await s.ReadAtLeastAsync(buffer, 11));
            }
            else
            {
                Assert.Throws <EndOfStreamException>(() => s.ReadAtLeast(buffer, 11));
            }
            Assert.Equal(2, readInvokedCount);

            readInvokedCount = 0;

            Assert.Equal(10, async ? await s.ReadAtLeastAsync(buffer, 11, throwOnEndOfStream: false) : s.ReadAtLeast(buffer, 11, throwOnEndOfStream: false));
            for (int i = 0; i < 10; i++)
            {
                Assert.Equal(i, buffer[i]);
            }
            for (int i = 10; i < 20; i++)
            {
                Assert.Equal(0, buffer[i]);
            }
            Assert.Equal(2, readInvokedCount);
        }
Exemplo n.º 17
0
        public void IfCanSeekIsTrueLengthAndPositionShouldOnlyBeCalledOnce()
        {
            var baseStream = new DelegateStream(
                canReadFunc: () => true,
                canSeekFunc: () => true,
                readFunc: (buffer, offset, count) => 0,
                lengthFunc: () => 0L,
                positionGetFunc: () => 0L);
            var trackingStream = new CallTrackingStream(baseStream);

            var dest = Stream.Null;
            trackingStream.CopyTo(dest);

            Assert.InRange(trackingStream.TimesCalled(nameof(trackingStream.Length)), 0, 1);
            Assert.InRange(trackingStream.TimesCalled(nameof(trackingStream.Position)), 0, 1);
        }
Exemplo n.º 18
0
        public async void AsyncIfCanSeekIsTrueLengthAndPositionShouldOnlyBeCalledOnce()
        {
            var baseStream = new DelegateStream(
                canReadFunc: () => true,
                canSeekFunc: () => true,
                readFunc: (buffer, offset, count) => 0,
                lengthFunc: () => 0L,
                positionGetFunc: () => 0L);
            var trackingStream = new CallTrackingStream(baseStream);

            var dest = Stream.Null;
            await trackingStream.CopyToAsync(dest);

            Assert.InRange(trackingStream.TimesCalled(nameof(trackingStream.Length)), 0, 1);
            Assert.InRange(trackingStream.TimesCalled(nameof(trackingStream.Position)), 0, 1);
        }
Exemplo n.º 19
0
        public async Task ThrowOnEndOfStream(bool async)
        {
            int readInvokedCount = 0;
            var s = new DelegateStream(
                canReadFunc: () => true,
                readFunc: (array, offset, count) =>
            {
                readInvokedCount++;

                if (readInvokedCount == 1)
                {
                    int byteCount = Math.Min(count, 10);
                    for (int i = 0; i < byteCount; i++)
                    {
                        array[offset + i] = (byte)i;
                    }
                    return(byteCount);
                }
                else
                {
                    return(0);
                }
            });

            byte[] buffer = new byte[11];
            if (async)
            {
                await Assert.ThrowsAsync <EndOfStreamException>(async() => await s.ReadExactlyAsync(buffer));
            }
            else
            {
                Assert.Throws <EndOfStreamException>(() => s.ReadExactly(buffer));
            }
            Assert.Equal(2, readInvokedCount);

            readInvokedCount = 0;
            if (async)
            {
                await Assert.ThrowsAsync <EndOfStreamException>(async() => await s.ReadExactlyAsync(buffer, 0, buffer.Length));
            }
            else
            {
                Assert.Throws <EndOfStreamException>(() => s.ReadExactly(buffer, 0, buffer.Length));
            }
            Assert.Equal(2, readInvokedCount);
        }
Exemplo n.º 20
0
        public async void AsyncIfLengthIsLessThanOrEqualToPositionCopyToShouldStillBeCalledWithAPositiveBufferSize(long length, long position)
        {
            var baseStream = new DelegateStream(
                canReadFunc: () => true,
                canSeekFunc: () => true,
                lengthFunc: () => length,
                positionGetFunc: () => position,
                readFunc: (buffer, offset, count) => 0);
            var trackingStream = new CallTrackingStream(baseStream);

            var dest = Stream.Null;
            await trackingStream.CopyToAsync(dest);

            Assert.Same(dest, trackingStream.CopyToAsyncDestination);
            Assert.InRange(trackingStream.CopyToAsyncBufferSize, 1, int.MaxValue);
            Assert.Equal(CancellationToken.None, trackingStream.CopyToAsyncCancellationToken);
        }
Exemplo n.º 21
0
        public async Task ReadPartialPageCorrectly_OffsetCount(bool async)
        {
            int readInvokedCount = 0;
            var s = new DelegateStream(
                canReadFunc: () => true,
                readFunc: (array, offset, count) =>
            {
                readInvokedCount++;

                int byteCount = Math.Min(count, 10);
                for (int i = 0; i < byteCount; i++)
                {
                    array[offset + i] = (byte)i;
                }
                return(byteCount);
            });

            byte[] buffer = new byte[25];

            if (async)
            {
                await s.ReadExactlyAsync(buffer, 5, 15);
            }
            else
            {
                s.ReadExactly(buffer, 5, 15);
            }

            Assert.Equal(2, readInvokedCount);
            for (int i = 0; i < 5; i++)
            {
                Assert.Equal(0, buffer[i]);
            }
            for (int i = 5; i < 15; i++)
            {
                Assert.Equal(i - 5, buffer[i]);
            }
            for (int i = 15; i < 20; i++)
            {
                Assert.Equal(i - 15, buffer[i]);
            }
            for (int i = 20; i < 25; i++)
            {
                Assert.Equal(0, buffer[i]);
            }
        }
        public async Task SslStream_StreamToStream_EOFDuringFrameRead_ThrowsIOException()
        {
            var network = new VirtualNetwork();

            using (var clientNetworkStream = new VirtualNetworkStream(network, isServer: false))
                using (var serverNetworkStream = new VirtualNetworkStream(network, isServer: true))
                {
                    int readMode = 0;
                    var serverWrappedNetworkStream = new DelegateStream(
                        canWriteFunc: () => true,
                        canReadFunc: () => true,
                        writeFunc: (buffer, offset, count) => serverNetworkStream.Write(buffer, offset, count),
                        readFunc: (buffer, offset, count) =>
                    {
                        // Do normal reads as requested until the read mode is set
                        // to 1.  Then do a single read of only 10 bytes to read only
                        // part of the message, and subsequently return EOF.
                        if (readMode == 0)
                        {
                            return(serverNetworkStream.Read(buffer, offset, count));
                        }
                        else if (readMode == 1)
                        {
                            readMode = 2;
                            return(serverNetworkStream.Read(buffer, offset, 10)); // read at least header but less than full frame
                        }
                        else
                        {
                            return(0);
                        }
                    });


                    using (var clientSslStream = new SslStream(clientNetworkStream, false, AllowAnyServerCertificate))
                        using (var serverSslStream = new SslStream(serverWrappedNetworkStream))
                        {
                            await DoHandshake(clientSslStream, serverSslStream);

                            await clientSslStream.WriteAsync(new byte[20], 0, 20);

                            readMode = 1;
                            await Assert.ThrowsAsync <IOException>(() => serverSslStream.ReadAsync(new byte[1], 0, 1));
                        }
                }
        }
Exemplo n.º 23
0
        public async Task OffsetCount_ArgumentChecking(bool async)
        {
            int readInvokedCount = 0;
            var s = new DelegateStream(
                canReadFunc: () => true,
                readFunc: (array, offset, count) =>
            {
                readInvokedCount++;

                int byteCount = Math.Min(count, 10);
                for (int i = 0; i < byteCount; i++)
                {
                    array[offset + i] = (byte)i;
                }
                return(byteCount);
            });

            byte[] buffer = new byte[30];

            if (async)
            {
                await Assert.ThrowsAsync <ArgumentNullException>(async() => await s.ReadExactlyAsync(null, 0, 1));

                await Assert.ThrowsAsync <ArgumentOutOfRangeException>(async() => await s.ReadExactlyAsync(buffer, 0, -1));

                await Assert.ThrowsAsync <ArgumentOutOfRangeException>(async() => await s.ReadExactlyAsync(buffer, -1, buffer.Length));

                await Assert.ThrowsAsync <ArgumentOutOfRangeException>(async() => await s.ReadExactlyAsync(buffer, buffer.Length, 1));

                await Assert.ThrowsAsync <ArgumentOutOfRangeException>(async() => await s.ReadExactlyAsync(buffer, 0, buffer.Length + 1));

                await Assert.ThrowsAsync <ArgumentOutOfRangeException>(async() => await s.ReadExactlyAsync(buffer, buffer.Length - 1, 2));
            }
            else
            {
                Assert.Throws <ArgumentNullException>(() => s.ReadExactly(null, 0, 1));
                Assert.Throws <ArgumentOutOfRangeException>(() => s.ReadExactly(buffer, 0, -1));
                Assert.Throws <ArgumentOutOfRangeException>(() => s.ReadExactly(buffer, -1, buffer.Length));
                Assert.Throws <ArgumentOutOfRangeException>(() => s.ReadExactly(buffer, buffer.Length, 1));
                Assert.Throws <ArgumentOutOfRangeException>(() => s.ReadExactly(buffer, 0, buffer.Length + 1));
                Assert.Throws <ArgumentOutOfRangeException>(() => s.ReadExactly(buffer, buffer.Length - 1, 2));
            }

            Assert.Equal(0, readInvokedCount);
        }
Exemplo n.º 24
0
        public async Task DelegatesToRead_Success(bool async)
        {
            int readInvokedCount = 0;
            var s = new DelegateStream(
                canReadFunc: () => true,
                readFunc: (array, offset, count) =>
            {
                readInvokedCount++;

                int byteCount = Math.Min(count, 10);
                for (int i = 0; i < byteCount; i++)
                {
                    array[offset + i] = (byte)i;
                }
                return(byteCount);
            });

            byte[] buffer = new byte[30];

            if (async)
            {
                await s.ReadExactlyAsync(buffer);
            }
            else
            {
                s.ReadExactly(buffer);
            }

            Assert.Equal(3, readInvokedCount);
            for (int i = 0; i < 10; i++)
            {
                Assert.Equal(i, buffer[i]);
            }
            for (int i = 10; i < 20; i++)
            {
                Assert.Equal(i - 10, buffer[i]);
            }
            for (int i = 20; i < 30; i++)
            {
                Assert.Equal(i - 20, buffer[i]);
            }
        }
Exemplo n.º 25
0
        public async void AsyncIfCanSeekIsFalseLengthAndPositionShouldNotBeCalled()
        {
            var baseStream = new DelegateStream(
                canReadFunc: () => true,
                canSeekFunc: () => false,
                readFunc: (buffer, offset, count) => 0);
            var trackingStream = new CallTrackingStream(baseStream);

            var dest = Stream.Null;
            await trackingStream.CopyToAsync(dest);

            Assert.InRange(trackingStream.TimesCalled(nameof(trackingStream.CanSeek)), 0, 1);
            Assert.Equal(0, trackingStream.TimesCalled(nameof(trackingStream.Length)));
            Assert.Equal(0, trackingStream.TimesCalled(nameof(trackingStream.Position)));
            Assert.Equal(1, trackingStream.TimesCalled(nameof(trackingStream.CopyToAsync)));

            Assert.Same(dest, trackingStream.CopyToAsyncDestination);
            Assert.InRange(trackingStream.CopyToAsyncBufferSize, 1, int.MaxValue);
            Assert.Equal(CancellationToken.None, trackingStream.CopyToAsyncCancellationToken);
        }
Exemplo n.º 26
0
        public async void AsyncIfCanSeekIsFalseLengthAndPositionShouldNotBeCalled()
        {
            var baseStream = new DelegateStream(
                canReadFunc: () => true,
                canSeekFunc: () => false,
                readFunc: (buffer, offset, count) => 0);
            var trackingStream = new CallTrackingStream(baseStream);

            var dest = Stream.Null;
            await trackingStream.CopyToAsync(dest);

            Assert.InRange(trackingStream.TimesCalled(nameof(trackingStream.CanSeek)), 0, 1);
            Assert.Equal(0, trackingStream.TimesCalled(nameof(trackingStream.Length)));
            Assert.Equal(0, trackingStream.TimesCalled(nameof(trackingStream.Position)));
            Assert.Equal(1, trackingStream.TimesCalled(nameof(trackingStream.CopyToAsync)));

            Assert.Same(dest, trackingStream.CopyToAsyncDestination);
            Assert.InRange(trackingStream.CopyToAsyncBufferSize, 1, int.MaxValue);
            Assert.Equal(CancellationToken.None, trackingStream.CopyToAsyncCancellationToken);
        }
Exemplo n.º 27
0
        public async void AsyncIfLengthMinusPositionPositiveOverflowsBufferSizeShouldStillBePositive(long length, long position)
        {
            var baseStream = new DelegateStream(
                canReadFunc: () => true,
                canSeekFunc: () => true,
                lengthFunc: () => length,
                positionGetFunc: () => position,
                readFunc: (buffer, offset, count) => 0);
            var trackingStream = new CallTrackingStream(baseStream);

            var dest = Stream.Null;
            await trackingStream.CopyToAsync(dest);

            // Note: We can't check how many times ReadAsync was called
            // here, since trackingStream overrides CopyToAsync and forwards
            // to the inner (non-tracking) stream for the implementation

            Assert.Same(dest, trackingStream.CopyToAsyncDestination);
            Assert.InRange(trackingStream.CopyToAsyncBufferSize, 1, int.MaxValue);
            Assert.Equal(CancellationToken.None, trackingStream.CopyToAsyncCancellationToken);
        }
Exemplo n.º 28
0
        public static void MemoryStream_CopyTo_Invalid()
        {
            MemoryStream memoryStream;

            using (memoryStream = new MemoryStream())
            {
                AssertExtensions.Throws <ArgumentNullException>("destination", () => memoryStream.CopyTo(destination: null));

                // Validate the destination parameter first.
                AssertExtensions.Throws <ArgumentNullException>("destination", () => memoryStream.CopyTo(destination: null, bufferSize: 0));
                AssertExtensions.Throws <ArgumentNullException>("destination", () => memoryStream.CopyTo(destination: null, bufferSize: -1));

                // Then bufferSize.
                AssertExtensions.Throws <ArgumentOutOfRangeException>("bufferSize", () => memoryStream.CopyTo(Stream.Null, bufferSize: 0)); // 0-length buffer doesn't make sense.
                AssertExtensions.Throws <ArgumentOutOfRangeException>("bufferSize", () => memoryStream.CopyTo(Stream.Null, bufferSize: -1));
            }

            // After the Stream is disposed, we should fail on all CopyTos.
            AssertExtensions.Throws <ArgumentOutOfRangeException>("bufferSize", () => memoryStream.CopyTo(Stream.Null, bufferSize: 0)); // Not before bufferSize is validated.
            AssertExtensions.Throws <ArgumentOutOfRangeException>("bufferSize", () => memoryStream.CopyTo(Stream.Null, bufferSize: -1));

            MemoryStream disposedStream = memoryStream;

            // We should throw first for the source being disposed...
            Assert.Throws <ObjectDisposedException>(() => memoryStream.CopyTo(disposedStream, 1));

            // Then for the destination being disposed.
            memoryStream = new MemoryStream();
            Assert.Throws <ObjectDisposedException>(() => memoryStream.CopyTo(disposedStream, 1));

            // Then we should check whether we can't read but can write, which isn't possible for non-subclassed MemoryStreams.

            // THen we should check whether the destination can read but can't write.
            var readOnlyStream = new DelegateStream(
                canReadFunc: () => true,
                canWriteFunc: () => false
                );

            Assert.Throws <NotSupportedException>(() => memoryStream.CopyTo(readOnlyStream, 1));
        }
Exemplo n.º 29
0
        public void TestAggregateStream()
        {
            const string string1 = "Hello, world!", string2 = " This is the second stream!", string3 = " And this is the third.";
            MemoryStream s1 = new MemoryStream(Encoding.UTF8.GetBytes(string1));
            MemoryStream s2 = new MemoryStream(Encoding.UTF8.GetBytes(string2));
            MemoryStream s3 = new MemoryStream(Encoding.UTF8.GetBytes(string3));

            byte[] allBytes = Encoding.UTF8.GetBytes(string1 + string2 + string3), allBytes2 = new byte[allBytes.Length];

            // we'll also test the delegate stream
            DelegateStream stream = new DelegateStream(new AggregateStream(s1, s2, s3), true);

            Assert.IsTrue(stream.CanRead);
            Assert.IsTrue(stream.CanSeek);
            Assert.AreEqual(s1.Length + s2.Length + s3.Length, stream.Length);
            Assert.AreEqual(0, stream.Position);

            for (int i = 0; i < allBytes.Length; i++)
            {
                Assert.AreEqual(allBytes[i], (byte)stream.ReadByte());
                Assert.AreEqual(i + 1, stream.Position);
            }
            Assert.AreEqual(-1, stream.ReadByte());

            stream.Position = 0;
            Assert.AreEqual(0, stream.Position);

            Assert.AreEqual(allBytes2.Length, stream.Read(allBytes2, 0, allBytes2.Length));
            TestHelpers.AssertArrayEquals(allBytes, allBytes2);
            Assert.AreEqual(stream.Length, stream.Position);

            stream.Seek(-stream.Length, SeekOrigin.Current);
            Assert.AreEqual(0, stream.Position);

            Assert.AreEqual(string1 + string2 + string3, new StreamReader(stream).ReadToEnd());
            Assert.AreEqual(stream.Length, stream.Position);
            stream.Seek(-stream.Length, SeekOrigin.End);
            Assert.AreEqual(0, stream.Position);
        }
Exemplo n.º 30
0
        public void IfLengthIsLessThanOrEqualToPositionCopyToShouldStillBeCalledWithAPositiveBufferSize(long length, long position)
        {
            // Streams with their Lengths <= their Positions, e.g.
            // new MemoryStream { Position = 3 }.SetLength(1)
            // should still be called CopyTo{Async} on with a
            // bufferSize of at least 1.

            var baseStream = new DelegateStream(
                canReadFunc: () => true,
                canSeekFunc: () => true,
                lengthFunc: () => length,
                positionGetFunc: () => position,
                readFunc: (buffer, offset, count) => 0);
            var trackingStream = new CallTrackingStream(baseStream);

            var dest = Stream.Null;
            trackingStream.CopyTo(dest);

            // CopyTo is not virtual, so we can't override it in
            // CallTrackingStream and record the arguments directly.
            // Instead, validate the arguments passed to Read.
            
            Assert.Equal(1, trackingStream.TimesCalled(nameof(trackingStream.Read)));

            byte[] outerBuffer = trackingStream.ReadBuffer;
            int outerOffset = trackingStream.ReadOffset;
            int outerCount = trackingStream.ReadCount;

            Assert.NotNull(outerBuffer);
            Assert.InRange(outerOffset, 0, outerBuffer.Length - outerCount);
            Assert.InRange(outerCount, 1, int.MaxValue);
        }
Exemplo n.º 31
0
        public static void MemoryStream_CopyTo_Invalid()
        {
            MemoryStream memoryStream;
            using (memoryStream = new MemoryStream())
            {
                Assert.Throws<ArgumentNullException>("destination", () => memoryStream.CopyTo(destination: null));
                
                // Validate the destination parameter first.
                Assert.Throws<ArgumentNullException>("destination", () => memoryStream.CopyTo(destination: null, bufferSize: 0));
                Assert.Throws<ArgumentNullException>("destination", () => memoryStream.CopyTo(destination: null, bufferSize: -1));

                // Then bufferSize.
                Assert.Throws<ArgumentOutOfRangeException>("bufferSize", () => memoryStream.CopyTo(Stream.Null, bufferSize: 0)); // 0-length buffer doesn't make sense.
                Assert.Throws<ArgumentOutOfRangeException>("bufferSize", () => memoryStream.CopyTo(Stream.Null, bufferSize: -1));
            }

            // After the Stream is disposed, we should fail on all CopyTos.
            Assert.Throws<ArgumentOutOfRangeException>("bufferSize", () => memoryStream.CopyTo(Stream.Null, bufferSize: 0)); // Not before bufferSize is validated.
            Assert.Throws<ArgumentOutOfRangeException>("bufferSize", () => memoryStream.CopyTo(Stream.Null, bufferSize: -1));

            MemoryStream disposedStream = memoryStream;

            // We should throw first for the source being disposed...
            Assert.Throws<ObjectDisposedException>(() => memoryStream.CopyTo(disposedStream, 1));

            // Then for the destination being disposed.
            memoryStream = new MemoryStream();
            Assert.Throws<ObjectDisposedException>(() => memoryStream.CopyTo(disposedStream, 1));

            // Then we should check whether we can't read but can write, which isn't possible for non-subclassed MemoryStreams.

            // THen we should check whether the destination can read but can't write.
            var readOnlyStream = new DelegateStream(
                canReadFunc: () => true,
                canWriteFunc: () => false
            );

            Assert.Throws<NotSupportedException>(() => memoryStream.CopyTo(readOnlyStream, 1));
        }
Exemplo n.º 32
0
        public void IfLengthMinusPositionPositiveOverflowsBufferSizeShouldStillBePositive(long length, long position)
        {
            // The new implementation of Stream.CopyTo calculates the bytes left
            // in the Stream by calling Length - Position. This can overflow to a
            // negative number, so this tests that if that happens we don't send
            // in a negative bufferSize.

            var baseStream = new DelegateStream(
                canReadFunc: () => true,
                canSeekFunc: () => true,
                lengthFunc: () => length,
                positionGetFunc: () => position,
                readFunc: (buffer, offset, count) => 0);
            var trackingStream = new CallTrackingStream(baseStream);

            var dest = Stream.Null;
            trackingStream.CopyTo(dest);

            // CopyTo is not virtual, so we can't override it in
            // CallTrackingStream and record the arguments directly.
            // Instead, validate the arguments passed to Read.
            
            Assert.Equal(1, trackingStream.TimesCalled(nameof(trackingStream.Read)));

            byte[] outerBuffer = trackingStream.ReadBuffer;
            int outerOffset = trackingStream.ReadOffset;
            int outerCount = trackingStream.ReadCount;

            Assert.NotNull(outerBuffer);
            Assert.InRange(outerOffset, 0, outerBuffer.Length - outerCount);
            Assert.InRange(outerCount, 1, int.MaxValue);
        }
Exemplo n.º 33
0
        public async void AsyncIfLengthIsLessThanOrEqualToPositionCopyToShouldStillBeCalledWithAPositiveBufferSize(long length, long position)
        {
            var baseStream = new DelegateStream(
                canReadFunc: () => true,
                canSeekFunc: () => true,
                lengthFunc: () => length,
                positionGetFunc: () => position,
                readFunc: (buffer, offset, count) => 0);
            var trackingStream = new CallTrackingStream(baseStream);

            var dest = Stream.Null;
            await trackingStream.CopyToAsync(dest);

            Assert.Same(dest, trackingStream.CopyToAsyncDestination);
            Assert.InRange(trackingStream.CopyToAsyncBufferSize, 1, int.MaxValue);
            Assert.Equal(CancellationToken.None, trackingStream.CopyToAsyncCancellationToken);
        }
Exemplo n.º 34
0
        public void IfLengthIsGreaterThanPositionAndDoesNotOverflowEverythingShouldGoNormally(long length, long position)
        {
            const int ReadLimit = 7;

            // Lambda state
            byte[] outerBuffer = null;
            int? outerOffset = null;
            int? outerCount = null;
            int readsLeft = ReadLimit;

            var srcBase = new DelegateStream(
                canReadFunc: () => true,
                canSeekFunc: () => true,
                lengthFunc: () => length,
                positionGetFunc: () => position,
                readFunc: (buffer, offset, count) =>
                {
                    Assert.NotNull(buffer);
                    Assert.InRange(offset, 0, buffer.Length - count);
                    Assert.InRange(count, 1, int.MaxValue);

                    // CopyTo should always pass in the same buffer/offset/count
                    
                    if (outerBuffer != null) Assert.Same(outerBuffer, buffer);
                    else outerBuffer = buffer;

                    if (outerOffset != null) Assert.Equal(outerOffset, offset);
                    else outerOffset = offset;

                    if (outerCount != null) Assert.Equal(outerCount, count);
                    else outerCount = count;

                    return --readsLeft; // CopyTo will call Read on this ReadLimit times before stopping 
                });

	        var src = new CallTrackingStream(srcBase);

            var destBase = new DelegateStream(
                canWriteFunc: () => true,
                writeFunc: (buffer, offset, count) =>
                {
                    Assert.Same(outerBuffer, buffer);
                    Assert.Equal(outerOffset, offset);
                    Assert.Equal(readsLeft, count);
                });

            var dest = new CallTrackingStream(destBase);
            src.CopyTo(dest);

            Assert.Equal(ReadLimit, src.TimesCalled(nameof(src.Read)));
            Assert.Equal(ReadLimit - 1, dest.TimesCalled(nameof(dest.Write)));
        }
Exemplo n.º 35
0
        public async void AsyncIfLengthMinusPositionPositiveOverflowsBufferSizeShouldStillBePositive(long length, long position)
        {
            var baseStream = new DelegateStream(
                canReadFunc: () => true,
                canSeekFunc: () => true,
                lengthFunc: () => length,
                positionGetFunc: () => position,
                readFunc: (buffer, offset, count) => 0);
            var trackingStream = new CallTrackingStream(baseStream);

            var dest = Stream.Null;
            await trackingStream.CopyToAsync(dest);

            // Note: We can't check how many times ReadAsync was called
            // here, since trackingStream overrides CopyToAsync and forwards
            // to the inner (non-tracking) stream for the implementation

            Assert.Same(dest, trackingStream.CopyToAsyncDestination);
            Assert.InRange(trackingStream.CopyToAsyncBufferSize, 1, int.MaxValue);
            Assert.Equal(CancellationToken.None, trackingStream.CopyToAsyncCancellationToken);
        }
Exemplo n.º 36
0
        public async void AsyncIfLengthIsGreaterThanPositionAndDoesNotOverflowEverythingShouldGoNormally(long length, long position)
        {
            const int ReadLimit = 7;

            // Lambda state
            byte[] outerBuffer = null;
            int? outerOffset = null;
            int? outerCount = null;
            int readsLeft = ReadLimit;

            var srcBase = new DelegateStream(
                canReadFunc: () => true,
                canSeekFunc: () => true,
                lengthFunc: () => length,
                positionGetFunc: () => position,
                readFunc: (buffer, offset, count) =>
                {
                    Assert.NotNull(buffer);
                    Assert.InRange(offset, 0, buffer.Length - count);
                    Assert.InRange(count, 1, int.MaxValue);

                    // CopyTo should always pass in the same buffer/offset/count
                    
                    if (outerBuffer != null) Assert.Same(outerBuffer, buffer);
                    else outerBuffer = buffer;

                    if (outerOffset != null) Assert.Equal(outerOffset, offset);
                    else outerOffset = offset;

                    if (outerCount != null) Assert.Equal(outerCount, count);
                    else outerCount = count;

                    return --readsLeft; // CopyTo will call Read on this ReadLimit times before stopping 
                });

	        var src = new CallTrackingStream(srcBase);

            var destBase = new DelegateStream(
                canWriteFunc: () => true,
                writeFunc: (buffer, offset, count) =>
                {
                    Assert.Same(outerBuffer, buffer);
                    Assert.Equal(outerOffset, offset);
                    Assert.Equal(readsLeft, count);
                });

            var dest = new CallTrackingStream(destBase);
            await src.CopyToAsync(dest);

            // Since we override CopyToAsync in CallTrackingStream,
            // src.Read will actually not get called ReadLimit
            // times, src.Inner.Read will. So, we just assert that
            // CopyToAsync was called once for src.

            Assert.Equal(1, src.TimesCalled(nameof(src.CopyToAsync)));
            Assert.Equal(ReadLimit - 1, dest.TimesCalled(nameof(dest.WriteAsync))); // dest.WriteAsync will still get called repeatedly
        }
Exemplo n.º 37
0
        internal void _EncryptThenMac(Stream inputStream, Stream outputStream, byte[] password, byte[] salt)
        {
            using (var rfc2898 = new Rfc2898DeriveBytes(password, salt, DefaultIteration))
            using (var algorithm = GetSymmetricAlgorithm())
            {
                algorithm.KeySize = DefaultKeySize;
                algorithm.BlockSize = DefaultBlockSize;

                var key = rfc2898.GetBytes(DefaultKeySize / 8);
                var iv = rfc2898.GetBytes(DefaultBlockSize / 8);

                long encryptedLength = 0;

                using (var transform = algorithm.CreateEncryptor(key, iv))
                using (var hasher = IncrementalHash.CreateHMAC(DefaultHashAlgorithm, password))
                using (var delegateStream = new DelegateStream(outputStream, null, (buffer, offset, count) => { encryptedLength += buffer.Length; hasher.AppendData(buffer); }))
                {
                    var hash = hasher.GetHashAndReset();
                    outputStream.Write(BitConverter.GetBytes(hash.Length), 0, HashLengthSize);
                    outputStream.Write(BitConverter.GetBytes(salt.Length), 0, SaltLengthSize);
                    outputStream.Write(BitConverter.GetBytes(encryptedLength), 0, EncryptedLengthSize);
                    outputStream.Write(hash, 0, hash.Length);
                    outputStream.Write(salt, 0, salt.Length);

                    using (var crytoStream = new CryptoStream(delegateStream, transform, CryptoStreamMode.Write))
                    {
                        foreach (var bytes in inputStream.ReadByChunk())
                            crytoStream.Write(bytes, 0, bytes.Length);
                    }

                    outputStream.Seek(HashLengthSize + SaltLengthSize, SeekOrigin.Begin);
                    outputStream.Write(BitConverter.GetBytes(encryptedLength), 0, EncryptedLengthSize);
                    outputStream.Write(hasher.GetHashAndReset(), 0, hash.Length);
                }
            }
        }
Exemplo n.º 38
0
        public void IfLengthIsGreaterThanPositionAndDoesNotOverflowEverythingShouldGoNormally(long length, long position)
        {
            const int ReadLimit = 7;

            // Lambda state
            byte[] outerBuffer = null;
            int?   outerOffset = null;
            int?   outerCount  = null;
            int    readsLeft   = ReadLimit;

            var srcBase = new DelegateStream(
                canReadFunc: () => true,
                canSeekFunc: () => true,
                lengthFunc: () => length,
                positionGetFunc: () => position,
                readFunc: (buffer, offset, count) =>
            {
                Assert.NotNull(buffer);
                Assert.InRange(offset, 0, buffer.Length - count);
                Assert.InRange(count, 1, int.MaxValue);

                // CopyTo should always pass in the same buffer/offset/count

                if (outerBuffer != null)
                {
                    Assert.Same(outerBuffer, buffer);
                }
                else
                {
                    outerBuffer = buffer;
                }

                if (outerOffset != null)
                {
                    Assert.Equal(outerOffset, offset);
                }
                else
                {
                    outerOffset = offset;
                }

                if (outerCount != null)
                {
                    Assert.Equal(outerCount, count);
                }
                else
                {
                    outerCount = count;
                }

                return(--readsLeft);    // CopyTo will call Read on this ReadLimit times before stopping
            });

            var src = new CallTrackingStream(srcBase);

            var destBase = new DelegateStream(
                canWriteFunc: () => true,
                writeFunc: (buffer, offset, count) =>
            {
                Assert.Same(outerBuffer, buffer);
                Assert.Equal(outerOffset, offset);
                Assert.Equal(readsLeft, count);
            });

            var dest = new CallTrackingStream(destBase);

            src.CopyTo(dest);

            Assert.Equal(ReadLimit, src.TimesCalled(nameof(src.Read)));
            Assert.Equal(ReadLimit - 1, dest.TimesCalled(nameof(dest.Write)));
        }
Exemplo n.º 39
0
        public async void AsyncIfLengthIsGreaterThanPositionAndDoesNotOverflowEverythingShouldGoNormally(long length, long position)
        {
            const int ReadLimit = 7;

            // Lambda state
            byte[] outerBuffer = null;
            int?   outerOffset = null;
            int?   outerCount  = null;
            int    readsLeft   = ReadLimit;

            var srcBase = new DelegateStream(
                canReadFunc: () => true,
                canSeekFunc: () => true,
                lengthFunc: () => length,
                positionGetFunc: () => position,
                readFunc: (buffer, offset, count) =>
            {
                Assert.NotNull(buffer);
                Assert.InRange(offset, 0, buffer.Length - count);
                Assert.InRange(count, 1, int.MaxValue);

                // CopyTo should always pass in the same buffer/offset/count

                if (outerBuffer != null)
                {
                    Assert.Same(outerBuffer, buffer);
                }
                else
                {
                    outerBuffer = buffer;
                }

                if (outerOffset != null)
                {
                    Assert.Equal(outerOffset, offset);
                }
                else
                {
                    outerOffset = offset;
                }

                if (outerCount != null)
                {
                    Assert.Equal(outerCount, count);
                }
                else
                {
                    outerCount = count;
                }

                return(--readsLeft);    // CopyTo will call Read on this ReadLimit times before stopping
            });

            var src = new CallTrackingStream(srcBase);

            var destBase = new DelegateStream(
                canWriteFunc: () => true,
                writeFunc: (buffer, offset, count) =>
            {
                Assert.Same(outerBuffer, buffer);
                Assert.Equal(outerOffset, offset);
                Assert.Equal(readsLeft, count);
            });

            var dest = new CallTrackingStream(destBase);
            await src.CopyToAsync(dest);

            // Since we override CopyToAsync in CallTrackingStream,
            // src.Read will actually not get called ReadLimit
            // times, src.Inner.Read will. So, we just assert that
            // CopyToAsync was called once for src.

            Assert.Equal(1, src.TimesCalled(nameof(src.CopyToAsync)));
            Assert.Equal(ReadLimit - 1, dest.TimesCalled(nameof(dest.WriteAsync))); // dest.WriteAsync will still get called repeatedly
        }
Exemplo n.º 40
0
        public void SetActivityResult(int requestCode, Result resultCode, Intent data)
        {
            var context = contextFactory();

            if (context == null)
            {
                return;
            }

            if (requestCode == ImagePickerCode)
            {
                if (imageChooserTcs == null)
                {
                    return;
                }
                if (resultCode != Result.Ok)
                {
                    imageChooserTcs.TrySetResult(null); return;
                }

                var selectedImageUri = data?.Data ?? _imagePath;
                if (selectedImageUri == null)
                {
                    imageChooserTcs.TrySetResult(null); return;
                }

                try
                {
                    using (var input = new DelegateStream(() => context.ContentResolver.OpenInputStream(selectedImageUri)))
                        using (var output = context.ContentResolver.OpenOutputStream(_compressedPath, "w"))
                            using (var bitmap = CreateBitmap(input, _maxSize))
                            {
                                if (bitmap == null)
                                {
                                    imageChooserTcs.TrySetResult(null);
                                    return;
                                }

                                try
                                {
                                    if (!bitmap.Compress(Bitmap.CompressFormat.Jpeg, 80, output))
                                    {
                                        imageChooserTcs.TrySetResult(null);
                                        return;
                                    }
                                }
                                finally
                                {
                                    bitmap.Recycle();
                                }
                            }

                    var compressed = _compressedPath;

                    imageChooserTcs.TrySetResult(new DelegateStream(
                                                     () => context.ContentResolver.OpenInputStream(compressed),
                                                     () => new Java.IO.File(compressed.Path).Delete()));
                }
                catch
                {
                    imageChooserTcs.TrySetResult(null);
                }
                finally
                {
                    if (_imagePath == selectedImageUri)
                    {
                        new Java.IO.File(selectedImageUri.Path).Delete();
                    }

                    GC.Collect();
                    Java.Lang.Runtime.GetRuntime().Gc();
                }
            }
        }