1 #ifndef PROTOZERO_PBF_READER_HPP
2 #define PROTOZERO_PBF_READER_HPP
30 #if PROTOZERO_BYTE_ORDER != PROTOZERO_LITTLE_ENDIAN
63 const char* m_data =
nullptr;
66 const char* m_end =
nullptr;
77 skip_bytes(
sizeof(T));
78 std::memcpy(&result, m_data -
sizeof(T),
sizeof(T));
79 #if PROTOZERO_BYTE_ORDER != PROTOZERO_LITTLE_ENDIAN
80 detail::byteswap_inplace(&result);
87 protozero_assert(
tag() != 0 &&
"call next() before accessing field value");
88 const auto len = get_len_and_skip();
89 protozero_assert(len %
sizeof(T) == 0);
106 return get_varint<pbf_length_type>();
110 if (m_data + len > m_end) {
123 const auto len = get_length();
128 template <
typename T>
130 protozero_assert(
tag() != 0 &&
"call next() before accessing field value");
131 const auto len = get_len_and_skip();
149 : m_data(view.data()),
150 m_end(view.data() + view.size()),
151 m_wire_type(pbf_wire_type::unknown),
168 m_wire_type(pbf_wire_type::unknown),
182 pbf_reader(
const std::pair<const char*, std::size_t>& data) noexcept
183 : m_data(data.first),
184 m_end(data.first + data.second),
185 m_wire_type(pbf_wire_type::unknown),
200 : m_data(data.data()),
201 m_end(data.data() + data.size()),
202 m_wire_type(pbf_wire_type::unknown),
233 swap(m_data, other.m_data);
234 swap(m_end, other.m_end);
235 swap(m_wire_type, other.m_wire_type);
236 swap(m_tag, other.m_tag);
244 operator bool() const noexcept {
245 return m_data < m_end;
258 return std::size_t(m_end - m_data);
277 if (m_data == m_end) {
281 const auto value = get_varint<uint32_t>();
286 protozero_assert(((m_tag > 0 && m_tag < 19000) ||
287 (m_tag > 19999 && m_tag <= ((1 << 29) - 1))) &&
"tag out of range");
290 switch (m_wire_type) {
291 case pbf_wire_type::varint:
292 case pbf_wire_type::fixed64:
293 case pbf_wire_type::length_delimited:
294 case pbf_wire_type::fixed32:
330 if (m_tag == next_tag) {
388 protozero_assert(
tag() != 0 &&
"call next() before calling skip()");
390 case pbf_wire_type::varint:
393 case pbf_wire_type::fixed64:
396 case pbf_wire_type::length_delimited:
397 skip_bytes(get_length());
399 case pbf_wire_type::fixed32:
403 protozero_assert(
false &&
"can not be here because next() should have thrown already");
420 protozero_assert(
tag() != 0 &&
"call next() before accessing field value");
421 protozero_assert(
has_wire_type(pbf_wire_type::varint) &&
"not a varint");
422 protozero_assert((*m_data & 0x80) == 0 &&
"not a 1 byte varint");
424 return m_data[-1] != 0;
435 protozero_assert(
has_wire_type(pbf_wire_type::varint) &&
"not a varint");
436 return get_varint<int32_t>();
447 protozero_assert(
has_wire_type(pbf_wire_type::varint) &&
"not a varint");
448 return get_varint<int32_t>();
459 protozero_assert(
has_wire_type(pbf_wire_type::varint) &&
"not a varint");
460 return get_svarint<int32_t>();
471 protozero_assert(
has_wire_type(pbf_wire_type::varint) &&
"not a varint");
472 return get_varint<uint32_t>();
483 protozero_assert(
has_wire_type(pbf_wire_type::varint) &&
"not a varint");
484 return get_varint<int64_t>();
495 protozero_assert(
has_wire_type(pbf_wire_type::varint) &&
"not a varint");
496 return get_svarint<int64_t>();
507 protozero_assert(
has_wire_type(pbf_wire_type::varint) &&
"not a varint");
508 return get_varint<uint64_t>();
519 protozero_assert(
tag() != 0 &&
"call next() before accessing field value");
520 protozero_assert(
has_wire_type(pbf_wire_type::fixed32) &&
"not a 32-bit fixed");
521 return get_fixed<uint32_t>();
532 protozero_assert(
tag() != 0 &&
"call next() before accessing field value");
533 protozero_assert(
has_wire_type(pbf_wire_type::fixed32) &&
"not a 32-bit fixed");
534 return get_fixed<int32_t>();
545 protozero_assert(
tag() != 0 &&
"call next() before accessing field value");
546 protozero_assert(
has_wire_type(pbf_wire_type::fixed64) &&
"not a 64-bit fixed");
547 return get_fixed<uint64_t>();
558 protozero_assert(
tag() != 0 &&
"call next() before accessing field value");
559 protozero_assert(
has_wire_type(pbf_wire_type::fixed64) &&
"not a 64-bit fixed");
560 return get_fixed<int64_t>();
571 protozero_assert(
tag() != 0 &&
"call next() before accessing field value");
572 protozero_assert(
has_wire_type(pbf_wire_type::fixed32) &&
"not a 32-bit fixed");
573 return get_fixed<float>();
584 protozero_assert(
tag() != 0 &&
"call next() before accessing field value");
585 protozero_assert(
has_wire_type(pbf_wire_type::fixed64) &&
"not a 64-bit fixed");
586 return get_fixed<double>();
599 protozero_assert(
tag() != 0 &&
"call next() before accessing field value");
600 protozero_assert(
has_wire_type(pbf_wire_type::length_delimited) &&
"not of type string, bytes or message");
601 const auto len = get_len_and_skip();
605 #ifndef PROTOZERO_STRICT_API
614 std::pair<const char*, pbf_length_type>
get_data() {
615 protozero_assert(
tag() != 0 &&
"call next() before accessing field value");
616 protozero_assert(
has_wire_type(pbf_wire_type::length_delimited) &&
"not of type string, bytes or message");
617 const auto len = get_len_and_skip();
618 return std::make_pair(m_data-len, len);
696 return get_packed<pbf_reader::const_bool_iterator>();
709 return get_packed<pbf_reader::const_enum_iterator>();
722 return get_packed<pbf_reader::const_int32_iterator>();
735 return get_packed<pbf_reader::const_sint32_iterator>();
748 return get_packed<pbf_reader::const_uint32_iterator>();
761 return get_packed<pbf_reader::const_int64_iterator>();
774 return get_packed<pbf_reader::const_sint64_iterator>();
787 return get_packed<pbf_reader::const_uint64_iterator>();
800 return packed_fixed<uint32_t>();
813 return packed_fixed<int32_t>();
826 return packed_fixed<uint64_t>();
839 return packed_fixed<int64_t>();
852 return packed_fixed<float>();
865 return packed_fixed<double>();
884 #endif // PROTOZERO_PBF_READER_HPP
pbf_reader(const data_view &view) noexcept
Definition: pbf_reader.hpp:148
int64_t get_sfixed64()
Definition: pbf_reader.hpp:557
uint32_t get_uint32()
Definition: pbf_reader.hpp:470
uint64_t get_fixed64()
Definition: pbf_reader.hpp:544
int32_t get_sfixed32()
Definition: pbf_reader.hpp:531
Definition: exception.hpp:48
uint64_t get_uint64()
Definition: pbf_reader.hpp:506
auto get_packed_double() -> decltype(packed_fixed< double >())
Definition: pbf_reader.hpp:864
Definition: iterators.hpp:146
int32_t get_int32()
Definition: pbf_reader.hpp:446
pbf_reader(const std::string &data) noexcept
Definition: pbf_reader.hpp:199
iterator_range< pbf_reader::const_sint64_iterator > get_packed_sint64()
Definition: pbf_reader.hpp:773
auto get_packed_float() -> decltype(packed_fixed< float >())
Definition: pbf_reader.hpp:851
auto get_packed_fixed32() -> decltype(packed_fixed< uint32_t >())
Definition: pbf_reader.hpp:799
void swap(pbf_reader &lhs, pbf_reader &rhs) noexcept
Definition: pbf_reader.hpp:878
Contains macro checks for different configurations.
Contains the declaration of low-level types used in the pbf format.
bool has_wire_type(pbf_wire_type type) const noexcept
Definition: pbf_reader.hpp:377
std::size_t length() const noexcept
Definition: pbf_reader.hpp:257
void skip()
Definition: pbf_reader.hpp:387
iterator_range< pbf_reader::const_int32_iterator > get_packed_int32()
Definition: pbf_reader.hpp:721
pbf_reader get_message()
Definition: pbf_reader.hpp:651
void swap(iterator_range< T > &lhs, iterator_range< T > &rhs) noexcept
Definition: iterators.hpp:137
pbf_reader() noexcept=default
iterator_range< pbf_reader::const_int64_iterator > get_packed_int64()
Definition: pbf_reader.hpp:760
void skip_varint(const char **data, const char *end)
Definition: varint.hpp:112
auto get_packed_sfixed64() -> decltype(packed_fixed< int64_t >())
Definition: pbf_reader.hpp:838
Contains the iterators for access to packed repeated fields.
auto get_packed_sfixed32() -> decltype(packed_fixed< int32_t >())
Definition: pbf_reader.hpp:812
pbf_wire_type
Definition: types.hpp:39
iterator_range< pbf_reader::const_uint64_iterator > get_packed_uint64()
Definition: pbf_reader.hpp:786
iterator_range< pbf_reader::const_sint32_iterator > get_packed_sint32()
Definition: pbf_reader.hpp:734
pbf_wire_type wire_type() const noexcept
Definition: pbf_reader.hpp:367
void swap(pbf_reader &other) noexcept
Definition: pbf_reader.hpp:231
int64_t get_sint64()
Definition: pbf_reader.hpp:494
bool next(pbf_tag_type next_tag)
Definition: pbf_reader.hpp:328
std::pair< const char *, pbf_length_type > get_data()
Definition: pbf_reader.hpp:614
auto get_packed_fixed64() -> decltype(packed_fixed< uint64_t >())
Definition: pbf_reader.hpp:825
iterator_range< pbf_reader::const_bool_iterator > get_packed_bool()
Definition: pbf_reader.hpp:695
Contains functions to swap bytes in values (for different endianness).
int32_t get_sint32()
Definition: pbf_reader.hpp:458
std::string get_bytes()
Definition: pbf_reader.hpp:629
double get_double()
Definition: pbf_reader.hpp:583
bool get_bool()
Definition: pbf_reader.hpp:419
std::string get_string()
Definition: pbf_reader.hpp:640
uint32_t pbf_length_type
Definition: types.hpp:51
Contains the exceptions used in the protozero library.
pbf_reader(const std::pair< const char *, std::size_t > &data) noexcept
Definition: pbf_reader.hpp:182
data_view get_view()
Definition: pbf_reader.hpp:598
pbf_reader(const char *data, std::size_t size) noexcept
Definition: pbf_reader.hpp:165
uint32_t pbf_tag_type
Definition: types.hpp:32
uint32_t get_fixed32()
Definition: pbf_reader.hpp:518
iterator_range< pbf_reader::const_enum_iterator > get_packed_enum()
Definition: pbf_reader.hpp:708
pbf_tag_type tag() const noexcept
Definition: pbf_reader.hpp:348
Definition: iterators.hpp:282
Definition: iterators.hpp:215
int32_t get_enum()
Definition: pbf_reader.hpp:434
Definition: pbf_reader.hpp:60
Definition: iterators.hpp:38
float get_float()
Definition: pbf_reader.hpp:570
Definition: exception.hpp:61
Contains low-level varint and zigzag encoding and decoding functions.
uint64_t decode_varint(const char **data, const char *end)
Definition: varint.hpp:89
bool next()
Definition: pbf_reader.hpp:276
int64_t get_int64()
Definition: pbf_reader.hpp:482
iterator_range< pbf_reader::const_uint32_iterator > get_packed_uint32()
Definition: pbf_reader.hpp:747
int64_t decode_zigzag64(uint64_t value) noexcept
Definition: varint.hpp:181
All parts of the protozero header-only library are in this namespace.
Definition: byteswap.hpp:24