C/C++ API Reference
Loading...
Searching...
No Matches
pw_protobuf

Overview

Expressive interface for encoding and decoding protocol buffers.

Main docs: Home | Extended size report

Submodules

 Find APIs
 

Classes

class  pw::protobuf::Decoder
 
class  pw::protobuf::CallbackDecoder
 
class  pw::protobuf::DecodeHandler
 
class  pw::protobuf::StreamEncoder
 
class  pw::protobuf::MemoryEncoder
 
class  pw::protobuf::Uint32
 
class  pw::protobuf::Int32
 
class  pw::protobuf::Sint32
 
class  pw::protobuf::Fixed32
 
class  pw::protobuf::Sfixed32
 
class  pw::protobuf::Uint64
 
class  pw::protobuf::Int64
 
class  pw::protobuf::Sint64
 
class  pw::protobuf::Fixed64
 
class  pw::protobuf::Sfixed64
 
class  pw::protobuf::Float
 
class  pw::protobuf::Double
 
class  pw::protobuf::Bool
 
class  pw::protobuf::Bytes
 
class  pw::protobuf::String
 
class  pw::protobuf::RepeatedFieldParser< FieldType >
 
class  pw::protobuf::StringMapEntryParser< ValueParser >
 
class  pw::protobuf::StringMapParser< ValueParser >
 
class  pw::protobuf::Message
 
class  pw::protobuf::StreamDecoder
 
class  pw::protobuf::FieldKey
 

Macros

#define PW_PROTOBUF_CFG_MAX_VARINT_SIZE   4
 

Typedefs

using pw::protobuf::RepeatedBytes = RepeatedFieldParser< Bytes >
 
using pw::protobuf::RepeatedStrings = RepeatedFieldParser< String >
 
using pw::protobuf::RepeatedMessages = RepeatedFieldParser< Message >
 
using pw::protobuf::StringToBytesMapEntry = StringMapEntryParser< Bytes >
 
using pw::protobuf::StringToStringMapEntry = StringMapEntryParser< String >
 
using pw::protobuf::StringToMessageMapEntry = StringMapEntryParser< Message >
 
using pw::protobuf::StringToBytesMap = StringMapParser< Bytes >
 
using pw::protobuf::StringToStringMap = StringMapParser< String >
 
using pw::protobuf::StringToMessageMap = StringMapParser< Message >
 

Enumerations

enum class  WireType { kVarint = 0 , kFixed64 = 1 , kDelimited = 2 , kFixed32 = 5 }
 

Functions

Result< uint32_t > pw::protobuf::DecodeBytesToUint32 (Decoder &decoder)
 
constexpr size_t pw::protobuf::MaxScratchBufferSize (size_t max_message_size, size_t max_nested_depth)
 
Status pw::protobuf::WriteVarint (uint64_t value, stream::Writer &writer)
 
Status pw::protobuf::WriteLengthDelimitedKeyAndLengthPrefix (uint32_t field_number, size_t payload_size, stream::Writer &writer)
 
template<typename ToStreamEncoder , typename FromStreamEncoder >
ToStreamEncoder & pw::protobuf::StreamEncoderCast (FromStreamEncoder &encoder)
 
Status pw::protobuf::WriteProtoStringToBytesMapEntry (uint32_t field_number, stream::Reader &key, size_t key_size, stream::Reader &value, size_t value_size, ByteSpan stream_pipe_buffer, stream::Writer &writer)
 
template<typename T >
constexpr size_t pw::protobuf::TagSizeBytes (T field_number)
 
template<typename T , typename U >
constexpr size_t pw::protobuf::SizeOfVarintField (T field_number, U value)
 
template<typename T >
constexpr size_t pw::protobuf::SizeOfDelimitedFieldWithoutValue (T field_number, uint32_t length_bytes=std::numeric_limits< uint32_t >::max())
 
template<typename T >
constexpr size_t pw::protobuf::SizeOfDelimitedField (T field_number, uint32_t length_bytes)
 
