xref: /aosp_15_r20/external/emboss/compiler/back_end/cpp/testcode/bits_test.cc (revision 99e0aae7469b87d12f0ad23e61142c2d74c1ef70)
1 // Copyright 2019 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 // Tests for generated code for "bits" types, using bits.emb.
16 #include <stdint.h>
17 
18 #include <vector>
19 
20 #include "gtest/gtest.h"
21 #include "runtime/cpp/emboss_cpp_util.h"
22 #include "testdata/bits.emb.h"
23 
24 namespace emboss {
25 namespace test {
26 namespace {
27 
TEST(Bits,OneByteView)28 TEST(Bits, OneByteView) {
29   ::std::uint8_t data[] = {0x2b};
30   auto one_byte = GenericOneByteView<support::BitBlock<
31       support::LittleEndianByteOrderer<support::ReadWriteContiguousBuffer>, 8>>{
32       support::BitBlock<
33           support::LittleEndianByteOrderer<support::ReadWriteContiguousBuffer>,
34           8>{support::ReadWriteContiguousBuffer{data, sizeof data}}};
35   EXPECT_EQ(0xa, one_byte.mid_nibble().Read());
36   EXPECT_EQ(0, one_byte.high_bit().Read());
37   EXPECT_EQ(1, one_byte.low_bit().Read());
38   one_byte.less_high_bit().Write(1);
39   EXPECT_EQ(0x6b, data[0]);
40   one_byte.less_low_bit().Write(0);
41   EXPECT_EQ(0x69, data[0]);
42   one_byte.mid_nibble().Write(5);
43   EXPECT_EQ(0x55, data[0]);
44 }
45 
TEST(Bits,StructOfBits)46 TEST(Bits, StructOfBits) {
47   alignas(8)::std::uint8_t data[] = {0xe8, 0x7f, 0xfe, 0xf1, 0xff, 0xbf, 0x3d};
48   auto struct_of_bits =
49       MakeAlignedStructOfBitsView</**/ ::std::uint8_t, 8>(data, sizeof data);
50   EXPECT_EQ(0xa, struct_of_bits.one_byte().mid_nibble().Read());
51   EXPECT_FALSE(struct_of_bits.Ok());
52   EXPECT_FALSE(struct_of_bits.located_byte().Ok());
53   struct_of_bits.one_byte().mid_nibble().Write(0x01);
54   EXPECT_EQ(0xc4, data[0]);
55   EXPECT_TRUE(struct_of_bits.Ok());
56   EXPECT_TRUE(struct_of_bits.located_byte().Ok());
57   EXPECT_EQ(0x7f, struct_of_bits.located_byte().Read());
58   EXPECT_EQ(0x9, struct_of_bits.two_byte().mid_nibble().Read());
59   EXPECT_EQ(0x6, struct_of_bits.four_byte().one_byte().mid_nibble().Read());
60   EXPECT_EQ(0x3, struct_of_bits.four_byte().high_nibble().Read());
61   struct_of_bits.four_byte().one_byte().mid_nibble().Write(0x9);
62   EXPECT_EQ(0x7f, data[5]);
63   EXPECT_EQ(0x3e, data[6]);
64   EXPECT_EQ(101, struct_of_bits.four_byte().low_nibble().Read());
65   struct_of_bits.four_byte().low_nibble().Write(115);
66   EXPECT_EQ(0xff, data[3]);
67   // Out-of-[range] write.
68 #if EMBOSS_CHECK_ABORTS
69   EXPECT_DEATH(struct_of_bits.four_byte().low_nibble().Write(100), "");
70 #endif  // EMBOSS_CHECK_ABORTS
71 }
72 
TEST(Bits,StructOfBitsFromText)73 TEST(Bits, StructOfBitsFromText) {
74   alignas(8)::std::uint8_t data[] = {0xe8, 0x7f, 0xfe, 0xf1, 0xff, 0xbf, 0x3d};
75   auto struct_of_bits =
76       MakeAlignedStructOfBitsView</**/ ::std::uint8_t, 8>(data, sizeof data);
77   EXPECT_TRUE(::emboss::UpdateFromText(struct_of_bits, R"(
78     {
79       one_byte: {
80         high_bit: false
81         mid_nibble: 0x01
82       }
83       four_byte: {
84         one_byte: {
85           mid_nibble: 0x9
86         }
87         low_nibble: 115
88       }
89     }
90   )"));
91   EXPECT_EQ(0x44, data[0]);
92   EXPECT_EQ(0x7f, data[5]);
93   EXPECT_EQ(0x3e, data[6]);
94   EXPECT_EQ(0xff, data[3]);
95 }
96 
TEST(Bits,ArrayOfBits)97 TEST(Bits, ArrayOfBits) {
98   alignas(8)::std::uint8_t data[] = {0xe8, 0x7f, 0xfe, 0xf1,
99                                      0xff, 0xbf, 0x00, 0x3d};
100   auto bit_array =
101       MakeAlignedBitArrayView</**/ ::std::uint8_t, 8>(data, sizeof data);
102   EXPECT_EQ(0xa, bit_array.one_byte()[0].mid_nibble().Read());
103   EXPECT_EQ(0xf, bit_array.one_byte()[7].mid_nibble().Read());
104   bit_array.one_byte()[7].mid_nibble().Write(0x0);
105   EXPECT_EQ(0x01, data[7]);
106   EXPECT_TRUE(bit_array.Ok());
107   bit_array =
108       MakeAlignedBitArrayView</**/ ::std::uint8_t, 8>(data, sizeof data - 1);
109   EXPECT_FALSE(bit_array.Ok());
110 }
111 
TEST(Bits,ArrayInBits)112 TEST(Bits, ArrayInBits) {
113   ::std::uint8_t data[] = {0xaa, 0xaa};
114   auto array = ArrayInBitsInStructWriter{data, sizeof data};
115   EXPECT_EQ(false, array.array_in_bits().flags()[0].Read());
116   EXPECT_EQ(true, array.array_in_bits().flags()[1].Read());
117   EXPECT_EQ(false, array.array_in_bits().flags()[10].Read());
118   EXPECT_EQ(true, array.array_in_bits().flags()[11].Read());
119   array.array_in_bits().flags()[8].Write(true);
120   EXPECT_EQ(0xab, data[1]);
121   EXPECT_EQ(12U, array.array_in_bits().flags().SizeInBits());
122   EXPECT_EQ(12U, array.array_in_bits().flags().ElementCount());
123   EXPECT_TRUE(array.array_in_bits().flags().Ok());
124   EXPECT_TRUE(array.array_in_bits().flags().IsComplete());
125 }
126 
TEST(Bits,ArrayInBitsFromText)127 TEST(Bits, ArrayInBitsFromText) {
128   ::std::uint8_t data[] = {0, 0};
129   auto array = ArrayInBitsInStructWriter{data, sizeof data};
130   EXPECT_TRUE(::emboss::UpdateFromText(array.array_in_bits(), R"(
131     {
132       lone_flag: true
133       flags: { true, false, true, false, true, false,
134                true, false, true, false, true, false }
135     }
136   )"));
137   EXPECT_EQ(0x55, data[0]);
138   EXPECT_EQ(0x85, data[1]);
139 }
140 
TEST(Bits,ArrayInBitsToText)141 TEST(Bits, ArrayInBitsToText) {
142   ::std::uint8_t data[] = {0x55, 0x85};
143   auto array = ArrayInBitsInStructWriter{data, sizeof data};
144   EXPECT_EQ(
145       "{\n"
146       "  lone_flag: true\n"
147       "  flags: {\n"
148       "    [0]: true\n"
149       "    [1]: false\n"
150       "    [2]: true\n"
151       "    [3]: false\n"
152       "    [4]: true\n"
153       "    [5]: false\n"
154       "    [6]: true\n"
155       "    [7]: false\n"
156       "    [8]: true\n"
157       "    [9]: false\n"
158       "    [10]: true\n"
159       "    [11]: false\n"
160       "  }\n"
161       "}",
162       ::emboss::WriteToString(array.array_in_bits(),
163                               ::emboss::MultilineText()));
164 }
165 
TEST(Bits,CopyFrom)166 TEST(Bits, CopyFrom) {
167   ::std::array</**/ ::std::uint8_t, 4> buf_x = {0x00, 0x00};
168   ::std::array</**/ ::std::uint8_t, 4> buf_y = {0xff, 0xff};
169 
170   auto x = ArrayInBitsInStructWriter{&buf_x};
171   auto y = ArrayInBitsInStructWriter{&buf_y};
172 
173   EXPECT_NE(x.array_in_bits().flags()[0].Read(),
174             y.array_in_bits().flags()[0].Read());
175 
176   x.array_in_bits().flags()[0].CopyFrom(y.array_in_bits().flags()[0]);
177   EXPECT_EQ(x.array_in_bits().flags()[0].Read(),
178             y.array_in_bits().flags()[0].Read());
179 
180   EXPECT_NE(x.array_in_bits().flags()[1].Read(),
181             y.array_in_bits().flags()[1].Read());
182   EXPECT_NE(x.array_in_bits().flags()[10].Read(),
183             y.array_in_bits().flags()[10].Read());
184   EXPECT_NE(x.array_in_bits().flags()[11].Read(),
185             y.array_in_bits().flags()[11].Read());
186 }
187 
TEST(Bits,TryToCopyFrom)188 TEST(Bits, TryToCopyFrom) {
189   ::std::array</**/ ::std::uint8_t, 4> buf_x = {0x00, 0x00};
190   ::std::array</**/ ::std::uint8_t, 4> buf_y = {0xff, 0xff};
191 
192   auto x = ArrayInBitsInStructWriter{&buf_x};
193   auto y = ArrayInBitsInStructWriter{&buf_y};
194 
195   EXPECT_NE(x.array_in_bits().flags()[0].Read(),
196             y.array_in_bits().flags()[0].Read());
197 
198   EXPECT_TRUE(
199       x.array_in_bits().flags()[0].TryToCopyFrom(y.array_in_bits().flags()[0]));
200   EXPECT_EQ(x.array_in_bits().flags()[0].Read(),
201             y.array_in_bits().flags()[0].Read());
202 
203   EXPECT_NE(x.array_in_bits().flags()[1].Read(),
204             y.array_in_bits().flags()[1].Read());
205   EXPECT_NE(x.array_in_bits().flags()[10].Read(),
206             y.array_in_bits().flags()[10].Read());
207   EXPECT_NE(x.array_in_bits().flags()[11].Read(),
208             y.array_in_bits().flags()[11].Read());
209 }
210 
TEST(Bits,Equals)211 TEST(Bits, Equals) {
212   alignas(8)::std::uint8_t buf_x[] = {0xe8, 0x7f, 0xfe, 0xf1,
213                                       0xff, 0xbf, 0x00, 0x3d};
214   alignas(8)::std::uint8_t buf_y[] = {0xe8, 0x7f, 0xfe, 0xf1,
215                                       0xff, 0xbf, 0x00, 0x3d};
216 
217   auto x = MakeAlignedBitArrayView</**/ ::std::uint8_t, 8>(buf_x, sizeof buf_x);
218   auto x_const =
219       MakeBitArrayView(static_cast</**/ ::std::uint8_t *>(buf_x), sizeof buf_x);
220   auto y = MakeAlignedBitArrayView</**/ ::std::uint8_t, 8>(buf_y, sizeof buf_y);
221 
222   EXPECT_TRUE(x.Equals(x));
223   EXPECT_TRUE(x.UncheckedEquals(x));
224   EXPECT_TRUE(y.Equals(y));
225   EXPECT_TRUE(y.UncheckedEquals(y));
226 
227   EXPECT_TRUE(x.Equals(y));
228   EXPECT_TRUE(x.UncheckedEquals(y));
229   EXPECT_TRUE(y.Equals(x));
230   EXPECT_TRUE(y.UncheckedEquals(x));
231 
232   EXPECT_TRUE(x_const.Equals(y));
233   EXPECT_TRUE(x_const.UncheckedEquals(y));
234   EXPECT_TRUE(y.Equals(x_const));
235   EXPECT_TRUE(y.UncheckedEquals(x_const));
236 
237   ++buf_y[1];
238   EXPECT_FALSE(x.Equals(y));
239   EXPECT_FALSE(x.UncheckedEquals(y));
240   EXPECT_FALSE(y.Equals(x));
241   EXPECT_FALSE(y.UncheckedEquals(x));
242 
243   EXPECT_FALSE(x_const.Equals(y));
244   EXPECT_FALSE(x_const.UncheckedEquals(y));
245   EXPECT_FALSE(y.Equals(x_const));
246   EXPECT_FALSE(y.UncheckedEquals(x_const));
247 }
248 
249 }  // namespace
250 }  // namespace test
251 }  // namespace emboss
252