1 // Copyright 2024 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "base/containers/span_reader.h"
6
7 #include "testing/gmock/include/gmock/gmock.h"
8 #include "testing/gtest/include/gtest/gtest.h"
9
10 using testing::Optional;
11
12 namespace base {
13 namespace {
14
TEST(SpanReaderTest,Construct)15 TEST(SpanReaderTest, Construct) {
16 std::array<const int, 5u> kArray = {1, 2, 3, 4, 5};
17
18 auto r = SpanReader(span(kArray));
19 EXPECT_EQ(r.remaining(), 5u);
20 EXPECT_EQ(r.remaining_span().data(), &kArray[0u]);
21 EXPECT_EQ(r.remaining_span().size(), 5u);
22 }
23
TEST(SpanReaderTest,Skip)24 TEST(SpanReaderTest, Skip) {
25 std::array<const int, 5u> kArray = {1, 2, 3, 4, 5};
26
27 auto r = SpanReader(span(kArray));
28 EXPECT_EQ(r.num_read(), 0u);
29 EXPECT_FALSE(r.Skip(6u));
30 EXPECT_THAT(r.Skip(2u), Optional(span(kArray).first(2u)));
31 EXPECT_EQ(r.num_read(), 2u);
32 }
33
TEST(SpanReaderTest,Read)34 TEST(SpanReaderTest, Read) {
35 std::array<const int, 5u> kArray = {1, 2, 3, 4, 5};
36
37 auto r = SpanReader(span(kArray));
38 EXPECT_EQ(r.num_read(), 0u);
39 {
40 auto o = r.Read(2u);
41 static_assert(std::same_as<decltype(*o), span<const int>&>);
42 ASSERT_TRUE(o.has_value());
43 EXPECT_TRUE(*o == span(kArray).subspan(0u, 2u));
44 EXPECT_EQ(r.remaining(), 3u);
45 EXPECT_EQ(r.num_read(), 2u);
46 }
47 {
48 auto o = r.Read(5u);
49 static_assert(std::same_as<decltype(*o), span<const int>&>);
50 EXPECT_FALSE(o.has_value());
51 EXPECT_EQ(r.remaining(), 3u);
52 EXPECT_EQ(r.num_read(), 2u);
53 }
54 {
55 auto o = r.Read(1u);
56 static_assert(std::same_as<decltype(*o), span<const int>&>);
57 ASSERT_TRUE(o.has_value());
58 EXPECT_TRUE(*o == span(kArray).subspan(2u, 1u));
59 EXPECT_EQ(r.remaining(), 2u);
60 EXPECT_EQ(r.num_read(), 3u);
61 }
62 {
63 auto o = r.Read(2u);
64 static_assert(std::same_as<decltype(*o), span<const int>&>);
65 ASSERT_TRUE(o.has_value());
66 EXPECT_TRUE(*o == span(kArray).subspan(3u, 2u));
67 EXPECT_EQ(r.remaining(), 0u);
68 EXPECT_EQ(r.num_read(), 5u);
69 }
70 }
71
TEST(SpanReaderTest,ReadFixed)72 TEST(SpanReaderTest, ReadFixed) {
73 std::array<const int, 5u> kArray = {1, 2, 3, 4, 5};
74
75 auto r = SpanReader(span(kArray));
76 {
77 auto o = r.Read<2u>();
78 static_assert(std::same_as<decltype(*o), span<const int, 2u>&>);
79 ASSERT_TRUE(o.has_value());
80 EXPECT_TRUE(*o == span(kArray).subspan(0u, 2u));
81 EXPECT_EQ(r.remaining(), 3u);
82 }
83 {
84 auto o = r.Read<5u>();
85 static_assert(std::same_as<decltype(*o), span<const int, 5u>&>);
86 EXPECT_FALSE(o.has_value());
87 EXPECT_EQ(r.remaining(), 3u);
88 }
89 {
90 auto o = r.Read<1u>();
91 static_assert(std::same_as<decltype(*o), span<const int, 1u>&>);
92 ASSERT_TRUE(o.has_value());
93 EXPECT_TRUE(*o == span(kArray).subspan(2u, 1u));
94 EXPECT_EQ(r.remaining(), 2u);
95 }
96 {
97 auto o = r.Read<2u>();
98 static_assert(std::same_as<decltype(*o), span<const int, 2u>&>);
99 ASSERT_TRUE(o.has_value());
100 EXPECT_TRUE(*o == span(kArray).subspan(3u, 2u));
101 EXPECT_EQ(r.remaining(), 0u);
102 }
103 }
104
TEST(SpanReaderTest,ReadInto)105 TEST(SpanReaderTest, ReadInto) {
106 std::array<const int, 5u> kArray = {1, 2, 3, 4, 5};
107
108 auto r = SpanReader(span(kArray));
109 {
110 span<const int> s;
111 EXPECT_TRUE(r.ReadInto(2u, s));
112 EXPECT_TRUE(s == span(kArray).subspan(0u, 2u));
113 EXPECT_EQ(r.remaining(), 3u);
114 }
115 {
116 span<const int> s;
117 EXPECT_FALSE(r.ReadInto(5u, s));
118 EXPECT_EQ(r.remaining(), 3u);
119 }
120 {
121 span<const int> s;
122 EXPECT_TRUE(r.ReadInto(1u, s));
123 EXPECT_TRUE(s == span(kArray).subspan(2u, 1u));
124 EXPECT_EQ(r.remaining(), 2u);
125 }
126 {
127 span<const int> s;
128 EXPECT_TRUE(r.ReadInto(2u, s));
129 EXPECT_TRUE(s == span(kArray).subspan(3u, 2u));
130 EXPECT_EQ(r.remaining(), 0u);
131 }
132 }
133
TEST(SpanReaderTest,ReadCopy)134 TEST(SpanReaderTest, ReadCopy) {
135 std::array<const int, 5u> kArray = {1, 2, 3, 4, 5};
136
137 auto r = SpanReader(span(kArray));
138 {
139 std::array<int, 2u> s;
140 EXPECT_TRUE(r.ReadCopy(s));
141 EXPECT_TRUE(s == span(kArray).subspan(0u, 2u));
142 EXPECT_EQ(r.remaining(), 3u);
143 }
144 {
145 std::array<int, 5u> s;
146 EXPECT_FALSE(r.ReadCopy(s));
147 EXPECT_EQ(r.remaining(), 3u);
148 }
149 {
150 std::array<int, 1u> s;
151 EXPECT_TRUE(r.ReadCopy(s));
152 EXPECT_TRUE(s == span(kArray).subspan(2u, 1u));
153 EXPECT_EQ(r.remaining(), 2u);
154 }
155 {
156 std::array<int, 2u> s;
157 EXPECT_TRUE(r.ReadCopy(s));
158 EXPECT_TRUE(s == span(kArray).subspan(3u, 2u));
159 EXPECT_EQ(r.remaining(), 0u);
160 }
161 }
162
TEST(SpanReaderTest,ReadBigEndian_Unsigned)163 TEST(SpanReaderTest, ReadBigEndian_Unsigned) {
164 const std::array<uint8_t, 5u> kArray = {1, 2, 3, 4, 5};
165 const std::array<uint8_t, 9u> kBigArray = {1, 2, 3, 4, 5, 6, 7, 8, 9};
166
167 {
168 uint8_t val;
169
170 auto r = SpanReader(span(kArray));
171 EXPECT_TRUE(r.Skip(1u));
172 EXPECT_TRUE(r.ReadU8BigEndian(val));
173 EXPECT_EQ(r.remaining(), 3u);
174 EXPECT_EQ(val, 0x02u);
175 }
176 {
177 uint16_t val;
178
179 auto r = SpanReader(span(kArray));
180 EXPECT_TRUE(r.Skip(1u));
181 EXPECT_TRUE(r.ReadU16BigEndian(val));
182 EXPECT_EQ(r.remaining(), 2u);
183 EXPECT_EQ(val, 0x0203u);
184 }
185 {
186 uint32_t val;
187
188 auto r = SpanReader(span(kArray));
189 EXPECT_TRUE(r.Skip(1u));
190 EXPECT_TRUE(r.ReadU32BigEndian(val));
191 EXPECT_EQ(r.remaining(), 0u);
192 EXPECT_EQ(val, 0x02030405u);
193 }
194 {
195 uint64_t val;
196
197 auto r = SpanReader(span(kBigArray));
198 EXPECT_TRUE(r.Skip(1u));
199 EXPECT_TRUE(r.ReadU64BigEndian(val));
200 EXPECT_EQ(r.remaining(), 0u);
201 EXPECT_EQ(val, 0x0203040506070809llu);
202 }
203 }
204
TEST(SpanReaderTest,ReadBigEndian_Signed)205 TEST(SpanReaderTest, ReadBigEndian_Signed) {
206 const std::array<uint8_t, 5u> kArray = {1, 2, 3, 4, 5};
207 const std::array<uint8_t, 9u> kBigArray = {1, 2, 3, 4, 5, 6, 7, 8, 9};
208
209 {
210 int8_t val;
211
212 auto r = SpanReader(span(kArray));
213 EXPECT_TRUE(r.Skip(1u));
214 EXPECT_TRUE(r.ReadI8BigEndian(val));
215 EXPECT_EQ(r.remaining(), 3u);
216 EXPECT_EQ(val, 0x02);
217 }
218 {
219 int16_t val;
220
221 auto r = SpanReader(span(kArray));
222 EXPECT_TRUE(r.Skip(1u));
223 EXPECT_TRUE(r.ReadI16BigEndian(val));
224 EXPECT_EQ(r.remaining(), 2u);
225 EXPECT_EQ(val, 0x0203);
226 }
227 {
228 int32_t val;
229
230 auto r = SpanReader(span(kArray));
231 EXPECT_TRUE(r.Skip(1u));
232 EXPECT_TRUE(r.ReadI32BigEndian(val));
233 EXPECT_EQ(r.remaining(), 0u);
234 EXPECT_EQ(val, 0x02030405);
235 }
236 {
237 int64_t val;
238
239 auto r = SpanReader(span(kBigArray));
240 EXPECT_TRUE(r.Skip(1u));
241 EXPECT_TRUE(r.ReadI64BigEndian(val));
242 EXPECT_EQ(r.remaining(), 0u);
243 EXPECT_EQ(val, 0x0203040506070809ll);
244 }
245 }
246
TEST(SpanReaderTest,ReadLittleEndian_Unsigned)247 TEST(SpanReaderTest, ReadLittleEndian_Unsigned) {
248 const std::array<uint8_t, 5u> kArray = {1, 2, 3, 4, 5};
249 const std::array<uint8_t, 9u> kBigArray = {1, 2, 3, 4, 5, 6, 7, 8, 9};
250
251 {
252 uint8_t val;
253
254 auto r = SpanReader(span(kArray));
255 EXPECT_TRUE(r.Skip(1u));
256 EXPECT_TRUE(r.ReadU8LittleEndian(val));
257 EXPECT_EQ(r.remaining(), 3u);
258 EXPECT_EQ(val, 0x02u);
259 }
260 {
261 uint16_t val;
262
263 auto r = SpanReader(span(kArray));
264 EXPECT_TRUE(r.Skip(1u));
265 EXPECT_TRUE(r.ReadU16LittleEndian(val));
266 EXPECT_EQ(r.remaining(), 2u);
267 EXPECT_EQ(val, 0x0302u);
268 }
269 {
270 uint32_t val;
271
272 auto r = SpanReader(span(kArray));
273 EXPECT_TRUE(r.Skip(1u));
274 EXPECT_TRUE(r.ReadU32LittleEndian(val));
275 EXPECT_EQ(r.remaining(), 0u);
276 EXPECT_EQ(val, 0x05040302u);
277 }
278 {
279 uint64_t val;
280
281 auto r = SpanReader(span(kBigArray));
282 EXPECT_TRUE(r.Skip(1u));
283 EXPECT_TRUE(r.ReadU64LittleEndian(val));
284 EXPECT_EQ(r.remaining(), 0u);
285 EXPECT_EQ(val, 0x0908070605040302llu);
286 }
287 }
288
TEST(SpanReaderTest,ReadLittleEndian_Signed)289 TEST(SpanReaderTest, ReadLittleEndian_Signed) {
290 const std::array<uint8_t, 5u> kArray = {1, 2, 3, 4, 5};
291 const std::array<uint8_t, 9u> kBigArray = {1, 2, 3, 4, 5, 6, 7, 8, 9};
292
293 {
294 int8_t val;
295
296 auto r = SpanReader(span(kArray));
297 EXPECT_TRUE(r.Skip(1u));
298 EXPECT_TRUE(r.ReadI8LittleEndian(val));
299 EXPECT_EQ(r.remaining(), 3u);
300 EXPECT_EQ(val, 0x02);
301 }
302 {
303 int16_t val;
304
305 auto r = SpanReader(span(kArray));
306 EXPECT_TRUE(r.Skip(1u));
307 EXPECT_TRUE(r.ReadI16LittleEndian(val));
308 EXPECT_EQ(r.remaining(), 2u);
309 EXPECT_EQ(val, 0x0302);
310 }
311 {
312 int32_t val;
313
314 auto r = SpanReader(span(kArray));
315 EXPECT_TRUE(r.Skip(1u));
316 EXPECT_TRUE(r.ReadI32LittleEndian(val));
317 EXPECT_EQ(r.remaining(), 0u);
318 EXPECT_EQ(val, 0x05040302);
319 }
320 {
321 int64_t val;
322
323 auto r = SpanReader(span(kBigArray));
324 EXPECT_TRUE(r.Skip(1u));
325 EXPECT_TRUE(r.ReadI64LittleEndian(val));
326 EXPECT_EQ(r.remaining(), 0u);
327 EXPECT_EQ(val, 0x0908070605040302ll);
328 }
329 }
330
TEST(SpanReaderTest,ReadNativeEndian_Unsigned)331 TEST(SpanReaderTest, ReadNativeEndian_Unsigned) {
332 const std::array<uint8_t, 5u> kArray = {1, 2, 3, 4, 5};
333 const std::array<uint8_t, 9u> kBigArray = {1, 2, 3, 4, 5, 6, 7, 8, 9};
334
335 {
336 uint8_t val;
337
338 auto r = SpanReader(span(kArray));
339 EXPECT_TRUE(r.Skip(1u));
340 EXPECT_TRUE(r.ReadU8NativeEndian(val));
341 EXPECT_EQ(r.remaining(), 3u);
342 EXPECT_EQ(val, 0x02u);
343 }
344 {
345 uint16_t val;
346
347 auto r = SpanReader(span(kArray));
348 EXPECT_TRUE(r.Skip(1u));
349 EXPECT_TRUE(r.ReadU16NativeEndian(val));
350 EXPECT_EQ(r.remaining(), 2u);
351 EXPECT_EQ(val, 0x0302u);
352 }
353 {
354 uint32_t val;
355
356 auto r = SpanReader(span(kArray));
357 EXPECT_TRUE(r.Skip(1u));
358 EXPECT_TRUE(r.ReadU32NativeEndian(val));
359 EXPECT_EQ(r.remaining(), 0u);
360 EXPECT_EQ(val, 0x05040302u);
361 }
362 {
363 uint64_t val;
364
365 auto r = SpanReader(span(kBigArray));
366 EXPECT_TRUE(r.Skip(1u));
367 EXPECT_TRUE(r.ReadU64NativeEndian(val));
368 EXPECT_EQ(r.remaining(), 0u);
369 EXPECT_EQ(val, 0x0908070605040302llu);
370 }
371 }
372
TEST(SpanReaderTest,ReadNativeEndian_Signed)373 TEST(SpanReaderTest, ReadNativeEndian_Signed) {
374 const std::array<uint8_t, 5u> kArray = {1, 2, 3, 4, 5};
375 const std::array<uint8_t, 9u> kBigArray = {1, 2, 3, 4, 5, 6, 7, 8, 9};
376
377 {
378 int8_t val;
379
380 auto r = SpanReader(span(kArray));
381 EXPECT_TRUE(r.Skip(1u));
382 EXPECT_TRUE(r.ReadI8NativeEndian(val));
383 EXPECT_EQ(r.remaining(), 3u);
384 EXPECT_EQ(val, 0x02);
385 }
386 {
387 int16_t val;
388
389 auto r = SpanReader(span(kArray));
390 EXPECT_TRUE(r.Skip(1u));
391 EXPECT_TRUE(r.ReadI16NativeEndian(val));
392 EXPECT_EQ(r.remaining(), 2u);
393 EXPECT_EQ(val, 0x0302);
394 }
395 {
396 int32_t val;
397
398 auto r = SpanReader(span(kArray));
399 EXPECT_TRUE(r.Skip(1u));
400 EXPECT_TRUE(r.ReadI32NativeEndian(val));
401 EXPECT_EQ(r.remaining(), 0u);
402 EXPECT_EQ(val, 0x05040302);
403 }
404 {
405 int64_t val;
406
407 auto r = SpanReader(span(kBigArray));
408 EXPECT_TRUE(r.Skip(1u));
409 EXPECT_TRUE(r.ReadI64NativeEndian(val));
410 EXPECT_EQ(r.remaining(), 0u);
411 EXPECT_EQ(val, 0x0908070605040302ll);
412 }
413 }
414
TEST(SpanReaderTest,ReadChar)415 TEST(SpanReaderTest, ReadChar) {
416 std::array<const uint8_t, 5u> kArray = {1, 2, 3, 4, 5};
417
418 auto r = SpanReader(span(kArray));
419 EXPECT_EQ(r.num_read(), 0u);
420
421 char c;
422 EXPECT_TRUE(r.ReadChar(c));
423 EXPECT_EQ(c, char{1});
424 EXPECT_TRUE(r.Skip(3u));
425 EXPECT_TRUE(r.ReadChar(c));
426 EXPECT_EQ(c, char{5});
427 EXPECT_FALSE(r.ReadChar(c));
428 EXPECT_EQ(c, char{5});
429 }
430
431 } // namespace
432 } // namespace base
433