Skip to content

Commit 6332b80

Browse files
committed
Naive implementation of KaitaiPipeReaderAsyncStream
1 parent 9812fe7 commit 6332b80

File tree

10 files changed

+980
-5
lines changed

10 files changed

+980
-5
lines changed
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
using System.Threading.Tasks;
2+
using Kaitai.Async;
3+
using Xunit;
4+
5+
namespace Kaitai.Struct.Runtime.Async.Tests.PipeReader
6+
{
7+
public class KaitaiPipeReaderAsyncStreamBaseTests
8+
{
9+
[Fact]
10+
public async Task AlignToByte_Test()
11+
{
12+
//Arrange
13+
var kaitaiStreamSUT = new KaitaiPipeReaderAsyncStream(new byte[]{0b_1000_0000});
14+
15+
var read = await kaitaiStreamSUT.ReadBitsIntAsync(1);
16+
Assert.Equal(1u, read);
17+
18+
//Act
19+
kaitaiStreamSUT.AlignToByte();
20+
//Assert
21+
Assert.Equal(1, kaitaiStreamSUT.Pos);
22+
}
23+
24+
[Theory]
25+
[InlineData(true, 0, 0)]
26+
[InlineData(false, 1, 0)]
27+
[InlineData(false, 1, 1)]
28+
[InlineData(false, 1, 2)]
29+
[InlineData(false, 1, 3)]
30+
[InlineData(false, 1, 4)]
31+
[InlineData(false, 1, 5)]
32+
[InlineData(false, 1, 6)]
33+
[InlineData(false, 1, 7)]
34+
[InlineData(true, 1, 8)]
35+
public async Task Eof_Test(bool shouldBeEof, int streamSize, int readBitsAmount)
36+
{
37+
var kaitaiStreamSUT = new KaitaiPipeReaderAsyncStream(new byte[streamSize]);
38+
39+
await kaitaiStreamSUT.ReadBitsIntAsync(readBitsAmount);
40+
41+
if (shouldBeEof)
42+
Assert.True(kaitaiStreamSUT.IsEof);
43+
else
44+
Assert.False(kaitaiStreamSUT.IsEof);
45+
}
46+
47+
[Theory]
48+
[InlineData(0, 0)]
49+
[InlineData(1, 1)]
50+
public async Task Pos_ByRead_Test(int expectedPos, int readBitsAmount)
51+
{
52+
var kaitaiStreamSUT = new KaitaiPipeReaderAsyncStream(new byte[1]);
53+
54+
await kaitaiStreamSUT.ReadBytesAsync(readBitsAmount);
55+
56+
Assert.Equal(expectedPos, kaitaiStreamSUT.Pos);
57+
}
58+
59+
[Theory]
60+
[InlineData(0, 0)]
61+
[InlineData(1, 1)]
62+
public async Task Pos_BySeek_Test(int expectedPos, int position)
63+
{
64+
var kaitaiStreamSUT = new KaitaiPipeReaderAsyncStream(new byte[1]);
65+
66+
await kaitaiStreamSUT.SeekAsync(position);
67+
68+
Assert.Equal(expectedPos, kaitaiStreamSUT.Pos);
69+
}
70+
71+
[Theory]
72+
[InlineData(0)]
73+
[InlineData(1)]
74+
public void Size_Test(int streamSize)
75+
{
76+
var kaitaiStreamSUT = new KaitaiPipeReaderAsyncStream(new byte[streamSize]);
77+
78+
Assert.Equal(streamSize, kaitaiStreamSUT.Size);
79+
}
80+
81+
[Fact]
82+
public void EmptyStream_NoRead_NoSeek_IsEof_ShouldBe_True()
83+
{
84+
var kaitaiStreamSUT = new KaitaiPipeReaderAsyncStream(new byte[0]);
85+
86+
Assert.True(kaitaiStreamSUT.IsEof);
87+
}
88+
89+
[Fact]
90+
public void EmptyStream_NoRead_NoSeek_Pos_ShouldBe_0()
91+
{
92+
var kaitaiStreamSUT = new KaitaiPipeReaderAsyncStream(new byte[0]);
93+
94+
Assert.Equal(0, kaitaiStreamSUT.Pos);
95+
}
96+
}
97+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
using System.Threading.Tasks;
2+
using Kaitai.Async;
3+
using Xunit;
4+
5+
namespace Kaitai.Struct.Runtime.Async.Tests.PipeReader
6+
{
7+
public class ReadBits
8+
{
9+
[Theory]
10+
[MemberData(nameof(BitsData.BitsBeData), MemberType = typeof(BitsData))]
11+
public async Task ReadBitsIntAsync_Test(ulong expected, byte[] streamContent, int bitsCount)
12+
{
13+
var kaitaiStreamSUT = new KaitaiPipeReaderAsyncStream(streamContent);
14+
15+
Assert.Equal(expected, await kaitaiStreamSUT.ReadBitsIntAsync(bitsCount));
16+
}
17+
18+
[Theory]
19+
[MemberData(nameof(BitsData.BitsLeData), MemberType = typeof(BitsData))]
20+
public async Task ReadBitsIntLeAsync_Test(ulong expected, byte[] streamContent, int bitsCount)
21+
{
22+
var kaitaiStreamSUT = new KaitaiPipeReaderAsyncStream(streamContent);
23+
24+
Assert.Equal(expected, await kaitaiStreamSUT.ReadBitsIntLeAsync(bitsCount));
25+
}
26+
}
27+
}
Lines changed: 208 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,208 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.IO;
4+
using System.Linq;
5+
using System.Text;
6+
using System.Threading.Tasks;
7+
using Kaitai.Async;
8+
using Xunit;
9+
10+
namespace Kaitai.Struct.Runtime.Async.Tests.PipeReader
11+
{
12+
public class ReadBytesAsync
13+
{
14+
public static IEnumerable<object[]> BytesData =>
15+
new List<(byte[] streamContent, int bytesCount)>
16+
{
17+
(new byte[] {0b_1101_0101}, 0),
18+
(new byte[] {0b_1101_0101}, 1),
19+
(new byte[] {0b_1101_0101, 0b_1101_0101}, 1),
20+
(new byte[] {0b_1101_0101, 0b_1101_0101}, 2),
21+
}.Select(t => new object[] { t.streamContent, t.bytesCount });
22+
23+
24+
[Theory]
25+
[MemberData(nameof(BytesData))]
26+
public async Task ReadBytesAsync_long_Test(byte[] streamContent, long bytesCount)
27+
{
28+
var kaitaiStreamSUT = new KaitaiPipeReaderAsyncStream(streamContent);
29+
30+
Assert.Equal(streamContent.Take((int)bytesCount), await kaitaiStreamSUT.ReadBytesAsync(bytesCount));
31+
}
32+
33+
[Theory]
34+
[MemberData(nameof(BytesData))]
35+
public async Task ReadBytesAsync_ulong_Test(byte[] streamContent, ulong bytesCount)
36+
{
37+
var kaitaiStreamSUT = new KaitaiPipeReaderAsyncStream(streamContent);
38+
39+
Assert.Equal(streamContent.Take((int)bytesCount), await kaitaiStreamSUT.ReadBytesAsync(bytesCount));
40+
}
41+
42+
[Fact]
43+
public async Task ReadBytesAsyncLong_NegativeInvoke_ThrowsArgumentOutOfRangeException()
44+
{
45+
var kaitaiStreamSUT = new KaitaiPipeReaderAsyncStream(new byte[0]);
46+
47+
await Assert.ThrowsAsync<ArgumentOutOfRangeException>(async () =>
48+
await kaitaiStreamSUT.ReadBytesAsync((long) -1));
49+
}
50+
51+
[Fact]
52+
public async Task ReadBytesAsyncLong_LargerThanInt32Invoke_ThrowsArgumentOutOfRangeException()
53+
{
54+
var kaitaiStreamSUT = new KaitaiPipeReaderAsyncStream(new byte[0]);
55+
56+
await Assert.ThrowsAsync<ArgumentOutOfRangeException>(async () =>
57+
await kaitaiStreamSUT.ReadBytesAsync((long)Int32.MaxValue+1));
58+
}
59+
60+
[Fact]
61+
public async Task ReadBytesAsyncLong_LargerThanBufferInvoke_ThrowsArgumentOutOfRangeException()
62+
{
63+
var kaitaiStreamSUT = new KaitaiPipeReaderAsyncStream(new byte[0]);
64+
65+
await Assert.ThrowsAsync<EndOfStreamException>(async () =>
66+
await kaitaiStreamSUT.ReadBytesAsync((long)1));
67+
}
68+
69+
[Fact]
70+
public async Task ReadBytesAsyncULong_LargerThanInt32Invoke_ThrowsArgumentOutOfRangeException()
71+
{
72+
var kaitaiStreamSUT = new KaitaiPipeReaderAsyncStream(new byte[0]);
73+
74+
await Assert.ThrowsAsync<ArgumentOutOfRangeException>(async () =>
75+
await kaitaiStreamSUT.ReadBytesAsync((ulong)Int32.MaxValue + 1));
76+
}
77+
78+
[Fact]
79+
public async Task ReadBytesAsyncULong_LargerThanBufferInvoke_ThrowsArgumentOutOfRangeException()
80+
{
81+
var kaitaiStreamSUT = new KaitaiPipeReaderAsyncStream(new byte[0]);
82+
83+
await Assert.ThrowsAsync<EndOfStreamException>(async () =>
84+
await kaitaiStreamSUT.ReadBytesAsync((ulong)1));
85+
}
86+
87+
public static IEnumerable<object[]> StringData =>
88+
new List<string>
89+
{
90+
"",
91+
"ABC",
92+
"ABCDEFGHIJKLMNOPQRSTUVWXYZ",
93+
}.Select(t => new []{ Encoding.ASCII.GetBytes(t)});
94+
95+
96+
[Theory]
97+
[MemberData(nameof(StringData))]
98+
public async Task ReadBytesFullAsync_Test(byte[] streamContent)
99+
{
100+
var kaitaiStreamSUT = new KaitaiPipeReaderAsyncStream(streamContent);
101+
102+
Assert.Equal(streamContent, await kaitaiStreamSUT.ReadBytesFullAsync());
103+
}
104+
105+
[Theory]
106+
[MemberData(nameof(StringData))]
107+
public async Task EnsureFixedContentsAsync_Test(byte[] streamContent)
108+
{
109+
var kaitaiStreamSUT = new KaitaiPipeReaderAsyncStream(streamContent);
110+
111+
Assert.Equal(streamContent, await kaitaiStreamSUT.EnsureFixedContentsAsync(streamContent));
112+
}
113+
114+
[Theory]
115+
[MemberData(nameof(StringData))]
116+
public async Task EnsureFixedContentsAsync_ThrowsIfByteIsChanged(byte[] streamContent)
117+
{
118+
if(streamContent.Length == 0) return;
119+
120+
var kaitaiStreamSUT = new KaitaiPipeReaderAsyncStream(streamContent);
121+
122+
var expected = streamContent.ToArray();
123+
expected[0] = (byte)~expected[0];
124+
125+
await Assert.ThrowsAsync<Exception>(async () => await kaitaiStreamSUT.EnsureFixedContentsAsync(expected));
126+
}
127+
128+
public static IEnumerable<object[]> StringWithTerminatorsData =>
129+
new List<(string streamContent, string expected, char terminator, bool isPresent, bool shouldInclude)>
130+
{
131+
("", "", '\0', false, false),
132+
("", "", '\0', false, true),
133+
134+
("ABC", "ABC", '\0', false, false),
135+
("ABC", "ABC", '\0', false, true),
136+
137+
("ABC", "", 'A', true, false),
138+
("ABC", "A", 'A', true, true),
139+
140+
("ABC", "A", 'B', true, false),
141+
("ABC", "AB", 'B', true, true),
142+
143+
("ABC", "AB", 'C', true, false),
144+
("ABC", "ABC", 'C', true, true),
145+
}.Select(t => new[] { Encoding.ASCII.GetBytes(t.streamContent), Encoding.ASCII.GetBytes(t.expected), (object)(byte)t.terminator, t.isPresent, t.shouldInclude});
146+
147+
[Theory]
148+
[MemberData(nameof(StringWithTerminatorsData))]
149+
public async Task ReadBytesTermAsync(byte[] streamContent, byte[] expected, byte terminator, bool _, bool shouldInclude)
150+
{
151+
var kaitaiStreamSUT = new KaitaiPipeReaderAsyncStream(streamContent);
152+
153+
Assert.Equal(expected, await kaitaiStreamSUT.ReadBytesTermAsync(terminator, shouldInclude, false, false));
154+
}
155+
156+
[Theory]
157+
[MemberData(nameof(StringWithTerminatorsData))]
158+
public async Task ReadBytesTermAsync_ThrowsIsTerminatorNotPresent(byte[] streamContent, byte[] expected, byte terminator, bool terminatorIsPresent, bool shouldInclude)
159+
{
160+
var kaitaiStreamSUT = new KaitaiPipeReaderAsyncStream(streamContent);
161+
162+
if(terminatorIsPresent) return;
163+
164+
await Assert.ThrowsAsync<EndOfStreamException>(async()=> await kaitaiStreamSUT.ReadBytesTermAsync(terminator, shouldInclude, false, true));
165+
}
166+
167+
[Theory]
168+
[MemberData(nameof(StringWithTerminatorsData))]
169+
public async Task ReadBytesTermAsync_ShouldNotConsumeTerminator(byte[] streamContent, byte[] expected, byte terminator, bool terminatorIsPresent, bool shouldInclude)
170+
{
171+
//Arrange
172+
var kaitaiStreamSUT = new KaitaiPipeReaderAsyncStream(streamContent);
173+
174+
//Act
175+
await kaitaiStreamSUT.ReadBytesTermAsync(terminator, shouldInclude, false, false);
176+
177+
//Assert
178+
var amountToConsume = expected.Length;
179+
if (expected.Length > 0 && shouldInclude && terminatorIsPresent)
180+
{
181+
amountToConsume--;
182+
}
183+
184+
Assert.Equal(amountToConsume, kaitaiStreamSUT.Pos);
185+
}
186+
187+
[Theory]
188+
[MemberData(nameof(StringWithTerminatorsData))]
189+
public async Task ReadBytesTermAsync_ShouldConsumeTerminator(byte[] streamContent, byte[] expected, byte terminator, bool terminatorIsPresent, bool shouldInclude)
190+
{
191+
//Arrange
192+
var kaitaiStreamSUT = new KaitaiPipeReaderAsyncStream(streamContent);
193+
194+
//Act
195+
await kaitaiStreamSUT.ReadBytesTermAsync(terminator, shouldInclude, true, false);
196+
197+
//Assert
198+
var amountToConsume = expected.Length;
199+
if (!shouldInclude && terminatorIsPresent)
200+
{
201+
amountToConsume++;
202+
}
203+
204+
Assert.Equal(amountToConsume, kaitaiStreamSUT.Pos);
205+
}
206+
207+
}
208+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
using System.Linq;
2+
using System.Threading.Tasks;
3+
using Kaitai.Async;
4+
using Xunit;
5+
6+
namespace Kaitai.Struct.Runtime.Async.Tests.PipeReader
7+
{
8+
public class ReadDecimal
9+
{
10+
[Theory]
11+
[MemberData(nameof(DecimalData.Decimal4Data), MemberType = typeof(DecimalData))]
12+
public async Task ReadF4beAsync_Test(float expected, byte[] streamContent)
13+
{
14+
var kaitaiStreamSUT = new KaitaiPipeReaderAsyncStream(streamContent.Reverse().ToArray());
15+
16+
Assert.Equal(expected, await kaitaiStreamSUT.ReadF4beAsync());
17+
}
18+
19+
[Theory]
20+
[MemberData(nameof(DecimalData.Decimal4Data), MemberType = typeof(DecimalData))]
21+
public async Task ReadF4leAsync_Test(float expected, byte[] streamContent)
22+
{
23+
var kaitaiStreamSUT = new KaitaiPipeReaderAsyncStream(streamContent);
24+
25+
Assert.Equal(expected, await kaitaiStreamSUT.ReadF4leAsync());
26+
}
27+
28+
[Theory]
29+
[MemberData(nameof(DecimalData.Decimal8Data), MemberType = typeof(DecimalData))]
30+
public async Task ReadF8beAsync_Test(double expected, byte[] streamContent)
31+
{
32+
var kaitaiStreamSUT = new KaitaiPipeReaderAsyncStream(streamContent.Reverse().ToArray());
33+
34+
Assert.Equal(expected, await kaitaiStreamSUT.ReadF8beAsync());
35+
}
36+
37+
[Theory]
38+
[MemberData(nameof(DecimalData.Decimal8Data), MemberType = typeof(DecimalData))]
39+
public async Task ReadF8leAsync_Test(double expected, byte[] streamContent)
40+
{
41+
var kaitaiStreamSUT = new KaitaiPipeReaderAsyncStream(streamContent);
42+
43+
Assert.Equal(expected, await kaitaiStreamSUT.ReadF8leAsync());
44+
}
45+
}
46+
}

0 commit comments

Comments
 (0)