xref: /aosp_15_r20/external/emboss/runtime/cpp/test/emboss_prelude_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 #include "runtime/cpp/emboss_prelude.h"
16 
17 #include <type_traits>
18 
19 #include "gtest/gtest.h"
20 #include "runtime/cpp/emboss_cpp_util.h"
21 #include "runtime/cpp/emboss_text_util.h"
22 
23 namespace emboss {
24 namespace prelude {
25 namespace test {
26 
27 using ::emboss::support::OffsetBitBlock;
28 using ::emboss::support::ReadWriteContiguousBuffer;
29 
30 template </**/ ::std::size_t kBits>
31 using BitBlockN = ::emboss::support::BitBlock<
32     ::emboss::support::LittleEndianByteOrderer<ReadWriteContiguousBuffer>,
33     kBits>;
34 
35 template </**/ ::std::size_t kBits>
36 using ViewParameters = ::emboss::support::FixedSizeViewParameters<
37     kBits, ::emboss::support::AllValuesAreOk>;
38 
TEST(FlagView,Methods)39 TEST(FlagView, Methods) {
40   ::std::uint8_t byte = 0;
41   auto flag_view =
42       FlagView<ViewParameters<1>, OffsetBitBlock<BitBlockN<8>>>{BitBlockN<8>{
43           ReadWriteContiguousBuffer{&byte, 1}}.GetOffsetStorage<1, 0>(0, 1)};
44   EXPECT_FALSE(flag_view.Read());
45   byte = 0xfe;
46   EXPECT_FALSE(flag_view.Read());
47   byte = 0x01;
48   EXPECT_TRUE(flag_view.Read());
49   byte = 0xff;
50   EXPECT_TRUE(flag_view.Read());
51   EXPECT_TRUE(flag_view.CouldWriteValue(false));
52   EXPECT_TRUE(flag_view.CouldWriteValue(true));
53   flag_view.Write(false);
54   EXPECT_EQ(0xfe, byte);
55   byte = 0xaa;
56   flag_view.Write(true);
57   EXPECT_EQ(0xab, byte);
58 }
59 
TEST(FlagView,TextDecode)60 TEST(FlagView, TextDecode) {
61   ::std::uint8_t byte = 0;
62   const auto flag_view =
63       FlagView<ViewParameters<1>, OffsetBitBlock<BitBlockN<8>>>{BitBlockN<8>{
64           ReadWriteContiguousBuffer{&byte, 1}}.GetOffsetStorage<1, 0>(0, 1)};
65   EXPECT_FALSE(UpdateFromText(flag_view, ""));
66   EXPECT_FALSE(UpdateFromText(flag_view, "FALSE"));
67   EXPECT_FALSE(UpdateFromText(flag_view, "TRUE"));
68   EXPECT_FALSE(UpdateFromText(flag_view, "+true"));
69   EXPECT_TRUE(UpdateFromText(flag_view, "true"));
70   EXPECT_EQ(0x01, byte);
71   EXPECT_TRUE(UpdateFromText(flag_view, "false"));
72   EXPECT_EQ(0x00, byte);
73   EXPECT_TRUE(UpdateFromText(flag_view, " true"));
74   EXPECT_EQ(0x01, byte);
75   {
76     auto stream = support::TextStream{" false  xxx"};
77     EXPECT_TRUE(flag_view.UpdateFromTextStream(&stream));
78     EXPECT_EQ(0x00, byte);
79     ::std::string token;
80     EXPECT_TRUE(::emboss::support::ReadToken(&stream, &token));
81     EXPECT_EQ("xxx", token);
82   }
83 }
84 
TEST(FlagView,TextEncode)85 TEST(FlagView, TextEncode) {
86   ::std::uint8_t byte = 0;
87   const auto flag_view =
88       FlagView<ViewParameters<1>, OffsetBitBlock<BitBlockN<8>>>{BitBlockN<8>{
89           ReadWriteContiguousBuffer{&byte, 1}}.GetOffsetStorage<1, 0>(0, 1)};
90   EXPECT_EQ("false", WriteToString(flag_view));
91   byte = 1;
92   EXPECT_EQ("true", WriteToString(flag_view));
93 }
94 
95 template <template <typename, typename> class ViewType, int kMaxBits>
CheckViewSizeInBits()96 void CheckViewSizeInBits() {
97   const int size_in_bits =
98       ViewType<ViewParameters<kMaxBits>, BitBlockN<64>>::SizeInBits();
99   EXPECT_EQ(size_in_bits, kMaxBits);
100   return CheckViewSizeInBits<ViewType, kMaxBits - 1>();
101 }
102 
103 template <>
CheckViewSizeInBits()104 void CheckViewSizeInBits<UIntView, 0>() {
105   return;
106 }
107 
108 template <>
CheckViewSizeInBits()109 void CheckViewSizeInBits<IntView, 0>() {
110   return;
111 }
112 
113 template <>
CheckViewSizeInBits()114 void CheckViewSizeInBits<BcdView, 0>() {
115   return;
116 }
117 
TEST(UIntView,SizeInBits)118 TEST(UIntView, SizeInBits) { CheckViewSizeInBits<UIntView, 64>(); }
119 
TEST(IntView,SizeInBits)120 TEST(IntView, SizeInBits) { CheckViewSizeInBits<IntView, 64>(); }
121 
TEST(BcdView,SizeInBits)122 TEST(BcdView, SizeInBits) { CheckViewSizeInBits<BcdView, 64>(); }
123 
124 template </**/ ::std::size_t kBits>
125 using UIntViewN = UIntView<ViewParameters<kBits>, BitBlockN<kBits>>;
126 
TEST(UIntView,ValueType)127 TEST(UIntView, ValueType) {
128   using BitBlockType = BitBlockN<64>;
129   EXPECT_TRUE((::std::is_same<
130                /**/ ::std::uint8_t,
131                UIntView<ViewParameters<8>, BitBlockType>::ValueType>::value));
132   EXPECT_TRUE((::std::is_same<
133                /**/ ::std::uint8_t,
134                UIntView<ViewParameters<6>, BitBlockType>::ValueType>::value));
135   EXPECT_TRUE((::std::is_same<
136                /**/ ::std::uint16_t,
137                UIntView<ViewParameters<9>, BitBlockType>::ValueType>::value));
138   EXPECT_TRUE((::std::is_same<
139                /**/ ::std::uint16_t,
140                UIntView<ViewParameters<16>, BitBlockType>::ValueType>::value));
141   EXPECT_TRUE((::std::is_same<
142                /**/ ::std::uint32_t,
143                UIntView<ViewParameters<17>, BitBlockType>::ValueType>::value));
144   EXPECT_TRUE((::std::is_same<
145                /**/ ::std::uint32_t,
146                UIntView<ViewParameters<32>, BitBlockType>::ValueType>::value));
147   EXPECT_TRUE((::std::is_same<
148                /**/ ::std::uint64_t,
149                UIntView<ViewParameters<33>, BitBlockType>::ValueType>::value));
150   EXPECT_TRUE((::std::is_same<
151                /**/ ::std::uint64_t,
152                UIntView<ViewParameters<64>, BitBlockType>::ValueType>::value));
153 }
154 
TEST(UIntView,CouldWriteValue)155 TEST(UIntView, CouldWriteValue) {
156   EXPECT_TRUE(UIntViewN<8>::CouldWriteValue(0xff));
157   EXPECT_TRUE(UIntViewN<8>::CouldWriteValue(0));
158   EXPECT_FALSE(UIntViewN<8>::CouldWriteValue(0x100));
159   EXPECT_FALSE(UIntViewN<8>::CouldWriteValue(-1));
160   EXPECT_TRUE(UIntViewN<16>::CouldWriteValue(0xffff));
161   EXPECT_TRUE(UIntViewN<16>::CouldWriteValue(0));
162   EXPECT_FALSE(UIntViewN<16>::CouldWriteValue(0x10000));
163   EXPECT_FALSE(UIntViewN<16>::CouldWriteValue(-1));
164   EXPECT_TRUE(UIntViewN<32>::CouldWriteValue(0xffffffffU));
165   EXPECT_TRUE(UIntViewN<32>::CouldWriteValue(0xffffffffL));
166   EXPECT_TRUE(UIntViewN<32>::CouldWriteValue(0));
167   EXPECT_FALSE(UIntViewN<32>::CouldWriteValue(0x100000000L));
168   EXPECT_FALSE(UIntViewN<32>::CouldWriteValue(-1));
169   EXPECT_TRUE(UIntViewN<48>::CouldWriteValue(0x0000ffffffffffffUL));
170   EXPECT_TRUE(UIntViewN<48>::CouldWriteValue(0x0000ffffffffffffL));
171   EXPECT_TRUE(UIntViewN<48>::CouldWriteValue(0));
172   EXPECT_FALSE(UIntViewN<48>::CouldWriteValue(0x1000000000000UL));
173   EXPECT_FALSE(UIntViewN<48>::CouldWriteValue(0x1000000000000L));
174   EXPECT_FALSE(UIntViewN<48>::CouldWriteValue(-1));
175   EXPECT_TRUE(UIntViewN<64>::CouldWriteValue(0xffffffffffffffffUL));
176   EXPECT_TRUE(UIntViewN<64>::CouldWriteValue(0));
177   EXPECT_FALSE(UIntViewN<64>::CouldWriteValue(-1));
178 }
179 
TEST(UIntView,CouldWriteValueNarrowing)180 TEST(UIntView, CouldWriteValueNarrowing) {
181   auto narrowing_could_write = [](int value) {
182     return UIntViewN<8>::CouldWriteValue(value);
183   };
184   EXPECT_TRUE(narrowing_could_write(0));
185   EXPECT_TRUE(narrowing_could_write(255));
186   EXPECT_FALSE(narrowing_could_write(-1));
187   EXPECT_FALSE(narrowing_could_write(256));
188 }
189 
TEST(UIntView,ReadAndWriteWithSufficientBuffer)190 TEST(UIntView, ReadAndWriteWithSufficientBuffer) {
191   ::std::vector</**/ ::std::uint8_t> bytes = {
192       {0x10, 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08}};
193   auto uint64_view =
194       UIntViewN<64>{BitBlockN<64>{ReadWriteContiguousBuffer{bytes.data(), 8}}};
195   EXPECT_EQ(0x090a0b0c0d0e0f10UL, uint64_view.Read());
196   EXPECT_EQ(0x090a0b0c0d0e0f10UL, uint64_view.UncheckedRead());
197   uint64_view.Write(0x100f0e0d0c0b0a09UL);
198   EXPECT_EQ((::std::vector</**/ ::std::uint8_t>{
199                 {0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x08}}),
200             bytes);
201   uint64_view.UncheckedWrite(0x090a0b0c0d0e0f10UL);
202   EXPECT_EQ((::std::vector</**/ ::std::uint8_t>{
203                 {0x10, 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08}}),
204             bytes);
205   EXPECT_TRUE(uint64_view.TryToWrite(0x100f0e0d0c0b0a09UL));
206   EXPECT_EQ((::std::vector</**/ ::std::uint8_t>{
207                 {0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x08}}),
208             bytes);
209   EXPECT_TRUE(uint64_view.TryToWrite(0x090a0b0c0d0e0f10UL));
210   EXPECT_EQ((::std::vector</**/ ::std::uint8_t>{
211                 {0x10, 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08}}),
212             bytes);
213   EXPECT_TRUE(uint64_view.Ok());
214   EXPECT_TRUE(uint64_view.IsComplete());
215 }
216 
TEST(UIntView,ReadAndWriteWithInsufficientBuffer)217 TEST(UIntView, ReadAndWriteWithInsufficientBuffer) {
218   ::std::vector</**/ ::std::uint8_t> bytes = {
219       {0x10, 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08}};
220   auto uint64_view =
221       UIntViewN<64>{BitBlockN<64>{ReadWriteContiguousBuffer{bytes.data(), 4}}};
222   EXPECT_EQ(0x090a0b0c0d0e0f10UL, uint64_view.UncheckedRead());
223 #if EMBOSS_CHECK_ABORTS
224   EXPECT_DEATH(uint64_view.Read(), "");
225   EXPECT_DEATH(uint64_view.Write(0x100f0e0d0c0b0a09UL), "");
226 #endif  // EMBOSS_CHECK_ABORTS
227   EXPECT_FALSE(uint64_view.TryToWrite(0x100f0e0d0c0b0a09UL));
228   EXPECT_EQ((::std::vector</**/ ::std::uint8_t>{
229                 {0x10, 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08}}),
230             bytes);
231   uint64_view.UncheckedWrite(0x100f0e0d0c0b0a09UL);
232   EXPECT_EQ((::std::vector</**/ ::std::uint8_t>{
233                 {0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x08}}),
234             bytes);
235   EXPECT_FALSE(uint64_view.Ok());
236   EXPECT_FALSE(uint64_view.IsComplete());
237   uint64_view.UncheckedWrite(0x090a0b0c0d0e0f10UL);
238 }
239 
TEST(UIntView,NonPowerOfTwoSize)240 TEST(UIntView, NonPowerOfTwoSize) {
241   ::std::vector</**/ ::std::uint8_t> bytes = {{0x10, 0x0f, 0x0e, 0x0d}};
242   auto uint24_view =
243       UIntViewN<24>{BitBlockN<24>{ReadWriteContiguousBuffer{bytes.data(), 3}}};
244   EXPECT_EQ(0x0e0f10U, uint24_view.Read());
245   EXPECT_EQ(0x0e0f10U, uint24_view.UncheckedRead());
246 #if EMBOSS_CHECK_ABORTS
247   EXPECT_DEATH(uint24_view.Write(0x1000000), "");
248 #endif  // EMBOSS_CHECK_ABORTS
249   uint24_view.Write(0x100f0e);
250   EXPECT_EQ((::std::vector</**/ ::std::uint8_t>{{0x0e, 0x0f, 0x10, 0x0d}}),
251             bytes);
252   uint24_view.UncheckedWrite(0x1000000);
253   EXPECT_EQ((::std::vector</**/ ::std::uint8_t>{{0x00, 0x00, 0x00, 0x0d}}),
254             bytes);
255   EXPECT_TRUE(uint24_view.Ok());
256   EXPECT_TRUE(uint24_view.IsComplete());
257 }
258 
TEST(UIntView,NonPowerOfTwoSizeInsufficientBuffer)259 TEST(UIntView, NonPowerOfTwoSizeInsufficientBuffer) {
260   ::std::vector</**/ ::std::uint8_t> bytes = {{0x10, 0x0f, 0x0e, 0x0d}};
261   auto uint24_view =
262       UIntViewN<24>{BitBlockN<24>{ReadWriteContiguousBuffer{bytes.data(), 2}}};
263   EXPECT_EQ(0x0e0f10U, uint24_view.UncheckedRead());
264 #if EMBOSS_CHECK_ABORTS
265   EXPECT_DEATH(uint24_view.Read(), "");
266   EXPECT_DEATH(uint24_view.Write(0x100f0e), "");
267 #endif  // EMBOSS_CHECK_ABORTS
268   uint24_view.UncheckedWrite(0x100f0e);
269   EXPECT_EQ((::std::vector</**/ ::std::uint8_t>{{0x0e, 0x0f, 0x10, 0x0d}}),
270             bytes);
271   uint24_view.UncheckedWrite(0x1000000);
272   EXPECT_EQ((::std::vector</**/ ::std::uint8_t>{{0x00, 0x00, 0x00, 0x0d}}),
273             bytes);
274   EXPECT_FALSE(uint24_view.Ok());
275   EXPECT_FALSE(uint24_view.IsComplete());
276 }
277 
TEST(UIntView,NonByteSize)278 TEST(UIntView, NonByteSize) {
279   ::std::vector</**/ ::std::uint8_t> bytes = {{0x00, 0x00, 0x80, 0x80}};
280   auto uint23_view =
281       UIntView<ViewParameters<23>, OffsetBitBlock<BitBlockN<24>>>{BitBlockN<24>{
282           ReadWriteContiguousBuffer{bytes.data(),
283                                     3}}.GetOffsetStorage<1, 0>(0, 23)};
284   EXPECT_EQ(0x0U, uint23_view.Read());
285   EXPECT_FALSE(uint23_view.CouldWriteValue(0x800f0e));
286   EXPECT_FALSE(uint23_view.CouldWriteValue(0x800000));
287   EXPECT_TRUE(uint23_view.CouldWriteValue(0x7fffff));
288 #if EMBOSS_CHECK_ABORTS
289   EXPECT_DEATH(uint23_view.Write(0x800f0e), "");
290 #endif  // EMBOSS_CHECK_ABORTS
291   uint23_view.Write(0x400f0e);
292   EXPECT_EQ((::std::vector</**/ ::std::uint8_t>{{0x0e, 0x0f, 0xc0, 0x80}}),
293             bytes);
294   uint23_view.UncheckedWrite(0x1000000);
295   EXPECT_EQ((::std::vector</**/ ::std::uint8_t>{{0x00, 0x00, 0x80, 0x80}}),
296             bytes);
297   EXPECT_TRUE(uint23_view.Ok());
298   EXPECT_TRUE(uint23_view.IsComplete());
299 }
300 
TEST(UIntView,TextDecode)301 TEST(UIntView, TextDecode) {
302   ::std::vector</**/ ::std::uint8_t> bytes = {{0x00, 0x00, 0x00, 0xff}};
303   const auto uint24_view =
304       UIntViewN<24>{BitBlockN<24>{ReadWriteContiguousBuffer{bytes.data(), 3}}};
305   EXPECT_TRUE(UpdateFromText(uint24_view, "23"));
306   EXPECT_EQ((::std::vector</**/ ::std::uint8_t>{{23, 0x00, 0x00, 0xff}}),
307             bytes);
308   EXPECT_EQ(23U, uint24_view.Read());
309   EXPECT_FALSE(UpdateFromText(uint24_view, "16777216"));
310   EXPECT_EQ((::std::vector</**/ ::std::uint8_t>{{23, 0x00, 0x00, 0xff}}),
311             bytes);
312   EXPECT_TRUE(UpdateFromText(uint24_view, "16777215"));
313   EXPECT_EQ((::std::vector</**/ ::std::uint8_t>{{0xff, 0xff, 0xff, 0xff}}),
314             bytes);
315   EXPECT_TRUE(UpdateFromText(uint24_view, "0x01_0203"));
316   EXPECT_EQ((::std::vector</**/ ::std::uint8_t>{{0x03, 0x02, 0x01, 0xff}}),
317             bytes);
318 }
319 
320 template </**/ ::std::size_t kBits>
321 using IntViewN = IntView<ViewParameters<kBits>, BitBlockN<kBits>>;
322 
TEST(IntView,ValueType)323 TEST(IntView, ValueType) {
324   using BitBlockType = BitBlockN<64>;
325   EXPECT_TRUE((::std::is_same<
326                /**/ ::std::int8_t,
327                IntView<ViewParameters<8>, BitBlockType>::ValueType>::value));
328   EXPECT_TRUE((::std::is_same<
329                /**/ ::std::int8_t,
330                IntView<ViewParameters<6>, BitBlockType>::ValueType>::value));
331   EXPECT_TRUE((::std::is_same<
332                /**/ ::std::int16_t,
333                IntView<ViewParameters<9>, BitBlockType>::ValueType>::value));
334   EXPECT_TRUE((::std::is_same<
335                /**/ ::std::int16_t,
336                IntView<ViewParameters<16>, BitBlockType>::ValueType>::value));
337   EXPECT_TRUE((::std::is_same<
338                /**/ ::std::int32_t,
339                IntView<ViewParameters<17>, BitBlockType>::ValueType>::value));
340   EXPECT_TRUE((::std::is_same<
341                /**/ ::std::int32_t,
342                IntView<ViewParameters<32>, BitBlockType>::ValueType>::value));
343   EXPECT_TRUE((::std::is_same<
344                /**/ ::std::int64_t,
345                IntView<ViewParameters<33>, BitBlockType>::ValueType>::value));
346   EXPECT_TRUE((::std::is_same<
347                /**/ ::std::int64_t,
348                IntView<ViewParameters<64>, BitBlockType>::ValueType>::value));
349 }
350 
TEST(IntView,CouldWriteValue)351 TEST(IntView, CouldWriteValue) {
352   // Note that many values are in decimal in order to avoid C++'s implicit
353   // conversions to unsigned for hex constants.
354   EXPECT_TRUE(IntViewN<8>::CouldWriteValue(0x7f));
355   EXPECT_TRUE(IntViewN<8>::CouldWriteValue(-0x80));
356   EXPECT_FALSE(IntViewN<8>::CouldWriteValue(0x80));
357   EXPECT_FALSE(IntViewN<8>::CouldWriteValue(0x8000000000000000UL));
358   EXPECT_FALSE(IntViewN<8>::CouldWriteValue(-0x81));
359   EXPECT_TRUE(IntViewN<16>::CouldWriteValue(32767));
360   EXPECT_TRUE(IntViewN<16>::CouldWriteValue(0));
361   EXPECT_FALSE(IntViewN<16>::CouldWriteValue(0x8000));
362   EXPECT_FALSE(IntViewN<16>::CouldWriteValue(-0x8001));
363   EXPECT_TRUE(IntViewN<32>::CouldWriteValue(0x7fffffffU));
364   EXPECT_TRUE(IntViewN<32>::CouldWriteValue(0x7fffffffL));
365   EXPECT_FALSE(IntViewN<32>::CouldWriteValue(0x80000000U));
366   EXPECT_FALSE(IntViewN<32>::CouldWriteValue(-2147483649L));
367   EXPECT_TRUE(IntViewN<48>::CouldWriteValue(0x00007fffffffffffUL));
368   EXPECT_FALSE(IntViewN<48>::CouldWriteValue(140737488355328L));
369   EXPECT_FALSE(IntViewN<48>::CouldWriteValue(-140737488355329L));
370   EXPECT_TRUE(IntViewN<64>::CouldWriteValue(0x7fffffffffffffffUL));
371   EXPECT_TRUE(IntViewN<64>::CouldWriteValue(9223372036854775807L));
372   EXPECT_TRUE(IntViewN<64>::CouldWriteValue(-9223372036854775807L - 1));
373   EXPECT_FALSE(IntViewN<64>::CouldWriteValue(0x8000000000000000UL));
374 }
375 
TEST(IntView,CouldWriteValueNarrowing)376 TEST(IntView, CouldWriteValueNarrowing) {
377   auto narrowing_could_write = [](int value) {
378     return IntViewN<8>::CouldWriteValue(value);
379   };
380   EXPECT_TRUE(narrowing_could_write(-128));
381   EXPECT_TRUE(narrowing_could_write(127));
382   EXPECT_FALSE(narrowing_could_write(-129));
383   EXPECT_FALSE(narrowing_could_write(128));
384 }
385 
TEST(IntView,ReadAndWriteWithSufficientBuffer)386 TEST(IntView, ReadAndWriteWithSufficientBuffer) {
387   ::std::vector</**/ ::std::uint8_t> bytes = {
388       {0x10, 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08}};
389   auto int64_view =
390       IntViewN<64>{BitBlockN<64>{ReadWriteContiguousBuffer{bytes.data(), 8}}};
391   EXPECT_EQ(0x090a0b0c0d0e0f10L, int64_view.Read());
392   EXPECT_EQ(0x090a0b0c0d0e0f10L, int64_view.UncheckedRead());
393   int64_view.Write(0x100f0e0d0c0b0a09L);
394   EXPECT_EQ((::std::vector</**/ ::std::uint8_t>{
395                 {0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x08}}),
396             bytes);
397   int64_view.UncheckedWrite(0x090a0b0c0d0e0f10L);
398   EXPECT_EQ((::std::vector</**/ ::std::uint8_t>{
399                 {0x10, 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08}}),
400             bytes);
401   EXPECT_TRUE(int64_view.TryToWrite(0x100f0e0d0c0b0a09L));
402   EXPECT_EQ((::std::vector</**/ ::std::uint8_t>{
403                 {0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x08}}),
404             bytes);
405   int64_view.Write(-0x100f0e0d0c0b0a09L);
406   EXPECT_EQ(-0x100f0e0d0c0b0a09L, int64_view.Read());
407   EXPECT_EQ((::std::vector</**/ ::std::uint8_t>{
408                 {0xf7, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0, 0xef, 0x08}}),
409             bytes);
410   EXPECT_TRUE(int64_view.Ok());
411   EXPECT_TRUE(int64_view.IsComplete());
412 }
413 
TEST(IntView,ReadAndWriteWithInsufficientBuffer)414 TEST(IntView, ReadAndWriteWithInsufficientBuffer) {
415   ::std::vector</**/ ::std::uint8_t> bytes = {
416       {0x10, 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08}};
417   auto int64_view =
418       IntViewN<64>{BitBlockN<64>{ReadWriteContiguousBuffer{bytes.data(), 4}}};
419   EXPECT_EQ(0x090a0b0c0d0e0f10L, int64_view.UncheckedRead());
420 #if EMBOSS_CHECK_ABORTS
421   EXPECT_DEATH(int64_view.Read(), "");
422   EXPECT_DEATH(int64_view.Write(0x100f0e0d0c0b0a09L), "");
423 #endif  // EMBOSS_CHECK_ABORTS
424   EXPECT_FALSE(int64_view.TryToWrite(0x100f0e0d0c0b0a09L));
425   EXPECT_EQ((::std::vector</**/ ::std::uint8_t>{
426                 {0x10, 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08}}),
427             bytes);
428   int64_view.UncheckedWrite(0x100f0e0d0c0b0a09L);
429   EXPECT_EQ((::std::vector</**/ ::std::uint8_t>{
430                 {0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x08}}),
431             bytes);
432   EXPECT_FALSE(int64_view.Ok());
433   EXPECT_FALSE(int64_view.IsComplete());
434 }
435 
TEST(IntView,NonPowerOfTwoSize)436 TEST(IntView, NonPowerOfTwoSize) {
437   ::std::vector</**/ ::std::uint8_t> bytes = {{0x10, 0x0f, 0x0e, 0x0d}};
438   auto int24_view =
439       IntViewN<24>{BitBlockN<24>{ReadWriteContiguousBuffer{bytes.data(), 3}}};
440   EXPECT_EQ(0x0e0f10, int24_view.Read());
441   EXPECT_EQ(0x0e0f10, int24_view.UncheckedRead());
442 #if EMBOSS_CHECK_ABORTS
443   EXPECT_DEATH(int24_view.Write(0x1000000), "");
444 #endif  // EMBOSS_CHECK_ABORTS
445   int24_view.Write(0x100f0e);
446   EXPECT_EQ((::std::vector</**/ ::std::uint8_t>{{0x0e, 0x0f, 0x10, 0x0d}}),
447             bytes);
448   int24_view.Write(-0x100f0e);
449   EXPECT_EQ((::std::vector</**/ ::std::uint8_t>{{0xf2, 0xf0, 0xef, 0x0d}}),
450             bytes);
451 #if EMBOSS_CHECK_ABORTS
452   EXPECT_DEATH(int24_view.Write(0x1000000), "");
453 #endif  // EMBOSS_CHECK_ABORTS
454   int24_view.UncheckedWrite(0x1000000);
455   EXPECT_EQ((::std::vector</**/ ::std::uint8_t>{{0x00, 0x00, 0x00, 0x0d}}),
456             bytes);
457   EXPECT_TRUE(int24_view.Ok());
458   EXPECT_TRUE(int24_view.IsComplete());
459 }
460 
TEST(IntView,NonPowerOfTwoSizeInsufficientBuffer)461 TEST(IntView, NonPowerOfTwoSizeInsufficientBuffer) {
462   ::std::vector</**/ ::std::uint8_t> bytes = {{0x10, 0x0f, 0x0e, 0x0d}};
463   auto int24_view =
464       IntViewN<24>{BitBlockN<24>{ReadWriteContiguousBuffer{bytes.data(), 2}}};
465   EXPECT_EQ(0x0e0f10, int24_view.UncheckedRead());
466 #if EMBOSS_CHECK_ABORTS
467   EXPECT_DEATH(int24_view.Read(), "");
468   EXPECT_DEATH(int24_view.Write(0x100f0e), "");
469 #endif  // EMBOSS_CHECK_ABORTS
470   int24_view.UncheckedWrite(0x100f0e);
471   EXPECT_EQ((::std::vector</**/ ::std::uint8_t>{{0x0e, 0x0f, 0x10, 0x0d}}),
472             bytes);
473   int24_view.UncheckedWrite(0x1000000);
474   EXPECT_EQ((::std::vector</**/ ::std::uint8_t>{{0x00, 0x00, 0x00, 0x0d}}),
475             bytes);
476   EXPECT_FALSE(int24_view.Ok());
477   EXPECT_FALSE(int24_view.IsComplete());
478 }
479 
TEST(IntView,NonByteSize)480 TEST(IntView, NonByteSize) {
481   ::std::vector</**/ ::std::uint8_t> bytes = {{0x00, 0x00, 0x80, 0x80}};
482   auto int23_view =
483       IntView<ViewParameters<23>, OffsetBitBlock<BitBlockN<24>>>{BitBlockN<24>{
484           ReadWriteContiguousBuffer{bytes.data(),
485                                     3}}.GetOffsetStorage<1, 0>(0, 23)};
486   EXPECT_EQ(0x0, int23_view.Read());
487   EXPECT_FALSE(int23_view.CouldWriteValue(0x400f0e));
488 #if EMBOSS_CHECK_ABORTS
489   EXPECT_DEATH(int23_view.Write(0x400f0e), "");
490 #endif  // EMBOSS_CHECK_ABORTS
491   int23_view.Write(0x200f0e);
492   EXPECT_EQ((::std::vector</**/ ::std::uint8_t>{{0x0e, 0x0f, 0xa0, 0x80}}),
493             bytes);
494   int23_view.Write(-0x400000);
495   EXPECT_EQ((::std::vector</**/ ::std::uint8_t>{{0x00, 0x00, 0xc0, 0x80}}),
496             bytes);
497   int23_view.UncheckedWrite(0x1000000);
498   EXPECT_EQ((::std::vector</**/ ::std::uint8_t>{{0x00, 0x00, 0x80, 0x80}}),
499             bytes);
500   EXPECT_TRUE(int23_view.Ok());
501   EXPECT_TRUE(int23_view.IsComplete());
502 }
503 
TEST(IntView,OneBit)504 TEST(IntView, OneBit) {
505   ::std::uint8_t bytes[] = {0xfe};
506   auto int1_view =
507       IntView<ViewParameters<1>, OffsetBitBlock<BitBlockN<8>>>{BitBlockN<8>{
508           ReadWriteContiguousBuffer{bytes, 1}}.GetOffsetStorage<1, 0>(0, 1)};
509   EXPECT_TRUE(int1_view.Ok());
510   EXPECT_TRUE(int1_view.IsComplete());
511   EXPECT_EQ(0, int1_view.Read());
512   EXPECT_FALSE(int1_view.CouldWriteValue(1));
513   EXPECT_TRUE(int1_view.CouldWriteValue(0));
514   EXPECT_TRUE(int1_view.CouldWriteValue(-1));
515 #if EMBOSS_CHECK_ABORTS
516   EXPECT_DEATH(int1_view.Write(1), "");
517 #endif  // EMBOSS_CHECK_ABORTS
518   int1_view.Write(-1);
519   EXPECT_EQ(0xff, bytes[0]);
520   EXPECT_EQ(-1, int1_view.Read());
521   int1_view.Write(0);
522   EXPECT_EQ(0xfe, bytes[0]);
523   bytes[0] = 0;
524   int1_view.Write(-1);
525   EXPECT_EQ(0x01, bytes[0]);
526 }
527 
TEST(IntView,TextDecode)528 TEST(IntView, TextDecode) {
529   ::std::vector</**/ ::std::uint8_t> bytes = {{0x00, 0x00, 0x00, 0xff}};
530   const auto int24_view =
531       IntViewN<24>{BitBlockN<24>{ReadWriteContiguousBuffer{bytes.data(), 3}}};
532   EXPECT_TRUE(UpdateFromText(int24_view, "23"));
533   EXPECT_EQ((::std::vector</**/ ::std::uint8_t>{{23, 0x00, 0x00, 0xff}}),
534             bytes);
535   EXPECT_EQ(23, int24_view.Read());
536   EXPECT_FALSE(UpdateFromText(int24_view, "16777216"));
537   EXPECT_EQ((::std::vector</**/ ::std::uint8_t>{{23, 0x00, 0x00, 0xff}}),
538             bytes);
539   EXPECT_FALSE(UpdateFromText(int24_view, "16777215"));
540   EXPECT_EQ((::std::vector</**/ ::std::uint8_t>{{23, 0x00, 0x00, 0xff}}),
541             bytes);
542   EXPECT_FALSE(UpdateFromText(int24_view, "8388608"));
543   EXPECT_EQ((::std::vector</**/ ::std::uint8_t>{{23, 0x00, 0x00, 0xff}}),
544             bytes);
545   EXPECT_TRUE(UpdateFromText(int24_view, "8388607"));
546   EXPECT_EQ((::std::vector</**/ ::std::uint8_t>{{0xff, 0xff, 0x7f, 0xff}}),
547             bytes);
548   EXPECT_TRUE(UpdateFromText(int24_view, "-8388608"));
549   EXPECT_EQ((::std::vector</**/ ::std::uint8_t>{{0x00, 0x00, 0x80, 0xff}}),
550             bytes);
551   EXPECT_TRUE(UpdateFromText(int24_view, "-1"));
552   EXPECT_EQ((::std::vector</**/ ::std::uint8_t>{{0xff, 0xff, 0xff, 0xff}}),
553             bytes);
554   EXPECT_TRUE(UpdateFromText(int24_view, "0x01_0203"));
555   EXPECT_EQ((::std::vector</**/ ::std::uint8_t>{{0x03, 0x02, 0x01, 0xff}}),
556             bytes);
557   EXPECT_TRUE(UpdateFromText(int24_view, "-0x01_0203"));
558   EXPECT_EQ((::std::vector</**/ ::std::uint8_t>{{0xfd, 0xfd, 0xfe, 0xff}}),
559             bytes);
560   EXPECT_FALSE(UpdateFromText(int24_view, "- 0x01_0203"));
561   EXPECT_EQ((::std::vector</**/ ::std::uint8_t>{{0xfd, 0xfd, 0xfe, 0xff}}),
562             bytes);
563 }
564 
TEST(MaxBcd,Values)565 TEST(MaxBcd, Values) {
566   EXPECT_EQ(0U, MaxBcd</**/ ::std::uint64_t>(0));
567   EXPECT_EQ(1U, MaxBcd</**/ ::std::uint64_t>(1));
568   EXPECT_EQ(3U, MaxBcd</**/ ::std::uint64_t>(2));
569   EXPECT_EQ(7U, MaxBcd</**/ ::std::uint64_t>(3));
570   EXPECT_EQ(9U, MaxBcd</**/ ::std::uint64_t>(4));
571   EXPECT_EQ(19U, MaxBcd</**/ ::std::uint64_t>(5));
572   EXPECT_EQ(39U, MaxBcd</**/ ::std::uint64_t>(6));
573   EXPECT_EQ(79U, MaxBcd</**/ ::std::uint64_t>(7));
574   EXPECT_EQ(99U, MaxBcd</**/ ::std::uint64_t>(8));
575   EXPECT_EQ(199U, MaxBcd</**/ ::std::uint64_t>(9));
576   EXPECT_EQ(999U, MaxBcd</**/ ::std::uint64_t>(12));
577   EXPECT_EQ(9999U, MaxBcd</**/ ::std::uint64_t>(16));
578   EXPECT_EQ(999999U, MaxBcd</**/ ::std::uint64_t>(24));
579   EXPECT_EQ(3999999999999999UL, MaxBcd</**/ ::std::uint64_t>(62));
580   EXPECT_EQ(7999999999999999UL, MaxBcd</**/ ::std::uint64_t>(63));
581   EXPECT_EQ(9999999999999999UL, MaxBcd</**/ ::std::uint64_t>(64));
582   // Max uint64_t is 18446744073709551616, which is big enough to hold a 76-bit
583   // BCD value.
584   EXPECT_EQ(19999999999999999UL, MaxBcd</**/ ::std::uint64_t>(65));
585   EXPECT_EQ(39999999999999999UL, MaxBcd</**/ ::std::uint64_t>(66));
586   EXPECT_EQ(99999999999999999UL, MaxBcd</**/ ::std::uint64_t>(68));
587   EXPECT_EQ(999999999999999999UL, MaxBcd</**/ ::std::uint64_t>(72));
588   EXPECT_EQ(9999999999999999999UL, MaxBcd</**/ ::std::uint64_t>(76));
589 }
590 
TEST(IsBcd,Values)591 TEST(IsBcd, Values) {
592   EXPECT_TRUE(IsBcd(0x00U));
593   EXPECT_TRUE(IsBcd(0x12U));
594   EXPECT_TRUE(IsBcd(0x91U));
595   EXPECT_TRUE(IsBcd(0x99U));
596   EXPECT_TRUE(IsBcd(::std::uint8_t{0x00}));
597   EXPECT_TRUE(IsBcd(::std::uint8_t{0x99}));
598   EXPECT_TRUE(IsBcd(::std::uint16_t{0x0000}));
599   EXPECT_TRUE(IsBcd(::std::uint16_t{0x9999}));
600   EXPECT_TRUE(IsBcd(0x9999999999999999UL));
601   EXPECT_FALSE(IsBcd(::std::uint8_t{0x0a}));
602   EXPECT_FALSE(IsBcd(::std::uint8_t{0xa0}));
603   EXPECT_FALSE(IsBcd(::std::uint8_t{0xff}));
604   EXPECT_FALSE(IsBcd(::std::uint16_t{0x0a00}));
605   EXPECT_FALSE(IsBcd(::std::uint16_t{0x000a}));
606   EXPECT_FALSE(IsBcd(0x999999999999999aUL));
607   EXPECT_FALSE(IsBcd(0xaUL));
608   EXPECT_FALSE(IsBcd(0xa000000000000000UL));
609   EXPECT_FALSE(IsBcd(0xf000000000000000UL));
610   EXPECT_FALSE(IsBcd(0xffffffffffffffffUL));
611 }
612 
TEST(BcdView,ValueType)613 TEST(BcdView, ValueType) {
614   using BitBlockType = BitBlockN<64>;
615   EXPECT_TRUE((::std::is_same<
616                /**/ ::std::uint8_t,
617                BcdView<ViewParameters<8>, BitBlockType>::ValueType>::value));
618   EXPECT_TRUE((::std::is_same<
619                /**/ ::std::uint8_t,
620                BcdView<ViewParameters<6>, BitBlockType>::ValueType>::value));
621   EXPECT_TRUE((::std::is_same<
622                /**/ ::std::uint16_t,
623                BcdView<ViewParameters<9>, BitBlockType>::ValueType>::value));
624   EXPECT_TRUE((::std::is_same<
625                /**/ ::std::uint16_t,
626                BcdView<ViewParameters<16>, BitBlockType>::ValueType>::value));
627   EXPECT_TRUE((::std::is_same<
628                /**/ ::std::uint32_t,
629                BcdView<ViewParameters<17>, BitBlockType>::ValueType>::value));
630   EXPECT_TRUE((::std::is_same<
631                /**/ ::std::uint32_t,
632                BcdView<ViewParameters<32>, BitBlockType>::ValueType>::value));
633   EXPECT_TRUE((::std::is_same<
634                /**/ ::std::uint64_t,
635                BcdView<ViewParameters<33>, BitBlockType>::ValueType>::value));
636   EXPECT_TRUE((::std::is_same<
637                /**/ ::std::uint64_t,
638                BcdView<ViewParameters<64>, BitBlockType>::ValueType>::value));
639 }
640 
TEST(BcdView,CouldWriteValue)641 TEST(BcdView, CouldWriteValue) {
642   EXPECT_TRUE((BcdView<ViewParameters<64>, int>::CouldWriteValue(0)));
643   EXPECT_TRUE(
644       (BcdView<ViewParameters<64>, int>::CouldWriteValue(9999999999999999)));
645   EXPECT_FALSE(
646       (BcdView<ViewParameters<64>, int>::CouldWriteValue(10000000000000000)));
647   EXPECT_FALSE((
648       BcdView<ViewParameters<64>, int>::CouldWriteValue(0xffffffffffffffffUL)));
649   EXPECT_FALSE(
650       (BcdView<ViewParameters<48>, int>::CouldWriteValue(9999999999999999)));
651   EXPECT_TRUE(
652       (BcdView<ViewParameters<48>, int>::CouldWriteValue(999999999999)));
653   EXPECT_TRUE((BcdView<ViewParameters<48>, int>::CouldWriteValue(0)));
654   EXPECT_FALSE((BcdView<ViewParameters<48>, int>::CouldWriteValue(
655       (0xffUL << 48) + 999999999999)));
656   EXPECT_FALSE(
657       (BcdView<ViewParameters<48>, int>::CouldWriteValue(10000000000000000)));
658   EXPECT_FALSE((
659       BcdView<ViewParameters<48>, int>::CouldWriteValue(0xffffffffffffffffUL)));
660 }
661 
662 template </**/ ::std::size_t kBits>
663 using BcdViewN = BcdView<ViewParameters<kBits>, BitBlockN<kBits>>;
664 
TEST(BcdView,ReadAndWriteWithSufficientBuffer)665 TEST(BcdView, ReadAndWriteWithSufficientBuffer) {
666   ::std::vector</**/ ::std::uint8_t> bytes = {
667       {0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x09, 0x08}};
668   auto bcd64_view =
669       BcdViewN<64>{BitBlockN<64>{ReadWriteContiguousBuffer{bytes.data(), 8}}};
670   EXPECT_EQ(910111213141516UL, bcd64_view.Read());
671   EXPECT_EQ(910111213141516UL, bcd64_view.UncheckedRead());
672   bcd64_view.Write(1615141312111009);
673   EXPECT_EQ((::std::vector</**/ ::std::uint8_t>{
674                 {0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x08}}),
675             bytes);
676   bcd64_view.UncheckedWrite(910111213141516UL);
677   EXPECT_EQ((::std::vector</**/ ::std::uint8_t>{
678                 {0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x09, 0x08}}),
679             bytes);
680   EXPECT_TRUE(bcd64_view.TryToWrite(1615141312111009));
681   EXPECT_EQ((::std::vector</**/ ::std::uint8_t>{
682                 {0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x08}}),
683             bytes);
684   EXPECT_TRUE(bcd64_view.Ok());
685   EXPECT_TRUE(bcd64_view.IsComplete());
686 }
687 
TEST(BcdView,ReadAndWriteWithInsufficientBuffer)688 TEST(BcdView, ReadAndWriteWithInsufficientBuffer) {
689   ::std::vector</**/ ::std::uint8_t> bytes = {
690       {0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x09, 0x08}};
691   auto bcd64_view =
692       BcdViewN<64>{BitBlockN<64>{ReadWriteContiguousBuffer{bytes.data(), 4}}};
693   EXPECT_EQ(910111213141516UL, bcd64_view.UncheckedRead());
694 #if EMBOSS_CHECK_ABORTS
695   EXPECT_DEATH(bcd64_view.Read(), "");
696   EXPECT_DEATH(bcd64_view.Write(1615141312111009), "");
697 #endif  // EMBOSS_CHECK_ABORTS
698   EXPECT_FALSE(bcd64_view.TryToWrite(1615141312111009));
699   EXPECT_EQ((::std::vector</**/ ::std::uint8_t>{
700                 {0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x09, 0x08}}),
701             bytes);
702   bcd64_view.UncheckedWrite(1615141312111009);
703   EXPECT_EQ((::std::vector</**/ ::std::uint8_t>{
704                 {0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x08}}),
705             bytes);
706   EXPECT_FALSE(bcd64_view.Ok());
707   EXPECT_FALSE(bcd64_view.IsComplete());
708 }
709 
TEST(BcdView,NonPowerOfTwoSize)710 TEST(BcdView, NonPowerOfTwoSize) {
711   ::std::vector</**/ ::std::uint8_t> bytes = {{0x16, 0x15, 0x14, 0x13}};
712   auto bcd24_view =
713       BcdViewN<24>{BitBlockN<24>{ReadWriteContiguousBuffer{bytes.data(), 3}}};
714   EXPECT_EQ(141516U, bcd24_view.Read());
715   EXPECT_EQ(141516U, bcd24_view.UncheckedRead());
716   bcd24_view.Write(161514);
717   EXPECT_EQ((::std::vector</**/ ::std::uint8_t>{{0x14, 0x15, 0x16, 0x13}}),
718             bytes);
719 #if EMBOSS_CHECK_ABORTS
720   EXPECT_DEATH(bcd24_view.Write(1000000), "");
721 #endif  // EMBOSS_CHECK_ABORTS
722   bcd24_view.UncheckedWrite(1000000);
723   EXPECT_EQ((::std::vector</**/ ::std::uint8_t>{{0x00, 0x00, 0x00, 0x13}}),
724             bytes);
725   bcd24_view.UncheckedWrite(141516);
726   EXPECT_EQ((::std::vector</**/ ::std::uint8_t>{{0x16, 0x15, 0x14, 0x13}}),
727             bytes);
728   EXPECT_TRUE(bcd24_view.Ok());
729   EXPECT_TRUE(bcd24_view.IsComplete());
730 }
731 
TEST(BcdView,NonPowerOfTwoSizeInsufficientBuffer)732 TEST(BcdView, NonPowerOfTwoSizeInsufficientBuffer) {
733   ::std::vector</**/ ::std::uint8_t> bytes = {{0x16, 0x15, 0x14, 0x13}};
734   auto bcd24_view =
735       BcdViewN<24>{BitBlockN<24>{ReadWriteContiguousBuffer{bytes.data(), 2}}};
736   EXPECT_EQ(141516U, bcd24_view.UncheckedRead());
737 #if EMBOSS_CHECK_ABORTS
738   EXPECT_DEATH(bcd24_view.Read(), "");
739   EXPECT_DEATH(bcd24_view.Write(161514), "");
740 #endif  // EMBOSS_CHECK_ABORTS
741   bcd24_view.UncheckedWrite(161514);
742   EXPECT_EQ((::std::vector</**/ ::std::uint8_t>{{0x14, 0x15, 0x16, 0x13}}),
743             bytes);
744   bcd24_view.UncheckedWrite(1000000);
745   EXPECT_EQ((::std::vector</**/ ::std::uint8_t>{{0x00, 0x00, 0x00, 0x13}}),
746             bytes);
747   EXPECT_FALSE(bcd24_view.Ok());
748   EXPECT_FALSE(bcd24_view.IsComplete());
749 }
750 
TEST(BcdView,NonByteSize)751 TEST(BcdView, NonByteSize) {
752   ::std::vector</**/ ::std::uint8_t> bytes = {{0x00, 0x00, 0x80, 0x80}};
753   auto bcd23_view =
754       BcdView<ViewParameters<23>, OffsetBitBlock<BitBlockN<24>>>{BitBlockN<24>{
755           ReadWriteContiguousBuffer{bytes.data(),
756                                     3}}.GetOffsetStorage<1, 0>(0, 23)};
757   EXPECT_EQ(0x0U, bcd23_view.Read());
758   EXPECT_FALSE(bcd23_view.CouldWriteValue(800000));
759   EXPECT_TRUE(bcd23_view.CouldWriteValue(799999));
760 #if EMBOSS_CHECK_ABORTS
761   EXPECT_DEATH(bcd23_view.Write(800000), "");
762 #endif  // EMBOSS_CHECK_ABORTS
763   bcd23_view.Write(432198);
764   EXPECT_EQ((::std::vector</**/ ::std::uint8_t>{{0x98, 0x21, 0xc3, 0x80}}),
765             bytes);
766   bcd23_view.UncheckedWrite(800000);
767   EXPECT_EQ((::std::vector</**/ ::std::uint8_t>{{0x00, 0x00, 0x80, 0x80}}),
768             bytes);
769   EXPECT_TRUE(bcd23_view.Ok());
770   EXPECT_TRUE(bcd23_view.IsComplete());
771 }
772 
TEST(BcdLittleEndianView,AllByteValues)773 TEST(BcdLittleEndianView, AllByteValues) {
774   ::std::uint8_t byte = 0;
775   auto bcd8_view =
776       BcdViewN<8>{BitBlockN<8>{ReadWriteContiguousBuffer{&byte, 1}}};
777   for (int i = 0; i < 15; ++i) {
778     for (int j = 0; j < 15; ++j) {
779       byte = i * 16 + j;
780       if (i > 9 || j > 9) {
781         EXPECT_FALSE(bcd8_view.Ok()) << i << ", " << j;
782       } else {
783         EXPECT_TRUE(bcd8_view.Ok()) << i << ", " << j;
784       }
785     }
786   }
787 }
788 
789 }  // namespace test
790 }  // namespace prelude
791 }  // namespace emboss
792