Skip to content

Commit 7eef9f2

Browse files
committed
Add unit tests for buffered StreamExtensions.Read<T>
1 parent fe6362b commit 7eef9f2

File tree

1 file changed

+79
-1
lines changed

1 file changed

+79
-1
lines changed

tests/CommunityToolkit.HighPerformance.UnitTests/Extensions/Test_StreamExtensions.cs

Lines changed: 79 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
using System;
66
using System.IO;
7-
using CommunityToolkit.HighPerformance;
87
using Microsoft.VisualStudio.TestTools.UnitTesting;
98

109
namespace CommunityToolkit.HighPerformance.UnitTests.Extensions;
@@ -37,4 +36,83 @@ public void Test_StreamExtensions_ReadWrite()
3736

3837
_ = Assert.ThrowsException<InvalidOperationException>(() => stream.Read<long>());
3938
}
39+
40+
// See https://github.com/CommunityToolkit/dotnet/issues/513
41+
[TestMethod]
42+
public void Test_StreamExtensions_ReadWrite_WithBufferedStream()
43+
{
44+
Stream stream = new BufferedStream();
45+
46+
stream.Write(true);
47+
stream.Write(42);
48+
stream.Write(3.14f);
49+
stream.Write(unchecked(uint.MaxValue * 324823489204ul));
50+
51+
stream.Position = 0;
52+
53+
Assert.AreEqual(true, stream.Read<bool>());
54+
Assert.AreEqual(42, stream.Read<int>());
55+
Assert.AreEqual(3.14f, stream.Read<float>());
56+
Assert.AreEqual(unchecked(uint.MaxValue * 324823489204ul), stream.Read<ulong>());
57+
58+
_ = Assert.ThrowsException<InvalidOperationException>(() => stream.Read<long>());
59+
}
60+
61+
private sealed class BufferedStream : MemoryStream
62+
{
63+
private ReadOnlyMemory<byte> bufferedBytes;
64+
65+
public override int Read(byte[] buffer, int offset, int count)
66+
{
67+
if (this.bufferedBytes.IsEmpty)
68+
{
69+
this.bufferedBytes = ReadMoreBytes();
70+
}
71+
72+
int bytesToCopy = Math.Min(this.bufferedBytes.Length, count);
73+
74+
this.bufferedBytes.Span.Slice(0, bytesToCopy).CopyTo(buffer.AsSpan(offset, count));
75+
this.bufferedBytes = this.bufferedBytes.Slice(bytesToCopy);
76+
77+
return bytesToCopy;
78+
}
79+
80+
#if NET6_0_OR_GREATER
81+
public override int Read(Span<byte> buffer)
82+
{
83+
if (this.bufferedBytes.IsEmpty)
84+
{
85+
this.bufferedBytes = ReadMoreBytes();
86+
}
87+
88+
int bytesToCopy = Math.Min(this.bufferedBytes.Length, buffer.Length);
89+
90+
this.bufferedBytes.Span.Slice(0, bytesToCopy).CopyTo(buffer);
91+
this.bufferedBytes = this.bufferedBytes.Slice(bytesToCopy);
92+
93+
return bytesToCopy;
94+
}
95+
#endif
96+
97+
private byte[] ReadMoreBytes()
98+
{
99+
byte[] array = new byte[3];
100+
int bytesOffset = 0;
101+
102+
do
103+
{
104+
int bytesRead = base.Read(array, bytesOffset, 3 - bytesOffset);
105+
106+
bytesOffset += bytesRead;
107+
108+
if (bytesRead == 0)
109+
{
110+
return array.AsSpan(0, bytesOffset).ToArray();
111+
}
112+
}
113+
while (bytesOffset < 3);
114+
115+
return array;
116+
}
117+
}
40118
}

0 commit comments

Comments
 (0)