template<typename T >
constexpr size_t pw::protobuf::SizeOfField (T field_number, WireType type, size_t data_size_bytes)
 
template<typename T >
constexpr size_t pw::protobuf::SizeOfFieldFloat (T field_number)
 
template<typename T >
constexpr size_t pw::protobuf::SizeOfFieldDouble (T field_number)
 
template<typename T >
constexpr size_t pw::protobuf::SizeOfFieldInt32 (T field_number, int32_t value=-1)
 
template<typename T >
constexpr size_t pw::protobuf::SizeOfFieldInt64 (T field_number, int64_t value=-1)
 
template<typename T >
constexpr size_t pw::protobuf::SizeOfFieldSint32 (T field_number, int32_t value=std::numeric_limits< int32_t >::min())
 
template<typename T >
constexpr size_t pw::protobuf::SizeOfFieldSint64 (T field_number, int64_t value=std::numeric_limits< int64_t >::min())
 
template<typename T >
constexpr size_t pw::protobuf::SizeOfFieldUint32 (T field_number, uint32_t value=std::numeric_limits< uint32_t >::max())
 
template<typename T >
constexpr size_t pw::protobuf::SizeOfFieldUint64 (T field_number, uint64_t value=std::numeric_limits< uint64_t >::max())
 
template<typename T >
constexpr size_t pw::protobuf::SizeOfFieldFixed32 (T field_number)
 
template<typename T >
constexpr size_t pw::protobuf::SizeOfFieldFixed64 (T field_number)
 
template<typename T >
constexpr size_t pw::protobuf::SizeOfFieldSfixed32 (T field_number)
 
template<typename T >
constexpr size_t pw::protobuf::SizeOfFieldSfixed64 (T field_number)
 
template<typename T >
constexpr size_t pw::protobuf::SizeOfFieldBool (T field_number)
 
template<typename T >
constexpr size_t pw::protobuf::SizeOfFieldString (T field_number, uint32_t length_bytes)
 
template<typename T >
constexpr size_t pw::protobuf::SizeOfFieldBytes (T field_number, uint32_t length_bytes)
 
template<typename T , typename U = int32_t>
constexpr size_t pw::protobuf::SizeOfFieldEnum (T field_number, U value=static_cast< U >(-1))
 
constexpr bool pw::protobuf::ValidFieldNumber (uint32_t field_number)
 
constexpr bool pw::protobuf::ValidFieldNumber (uint64_t field_number)
 
constexpr uint32_t pw::protobuf::MakeKey (uint32_t field_number, WireType wire_type)
 
template<>
Uint32 pw::protobuf::Message::Field::As ()
 

Variables

constexpr size_t pw::protobuf::kMaxSizeBytesFixed32 = 4
 Field sizes that directly map to fixed wire types:
 
constexpr size_t pw::protobuf::kMaxSizeBytesFixed64 = 8
 
constexpr size_t pw::protobuf::kMaxSizeBytesSfixed32 = 4
 
constexpr size_t pw::protobuf::kMaxSizeBytesSfixed64 = 8
 
constexpr size_t pw::protobuf::kMaxSizeBytesFloat = kMaxSizeBytesFixed32
 
constexpr size_t pw::protobuf::kMaxSizeBytesDouble = kMaxSizeBytesFixed64
 
constexpr size_t pw::protobuf::kMaxSizeBytesUint32 = varint::kMaxVarint32SizeBytes
 Field sizes that map to varints:
 
constexpr size_t pw::protobuf::kMaxSizeBytesUint64 = varint::kMaxVarint64SizeBytes
 
constexpr size_t pw::protobuf::kMaxSizeBytesSint32 = varint::kMaxVarint32SizeBytes
 
constexpr size_t pw::protobuf::kMaxSizeBytesSint64 = varint::kMaxVarint64SizeBytes
 
