protozero
Minimalistic protocol buffer decoder and encoder in C++.
Public Types | Public Member Functions | List of all members
protozero::pbf_reader Class Reference

#include <pbf_reader.hpp>

Inheritance diagram for protozero::pbf_reader:
Inheritance graph
[legend]

Public Types

using const_bool_iterator = const_varint_iterator< int32_t >
 Forward iterator for iterating over bool (int32 varint) values.
 
using const_enum_iterator = const_varint_iterator< int32_t >
 Forward iterator for iterating over enum (int32 varint) values.
 
using const_int32_iterator = const_varint_iterator< int32_t >
 Forward iterator for iterating over int32 (varint) values.
 
using const_sint32_iterator = const_svarint_iterator< int32_t >
 Forward iterator for iterating over sint32 (varint) values.
 
using const_uint32_iterator = const_varint_iterator< uint32_t >
 Forward iterator for iterating over uint32 (varint) values.
 
using const_int64_iterator = const_varint_iterator< int64_t >
 Forward iterator for iterating over int64 (varint) values.
 
using const_sint64_iterator = const_svarint_iterator< int64_t >
 Forward iterator for iterating over sint64 (varint) values.
 
using const_uint64_iterator = const_varint_iterator< uint64_t >
 Forward iterator for iterating over uint64 (varint) values.
 

Public Member Functions

 pbf_reader (const data_view &view) noexcept
 
 pbf_reader (const char *data, std::size_t size) noexcept
 
 pbf_reader (const std::pair< const char *, std::size_t > &data) noexcept
 
 pbf_reader (const std::string &data) noexcept
 
 pbf_reader () noexcept=default
 
 pbf_reader (const pbf_reader &) noexcept=default
 pbf_reader messages can be copied trivially.
 
 pbf_reader (pbf_reader &&) noexcept=default
 pbf_reader messages can be moved trivially.
 
pbf_readeroperator= (const pbf_reader &other) noexcept=default
 pbf_reader messages can be copied trivially.
 
pbf_readeroperator= (pbf_reader &&other) noexcept=default
 pbf_reader messages can be moved trivially.
 
void swap (pbf_reader &other) noexcept
 
 operator bool () const noexcept
 
std::size_t length () const noexcept
 
bool next ()
 
bool next (pbf_tag_type next_tag)
 
bool next (pbf_tag_type next_tag, pbf_wire_type type)
 
pbf_tag_type tag () const noexcept
 
pbf_wire_type wire_type () const noexcept
 
uint32_t tag_and_type () const noexcept
 
bool has_wire_type (pbf_wire_type type) const noexcept
 
void skip ()
 
Scalar field accessor functions
bool get_bool ()
 
int32_t get_enum ()
 
int32_t get_int32 ()
 
int32_t get_sint32 ()
 
uint32_t get_uint32 ()
 
int64_t get_int64 ()
 
int64_t get_sint64 ()
 
uint64_t get_uint64 ()
 
uint32_t get_fixed32 ()
 
int32_t get_sfixed32 ()
 
uint64_t get_fixed64 ()
 
int64_t get_sfixed64 ()
 
float get_float ()
 
double get_double ()
 
data_view get_view ()
 
std::pair< const char *, pbf_length_typeget_data ()
 
std::string get_bytes ()
 
std::string get_string ()
 
pbf_reader get_message ()
 
Repeated packed field accessor functions
iterator_range< pbf_reader::const_bool_iteratorget_packed_bool ()
 
iterator_range< pbf_reader::const_enum_iteratorget_packed_enum ()
 
iterator_range< pbf_reader::const_int32_iteratorget_packed_int32 ()
 
iterator_range< pbf_reader::const_sint32_iteratorget_packed_sint32 ()
 
iterator_range< pbf_reader::const_uint32_iteratorget_packed_uint32 ()
 
iterator_range< pbf_reader::const_int64_iteratorget_packed_int64 ()
 
iterator_range< pbf_reader::const_sint64_iteratorget_packed_sint64 ()
 
iterator_range< pbf_reader::const_uint64_iteratorget_packed_uint64 ()
 
auto get_packed_fixed32 () -> decltype(packed_fixed< uint32_t >())
 
auto get_packed_sfixed32 () -> decltype(packed_fixed< int32_t >())
 
auto get_packed_fixed64 () -> decltype(packed_fixed< uint64_t >())
 
auto get_packed_sfixed64 () -> decltype(packed_fixed< int64_t >())
 
auto get_packed_float () -> decltype(packed_fixed< float >())
 
