21#include "pw_assert/assert.h"
22#include "pw_containers/vector.h"
23#include "pw_protobuf/internal/codegen.h"
24#include "pw_protobuf/wire_format.h"
25#include "pw_span/span.h"
26#include "pw_status/status.h"
27#include "pw_status/status_with_size.h"
28#include "pw_stream/stream.h"
29#include "pw_varint/stream.h"
32namespace pw::protobuf {
78 ~BytesReader()
override { decoder_.CloseBytesReader(*
this); }
80 constexpr size_t field_size()
const {
return end_offset_ - start_offset_; }
89 start_offset_(start_offset),
90 end_offset_(end_offset),
103 size_t start_offset_;
109 :
StreamDecoder(reader, std::numeric_limits<size_t>::max()) {}
116 stream_bounds_({0, length}),
118 current_field_(kInitialFieldKey),
119 delimited_field_size_(0),
120 delimited_field_offset_(0),
122 field_consumed_(
true),
123 nested_reader_open_(
false),
126 StreamDecoder(
const StreamDecoder& other) =
delete;
127 StreamDecoder& operator=(
const StreamDecoder& other) =
delete;
149 constexpr Result<uint32_t> FieldNumber()
const {
150 if (field_consumed_) {
154 return status_.
ok() ? current_field_.field_number()
155 : Result<uint32_t>(status_);
163 Result<int32_t> ReadInt32() {
164 return ReadVarintField<int32_t>(internal::VarintType::kNormal);
172 StatusWithSize ReadPackedInt32(span<int32_t> out) {
173 return ReadPackedVarintField(
174 as_writable_bytes(out),
sizeof(int32_t), internal::VarintType::kNormal);
180 return ReadRepeatedVarintField<int32_t>(out, internal::VarintType::kNormal);
184 Result<uint32_t> ReadUint32() {
185 return ReadVarintField<uint32_t>(internal::VarintType::kUnsigned);
193 StatusWithSize ReadPackedUint32(span<uint32_t> out) {
194 return ReadPackedVarintField(as_writable_bytes(out),
196 internal::VarintType::kUnsigned);
202 return ReadRepeatedVarintField<uint32_t>(out,
203 internal::VarintType::kUnsigned);
207 Result<int64_t> ReadInt64() {
208 return ReadVarintField<int64_t>(internal::VarintType::kNormal);
217 StatusWithSize ReadPackedInt64(span<int64_t> out) {
218 return ReadPackedVarintField(
219 as_writable_bytes(out),
sizeof(int64_t), internal::VarintType::kNormal);
225 return ReadRepeatedVarintField<int64_t>(out, internal::VarintType::kNormal);
229 Result<uint64_t> ReadUint64() {
230 return ReadVarintField<uint64_t>(internal::VarintType::kUnsigned);
239 StatusWithSize ReadPackedUint64(span<uint64_t> out) {
240 return ReadPackedVarintField(as_writable_bytes(out),
242 internal::VarintType::kUnsigned);
248 return ReadRepeatedVarintField<uint64_t>(out,
249 internal::VarintType::kUnsigned);
253 Result<int32_t> ReadSint32() {
254 return ReadVarintField<int32_t>(internal::VarintType::kZigZag);
263 StatusWithSize ReadPackedSint32(span<int32_t> out) {
264 return ReadPackedVarintField(
265 as_writable_bytes(out),
sizeof(int32_t), internal::VarintType::kZigZag);
271 return ReadRepeatedVarintField<int32_t>(out, internal::VarintType::kZigZag);
275 Result<int64_t> ReadSint64() {
276 return ReadVarintField<int64_t>(internal::VarintType::kZigZag);
285 StatusWithSize ReadPackedSint64(span<int64_t> out) {
286 return ReadPackedVarintField(
287 as_writable_bytes(out),
sizeof(int64_t), internal::VarintType::kZigZag);
293 return ReadRepeatedVarintField<int64_t>(out, internal::VarintType::kZigZag);
297 Result<bool> ReadBool() {
298 return ReadVarintField<bool>(internal::VarintType::kUnsigned);
307 StatusWithSize ReadPackedBool(span<bool> out) {
308 return ReadPackedVarintField(
309 as_writable_bytes(out),
sizeof(
bool), internal::VarintType::kUnsigned);
315 return ReadRepeatedVarintField<bool>(out, internal::VarintType::kUnsigned);
319 Result<uint32_t> ReadFixed32() {
return ReadFixedField<uint32_t>(); }
325 StatusWithSize ReadPackedFixed32(span<uint32_t> out) {
326 return ReadPackedFixedField(as_writable_bytes(out),
sizeof(uint32_t));
332 return ReadRepeatedFixedField<uint32_t>(out);
336 Result<uint64_t> ReadFixed64() {
return ReadFixedField<uint64_t>(); }
342 StatusWithSize ReadPackedFixed64(span<uint64_t> out) {
343 return ReadPackedFixedField(as_writable_bytes(out),
sizeof(uint64_t));
349 return ReadRepeatedFixedField<uint64_t>(out);
353 Result<int32_t> ReadSfixed32() {
return ReadFixedField<int32_t>(); }
359 StatusWithSize ReadPackedSfixed32(span<int32_t> out) {
360 return ReadPackedFixedField(as_writable_bytes(out),
sizeof(int32_t));
366 return ReadRepeatedFixedField<int32_t>(out);
370 Result<int64_t> ReadSfixed64() {
return ReadFixedField<int64_t>(); }
376 StatusWithSize ReadPackedSfixed64(span<int64_t> out) {
377 return ReadPackedFixedField(as_writable_bytes(out),
sizeof(int64_t));
383 return ReadRepeatedFixedField<int64_t>(out);
387 Result<float> ReadFloat() {
388 static_assert(
sizeof(float) ==
sizeof(uint32_t),
389 "Float and uint32_t must be the same size for protobufs");
390 return ReadFixedField<float>();
397 StatusWithSize ReadPackedFloat(span<float> out) {
398 static_assert(
sizeof(float) ==
sizeof(uint32_t),
399 "Float and uint32_t must be the same size for protobufs");
400 return ReadPackedFixedField(as_writable_bytes(out),
sizeof(
float));
406 return ReadRepeatedFixedField<float>(out);
410 Result<double> ReadDouble() {
411 static_assert(
sizeof(double) ==
sizeof(uint64_t),
412 "Double and uint64_t must be the same size for protobufs");
413 return ReadFixedField<double>();
420 StatusWithSize ReadPackedDouble(span<double> out) {
421 static_assert(
sizeof(double) ==
sizeof(uint64_t),
422 "Double and uint64_t must be the same size for protobufs");
423 return ReadPackedFixedField(as_writable_bytes(out),
sizeof(
double));
429 return ReadRepeatedFixedField<double>(out);
440 StatusWithSize ReadString(span<char> out) {
441 return ReadBytes(as_writable_bytes(out));
453 StatusWithSize ReadBytes(span<std::byte> out) {
454 return ReadDelimitedField(out);
486 BytesReader GetBytesReader();
496 StreamDecoder GetNestedDecoder();
514 : reader_(other.reader_),
515 stream_bounds_(other.stream_bounds_),
516 position_(other.position_),
517 current_field_(other.current_field_),
518 delimited_field_size_(other.delimited_field_size_),
519 delimited_field_offset_(other.delimited_field_offset_),
520 parent_(other.parent_),
521 field_consumed_(other.field_consumed_),
522 nested_reader_open_(other.nested_reader_open_),
523 status_(other.status_) {
524 PW_ASSERT(!nested_reader_open_);
528 other.nested_reader_open_ =
true;
529 other.parent_ =
nullptr;
543 friend class BytesReader;
549 static constexpr FieldKey kInitialFieldKey =
557 stream_bounds_({low, high}),
558 position_(parent->position_),
559 current_field_(kInitialFieldKey),
560 delimited_field_size_(0),
561 delimited_field_offset_(0),
563 field_consumed_(
true),
564 nested_reader_open_(
false),
569 constexpr StreamDecoder(stream::Reader& reader,
570 StreamDecoder* parent,
573 stream_bounds_({0, std::numeric_limits<size_t>::max()}),
575 current_field_(kInitialFieldKey),
576 delimited_field_size_(0),
577 delimited_field_offset_(0),
579 field_consumed_(
true),
580 nested_reader_open_(
false),
582 PW_ASSERT(!status.ok());
585 Status Advance(
size_t end_position);
587 size_t RemainingBytes() {
588 return stream_bounds_.high < std::numeric_limits<size_t>::max()
589 ? stream_bounds_.high - position_
590 : std::numeric_limits<size_t>::max();
593 void CloseBytesReader(BytesReader& reader);
594 void CloseNestedDecoder(StreamDecoder& nested);
596 Status ReadFieldKey();
599 Status ReadVarintField(span<std::byte> out, internal::VarintType decode_type);
601 StatusWithSize ReadOneVarint(span<std::byte> out,
602 internal::VarintType decode_type);
604 template <
typename T>
605 Result<T> ReadVarintField(internal::VarintType decode_type) {
607 std::is_same_v<T, bool> || std::is_same_v<T, uint32_t> ||
608 std::is_same_v<T, int32_t> || std::is_same_v<T, uint64_t> ||
609 std::is_same_v<T, int64_t>,
610 "Protobuf varints must be of type bool, uint32_t, int32_t, uint64_t, "
613 std::conditional_t<std::is_signed<T>::value, int64_t, uint64_t>;
614 static_assert(
sizeof(DecodedValue) >=
sizeof(T));
618 ReadVarintField(as_writable_bytes(span(&result, 1)), decode_type);
622 if (result >
static_cast<DecodedValue
>(std::numeric_limits<T>::max()) ||
623 result <
static_cast<DecodedValue
>(std::numeric_limits<T>::lowest())) {
628 return static_cast<T
>(result);
631 Status ReadFixedField(span<std::byte> out);
633 template <
typename T>
634 Result<T> ReadFixedField() {
636 sizeof(T) ==
sizeof(uint32_t) ||
sizeof(T) ==
sizeof(uint64_t),
637 "Protobuf fixed-size fields must be 32- or 64-bit");
640 if (Status status = ReadFixedField(as_writable_bytes(span(&result, 1)));
648 StatusWithSize ReadDelimitedField(span<std::byte> out);
650 StatusWithSize ReadPackedFixedField(span<std::byte> out,
size_t elem_size);
652 StatusWithSize ReadPackedVarintField(span<std::byte> out,
654 internal::VarintType decode_type);
656 template <
typename T>
661 const size_t old_size = out.size();
662 if (current_field_.wire_type() == WireType::kDelimited) {
663 out.resize(out.capacity());
664 const auto sws = ReadPackedFixedField(
665 as_writable_bytes(span(out.data() + old_size, out.size() - old_size)),
667 out.resize(old_size + sws.size());
670 out.resize(old_size + 1);
671 const auto status = ReadFixedField(as_writable_bytes(
672 span(out.data() + old_size, out.size() - old_size)));
674 out.resize(old_size);
680 template <
typename T>
682 internal::VarintType decode_type) {
686 const size_t old_size = out.size();
687 if (current_field_.wire_type() == WireType::kDelimited) {
688 out.resize(out.capacity());
689 const auto sws = ReadPackedVarintField(
690 as_writable_bytes(span(out.data() + old_size, out.size() - old_size)),
693 out.resize(old_size + sws.size());
696 out.resize(old_size + 1);
697 const auto status = ReadVarintField(
698 as_writable_bytes(span(out.data() + old_size, out.size() - old_size)),
701 out.resize(old_size);
707 template <
typename Container>
708 Status ReadStringOrBytesField(std::byte* raw_container) {
709 auto& container = *
reinterpret_cast<Container*
>(raw_container);
710 if (container.capacity() < delimited_field_size_) {
713 container.resize(container.capacity());
714 const auto sws = ReadDelimitedField(as_writable_bytes(span(container)));
715 size_t size = sws.size();
716 PW_DASSERT(size <= std::numeric_limits<uint16_t>::max());
717 container.resize(
static_cast<uint16_t
>(size));
721 Status CheckOkToRead(WireType type);
723 stream::Reader& reader_;
724 Bounds stream_bounds_;
727 FieldKey current_field_;
728 size_t delimited_field_size_;
729 size_t delimited_field_offset_;
731 StreamDecoder* parent_;
733 bool field_consumed_;
734 bool nested_reader_open_;
738 friend class Message;
static constexpr Status Cancelled()
Operation was cancelled, typically by the caller.
Definition: status.h:121
constexpr bool ok() const
Definition: status.h:214
static constexpr Status FailedPrecondition()
System isn’t in the required state; e.g. deleting a non-empty directory.
Definition: status.h:162
static constexpr Status ResourceExhausted()
Definition: status.h:157
Definition: status_with_size.h:51
Definition: wire_format.h:54
Definition: stream_decoder.h:76
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:69
Whence
Positions from which to seek.
Definition: stream.h:48
constexpr Status OkStatus()
Definition: status.h:297
Definition: stream_decoder.h:498