constexpr size_t pw::protobuf::kMaxSizeBytesInt32 = varint::kMaxVarint64SizeBytes
 
constexpr size_t pw::protobuf::kMaxSizeBytesInt64 = varint::kMaxVarint64SizeBytes
 
constexpr size_t pw::protobuf::kMaxSizeBytesBool = 1
 
constexpr size_t pw::protobuf::kMaxSizeBytesEnum = kMaxSizeBytesInt32
 
constexpr size_t pw::protobuf::kMaxSizeOfFieldNumber = varint::kMaxVarint32SizeBytes
 
constexpr size_t pw::protobuf::kMaxSizeOfLength = varint::kMaxVarint32SizeBytes
 
static constexpr uint32_t pw::protobuf::kMaxFieldNumber = (1u << 29) - 1
 
static constexpr uint32_t pw::protobuf::kFirstReservedNumber = 19000
 
static constexpr uint32_t pw::protobuf::kLastReservedNumber = 19999
 

Macro Definition Documentation

◆ PW_PROTOBUF_CFG_MAX_VARINT_SIZE

#define PW_PROTOBUF_CFG_MAX_VARINT_SIZE   4

When encoding nested messages, this macro defines the number of bytes to reserve for the varint submessage length prefix. Nested messages are limited in size to the maximum value that can be varint-encoded into this reserved space.

The values that can be set, and their corresponding maximum submessage lengths, are outlined below:

  • 1 byte => 127 bytes
  • 2 bytes => 16,383 bytes (< 16 KiB)
  • 3 bytes => 2,097,151 bytes (< 2048 KiB)
  • 4 bytes => 268,435,455 bytes (< 256 MiB)
  • 5 bytes => 4,294,967,295 bytes (< 4 GiB, max uint32_t)

Function Documentation

◆ DecodeBytesToUint32()

Result< uint32_t > pw::protobuf::DecodeBytesToUint32 ( Decoder decoder)
inline

Decodes a proto message bytes field to a uint32_t value.

Warning
The caller must advance the decoder using Next() and verify the field number using FieldNumber() prior to calling this function; otherwise, behavior is undefined.
protobuf::Decoder decoder(request);
if (!decoder.Next().ok()) {
// Handle error.
}
if (static_cast<MyProtoMessage::Fields>(decoder.FieldNumber()) !=
MyProtoMessage::Fields::kMyFields) {
// Handle error.
}
Result<uint32_t> result = DecodeBytesToUint32(decoder);
if (result.ok()) {
// Do something with result.value().
}
Definition: decoder.h:61
Result< uint32_t > DecodeBytesToUint32(Decoder &decoder)
Definition: bytes_utils.h:54
Parameters
[in,out]decoderThe decoder currently positioned at the bytes field.
Returns
A Result containing the decoded uint32_t value on success or one of the following error codes on failure:

◆ MaxScratchBufferSize()

constexpr size_t pw::protobuf::MaxScratchBufferSize ( size_t  max_message_size,
size_t  max_nested_depth 
)
constexpr

Provides a size estimate to help with sizing buffers passed to StreamEncoder and MemoryEncoder objects.

Writing proto messages with nested submessages requires buffering due to limitations of the proto format. Every proto submessage must know the size of the submessage before its final serialization can begin. A streaming encoder can be passed a scratch buffer to use when constructing nested messages. All submessage data is buffered to this scratch buffer until the submessage is finalized. Note that the contents of this scratch buffer is not necessarily valid proto data, so don't try to use it directly.

See also
If you need to avoid scratch buffers or reduce copying of nested submessages, consider using BufferEncoder instead of StreamEncoder or MemoryEncoder.

The code generation includes a kScratchBufferSizeBytes constant that represents the size of the largest submessage and all necessary overhead, excluding the contents of any field values which require a callback. If a submessage field requires a callback due to a dependency cycle or a repeated field of unknown length, add the appropriate structure's kMaxEncodedSizeBytes constant to the scratch buffer size to guarantee enough space.

