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