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 for Container and Box from
16 // nested_structure.emb.
17 //
18 // These tests check that nested structures work.
19 #include <stdint.h>
20
21 #include <vector>
22
23 #include "gtest/gtest.h"
24 #include "testdata/int_sizes.emb.h"
25
26 namespace emboss {
27 namespace test {
28 namespace {
29
30 alignas(8) static const ::std::uint8_t kIntSizes[36] = {
31 0x02, // 0:1 one_byte == 2
32 0xfc, 0xfe, // 1:3 two_byte == -260
33 0x66, 0x55, 0x44, // 3:6 three_byte == 0x445566
34 0xfa, 0xfa, 0xfb, 0xfc, // 6:10 four_byte == -0x03040506
35 0x21, 0x43, 0x65, 0x87, // 10:14 five_byte
36 0x29, // 14:15 five_byte == 0x2987654321
37 0x44, 0x65, 0x87, 0xa9, // 15:19 six_byte
38 0xcb, 0xed, // 19:21 six_byte == -0x123456789abc
39 0x97, 0xa6, 0xb5, 0xc4, // 21:25 seven_byte
40 0xd3, 0xe2, 0x71, // 25:28 seven_byte == 0x71e2d3c4b5a697
41 0xfa, 0xfa, 0xfb, 0xfc, // 28:32 eight_byte
42 0xfd, 0xfe, 0xff, 0x80, // 32:36 eight_byte == -0x7f00010203040506
43 };
44
TEST(SizesView,CanReadSizes)45 TEST(SizesView, CanReadSizes) {
46 auto view = MakeAlignedSizesView<const ::std::uint8_t, 8>(kIntSizes,
47 sizeof kIntSizes);
48 EXPECT_EQ(2, view.one_byte().Read());
49 EXPECT_EQ(-260, view.two_byte().Read());
50 EXPECT_EQ(0x445566, view.three_byte().Read());
51 EXPECT_EQ(-0x03040506, view.four_byte().Read());
52 EXPECT_EQ(0x2987654321, view.five_byte().Read());
53 EXPECT_EQ(-0x123456789abc, view.six_byte().Read());
54 EXPECT_EQ(0x71e2d3c4b5a697, view.seven_byte().Read());
55 EXPECT_EQ(-0x7f00010203040506, view.eight_byte().Read());
56 // Test that the views return appropriate integer widths.
57 EXPECT_EQ(1U, sizeof(view.one_byte().Read()));
58 EXPECT_EQ(2U, sizeof(view.two_byte().Read()));
59 EXPECT_EQ(4U, sizeof(view.three_byte().Read()));
60 EXPECT_EQ(4U, sizeof(view.four_byte().Read()));
61 EXPECT_EQ(8U, sizeof(view.five_byte().Read()));
62 EXPECT_EQ(8U, sizeof(view.six_byte().Read()));
63 EXPECT_EQ(8U, sizeof(view.seven_byte().Read()));
64 EXPECT_EQ(8U, sizeof(view.eight_byte().Read()));
65 }
66
TEST(SizesWriter,CanWriteSizes)67 TEST(SizesWriter, CanWriteSizes) {
68 ::std::uint8_t buffer[sizeof kIntSizes];
69 auto writer = SizesWriter(buffer, sizeof buffer);
70 writer.one_byte().Write(2);
71 writer.two_byte().Write(-260);
72 writer.three_byte().Write(0x445566);
73 writer.four_byte().Write(-0x03040506);
74 writer.five_byte().Write(0x2987654321);
75 writer.six_byte().Write(-0x123456789abc);
76 writer.seven_byte().Write(0x71e2d3c4b5a697);
77 writer.eight_byte().Write(-0x7f00010203040506);
78 EXPECT_EQ(::std::vector</**/ ::std::uint8_t>(kIntSizes,
79 kIntSizes + sizeof kIntSizes),
80 ::std::vector</**/ ::std::uint8_t>(buffer, buffer + sizeof buffer));
81 }
82
83 alignas(8) static const ::std::uint8_t kIntSizesNegativeOnes[36] = {
84 0xff, // 0:1 one_byte == -1
85 0xff, 0xff, // 1:3 two_byte == -1
86 0xff, 0xff, 0xff, // 3:6 three_byte == -1
87 0xff, 0xff, 0xff, 0xff, // 6:10 four_byte == -1
88 0xff, 0xff, 0xff, 0xff, // 10:14 five_byte
89 0xff, // 14:15 five_byte == -1
90 0xff, 0xff, 0xff, 0xff, // 15:19 six_byte
91 0xff, 0xff, // 19:21 six_byte == -1
92 0xff, 0xff, 0xff, 0xff, // 21:25 seven_byte
93 0xff, 0xff, 0xff, // 25:28 seven_byte == -1
94 0xff, 0xff, 0xff, 0xff, // 28:32 eight_byte
95 0xff, 0xff, 0xff, 0xff, // 32:36 eight_byte == -1
96 };
97
TEST(SizesView,CanReadNegativeOne)98 TEST(SizesView, CanReadNegativeOne) {
99 auto view = MakeAlignedSizesView<const ::std::uint8_t, 8>(
100 kIntSizesNegativeOnes, sizeof kIntSizesNegativeOnes);
101 EXPECT_EQ(-1, view.one_byte().Read());
102 EXPECT_EQ(-1, view.two_byte().Read());
103 EXPECT_EQ(-1, view.three_byte().Read());
104 EXPECT_EQ(-1, view.four_byte().Read());
105 EXPECT_EQ(-1, view.five_byte().Read());
106 EXPECT_EQ(-1, view.six_byte().Read());
107 EXPECT_EQ(-1, view.seven_byte().Read());
108 EXPECT_EQ(-1, view.eight_byte().Read());
109 }
110
TEST(SizesView,CanWriteNegativeOne)111 TEST(SizesView, CanWriteNegativeOne) {
112 ::std::uint8_t buffer[sizeof kIntSizesNegativeOnes];
113 auto writer = SizesWriter(buffer, sizeof buffer);
114 writer.one_byte().Write(-1);
115 writer.two_byte().Write(-1);
116 writer.three_byte().Write(-1);
117 writer.four_byte().Write(-1);
118 writer.five_byte().Write(-1);
119 writer.six_byte().Write(-1);
120 writer.seven_byte().Write(-1);
121 writer.eight_byte().Write(-1);
122 EXPECT_EQ(::std::vector</**/ ::std::uint8_t>(
123 kIntSizesNegativeOnes,
124 kIntSizesNegativeOnes + sizeof kIntSizesNegativeOnes),
125 ::std::vector</**/ ::std::uint8_t>(buffer, buffer + sizeof buffer));
126 }
127
TEST(SizesView,CopyFrom)128 TEST(SizesView, CopyFrom) {
129 ::std::array</**/ ::std::uint8_t, sizeof kIntSizesNegativeOnes> buf_x = {};
130 ::std::array</**/ ::std::uint8_t, sizeof kIntSizesNegativeOnes> buf_y = {};
131
132 auto x = SizesWriter(&buf_x);
133 auto y = SizesWriter(&buf_y);
134
135 constexpr int kValue = -1;
136 x.one_byte().Write(kValue);
137 EXPECT_NE(x.one_byte().Read(), y.one_byte().Read());
138 y.one_byte().CopyFrom(x.one_byte());
139 EXPECT_EQ(x.one_byte().Read(), y.one_byte().Read());
140 }
141
TEST(SizesView,TryToCopyFrom)142 TEST(SizesView, TryToCopyFrom) {
143 ::std::array</**/ ::std::uint8_t, sizeof kIntSizesNegativeOnes> buf_x = {};
144 ::std::array</**/ ::std::uint8_t, sizeof kIntSizesNegativeOnes> buf_y = {};
145
146 auto x = SizesWriter(&buf_x);
147 auto y = SizesWriter(&buf_y);
148
149 constexpr int kValue = -1;
150 x.one_byte().Write(kValue);
151 EXPECT_NE(x.one_byte().Read(), y.one_byte().Read());
152 EXPECT_TRUE(y.one_byte().TryToCopyFrom(x.one_byte()));
153 EXPECT_EQ(x.one_byte().Read(), y.one_byte().Read());
154 }
155
156 } // namespace
157 } // namespace test
158 } // namespace emboss
159