When calculating buffer sizes yourself, MaxScratchBufferSize() can be useful in estimating how much space to allocate to account for nested submessage encoding overhead.

Warning
If the scratch buffer size is not sufficient, the encoding will fail with RESOURCE_EXHAUSTED. Always check the results of Write calls or the encoder status to ensure success, as otherwise the encoded data will be invalid.
Parameters
[in]max_message_sizeFor MemoryEncoder objects, this is the max expected size of the final proto. For StreamEncoder objects, this should be the max size of any nested proto submessage that will be built with this encoder (recursively accumulating the size from the root submessage). If your proto will encode many large submessages, this value should just be the size of the largest one.
[in]max_nested_depthThe max number of nested submessage encoders that are expected to be open simultaneously to encode this proto message.

◆ SizeOfDelimitedField()

template<typename T >
constexpr size_t pw::protobuf::SizeOfDelimitedField ( field_number,
uint32_t  length_bytes 
)
constexpr

Calculates the total size of a delimited field (string, bytes, nested message, packed repeated) including the payload data itself.

◆ SizeOfDelimitedFieldWithoutValue()

template<typename T >
constexpr size_t pw::protobuf::SizeOfDelimitedFieldWithoutValue ( field_number,
uint32_t  length_bytes = std::numeric_limits<uint32_t>::max() 
)
constexpr

Calculates the size of a delimited field (string, bytes, nested message, packed repeated) excluding the payload data itself.

Accounts for the field tag and length varint only. length_bytes defaults to kMaxSizeOfLength (kMaxVarint32SizeBytes).

◆ SizeOfField()

template<typename T >
constexpr size_t pw::protobuf::SizeOfField ( field_number,
WireType  type,
size_t  data_size_bytes 
)
constexpr

Calculates the size of a proto field in the wire format.

This is the size of a final serialized protobuf entry, including the key (field number + wire type), encoded payload size (for length-delimited types), and payload data.

Parameters
[in]field_numberThe field number for the field.
[in]typeThe wire type (WireType) of the field.
[in]data_size_bytesThe size of the payload data in bytes.
Returns
The total encoded size of the field in bytes.
Precondition
field_number must be a valid field number (ValidFieldNumber(field_number)).
data_size_bytes must be smaller than or equal to std::numeric_limits<uint32_t>::max().

◆ SizeOfFieldFloat()

template<typename T >
constexpr size_t pw::protobuf::SizeOfFieldFloat ( field_number)
constexpr

Functions for calculating the worst-case serialized size of each protobuf field type. Varint fields (int32, uint64, etc.) accept a value argument that defaults to the largest-to-encode value for the type.

◆ SizeOfVarintField()

template<typename T , typename U >
constexpr size_t pw::protobuf::SizeOfVarintField ( field_number,
value 
)
constexpr

Calculates the size in bytes of a varint field (uint32/64, int32/64, sint32/64, enum).

◆ StreamEncoderCast()

template<typename ToStreamEncoder , typename FromStreamEncoder >
ToStreamEncoder & pw::protobuf::StreamEncoderCast ( FromStreamEncoder &  encoder)
inline

pw_protobuf guarantees that all generated StreamEncoder classes can be converted among each other. It is also safe to convert any MemoryEncoder to any other StreamEncoder.

This guarantee exists to facilitate usage of protobuf overlays. Protobuf overlays are protobuf message definitions that deliberately ensure that fields defined in one message will not conflict with fields defined in other messages.

// The first half of the overlaid message.
message BaseMessage {
uint32 length = 1;
reserved 2; // Reserved for Overlay
}
// OK: The second half of the overlaid message.
message Overlay {
reserved 1; // Reserved for BaseMessage
uint32 height = 2;
}
// OK: A message that overlays and bundles both types together.
message Both {
uint32 length = 1; // Defined independently by BaseMessage
uint32 height = 2; // Defined independently by Overlay
}
// BAD: Diverges from BaseMessage's definition, and can cause decode
// errors/corruption.
message InvalidOverlay {
fixed32 length = 1;
}

