예제 #1
0
        public 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;

            trackingStream.CopyTo(dest);

            var times = trackingStream.TimesCalled(nameof(trackingStream.Length));

            Assert.True(times >= 0 && times <= 1);

            times = trackingStream.TimesCalled(nameof(trackingStream.Position));
            Assert.True(times >= 0 && times <= 1);
        }
예제 #2
0
        public void IfLengthIsLessThanOrEqualToPositionCopyToShouldStillBeCalledWithAPositiveBufferSize()
        {
            var data = LengthIsLessThanOrEqualToPosition();

            foreach (var item in data)
            {
                long length   = (long)item[0];
                long position = (long)item[1];

                // 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.AreEqual(1, trackingStream.TimesCalled(nameof(trackingStream.Read)));

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

                Assert.NotNull(outerBuffer);
                Assert.True(outerOffset >= 0 && outerOffset <= (outerBuffer.Length - outerCount));
                Assert.True(outerCount >= 1 && outerCount <= int.MaxValue);
            }
        }
예제 #3
0
        public void IfLengthMinusPositionPositiveOverflowsBufferSizeShouldStillBePositive()
        {
            var data = LengthMinusPositionPositiveOverflows();

            foreach (var item in data)
            {
                long length   = (long)item[0];
                long position = (long)item[1];
                // 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.AreEqual(1, trackingStream.TimesCalled(nameof(trackingStream.Read)));

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

                Assert.NotNull(outerBuffer);
                Assert.True(outerOffset >= 0 && outerOffset <= (outerBuffer.Length - outerCount));
                Assert.True(outerCount >= 1 && outerCount <= int.MaxValue);
            }
        }
예제 #4
0
        public void IfLengthIsGreaterThanPositionAndDoesNotOverflowEverythingShouldGoNormally()
        {
            const int ReadLimit = 7;

            var data = LengthIsGreaterThanPositionAndDoesNotOverflow();

            foreach (var item in data)
            {
                long length   = (long)item[0];
                long position = (long)item[1];

                // 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.True(offset >= 0 && offset <= (buffer.Length - count));
                    Assert.True(count >= 1 && count <= int.MaxValue);

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

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

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

                    if (outerCount != null)
                    {
                        Assert.AreEqual(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.AreDeepEqual(outerBuffer, buffer);
                    Assert.AreEqual(outerOffset, offset);
                    Assert.AreEqual(readsLeft, count);
                });

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

                Assert.AreEqual(ReadLimit, src.TimesCalled(nameof(src.Read)));
                Assert.AreEqual(ReadLimit - 1, dest.TimesCalled(nameof(dest.Write)));
            }
        }