• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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