While this use case is somewhat uncommon, it is a core supported use case of pw_protobuf.

Warning
Using this to convert one stream encoder to another when the messages themselves do not safely overlay will result in corrupt protos. Be careful when doing this as there is no compile-time way to detect whether or not two messages are meant to overlay.
Parameters
[in]encoderThe encoder to cast.
Returns
A reference to the casted StreamEncoder type.

◆ TagSizeBytes()

template<typename T >
constexpr size_t pw::protobuf::TagSizeBytes ( field_number)
constexpr

Calculates the serialized size of a proto tag (field number + wire type).

Parameters
[in]field_numberThe field number for the field.
Returns
The size in bytes of the field's encoded tag.
Precondition
field_number must be a valid field number (ValidFieldNumber(field_number)).

◆ WriteLengthDelimitedKeyAndLengthPrefix()

Status pw::protobuf::WriteLengthDelimitedKeyAndLengthPrefix ( uint32_t  field_number,
size_t  payload_size,
stream::Writer writer 
)
inline

Writes the field key and length prefix for a length-delimited field.

It is up to the caller to ensure that this will be followed by an exact number of bytes written for the field in order to form a valid proto message.

Parameters
[in]field_numberThe field number for the field.
[in]payload_sizeThe size of the payload.
[in]writerThe output writer to write to.
Returns
  • OK: Field key and length prefix written successfully.
  • Other errors encountered by writer are returned as is.
Precondition
field_number must be a valid field number (ValidFieldNumber(field_number)).
payload_size must be smaller than or equal to std::numeric_limits<uint32_t>::max().

◆ WriteProtoStringToBytesMapEntry()

Status pw::protobuf::WriteProtoStringToBytesMapEntry ( uint32_t  field_number,
stream::Reader key,
size_t  key_size,
stream::Reader value,
size_t  value_size,
ByteSpan  stream_pipe_buffer,
stream::Writer writer 
)

Writes an entry for the proto map<string, bytes> field type.

Since all length-delimited fields can be treated as bytes, this function can be used to write any string-keyed map entry with length-delimited values, such as map<string, message> or map<string, bytes>.

Parameters
[in]field_numberThe field number for the map.
[in,out]keyStream reader for the string key payload.
[in]key_sizeNumber of bytes in the key.
[in,out]valueStream reader for the value payload.
[in]value_sizeNumber of bytes in the value.
[in]stream_pipe_bufferA non-zero sized buffer used for reading data from the readers and staging it to the writer.
[in,out]writerThe output writer to write serialized map entry data to.
Returns

◆ WriteVarint()

Status pw::protobuf::WriteVarint ( uint64_t  value,
stream::Writer writer 
)
inline

Writes a varint value to the writer.

Parameters
[in]valueThe value of the varint to write.
[in]writerThe writer for writing to output.
Returns
  • OK: Varint written successfully.
  • Other errors encountered by writer are returned as is.

Variable Documentation

◆ kMaxFieldNumber

constexpr uint32_t pw::protobuf::kMaxFieldNumber = (1u << 29) - 1
inlinestaticconstexpr

Per the protobuf specification, valid field numbers range between 1 and 2^29 - 1, inclusive. The numbers 19000 to 19999 are reserved for internal use by protobuf implementations.

◆ kMaxSizeBytesBool

constexpr size_t pw::protobuf::kMaxSizeBytesBool = 1
inlineconstexpr

The bool field type is backed by a varint, but has a limited value range (1 byte).

◆ kMaxSizeBytesInt32

constexpr size_t pw::protobuf::kMaxSizeBytesInt32 = varint::kMaxVarint64SizeBytes
inlineconstexpr

The int32 field type does not use zigzag encoding, so negative values can result in the worst-case varint size (kMaxVarint64SizeBytes).