xref: /aosp_15_r20/external/emboss/compiler/back_end/cpp/testcode/bcd_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 the generated View class from bcd.emb.
16 //
17 // These tests check that Binary-Coded Decimal (BCD) numbers work.
18 #include <stdint.h>
19 
20 #include <array>
21 #include <string>
22 #include <vector>
23 
24 #include "gtest/gtest.h"
25 #include "testdata/bcd.emb.h"
26 
27 namespace emboss {
28 namespace test {
29 namespace {
30 
31 alignas(8) static const ::std::uint8_t kBcd[40] = {
32     0x02,                    // 0  [+1]  one_byte == 2
33     0x04, 0x01,              // 1  [+2]  two_byte == 104
34     0x66, 0x55, 0x44,        // 3  [+3]  three_byte == 445566
35     0x06, 0x05, 0x04, 0x03,  // 6  [+4]  four_byte == 3040506
36     0x21, 0x43, 0x65, 0x87,  // 10 [+5]  five_byte
37     0x99,                    // 10 [+5]  five_byte == 9987654321
38     0x23, 0x91, 0x78, 0x56,  // 15 [+6]  six_byte
39     0x34, 0x12,              // 15 [+6]  six_byte == 123456789123
40     0x37, 0x46, 0x55, 0x64,  // 21 [+7]  seven_byte
41     0x73, 0x82, 0x91,        // 21 [+7]  seven_byte == 91827364554637
42     0x06, 0x05, 0x04, 0x03,  // 28 [+8]  eight_byte
43     0x02, 0x01, 0x00, 0x99,  // 28 [+8]  eight_byte == 9900010203040506
44     0x34, 0x1d, 0x3c, 0x12,  // 36 [+4]  four_bit = 4,
45                              //          six_bit = 13,
46                              //          ten_bit = 307,
47                              //          twelve_bit = 123,
48 };
49 
TEST(BcdSizesView,CanReadBcd)50 TEST(BcdSizesView, CanReadBcd) {
51   auto view =
52       MakeAlignedBcdSizesView<const ::std::uint8_t, 8>(kBcd, sizeof kBcd);
53   EXPECT_EQ(2, view.one_byte().Read());
54   EXPECT_EQ(104, view.two_byte().Read());
55   EXPECT_EQ(445566U, view.three_byte().Read());
56   EXPECT_EQ(3040506U, view.four_byte().Read());
57   EXPECT_EQ(9987654321UL, view.five_byte().Read());
58   EXPECT_EQ(123456789123UL, view.six_byte().Read());
59   EXPECT_EQ(91827364554637UL, view.seven_byte().Read());
60   EXPECT_EQ(9900010203040506UL, view.eight_byte().Read());
61   EXPECT_EQ(4, view.four_bit().Read());
62   EXPECT_EQ(13, view.six_bit().Read());
63   EXPECT_EQ(307, view.ten_bit().Read());
64   EXPECT_EQ(123, view.twelve_bit().Read());
65   // Test that the views return appropriate integer widths.
66   EXPECT_EQ(1U, sizeof(view.one_byte().Read()));
67   EXPECT_EQ(2U, sizeof(view.two_byte().Read()));
68   EXPECT_EQ(4U, sizeof(view.three_byte().Read()));
69   EXPECT_EQ(4U, sizeof(view.four_byte().Read()));
70   EXPECT_EQ(8U, sizeof(view.five_byte().Read()));
71   EXPECT_EQ(8U, sizeof(view.six_byte().Read()));
72   EXPECT_EQ(8U, sizeof(view.seven_byte().Read()));
73   EXPECT_EQ(8U, sizeof(view.eight_byte().Read()));
74   EXPECT_EQ(1U, sizeof(view.four_bit().Read()));
75   EXPECT_EQ(1U, sizeof(view.six_bit().Read()));
76   EXPECT_EQ(2U, sizeof(view.ten_bit().Read()));
77   EXPECT_EQ(2U, sizeof(view.twelve_bit().Read()));
78 }
79 
TEST(BcdSizesWriter,CanWriteBcd)80 TEST(BcdSizesWriter, CanWriteBcd) {
81   ::std::uint8_t buffer[sizeof kBcd] = {0};
82   auto writer = BcdSizesWriter(buffer, sizeof buffer);
83   writer.one_byte().Write(2);
84   writer.two_byte().Write(104);
85   writer.three_byte().Write(445566);
86   writer.four_byte().Write(3040506);
87   writer.five_byte().Write(9987654321UL);
88   writer.six_byte().Write(123456789123UL);
89   writer.seven_byte().Write(91827364554637UL);
90   writer.eight_byte().Write(9900010203040506UL);
91   writer.four_bit().Write(4);
92   writer.six_bit().Write(13);
93   writer.ten_bit().Write(307);
94   writer.twelve_bit().Write(123);
95   EXPECT_EQ(::std::vector</**/ ::std::uint8_t>(kBcd, kBcd + sizeof kBcd),
96             ::std::vector</**/ ::std::uint8_t>(buffer, buffer + sizeof buffer));
97 
98 #if EMBOSS_CHECK_ABORTS
99   EXPECT_DEATH(writer.one_byte().Write(100), "");
100   EXPECT_DEATH(writer.three_byte().Write(1445566), "");
101   EXPECT_DEATH(writer.ten_bit().Write(400), "");
102 #endif  // EMBOSS_CHECK_ABORTS
103 }
104 
TEST(BcdSizesView,OkIsTrueForGoodBcd)105 TEST(BcdSizesView, OkIsTrueForGoodBcd) {
106   auto view = BcdSizesView(kBcd, sizeof kBcd);
107   EXPECT_TRUE(view.Ok());
108   EXPECT_TRUE(view.one_byte().Ok());
109   EXPECT_TRUE(view.one_byte().Ok());
110   EXPECT_TRUE(view.two_byte().Ok());
111   EXPECT_TRUE(view.three_byte().Ok());
112   EXPECT_TRUE(view.four_byte().Ok());
113   EXPECT_TRUE(view.five_byte().Ok());
114   EXPECT_TRUE(view.six_byte().Ok());
115   EXPECT_TRUE(view.seven_byte().Ok());
116   EXPECT_TRUE(view.eight_byte().Ok());
117 }
118 
119 static const ::std::uint8_t kBadBcd[40] = {
120     0x0a,                    // 0  [+1]  one_byte
121     0xb4, 0x01,              // 1  [+2]  two_byte
122     0xaa, 0x55, 0x44,        // 3  [+3]  three_byte
123     0x06, 0x05, 0x04, 0xff,  // 6  [+4]  four_byte
124     0xff, 0xff, 0xff, 0xff,  // 10 [+5]  five_byte
125     0xff,                    // 10 [+5]  five_byte
126     0xff, 0xff, 0xff, 0xff,  // 15 [+6]  six_byte
127     0xff, 0xff,              // 15 [+6]  six_byte
128     0xff, 0xff, 0xff, 0xff,  // 21 [+7]  seven_byte
129     0xff, 0xff, 0xff,        // 21 [+7]  seven_byte
130     0xff, 0xff, 0xff, 0xff,  // 28 [+8]  eight_byte
131     0xff, 0xff, 0xff, 0xff,  // 28 [+8]  eight_byte
132     0xff, 0xff, 0xff, 0xff,  // 36 [+4]  four_, six_, ten_, twelve_bit
133 };
134 
TEST(BcdSizesView,UncheckedReadingInvalidBcdDoesNotCrash)135 TEST(BcdSizesView, UncheckedReadingInvalidBcdDoesNotCrash) {
136   auto view = BcdSizesView(kBadBcd, sizeof kBadBcd);
137   view.one_byte().UncheckedRead();
138   view.two_byte().UncheckedRead();
139   view.three_byte().UncheckedRead();
140   view.four_byte().UncheckedRead();
141   view.five_byte().UncheckedRead();
142   view.six_byte().UncheckedRead();
143   view.seven_byte().UncheckedRead();
144   view.eight_byte().UncheckedRead();
145   view.four_bit().UncheckedRead();
146   view.six_bit().UncheckedRead();
147   view.ten_bit().UncheckedRead();
148   view.twelve_bit().UncheckedRead();
149 }
150 
151 #if EMBOSS_CHECK_ABORTS
TEST(BcdSizesView,ReadingInvalidBcdCrashes)152 TEST(BcdSizesView, ReadingInvalidBcdCrashes) {
153   auto view = BcdSizesView(kBadBcd, sizeof kBadBcd);
154   EXPECT_DEATH(view.one_byte().Read(), "");
155   EXPECT_DEATH(view.two_byte().Read(), "");
156   EXPECT_DEATH(view.three_byte().Read(), "");
157   EXPECT_DEATH(view.four_byte().Read(), "");
158   EXPECT_DEATH(view.five_byte().Read(), "");
159   EXPECT_DEATH(view.six_byte().Read(), "");
160   EXPECT_DEATH(view.seven_byte().Read(), "");
161   EXPECT_DEATH(view.eight_byte().Read(), "");
162   EXPECT_DEATH(view.four_bit().Read(), "");
163   EXPECT_DEATH(view.six_bit().Read(), "");
164   EXPECT_DEATH(view.ten_bit().Read(), "");
165   EXPECT_DEATH(view.twelve_bit().Read(), "");
166 }
167 #endif  // EMBOSS_CHECK_ABORTS
168 
TEST(BcdSizesView,OkIsFalseForBadBcd)169 TEST(BcdSizesView, OkIsFalseForBadBcd) {
170   auto view = BcdSizesView(kBadBcd, sizeof kBadBcd);
171   EXPECT_FALSE(view.Ok());
172   EXPECT_FALSE(view.one_byte().Ok());
173   EXPECT_FALSE(view.two_byte().Ok());
174   EXPECT_FALSE(view.three_byte().Ok());
175   EXPECT_FALSE(view.four_byte().Ok());
176   EXPECT_FALSE(view.five_byte().Ok());
177   EXPECT_FALSE(view.six_byte().Ok());
178   EXPECT_FALSE(view.seven_byte().Ok());
179   EXPECT_FALSE(view.eight_byte().Ok());
180   EXPECT_FALSE(view.four_bit().Ok());
181   EXPECT_FALSE(view.six_bit().Ok());
182   EXPECT_FALSE(view.ten_bit().Ok());
183   EXPECT_FALSE(view.twelve_bit().Ok());
184 }
185 
TEST(BcdBigEndianView,BigEndianReadWrite)186 TEST(BcdBigEndianView, BigEndianReadWrite) {
187   ::std::uint8_t big_endian[4] = {0x12, 0x34, 0x56, 0x78};
188   auto writer = BcdBigEndianWriter(big_endian, sizeof big_endian);
189   EXPECT_EQ(12345678U, writer.four_byte().Read());
190   writer.four_byte().Write(87654321);
191   EXPECT_EQ(0x87, big_endian[0]);
192   EXPECT_EQ(0x65, big_endian[1]);
193   EXPECT_EQ(0x43, big_endian[2]);
194   EXPECT_EQ(0x21, big_endian[3]);
195 }
196 
TEST(BcdBigEndianView,CopyFrom)197 TEST(BcdBigEndianView, CopyFrom) {
198   ::std::array</**/ ::std::uint8_t, 4> buf_x = {0x12, 0x34, 0x56, 0x78};
199   ::std::array</**/ ::std::uint8_t, 4> buf_y = {0x00, 0x00, 0x00, 0x00};
200 
201   auto x = BcdBigEndianWriter(&buf_x);
202   auto y = BcdBigEndianWriter(&buf_y);
203 
204   EXPECT_NE(x.four_byte().Read(), y.four_byte().Read());
205   x.four_byte().CopyFrom(y.four_byte());
206   EXPECT_EQ(x.four_byte().Read(), y.four_byte().Read());
207 }
208 
TEST(BcdBigEndianView,TryToCopyFrom)209 TEST(BcdBigEndianView, TryToCopyFrom) {
210   ::std::array</**/ ::std::uint8_t, 4> buf_x = {0x12, 0x34, 0x56, 0x78};
211   ::std::array</**/ ::std::uint8_t, 4> buf_y = {0x00, 0x00, 0x00, 0x00};
212 
213   auto x = BcdBigEndianWriter(&buf_x);
214   auto y = BcdBigEndianWriter(&buf_y);
215 
216   EXPECT_NE(x.four_byte().Read(), y.four_byte().Read());
217   EXPECT_TRUE(x.four_byte().TryToCopyFrom(y.four_byte()));
218   EXPECT_EQ(x.four_byte().Read(), y.four_byte().Read());
219 }
220 
TEST(BcdSizesView,Equals)221 TEST(BcdSizesView, Equals) {
222   ::std::array</**/ ::std::uint8_t, sizeof kBcd> buf_x;
223   ::std::array</**/ ::std::uint8_t, sizeof kBcd> buf_y;
224 
225   ::std::copy(kBcd, kBcd + sizeof kBcd, buf_x.begin());
226   ::std::copy(kBcd, kBcd + sizeof kBcd, buf_y.begin());
227 
228   EXPECT_EQ(buf_x, buf_y);
229   auto x = BcdSizesView(&buf_x);
230   auto x_const = BcdSizesView(
231       static_cast</**/ ::std::array</**/ ::std::uint8_t, sizeof kBcd>*>(
232           &buf_x));
233   auto y = BcdSizesView(&buf_y);
234 
235   EXPECT_TRUE(x.Equals(x));
236   EXPECT_TRUE(x.UncheckedEquals(x));
237   EXPECT_TRUE(y.Equals(y));
238   EXPECT_TRUE(y.UncheckedEquals(y));
239 
240   EXPECT_TRUE(x.Equals(y));
241   EXPECT_TRUE(x.UncheckedEquals(y));
242   EXPECT_TRUE(y.Equals(x));
243   EXPECT_TRUE(y.UncheckedEquals(x));
244 
245   EXPECT_TRUE(x_const.Equals(y));
246   EXPECT_TRUE(x_const.UncheckedEquals(y));
247   EXPECT_TRUE(y.Equals(x_const));
248   EXPECT_TRUE(y.UncheckedEquals(x_const));
249 
250   ++buf_y[1];
251   EXPECT_FALSE(x.Equals(y));
252   EXPECT_FALSE(x.UncheckedEquals(y));
253   EXPECT_FALSE(y.Equals(x));
254   EXPECT_FALSE(y.UncheckedEquals(x));
255 
256   EXPECT_FALSE(x_const.Equals(y));
257   EXPECT_FALSE(x_const.UncheckedEquals(y));
258   EXPECT_FALSE(y.Equals(x_const));
259   EXPECT_FALSE(y.UncheckedEquals(x_const));
260 }
261 
TEST(BcdSizesView,UncheckedEquals)262 TEST(BcdSizesView, UncheckedEquals) {
263   ::std::array</**/ ::std::uint8_t, sizeof kBadBcd> buf_x;
264   ::std::array</**/ ::std::uint8_t, sizeof kBadBcd> buf_y;
265 
266   ::std::copy(kBadBcd, kBadBcd + sizeof kBadBcd, buf_x.begin());
267   ::std::copy(kBadBcd, kBadBcd + sizeof kBadBcd, buf_y.begin());
268 
269   EXPECT_EQ(buf_x, buf_y);
270   auto x = BcdSizesView(&buf_x);
271   auto x_const = BcdSizesView(
272       static_cast</**/ ::std::array</**/ ::std::uint8_t, sizeof kBadBcd>*>(
273           &buf_x));
274   auto y = BcdSizesView(&buf_y);
275 
276   EXPECT_TRUE(x.UncheckedEquals(x));
277   EXPECT_TRUE(y.UncheckedEquals(y));
278 #if EMBOSS_CHECK_ABORTS
279   EXPECT_DEATH(x.Equals(x), "");
280   EXPECT_DEATH(y.Equals(y), "");
281 #endif  // EMBOSS_CHECK_ABORTS
282 
283   EXPECT_TRUE(x.UncheckedEquals(y));
284   EXPECT_TRUE(y.UncheckedEquals(x));
285 #if EMBOSS_CHECK_ABORTS
286   EXPECT_DEATH(x.Equals(y), "");
287   EXPECT_DEATH(y.Equals(x), "");
288 #endif  // EMBOSS_CHECK_ABORTS
289 
290   EXPECT_TRUE(x_const.UncheckedEquals(y));
291   EXPECT_TRUE(y.UncheckedEquals(x_const));
292 #if EMBOSS_CHECK_ABORTS
293   EXPECT_DEATH(x_const.Equals(y), "");
294   EXPECT_DEATH(y.Equals(x_const), "");
295 #endif  // EMBOSS_CHECK_ABORTS
296 
297   ++buf_y[1];
298   EXPECT_FALSE(x.UncheckedEquals(y));
299   EXPECT_FALSE(y.UncheckedEquals(x));
300 #if EMBOSS_CHECK_ABORTS
301   EXPECT_DEATH(x.Equals(y), "");
302   EXPECT_DEATH(y.Equals(x), "");
303 #endif  // EMBOSS_CHECK_ABORTS
304 
305   EXPECT_FALSE(x_const.UncheckedEquals(y));
306   EXPECT_FALSE(y.UncheckedEquals(x_const));
307 #if EMBOSS_CHECK_ABORTS
308   EXPECT_DEATH(x_const.Equals(y), "");
309   EXPECT_DEATH(y.Equals(x_const), "");
310 #endif  // EMBOSS_CHECK_ABORTS
311 }
312 
313 }  // namespace
314 }  // namespace test
315 }  // namespace emboss
316