auto get_packed_double () -> decltype(packed_fixed< double >())
 

Detailed Description

This class represents a protobuf message. Either a top-level message or a nested sub-message. Top-level messages can be created from any buffer with a pointer and length:

std::string buffer;
// fill buffer...
pbf_reader message(buffer.data(), buffer.size());

Sub-messages are created using get_message():

pbf_reader message(...);
message.next();
pbf_reader submessage = message.get_message();

All methods of the pbf_reader class except get_bytes() and get_string() provide the strong exception guarantee, ie they either succeed or do not change the pbf_reader object they are called on. Use the get_view() method instead of get_bytes() or get_string(), if you need this guarantee.

Constructor & Destructor Documentation

◆ pbf_reader() [1/5]

protozero::pbf_reader::pbf_reader ( const data_view view)
inlineexplicitnoexcept

Construct a pbf_reader message from a data_view. The pointer from the data_view will be stored inside the pbf_reader object, no data is copied. So you must make sure the view stays valid as long as the pbf_reader object is used.

The buffer must contain a complete protobuf message.

Postcondition
There is no current field.

◆ pbf_reader() [2/5]

protozero::pbf_reader::pbf_reader ( const char *  data,
std::size_t  size 
)
inlinenoexcept

Construct a pbf_reader message from a data pointer and a length. The pointer will be stored inside the pbf_reader object, no data is copied. So you must make sure the buffer stays valid as long as the pbf_reader object is used.

The buffer must contain a complete protobuf message.

Postcondition
There is no current field.

◆ pbf_reader() [3/5]

protozero::pbf_reader::pbf_reader ( const std::pair< const char *, std::size_t > &  data)
inlineexplicitnoexcept

Construct a pbf_reader message from a data pointer and a length. The pointer will be stored inside the pbf_reader object, no data is copied. So you must make sure the buffer stays valid as long as the pbf_reader object is used.

The buffer must contain a complete protobuf message.

Postcondition
There is no current field.

◆ pbf_reader() [4/5]

protozero::pbf_reader::pbf_reader ( const std::string &  data)
inlineexplicitnoexcept

Construct a pbf_reader message from a std::string. A pointer to the string internals will be stored inside the pbf_reader object, no data is copied. So you must make sure the string is unchanged as long as the pbf_reader object is used.

The string must contain a complete protobuf message.

Postcondition
There is no current field.

◆ pbf_reader() [5/5]

protozero::pbf_reader::pbf_reader ( )
defaultnoexcept

pbf_reader can be default constructed and behaves like it has an empty buffer.

Member Function Documentation

◆ get_bool()

bool protozero::pbf_reader::get_bool ( )
inline

Consume and return value of current "bool" field.

Precondition
There must be a current field (ie. next() must have returned true).
The current field must be of type "bool".
Postcondition
The current field was consumed and there is no current field now.

◆ get_bytes()

std::string protozero::pbf_reader::get_bytes ( )
inline

Consume and return value of current "bytes" field.

Precondition
There must be a current field (ie. next() must have returned true).
The current field must be of type "bytes".
Postcondition
The current field was consumed and there is no current field now.

◆ get_data()

std::pair<const char*, pbf_length_type> protozero::pbf_reader::get_data ( )
inline

Consume and return value of current "bytes" or "string" field.

Returns
A pair with a pointer to the data and the length of the data.
Precondition
There must be a current field (ie. next() must have returned true).
The current field must be of type "bytes" or "string".
Postcondition
The current field was consumed and there is no current field now.

◆ get_double()

double protozero::pbf_reader::get_double ( )
inline

Consume and return value of current "double" field.

Precondition
There must be a current field (ie. next() must have returned true).
The current field must be of type "double".
Postcondition
The current field was consumed and there is no current field now.

◆ get_enum()

int32_t protozero::pbf_reader::get_enum ( )
inline

Consume and return value of current "enum" field.

Precondition
There must be a current field (ie. next() must have returned true).
The current field must be of type "enum".
Postcondition
The current field was consumed and there is no current field now.

◆ get_fixed32()

uint32_t protozero::pbf_reader::get_fixed32 ( )
inline

Consume and return value of current "fixed32" field.

Precondition
There must be a current field (ie. next() must have returned true).
The current field must be of type "fixed32".
Postcondition
The current field was consumed and there is no current field now.

◆ get_fixed64()

uint64_t protozero::pbf_reader::get_fixed64 ( )
inline

Consume and return value of current "fixed64" field.

Precondition
There must be a current field (ie. next() must have returned true).
The current field must be of type "fixed64".
Postcondition
The current field was consumed and there is no current field now.

