protozero
1.6.8
Minimalistic protocol buffer decoder and encoder in C++.
|
Go to the documentation of this file. 1 #ifndef PROTOZERO_PBF_READER_HPP
2 #define PROTOZERO_PBF_READER_HPP
26 #if PROTOZERO_BYTE_ORDER != PROTOZERO_LITTLE_ENDIAN
65 const char* m_data =
nullptr;
68 const char* m_end =
nullptr;
79 const char*
data = m_data;
80 skip_bytes(
sizeof(T));
81 std::memcpy(&result,
data,
sizeof(T));
82 #if PROTOZERO_BYTE_ORDER != PROTOZERO_LITTLE_ENDIAN
89 iterator_range<const_fixed_iterator<T>> packed_fixed() {
90 protozero_assert(
tag() != 0 &&
"call next() before accessing field value");
91 const auto len = get_len_and_skip();
92 if (len %
sizeof(T) != 0) {
93 throw invalid_length_exception{};
95 return {const_fixed_iterator<T>(m_data - len),
96 const_fixed_iterator<T>(m_data)};
101 const auto val = static_cast<T>(
decode_varint(&m_data, m_end));
105 template <
typename T>
112 return get_varint<pbf_length_type>();
116 if (m_end - m_data < static_cast<ptrdiff_t>(len)) {
117 throw end_of_buffer_exception{};
129 const auto len = get_length();
134 template <
typename T>
135 iterator_range<T> get_packed() {
136 protozero_assert(
tag() != 0 &&
"call next() before accessing field value");
137 const auto len = get_len_and_skip();
138 return {T{m_data - len, m_data},
154 explicit pbf_reader(
const data_view& view) noexcept
155 : m_data{view.data()},
156 m_end{view.data() + view.size()} {
174 #ifndef PROTOZERO_STRICT_API
186 explicit pbf_reader(
const std::pair<const char*, std::size_t>&
data) noexcept
187 : m_data{
data.first},
234 swap(m_data, other.m_data);
235 swap(m_end, other.m_end);
236 swap(m_wire_type, other.m_wire_type);
237 swap(m_tag, other.m_tag);
245 operator bool() const noexcept {
246 return m_data != m_end;
252 data_view
data() const noexcept {
253 return {m_data, static_cast<std::size_t>(m_end - m_data)};
265 std::size_t
length() const noexcept {
266 return std::size_t(m_end - m_data);
285 if (m_data == m_end) {
289 const auto value = get_varint<uint32_t>();
294 if (m_tag == 0 || (m_tag >= 19000 && m_tag <= 19999)) {
295 throw invalid_tag_exception{};
299 switch (m_wire_type) {
300 case pbf_wire_type::varint:
301 case pbf_wire_type::fixed64:
302 case pbf_wire_type::length_delimited:
303 case pbf_wire_type::fixed32:
306 throw unknown_pbf_wire_type_exception{};
342 if (m_tag == next_tag) {
380 if (m_tag == next_tag && m_wire_type == type) {
463 protozero_assert(
tag() != 0 &&
"call next() before calling skip()");
465 case pbf_wire_type::varint:
468 case pbf_wire_type::fixed64:
471 case pbf_wire_type::length_delimited:
472 skip_bytes(get_length());
474 case pbf_wire_type::fixed32:
495 protozero_assert(
tag() != 0 &&
"call next() before accessing field value");
496 protozero_assert(
has_wire_type(pbf_wire_type::varint) &&
"not a varint");
497 const auto data = m_data;
510 protozero_assert(
has_wire_type(pbf_wire_type::varint) &&
"not a varint");
511 return get_varint<int32_t>();
522 protozero_assert(
has_wire_type(pbf_wire_type::varint) &&
"not a varint");
523 return get_varint<int32_t>();
534 protozero_assert(
has_wire_type(pbf_wire_type::varint) &&
"not a varint");
535 return get_svarint<int32_t>();
546 protozero_assert(
has_wire_type(pbf_wire_type::varint) &&
"not a varint");
547 return get_varint<uint32_t>();
558 protozero_assert(
has_wire_type(pbf_wire_type::varint) &&
"not a varint");
559 return get_varint<int64_t>();
570 protozero_assert(
has_wire_type(pbf_wire_type::varint) &&
"not a varint");
571 return get_svarint<int64_t>();
582 protozero_assert(
has_wire_type(pbf_wire_type::varint) &&
"not a varint");
583 return get_varint<uint64_t>();
594 protozero_assert(
tag() != 0 &&
"call next() before accessing field value");
595 protozero_assert(
has_wire_type(pbf_wire_type::fixed32) &&
"not a 32-bit fixed");
596 return get_fixed<uint32_t>();
607 protozero_assert(
tag() != 0 &&
"call next() before accessing field value");
608 protozero_assert(
has_wire_type(pbf_wire_type::fixed32) &&
"not a 32-bit fixed");
609 return get_fixed<int32_t>();
620 protozero_assert(
tag() != 0 &&
"call next() before accessing field value");
621 protozero_assert(
has_wire_type(pbf_wire_type::fixed64) &&
"not a 64-bit fixed");
622 return get_fixed<uint64_t>();
633 protozero_assert(
tag() != 0 &&
"call next() before accessing field value");
634 protozero_assert(
has_wire_type(pbf_wire_type::fixed64) &&
"not a 64-bit fixed");
635 return get_fixed<int64_t>();
646 protozero_assert(
tag() != 0 &&
"call next() before accessing field value");
647 protozero_assert(
has_wire_type(pbf_wire_type::fixed32) &&
"not a 32-bit fixed");
648 return get_fixed<float>();
659 protozero_assert(
tag() != 0 &&
"call next() before accessing field value");
660 protozero_assert(
has_wire_type(pbf_wire_type::fixed64) &&
"not a 64-bit fixed");
661 return get_fixed<double>();
674 protozero_assert(
tag() != 0 &&
"call next() before accessing field value");
675 protozero_assert(
has_wire_type(pbf_wire_type::length_delimited) &&
"not of type string, bytes or message");
676 const auto len = get_len_and_skip();
677 return {m_data - len, len};
680 #ifndef PROTOZERO_STRICT_API
689 std::pair<const char*, pbf_length_type>
get_data() {
690 protozero_assert(
tag() != 0 &&
"call next() before accessing field value");
691 protozero_assert(
has_wire_type(pbf_wire_type::length_delimited) &&
"not of type string, bytes or message");
692 const auto len = get_len_and_skip();
693 return {m_data - len, len};
789 return get_packed<pbf_reader::const_bool_iterator>();
802 return get_packed<pbf_reader::const_enum_iterator>();
815 return get_packed<pbf_reader::const_int32_iterator>();
828 return get_packed<pbf_reader::const_sint32_iterator>();
841 return get_packed<pbf_reader::const_uint32_iterator>();
854 return get_packed<pbf_reader::const_int64_iterator>();
867 return get_packed<pbf_reader::const_sint64_iterator>();
880 return get_packed<pbf_reader::const_uint64_iterator>();
893 return packed_fixed<uint32_t>();
906 return packed_fixed<int32_t>();
919 return packed_fixed<uint64_t>();
932 return packed_fixed<int64_t>();
945 return packed_fixed<float>();
958 return packed_fixed<double>();
971 inline void swap(pbf_reader& lhs, pbf_reader& rhs) noexcept {
977 #endif // PROTOZERO_PBF_READER_HPP
pbf_reader get_message()
Definition: pbf_reader.hpp:725
pbf_wire_type
Definition: types.hpp:39
iterator_range< pbf_reader::const_sfixed64_iterator > get_packed_sfixed64()
Definition: pbf_reader.hpp:930
std::string get_bytes()
Definition: pbf_reader.hpp:703
iterator_range< pbf_reader::const_float_iterator > get_packed_float()
Definition: pbf_reader.hpp:943
int64_t get_int64()
Definition: pbf_reader.hpp:556
iterator_range< pbf_reader::const_bool_iterator > get_packed_bool()
Definition: pbf_reader.hpp:787
uint32_t get_uint32()
Definition: pbf_reader.hpp:544
const_varint_iterator< uint64_t > const_uint64_iterator
Forward iterator for iterating over uint64 (varint) values.
Definition: pbf_reader.hpp:753
Contains macro checks for different configurations.
All parts of the protozero header-only library are in this namespace.
Definition: byteswap.hpp:22
Contains functions to swap bytes in values (for different endianness).
Contains the declaration of low-level types used in the pbf format.
iterator_range< pbf_reader::const_sint32_iterator > get_packed_sint32()
Definition: pbf_reader.hpp:826
uint32_t tag_and_type() const noexcept
Definition: pbf_reader.hpp:441
const_fixed_iterator< double > const_double_iterator
Forward iterator for iterating over double values.
Definition: pbf_reader.hpp:771
constexpr std::size_t size() const noexcept
Return length of data in bytes.
Definition: data_view.hpp:98
const_svarint_iterator< int64_t > const_sint64_iterator
Forward iterator for iterating over sint64 (varint) values.
Definition: pbf_reader.hpp:750
void swap(pbf_reader &lhs, pbf_reader &rhs) noexcept
Definition: pbf_reader.hpp:970
const_fixed_iterator< int64_t > const_sfixed64_iterator
Forward iterator for iterating over sfixed64 values.
Definition: pbf_reader.hpp:765
int32_t get_sint32()
Definition: pbf_reader.hpp:532
constexpr int64_t decode_zigzag64(uint64_t value) noexcept
Definition: varint.hpp:198
const_fixed_iterator< float > const_float_iterator
Forward iterator for iterating over float values.
Definition: pbf_reader.hpp:768
iterator_range< pbf_reader::const_int64_iterator > get_packed_int64()
Definition: pbf_reader.hpp:852
float get_float()
Definition: pbf_reader.hpp:644
int32_t get_int32()
Definition: pbf_reader.hpp:520
uint64_t get_fixed64()
Definition: pbf_reader.hpp:618
const_fixed_iterator< uint64_t > const_fixed64_iterator
Forward iterator for iterating over fixed64 values.
Definition: pbf_reader.hpp:762
Contains the iterators for access to packed repeated fields.
iterator_range< pbf_reader::const_enum_iterator > get_packed_enum()
Definition: pbf_reader.hpp:800
std::size_t length() const noexcept
Definition: pbf_reader.hpp:264
const_varint_iterator< int32_t > const_enum_iterator
Forward iterator for iterating over enum (int32 varint) values.
Definition: pbf_reader.hpp:735
int64_t get_sfixed64()
Definition: pbf_reader.hpp:631
bool next()
Definition: pbf_reader.hpp:283
pbf_tag_type tag() const noexcept
Definition: pbf_reader.hpp:396
int32_t get_enum()
Definition: pbf_reader.hpp:508
const_svarint_iterator< int32_t > const_sint32_iterator
Forward iterator for iterating over sint32 (varint) values.
Definition: pbf_reader.hpp:741
pbf_wire_type wire_type() const noexcept
Definition: pbf_reader.hpp:415
void swap(pbf_reader &other) noexcept
Definition: pbf_reader.hpp:231
uint32_t pbf_tag_type
Definition: types.hpp:32
bool has_wire_type(pbf_wire_type type) const noexcept
Definition: pbf_reader.hpp:451
const_varint_iterator< int64_t > const_int64_iterator
Forward iterator for iterating over int64 (varint) values.
Definition: pbf_reader.hpp:747
const_varint_iterator< int32_t > const_int32_iterator
Forward iterator for iterating over int32 (varint) values.
Definition: pbf_reader.hpp:738
data_view get_view()
Definition: pbf_reader.hpp:672
void skip()
Definition: pbf_reader.hpp:461
int64_t get_sint64()
Definition: pbf_reader.hpp:568
const_fixed_iterator< uint32_t > const_fixed32_iterator
Forward iterator for iterating over fixed32 values.
Definition: pbf_reader.hpp:756
double get_double()
Definition: pbf_reader.hpp:657
iterator_range< pbf_reader::const_int32_iterator > get_packed_int32()
Definition: pbf_reader.hpp:813
void swap(data_view &lhs, data_view &rhs) noexcept
Definition: data_view.hpp:164
constexpr uint32_t tag_and_type(T tag, pbf_wire_type wire_type) noexcept
Definition: types.hpp:54
pbf_reader() noexcept=default
void byteswap_inplace(uint32_t *ptr) noexcept
byteswap the data pointed to by ptr in-place.
Definition: byteswap.hpp:54
iterator_range< pbf_reader::const_uint64_iterator > get_packed_uint64()
Definition: pbf_reader.hpp:878
Contains the exceptions used in the protozero library.
const_fixed_iterator< int32_t > const_sfixed32_iterator
Forward iterator for iterating over sfixed32 values.
Definition: pbf_reader.hpp:759
uint64_t decode_varint(const char **data, const char *end)
Definition: varint.hpp:88
iterator_range< pbf_reader::const_fixed64_iterator > get_packed_fixed64()
Definition: pbf_reader.hpp:917
std::pair< const char *, pbf_length_type > get_data()
Definition: pbf_reader.hpp:688
uint64_t get_uint64()
Definition: pbf_reader.hpp:580
const_varint_iterator< int32_t > const_bool_iterator
Forward iterator for iterating over bool (int32 varint) values.
Definition: pbf_reader.hpp:732
iterator_range< pbf_reader::const_sint64_iterator > get_packed_sint64()
Definition: pbf_reader.hpp:865
const_varint_iterator< uint32_t > const_uint32_iterator
Forward iterator for iterating over uint32 (varint) values.
Definition: pbf_reader.hpp:744
iterator_range< pbf_reader::const_uint32_iterator > get_packed_uint32()
Definition: pbf_reader.hpp:839
iterator_range< pbf_reader::const_fixed32_iterator > get_packed_fixed32()
Definition: pbf_reader.hpp:891
uint32_t pbf_length_type
Definition: types.hpp:61
iterator_range< pbf_reader::const_sfixed32_iterator > get_packed_sfixed32()
Definition: pbf_reader.hpp:904
iterator_range< pbf_reader::const_double_iterator > get_packed_double()
Definition: pbf_reader.hpp:956
void skip_varint(const char **data, const char *end)
Definition: varint.hpp:111
Contains low-level varint and zigzag encoding and decoding functions.
int32_t get_sfixed32()
Definition: pbf_reader.hpp:605
bool get_bool()
Definition: pbf_reader.hpp:493
uint32_t get_fixed32()
Definition: pbf_reader.hpp:592
data_view data() const noexcept
Definition: pbf_reader.hpp:251
Contains the implementation of the data_view class.
std::string get_string()
Definition: pbf_reader.hpp:714
constexpr const char * data() const noexcept
Return pointer to data.
Definition: data_view.hpp:93