15#include "wpi/util/SmallVector.hpp"
35concept StringLike = std::is_convertible_v<T, std::string_view>;
48 { t.resize(
size_t()) };
49 { t.size() } -> std::same_as<size_t>;
50 { t.data() } -> std::convertible_to<void*>;
73template <Val
idatable T>
77 return std::integral<T>;
81 return std::unsigned_integral<T>;
83 return std::signed_integral<T>;
85 return std::integral<T> || std::floating_point<T>;
87 return std::integral<T> || std::floating_point<T>;
112template <ProtoCallbackUnpackable T,
typename U,
size_t N = 1>
121 m_callback.funcs.decode = CallbackFunc;
122 m_callback.arg =
this;
145 bool SizeCheck(
bool* retVal)
const {
146 if (m_storage.size() >= N) {
164 if constexpr (ProtoPackable<T>) {
167 if constexpr (std::integral<T>) {
172 m_storage.emplace_back(
static_cast<T
>(val));
178 if constexpr (std::signed_integral<T> || ProtoEnumeration<T>) {
183 m_storage.emplace_back(
static_cast<T
>(val));
189 if constexpr (std::unsigned_integral<T>) {
194 m_storage.emplace_back(
static_cast<T
>(val));
200 if constexpr (std::signed_integral<T>) {
205 m_storage.emplace_back(
static_cast<T
>(val));
211 if constexpr (std::signed_integral<T>) {
216 m_storage.emplace_back(
static_cast<T
>(val));
218 }
else if constexpr (std::unsigned_integral<T>) {
223 m_storage.emplace_back(
static_cast<T
>(val));
226 if constexpr (std::floating_point<T>) {
231 m_storage.emplace_back(
static_cast<T
>(val));
237 if constexpr (std::signed_integral<T>) {
242 m_storage.emplace_back(
static_cast<T
>(val));
244 }
else if constexpr (std::unsigned_integral<T>) {
249 m_storage.emplace_back(
static_cast<T
>(val));
252 if constexpr (std::floating_point<T>) {
257 m_storage.emplace_back(
static_cast<T
>(val));
265 }
else if constexpr (UnpackBytes<T>) {
266 T&
space = m_storage.emplace_back(T{});
270 }
else if constexpr (ProtobufSerializable<T>) {
271 ProtoInputStream<T> istream{stream};
272 auto decoded = wpi::util::Protobuf<T>::Unpack(istream);
273 if (decoded.has_value()) {
274 m_storage.emplace_back(std::move(decoded.value()));
289 if constexpr (ProtoPackable<T>) {
293 if (!SizeCheck(&sizeRetVal)) {
297 if (!Decode(stream, fieldType)) {
305 if (!SizeCheck(&sizeRetVal)) {
310 return Decode(stream, fieldType);
334template <ProtoCallbackUnpackable T,
size_t N = 1>
352 std::span<T>
Items() noexcept {
return m_storedBuffer; }
359 std::span<const T>
Items() const noexcept {
return m_storedBuffer; }
366 wpi::util::SmallVector<T, N>&
Vec() noexcept {
return m_storedBuffer; }
369 wpi::util::SmallVector<T, N> m_storedBuffer;
381template <ProtoCallbackUnpackable T,
size_t N = 1>
398 std::span<T>
Items() noexcept {
return m_storedBuffer; }
405 std::span<const T>
Items() const noexcept {
return m_storedBuffer; }
412 std::vector<T>&
Vec() noexcept {
return m_storedBuffer; }
415 std::vector<T> m_storedBuffer;
422template <ProtoCallbackUnpackable T,
size_t N>
429 template <
typename... ArgTypes>
446template <ProtoCallbackUnpackable T,
size_t N>
462 bool IsFull() const noexcept {
return m_array.m_currentIndex == N; }
469 size_t Size() const noexcept {
return m_array.m_currentIndex; }
488template <ProtoCallbackPackable T,
489 std::ranges::input_range R = std::span<const T>>
490 requires std::same_as<std::remove_cvref_t<std::ranges::range_value_t<R>>, T>
498 requires(!std::same_as<R, std::span<const T>>)
500 m_callback.funcs.encode = CallbackFunc;
501 m_callback.arg =
this;
509 requires std::same_as<R, std::span<const T>>
510 : m_storedSpan{buffer}, m_range{&m_storedSpan} {
512 m_callback.
arg =
this;
522 requires std::same_as<R, std::span<const T>>
538 static auto EncodeStreamTypeFinder() {
545 using EncodeStreamType =
decltype(EncodeStreamTypeFinder());
547 bool EncodeItem(EncodeStreamType& stream,
const pb_field_t* field,
548 const T& value)
const {
549 if constexpr (std::floating_point<T>) {
553 float flt =
static_cast<float>(value);
557 double dbl =
static_cast<double>(value);
563 }
else if constexpr (std::integral<T> || ProtoEnumeration<T>) {
583 }
else if constexpr (StringLike<T>) {
584 std::string_view view{value};
586 reinterpret_cast<const pb_byte_t*
>(view.data()),
588 }
else if constexpr (ConstVectorLike<T>) {
589 std::span<const uint8_t> view{value};
591 reinterpret_cast<const pb_byte_t*
>(view.data()),
593 }
else if constexpr (ProtobufSerializable<T>) {
594 return wpi::util::Protobuf<T>::Pack(stream, value);
599 bool writeTag)
const {
600 const R& range = *m_range;
601 if constexpr (ProtobufSerializable<T>) {
602 ProtoOutputStream<T> ostream{stream};
603 for (
const auto& i : range) {
609 if (!EncodeItem(ostream, field, i)) {
614 for (
const auto& i : range) {
620 if (!EncodeItem(*stream, field, i)) {
633 if (!EncodeLoop(&substream, field,
false)) {
648 return EncodeLoop(stream, field,
false);
653 if (std::ranges::empty(*m_range)) {
663 if constexpr (ProtoPackable<T>) {
664 return PackedEncode(stream, field);
666 return EncodeLoop(stream, field,
true);
672 return reinterpret_cast<const PackCallback*
>(*arg)->CallbackFunc(stream,
676 std::span<const T> m_storedSpan;
677 const R* m_range{
nullptr};
681template <std::ranges::input_range R>
685template <ProtoCallbackPackable T>
auto arg(const Char *name, const T &arg) -> detail::named_arg< Char, T >
Returns a named argument to be used in a formatting function.
Definition base.h:2846
@ space
Definition base.h:689
void SetLimits(DecodeLimits limit) noexcept
Set the limits on what happens if more elements exist in the buffer then expected.
Definition ProtobufCallbacks.hpp:135
DirectUnpackCallback(U &storage)
Constructs a callback from a vector like type.
Definition ProtobufCallbacks.hpp:120
DirectUnpackCallback(DirectUnpackCallback &&)=delete
DirectUnpackCallback(const DirectUnpackCallback &)=delete
DirectUnpackCallback & operator=(DirectUnpackCallback &&)=delete
DirectUnpackCallback & operator=(const DirectUnpackCallback &)=delete
pb_callback_t Callback() const
Gets the nanopb callback pointing to this object.
Definition ProtobufCallbacks.hpp:142
A callback method that will pack elements when called.
Definition ProtobufCallbacks.hpp:491
PackCallback(std::span< const T > buffer)
Constructs a pack callback from a span of elements.
Definition ProtobufCallbacks.hpp:508
PackCallback & operator=(PackCallback &&)=delete
PackCallback & operator=(const PackCallback &)=delete
PackCallback(const T *element)
Constructs a pack callback from a pointer to a single element.
Definition ProtobufCallbacks.hpp:521
pb_callback_t Callback() const
Gets the nanopb callback pointing to this object.
Definition ProtobufCallbacks.hpp:535
PackCallback(const PackCallback &)=delete
PackCallback(PackCallback &&)=delete
PackCallback(const R &range)
Constructs a pack callback from a range of elements.
Definition ProtobufCallbacks.hpp:497
Class for wrapping a nanopb ostream.
Definition Protobuf.hpp:119
std::vector< T > & Vec() noexcept
Gets a reference to the backing vector.
Definition ProtobufCallbacks.hpp:412
std::span< T > Items() noexcept
Gets a span pointing to the storage buffer.
Definition ProtobufCallbacks.hpp:398
std::span< const T > Items() const noexcept
Gets a const span pointing to the storage buffer.
Definition ProtobufCallbacks.hpp:405
StdVectorUnpackCallback()
Constructs a StdVectorUnpackCallback.
Definition ProtobufCallbacks.hpp:388
UnpackCallback()
Constructs an UnpackCallback.
Definition ProtobufCallbacks.hpp:341
wpi::util::SmallVector< T, N > & Vec() noexcept
Gets a reference to the backing small vector.
Definition ProtobufCallbacks.hpp:366
std::span< T > Items() noexcept
Gets a span pointing to the storage buffer.
Definition ProtobufCallbacks.hpp:352
std::span< const T > Items() const noexcept
Gets a const span pointing to the storage buffer.
Definition ProtobufCallbacks.hpp:359
This class is a wrapper around std::array that does compile time size checking.
Definition array.hpp:26
Definition ProtobufCallbacks.hpp:38
Definition ProtobufCallbacks.hpp:41
Definition ProtobufCallbacks.hpp:44
Definition ProtobufCallbacks.hpp:61
Definition ProtobufCallbacks.hpp:65
Definition ProtobufCallbacks.hpp:54
Definition ProtobufCallbacks.hpp:57
Specifies that a type is capable of protobuf serialization and deserialization.
Definition Protobuf.hpp:252
Definition ProtobufCallbacks.hpp:35
Definition ProtobufCallbacks.hpp:47
Definition ProtobufCallbacks.hpp:71
Converts a string literal into a format string that will be parsed at compile time and converted into...
Definition printf.h:50
Definition StringMap.hpp:773
constexpr bool ValidateType(pb_type_t type)
Definition ProtobufCallbacks.hpp:74
Definition raw_os_ostream.hpp:19
DecodeLimits
The behavior to use when more elements are in the message then expected when decoding.
Definition ProtobufCallbacks.hpp:25
@ Fail
Definition ProtobufCallbacks.hpp:31
@ Add
Definition ProtobufCallbacks.hpp:29
@ Ignore
Definition ProtobufCallbacks.hpp:27
PackCallback(const R &) -> PackCallback< std::remove_cvref_t< std::ranges::range_value_t< R > >, R >
Definition CvSource.hpp:15
struct pb_ostream_s pb_ostream_t
Definition pb.h:318
uint_least8_t pb_byte_t
Definition pb.h:228
#define PB_LTYPE_STRING
Definition pb.h:256
#define PB_LTYPE_BOOL
Definition pb.h:240
#define PB_LTYPE_FIXED64
Definition pb.h:245
#define PB_LTYPE_SVARINT
Definition pb.h:243
pb_field_iter_t pb_field_t
Definition pb.h:369
#define PB_LTYPE_UVARINT
Definition pb.h:242
#define PB_LTYPE(x)
Definition pb.h:300
#define PB_LTYPE_VARINT
Definition pb.h:241
#define PB_LTYPE_BYTES
Definition pb.h:252
@ PB_WT_STRING
Definition pb.h:433
#define PB_LTYPE_FIXED32
Definition pb.h:244
struct pb_callback_s pb_callback_t
Definition pb.h:413
struct pb_istream_s pb_istream_t
Definition pb.h:317
#define PB_LTYPE_SUBMESSAGE
Definition pb.h:260
pb_byte_t pb_type_t
Definition pb.h:235
bool pb_read(pb_istream_t *stream, pb_byte_t *buf, size_t count)
bool pb_decode_varint(pb_istream_t *stream, uint64_t *dest)
bool pb_decode_fixed32(pb_istream_t *stream, void *dest)
bool pb_decode_bool(pb_istream_t *stream, bool *dest)
bool pb_decode_fixed64(pb_istream_t *stream, void *dest)
bool pb_decode_svarint(pb_istream_t *stream, int64_t *dest)
bool pb_encode_tag_for_field(pb_ostream_t *stream, const pb_field_iter_t *field)
#define PB_OSTREAM_SIZING
Definition pb_encode.h:124
bool pb_encode_varint(pb_ostream_t *stream, uint64_t value)
bool pb_encode_fixed64(pb_ostream_t *stream, const void *value)
bool pb_encode_tag(pb_ostream_t *stream, pb_wire_type_t wiretype, uint32_t field_number)
bool pb_encode_fixed32(pb_ostream_t *stream, const void *value)
bool pb_encode_svarint(pb_ostream_t *stream, int64_t value)
bool pb_encode_string(pb_ostream_t *stream, const pb_byte_t *buffer, size_t size)
union pb_callback_s::@361166177370034357342125062245131070012154074174 funcs
void * arg
Definition pb.h:424
bool(* encode)(pb_ostream_t *stream, const pb_field_t *field, void *const *arg)
Definition pb.h:420
pb_type_t type
Definition pb.h:359
pb_size_t tag
Definition pb.h:356
size_t bytes_left
Definition pb_decode.h:49
size_t bytes_written
Definition pb_encode.h:49
A wrapper around a wpi::util::array that lets us treat it as a limited sized vector.
Definition ProtobufCallbacks.hpp:423
size_t m_currentIndex
Definition ProtobufCallbacks.hpp:425
size_t size() const
Definition ProtobufCallbacks.hpp:427
T & emplace_back(ArgTypes &&... Args)
Definition ProtobufCallbacks.hpp:430
wpi::util::array< T, N > m_array
Definition ProtobufCallbacks.hpp:424
bool IsFull() const noexcept
Returns if the buffer is completely filled up.
Definition ProtobufCallbacks.hpp:462
size_t Size() const noexcept
Returns the number of elements in the buffer.
Definition ProtobufCallbacks.hpp:469
WpiArrayUnpackCallback()
Constructs a WpiArrayUnpackCallback.
Definition ProtobufCallbacks.hpp:452
wpi::util::array< T, N > & Array() noexcept
Returns a reference to the backing array.
Definition ProtobufCallbacks.hpp:476