42#include "pw_bytes/span.h"
43#include "pw_protobuf/decoder.h"
44#include "pw_protobuf/stream_decoder.h"
45#include "pw_result/result.h"
46#include "pw_status/try.h"
49namespace pw::protobuf {
53Status AdvanceToField(Decoder& decoder, uint32_t field_number);
54Status AdvanceToField(StreamDecoder& decoder, uint32_t field_number);
58template <
typename T, auto kReadFn>
61 constexpr Finder(ConstByteSpan message, uint32_t field_number)
62 : decoder_(message), field_number_(field_number) {}
66 PW_TRY(internal::AdvanceToField(decoder_, field_number_));
67 PW_TRY((decoder_.*kReadFn)(&output));
73 uint32_t field_number_;
76template <
typename T, auto kReadFn>
80 : decoder_(reader), field_number_(field_number) {}
83 PW_TRY(internal::AdvanceToField(decoder_, field_number_));
84 Result<T> result = (decoder_.*kReadFn)();
89 return result.status().IsNotFound()
90 ? Result<T>(Status::FailedPrecondition())
95 StreamDecoder decoder_;
96 uint32_t field_number_;
102 using Finder::Finder;
105 Result<uint32_t> result = Finder::Next();
107 return result.status();
109 return static_cast<T
>(result.value());
115 :
private StreamFinder<uint32_t, &StreamDecoder::ReadUint32> {
117 using StreamFinder::StreamFinder;
120 Result<uint32_t> result = StreamFinder::Next();
122 return result.status();
124 return static_cast<T
>(result.value());
129template <
typename T, auto kReadFn>
130Result<T> Find(ConstByteSpan message, uint32_t field_number) {
132 return finder.Next();
135template <
typename T, auto kReadFn>
137 StreamFinder<T, kReadFn> finder(reader, field_number);
138 return finder.Next();
162 uint32_t field_number) {
163 return internal::Find<uint32_t, &Decoder::ReadUint32>(message, field_number);
166template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
167inline Result<uint32_t> FindUint32(ConstByteSpan message, T field) {
168 return FindUint32(message,
static_cast<uint32_t
>(field));
190 uint32_t field_number) {
191 return internal::Find<uint32_t, &StreamDecoder::ReadUint32>(message_stream,
195template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
196inline Result<uint32_t> FindUint32(
stream::Reader& message_stream, T field) {
197 return FindUint32(message_stream,
static_cast<uint32_t
>(field));
200using Uint32Finder = Finder<uint32_t, &Decoder::ReadUint32>;
201using Uint32StreamFinder = StreamFinder<uint32_t, &StreamDecoder::ReadUint32>;
221inline Result<int32_t>
FindInt32(ConstByteSpan message, uint32_t field_number) {
222 return internal::Find<int32_t, &Decoder::ReadInt32>(message, field_number);
225template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
226inline Result<int32_t> FindInt32(ConstByteSpan message, T field) {
227 return FindInt32(message,
static_cast<uint32_t
>(field));
249 uint32_t field_number) {
250 return internal::Find<int32_t, &StreamDecoder::ReadInt32>(message_stream,
254template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
255inline Result<int32_t> FindInt32(
stream::Reader& message_stream, T field) {
256 return FindInt32(message_stream,
static_cast<uint32_t
>(field));
259using Int32Finder = Finder<int32_t, &Decoder::ReadInt32>;
260using Int32StreamFinder = StreamFinder<int32_t, &StreamDecoder::ReadInt32>;
281 uint32_t field_number) {
282 return internal::Find<int32_t, &Decoder::ReadSint32>(message, field_number);
285template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
286inline Result<int32_t> FindSint32(ConstByteSpan message, T field) {
287 return FindSint32(message,
static_cast<uint32_t
>(field));
309 uint32_t field_number) {
310 return internal::Find<int32_t, &StreamDecoder::ReadSint32>(message_stream,
314template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
315inline Result<int32_t> FindSint32(
stream::Reader& message_stream, T field) {
316 return FindSint32(message_stream,
static_cast<uint32_t
>(field));
319using Sint32Finder = Finder<int32_t, &Decoder::ReadSint32>;
320using Sint32StreamFinder = StreamFinder<int32_t, &StreamDecoder::ReadSint32>;
341 uint32_t field_number) {
342 return internal::Find<uint64_t, &Decoder::ReadUint64>(message, field_number);
345template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
346inline Result<uint64_t> FindUint64(ConstByteSpan message, T field) {
347 return FindUint64(message,
static_cast<uint32_t
>(field));
369 uint32_t field_number) {
370 return internal::Find<uint64_t, &StreamDecoder::ReadUint64>(message_stream,
374template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
375inline Result<uint64_t> FindUint64(
stream::Reader& message_stream, T field) {
376 return FindUint64(message_stream,
static_cast<uint32_t
>(field));
379using Uint64Finder = Finder<uint64_t, &Decoder::ReadUint64>;
380using Uint64StreamFinder = StreamFinder<uint64_t, &StreamDecoder::ReadUint64>;
400inline Result<int64_t>
FindInt64(ConstByteSpan message, uint32_t field_number) {
401 return internal::Find<int64_t, &Decoder::ReadInt64>(message, field_number);
404template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
405inline Result<int64_t> FindInt64(ConstByteSpan message, T field) {
406 return FindInt64(message,
static_cast<uint32_t
>(field));
428 uint32_t field_number) {
429 return internal::Find<int64_t, &StreamDecoder::ReadInt64>(message_stream,
433template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
434inline Result<int64_t> FindInt64(
stream::Reader& message_stream, T field) {
435 return FindInt64(message_stream,
static_cast<uint32_t
>(field));
438using Int64Finder = Finder<int64_t, &Decoder::ReadInt64>;
439using Int64StreamFinder = StreamFinder<int64_t, &StreamDecoder::ReadInt64>;
460 uint32_t field_number) {
461 return internal::Find<int64_t, &Decoder::ReadSint64>(message, field_number);
464template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
465inline Result<int64_t> FindSint64(ConstByteSpan message, T field) {
466 return FindSint64(message,
static_cast<uint32_t
>(field));
488 uint32_t field_number) {
489 return internal::Find<int64_t, &StreamDecoder::ReadSint64>(message_stream,
493template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
494inline Result<int64_t> FindSint64(
stream::Reader& message_stream, T field) {
495 return FindSint64(message_stream,
static_cast<uint32_t
>(field));
498using Sint64Finder = Finder<int64_t, &Decoder::ReadSint64>;
499using Sint64StreamFinder = StreamFinder<int64_t, &StreamDecoder::ReadSint64>;
519inline Result<bool>
FindBool(ConstByteSpan message, uint32_t field_number) {
520 return internal::Find<bool, &Decoder::ReadBool>(message, field_number);
523template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
524inline Result<bool> FindBool(ConstByteSpan message, T field) {
525 return FindBool(message,
static_cast<uint32_t
>(field));
547 uint32_t field_number) {
548 return internal::Find<bool, &StreamDecoder::ReadBool>(message_stream,
552template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
553inline Result<bool> FindBool(
stream::Reader& message_stream, T field) {
554 return FindBool(message_stream,
static_cast<uint32_t
>(field));
557using BoolFinder = Finder<bool, &Decoder::ReadBool>;
558using BoolStreamFinder = StreamFinder<bool, &StreamDecoder::ReadBool>;
579 uint32_t field_number) {
580 return internal::Find<uint32_t, &Decoder::ReadFixed32>(message, field_number);
583template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
584inline Result<uint32_t> FindFixed32(ConstByteSpan message, T field) {
585 return FindFixed32(message,
static_cast<uint32_t
>(field));
607 uint32_t field_number) {
608 return internal::Find<uint32_t, &StreamDecoder::ReadFixed32>(message_stream,
612template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
613inline Result<uint32_t> FindFixed32(
stream::Reader& message_stream, T field) {
614 return FindFixed32(message_stream,
static_cast<uint32_t
>(field));
617using Fixed32Finder = Finder<uint32_t, &Decoder::ReadFixed32>;
618using Fixed32StreamFinder = StreamFinder<uint32_t, &StreamDecoder::ReadFixed32>;
639 uint32_t field_number) {
640 return internal::Find<uint64_t, &Decoder::ReadFixed64>(message, field_number);
643template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
644inline Result<uint64_t> FindFixed64(ConstByteSpan message, T field) {
645 return FindFixed64(message,
static_cast<uint32_t
>(field));
667 uint32_t field_number) {
668 return internal::Find<uint64_t, &StreamDecoder::ReadFixed64>(message_stream,
672template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
673inline Result<uint64_t> FindFixed64(
stream::Reader& message_stream, T field) {
674 return FindFixed64(message_stream,
static_cast<uint32_t
>(field));
677using Fixed64Finder = Finder<uint64_t, &Decoder::ReadFixed64>;
678using Fixed64StreamFinder = StreamFinder<uint64_t, &StreamDecoder::ReadFixed64>;
699 uint32_t field_number) {
700 return internal::Find<int32_t, &Decoder::ReadSfixed32>(message, field_number);
703template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
704inline Result<int32_t> FindSfixed32(ConstByteSpan message, T field) {
705 return FindSfixed32(message,
static_cast<uint32_t
>(field));
727 uint32_t field_number) {
728 return internal::Find<int32_t, &StreamDecoder::ReadSfixed32>(message_stream,
732template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
733inline Result<int32_t> FindSfixed32(
stream::Reader& message_stream, T field) {
734 return FindSfixed32(message_stream,
static_cast<uint32_t
>(field));
737using Sfixed32Finder = Finder<int32_t, &Decoder::ReadSfixed32>;
738using Sfixed32StreamFinder =
739 StreamFinder<int32_t, &StreamDecoder::ReadSfixed32>;
760 uint32_t field_number) {
761 return internal::Find<int64_t, &Decoder::ReadSfixed64>(message, field_number);
764template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
765inline Result<int64_t> FindSfixed64(ConstByteSpan message, T field) {
766 return FindSfixed64(message,
static_cast<uint32_t
>(field));
788 uint32_t field_number) {
789 return internal::Find<int64_t, &StreamDecoder::ReadSfixed64>(message_stream,
793template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
794inline Result<int64_t> FindSfixed64(
stream::Reader& message_stream, T field) {
795 return FindSfixed64(message_stream,
static_cast<uint32_t
>(field));
798using Sfixed64Finder = Finder<int64_t, &Decoder::ReadSfixed64>;
799using Sfixed64StreamFinder =
800 StreamFinder<int64_t, &StreamDecoder::ReadSfixed64>;
820inline Result<float>
FindFloat(ConstByteSpan message, uint32_t field_number) {
821 return internal::Find<float, &Decoder::ReadFloat>(message, field_number);
824template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
825inline Result<float> FindFloat(ConstByteSpan message, T field) {
826 return FindFloat(message,
static_cast<uint32_t
>(field));
848 uint32_t field_number) {
849 return internal::Find<float, &StreamDecoder::ReadFloat>(message_stream,
853template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
854inline Result<float> FindFloat(
stream::Reader& message_stream, T field) {
855 return FindFloat(message_stream,
static_cast<uint32_t
>(field));
858using FloatFinder = Finder<float, &Decoder::ReadFloat>;
859using FloatStreamFinder = StreamFinder<float, &StreamDecoder::ReadFloat>;
879inline Result<double>
FindDouble(ConstByteSpan message, uint32_t field_number) {
880 return internal::Find<double, &Decoder::ReadDouble>(message, field_number);
883template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
884inline Result<double> FindDouble(ConstByteSpan message, T field) {
885 return FindDouble(message,
static_cast<uint32_t
>(field));
908 uint32_t field_number) {
909 return internal::Find<double, &StreamDecoder::ReadDouble>(message_stream,
913template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
914inline Result<double> FindDouble(
stream::Reader& message_stream, T field) {
915 return FindDouble(message_stream,
static_cast<uint32_t
>(field));
918using DoubleFinder = Finder<double, &Decoder::ReadDouble>;
919using DoubleStreamFinder = StreamFinder<double, &StreamDecoder::ReadDouble>;
940inline Result<std::string_view>
FindString(ConstByteSpan message,
941 uint32_t field_number) {
942 return internal::Find<std::string_view, &Decoder::ReadString>(message,
946template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
947inline Result<std::string_view> FindString(ConstByteSpan message, T field) {
948 return FindString(message,
static_cast<uint32_t
>(field));
973 uint32_t field_number,
975 StreamDecoder decoder(message_stream);
976 Status status = internal::AdvanceToField(decoder, field_number);
985 return sws.status().IsNotFound() ? StatusWithSize::FailedPrecondition() : sws;
1009 uint32_t field_number,
1013 out.resize_and_overwrite([&](
char* data,
size_t size) {
1014 sws =
FindString(message_stream, field_number, span(data, size));
1021template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
1025 return FindString(message_stream,
static_cast<uint32_t
>(field), out);
1028template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
1029inline StatusWithSize FindString(stream::Reader& message_stream,
1031 InlineString<>& out) {
1032 return FindString(message_stream,
static_cast<uint32_t
>(field), out);
1035using StringFinder = Finder<std::string_view, &Decoder::ReadString>;
1055inline Result<ConstByteSpan>
FindBytes(ConstByteSpan message,
1056 uint32_t field_number) {
1057 return internal::Find<ConstByteSpan, &Decoder::ReadBytes>(message,
1061template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
1062inline Result<ConstByteSpan> FindBytes(ConstByteSpan message, T field) {
1063 return FindBytes(message,
static_cast<uint32_t
>(field));
1086 uint32_t field_number,
1088 StreamDecoder decoder(message_stream);
1089 Status status = internal::AdvanceToField(decoder, field_number);
1098 return sws.status().IsNotFound() ? StatusWithSize::FailedPrecondition() : sws;
1101template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
1105 return FindBytes(message_stream,
static_cast<uint32_t
>(field), out);
1108using BytesFinder = Finder<ConstByteSpan, &Decoder::ReadBytes>;
1129 uint32_t field_number) {
1132 return FindBytes(message, field_number);
1135template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
1136inline Result<ConstByteSpan> FindSubmessage(ConstByteSpan message, T field) {
1137 return FindSubmessage(message,
static_cast<uint32_t
>(field));
1141inline Result<ConstByteSpan>
FindRaw(ConstByteSpan message,
1142 uint32_t field_number) {
1143 Decoder decoder(message);
1144 PW_TRY(internal::AdvanceToField(decoder, field_number));
1145 return decoder.RawFieldBytes();
1148template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
1149Result<ConstByteSpan> FindRaw(ConstByteSpan message, T field) {
1150 return FindRaw(message,
static_cast<uint32_t
>(field));
pw::InlineBasicString is a fixed-capacity version of std::basic_string. In brief:
Definition: string.h:64
constexpr bool ok() const
Definition: status.h:157
Definition: status_with_size.h:49
constexpr size_t size() const
Definition: status_with_size.h:146
Result< int32_t > FindInt32(ConstByteSpan message, uint32_t field_number)
Scans a serialized protobuf message for an int32 field.
Definition: find.h:221
Result< int64_t > FindInt64(ConstByteSpan message, uint32_t field_number)
Scans a serialized protobuf message for an int64 field.
Definition: find.h:400
Result< int64_t > FindSfixed64(ConstByteSpan message, uint32_t field_number)
Scans a serialized protobuf message for an sfixed64 field.
Definition: find.h:759
Result< ConstByteSpan > FindRaw(ConstByteSpan message, uint32_t field_number)
Returns a span containing the raw bytes of the value.
Definition: find.h:1141
Result< ConstByteSpan > FindBytes(ConstByteSpan message, uint32_t field_number)
Scans a serialized protobuf message for a bytes field.
Definition: find.h:1055
Result< int64_t > FindSint64(ConstByteSpan message, uint32_t field_number)
Scans a serialized protobuf message for an sint64 field.
Definition: find.h:459
Result< int32_t > FindSfixed32(ConstByteSpan message, uint32_t field_number)
Scans a serialized protobuf message for an sfixed32 field.
Definition: find.h:698
Result< int32_t > FindSint32(ConstByteSpan message, uint32_t field_number)
Scans a serialized protobuf message for an sint32 field.
Definition: find.h:280
Result< float > FindFloat(ConstByteSpan message, uint32_t field_number)
Scans a serialized protobuf message for a float field.
Definition: find.h:820
Result< uint64_t > FindFixed64(ConstByteSpan message, uint32_t field_number)
Scans a serialized protobuf message for a fixed64 field.
Definition: find.h:638
Result< uint32_t > FindFixed32(ConstByteSpan message, uint32_t field_number)
Scans a serialized protobuf message for a fixed32 field.
Definition: find.h:578
Result< ConstByteSpan > FindSubmessage(ConstByteSpan message, uint32_t field_number)
Scans a serialized protobuf message for a submessage.
Definition: find.h:1128
Result< std::string_view > FindString(ConstByteSpan message, uint32_t field_number)
Scans a serialized protobuf message for a string field.
Definition: find.h:940
Result< uint32_t > FindUint32(ConstByteSpan message, uint32_t field_number)
Scans a serialized protobuf message for a uint32 field.
Definition: find.h:161
Result< uint64_t > FindUint64(ConstByteSpan message, uint32_t field_number)
Scans a serialized protobuf message for a uint64 field.
Definition: find.h:340
Result< double > FindDouble(ConstByteSpan message, uint32_t field_number)
Scans a serialized protobuf message for a double field.
Definition: find.h:879
Result< bool > FindBool(ConstByteSpan message, uint32_t field_number)
Scans a serialized protobuf message for a bool field.
Definition: find.h:519
pw::InlineBasicString and pw::InlineString are safer alternatives to std::basic_string and std::strin...