◆ get_float()

float protozero::pbf_reader::get_float ( )
inline

Consume and return value of current "float" field.

Precondition
There must be a current field (ie. next() must have returned true).
The current field must be of type "float".
Postcondition
The current field was consumed and there is no current field now.

◆ get_int32()

int32_t protozero::pbf_reader::get_int32 ( )
inline

Consume and return value of current "int32" varint field.

Precondition
There must be a current field (ie. next() must have returned true).
The current field must be of type "int32".
Postcondition
The current field was consumed and there is no current field now.

◆ get_int64()

int64_t protozero::pbf_reader::get_int64 ( )
inline

Consume and return value of current "int64" varint field.

Precondition
There must be a current field (ie. next() must have returned true).
The current field must be of type "int64".
Postcondition
The current field was consumed and there is no current field now.

◆ get_message()

pbf_reader protozero::pbf_reader::get_message ( )
inline

Consume and return value of current "message" field.

Precondition
There must be a current field (ie. next() must have returned true).
The current field must be of type "message".
Postcondition
The current field was consumed and there is no current field now.

◆ get_packed_bool()

iterator_range<pbf_reader::const_bool_iterator> protozero::pbf_reader::get_packed_bool ( )
inline

Consume current "repeated packed bool" field.

Returns
a pair of iterators to the beginning and one past the end of the data.
Precondition
There must be a current field (ie. next() must have returned true).
The current field must be of type "repeated packed bool".
Postcondition
The current field was consumed and there is no current field now.

◆ get_packed_double()

auto protozero::pbf_reader::get_packed_double ( ) -> decltype(packed_fixed<double>())
inline

Consume current "repeated packed double" field.

Returns
a pair of iterators to the beginning and one past the end of the data.
Precondition
There must be a current field (ie. next() must have returned true).
The current field must be of type "repeated packed double".
Postcondition
The current field was consumed and there is no current field now.

◆ get_packed_enum()

iterator_range<pbf_reader::const_enum_iterator> protozero::pbf_reader::get_packed_enum ( )
inline

Consume current "repeated packed enum" field.

Returns
a pair of iterators to the beginning and one past the end of the data.
Precondition
There must be a current field (ie. next() must have returned true).
The current field must be of type "repeated packed enum".
Postcondition
The current field was consumed and there is no current field now.

◆ get_packed_fixed32()

auto protozero::pbf_reader::get_packed_fixed32 ( ) -> decltype(packed_fixed<uint32_t>())
inline

Consume current "repeated packed fixed32" field.

Returns
a pair of iterators to the beginning and one past the end of the data.
Precondition
There must be a current field (ie. next() must have returned true).
The current field must be of type "repeated packed fixed32".
Postcondition
The current field was consumed and there is no current field now.

◆ get_packed_fixed64()

auto protozero::pbf_reader::get_packed_fixed64 ( ) -> decltype(packed_fixed<uint64_t>())
inline

Consume current "repeated packed fixed64" field.

Returns
a pair of iterators to the beginning and one past the end of the data.
Precondition
There must be a current field (ie. next() must have returned true).
The current field must be of type "repeated packed fixed64".
Postcondition
The current field was consumed and there is no current field now.

◆ get_packed_float()

auto protozero::pbf_reader::get_packed_float ( ) -> decltype(packed_fixed<float>())
inline

Consume current "repeated packed float" field.

Returns
a pair of iterators to the beginning and one past the end of the data.
Precondition
There must be a current field (ie. next() must have returned true).
The current field must be of type "repeated packed float".
Postcondition
The current field was consumed and there is no current field now.

◆ get_packed_int32()

iterator_range<pbf_reader::const_int32_iterator> protozero::pbf_reader::get_packed_int32 ( )
inline

Consume current "repeated packed int32" field.

Returns
a pair of iterators to the beginning and one past the end of the data.
Precondition
There must be a current field (ie. next() must have returned true).
The current field must be of type "repeated packed int32".
Postcondition
The current field was consumed and there is no current field now.

◆ get_packed_int64()

iterator_range<pbf_reader::const_int64_iterator> protozero::pbf_reader::get_packed_int64 ( )
inline

Consume current "repeated packed int64" field.

Returns
a pair of iterators to the beginning and one past the end of the data.
Precondition
There must be a current field (ie. next() must have returned true).
The current field must be of type "repeated packed int64".
Postcondition
The current field was consumed and there is no current field now.

◆ get_packed_sfixed32()

