1 #ifndef PROTOZERO_PBF_READER_HPP
2 #define PROTOZERO_PBF_READER_HPP
31 #if __BYTE_ORDER != __LITTLE_ENDIAN
36 #ifndef protozero_assert
37 # define protozero_assert(x) assert(x)
69 const char *m_data =
nullptr;
72 const char *m_end =
nullptr;
81 inline T get_fixed() {
83 skip_bytes(
sizeof(T));
84 #if __BYTE_ORDER == __LITTLE_ENDIAN
85 memcpy(&result, m_data -
sizeof(T),
sizeof(T));
87 byteswap<sizeof(T)>(m_data -
sizeof(T), reinterpret_cast<char*>(&result));
92 #if __BYTE_ORDER == __LITTLE_ENDIAN
94 inline std::pair<const T*, const T*> packed_fixed() {
96 auto len = get_len_and_skip();
98 return std::make_pair(reinterpret_cast<const T*>(m_data-len), reinterpret_cast<const T*>(m_data));
103 template <
typename T>
104 class const_fixed_iterator :
public std::iterator<std::forward_iterator_tag, T> {
111 const_fixed_iterator() noexcept :
116 const_fixed_iterator(
const char *data,
const char* end) noexcept :
121 const_fixed_iterator(
const const_fixed_iterator&) noexcept =
default;
122 const_fixed_iterator(const_fixed_iterator&&) noexcept =
default;
124 const_fixed_iterator&
operator=(
const const_fixed_iterator&) noexcept =
default;
125 const_fixed_iterator&
operator=(const_fixed_iterator&&) noexcept =
default;
127 ~const_fixed_iterator() noexcept =
default;
131 byteswap<sizeof(T)>(m_data,
reinterpret_cast<char*
>(&result));
135 const_fixed_iterator& operator++() {
140 const_fixed_iterator operator++(
int) {
141 const const_fixed_iterator tmp(*
this);
146 bool operator==(
const const_fixed_iterator& rhs)
const noexcept {
147 return m_data == rhs.m_data && m_end == rhs.m_end;
150 bool operator!=(
const const_fixed_iterator& rhs)
const noexcept {
151 return !(*
this == rhs);
156 template <
typename T>
157 inline std::pair<const_fixed_iterator<T>, const_fixed_iterator<T>> packed_fixed() {
159 auto len = get_len_and_skip();
161 return std::make_pair(const_fixed_iterator<T>(m_data-len, m_data),
162 const_fixed_iterator<T>(m_data, m_data));
166 template <
typename T>
inline T get_varint();
167 template <
typename T>
inline T get_svarint();
169 inline pbf_length_type get_length() {
return get_varint<pbf_length_type>(); }
197 inline pbf_reader(std::pair<const char *, size_t> data) noexcept;
209 inline pbf_reader(
const std::string& data) noexcept;
235 inline operator bool()
const noexcept;
247 return size_t(m_end - m_data);
361 return get_varint<int32_t>();
373 return get_varint<int32_t>();
385 return get_svarint<int32_t>();
397 return get_varint<uint32_t>();
409 return get_varint<int64_t>();
421 return get_svarint<int64_t>();
433 return get_varint<uint64_t>();
498 inline std::pair<const char*, pbf_length_type>
get_data();
533 template <
typename T>
534 class const_varint_iterator :
public std::iterator<std::forward_iterator_tag, T> {
543 const_varint_iterator() noexcept :
548 const_varint_iterator(
const char *data,
const char* end) noexcept :
553 const_varint_iterator(
const const_varint_iterator&) noexcept = default;
554 const_varint_iterator(const_varint_iterator&&) noexcept = default;
556 const_varint_iterator& operator=(const const_varint_iterator&) noexcept = default;
557 const_varint_iterator& operator=(const_varint_iterator&&) noexcept = default;
559 ~const_varint_iterator() noexcept = default;
562 const char* d = m_data;
566 const_varint_iterator& operator++() {
573 const_varint_iterator operator++(
int) {
574 const const_varint_iterator tmp(*
this);
579 bool operator==(
const const_varint_iterator& rhs)
const noexcept {
580 return m_data == rhs.m_data && m_end == rhs.m_end;
583 bool operator!=(
const const_varint_iterator& rhs)
const noexcept {
584 return !(*
this == rhs);
589 template <
typename T>
590 class const_svarint_iterator :
public const_varint_iterator<T> {
594 const_svarint_iterator() noexcept :
595 const_varint_iterator<T>() {
598 const_svarint_iterator(
const char *data,
const char* end) noexcept :
599 const_varint_iterator<T>(data, end) {
602 const_svarint_iterator(
const const_svarint_iterator&) =
default;
603 const_svarint_iterator(const_svarint_iterator&&) =
default;
605 const_svarint_iterator&
operator=(
const const_svarint_iterator&) =
default;
606 const_svarint_iterator&
operator=(const_svarint_iterator&&) =
default;
608 ~const_svarint_iterator() =
default;
611 const char* d = this->m_data;
615 const_svarint_iterator& operator++() {
622 const_svarint_iterator operator++(
int) {
623 const const_svarint_iterator tmp(*
this);
670 inline std::pair<pbf_reader::const_bool_iterator, pbf_reader::const_bool_iterator>
get_packed_bool();
681 inline std::pair<pbf_reader::const_enum_iterator, pbf_reader::const_enum_iterator>
get_packed_enum();
692 inline std::pair<pbf_reader::const_int32_iterator, pbf_reader::const_int32_iterator>
get_packed_int32();
703 inline std::pair<pbf_reader::const_sint32_iterator, pbf_reader::const_sint32_iterator>
get_packed_sint32();
714 inline std::pair<pbf_reader::const_uint32_iterator, pbf_reader::const_uint32_iterator>
get_packed_uint32();
725 inline std::pair<pbf_reader::const_int64_iterator, pbf_reader::const_int64_iterator>
get_packed_int64();
736 inline std::pair<pbf_reader::const_sint64_iterator, pbf_reader::const_sint64_iterator>
get_packed_sint64();
747 inline std::pair<pbf_reader::const_uint64_iterator, pbf_reader::const_uint64_iterator>
get_packed_uint64();
759 return packed_fixed<uint32_t>();
772 return packed_fixed<int32_t>();
785 return packed_fixed<uint64_t>();
798 return packed_fixed<int64_t>();
811 return packed_fixed<float>();
824 return packed_fixed<double>();
833 m_end(data + length),
834 m_wire_type(pbf_wire_type::unknown),
839 : m_data(data.first),
840 m_end(data.first + data.second),
841 m_wire_type(pbf_wire_type::unknown),
846 : m_data(data.data()),
847 m_end(data.data() + data.size()),
848 m_wire_type(pbf_wire_type::unknown),
852 pbf_reader::operator bool() const noexcept {
853 return m_data < m_end;
857 if (m_data == m_end) {
861 auto value = get_varint<uint32_t>();
866 protozero_assert(((m_tag > 0 && m_tag < 19000) || (m_tag > 19999 && m_tag <= ((1 << 29) - 1))) &&
"tag out of range");
869 switch (m_wire_type) {
870 case pbf_wire_type::varint:
871 case pbf_wire_type::fixed64:
872 case pbf_wire_type::length_delimited:
873 case pbf_wire_type::fixed32:
884 if (m_tag == requested_tag) {
902 return wire_type() == type;
906 if (m_data + len > m_end) {
921 case pbf_wire_type::varint:
924 case pbf_wire_type::fixed64:
927 case pbf_wire_type::length_delimited:
928 skip_bytes(get_length());
930 case pbf_wire_type::fixed32:
939 auto len = get_length();
944 template <
typename T>
945 T pbf_reader::get_varint() {
949 template <
typename T>
950 T pbf_reader::get_svarint() {
958 return get_fixed<uint32_t>();
964 return get_fixed<int32_t>();
970 return get_fixed<uint64_t>();
976 return get_fixed<int64_t>();
982 return get_fixed<float>();
988 return get_fixed<double>();
996 return m_data[-1] != 0;
1002 auto len = get_len_and_skip();
1003 return std::make_pair(m_data-len, len);
1008 return std::string(d.first, d.second);
1025 auto len = get_len_and_skip();
1032 auto len = get_len_and_skip();
1039 auto len = get_len_and_skip();
1046 auto len = get_len_and_skip();
1053 auto len = get_len_and_skip();
1060 auto len = get_len_and_skip();
1067 #endif // PROTOZERO_PBF_READER_HPP
int64_t get_sfixed64()
Definition: pbf_reader.hpp:973
uint32_t get_uint32()
Definition: pbf_reader.hpp:395
uint64_t get_fixed64()
Definition: pbf_reader.hpp:967
int32_t get_sfixed32()
Definition: pbf_reader.hpp:961
Definition: exception.hpp:48
uint64_t get_uint64()
Definition: pbf_reader.hpp:431
auto get_packed_double() -> decltype(packed_fixed< double >())
Definition: pbf_reader.hpp:823
int32_t get_int32()
Definition: pbf_reader.hpp:371
uint32_t pbf_length_type
Definition: pbf_types.hpp:45
std::pair< pbf_reader::const_sint32_iterator, pbf_reader::const_sint32_iterator > get_packed_sint32()
Definition: pbf_reader.hpp:1037
auto get_packed_float() -> decltype(packed_fixed< float >())
Definition: pbf_reader.hpp:810
auto get_packed_fixed32() -> decltype(packed_fixed< uint32_t >())
Definition: pbf_reader.hpp:758
std::pair< const char *, pbf_length_type > get_data()
Definition: pbf_reader.hpp:999
bool has_wire_type(pbf_wire_type type) const noexcept
Definition: pbf_reader.hpp:901
void skip()
Definition: pbf_reader.hpp:918
const_varint_iterator< uint32_t > const_uint32_iterator
Forward iterator for iterating over uint32 (varint) values.
Definition: pbf_reader.hpp:645
pbf_reader get_message()
Definition: pbf_reader.hpp:525
pbf_reader() noexcept=default
std::pair< pbf_reader::const_bool_iterator, pbf_reader::const_bool_iterator > get_packed_bool()
Definition: pbf_reader.hpp:1015
auto get_packed_sfixed64() -> decltype(packed_fixed< int64_t >())
Definition: pbf_reader.hpp:797
auto get_packed_sfixed32() -> decltype(packed_fixed< int32_t >())
Definition: pbf_reader.hpp:771
pbf_wire_type
Definition: pbf_types.hpp:33
Contains the declaration of low-level types used in the pbf format.
pbf_wire_type wire_type() const noexcept
Definition: pbf_reader.hpp:897
uint32_t pbf_tag_type
Definition: pbf_types.hpp:26
std::pair< pbf_reader::const_int32_iterator, pbf_reader::const_int32_iterator > get_packed_int32()
Definition: pbf_reader.hpp:1023
#define protozero_assert(x)
Wrapper for assert() used for testing.
Definition: pbf_reader.hpp:37
int64_t get_sint64()
Definition: pbf_reader.hpp:419
auto get_packed_fixed64() -> decltype(packed_fixed< uint64_t >())
Definition: pbf_reader.hpp:784
Contains functions to swap bytes in values (for different endianness).
int32_t get_sint32()
Definition: pbf_reader.hpp:383
std::string get_bytes()
Definition: pbf_reader.hpp:1006
double get_double()
Definition: pbf_reader.hpp:985
pbf_reader & operator=(const pbf_reader &other) noexcept=default
pbf_reader messages can be copied trivially.
const_svarint_iterator< int64_t > const_sint64_iterator
Forward iterator for iterating over sint64 (varint) values.
Definition: pbf_reader.hpp:651
bool get_bool()
Definition: pbf_reader.hpp:991
std::string get_string()
Definition: pbf_reader.hpp:1011
const_varint_iterator< int32_t > const_enum_iterator
Forward iterator for iterating over enum (int32 varint) values.
Definition: pbf_reader.hpp:636
Contains the exceptions used in the protozero library.
uint32_t get_fixed32()
Definition: pbf_reader.hpp:955
pbf_tag_type tag() const noexcept
Definition: pbf_reader.hpp:893
const_varint_iterator< int32_t > const_int32_iterator
Forward iterator for iterating over int32 (varint) values.
Definition: pbf_reader.hpp:639
std::pair< pbf_reader::const_int64_iterator, pbf_reader::const_int64_iterator > get_packed_int64()
Definition: pbf_reader.hpp:1044
const_varint_iterator< int32_t > const_bool_iterator
Forward iterator for iterating over bool (int32 varint) values.
Definition: pbf_reader.hpp:633
int32_t get_enum()
Definition: pbf_reader.hpp:359
Definition: pbf_reader.hpp:66
const_varint_iterator< uint64_t > const_uint64_iterator
Forward iterator for iterating over uint64 (varint) values.
Definition: pbf_reader.hpp:654
float get_float()
Definition: pbf_reader.hpp:979
Definition: exception.hpp:61
Contains low-level varint and zigzag encoding and decoding functions.
const_varint_iterator< int64_t > const_int64_iterator
Forward iterator for iterating over int64 (varint) values.
Definition: pbf_reader.hpp:648
std::pair< pbf_reader::const_uint64_iterator, pbf_reader::const_uint64_iterator > get_packed_uint64()
Definition: pbf_reader.hpp:1051
uint64_t decode_varint(const char **data, const char *end)
Definition: varint.hpp:48
std::pair< pbf_reader::const_enum_iterator, pbf_reader::const_enum_iterator > get_packed_enum()
Definition: pbf_reader.hpp:1019
const_svarint_iterator< int32_t > const_sint32_iterator
Forward iterator for iterating over sint32 (varint) values.
Definition: pbf_reader.hpp:642
bool next()
Definition: pbf_reader.hpp:856
size_t length() const noexcept
Definition: pbf_reader.hpp:246
int64_t get_int64()
Definition: pbf_reader.hpp:407
int64_t decode_zigzag64(uint64_t value) noexcept
Definition: varint.hpp:126
std::pair< pbf_reader::const_sint64_iterator, pbf_reader::const_sint64_iterator > get_packed_sint64()
Definition: pbf_reader.hpp:1058
All parts of the protozero header-only library are in this namespace.
Definition: byteswap.hpp:22
std::pair< pbf_reader::const_uint32_iterator, pbf_reader::const_uint32_iterator > get_packed_uint32()
Definition: pbf_reader.hpp:1030