xref: /aosp_15_r20/external/emboss/runtime/cpp/test/emboss_array_view_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_array_view.h"
16 
17 #include <string>
18 #include <type_traits>
19 
20 #include "absl/strings/str_format.h"
21 #include "gtest/gtest.h"
22 #include "runtime/cpp/emboss_prelude.h"
23 #include "runtime/cpp/emboss_text_util.h"
24 
25 namespace emboss {
26 namespace support {
27 namespace test {
28 
29 using ::emboss::prelude::IntView;
30 using ::emboss::prelude::UIntView;
31 
32 template <class ElementView, class BufferType, ::std::size_t kElementSize>
33 using ArrayView = GenericArrayView<ElementView, BufferType, kElementSize, 8>;
34 
35 template <class ElementView, class BufferType, ::std::size_t kElementSize>
36 using BitArrayView = GenericArrayView<ElementView, BufferType, kElementSize, 1>;
37 
38 template </**/ ::std::size_t kBits>
39 using LittleEndianBitBlockN =
40     BitBlock<LittleEndianByteOrderer<ReadWriteContiguousBuffer>, kBits>;
41 
42 template </**/ ::std::size_t kBits>
43 using FixedUIntView = UIntView<FixedSizeViewParameters<kBits, AllValuesAreOk>,
44                                LittleEndianBitBlockN<kBits>>;
45 
46 template </**/ ::std::size_t kBits>
47 using FixedIntView = IntView<FixedSizeViewParameters<kBits, AllValuesAreOk>,
48                              LittleEndianBitBlockN<kBits>>;
49 
TEST(ArrayView,Methods)50 TEST(ArrayView, Methods) {
51   ::std::uint8_t bytes[] = {0x10, 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09,
52                             0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01};
53   auto byte_array = ArrayView<FixedUIntView<8>, ReadWriteContiguousBuffer, 1>{
54       ReadWriteContiguousBuffer{bytes, sizeof bytes - 4}};
55   EXPECT_EQ(sizeof bytes - 4, byte_array.SizeInBytes());
56   EXPECT_EQ(bytes[0], byte_array[0].Read());
57   EXPECT_EQ(bytes[1], byte_array[1].Read());
58   EXPECT_EQ(bytes[2], byte_array[2].Read());
59 #if EMBOSS_CHECK_ABORTS
60   EXPECT_DEATH(byte_array[sizeof bytes - 4].Read(), "");
61 #endif  // EMBOSS_CHECK_ABORTS
62   EXPECT_EQ(bytes[sizeof bytes - 4],
63             byte_array[sizeof bytes - 4].UncheckedRead());
64   EXPECT_TRUE(byte_array[sizeof bytes - 5].IsComplete());
65   EXPECT_FALSE(byte_array[sizeof bytes - 4].IsComplete());
66   EXPECT_TRUE(byte_array.Ok());
67   EXPECT_TRUE(byte_array.IsComplete());
68   EXPECT_FALSE((ArrayView<FixedUIntView<8>, ReadWriteContiguousBuffer, 1>{
69       ReadWriteContiguousBuffer{
70           nullptr}}.Ok()));
71   EXPECT_TRUE(byte_array.IsComplete());
72 
73   auto uint32_array =
74       ArrayView<FixedUIntView<32>, ReadWriteContiguousBuffer, 4>{
75           ReadWriteContiguousBuffer{bytes, sizeof bytes - 4}};
76   EXPECT_EQ(sizeof bytes - 4, uint32_array.SizeInBytes());
77   EXPECT_TRUE(uint32_array[0].Ok());
78   EXPECT_EQ(0x0d0e0f10U, uint32_array[0].Read());
79   EXPECT_EQ(0x090a0b0cU, uint32_array[1].Read());
80   EXPECT_EQ(0x05060708U, uint32_array[2].Read());
81 #if EMBOSS_CHECK_ABORTS
82   EXPECT_DEATH(uint32_array[3].Read(), "");
83 #endif  // EMBOSS_CHECK_ABORTS
84   EXPECT_EQ(0x01020304U, uint32_array[3].UncheckedRead());
85   EXPECT_TRUE(uint32_array[2].IsComplete());
86   EXPECT_FALSE(uint32_array[3].IsComplete());
87   EXPECT_TRUE(uint32_array.Ok());
88   EXPECT_TRUE(uint32_array.IsComplete());
89   EXPECT_FALSE((ArrayView<FixedUIntView<32>, ReadWriteContiguousBuffer, 1>{
90       ReadWriteContiguousBuffer{
91           nullptr}}.Ok()));
92 }
93 
TEST(ArrayView,Ok)94 TEST(ArrayView, Ok) {
95   ::std::uint8_t bytes[] = {0x10, 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09,
96                             0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01};
97   // All elements are complete and, themselves, Ok(), so the array should be
98   // Ok().
99   auto byte_array = ArrayView<FixedUIntView<16>, ReadWriteContiguousBuffer, 2>(
100       ReadWriteContiguousBuffer(bytes, sizeof bytes - 4));
101   EXPECT_TRUE(byte_array.Ok());
102 
103   // An array with a partial element at the end should not be Ok().
104   byte_array = ArrayView<FixedUIntView<16>, ReadWriteContiguousBuffer, 2>(
105       ReadWriteContiguousBuffer(bytes, sizeof bytes - 3));
106   EXPECT_FALSE(byte_array.Ok());
107 
108   // An empty array should be Ok().
109   byte_array = ArrayView<FixedUIntView<16>, ReadWriteContiguousBuffer, 2>(
110       ReadWriteContiguousBuffer(bytes, 0));
111   EXPECT_TRUE(byte_array.Ok());
112 }
113 
TEST(ArrayView,TextFormatInput)114 TEST(ArrayView, TextFormatInput) {
115   ::std::uint8_t bytes[16] = {0};
116   auto byte_array = ArrayView<FixedUIntView<8>, ReadWriteContiguousBuffer, 1>{
117       ReadWriteContiguousBuffer{bytes, sizeof bytes}};
118   EXPECT_FALSE(UpdateFromText(byte_array, ""));
119   EXPECT_FALSE(UpdateFromText(byte_array, "[]"));
120   EXPECT_FALSE(UpdateFromText(byte_array, "{"));
121   EXPECT_FALSE(UpdateFromText(byte_array, "{[0"));
122   EXPECT_FALSE(UpdateFromText(byte_array, "{[0:0}"));
123   EXPECT_FALSE(UpdateFromText(byte_array, "{[]:0}"));
124   EXPECT_FALSE(UpdateFromText(byte_array, "{[0] 0}"));
125   EXPECT_FALSE(UpdateFromText(byte_array, "{[0] 0}"));
126   EXPECT_TRUE(UpdateFromText(byte_array, "{}"));
127   EXPECT_FALSE(UpdateFromText(byte_array, "{,1}"));
128   EXPECT_FALSE(UpdateFromText(byte_array, "{1,,}"));
129   EXPECT_FALSE(UpdateFromText(byte_array, "{ a }"));
130   EXPECT_TRUE(UpdateFromText(byte_array, "{1}"));
131   EXPECT_EQ(1, bytes[0]);
132   EXPECT_TRUE(UpdateFromText(byte_array, " {2}"));
133   EXPECT_EQ(2, bytes[0]);
134   EXPECT_TRUE(UpdateFromText(byte_array, " {\t\r\n4  } junk"));
135   EXPECT_EQ(4, bytes[0]);
136   EXPECT_TRUE(UpdateFromText(byte_array, "{3,}"));
137   EXPECT_EQ(3, bytes[0]);
138   EXPECT_FALSE(UpdateFromText(byte_array, "{4 5}"));
139   EXPECT_TRUE(UpdateFromText(byte_array, "{4, 5}"));
140   EXPECT_EQ(4, bytes[0]);
141   EXPECT_EQ(5, bytes[1]);
142   EXPECT_TRUE(UpdateFromText(byte_array, "{5, [6]: 5}"));
143   EXPECT_EQ(5, bytes[0]);
144   EXPECT_EQ(5, bytes[1]);
145   EXPECT_EQ(5, bytes[6]);
146   EXPECT_TRUE(UpdateFromText(byte_array, "{6, [7]:6, 6}"));
147   EXPECT_EQ(6, bytes[0]);
148   EXPECT_EQ(5, bytes[1]);
149   EXPECT_EQ(5, bytes[6]);
150   EXPECT_EQ(6, bytes[7]);
151   EXPECT_EQ(6, bytes[8]);
152   EXPECT_TRUE(UpdateFromText(byte_array, "{[7]: 7, 7, [0]: 7, 7}"));
153   EXPECT_EQ(7, bytes[0]);
154   EXPECT_EQ(7, bytes[1]);
155   EXPECT_EQ(7, bytes[7]);
156   EXPECT_EQ(7, bytes[8]);
157   EXPECT_FALSE(UpdateFromText(byte_array, "{[16]: 0}"));
158   EXPECT_FALSE(UpdateFromText(byte_array, "{[15]: 0, 0}"));
159 }
160 
TEST(ArrayView,TextFormatOutput_WithAndWithoutComments)161 TEST(ArrayView, TextFormatOutput_WithAndWithoutComments) {
162   signed char bytes[16] = {-3, 2, -1, 1,  0,  1,  1,  2,
163                            3,  5, 8,  13, 21, 34, 55, 89};
164   auto buffer = ReadWriteContiguousBuffer{
165       reinterpret_cast</**/ ::std::uint8_t *>(bytes), sizeof bytes};
166   auto byte_array =
167       ArrayView<FixedIntView<8>, ReadWriteContiguousBuffer, 1>{buffer};
168   EXPECT_EQ(
169       "{ [0]: -3, 2, -1, 1, 0, 1, 1, 2, [8]: 3, 5, 8, 13, 21, 34, 55, 89 }",
170       WriteToString(byte_array));
171   EXPECT_EQ(WriteToString(byte_array, MultilineText()),
172             R"({
173   # ............."7Y
174   [0]: -3  # -0x3
175   [1]: 2  # 0x2
176   [2]: -1  # -0x1
177   [3]: 1  # 0x1
178   [4]: 0  # 0x0
179   [5]: 1  # 0x1
180   [6]: 1  # 0x1
181   [7]: 2  # 0x2
182   [8]: 3  # 0x3
183   [9]: 5  # 0x5
184   [10]: 8  # 0x8
185   [11]: 13  # 0xd
186   [12]: 21  # 0x15
187   [13]: 34  # 0x22
188   [14]: 55  # 0x37
189   [15]: 89  # 0x59
190 })");
191   EXPECT_EQ(
192       WriteToString(byte_array,
193                     MultilineText().WithIndent("    ").WithComments(false)),
194       R"({
195     [0]: -3
196     [1]: 2
197     [2]: -1
198     [3]: 1
199     [4]: 0
200     [5]: 1
201     [6]: 1
202     [7]: 2
203     [8]: 3
204     [9]: 5
205     [10]: 8
206     [11]: 13
207     [12]: 21
208     [13]: 34
209     [14]: 55
210     [15]: 89
211 })");
212   EXPECT_EQ(
213       WriteToString(byte_array, TextOutputOptions().WithNumericBase(16)),
214       "{ [0x0]: -0x3, 0x2, -0x1, 0x1, 0x0, 0x1, 0x1, 0x2, [0x8]: 0x3, 0x5, "
215       "0x8, 0xd, 0x15, 0x22, 0x37, 0x59 }");
216 }
217 
TEST(ArrayView,TextFormatOutput_8BitIntElementTypes)218 TEST(ArrayView, TextFormatOutput_8BitIntElementTypes) {
219   ::std::uint8_t bytes[1] = {65};
220   auto buffer = ReadWriteContiguousBuffer{bytes, sizeof bytes};
221   const ::std::string expected_text = R"({
222   # A
223   [0]: 65  # 0x41
224 })";
225   EXPECT_EQ(
226       WriteToString(
227           ArrayView<FixedIntView<8>, ReadWriteContiguousBuffer, 1>{buffer},
228           MultilineText()),
229       expected_text);
230   EXPECT_EQ(
231       WriteToString(
232           ArrayView<FixedUIntView<8>, ReadWriteContiguousBuffer, 1>{buffer},
233           MultilineText()),
234       expected_text);
235 }
236 
TEST(ArrayView,TextFormatOutput_16BitIntElementTypes)237 TEST(ArrayView, TextFormatOutput_16BitIntElementTypes) {
238   ::std::uint16_t bytes[1] = {65};
239   auto buffer = ReadWriteContiguousBuffer{
240       reinterpret_cast</**/ ::std::uint8_t *>(bytes), sizeof bytes};
241   const ::std::string expected_text = R"({
242   [0]: 65  # 0x41
243 })";
244   EXPECT_EQ(
245       WriteToString(
246           ArrayView<FixedIntView<16>, ReadWriteContiguousBuffer, 2>{buffer},
247           MultilineText()),
248       expected_text);
249   EXPECT_EQ(
250       WriteToString(
251           ArrayView<FixedUIntView<16>, ReadWriteContiguousBuffer, 2>{buffer},
252           MultilineText()),
253       expected_text);
254 }
255 
TEST(ArrayView,TextFormatOutput_MultilineComment)256 TEST(ArrayView, TextFormatOutput_MultilineComment) {
257   ::std::uint8_t bytes[65];
258   for (::std::size_t i = 0; i < sizeof bytes; ++i) {
259     bytes[i] = '0' + (i % 10);
260   }
261   for (const ::std::size_t length : {63, 64, 65}) {
262     auto buffer = ReadWriteContiguousBuffer{bytes, length};
263     ::std::string expected_text =
264         "{\n  # "
265         "012345678901234567890123456789012345678901234567890123456789012";
266     if (length > 63) expected_text += "3";
267     if (length > 64) expected_text += "\n  # 4";
268     expected_text += "\n";
269     for (::std::size_t i = 0; i < length; ++i) {
270       expected_text +=
271           absl::StrFormat("  [%d]: %d  # 0x%02x\n", i, bytes[i], bytes[i]);
272     }
273     expected_text += "}";
274     EXPECT_EQ(
275         WriteToString(
276             ArrayView<FixedIntView<8>, ReadWriteContiguousBuffer, 1>{buffer},
277             MultilineText()),
278         expected_text);
279   }
280 }
281 
282 }  // namespace test
283 }  // namespace support
284 }  // namespace emboss
285