auto protozero::pbf_reader::get_packed_sfixed32 ( ) -> decltype(packed_fixed<int32_t>())
inline

Consume current "repeated packed sfixed32" field.

Returns
a pair of iterators to the beginning and one past the end of the data.
Precondition
There must be a current field (ie. next() must have returned true).
The current field must be of type "repeated packed sfixed32".
Postcondition
The current field was consumed and there is no current field now.

◆ get_packed_sfixed64()

auto protozero::pbf_reader::get_packed_sfixed64 ( ) -> decltype(packed_fixed<int64_t>())
inline

Consume current "repeated packed sfixed64" field.

Returns
a pair of iterators to the beginning and one past the end of the data.
Precondition
There must be a current field (ie. next() must have returned true).
The current field must be of type "repeated packed sfixed64".
Postcondition
The current field was consumed and there is no current field now.

◆ get_packed_sint32()

iterator_range<pbf_reader::const_sint32_iterator> protozero::pbf_reader::get_packed_sint32 ( )
inline

Consume current "repeated packed sint32" field.

Returns
a pair of iterators to the beginning and one past the end of the data.
Precondition
There must be a current field (ie. next() must have returned true).
The current field must be of type "repeated packed sint32".
Postcondition
The current field was consumed and there is no current field now.

◆ get_packed_sint64()

iterator_range<pbf_reader::const_sint64_iterator> protozero::pbf_reader::get_packed_sint64 ( )
inline

Consume current "repeated packed sint64" field.

Returns
a pair of iterators to the beginning and one past the end of the data.
Precondition
There must be a current field (ie. next() must have returned true).
The current field must be of type "repeated packed sint64".
Postcondition
The current field was consumed and there is no current field now.

◆ get_packed_uint32()

iterator_range<pbf_reader::const_uint32_iterator> protozero::pbf_reader::get_packed_uint32 ( )
inline

Consume current "repeated packed uint32" field.

Returns
a pair of iterators to the beginning and one past the end of the data.
Precondition
There must be a current field (ie. next() must have returned true).
The current field must be of type "repeated packed uint32".
Postcondition
The current field was consumed and there is no current field now.

◆ get_packed_uint64()

iterator_range<pbf_reader::const_uint64_iterator> protozero::pbf_reader::get_packed_uint64 ( )
inline

Consume current "repeated packed uint64" field.

Returns
a pair of iterators to the beginning and one past the end of the data.
Precondition
There must be a current field (ie. next() must have returned true).
The current field must be of type "repeated packed uint64".
Postcondition
The current field was consumed and there is no current field now.

◆ get_sfixed32()

int32_t protozero::pbf_reader::get_sfixed32 ( )
inline

Consume and return value of current "sfixed32" field.

Precondition
There must be a current field (ie. next() must have returned true).
The current field must be of type "sfixed32".
Postcondition
The current field was consumed and there is no current field now.

◆ get_sfixed64()

int64_t protozero::pbf_reader::get_sfixed64 ( )
inline

Consume and return value of current "sfixed64" field.

Precondition
There must be a current field (ie. next() must have returned true).
The current field must be of type "sfixed64".
Postcondition
The current field was consumed and there is no current field now.

◆ get_sint32()

int32_t protozero::pbf_reader::get_sint32 ( )
inline

Consume and return value of current "sint32" varint field.

Precondition
There must be a current field (ie. next() must have returned true).
The current field must be of type "sint32".
Postcondition
The current field was consumed and there is no current field now.

◆ get_sint64()

int64_t protozero::pbf_reader::get_sint64 ( )
inline

Consume and return value of current "sint64" varint field.

Precondition
There must be a current field (ie. next() must have returned true).
The current field must be of type "sint64".
Postcondition
The current field was consumed and there is no current field now.

◆ get_string()

std::string protozero::pbf_reader::get_string ( )
inline

Consume and return value of current "string" field.

Precondition
There must be a current field (ie. next() must have returned true).
The current field must be of type "string".
Postcondition
The current field was consumed and there is no current field now.

◆ get_uint32()

uint32_t protozero::pbf_reader::get_uint32 ( )
inline

Consume and return value of current "uint32" varint field.

Precondition
There must be a current field (ie. next() must have returned true).
The current field must be of type "uint32".
Postcondition
The current field was consumed and there is no current field now.

◆ get_uint64()

uint64_t protozero::pbf_reader::get_uint64 ( )
inline

Consume and return value of current "uint64" varint field.

Precondition
There must be a current field (ie. next() must have returned true).
The current field must be of type "uint64".
Postcondition
The current field was consumed and there is no current field now.

