Serenity Operating System
1/*
2 * Copyright (c) 2023, Tim Schumacher <timschumi@gmx.de>
3 *
4 * SPDX-License-Identifier: BSD-2-Clause
5 */
6
7#include <AK/BitStream.h>
8#include <AK/MemoryStream.h>
9#include <LibTest/TestCase.h>
10
11// Note: This does not do any checks on the internal representation, it just ensures that the behavior of the input and output streams match.
12TEST_CASE(little_endian_bit_stream_input_output_match)
13{
14 auto memory_stream = make<AllocatingMemoryStream>();
15
16 // Note: The bit stream only ever reads from/writes to the underlying stream in one byte chunks,
17 // so testing with sizes that will not trigger a write will yield unexpected results.
18 LittleEndianOutputBitStream bit_write_stream { MaybeOwned<Stream>(*memory_stream) };
19 LittleEndianInputBitStream bit_read_stream { MaybeOwned<Stream>(*memory_stream) };
20
21 // Test two mirrored chunks of a fully mirrored pattern to check that we are not dropping bits.
22 {
23 MUST(bit_write_stream.write_bits(0b1111u, 4));
24 MUST(bit_write_stream.write_bits(0b1111u, 4));
25 auto result = MUST(bit_read_stream.read_bits(4));
26 EXPECT_EQ(0b1111u, result);
27 result = MUST(bit_read_stream.read_bits(4));
28 EXPECT_EQ(0b1111u, result);
29 }
30 {
31 MUST(bit_write_stream.write_bits(0b0000u, 4));
32 MUST(bit_write_stream.write_bits(0b0000u, 4));
33 auto result = MUST(bit_read_stream.read_bits(4));
34 EXPECT_EQ(0b0000u, result);
35 result = MUST(bit_read_stream.read_bits(4));
36 EXPECT_EQ(0b0000u, result);
37 }
38
39 // Test two mirrored chunks of a non-mirrored pattern to check that we are writing bits within a pattern in the correct order.
40 {
41 MUST(bit_write_stream.write_bits(0b1000u, 4));
42 MUST(bit_write_stream.write_bits(0b1000u, 4));
43 auto result = MUST(bit_read_stream.read_bits(4));
44 EXPECT_EQ(0b1000u, result);
45 result = MUST(bit_read_stream.read_bits(4));
46 EXPECT_EQ(0b1000u, result);
47 }
48
49 // Test two different chunks to check that we are not confusing their order.
50 {
51 MUST(bit_write_stream.write_bits(0b1000u, 4));
52 MUST(bit_write_stream.write_bits(0b0100u, 4));
53 auto result = MUST(bit_read_stream.read_bits(4));
54 EXPECT_EQ(0b1000u, result);
55 result = MUST(bit_read_stream.read_bits(4));
56 EXPECT_EQ(0b0100u, result);
57 }
58
59 // Test a pattern that spans multiple bytes.
60 {
61 MUST(bit_write_stream.write_bits(0b1101001000100001u, 16));
62 auto result = MUST(bit_read_stream.read_bits(16));
63 EXPECT_EQ(0b1101001000100001u, result);
64 }
65}
66
67// Note: This does not do any checks on the internal representation, it just ensures that the behavior of the input and output streams match.
68TEST_CASE(big_endian_bit_stream_input_output_match)
69{
70 auto memory_stream = make<AllocatingMemoryStream>();
71
72 // Note: The bit stream only ever reads from/writes to the underlying stream in one byte chunks,
73 // so testing with sizes that will not trigger a write will yield unexpected results.
74 BigEndianOutputBitStream bit_write_stream { MaybeOwned<Stream>(*memory_stream) };
75 BigEndianInputBitStream bit_read_stream { MaybeOwned<Stream>(*memory_stream) };
76
77 // Test two mirrored chunks of a fully mirrored pattern to check that we are not dropping bits.
78 {
79 MUST(bit_write_stream.write_bits(0b1111u, 4));
80 MUST(bit_write_stream.write_bits(0b1111u, 4));
81 auto result = MUST(bit_read_stream.read_bits(4));
82 EXPECT_EQ(0b1111u, result);
83 result = MUST(bit_read_stream.read_bits(4));
84 EXPECT_EQ(0b1111u, result);
85 }
86 {
87 MUST(bit_write_stream.write_bits(0b0000u, 4));
88 MUST(bit_write_stream.write_bits(0b0000u, 4));
89 auto result = MUST(bit_read_stream.read_bits(4));
90 EXPECT_EQ(0b0000u, result);
91 result = MUST(bit_read_stream.read_bits(4));
92 EXPECT_EQ(0b0000u, result);
93 }
94
95 // Test two mirrored chunks of a non-mirrored pattern to check that we are writing bits within a pattern in the correct order.
96 {
97 MUST(bit_write_stream.write_bits(0b1000u, 4));
98 MUST(bit_write_stream.write_bits(0b1000u, 4));
99 auto result = MUST(bit_read_stream.read_bits(4));
100 EXPECT_EQ(0b1000u, result);
101 result = MUST(bit_read_stream.read_bits(4));
102 EXPECT_EQ(0b1000u, result);
103 }
104
105 // Test two different chunks to check that we are not confusing their order.
106 {
107 MUST(bit_write_stream.write_bits(0b1000u, 4));
108 MUST(bit_write_stream.write_bits(0b0100u, 4));
109 auto result = MUST(bit_read_stream.read_bits(4));
110 EXPECT_EQ(0b1000u, result);
111 result = MUST(bit_read_stream.read_bits(4));
112 EXPECT_EQ(0b0100u, result);
113 }
114
115 // Test a pattern that spans multiple bytes.
116 {
117 MUST(bit_write_stream.write_bits(0b1101001000100001u, 16));
118 auto result = MUST(bit_read_stream.read_bits(16));
119 EXPECT_EQ(0b1101001000100001u, result);
120 }
121}