• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2021 The Pigweed Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
5 // 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, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations under
13 // the License.
14 
15 #include "pw_protobuf/stream_decoder.h"
16 
17 #include <array>
18 
19 #include "gtest/gtest.h"
20 #include "pw_status/status.h"
21 #include "pw_status/status_with_size.h"
22 #include "pw_stream/memory_stream.h"
23 #include "pw_stream/stream.h"
24 
25 namespace pw::protobuf {
26 namespace {
27 // Non-seekable wrapper for MemoryReader for testing behavior when seeking is
28 // not available.
29 class NonSeekableMemoryReader : public stream::NonSeekableReader {
30  public:
NonSeekableMemoryReader(stream::MemoryReader & reader)31   explicit NonSeekableMemoryReader(stream::MemoryReader& reader)
32       : reader_(reader) {}
33 
bytes_read() const34   size_t bytes_read() const { return reader_.bytes_read(); }
data() const35   const std::byte* data() const { return reader_.data(); }
36 
37  private:
DoRead(ByteSpan destination)38   virtual StatusWithSize DoRead(ByteSpan destination) override {
39     const pw::Result<pw::ByteSpan> result = reader_.Read(destination);
40     if (!result.ok()) {
41       return StatusWithSize(result.status(), 0);
42     }
43     return StatusWithSize(result.value().size_bytes());
44   }
45 
46   stream::MemoryReader& reader_;
47 };
48 
TEST(StreamDecoder,Decode)49 TEST(StreamDecoder, Decode) {
50   // clang-format off
51   constexpr uint8_t encoded_proto[] = {
52     // type=int32, k=1, v=42
53     0x08, 0x2a,
54     // type=sint32, k=2, v=-13
55     0x10, 0x19,
56     // type=bool, k=3, v=false
57     0x18, 0x00,
58     // type=double, k=4, v=3.14159
59     0x21, 0x6e, 0x86, 0x1b, 0xf0, 0xf9, 0x21, 0x09, 0x40,
60     // type=fixed32, k=5, v=0xdeadbeef
61     0x2d, 0xef, 0xbe, 0xad, 0xde,
62     // type=string, k=6, v="Hello world"
63     0x32, 0x0b, 'H', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd',
64     // type=sfixed32, k=7, v=-50
65     0x3d, 0xce, 0xff, 0xff, 0xff,
66     // type=sfixed64, k=8, v=-1647993274
67     0x41, 0x46, 0x9e, 0xc5, 0x9d, 0xff, 0xff, 0xff, 0xff,
68     // type=float, k=9, v=2.718
69     0x4d, 0xb6, 0xf3, 0x2d, 0x40,
70   };
71   // clang-format on
72 
73   stream::MemoryReader reader(std::as_bytes(std::span(encoded_proto)));
74   StreamDecoder decoder(reader);
75 
76   EXPECT_EQ(decoder.Next(), OkStatus());
77   ASSERT_EQ(decoder.FieldNumber().value(), 1u);
78   Result<int32_t> int32 = decoder.ReadInt32();
79   ASSERT_EQ(int32.status(), OkStatus());
80   EXPECT_EQ(int32.value(), 42);
81 
82   EXPECT_EQ(decoder.Next(), OkStatus());
83   ASSERT_EQ(decoder.FieldNumber().value(), 2u);
84   Result<int32_t> sint32 = decoder.ReadSint32();
85   ASSERT_EQ(sint32.status(), OkStatus());
86   EXPECT_EQ(sint32.value(), -13);
87 
88   EXPECT_EQ(decoder.Next(), OkStatus());
89   ASSERT_EQ(decoder.FieldNumber().value(), 3u);
90   Result<bool> boolean = decoder.ReadBool();
91   ASSERT_EQ(boolean.status(), OkStatus());
92   EXPECT_FALSE(boolean.value());
93 
94   EXPECT_EQ(decoder.Next(), OkStatus());
95   ASSERT_EQ(decoder.FieldNumber().value(), 4u);
96   Result<double> dbl = decoder.ReadDouble();
97   ASSERT_EQ(dbl.status(), OkStatus());
98   EXPECT_EQ(dbl.value(), 3.14159);
99 
100   EXPECT_EQ(decoder.Next(), OkStatus());
101   ASSERT_EQ(decoder.FieldNumber().value(), 5u);
102   Result<uint32_t> fixed32 = decoder.ReadFixed32();
103   ASSERT_EQ(fixed32.status(), OkStatus());
104   EXPECT_EQ(fixed32.value(), 0xdeadbeef);
105 
106   char buffer[16];
107   EXPECT_EQ(decoder.Next(), OkStatus());
108   ASSERT_EQ(decoder.FieldNumber().value(), 6u);
109   StatusWithSize sws = decoder.ReadString(buffer);
110   ASSERT_EQ(sws.status(), OkStatus());
111   buffer[sws.size()] = '\0';
112   EXPECT_STREQ(buffer, "Hello world");
113 
114   EXPECT_EQ(decoder.Next(), OkStatus());
115   ASSERT_EQ(decoder.FieldNumber().value(), 7u);
116   Result<int32_t> sfixed32 = decoder.ReadSfixed32();
117   ASSERT_EQ(sfixed32.status(), OkStatus());
118   EXPECT_EQ(sfixed32.value(), -50);
119 
120   EXPECT_EQ(decoder.Next(), OkStatus());
121   ASSERT_EQ(decoder.FieldNumber().value(), 8u);
122   Result<int64_t> sfixed64 = decoder.ReadSfixed64();
123   ASSERT_EQ(sfixed64.status(), OkStatus());
124   EXPECT_EQ(sfixed64.value(), -1647993274);
125 
126   EXPECT_EQ(decoder.Next(), OkStatus());
127   ASSERT_EQ(decoder.FieldNumber().value(), 9u);
128   Result<float> flt = decoder.ReadFloat();
129   ASSERT_EQ(flt.status(), OkStatus());
130   EXPECT_EQ(flt.value(), 2.718f);
131 
132   EXPECT_EQ(decoder.Next(), Status::OutOfRange());
133 }
134 
TEST(StreamDecoder,Decode_SkipsUnusedFields)135 TEST(StreamDecoder, Decode_SkipsUnusedFields) {
136   // clang-format off
137   constexpr uint8_t encoded_proto[] = {
138     // type=int32, k=1, v=42
139     0x08, 0x2a,
140     // type=sint32, k=2, v=-13
141     0x10, 0x19,
142     // type=bool, k=3, v=false
143     0x18, 0x00,
144     // type=double, k=4, v=3.14159
145     0x21, 0x6e, 0x86, 0x1b, 0xf0, 0xf9, 0x21, 0x09, 0x40,
146     // type=fixed32, k=5, v=0xdeadbeef
147     0x2d, 0xef, 0xbe, 0xad, 0xde,
148     // type=string, k=6, v="Hello world"
149     0x32, 0x0b, 'H', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd',
150   };
151   // clang-format on
152 
153   stream::MemoryReader reader(std::as_bytes(std::span(encoded_proto)));
154   StreamDecoder decoder(reader);
155 
156   // Don't process any fields except for the fourth. Next should still iterate
157   // correctly despite field values not being consumed.
158   EXPECT_EQ(decoder.Next(), OkStatus());
159   EXPECT_EQ(decoder.Next(), OkStatus());
160   EXPECT_EQ(decoder.Next(), OkStatus());
161   EXPECT_EQ(decoder.Next(), OkStatus());
162   ASSERT_EQ(*decoder.FieldNumber(), 4u);
163   EXPECT_EQ(decoder.Next(), OkStatus());
164   EXPECT_EQ(decoder.Next(), OkStatus());
165   EXPECT_EQ(decoder.Next(), Status::OutOfRange());
166 }
167 
TEST(StreamDecoder,Decode_NonSeekable_SkipsUnusedFields)168 TEST(StreamDecoder, Decode_NonSeekable_SkipsUnusedFields) {
169   // clang-format off
170   constexpr uint8_t encoded_proto[] = {
171     // type=int32, k=1, v=42
172     0x08, 0x2a,
173     // type=sint32, k=2, v=-13
174     0x10, 0x19,
175     // type=bool, k=3, v=false
176     0x18, 0x00,
177     // type=double, k=4, v=3.14159
178     0x21, 0x6e, 0x86, 0x1b, 0xf0, 0xf9, 0x21, 0x09, 0x40,
179     // type=fixed32, k=5, v=0xdeadbeef
180     0x2d, 0xef, 0xbe, 0xad, 0xde,
181     // type=string, k=6, v="Hello world"
182     0x32, 0x0b, 'H', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd',
183   };
184   // clang-format on
185 
186   // Test with a non-seekable memory reader
187   stream::MemoryReader wrapped_reader(std::as_bytes(std::span(encoded_proto)));
188   NonSeekableMemoryReader reader(wrapped_reader);
189   StreamDecoder decoder(reader);
190 
191   // Don't process any fields except for the fourth. Next should still iterate
192   // correctly despite field values not being consumed.
193   EXPECT_EQ(decoder.Next(), OkStatus());
194   EXPECT_EQ(decoder.Next(), OkStatus());
195   EXPECT_EQ(decoder.Next(), OkStatus());
196   EXPECT_EQ(decoder.Next(), OkStatus());
197   ASSERT_EQ(*decoder.FieldNumber(), 4u);
198   EXPECT_EQ(decoder.Next(), OkStatus());
199   EXPECT_EQ(decoder.Next(), OkStatus());
200   EXPECT_EQ(decoder.Next(), Status::OutOfRange());
201 }
202 
TEST(StreamDecoder,Decode_BadData)203 TEST(StreamDecoder, Decode_BadData) {
204   // clang-format off
205   constexpr uint8_t encoded_proto[] = {
206     // type=int32, k=1, v=42
207     0x08, 0x2a,
208     // type=sint32, k=2, value... missing
209     0x10,
210   };
211   // clang-format on
212 
213   stream::MemoryReader reader(std::as_bytes(std::span(encoded_proto)));
214   StreamDecoder decoder(reader);
215 
216   EXPECT_EQ(decoder.Next(), OkStatus());
217   ASSERT_EQ(*decoder.FieldNumber(), 1u);
218   Result<int32_t> int32 = decoder.ReadInt32();
219   ASSERT_EQ(int32.status(), OkStatus());
220   EXPECT_EQ(int32.value(), 42);
221 
222   EXPECT_EQ(decoder.Next(), OkStatus());
223   ASSERT_EQ(*decoder.FieldNumber(), 2u);
224   EXPECT_EQ(decoder.ReadSint32().status(), Status::DataLoss());
225 
226   EXPECT_EQ(decoder.Next(), Status::DataLoss());
227 }
228 
TEST(Decoder,Decode_SkipsBadFieldNumbers)229 TEST(Decoder, Decode_SkipsBadFieldNumbers) {
230   // clang-format off
231   constexpr uint8_t encoded_proto[] = {
232     // type=int32, k=1, v=42
233     0x08, 0x2a,
234     // type=int32, k=19001, v=42 (invalid field number)
235     0xc8, 0xa3, 0x09, 0x2a,
236     // type=bool, k=3, v=false
237     0x18, 0x00,
238   };
239   // clang-format on
240 
241   stream::MemoryReader reader(std::as_bytes(std::span(encoded_proto)));
242   StreamDecoder decoder(reader);
243 
244   EXPECT_EQ(decoder.Next(), OkStatus());
245   EXPECT_EQ(*decoder.FieldNumber(), 1u);
246   Result<int32_t> int32 = decoder.ReadInt32();
247   ASSERT_EQ(int32.status(), OkStatus());
248   EXPECT_EQ(int32.value(), 42);
249 
250   // Bad field.
251   EXPECT_EQ(decoder.Next(), Status::DataLoss());
252   EXPECT_EQ(decoder.FieldNumber().status(), Status::FailedPrecondition());
253 
254   EXPECT_EQ(decoder.Next(), Status::DataLoss());
255 }
256 
TEST(StreamDecoder,Decode_Nested)257 TEST(StreamDecoder, Decode_Nested) {
258   // clang-format off
259   constexpr uint8_t encoded_proto[] = {
260     // type=int32, k=1, v=42
261     0x08, 0x2a,
262 
263     // Submessage (bytes) key=8, length=4
264     0x32, 0x04,
265     // type=uint32, k=1, v=2
266     0x08, 0x02,
267     // type=uint32, k=2, v=7
268     0x10, 0x07,
269     // End submessage
270 
271     // type=sint32, k=2, v=-13
272     0x10, 0x19,
273   };
274   // clang-format on
275 
276   stream::MemoryReader reader(std::as_bytes(std::span(encoded_proto)));
277   StreamDecoder decoder(reader);
278 
279   EXPECT_EQ(decoder.Next(), OkStatus());
280   ASSERT_EQ(*decoder.FieldNumber(), 1u);
281   Result<int32_t> int32 = decoder.ReadInt32();
282   ASSERT_EQ(int32.status(), OkStatus());
283   EXPECT_EQ(int32.value(), 42);
284 
285   EXPECT_EQ(decoder.Next(), OkStatus());
286   ASSERT_EQ(*decoder.FieldNumber(), 6u);
287   {
288     StreamDecoder nested = decoder.GetNestedDecoder();
289 
290     EXPECT_EQ(nested.Next(), OkStatus());
291     ASSERT_EQ(*nested.FieldNumber(), 1u);
292     Result<uint32_t> uint32 = nested.ReadUint32();
293     ASSERT_EQ(uint32.status(), OkStatus());
294     EXPECT_EQ(uint32.value(), 2u);
295 
296     EXPECT_EQ(nested.Next(), OkStatus());
297     ASSERT_EQ(*nested.FieldNumber(), 2u);
298     uint32 = nested.ReadUint32();
299     ASSERT_EQ(uint32.status(), OkStatus());
300     EXPECT_EQ(uint32.value(), 7u);
301 
302     ASSERT_EQ(nested.Next(), Status::OutOfRange());
303   }
304 
305   EXPECT_EQ(decoder.Next(), OkStatus());
306   ASSERT_EQ(*decoder.FieldNumber(), 2u);
307   Result<int32_t> sint32 = decoder.ReadSint32();
308   ASSERT_EQ(sint32.status(), OkStatus());
309   EXPECT_EQ(sint32.value(), -13);
310 
311   EXPECT_EQ(decoder.Next(), Status::OutOfRange());
312 }
313 
TEST(StreamDecoder,Decode_Nested_SeeksToNextFieldOnDestruction)314 TEST(StreamDecoder, Decode_Nested_SeeksToNextFieldOnDestruction) {
315   // clang-format off
316   constexpr uint8_t encoded_proto[] = {
317     // type=int32, k=1, v=42
318     0x08, 0x2a,
319 
320     // Submessage (bytes) key=8, length=4
321     0x32, 0x04,
322     // type=uint32, k=1, v=2
323     0x08, 0x02,
324     // type=uint32, k=2, v=7
325     0x10, 0x07,
326     // End submessage
327 
328     // type=sint32, k=2, v=-13
329     0x10, 0x19,
330   };
331   // clang-format on
332 
333   stream::MemoryReader reader(std::as_bytes(std::span(encoded_proto)));
334   StreamDecoder decoder(reader);
335 
336   EXPECT_EQ(decoder.Next(), OkStatus());
337   ASSERT_EQ(*decoder.FieldNumber(), 1u);
338 
339   // Create a nested encoder for the nested field, but don't use it.
340   EXPECT_EQ(decoder.Next(), OkStatus());
341   ASSERT_EQ(*decoder.FieldNumber(), 6u);
342   { StreamDecoder nested = decoder.GetNestedDecoder(); }
343 
344   // The root decoder should still advance to the next field after the nested
345   // decoder is closed.
346   EXPECT_EQ(decoder.Next(), OkStatus());
347   ASSERT_EQ(*decoder.FieldNumber(), 2u);
348 
349   EXPECT_EQ(decoder.Next(), Status::OutOfRange());
350 }
351 
TEST(StreamDecoder,Decode_Nested_NonSeekable_AdvancesToNextFieldOnDestruction)352 TEST(StreamDecoder,
353      Decode_Nested_NonSeekable_AdvancesToNextFieldOnDestruction) {
354   // clang-format off
355   constexpr uint8_t encoded_proto[] = {
356     // type=int32, k=1, v=42
357     0x08, 0x2a,
358 
359     // Submessage (bytes) key=8, length=4
360     0x32, 0x04,
361     // type=uint32, k=1, v=2
362     0x08, 0x02,
363     // type=uint32, k=2, v=7
364     0x10, 0x07,
365     // End submessage
366 
367     // type=sint32, k=2, v=-13
368     0x10, 0x19,
369   };
370   // clang-format on
371 
372   // Test with a non-seekable memory reader
373   stream::MemoryReader wrapped_reader(std::as_bytes(std::span(encoded_proto)));
374   NonSeekableMemoryReader reader(wrapped_reader);
375   StreamDecoder decoder(reader);
376 
377   EXPECT_EQ(decoder.Next(), OkStatus());
378   ASSERT_EQ(*decoder.FieldNumber(), 1u);
379 
380   // Create a nested encoder for the nested field, but don't use it.
381   EXPECT_EQ(decoder.Next(), OkStatus());
382   ASSERT_EQ(*decoder.FieldNumber(), 6u);
383   { StreamDecoder nested = decoder.GetNestedDecoder(); }
384 
385   // The root decoder should still advance to the next field after the nested
386   // decoder is closed.
387   EXPECT_EQ(decoder.Next(), OkStatus());
388   ASSERT_EQ(*decoder.FieldNumber(), 2u);
389 
390   EXPECT_EQ(decoder.Next(), Status::OutOfRange());
391 }
392 
TEST(StreamDecoder,Decode_Nested_LastField)393 TEST(StreamDecoder, Decode_Nested_LastField) {
394   // clang-format off
395   constexpr uint8_t encoded_proto[] = {
396     // type=int32, k=1, v=42
397     0x08, 0x2a,
398 
399     // Submessage (bytes) key=8, length=4
400     0x32, 0x04,
401     // type=uint32, k=1, v=2
402     0x08, 0x02,
403     // type=uint32, k=2, v=7
404     0x10, 0x07,
405     // End submessage and proto
406   };
407   // clang-format on
408 
409   stream::MemoryReader reader(std::as_bytes(std::span(encoded_proto)));
410   StreamDecoder decoder(reader);
411 
412   EXPECT_EQ(decoder.Next(), OkStatus());
413   ASSERT_EQ(*decoder.FieldNumber(), 1u);
414 
415   // Create a nested encoder for the nested field, which is the last field in
416   // the root proto.
417   EXPECT_EQ(decoder.Next(), OkStatus());
418   ASSERT_EQ(*decoder.FieldNumber(), 6u);
419   { StreamDecoder nested = decoder.GetNestedDecoder(); }
420 
421   // Root decoder should correctly terminate after the nested decoder is closed.
422   EXPECT_EQ(decoder.Next(), Status::OutOfRange());
423 }
424 
TEST(StreamDecoder,Decode_Nested_MultiLevel)425 TEST(StreamDecoder, Decode_Nested_MultiLevel) {
426   // clang-format off
427   constexpr uint8_t encoded_proto[] = {
428     // Submessage key=1, length=4
429     0x0a, 0x04,
430 
431     // Sub-submessage key=1, length=2
432     0x0a, 0x02,
433     // type=uint32, k=2, v=7
434     0x10, 0x07,
435     // End sub-submessage
436 
437     // End submessage
438   };
439   // clang-format on
440 
441   stream::MemoryReader reader(std::as_bytes(std::span(encoded_proto)));
442   StreamDecoder decoder(reader);
443 
444   EXPECT_EQ(decoder.Next(), OkStatus());
445   ASSERT_EQ(*decoder.FieldNumber(), 1u);
446   {
447     StreamDecoder nested = decoder.GetNestedDecoder();
448 
449     EXPECT_EQ(nested.Next(), OkStatus());
450     ASSERT_EQ(*nested.FieldNumber(), 1u);
451 
452     {
453       StreamDecoder double_nested = nested.GetNestedDecoder();
454 
455       EXPECT_EQ(double_nested.Next(), OkStatus());
456       ASSERT_EQ(*double_nested.FieldNumber(), 2u);
457       Result<uint32_t> result = double_nested.ReadUint32();
458       ASSERT_EQ(result.status(), OkStatus());
459       EXPECT_EQ(result.value(), 7u);
460 
461       EXPECT_EQ(double_nested.Next(), Status::OutOfRange());
462     }
463 
464     EXPECT_EQ(nested.Next(), Status::OutOfRange());
465   }
466 
467   EXPECT_EQ(decoder.Next(), Status::OutOfRange());
468 }
469 
TEST(StreamDecoder,Decode_Nested_InvalidField)470 TEST(StreamDecoder, Decode_Nested_InvalidField) {
471   // clang-format off
472   constexpr uint8_t encoded_proto[] = {
473     // Submessage key=1, length=4
474     0x0a, 0x04,
475 
476     // Oops. No data!
477   };
478 
479   stream::MemoryReader reader(std::as_bytes(std::span(encoded_proto)));
480   StreamDecoder decoder(reader);
481 
482   EXPECT_EQ(decoder.Next(), OkStatus());
483   ASSERT_EQ(*decoder.FieldNumber(), 1u);
484   {
485     StreamDecoder nested = decoder.GetNestedDecoder();
486     EXPECT_EQ(nested.Next(), Status::DataLoss());
487   }
488 
489   EXPECT_EQ(decoder.Next(), Status::DataLoss());
490 }
491 
TEST(StreamDecoder,Decode_BytesReader)492 TEST(StreamDecoder, Decode_BytesReader) {
493   // clang-format off
494   constexpr uint8_t encoded_proto[] = {
495     // bytes key=1, length=14
496     0x0a, 0x0e,
497 
498     0x00, 0x01, 0x02, 0x03,
499     0x04, 0x05, 0x06, 0x07,
500     0x08, 0x09, 0x0a, 0x0b,
501     0x0c, 0x0d,
502   };
503   // clang-format on
504 
505   stream::MemoryReader reader(std::as_bytes(std::span(encoded_proto)));
506   StreamDecoder decoder(reader);
507 
508   EXPECT_EQ(decoder.Next(), OkStatus());
509   EXPECT_EQ(*decoder.FieldNumber(), 1u);
510   {
511     StreamDecoder::BytesReader bytes = decoder.GetBytesReader();
512     EXPECT_EQ(bytes.field_size(), 14u);
513 
514     std::byte buffer[7];
515     EXPECT_EQ(bytes.Read(buffer).status(), OkStatus());
516     EXPECT_EQ(std::memcmp(buffer, encoded_proto + 2, sizeof(buffer)), 0);
517 
518     EXPECT_EQ(bytes.Read(buffer).status(), OkStatus());
519     EXPECT_EQ(std::memcmp(buffer, encoded_proto + 9, sizeof(buffer)), 0);
520 
521     EXPECT_EQ(bytes.Read(buffer).status(), Status::OutOfRange());
522   }
523 
524   EXPECT_EQ(decoder.Next(), Status::OutOfRange());
525 }
526 
TEST(StreamDecoder,Decode_BytesReader_Seek)527 TEST(StreamDecoder, Decode_BytesReader_Seek) {
528   // clang-format off
529   constexpr uint8_t encoded_proto[] = {
530     // bytes key=1, length=14
531     0x0a, 0x0e,
532 
533     0x00, 0x01, 0x02, 0x03,
534     0x04, 0x05, 0x06, 0x07,
535     0x08, 0x09, 0x0a, 0x0b,
536     0x0c, 0x0d,
537   };
538   // clang-format on
539 
540   stream::MemoryReader reader(std::as_bytes(std::span(encoded_proto)));
541   StreamDecoder decoder(reader);
542 
543   EXPECT_EQ(decoder.Next(), OkStatus());
544   EXPECT_EQ(*decoder.FieldNumber(), 1u);
545   {
546     StreamDecoder::BytesReader bytes = decoder.GetBytesReader();
547 
548     std::byte buffer[2];
549 
550     ASSERT_EQ(bytes.Seek(3), OkStatus());
551 
552     EXPECT_EQ(bytes.Read(buffer).status(), OkStatus());
553     EXPECT_EQ(std::memcmp(buffer, encoded_proto + 5, sizeof(buffer)), 0);
554 
555     // Bad seek offset (absolute).
556     ASSERT_EQ(bytes.Seek(15), Status::OutOfRange());
557 
558     // Seek back from current position.
559     ASSERT_EQ(bytes.Seek(-4, stream::Stream::kCurrent), OkStatus());
560 
561     EXPECT_EQ(bytes.Read(buffer).status(), OkStatus());
562     EXPECT_EQ(std::memcmp(buffer, encoded_proto + 3, sizeof(buffer)), 0);
563 
564     // Bad seek offset (relative).
565     ASSERT_EQ(bytes.Seek(-4, stream::Stream::kCurrent), Status::OutOfRange());
566 
567     // Seek from the end of the bytes field.
568     ASSERT_EQ(bytes.Seek(-2, stream::Stream::kEnd), OkStatus());
569 
570     EXPECT_EQ(bytes.Read(buffer).status(), OkStatus());
571     EXPECT_EQ(std::memcmp(buffer, encoded_proto + 14, sizeof(buffer)), 0);
572 
573     // Bad seek offset (end).
574     ASSERT_EQ(bytes.Seek(-15, stream::Stream::kEnd), Status::OutOfRange());
575   }
576 
577   EXPECT_EQ(decoder.Next(), Status::OutOfRange());
578 }
579 
TEST(StreamDecoder,Decode_BytesReader_Close)580 TEST(StreamDecoder, Decode_BytesReader_Close) {
581   // clang-format off
582   constexpr uint8_t encoded_proto[] = {
583     // bytes key=1, length=14
584     0x0a, 0x0e,
585 
586     0x00, 0x01, 0x02, 0x03,
587     0x04, 0x05, 0x06, 0x07,
588     0x08, 0x09, 0x0a, 0x0b,
589     0x0c, 0x0d,
590     // End bytes
591 
592     // type=sint32, k=2, v=-13
593     0x10, 0x19,
594   };
595   // clang-format on
596 
597   stream::MemoryReader reader(std::as_bytes(std::span(encoded_proto)));
598   StreamDecoder decoder(reader);
599 
600   EXPECT_EQ(decoder.Next(), OkStatus());
601   EXPECT_EQ(*decoder.FieldNumber(), 1u);
602   {
603     // Partially consume the bytes field.
604     StreamDecoder::BytesReader bytes = decoder.GetBytesReader();
605 
606     std::byte buffer[2];
607     EXPECT_EQ(bytes.Read(buffer).status(), OkStatus());
608     EXPECT_EQ(std::memcmp(buffer, encoded_proto + 2, sizeof(buffer)), 0);
609   }
610 
611   // Continue reading the top-level message.
612   EXPECT_EQ(decoder.Next(), OkStatus());
613   EXPECT_EQ(*decoder.FieldNumber(), 2u);
614 
615   EXPECT_EQ(decoder.Next(), Status::OutOfRange());
616 }
617 
TEST(StreamDecoder,Decode_BytesReader_NonSeekable_Close)618 TEST(StreamDecoder, Decode_BytesReader_NonSeekable_Close) {
619   // clang-format off
620   constexpr uint8_t encoded_proto[] = {
621     // bytes key=1, length=14
622     0x0a, 0x0e,
623 
624     0x00, 0x01, 0x02, 0x03,
625     0x04, 0x05, 0x06, 0x07,
626     0x08, 0x09, 0x0a, 0x0b,
627     0x0c, 0x0d,
628     // End bytes
629 
630     // type=sint32, k=2, v=-13
631     0x10, 0x19,
632   };
633   // clang-format on
634 
635   // Test with a non-seekable memory reader
636   stream::MemoryReader wrapped_reader(std::as_bytes(std::span(encoded_proto)));
637   NonSeekableMemoryReader reader(wrapped_reader);
638   StreamDecoder decoder(reader);
639 
640   EXPECT_EQ(decoder.Next(), OkStatus());
641   EXPECT_EQ(*decoder.FieldNumber(), 1u);
642   {
643     // Partially consume the bytes field.
644     StreamDecoder::BytesReader bytes = decoder.GetBytesReader();
645 
646     std::byte buffer[2];
647     EXPECT_EQ(bytes.Read(buffer).status(), OkStatus());
648     EXPECT_EQ(std::memcmp(buffer, encoded_proto + 2, sizeof(buffer)), 0);
649   }
650 
651   // Continue reading the top-level message.
652   EXPECT_EQ(decoder.Next(), OkStatus());
653   EXPECT_EQ(*decoder.FieldNumber(), 2u);
654 
655   EXPECT_EQ(decoder.Next(), Status::OutOfRange());
656 }
657 
TEST(StreamDecoder,Decode_BytesReader_InvalidField)658 TEST(StreamDecoder, Decode_BytesReader_InvalidField) {
659   // clang-format off
660   constexpr uint8_t encoded_proto[] = {
661     // bytes key=1, length=4
662     0x0a, 0x04,
663 
664     // Oops. No data!
665   };
666 
667   stream::MemoryReader reader(std::as_bytes(std::span(encoded_proto)));
668   StreamDecoder decoder(reader);
669 
670   EXPECT_EQ(decoder.Next(), OkStatus());
671   ASSERT_EQ(*decoder.FieldNumber(), 1u);
672   {
673     StreamDecoder::BytesReader bytes = decoder.GetBytesReader();
674     EXPECT_EQ(bytes.Seek(0), Status::DataLoss());
675 
676     std::byte buffer[2];
677     EXPECT_EQ(bytes.Read(buffer).status(), Status::DataLoss());
678   }
679 
680   EXPECT_EQ(decoder.Next(), Status::DataLoss());
681 }
682 
TEST(StreamDecoder,GetLengthDelimitedPayloadBounds)683 TEST(StreamDecoder, GetLengthDelimitedPayloadBounds) {
684   // clang-format off
685   constexpr uint8_t encoded_proto[] = {
686     // bytes key=1, length=14
687     0x0a, 0x0e,
688 
689     0x00, 0x01, 0x02, 0x03,
690     0x04, 0x05, 0x06, 0x07,
691     0x08, 0x09, 0x0a, 0x0b,
692     0x0c, 0x0d,
693     // End bytes
694 
695     // type=sint32, k=2, v=-13
696     0x10, 0x19,
697   };
698   // clang-format on
699 
700   stream::MemoryReader reader(std::as_bytes(std::span(encoded_proto)));
701   StreamDecoder decoder(reader);
702 
703   ASSERT_EQ(OkStatus(), decoder.Next());
704   Result<StreamDecoder::Bounds> field_bound =
705       decoder.GetLengthDelimitedPayloadBounds();
706   ASSERT_EQ(OkStatus(), field_bound.status());
707   ASSERT_EQ(field_bound.value().low, 2ULL);
708   ASSERT_EQ(field_bound.value().high, 16ULL);
709 
710   ASSERT_EQ(OkStatus(), decoder.Next());
711   ASSERT_EQ(Status::NotFound(),
712             decoder.GetLengthDelimitedPayloadBounds().status());
713 }
714 
TEST(StreamDecoder,ReadDelimitedField_DoesntOverConsume)715 TEST(StreamDecoder, ReadDelimitedField_DoesntOverConsume) {
716   // clang-format off
717   constexpr uint8_t encoded_proto[] = {
718     // type=string, k=1, v="Hello world"
719     0x0a, 0x0b, 'H', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd',
720     // type=int32, k=2, v=42
721     0x10, 0x2a,
722   };
723   // clang-format on
724 
725   stream::MemoryReader reader(std::as_bytes(std::span(encoded_proto)));
726   StreamDecoder decoder(reader);
727 
728   ASSERT_EQ(OkStatus(), decoder.Next());
729 
730   // This buffer is much larger than the string.
731   char buffer[128];
732   const StatusWithSize size = decoder.ReadString(buffer);
733   EXPECT_EQ(size.status(), OkStatus());
734   EXPECT_EQ(size.size(), 11u);
735 
736   // Make sure we can still read the next field.
737   ASSERT_EQ(OkStatus(), decoder.Next());
738   const pw::Result<int32_t> result = decoder.ReadInt32();
739   EXPECT_EQ(result.status(), OkStatus());
740   EXPECT_EQ(result.value(), 42);
741 }
742 
TEST(StreamDecoder,Decode_WithLength)743 TEST(StreamDecoder, Decode_WithLength) {
744   // clang-format off
745   constexpr uint8_t encoded_proto[] = {
746     // type=int32, k=1, v=42
747     0x08, 0x2a,
748     // This field is beyond the range of the protobuf:
749     // type=sint32, k=2, v=-13
750     0x10, 0x19,
751   };
752   // clang-format on
753 
754   stream::MemoryReader reader(std::as_bytes(std::span(encoded_proto)));
755   StreamDecoder decoder(reader, /*length=*/2u);
756 
757   EXPECT_EQ(decoder.Next(), OkStatus());
758   ASSERT_EQ(decoder.FieldNumber().value(), 1u);
759   Result<int32_t> int32 = decoder.ReadInt32();
760   ASSERT_EQ(int32.status(), OkStatus());
761   EXPECT_EQ(int32.value(), 42);
762 
763   EXPECT_EQ(decoder.Next(), Status::OutOfRange());
764 }
765 
TEST(StreamDecoder,Decode_WithLength_SkipsToEnd)766 TEST(StreamDecoder, Decode_WithLength_SkipsToEnd) {
767   // clang-format off
768   constexpr uint8_t encoded_proto[] = {
769     // type=string, k=1, v="Hello world"
770     0x08, 0x0b, 'H', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd',
771     // This field is beyond the range of the protobuf:
772     // type=sint32, k=2, v=-13
773     0x10, 0x19,
774   };
775   // clang-format on
776 
777   stream::MemoryReader reader(std::as_bytes(std::span(encoded_proto)));
778   {
779     StreamDecoder decoder(reader, /*length=*/13u);
780 
781     EXPECT_EQ(decoder.Next(), OkStatus());
782     ASSERT_EQ(decoder.FieldNumber().value(), 1u);
783     // Don't read the value out, or advance further. Destructing the object
784     // should advance to the end of the length given.
785   }
786 
787   EXPECT_EQ(reader.Tell(), 13u);
788 }
789 
TEST(StreamDecoder,RepeatedField)790 TEST(StreamDecoder, RepeatedField) {
791   // clang-format off
792   constexpr uint8_t encoded_proto[] = {
793     // type=uint32, k=1, v=0
794     0x08, 0x00,
795     // type=uint32, k=1, v=50
796     0x08, 0x32,
797     // type=uint32, k=1, v=100
798     0x08, 0x64,
799     // type=uint32, k=1, v=150
800     0x08, 0x96, 0x01,
801     // type=uint32, k=1, v=200
802     0x08, 0xc8, 0x01
803   };
804   // clang-format on
805 
806   stream::MemoryReader reader(std::as_bytes(std::span(encoded_proto)));
807   StreamDecoder decoder(reader);
808 
809   EXPECT_EQ(decoder.Next(), OkStatus());
810   ASSERT_EQ(decoder.FieldNumber().value(), 1u);
811   Result<uint32_t> uint32 = decoder.ReadUint32();
812   ASSERT_EQ(uint32.status(), OkStatus());
813   EXPECT_EQ(uint32.value(), 0u);
814 
815   EXPECT_EQ(decoder.Next(), OkStatus());
816   ASSERT_EQ(decoder.FieldNumber().value(), 1u);
817   uint32 = decoder.ReadUint32();
818   ASSERT_EQ(uint32.status(), OkStatus());
819   EXPECT_EQ(uint32.value(), 50u);
820 
821   EXPECT_EQ(decoder.Next(), OkStatus());
822   ASSERT_EQ(decoder.FieldNumber().value(), 1u);
823   uint32 = decoder.ReadUint32();
824   ASSERT_EQ(uint32.status(), OkStatus());
825   EXPECT_EQ(uint32.value(), 100u);
826 
827   EXPECT_EQ(decoder.Next(), OkStatus());
828   ASSERT_EQ(decoder.FieldNumber().value(), 1u);
829   uint32 = decoder.ReadUint32();
830   ASSERT_EQ(uint32.status(), OkStatus());
831   EXPECT_EQ(uint32.value(), 150u);
832 
833   EXPECT_EQ(decoder.Next(), OkStatus());
834   ASSERT_EQ(decoder.FieldNumber().value(), 1u);
835   uint32 = decoder.ReadUint32();
836   ASSERT_EQ(uint32.status(), OkStatus());
837   EXPECT_EQ(uint32.value(), 200u);
838 
839   EXPECT_EQ(decoder.Next(), Status::OutOfRange());
840 }
841 
TEST(StreamDecoder,RepeatedFieldVector)842 TEST(StreamDecoder, RepeatedFieldVector) {
843   // clang-format off
844   constexpr uint8_t encoded_proto[] = {
845     // type=uint32, k=1, v=0
846     0x08, 0x00,
847     // type=uint32, k=1, v=50
848     0x08, 0x32,
849     // type=uint32, k=1, v=100
850     0x08, 0x64,
851     // type=uint32, k=1, v=150
852     0x08, 0x96, 0x01,
853     // type=uint32, k=1, v=200
854     0x08, 0xc8, 0x01
855   };
856   // clang-format on
857 
858   stream::MemoryReader reader(std::as_bytes(std::span(encoded_proto)));
859   StreamDecoder decoder(reader);
860 
861   pw::Vector<uint32_t, 8> uint32{};
862 
863   EXPECT_EQ(decoder.Next(), OkStatus());
864   ASSERT_EQ(decoder.FieldNumber().value(), 1u);
865   Status status = decoder.ReadRepeatedUint32(uint32);
866   ASSERT_EQ(status, OkStatus());
867   EXPECT_EQ(uint32.size(), 1u);
868   EXPECT_EQ(uint32[0], 0u);
869 
870   EXPECT_EQ(decoder.Next(), OkStatus());
871   ASSERT_EQ(decoder.FieldNumber().value(), 1u);
872   status = decoder.ReadRepeatedUint32(uint32);
873   ASSERT_EQ(status, OkStatus());
874   EXPECT_EQ(uint32.size(), 2u);
875   EXPECT_EQ(uint32[1], 50u);
876 
877   EXPECT_EQ(decoder.Next(), OkStatus());
878   ASSERT_EQ(decoder.FieldNumber().value(), 1u);
879   status = decoder.ReadRepeatedUint32(uint32);
880   ASSERT_EQ(status, OkStatus());
881   EXPECT_EQ(uint32.size(), 3u);
882   EXPECT_EQ(uint32[2], 100u);
883 
884   EXPECT_EQ(decoder.Next(), OkStatus());
885   ASSERT_EQ(decoder.FieldNumber().value(), 1u);
886   status = decoder.ReadRepeatedUint32(uint32);
887   ASSERT_EQ(status, OkStatus());
888   EXPECT_EQ(uint32.size(), 4u);
889   EXPECT_EQ(uint32[3], 150u);
890 
891   EXPECT_EQ(decoder.Next(), OkStatus());
892   ASSERT_EQ(decoder.FieldNumber().value(), 1u);
893   status = decoder.ReadRepeatedUint32(uint32);
894   ASSERT_EQ(status, OkStatus());
895   EXPECT_EQ(uint32.size(), 5u);
896   EXPECT_EQ(uint32[4], 200u);
897 
898   EXPECT_EQ(decoder.Next(), Status::OutOfRange());
899 }
900 
TEST(StreamDecoder,RepeatedFieldVectorFull)901 TEST(StreamDecoder, RepeatedFieldVectorFull) {
902   // clang-format off
903   constexpr uint8_t encoded_proto[] = {
904     // type=uint32, k=1, v=0
905     0x08, 0x00,
906     // type=uint32, k=1, v=50
907     0x08, 0x32,
908     // type=uint32, k=1, v=100
909     0x08, 0x64,
910     // type=uint32, k=1, v=150
911     0x08, 0x96, 0x01,
912     // type=uint32, k=1, v=200
913     0x08, 0xc8, 0x01
914   };
915   // clang-format on
916 
917   stream::MemoryReader reader(std::as_bytes(std::span(encoded_proto)));
918   StreamDecoder decoder(reader);
919 
920   pw::Vector<uint32_t, 2> uint32{};
921 
922   EXPECT_EQ(decoder.Next(), OkStatus());
923   ASSERT_EQ(decoder.FieldNumber().value(), 1u);
924   Status status = decoder.ReadRepeatedUint32(uint32);
925   ASSERT_EQ(status, OkStatus());
926   EXPECT_EQ(uint32.size(), 1u);
927   EXPECT_EQ(uint32[0], 0u);
928 
929   EXPECT_EQ(decoder.Next(), OkStatus());
930   ASSERT_EQ(decoder.FieldNumber().value(), 1u);
931   status = decoder.ReadRepeatedUint32(uint32);
932   ASSERT_EQ(status, OkStatus());
933   EXPECT_EQ(uint32.size(), 2u);
934   EXPECT_EQ(uint32[1], 50u);
935 
936   EXPECT_EQ(decoder.Next(), OkStatus());
937   ASSERT_EQ(decoder.FieldNumber().value(), 1u);
938   status = decoder.ReadRepeatedUint32(uint32);
939   ASSERT_EQ(status, Status::ResourceExhausted());
940   EXPECT_EQ(uint32.size(), 2u);
941 }
942 
TEST(StreamDecoder,PackedVarint)943 TEST(StreamDecoder, PackedVarint) {
944   // clang-format off
945   constexpr uint8_t encoded_proto[] = {
946     // type=uint32[], k=1, v={0, 50, 100, 150, 200}
947     0x0a, 0x07,
948     0x00,
949     0x32,
950     0x64,
951     0x96, 0x01,
952     0xc8, 0x01
953   };
954   // clang-format on
955 
956   stream::MemoryReader reader(std::as_bytes(std::span(encoded_proto)));
957   StreamDecoder decoder(reader);
958 
959   EXPECT_EQ(decoder.Next(), OkStatus());
960   ASSERT_EQ(decoder.FieldNumber().value(), 1u);
961   std::array<uint32_t, 8> uint32{};
962   StatusWithSize size = decoder.ReadPackedUint32(uint32);
963   ASSERT_EQ(size.status(), OkStatus());
964   EXPECT_EQ(size.size(), 5u);
965 
966   EXPECT_EQ(uint32[0], 0u);
967   EXPECT_EQ(uint32[1], 50u);
968   EXPECT_EQ(uint32[2], 100u);
969   EXPECT_EQ(uint32[3], 150u);
970   EXPECT_EQ(uint32[4], 200u);
971 }
972 
TEST(StreamDecoder,PackedVarintInsufficientSpace)973 TEST(StreamDecoder, PackedVarintInsufficientSpace) {
974   // clang-format off
975   constexpr uint8_t encoded_proto[] = {
976     // type=uint32[], k=1, v={0, 50, 100, 150, 200}
977     0x0a, 0x07,
978     0x00,
979     0x32,
980     0x64,
981     0x96, 0x01,
982     0xc8, 0x01
983   };
984   // clang-format on
985 
986   stream::MemoryReader reader(std::as_bytes(std::span(encoded_proto)));
987   StreamDecoder decoder(reader);
988 
989   EXPECT_EQ(decoder.Next(), OkStatus());
990   ASSERT_EQ(decoder.FieldNumber().value(), 1u);
991   std::array<uint32_t, 2> uint32{};
992   StatusWithSize size = decoder.ReadPackedUint32(uint32);
993   ASSERT_EQ(size.status(), Status::ResourceExhausted());
994   EXPECT_EQ(size.size(), 2u);
995 
996   // Still returns values in case of error.
997   EXPECT_EQ(uint32[0], 0u);
998   EXPECT_EQ(uint32[1], 50u);
999 }
1000 
TEST(StreamDecoder,PackedVarintVector)1001 TEST(StreamDecoder, PackedVarintVector) {
1002   // clang-format off
1003   constexpr uint8_t encoded_proto[] = {
1004     // type=uint32[], k=1, v={0, 50, 100, 150, 200}
1005     0x0a, 0x07,
1006     0x00,
1007     0x32,
1008     0x64,
1009     0x96, 0x01,
1010     0xc8, 0x01
1011   };
1012   // clang-format on
1013 
1014   stream::MemoryReader reader(std::as_bytes(std::span(encoded_proto)));
1015   StreamDecoder decoder(reader);
1016 
1017   EXPECT_EQ(decoder.Next(), OkStatus());
1018   ASSERT_EQ(decoder.FieldNumber().value(), 1u);
1019   pw::Vector<uint32_t, 8> uint32{};
1020   Status status = decoder.ReadRepeatedUint32(uint32);
1021   ASSERT_EQ(status, OkStatus());
1022   EXPECT_EQ(uint32.size(), 5u);
1023 
1024   EXPECT_EQ(uint32[0], 0u);
1025   EXPECT_EQ(uint32[1], 50u);
1026   EXPECT_EQ(uint32[2], 100u);
1027   EXPECT_EQ(uint32[3], 150u);
1028   EXPECT_EQ(uint32[4], 200u);
1029 }
1030 
TEST(StreamDecoder,PackedVarintVectorFull)1031 TEST(StreamDecoder, PackedVarintVectorFull) {
1032   // clang-format off
1033   constexpr uint8_t encoded_proto[] = {
1034     // type=uint32[], k=1, v={0, 50, 100, 150, 200}
1035     0x0a, 0x07,
1036     0x00,
1037     0x32,
1038     0x64,
1039     0x96, 0x01,
1040     0xc8, 0x01
1041   };
1042   // clang-format on
1043 
1044   stream::MemoryReader reader(std::as_bytes(std::span(encoded_proto)));
1045   StreamDecoder decoder(reader);
1046 
1047   EXPECT_EQ(decoder.Next(), OkStatus());
1048   ASSERT_EQ(decoder.FieldNumber().value(), 1u);
1049   pw::Vector<uint32_t, 2> uint32{};
1050   Status status = decoder.ReadRepeatedUint32(uint32);
1051   ASSERT_EQ(status, Status::ResourceExhausted());
1052   EXPECT_EQ(uint32.size(), 2u);
1053 
1054   // Still returns values in case of error.
1055   EXPECT_EQ(uint32[0], 0u);
1056   EXPECT_EQ(uint32[1], 50u);
1057 }
1058 
TEST(StreamDecoder,PackedZigZag)1059 TEST(StreamDecoder, PackedZigZag) {
1060   // clang-format off
1061   constexpr uint8_t encoded_proto[] = {
1062     // type=sint32[], k=1, v={-100, -25, -1, 0, 1, 25, 100}
1063     0x0a, 0x09,
1064     0xc7, 0x01,
1065     0x31,
1066     0x01,
1067     0x00,
1068     0x02,
1069     0x32,
1070     0xc8, 0x01
1071   };
1072   // clang-format on
1073 
1074   stream::MemoryReader reader(std::as_bytes(std::span(encoded_proto)));
1075   StreamDecoder decoder(reader);
1076 
1077   EXPECT_EQ(decoder.Next(), OkStatus());
1078   ASSERT_EQ(decoder.FieldNumber().value(), 1u);
1079   std::array<int32_t, 8> sint32{};
1080   StatusWithSize size = decoder.ReadPackedSint32(sint32);
1081   ASSERT_EQ(size.status(), OkStatus());
1082   EXPECT_EQ(size.size(), 7u);
1083 
1084   EXPECT_EQ(sint32[0], -100);
1085   EXPECT_EQ(sint32[1], -25);
1086   EXPECT_EQ(sint32[2], -1);
1087   EXPECT_EQ(sint32[3], 0);
1088   EXPECT_EQ(sint32[4], 1);
1089   EXPECT_EQ(sint32[5], 25);
1090   EXPECT_EQ(sint32[6], 100);
1091 }
1092 
TEST(StreamDecoder,PackedZigZagVector)1093 TEST(StreamDecoder, PackedZigZagVector) {
1094   // clang-format off
1095   constexpr uint8_t encoded_proto[] = {
1096     // type=sint32[], k=1, v={-100, -25, -1, 0, 1, 25, 100}
1097     0x0a, 0x09,
1098     0xc7, 0x01,
1099     0x31,
1100     0x01,
1101     0x00,
1102     0x02,
1103     0x32,
1104     0xc8, 0x01
1105   };
1106   // clang-format on
1107 
1108   stream::MemoryReader reader(std::as_bytes(std::span(encoded_proto)));
1109   StreamDecoder decoder(reader);
1110 
1111   EXPECT_EQ(decoder.Next(), OkStatus());
1112   ASSERT_EQ(decoder.FieldNumber().value(), 1u);
1113   pw::Vector<int32_t, 8> sint32{};
1114   Status status = decoder.ReadRepeatedSint32(sint32);
1115   ASSERT_EQ(status, OkStatus());
1116   EXPECT_EQ(sint32.size(), 7u);
1117 
1118   EXPECT_EQ(sint32[0], -100);
1119   EXPECT_EQ(sint32[1], -25);
1120   EXPECT_EQ(sint32[2], -1);
1121   EXPECT_EQ(sint32[3], 0);
1122   EXPECT_EQ(sint32[4], 1);
1123   EXPECT_EQ(sint32[5], 25);
1124   EXPECT_EQ(sint32[6], 100);
1125 }
1126 
TEST(StreamDecoder,PackedFixed)1127 TEST(StreamDecoder, PackedFixed) {
1128   // clang-format off
1129   constexpr uint8_t encoded_proto[] = {
1130     // type=fixed32[], k=1, v={0, 50, 100, 150, 200}
1131     0x0a, 0x14,
1132     0x00, 0x00, 0x00, 0x00,
1133     0x32, 0x00, 0x00, 0x00,
1134     0x64, 0x00, 0x00, 0x00,
1135     0x96, 0x00, 0x00, 0x00,
1136     0xc8, 0x00, 0x00, 0x00,
1137     // type=fixed64[], v=2, v={0x0102030405060708}
1138     0x12, 0x08,
1139     0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01,
1140     // type=sfixed32[], k=3, v={0, -50, 100, -150, 200}
1141     0x1a, 0x14,
1142     0x00, 0x00, 0x00, 0x00,
1143     0xce, 0xff, 0xff, 0xff,
1144     0x64, 0x00, 0x00, 0x00,
1145     0x6a, 0xff, 0xff, 0xff,
1146     0xc8, 0x00, 0x00, 0x00,
1147     // type=sfixed64[], v=4, v={-1647993274}
1148     0x22, 0x08,
1149     0x46, 0x9e, 0xc5, 0x9d, 0xff, 0xff, 0xff, 0xff,
1150     // type=double[], k=5, v=3.14159
1151     0x2a, 0x08,
1152     0x6e, 0x86, 0x1b, 0xf0, 0xf9, 0x21, 0x09, 0x40,
1153     // type=float[], k=6, v=2.718
1154     0x32, 0x04,
1155     0xb6, 0xf3, 0x2d, 0x40,
1156   };
1157   // clang-format on
1158 
1159   stream::MemoryReader reader(std::as_bytes(std::span(encoded_proto)));
1160   StreamDecoder decoder(reader);
1161 
1162   EXPECT_EQ(decoder.Next(), OkStatus());
1163   ASSERT_EQ(decoder.FieldNumber().value(), 1u);
1164   std::array<uint32_t, 8> fixed32{};
1165   StatusWithSize size = decoder.ReadPackedFixed32(fixed32);
1166   ASSERT_EQ(size.status(), OkStatus());
1167   EXPECT_EQ(size.size(), 5u);
1168 
1169   EXPECT_EQ(fixed32[0], 0u);
1170   EXPECT_EQ(fixed32[1], 50u);
1171   EXPECT_EQ(fixed32[2], 100u);
1172   EXPECT_EQ(fixed32[3], 150u);
1173   EXPECT_EQ(fixed32[4], 200u);
1174 
1175   EXPECT_EQ(decoder.Next(), OkStatus());
1176   ASSERT_EQ(decoder.FieldNumber().value(), 2u);
1177   std::array<uint64_t, 8> fixed64{};
1178   size = decoder.ReadPackedFixed64(fixed64);
1179   ASSERT_EQ(size.status(), OkStatus());
1180   EXPECT_EQ(size.size(), 1u);
1181 
1182   EXPECT_EQ(fixed64[0], 0x0102030405060708u);
1183 
1184   EXPECT_EQ(decoder.Next(), OkStatus());
1185   ASSERT_EQ(decoder.FieldNumber().value(), 3u);
1186   std::array<int32_t, 8> sfixed32{};
1187   size = decoder.ReadPackedSfixed32(sfixed32);
1188   ASSERT_EQ(size.status(), OkStatus());
1189   EXPECT_EQ(size.size(), 5u);
1190 
1191   EXPECT_EQ(sfixed32[0], 0);
1192   EXPECT_EQ(sfixed32[1], -50);
1193   EXPECT_EQ(sfixed32[2], 100);
1194   EXPECT_EQ(sfixed32[3], -150);
1195   EXPECT_EQ(sfixed32[4], 200);
1196 
1197   EXPECT_EQ(decoder.Next(), OkStatus());
1198   ASSERT_EQ(decoder.FieldNumber().value(), 4u);
1199   std::array<int64_t, 8> sfixed64{};
1200   size = decoder.ReadPackedSfixed64(sfixed64);
1201   ASSERT_EQ(size.status(), OkStatus());
1202   EXPECT_EQ(size.size(), 1u);
1203 
1204   EXPECT_EQ(sfixed64[0], -1647993274);
1205 
1206   EXPECT_EQ(decoder.Next(), OkStatus());
1207   ASSERT_EQ(decoder.FieldNumber().value(), 5u);
1208   std::array<double, 8> dbl{};
1209   size = decoder.ReadPackedDouble(dbl);
1210   ASSERT_EQ(size.status(), OkStatus());
1211   EXPECT_EQ(size.size(), 1u);
1212 
1213   EXPECT_EQ(dbl[0], 3.14159);
1214 
1215   EXPECT_EQ(decoder.Next(), OkStatus());
1216   ASSERT_EQ(decoder.FieldNumber().value(), 6u);
1217   std::array<float, 8> flt{};
1218   size = decoder.ReadPackedFloat(flt);
1219   ASSERT_EQ(size.status(), OkStatus());
1220   EXPECT_EQ(size.size(), 1u);
1221 
1222   EXPECT_EQ(flt[0], 2.718f);
1223 
1224   EXPECT_EQ(decoder.Next(), Status::OutOfRange());
1225 }
1226 
TEST(StreamDecoder,PackedFixedInsufficientSpace)1227 TEST(StreamDecoder, PackedFixedInsufficientSpace) {
1228   // clang-format off
1229   constexpr uint8_t encoded_proto[] = {
1230     // type=fixed32[], k=1, v={0, 50, 100, 150, 200}
1231     0x0a, 0x14,
1232     0x00, 0x00, 0x00, 0x00,
1233     0x32, 0x00, 0x00, 0x00,
1234     0x64, 0x00, 0x00, 0x00,
1235     0x96, 0x00, 0x00, 0x00,
1236     0xc8, 0x00, 0x00, 0x00,
1237   };
1238   // clang-format on
1239 
1240   stream::MemoryReader reader(std::as_bytes(std::span(encoded_proto)));
1241   StreamDecoder decoder(reader);
1242 
1243   EXPECT_EQ(decoder.Next(), OkStatus());
1244   ASSERT_EQ(decoder.FieldNumber().value(), 1u);
1245   std::array<uint32_t, 2> fixed32{};
1246   StatusWithSize size = decoder.ReadPackedFixed32(fixed32);
1247   ASSERT_EQ(size.status(), Status::ResourceExhausted());
1248 }
1249 
TEST(StreamDecoder,PackedFixedVector)1250 TEST(StreamDecoder, PackedFixedVector) {
1251   // clang-format off
1252   constexpr uint8_t encoded_proto[] = {
1253     // type=sfixed32[], k=1, v={0, -50, 100, -150, 200}
1254     0x0a, 0x14,
1255     0x00, 0x00, 0x00, 0x00,
1256     0xce, 0xff, 0xff, 0xff,
1257     0x64, 0x00, 0x00, 0x00,
1258     0x6a, 0xff, 0xff, 0xff,
1259     0xc8, 0x00, 0x00, 0x00,
1260   };
1261   // clang-format on
1262 
1263   stream::MemoryReader reader(std::as_bytes(std::span(encoded_proto)));
1264   StreamDecoder decoder(reader);
1265 
1266   EXPECT_EQ(decoder.Next(), OkStatus());
1267   ASSERT_EQ(decoder.FieldNumber().value(), 1u);
1268   pw::Vector<int32_t, 8> sfixed32{};
1269   Status status = decoder.ReadRepeatedSfixed32(sfixed32);
1270   ASSERT_EQ(status, OkStatus());
1271   EXPECT_EQ(sfixed32.size(), 5u);
1272 
1273   EXPECT_EQ(sfixed32[0], 0);
1274   EXPECT_EQ(sfixed32[1], -50);
1275   EXPECT_EQ(sfixed32[2], 100);
1276   EXPECT_EQ(sfixed32[3], -150);
1277   EXPECT_EQ(sfixed32[4], 200);
1278 
1279   EXPECT_EQ(decoder.Next(), Status::OutOfRange());
1280 }
1281 
TEST(StreamDecoder,PackedFixedVectorFull)1282 TEST(StreamDecoder, PackedFixedVectorFull) {
1283   // clang-format off
1284   constexpr uint8_t encoded_proto[] = {
1285     // type=sfixed32[], k=1, v={0, -50, 100, -150, 200}
1286     0x0a, 0x14,
1287     0x00, 0x00, 0x00, 0x00,
1288     0xce, 0xff, 0xff, 0xff,
1289     0x64, 0x00, 0x00, 0x00,
1290     0x6a, 0xff, 0xff, 0xff,
1291     0xc8, 0x00, 0x00, 0x00,
1292   };
1293   // clang-format on
1294 
1295   stream::MemoryReader reader(std::as_bytes(std::span(encoded_proto)));
1296   StreamDecoder decoder(reader);
1297 
1298   EXPECT_EQ(decoder.Next(), OkStatus());
1299   ASSERT_EQ(decoder.FieldNumber().value(), 1u);
1300   pw::Vector<int32_t, 2> sfixed32{};
1301   Status status = decoder.ReadRepeatedSfixed32(sfixed32);
1302   ASSERT_EQ(status, Status::ResourceExhausted());
1303   EXPECT_EQ(sfixed32.size(), 0u);
1304 }
1305 
1306 }  // namespace
1307 }  // namespace pw::protobuf
1308