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_));
65 return result.status().IsNotFound()
72 uint32_t field_number_;
83 return result.status();
85 return static_cast<T
>(result.value());
91 :
private StreamFinder<uint32_t, &StreamDecoder::ReadUint32> {
93 using StreamFinder::StreamFinder;
98 return result.status();
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();
142 uint32_t field_number) {
143 return internal::Find<uint32_t, &Decoder::ReadUint32>(message, field_number);
146template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
148 return FindUint32(message,
static_cast<uint32_t
>(field));
170 uint32_t field_number) {
171 return internal::Find<uint32_t, &StreamDecoder::ReadUint32>(message_stream,
175template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
177 return FindUint32(message_stream,
static_cast<uint32_t
>(field));
180using Uint32Finder = Finder<uint32_t, &Decoder::ReadUint32>;
181using Uint32StreamFinder = StreamFinder<uint32_t, &StreamDecoder::ReadUint32>;
202 return internal::Find<int32_t, &Decoder::ReadInt32>(message, field_number);
205template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
207 return FindInt32(message,
static_cast<uint32_t
>(field));
229 uint32_t field_number) {
230 return internal::Find<int32_t, &StreamDecoder::ReadInt32>(message_stream,
234template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
236 return FindInt32(message_stream,
static_cast<uint32_t
>(field));
239using Int32Finder = Finder<int32_t, &Decoder::ReadInt32>;
240using Int32StreamFinder = StreamFinder<int32_t, &StreamDecoder::ReadInt32>;
261 uint32_t field_number) {
262 return internal::Find<int32_t, &Decoder::ReadSint32>(message, field_number);
265template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
267 return FindSint32(message,
static_cast<uint32_t
>(field));
289 uint32_t field_number) {
290 return internal::Find<int32_t, &StreamDecoder::ReadSint32>(message_stream,
294template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
296 return FindSint32(message_stream,
static_cast<uint32_t
>(field));
299using Sint32Finder = Finder<int32_t, &Decoder::ReadSint32>;
300using Sint32StreamFinder = StreamFinder<int32_t, &StreamDecoder::ReadSint32>;
321 uint32_t field_number) {
322 return internal::Find<uint64_t, &Decoder::ReadUint64>(message, field_number);
325template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
327 return FindUint64(message,
static_cast<uint32_t
>(field));
349 uint32_t field_number) {
350 return internal::Find<uint64_t, &StreamDecoder::ReadUint64>(message_stream,
354template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
356 return FindUint64(message_stream,
static_cast<uint32_t
>(field));
359using Uint64Finder = Finder<uint64_t, &Decoder::ReadUint64>;
360using Uint64StreamFinder = StreamFinder<uint64_t, &StreamDecoder::ReadUint64>;
381 return internal::Find<int64_t, &Decoder::ReadInt64>(message, field_number);
384template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
386 return FindInt64(message,
static_cast<uint32_t
>(field));
408 uint32_t field_number) {
409 return internal::Find<int64_t, &StreamDecoder::ReadInt64>(message_stream,
413template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
415 return FindInt64(message_stream,
static_cast<uint32_t
>(field));
418using Int64Finder = Finder<int64_t, &Decoder::ReadInt64>;
419using Int64StreamFinder = StreamFinder<int64_t, &StreamDecoder::ReadInt64>;
440 uint32_t field_number) {
441 return internal::Find<int64_t, &Decoder::ReadSint64>(message, field_number);
444template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
446 return FindSint64(message,
static_cast<uint32_t
>(field));
468 uint32_t field_number) {
469 return internal::Find<int64_t, &StreamDecoder::ReadSint64>(message_stream,
473template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
475 return FindSint64(message_stream,
static_cast<uint32_t
>(field));
478using Sint64Finder = Finder<int64_t, &Decoder::ReadSint64>;
479using Sint64StreamFinder = StreamFinder<int64_t, &StreamDecoder::ReadSint64>;
500 return internal::Find<bool, &Decoder::ReadBool>(message, field_number);
503template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
505 return FindBool(message,
static_cast<uint32_t
>(field));
527 uint32_t field_number) {
528 return internal::Find<bool, &StreamDecoder::ReadBool>(message_stream,
532template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
534 return FindBool(message_stream,
static_cast<uint32_t
>(field));
537using BoolFinder = Finder<bool, &Decoder::ReadBool>;
538using BoolStreamFinder = StreamFinder<bool, &StreamDecoder::ReadBool>;
559 uint32_t field_number) {
560 return internal::Find<uint32_t, &Decoder::ReadFixed32>(message, field_number);
563template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
565 return FindFixed32(message,
static_cast<uint32_t
>(field));
587 uint32_t field_number) {
588 return internal::Find<uint32_t, &StreamDecoder::ReadFixed32>(message_stream,
592template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
594 return FindFixed32(message_stream,
static_cast<uint32_t
>(field));
597using Fixed32Finder = Finder<uint32_t, &Decoder::ReadFixed32>;
598using Fixed32StreamFinder = StreamFinder<uint32_t, &StreamDecoder::ReadFixed32>;
619 uint32_t field_number) {
620 return internal::Find<uint64_t, &Decoder::ReadFixed64>(message, field_number);
623template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
625 return FindFixed64(message,
static_cast<uint32_t
>(field));
647 uint32_t field_number) {
648 return internal::Find<uint64_t, &StreamDecoder::ReadFixed64>(message_stream,
652template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
654 return FindFixed64(message_stream,
static_cast<uint32_t
>(field));
657using Fixed64Finder = Finder<uint64_t, &Decoder::ReadFixed64>;
658using Fixed64StreamFinder = StreamFinder<uint64_t, &StreamDecoder::ReadFixed64>;
679 uint32_t field_number) {
680 return internal::Find<int32_t, &Decoder::ReadSfixed32>(message, field_number);
683template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
685 return FindSfixed32(message,
static_cast<uint32_t
>(field));
707 uint32_t field_number) {
708 return internal::Find<int32_t, &StreamDecoder::ReadSfixed32>(message_stream,
712template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
714 return FindSfixed32(message_stream,
static_cast<uint32_t
>(field));
717using Sfixed32Finder = Finder<int32_t, &Decoder::ReadSfixed32>;
718using Sfixed32StreamFinder =
719 StreamFinder<int32_t, &StreamDecoder::ReadSfixed32>;
740 uint32_t field_number) {
741 return internal::Find<int64_t, &Decoder::ReadSfixed64>(message, field_number);
744template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
746 return FindSfixed64(message,
static_cast<uint32_t
>(field));
768 uint32_t field_number) {
769 return internal::Find<int64_t, &StreamDecoder::ReadSfixed64>(message_stream,
773template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
775 return FindSfixed64(message_stream,
static_cast<uint32_t
>(field));
778using Sfixed64Finder = Finder<int64_t, &Decoder::ReadSfixed64>;
779using Sfixed64StreamFinder =
780 StreamFinder<int64_t, &StreamDecoder::ReadSfixed64>;
801 return internal::Find<float, &Decoder::ReadFloat>(message, field_number);
804template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
806 return FindFloat(message,
static_cast<uint32_t
>(field));
828 uint32_t field_number) {
829 return internal::Find<float, &StreamDecoder::ReadFloat>(message_stream,
833template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
835 return FindFloat(message_stream,
static_cast<uint32_t
>(field));
838using FloatFinder = Finder<float, &Decoder::ReadFloat>;
839using FloatStreamFinder = StreamFinder<float, &StreamDecoder::ReadFloat>;
860 return internal::Find<double, &Decoder::ReadDouble>(message, field_number);
863template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
865 return FindDouble(message,
static_cast<uint32_t
>(field));
888 uint32_t field_number) {
889 return internal::Find<double, &StreamDecoder::ReadDouble>(message_stream,
893template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
895 return FindDouble(message_stream,
static_cast<uint32_t
>(field));
898using DoubleFinder = Finder<double, &Decoder::ReadDouble>;
899using DoubleStreamFinder = StreamFinder<double, &StreamDecoder::ReadDouble>;
921 uint32_t field_number) {
922 return internal::Find<std::string_view, &Decoder::ReadString>(message,
926template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
928 return FindString(message,
static_cast<uint32_t
>(field));
953 uint32_t field_number,
956 Status status = internal::AdvanceToField(decoder, field_number);
965 return sws.status().IsNotFound() ? StatusWithSize::FailedPrecondition() : sws;
989 uint32_t field_number,
993 out.resize_and_overwrite([&](
char* data,
size_t size) {
1001template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
1005 return FindString(message_stream,
static_cast<uint32_t
>(field), out);
1008template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
1009inline StatusWithSize
FindString(stream::Reader& message_stream,
1011 InlineString<>& out) {
1012 return FindString(message_stream,
static_cast<uint32_t
>(field), out);
1015using StringFinder = Finder<std::string_view, &Decoder::ReadString>;
1036 uint32_t field_number) {
1037 return internal::Find<ConstByteSpan, &Decoder::ReadBytes>(message,
1041template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
1043 return FindBytes(message,
static_cast<uint32_t
>(field));
1066 uint32_t field_number,
1069 Status status = internal::AdvanceToField(decoder, field_number);
1078 return sws.status().IsNotFound() ? StatusWithSize::FailedPrecondition() : sws;
1081template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
1085 return FindBytes(message_stream,
static_cast<uint32_t
>(field), out);
1088using BytesFinder = Finder<ConstByteSpan, &Decoder::ReadBytes>;
1109 uint32_t field_number) {
1112 return FindBytes(message, field_number);
1115template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
1122 uint32_t field_number) {
1124 PW_TRY(internal::AdvanceToField(decoder, field_number));
1125 return decoder.RawFieldBytes();
1128template <
typename T,
typename = std::enable_if_t<std::is_enum_v<T>>>
1130 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: 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
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:201
Result< int64_t > FindInt64(ConstByteSpan message, uint32_t field_number)
Scans a serialized protobuf message for an int64 field.
Definition: find.h:380
Result< int64_t > FindSfixed64(ConstByteSpan message, uint32_t field_number)
Scans a serialized protobuf message for an sfixed64 field.
Definition: find.h:739
Result< ConstByteSpan > FindRaw(ConstByteSpan message, uint32_t field_number)
Returns a span containing the raw bytes of the value.
Definition: find.h:1121
Result< ConstByteSpan > FindBytes(ConstByteSpan message, uint32_t field_number)
Scans a serialized protobuf message for a bytes field.
Definition: find.h:1035
Result< int64_t > FindSint64(ConstByteSpan message, uint32_t field_number)
Scans a serialized protobuf message for an sint64 field.
Definition: find.h:439
Result< int32_t > FindSfixed32(ConstByteSpan message, uint32_t field_number)
Scans a serialized protobuf message for an sfixed32 field.
Definition: find.h:678
Result< int32_t > FindSint32(ConstByteSpan message, uint32_t field_number)
Scans a serialized protobuf message for an sint32 field.
Definition: find.h:260
Result< float > FindFloat(ConstByteSpan message, uint32_t field_number)
Scans a serialized protobuf message for a float field.
Definition: find.h:800
Result< uint64_t > FindFixed64(ConstByteSpan message, uint32_t field_number)
Scans a serialized protobuf message for a fixed64 field.
Definition: find.h:618
Result< uint32_t > FindFixed32(ConstByteSpan message, uint32_t field_number)
Scans a serialized protobuf message for a fixed32 field.
Definition: find.h:558
Result< ConstByteSpan > FindSubmessage(ConstByteSpan message, uint32_t field_number)
Scans a serialized protobuf message for a submessage.
Definition: find.h:1108
Result< std::string_view > FindString(ConstByteSpan message, uint32_t field_number)
Scans a serialized protobuf message for a string field.
Definition: find.h:920
Result< uint32_t > FindUint32(ConstByteSpan message, uint32_t field_number)
Scans a serialized protobuf message for a uint32 field.
Definition: find.h:141
Result< uint64_t > FindUint64(ConstByteSpan message, uint32_t field_number)
Scans a serialized protobuf message for a uint64 field.
Definition: find.h:320
Result< double > FindDouble(ConstByteSpan message, uint32_t field_number)
Scans a serialized protobuf message for a double field.
Definition: find.h:859
Result< bool > FindBool(ConstByteSpan message, uint32_t field_number)
Scans a serialized protobuf message for a bool field.
Definition: find.h:499
#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...