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