blob: 0cff426b80150ef1d86a146f621a2c8d0d5e76db [file] [log] [blame]
Alexei Frolov03e1b262021-09-02 16:56:43 -07001// 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
Scott James Remnantc2ae0742022-03-07 16:32:52 -080017#include <array>
18
Alexei Frolov03e1b262021-09-02 16:56:43 -070019#include "gtest/gtest.h"
Scott James Remnantf6565f12021-12-11 18:18:14 -080020#include "pw_status/status.h"
21#include "pw_status/status_with_size.h"
Alexei Frolov03e1b262021-09-02 16:56:43 -070022#include "pw_stream/memory_stream.h"
Scott James Remnanta5294632021-12-15 13:04:06 -080023#include "pw_stream/stream.h"
Alexei Frolov03e1b262021-09-02 16:56:43 -070024
25namespace pw::protobuf {
26namespace {
Scott James Remnanta5294632021-12-15 13:04:06 -080027// Non-seekable wrapper for MemoryReader for testing behavior when seeking is
28// not available.
29class NonSeekableMemoryReader : public stream::NonSeekableReader {
30 public:
31 explicit NonSeekableMemoryReader(stream::MemoryReader& reader)
32 : reader_(reader) {}
33
34 size_t bytes_read() const { return reader_.bytes_read(); }
35 const std::byte* data() const { return reader_.data(); }
36
37 private:
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};
Alexei Frolov03e1b262021-09-02 16:56:43 -070048
49TEST(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',
Scott James Remnant1425cfb2022-03-22 17:24:44 -070064 // 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,
Alexei Frolov03e1b262021-09-02 16:56:43 -070070 };
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
Scott James Remnant1425cfb2022-03-22 17:24:44 -0700114 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
Alexei Frolov03e1b262021-09-02 16:56:43 -0700132 EXPECT_EQ(decoder.Next(), Status::OutOfRange());
133}
134
135TEST(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
Scott James Remnanta5294632021-12-15 13:04:06 -0800168TEST(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
Alexei Frolov03e1b262021-09-02 16:56:43 -0700203TEST(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
229TEST(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
257TEST(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
314TEST(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
Scott James Remnanta5294632021-12-15 13:04:06 -0800352TEST(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
Alexei Frolov03e1b262021-09-02 16:56:43 -0700393TEST(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
425TEST(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
470TEST(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
492TEST(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
527TEST(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
580TEST(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
Scott James Remnanta5294632021-12-15 13:04:06 -0800618TEST(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
Alexei Frolov03e1b262021-09-02 16:56:43 -0700658TEST(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
Yecheng Zhao321fb692021-09-06 10:26:04 -0700683TEST(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
Scott James Remnantf6565f12021-12-11 18:18:14 -0800715TEST(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
Scott James Remnant27e12c52021-12-15 13:18:57 -0800743TEST(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
766TEST(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
Scott James Remnantc2ae0742022-03-07 16:32:52 -0800790TEST(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);
Scott James Remnant75c76842022-03-17 16:51:33 -0700838
839 EXPECT_EQ(decoder.Next(), Status::OutOfRange());
840}
841
842TEST(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
901TEST(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);
Scott James Remnantc2ae0742022-03-07 16:32:52 -0800941}
942
943TEST(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
973TEST(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
Scott James Remnant75c76842022-03-17 16:51:33 -07001001TEST(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
1031TEST(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
Scott James Remnantc2ae0742022-03-07 16:32:52 -08001059TEST(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
Scott James Remnant75c76842022-03-17 16:51:33 -07001093TEST(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
Scott James Remnantc2ae0742022-03-07 16:32:52 -08001127TEST(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,
Scott James Remnant1425cfb2022-03-22 17:24:44 -07001139 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,
Scott James Remnantc2ae0742022-03-07 16:32:52 -08001156 };
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);
Scott James Remnant1425cfb2022-03-22 17:24:44 -07001183
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());
Scott James Remnantc2ae0742022-03-07 16:32:52 -08001225}
1226
1227TEST(StreamDecoder, PackedFixedInsufficientSpace) {
1228 // clang-format off
1229 constexpr uint8_t encoded_proto[] = {
Scott James Remnant1425cfb2022-03-22 17:24:44 -07001230 // type=fixed32[], k=1, v={0, 50, 100, 150, 200}
Scott James Remnantc2ae0742022-03-07 16:32:52 -08001231 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);
Scott James Remnant1425cfb2022-03-22 17:24:44 -07001245 std::array<uint32_t, 2> fixed32{};
1246 StatusWithSize size = decoder.ReadPackedFixed32(fixed32);
Scott James Remnantc2ae0742022-03-07 16:32:52 -08001247 ASSERT_EQ(size.status(), Status::ResourceExhausted());
1248}
1249
Scott James Remnant75c76842022-03-17 16:51:33 -07001250TEST(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
1282TEST(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
Alexei Frolov03e1b262021-09-02 16:56:43 -07001306} // namespace
1307} // namespace pw::protobuf