16#include "pw_bytes/span.h"
17#include "pw_protobuf/decoder.h"
18#include "pw_protobuf/stream_decoder.h"
19#include "pw_result/result.h"
20#include "pw_status/try.h"
23namespace pw::protobuf {
27Status AdvanceToField(Decoder& decoder, uint32_t field_number);
28Status AdvanceToField(StreamDecoder& decoder, uint32_t field_number);
34template <
typename T, auto kReadFn>
38 : decoder_(message), field_number_(field_number) {}
42 PW_TRY(internal::AdvanceToField(decoder_, field_number_));
43 PW_TRY((decoder_.*kReadFn)(&output));
49 uint32_t field_number_;
52template <
typename T, auto kReadFn>
56 : decoder_(reader), field_number_(field_number) {}
59 PW_TRY(internal::AdvanceToField(decoder_, field_number_));
72 uint32_t field_number_;
85 return static_cast<T
>(result.
value());
91 :
private StreamFinder<uint32_t, &StreamDecoder::ReadUint32> {
93 using StreamFinder::StreamFinder;
100 return static_cast<T
>(result.
value());
107template <
typename T, auto kReadFn>
110 return finder.Next();
113template <
typename T, auto kReadFn>
115 StreamFinder<T, kReadFn> finder(reader, field_number);
116 return finder.Next();
133 uint32_t field_number) {
134 return internal::Find<uint32_t, &Decoder::ReadUint32>(message, field_number);
137template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
139 return FindUint32(message,
static_cast<uint32_t
>(field));
152 uint32_t field_number) {
153 return internal::Find<uint32_t, &StreamDecoder::ReadUint32>(message_stream,
157template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
159 return FindUint32(message_stream,
static_cast<uint32_t
>(field));
162using Uint32Finder = Finder<uint32_t, &Decoder::ReadUint32>;
163using Uint32StreamFinder = StreamFinder<uint32_t, &StreamDecoder::ReadUint32>;
175 return internal::Find<int32_t, &Decoder::ReadInt32>(message, field_number);
178template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
180 return FindInt32(message,
static_cast<uint32_t
>(field));
193 uint32_t field_number) {
194 return internal::Find<int32_t, &StreamDecoder::ReadInt32>(message_stream,
198template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
200 return FindInt32(message_stream,
static_cast<uint32_t
>(field));
203using Int32Finder = Finder<int32_t, &Decoder::ReadInt32>;
204using Int32StreamFinder = StreamFinder<int32_t, &StreamDecoder::ReadInt32>;
216 uint32_t field_number) {
217 return internal::Find<int32_t, &Decoder::ReadSint32>(message, field_number);
220template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
222 return FindSint32(message,
static_cast<uint32_t
>(field));
235 uint32_t field_number) {
236 return internal::Find<int32_t, &StreamDecoder::ReadSint32>(message_stream,
240template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
242 return FindSint32(message_stream,
static_cast<uint32_t
>(field));
245using Sint32Finder = Finder<int32_t, &Decoder::ReadSint32>;
246using Sint32StreamFinder = StreamFinder<int32_t, &StreamDecoder::ReadSint32>;
258 uint32_t field_number) {
259 return internal::Find<uint64_t, &Decoder::ReadUint64>(message, field_number);
262template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
264 return FindUint64(message,
static_cast<uint32_t
>(field));
277 uint32_t field_number) {
278 return internal::Find<uint64_t, &StreamDecoder::ReadUint64>(message_stream,
282template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
284 return FindUint64(message_stream,
static_cast<uint32_t
>(field));
287using Uint64Finder = Finder<uint64_t, &Decoder::ReadUint64>;
288using Uint64StreamFinder = StreamFinder<uint64_t, &StreamDecoder::ReadUint64>;
300 return internal::Find<int64_t, &Decoder::ReadInt64>(message, field_number);
303template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
305 return FindInt64(message,
static_cast<uint32_t
>(field));
318 uint32_t field_number) {
319 return internal::Find<int64_t, &StreamDecoder::ReadInt64>(message_stream,
323template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
325 return FindInt64(message_stream,
static_cast<uint32_t
>(field));
328using Int64Finder = Finder<int64_t, &Decoder::ReadInt64>;
329using Int64StreamFinder = StreamFinder<int64_t, &StreamDecoder::ReadInt64>;
341 uint32_t field_number) {
342 return internal::Find<int64_t, &Decoder::ReadSint64>(message, field_number);
345template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
347 return FindSint64(message,
static_cast<uint32_t
>(field));
360 uint32_t field_number) {
361 return internal::Find<int64_t, &StreamDecoder::ReadSint64>(message_stream,
365template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
367 return FindSint64(message_stream,
static_cast<uint32_t
>(field));
370using Sint64Finder = Finder<int64_t, &Decoder::ReadSint64>;
371using Sint64StreamFinder = StreamFinder<int64_t, &StreamDecoder::ReadSint64>;
383 return internal::Find<bool, &Decoder::ReadBool>(message, field_number);
386template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
388 return FindBool(message,
static_cast<uint32_t
>(field));
401 uint32_t field_number) {
402 return internal::Find<bool, &StreamDecoder::ReadBool>(message_stream,
406template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
408 return FindBool(message_stream,
static_cast<uint32_t
>(field));
411using BoolFinder = Finder<bool, &Decoder::ReadBool>;
412using BoolStreamFinder = StreamFinder<bool, &StreamDecoder::ReadBool>;
424 uint32_t field_number) {
425 return internal::Find<uint32_t, &Decoder::ReadFixed32>(message, field_number);
428template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
430 return FindFixed32(message,
static_cast<uint32_t
>(field));
443 uint32_t field_number) {
444 return internal::Find<uint32_t, &StreamDecoder::ReadFixed32>(message_stream,
448template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
450 return FindFixed32(message_stream,
static_cast<uint32_t
>(field));
453using Fixed32Finder = Finder<uint32_t, &Decoder::ReadFixed32>;
454using Fixed32StreamFinder = StreamFinder<uint32_t, &StreamDecoder::ReadFixed32>;
466 uint32_t field_number) {
467 return internal::Find<uint64_t, &Decoder::ReadFixed64>(message, field_number);
470template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
472 return FindFixed64(message,
static_cast<uint32_t
>(field));
485 uint32_t field_number) {
486 return internal::Find<uint64_t, &StreamDecoder::ReadFixed64>(message_stream,
490template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
492 return FindFixed64(message_stream,
static_cast<uint32_t
>(field));
495using Fixed64Finder = Finder<uint64_t, &Decoder::ReadFixed64>;
496using Fixed64StreamFinder = StreamFinder<uint64_t, &StreamDecoder::ReadFixed64>;
508 uint32_t field_number) {
509 return internal::Find<int32_t, &Decoder::ReadSfixed32>(message, field_number);
512template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
514 return FindSfixed32(message,
static_cast<uint32_t
>(field));
527 uint32_t field_number) {
528 return internal::Find<int32_t, &StreamDecoder::ReadSfixed32>(message_stream,
532template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
534 return FindSfixed32(message_stream,
static_cast<uint32_t
>(field));
537using Sfixed32Finder = Finder<int32_t, &Decoder::ReadSfixed32>;
538using Sfixed32StreamFinder =
539 StreamFinder<int32_t, &StreamDecoder::ReadSfixed32>;
551 uint32_t field_number) {
552 return internal::Find<int64_t, &Decoder::ReadSfixed64>(message, field_number);
555template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
557 return FindSfixed64(message,
static_cast<uint32_t
>(field));
570 uint32_t field_number) {
571 return internal::Find<int64_t, &StreamDecoder::ReadSfixed64>(message_stream,
575template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
577 return FindSfixed64(message_stream,
static_cast<uint32_t
>(field));
580using Sfixed64Finder = Finder<int64_t, &Decoder::ReadSfixed64>;
581using Sfixed64StreamFinder =
582 StreamFinder<int64_t, &StreamDecoder::ReadSfixed64>;
594 return internal::Find<float, &Decoder::ReadFloat>(message, field_number);
597template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
599 return FindFloat(message,
static_cast<uint32_t
>(field));
612 uint32_t field_number) {
613 return internal::Find<float, &StreamDecoder::ReadFloat>(message_stream,
617template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
619 return FindFloat(message_stream,
static_cast<uint32_t
>(field));
622using FloatFinder = Finder<float, &Decoder::ReadFloat>;
623using FloatStreamFinder = StreamFinder<float, &StreamDecoder::ReadFloat>;
635 return internal::Find<double, &Decoder::ReadDouble>(message, field_number);
638template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
640 return FindDouble(message,
static_cast<uint32_t
>(field));
653 uint32_t field_number) {
654 return internal::Find<double, &StreamDecoder::ReadDouble>(message_stream,
658template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
660 return FindDouble(message_stream,
static_cast<uint32_t
>(field));
663using DoubleFinder = Finder<double, &Decoder::ReadDouble>;
664using DoubleStreamFinder = StreamFinder<double, &StreamDecoder::ReadDouble>;
678 uint32_t field_number) {
679 return internal::Find<std::string_view, &Decoder::ReadString>(message,
683template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
685 return FindString(message,
static_cast<uint32_t
>(field));
703 uint32_t field_number,
706 Status status = internal::AdvanceToField(decoder, field_number);
715 return sws.status().
IsNotFound() ? StatusWithSize::FailedPrecondition() : sws;
731 uint32_t field_number,
735 out.resize_and_overwrite([&](
char* data,
size_t size) {
743template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
747 return FindString(message_stream,
static_cast<uint32_t
>(field), out);
750template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
751inline StatusWithSize
FindString(stream::Reader& message_stream,
753 InlineString<>& out) {
754 return FindString(message_stream,
static_cast<uint32_t
>(field), out);
757using StringFinder = Finder<std::string_view, &Decoder::ReadString>;
769 uint32_t field_number) {
770 return internal::Find<ConstByteSpan, &Decoder::ReadBytes>(message,
774template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
776 return FindBytes(message,
static_cast<uint32_t
>(field));
791 uint32_t field_number,
794 Status status = internal::AdvanceToField(decoder, field_number);
803 return sws.status().
IsNotFound() ? StatusWithSize::FailedPrecondition() : sws;
806template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
810 return FindBytes(message_stream,
static_cast<uint32_t
>(field), out);
813using BytesFinder = Finder<ConstByteSpan, &Decoder::ReadBytes>;
825 uint32_t field_number) {
831template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
838 uint32_t field_number) {
840 PW_TRY(internal::AdvanceToField(decoder, field_number));
841 return decoder.RawFieldBytes();
844template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
846 return FindRaw(message,
static_cast<uint32_t
>(field));
pw::InlineBasicString is a fixed-capacity version of std::basic_string. In brief:
Definition: string.h:68
constexpr bool ok() const
Definition: result.h:447
constexpr const T & value() const &PW_ATTRIBUTE_LIFETIME_BOUND
Definition: result.h:808
constexpr Status status() const
Definition: result.h:803
constexpr bool IsNotFound() const
Definition: status.h:365
constexpr bool ok() const
Definition: status.h:346
static constexpr Status FailedPrecondition()
Definition: status.h:243
Definition: status_with_size.h:51
constexpr size_t size() const
Definition: status_with_size.h:148
Definition: stream_decoder.h:69
Result< int32_t > FindInt32(ConstByteSpan message, uint32_t field_number)
Scans a serialized protobuf message for an int32 field.
Definition: find.h:174
Result< int64_t > FindInt64(ConstByteSpan message, uint32_t field_number)
Scans a serialized protobuf message for an int64 field.
Definition: find.h:299
Result< int64_t > FindSfixed64(ConstByteSpan message, uint32_t field_number)
Scans a serialized protobuf message for an sfixed64 field.
Definition: find.h:550
Result< ConstByteSpan > FindRaw(ConstByteSpan message, uint32_t field_number)
Returns a span containing the raw bytes of the value.
Definition: find.h:837
Result< ConstByteSpan > FindBytes(ConstByteSpan message, uint32_t field_number)
Scans a serialized protobuf message for a bytes field.
Definition: find.h:768
Result< int64_t > FindSint64(ConstByteSpan message, uint32_t field_number)
Scans a serialized protobuf message for an sint64 field.
Definition: find.h:340
Result< int32_t > FindSfixed32(ConstByteSpan message, uint32_t field_number)
Scans a serialized protobuf message for an sfixed32 field.
Definition: find.h:507
Result< int32_t > FindSint32(ConstByteSpan message, uint32_t field_number)
Scans a serialized protobuf message for an sint32 field.
Definition: find.h:215
Result< float > FindFloat(ConstByteSpan message, uint32_t field_number)
Scans a serialized protobuf message for a float field.
Definition: find.h:593
Result< uint64_t > FindFixed64(ConstByteSpan message, uint32_t field_number)
Scans a serialized protobuf message for a fixed64 field.
Definition: find.h:465
Result< uint32_t > FindFixed32(ConstByteSpan message, uint32_t field_number)
Scans a serialized protobuf message for a fixed32 field.
Definition: find.h:423
Result< ConstByteSpan > FindSubmessage(ConstByteSpan message, uint32_t field_number)
Scans a serialized protobuf message for a submessage.
Definition: find.h:824
Result< std::string_view > FindString(ConstByteSpan message, uint32_t field_number)
Scans a serialized protobuf message for a string field.
Definition: find.h:677
Result< uint32_t > FindUint32(ConstByteSpan message, uint32_t field_number)
Scans a serialized protobuf message for a uint32 field.
Definition: find.h:132
Result< uint64_t > FindUint64(ConstByteSpan message, uint32_t field_number)
Scans a serialized protobuf message for a uint64 field.
Definition: find.h:257
Result< double > FindDouble(ConstByteSpan message, uint32_t field_number)
Scans a serialized protobuf message for a double field.
Definition: find.h:634
Result< bool > FindBool(ConstByteSpan message, uint32_t field_number)
Scans a serialized protobuf message for a bool field.
Definition: find.h:382
#define PW_TRY(expr)
Returns early if expr is a non-OK Status or Result.
Definition: try.h:27
pw::InlineBasicString and pw::InlineString are safer alternatives to std::basic_string and std::strin...