◆ get_view()

data_view protozero::pbf_reader::get_view ( )
inline

Consume and return value of current "bytes", "string", or "message" field.

Returns
A data_view object.
Precondition
There must be a current field (ie. next() must have returned true).
The current field must be of type "bytes", "string", or "message".
Postcondition
The current field was consumed and there is no current field now.

◆ has_wire_type()

bool protozero::pbf_reader::has_wire_type ( pbf_wire_type  type) const
inlinenoexcept

Check the wire type of the current field.

Returns
true if the current field has the given wire type.
Precondition
There must be a current field (ie. next() must have returned true).

◆ length()

std::size_t protozero::pbf_reader::length ( ) const
inlinenoexcept

Return the length in bytes of the current message. If you have already called next() and/or any of the get_*() functions, this will return the remaining length.

This can, for instance, be used to estimate the space needed for a buffer. Of course you have to know reasonably well what data to expect and how it is encoded for this number to have any meaning.

◆ next() [1/3]

bool protozero::pbf_reader::next ( )
inline

Set next field in the message as the current field. This is usually called in a while loop:

pbf_reader message(...);
while (message.next()) {
// handle field
}
Returns
true if there is a next field, false if not.
Precondition
There must be no current field.
Postcondition
If it returns true there is a current field now.

◆ next() [2/3]

bool protozero::pbf_reader::next ( pbf_tag_type  next_tag)
inline

Set next field with given tag in the message as the current field. Fields with other tags are skipped. This is usually called in a while loop for repeated fields:

pbf_reader message(...);
while (message.next(17)) {
// handle field
}

or you can call it just once to get the one field with this tag:

pbf_reader message(...);
if (message.next(17)) {
// handle field
}

Note that this will not check the wire type. The two-argument version of this function will also check the wire type.

Returns
true if there is a next field with this tag.
Precondition
There must be no current field.
Postcondition
If it returns true there is a current field now with the given tag.

◆ next() [3/3]

bool protozero::pbf_reader::next ( pbf_tag_type  next_tag,
pbf_wire_type  type 
)
inline

Set next field with given tag and wire type in the message as the current field. Fields with other tags are skipped. This is usually called in a while loop for repeated fields:

pbf_reader message(...);
while (message.next(17, pbf_wire_type::varint)) {
// handle field
}

or you can call it just once to get the one field with this tag:

pbf_reader message(...);
if (message.next(17, pbf_wire_type::varint)) {
// handle field
}

Note that this will also check the wire type. The one-argument version of this function will not check the wire type.

Returns
true if there is a next field with this tag.
Precondition
There must be no current field.
Postcondition
If it returns true there is a current field now with the given tag.

◆ operator bool()

protozero::pbf_reader::operator bool ( ) const
inlinenoexcept

In a boolean context the pbf_reader class evaluates to true if there are still fields available and to false if the last field has been read.

◆ skip()

void protozero::pbf_reader::skip ( )
inline

Consume the current field.

Precondition
There must be a current field (ie. next() must have returned true).
Postcondition
The current field was consumed and there is no current field now.

◆ swap()

void protozero::pbf_reader::swap ( pbf_reader other)
inlinenoexcept

Swap the contents of this object with the other.

Parameters
otherOther object to swap data with.

◆ tag()

pbf_tag_type protozero::pbf_reader::tag ( ) const
inlinenoexcept

The tag of the current field. The tag is the field number from the description in the .proto file.

Call next() before calling this function to set the current field.

Returns
tag of the current field.
Precondition
There must be a current field (ie. next() must have returned true).

◆ tag_and_type()

uint32_t protozero::pbf_reader::tag_and_type ( ) const
inlinenoexcept

Get the tag and wire type of the current field in one integer suitable for comparison with a switch statement.

Use it like this:

pbf_reader message(...);
while (message.next()) {
switch (message.tag_and_type()) {
case tag_and_type(17, pbf_wire_type::length_delimited):
....
break;
case tag_and_type(21, pbf_wire_type::varint):
....
break;
default:
message.skip();
}
}

◆ wire_type()

pbf_wire_type protozero::pbf_reader::wire_type ( ) const
inlinenoexcept

Get the wire type of the current field. The wire types are:

  • 0 - varint
  • 1 - 64 bit
  • 2 - length-delimited
  • 5 - 32 bit

All other types are illegal.

Call next() before calling this function to set the current field.

Returns
wire type of the current field.
Precondition
There must be a current field (ie. next() must have returned true).

The documentation for this class was generated from the following file: