20#include "pw_assert/assert.h"
21#include "pw_containers/vector.h"
22#include "pw_protobuf/internal/codegen.h"
23#include "pw_protobuf/wire_format.h"
24#include "pw_span/span.h"
25#include "pw_status/status.h"
26#include "pw_status/status_with_size.h"
27#include "pw_stream/stream.h"
28#include "pw_varint/stream.h"
31namespace pw::protobuf {
77 ~BytesReader()
override { decoder_.CloseBytesReader(*
this); }
79 constexpr size_t field_size()
const {
return end_offset_ - start_offset_; }
88 start_offset_(start_offset),
89 end_offset_(end_offset),
102 size_t start_offset_;
108 :
StreamDecoder(reader, std::numeric_limits<size_t>::max()) {}
115 stream_bounds_({0, length}),
117 current_field_(kInitialFieldKey),
118 delimited_field_size_(0),
119 delimited_field_offset_(0),
121 field_consumed_(
true),
122 nested_reader_open_(
false),
125 StreamDecoder(
const StreamDecoder& other) =
delete;
126 StreamDecoder& operator=(
const StreamDecoder& other) =
delete;
148 constexpr Result<uint32_t> FieldNumber()
const {
149 if (field_consumed_) {
153 return status_.
ok() ? current_field_.field_number()
154 : Result<uint32_t>(status_);
162 Result<int32_t> ReadInt32() {
163 return ReadVarintField<int32_t>(internal::VarintType::kNormal);
171 StatusWithSize ReadPackedInt32(span<int32_t> out) {
172 return ReadPackedVarintField(
173 as_writable_bytes(out),
sizeof(int32_t), internal::VarintType::kNormal);
179 return ReadRepeatedVarintField<int32_t>(out, internal::VarintType::kNormal);
183 Result<uint32_t> ReadUint32() {
184 return ReadVarintField<uint32_t>(internal::VarintType::kUnsigned);
192 StatusWithSize ReadPackedUint32(span<uint32_t> out) {
193 return ReadPackedVarintField(as_writable_bytes(out),
195 internal::VarintType::kUnsigned);
201 return ReadRepeatedVarintField<uint32_t>(out,
202 internal::VarintType::kUnsigned);
207 template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
208 StatusWithSize ReadPackedEnum(span<T> out) {
209 static_assert(
sizeof(T) ==
sizeof(int32_t),
210 "Protobuf enums are always 4-byte integers");
211 return ReadPackedVarintField(
212 as_writable_bytes(out),
sizeof(T), internal::VarintType::kUnsigned);
217 template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
219 static_assert(
sizeof(T) ==
sizeof(int32_t),
220 "Protobuf enums are always 4-byte integers");
224 const size_t old_size = out.size();
225 out.resize(out.capacity());
226 size_t size = old_size;
228 ReadRepeatedVarintFieldGeneric(
reinterpret_cast<std::byte*
>(out.data()),
232 internal::VarintType::kUnsigned);
238 Result<int64_t> ReadInt64() {
239 return ReadVarintField<int64_t>(internal::VarintType::kNormal);
248 StatusWithSize ReadPackedInt64(span<int64_t> out) {
249 return ReadPackedVarintField(
250 as_writable_bytes(out),
sizeof(int64_t), internal::VarintType::kNormal);
256 return ReadRepeatedVarintField<int64_t>(out, internal::VarintType::kNormal);
260 Result<uint64_t> ReadUint64() {
261 return ReadVarintField<uint64_t>(internal::VarintType::kUnsigned);
270 StatusWithSize ReadPackedUint64(span<uint64_t> out) {
271 return ReadPackedVarintField(as_writable_bytes(out),
273 internal::VarintType::kUnsigned);
279 return ReadRepeatedVarintField<uint64_t>(out,
280 internal::VarintType::kUnsigned);
284 Result<int32_t> ReadSint32() {
285 return ReadVarintField<int32_t>(internal::VarintType::kZigZag);
294 StatusWithSize ReadPackedSint32(span<int32_t> out) {
295 return ReadPackedVarintField(
296 as_writable_bytes(out),
sizeof(int32_t), internal::VarintType::kZigZag);
302 return ReadRepeatedVarintField<int32_t>(out, internal::VarintType::kZigZag);
306 Result<int64_t> ReadSint64() {
307 return ReadVarintField<int64_t>(internal::VarintType::kZigZag);
316 StatusWithSize ReadPackedSint64(span<int64_t> out) {
317 return ReadPackedVarintField(
318 as_writable_bytes(out),
sizeof(int64_t), internal::VarintType::kZigZag);
324 return ReadRepeatedVarintField<int64_t>(out, internal::VarintType::kZigZag);
328 Result<bool> ReadBool() {
329 return ReadVarintField<bool>(internal::VarintType::kUnsigned);
338 StatusWithSize ReadPackedBool(span<bool> out) {
339 return ReadPackedVarintField(
340 as_writable_bytes(out),
sizeof(
bool), internal::VarintType::kUnsigned);
346 return ReadRepeatedVarintField<bool>(out, internal::VarintType::kUnsigned);
350 Result<uint32_t> ReadFixed32() {
return ReadFixedField<uint32_t>(); }
356 StatusWithSize ReadPackedFixed32(span<uint32_t> out) {
357 return ReadPackedFixedField(as_writable_bytes(out),
sizeof(uint32_t));
363 return ReadRepeatedFixedField<uint32_t>(out);
367 Result<uint64_t> ReadFixed64() {
return ReadFixedField<uint64_t>(); }
373 StatusWithSize ReadPackedFixed64(span<uint64_t> out) {
374 return ReadPackedFixedField(as_writable_bytes(out),
sizeof(uint64_t));
380 return ReadRepeatedFixedField<uint64_t>(out);
384 Result<int32_t> ReadSfixed32() {
return ReadFixedField<int32_t>(); }
390 StatusWithSize ReadPackedSfixed32(span<int32_t> out) {
391 return ReadPackedFixedField(as_writable_bytes(out),
sizeof(int32_t));
397 return ReadRepeatedFixedField<int32_t>(out);
401 Result<int64_t> ReadSfixed64() {
return ReadFixedField<int64_t>(); }
407 StatusWithSize ReadPackedSfixed64(span<int64_t> out) {
408 return ReadPackedFixedField(as_writable_bytes(out),
sizeof(int64_t));
414 return ReadRepeatedFixedField<int64_t>(out);
418 Result<float> ReadFloat() {
419 static_assert(
sizeof(float) ==
sizeof(uint32_t),
420 "Float and uint32_t must be the same size for protobufs");
421 return ReadFixedField<float>();
428 StatusWithSize ReadPackedFloat(span<float> out) {
429 static_assert(
sizeof(float) ==
sizeof(uint32_t),
430 "Float and uint32_t must be the same size for protobufs");
431 return ReadPackedFixedField(as_writable_bytes(out),
sizeof(
float));
437 return ReadRepeatedFixedField<float>(out);
441 Result<double> ReadDouble() {
442 static_assert(
sizeof(double) ==
sizeof(uint64_t),
443 "Double and uint64_t must be the same size for protobufs");
444 return ReadFixedField<double>();
451 StatusWithSize ReadPackedDouble(span<double> out) {
452 static_assert(
sizeof(double) ==
sizeof(uint64_t),
453 "Double and uint64_t must be the same size for protobufs");
454 return ReadPackedFixedField(as_writable_bytes(out),
sizeof(
double));
460 return ReadRepeatedFixedField<double>(out);
471 StatusWithSize ReadString(span<char> out) {
472 return ReadBytes(as_writable_bytes(out));
484 StatusWithSize ReadBytes(span<std::byte> out) {
485 return ReadDelimitedField(out);
517 BytesReader GetBytesReader();
527 StreamDecoder GetNestedDecoder();
545 : reader_(other.reader_),
546 stream_bounds_(other.stream_bounds_),
547 position_(other.position_),
548 current_field_(other.current_field_),
549 delimited_field_size_(other.delimited_field_size_),
550 delimited_field_offset_(other.delimited_field_offset_),
551 parent_(other.parent_),
552 field_consumed_(other.field_consumed_),
553 nested_reader_open_(other.nested_reader_open_),
554 status_(other.status_) {
555 PW_ASSERT(!nested_reader_open_);
559 other.nested_reader_open_ =
true;
560 other.parent_ =
nullptr;
574 friend class BytesReader;
580 static constexpr FieldKey kInitialFieldKey =
588 stream_bounds_({low, high}),
589 position_(parent->position_),
590 current_field_(kInitialFieldKey),
591 delimited_field_size_(0),
592 delimited_field_offset_(0),
594 field_consumed_(
true),
595 nested_reader_open_(
false),
600 constexpr StreamDecoder(stream::Reader& reader,
601 StreamDecoder* parent,
604 stream_bounds_({0, std::numeric_limits<size_t>::max()}),
606 current_field_(kInitialFieldKey),
607 delimited_field_size_(0),
608 delimited_field_offset_(0),
610 field_consumed_(
true),
611 nested_reader_open_(
false),
613 PW_ASSERT(!status.ok());
616 Status Advance(
size_t end_position);
618 size_t RemainingBytes() {
619 return stream_bounds_.high < std::numeric_limits<size_t>::max()
620 ? stream_bounds_.high - position_
621 : std::numeric_limits<size_t>::max();
624 void CloseBytesReader(BytesReader& reader);
625 void CloseNestedDecoder(StreamDecoder& nested);
627 Status ReadFieldKey();
630 Status ReadVarintField(span<std::byte> out, internal::VarintType decode_type);
632 StatusWithSize ReadOneVarint(span<std::byte> out,
633 internal::VarintType decode_type);
635 template <
typename T>
636 Result<T> ReadVarintField(internal::VarintType decode_type) {
638 std::is_same_v<T, bool> || std::is_same_v<T, uint32_t> ||
639 std::is_same_v<T, int32_t> || std::is_same_v<T, uint64_t> ||
640 std::is_same_v<T, int64_t>,
641 "Protobuf varints must be of type bool, uint32_t, int32_t, uint64_t, "
644 std::conditional_t<std::is_signed<T>::value, int64_t, uint64_t>;
645 static_assert(
sizeof(DecodedValue) >=
sizeof(T));
649 ReadVarintField(as_writable_bytes(span(&result, 1)), decode_type);
653 if (result >
static_cast<DecodedValue
>(std::numeric_limits<T>::max()) ||
654 result <
static_cast<DecodedValue
>(std::numeric_limits<T>::lowest())) {
659 return static_cast<T
>(result);
662 Status ReadFixedField(span<std::byte> out);
664 template <
typename T>
665 Result<T> ReadFixedField() {
667 sizeof(T) ==
sizeof(uint32_t) ||
sizeof(T) ==
sizeof(uint64_t),
668 "Protobuf fixed-size fields must be 32- or 64-bit");
671 if (Status status = ReadFixedField(as_writable_bytes(span(&result, 1)));
679 StatusWithSize ReadDelimitedField(span<std::byte> out);
681 StatusWithSize ReadPackedFixedField(span<std::byte> out,
size_t elem_size);
683 StatusWithSize ReadPackedVarintField(span<std::byte> out,
685 internal::VarintType decode_type);
687 template <
typename T>
690 sizeof(T) == 1 ||
sizeof(T) == 2 ||
sizeof(T) == 4 ||
sizeof(T) == 8,
691 "Unsupported element size");
695 const size_t old_size = out.size();
696 out.resize(out.capacity());
697 size_t size = old_size;
699 ReadRepeatedFixedFieldGeneric(
reinterpret_cast<std::byte*
>(out.data()),
707 template <
typename T>
709 internal::VarintType decode_type) {
711 sizeof(T) == 1 ||
sizeof(T) == 2 ||
sizeof(T) == 4 ||
sizeof(T) == 8,
712 "Unsupported element size");
716 const size_t old_size = out.size();
717 out.resize(out.capacity());
718 size_t size = old_size;
720 ReadRepeatedVarintFieldGeneric(
reinterpret_cast<std::byte*
>(out.data()),
733 Status ReadRepeatedVarintFieldGeneric(std::byte* data,
737 internal::VarintType decode_type);
739 Status ReadRepeatedFixedFieldGeneric(std::byte* data,
744 template <
typename Container>
745 Status ReadStringOrBytesField(std::byte* raw_container) {
746 auto& container = *
reinterpret_cast<Container*
>(raw_container);
747 if (container.capacity() < delimited_field_size_) {
750 container.resize(container.capacity());
751 const auto sws = ReadDelimitedField(as_writable_bytes(span(container)));
752 size_t size = sws.size();
753 PW_DASSERT(size <= std::numeric_limits<uint16_t>::max());
754 container.resize(
static_cast<uint16_t
>(size));
758 Status CheckOkToRead(WireType type);
760 stream::Reader& reader_;
761 Bounds stream_bounds_;
764 FieldKey current_field_;
765 size_t delimited_field_size_;
766 size_t delimited_field_offset_;
768 StreamDecoder* parent_;
770 bool field_consumed_;
771 bool nested_reader_open_;
775 friend class Message;
static constexpr Status Cancelled()
Definition: status.h:139
constexpr bool ok() const
Definition: status.h:346
static constexpr Status FailedPrecondition()
Definition: status.h:243
static constexpr Status ResourceExhausted()
Definition: status.h:230
Definition: status_with_size.h:51
Definition: wire_format.h:54
Definition: stream_decoder.h:75
Status DoSeek(ptrdiff_t offset, Whence origin) final
Virtual Seek() function implemented by derived classes.
StatusWithSize DoRead(ByteSpan destination) final
Virtual Read() function implemented by derived classes.
Definition: stream_decoder.h:68
Whence
Positions from which to seek.
Definition: stream.h:48
constexpr Status OkStatus()
Definition: status.h:450
Definition: stream_decoder.h:529