protozero
Minimalistic protocol buffer decoder and encoder in C++.
pbf_reader.hpp
Go to the documentation of this file.
1 #ifndef PROTOZERO_PBF_READER_HPP
2 #define PROTOZERO_PBF_READER_HPP
3 
4 /*****************************************************************************
5 
6 protozero - Minimalistic protocol buffer decoder and encoder in C++.
7 
8 This file is from https://github.com/mapbox/protozero where you can find more
9 documentation.
10 
11 *****************************************************************************/
12 
19 #include <cstddef>
20 #include <cstdint>
21 #include <cstring>
22 #include <iterator>
23 #include <string>
24 #include <utility>
25 
26 #include <protozero/config.hpp>
27 #include <protozero/exception.hpp>
28 #include <protozero/pbf_types.hpp>
29 #include <protozero/varint.hpp>
30 
31 #if PROTOZERO_BYTE_ORDER != PROTOZERO_LITTLE_ENDIAN
32 # include <protozero/byteswap.hpp>
33 #endif
34 
35 namespace protozero {
36 
61 class pbf_reader {
62 
63  // A pointer to the next unread data.
64  const char *m_data = nullptr;
65 
66  // A pointer to one past the end of data.
67  const char *m_end = nullptr;
68 
69  // The wire type of the current field.
70  pbf_wire_type m_wire_type = pbf_wire_type::unknown;
71 
72  // The tag of the current field.
73  pbf_tag_type m_tag = 0;
74 
75  // Copy N bytes from src to dest on little endian machines, on big endian
76  // swap the bytes in the process.
77  template <int N>
78  static void copy_or_byteswap(const char* src, void* dest) noexcept {
79 #if PROTOZERO_BYTE_ORDER == PROTOZERO_LITTLE_ENDIAN
80  memcpy(dest, src, N);
81 #else
82  byteswap<N>(src, reinterpret_cast<char*>(dest));
83 #endif
84  }
85 
86  template <typename T>
87  inline T get_fixed() {
88  T result;
89  skip_bytes(sizeof(T));
90  copy_or_byteswap<sizeof(T)>(m_data - sizeof(T), &result);
91  return result;
92  }
93 
94 #ifdef PROTOZERO_USE_BARE_POINTER_FOR_PACKED_FIXED
95 
96  template <typename T>
97  inline std::pair<const T*, const T*> packed_fixed() {
98  protozero_assert(tag() != 0 && "call next() before accessing field value");
99  auto len = get_len_and_skip();
100  protozero_assert(len % sizeof(T) == 0);
101  return std::make_pair(reinterpret_cast<const T*>(m_data-len), reinterpret_cast<const T*>(m_data));
102  }
103 
104 #else
105 
106  template <typename T>
107  class const_fixed_iterator : public std::iterator<std::forward_iterator_tag, T> {
108 
109  const char* m_data;
110  const char* m_end;
111 
112  public:
113 
114  const_fixed_iterator() noexcept :
115  m_data(nullptr),
116  m_end(nullptr) {
117  }
118 
119  const_fixed_iterator(const char *data, const char* end) noexcept :
120  m_data(data),
121  m_end(end) {
122  }
123 
124  const_fixed_iterator(const const_fixed_iterator&) noexcept = default;
125  const_fixed_iterator(const_fixed_iterator&&) noexcept = default;
126 
127  const_fixed_iterator& operator=(const const_fixed_iterator&) noexcept = default;
128  const_fixed_iterator& operator=(const_fixed_iterator&&) noexcept = default;
129 
130  ~const_fixed_iterator() noexcept = default;
131 
132  T operator*() {
133  T result;
134  copy_or_byteswap<sizeof(T)>(m_data , &result);
135  return result;
136  }
137 
138  const_fixed_iterator& operator++() {
139  m_data += sizeof(T);
140  return *this;
141  }
142 
143  const_fixed_iterator operator++(int) {
144  const const_fixed_iterator tmp(*this);
145  ++(*this);
146  return tmp;
147  }
148 
149  bool operator==(const const_fixed_iterator& rhs) const noexcept {
150  return m_data == rhs.m_data && m_end == rhs.m_end;
151  }
152 
153  bool operator!=(const const_fixed_iterator& rhs) const noexcept {
154  return !(*this == rhs);
155  }
156 
157  }; // class const_fixed_iterator
158 
159  template <typename T>
160  inline std::pair<const_fixed_iterator<T>, const_fixed_iterator<T>> packed_fixed() {
161  protozero_assert(tag() != 0 && "call next() before accessing field value");
162  auto len = get_len_and_skip();
163  protozero_assert(len % sizeof(T) == 0);
164  return std::make_pair(const_fixed_iterator<T>(m_data-len, m_data),
165  const_fixed_iterator<T>(m_data, m_data));
166  }
167 
168 #endif
169 
170  template <typename T> inline T get_varint();
171  template <typename T> inline T get_svarint();
172 
173  inline pbf_length_type get_length() { return get_varint<pbf_length_type>(); }
174 
175  inline void skip_bytes(pbf_length_type len);
176 
177  inline pbf_length_type get_len_and_skip();
178 
179 public:
180 
190  inline pbf_reader(const char *data, size_t length) noexcept;
191 
201  inline pbf_reader(std::pair<const char *, size_t> data) noexcept;
202 
213  inline pbf_reader(const std::string& data) noexcept;
214 
219  inline pbf_reader() noexcept = default;
220 
222  inline pbf_reader(const pbf_reader&) noexcept = default;
223 
225  inline pbf_reader(pbf_reader&&) noexcept = default;
226 
228  inline pbf_reader& operator=(const pbf_reader& other) noexcept = default;
229 
231  inline pbf_reader& operator=(pbf_reader&& other) noexcept = default;
232 
233  inline ~pbf_reader() = default;
234 
239  inline operator bool() const noexcept;
240 
250  size_t length() const noexcept {
251  return size_t(m_end - m_data);
252  }
253 
269  inline bool next();
270 
296  inline bool next(pbf_tag_type tag);
297 
307  inline pbf_tag_type tag() const noexcept;
308 
324  inline pbf_wire_type wire_type() const noexcept;
325 
332  inline bool has_wire_type(pbf_wire_type type) const noexcept;
333 
340  inline void skip();
341 
343 
354  inline bool get_bool();
355 
363  inline int32_t get_enum() {
364  protozero_assert(has_wire_type(pbf_wire_type::varint) && "not a varint");
365  return get_varint<int32_t>();
366  }
367 
375  inline int32_t get_int32() {
376  protozero_assert(has_wire_type(pbf_wire_type::varint) && "not a varint");
377  return get_varint<int32_t>();
378  }
379 
387  inline int32_t get_sint32() {
388  protozero_assert(has_wire_type(pbf_wire_type::varint) && "not a varint");
389  return get_svarint<int32_t>();
390  }
391 
399  inline uint32_t get_uint32() {
400  protozero_assert(has_wire_type(pbf_wire_type::varint) && "not a varint");
401  return get_varint<uint32_t>();
402  }
403 
411  inline int64_t get_int64() {
412  protozero_assert(has_wire_type(pbf_wire_type::varint) && "not a varint");
413  return get_varint<int64_t>();
414  }
415 
423  inline int64_t get_sint64() {
424  protozero_assert(has_wire_type(pbf_wire_type::varint) && "not a varint");
425  return get_svarint<int64_t>();
426  }
427 
435  inline uint64_t get_uint64() {
436  protozero_assert(has_wire_type(pbf_wire_type::varint) && "not a varint");
437  return get_varint<uint64_t>();
438  }
439 
447  inline uint32_t get_fixed32();
448 
456  inline int32_t get_sfixed32();
457 
465  inline uint64_t get_fixed64();
466 
474  inline int64_t get_sfixed64();
475 
483  inline float get_float();
484 
492  inline double get_double();
493 
502  inline std::pair<const char*, pbf_length_type> get_data();
503 
511  inline std::string get_bytes();
512 
520  inline std::string get_string();
521 
530  return pbf_reader(get_data());
531  }
532 
534 
535 private:
536 
537  template <typename T>
538  class const_varint_iterator : public std::iterator<std::forward_iterator_tag, T> {
539 
540  protected:
541 
542  const char* m_data;
543  const char* m_end;
544 
545  public:
546 
547  const_varint_iterator() noexcept :
548  m_data(nullptr),
549  m_end(nullptr) {
550  }
551 
552  const_varint_iterator(const char *data, const char* end) noexcept :
553  m_data(data),
554  m_end(end) {
555  }
556 
557  const_varint_iterator(const const_varint_iterator&) noexcept = default;
558  const_varint_iterator(const_varint_iterator&&) noexcept = default;
559 
560  const_varint_iterator& operator=(const const_varint_iterator&) noexcept = default;
561  const_varint_iterator& operator=(const_varint_iterator&&) noexcept = default;
562 
563  ~const_varint_iterator() noexcept = default;
564 
565  T operator*() {
566  const char* d = m_data; // will be thrown away
567  return static_cast<T>(decode_varint(&d, m_end));
568  }
569 
570  const_varint_iterator& operator++() {
571  // Ignore the result, we call decode_varint() just for the
572  // side-effect of updating m_data.
573  decode_varint(&m_data, m_end);
574  return *this;
575  }
576 
577  const_varint_iterator operator++(int) {
578  const const_varint_iterator tmp(*this);
579  ++(*this);
580  return tmp;
581  }
582 
583  bool operator==(const const_varint_iterator& rhs) const noexcept {
584  return m_data == rhs.m_data && m_end == rhs.m_end;
585  }
586 
587  bool operator!=(const const_varint_iterator& rhs) const noexcept {
588  return !(*this == rhs);
589  }
590 
591  }; // class const_varint_iterator
592 
593  template <typename T>
594  class const_svarint_iterator : public const_varint_iterator<T> {
595 
596  public:
597 
598  const_svarint_iterator() noexcept :
599  const_varint_iterator<T>() {
600  }
601 
602  const_svarint_iterator(const char *data, const char* end) noexcept :
603  const_varint_iterator<T>(data, end) {
604  }
605 
606  const_svarint_iterator(const const_svarint_iterator&) = default;
607  const_svarint_iterator(const_svarint_iterator&&) = default;
608 
609  const_svarint_iterator& operator=(const const_svarint_iterator&) = default;
610  const_svarint_iterator& operator=(const_svarint_iterator&&) = default;
611 
612  ~const_svarint_iterator() = default;
613 
614  T operator*() {
615  const char* d = this->m_data; // will be thrown away
616  return static_cast<T>(decode_zigzag64(decode_varint(&d, this->m_end)));
617  }
618 
619  const_svarint_iterator& operator++() {
620  // Ignore the result, we call decode_varint() just for the
621  // side-effect of updating m_data.
622  decode_varint(&this->m_data, this->m_end);
623  return *this;
624  }
625 
626  const_svarint_iterator operator++(int) {
627  const const_svarint_iterator tmp(*this);
628  ++(*this);
629  return tmp;
630  }
631 
632  }; // class const_svarint_iterator
633 
634 public:
635 
637  typedef const_varint_iterator< int32_t> const_bool_iterator;
638 
640  typedef const_varint_iterator< int32_t> const_enum_iterator;
641 
643  typedef const_varint_iterator< int32_t> const_int32_iterator;
644 
646  typedef const_svarint_iterator<int32_t> const_sint32_iterator;
647 
649  typedef const_varint_iterator<uint32_t> const_uint32_iterator;
650 
652  typedef const_varint_iterator< int64_t> const_int64_iterator;
653 
655  typedef const_svarint_iterator<int64_t> const_sint64_iterator;
656 
658  typedef const_varint_iterator<uint64_t> const_uint64_iterator;
659 
661 
674  inline std::pair<pbf_reader::const_bool_iterator, pbf_reader::const_bool_iterator> get_packed_bool();
675 
685  inline std::pair<pbf_reader::const_enum_iterator, pbf_reader::const_enum_iterator> get_packed_enum();
686 
696  inline std::pair<pbf_reader::const_int32_iterator, pbf_reader::const_int32_iterator> get_packed_int32();
697 
707  inline std::pair<pbf_reader::const_sint32_iterator, pbf_reader::const_sint32_iterator> get_packed_sint32();
708 
718  inline std::pair<pbf_reader::const_uint32_iterator, pbf_reader::const_uint32_iterator> get_packed_uint32();
719 
729  inline std::pair<pbf_reader::const_int64_iterator, pbf_reader::const_int64_iterator> get_packed_int64();
730 
740  inline std::pair<pbf_reader::const_sint64_iterator, pbf_reader::const_sint64_iterator> get_packed_sint64();
741 
751  inline std::pair<pbf_reader::const_uint64_iterator, pbf_reader::const_uint64_iterator> get_packed_uint64();
752 
762  inline auto get_packed_fixed32() -> decltype(packed_fixed<uint32_t>()) {
763  return packed_fixed<uint32_t>();
764  }
765 
775  inline auto get_packed_sfixed32() -> decltype(packed_fixed<int32_t>()) {
776  return packed_fixed<int32_t>();
777  }
778 
788  inline auto get_packed_fixed64() -> decltype(packed_fixed<uint64_t>()) {
789  return packed_fixed<uint64_t>();
790  }
791 
801  inline auto get_packed_sfixed64() -> decltype(packed_fixed<int64_t>()) {
802  return packed_fixed<int64_t>();
803  }
804 
814  inline auto get_packed_float() -> decltype(packed_fixed<float>()) {
815  return packed_fixed<float>();
816  }
817 
827  inline auto get_packed_double() -> decltype(packed_fixed<double>()) {
828  return packed_fixed<double>();
829  }
830 
832 
833 }; // class pbf_reader
834 
835 pbf_reader::pbf_reader(const char *data, size_t length) noexcept
836  : m_data(data),
837  m_end(data + length),
838  m_wire_type(pbf_wire_type::unknown),
839  m_tag(0) {
840 }
841 
842 pbf_reader::pbf_reader(std::pair<const char *, size_t> data) noexcept
843  : m_data(data.first),
844  m_end(data.first + data.second),
845  m_wire_type(pbf_wire_type::unknown),
846  m_tag(0) {
847 }
848 
849 pbf_reader::pbf_reader(const std::string& data) noexcept
850  : m_data(data.data()),
851  m_end(data.data() + data.size()),
852  m_wire_type(pbf_wire_type::unknown),
853  m_tag(0) {
854 }
855 
856 pbf_reader::operator bool() const noexcept {
857  return m_data < m_end;
858 }
859 
861  if (m_data == m_end) {
862  return false;
863  }
864 
865  auto value = get_varint<uint32_t>();
866  m_tag = value >> 3;
867 
868  // tags 0 and 19000 to 19999 are not allowed as per
869  // https://developers.google.com/protocol-buffers/docs/proto
870  protozero_assert(((m_tag > 0 && m_tag < 19000) || (m_tag > 19999 && m_tag <= ((1 << 29) - 1))) && "tag out of range");
871 
872  m_wire_type = pbf_wire_type(value & 0x07);
873  switch (m_wire_type) {
874  case pbf_wire_type::varint:
875  case pbf_wire_type::fixed64:
876  case pbf_wire_type::length_delimited:
877  case pbf_wire_type::fixed32:
878  break;
879  default:
881  }
882 
883  return true;
884 }
885 
886 bool pbf_reader::next(pbf_tag_type requested_tag) {
887  while (next()) {
888  if (m_tag == requested_tag) {
889  return true;
890  } else {
891  skip();
892  }
893  }
894  return false;
895 }
896 
897 pbf_tag_type pbf_reader::tag() const noexcept {
898  return m_tag;
899 }
900 
902  return m_wire_type;
903 }
904 
905 bool pbf_reader::has_wire_type(pbf_wire_type type) const noexcept {
906  return wire_type() == type;
907 }
908 
909 void pbf_reader::skip_bytes(pbf_length_type len) {
910  if (m_data + len > m_end) {
911  throw end_of_buffer_exception();
912  }
913  m_data += len;
914 
915 // In debug builds reset the tag to zero so that we can detect (some)
916 // wrong code.
917 #ifndef NDEBUG
918  m_tag = 0;
919 #endif
920 }
921 
923  protozero_assert(tag() != 0 && "call next() before calling skip()");
924  switch (wire_type()) {
925  case pbf_wire_type::varint:
926  (void)get_uint32(); // called for the side-effect of skipping value
927  break;
928  case pbf_wire_type::fixed64:
929  skip_bytes(8);
930  break;
931  case pbf_wire_type::length_delimited:
932  skip_bytes(get_length());
933  break;
934  case pbf_wire_type::fixed32:
935  skip_bytes(4);
936  break;
937  default:
939  }
940 }
941 
942 pbf_length_type pbf_reader::get_len_and_skip() {
943  auto len = get_length();
944  skip_bytes(len);
945  return len;
946 }
947 
948 template <typename T>
949 T pbf_reader::get_varint() {
950  return static_cast<T>(decode_varint(&m_data, m_end));
951 }
952 
953 template <typename T>
954 T pbf_reader::get_svarint() {
955  protozero_assert((has_wire_type(pbf_wire_type::varint) || has_wire_type(pbf_wire_type::length_delimited)) && "not a varint");
956  return static_cast<T>(decode_zigzag64(decode_varint(&m_data, m_end)));
957 }
958 
960  protozero_assert(tag() != 0 && "call next() before accessing field value");
961  protozero_assert(has_wire_type(pbf_wire_type::fixed32) && "not a 32-bit fixed");
962  return get_fixed<uint32_t>();
963 }
964 
966  protozero_assert(tag() != 0 && "call next() before accessing field value");
967  protozero_assert(has_wire_type(pbf_wire_type::fixed32) && "not a 32-bit fixed");
968  return get_fixed<int32_t>();
969 }
970 
972  protozero_assert(tag() != 0 && "call next() before accessing field value");
973  protozero_assert(has_wire_type(pbf_wire_type::fixed64) && "not a 64-bit fixed");
974  return get_fixed<uint64_t>();
975 }
976 
978  protozero_assert(tag() != 0 && "call next() before accessing field value");
979  protozero_assert(has_wire_type(pbf_wire_type::fixed64) && "not a 64-bit fixed");
980  return get_fixed<int64_t>();
981 }
982 
984  protozero_assert(tag() != 0 && "call next() before accessing field value");
985  protozero_assert(has_wire_type(pbf_wire_type::fixed32) && "not a 32-bit fixed");
986  return get_fixed<float>();
987 }
988 
990  protozero_assert(tag() != 0 && "call next() before accessing field value");
991  protozero_assert(has_wire_type(pbf_wire_type::fixed64) && "not a 64-bit fixed");
992  return get_fixed<double>();
993 }
994 
996  protozero_assert(tag() != 0 && "call next() before accessing field value");
997  protozero_assert(has_wire_type(pbf_wire_type::varint) && "not a varint");
998  protozero_assert((*m_data & 0x80) == 0 && "not a 1 byte varint");
999  skip_bytes(1);
1000  return m_data[-1] != 0; // -1 okay because we incremented m_data the line before
1001 }
1002 
1003 std::pair<const char*, pbf_length_type> pbf_reader::get_data() {
1004  protozero_assert(tag() != 0 && "call next() before accessing field value");
1005  protozero_assert(has_wire_type(pbf_wire_type::length_delimited) && "not of type string, bytes or message");
1006  auto len = get_len_and_skip();
1007  return std::make_pair(m_data-len, len);
1008 }
1009 
1010 std::string pbf_reader::get_bytes() {
1011  auto d = get_data();
1012  return std::string(d.first, d.second);
1013 }
1014 
1015 std::string pbf_reader::get_string() {
1016  return get_bytes();
1017 }
1018 
1019 std::pair<pbf_reader::const_bool_iterator, pbf_reader::const_bool_iterator> pbf_reader::get_packed_bool() {
1020  return get_packed_int32();
1021 }
1022 
1023 std::pair<pbf_reader::const_enum_iterator, pbf_reader::const_enum_iterator> pbf_reader::get_packed_enum() {
1024  return get_packed_int32();
1025 }
1026 
1027 std::pair<pbf_reader::const_int32_iterator, pbf_reader::const_int32_iterator> pbf_reader::get_packed_int32() {
1028  protozero_assert(tag() != 0 && "call next() before accessing field value");
1029  auto len = get_len_and_skip();
1030  return std::make_pair(pbf_reader::const_int32_iterator(m_data-len, m_data),
1031  pbf_reader::const_int32_iterator(m_data, m_data));
1032 }
1033 
1034 std::pair<pbf_reader::const_uint32_iterator, pbf_reader::const_uint32_iterator> pbf_reader::get_packed_uint32() {
1035  protozero_assert(tag() != 0 && "call next() before accessing field value");
1036  auto len = get_len_and_skip();
1037  return std::make_pair(pbf_reader::const_uint32_iterator(m_data-len, m_data),
1038  pbf_reader::const_uint32_iterator(m_data, m_data));
1039 }
1040 
1041 std::pair<pbf_reader::const_sint32_iterator, pbf_reader::const_sint32_iterator> pbf_reader::get_packed_sint32() {
1042  protozero_assert(tag() != 0 && "call next() before accessing field value");
1043  auto len = get_len_and_skip();
1044  return std::make_pair(pbf_reader::const_sint32_iterator(m_data-len, m_data),
1045  pbf_reader::const_sint32_iterator(m_data, m_data));
1046 }
1047 
1048 std::pair<pbf_reader::const_int64_iterator, pbf_reader::const_int64_iterator> pbf_reader::get_packed_int64() {
1049  protozero_assert(tag() != 0 && "call next() before accessing field value");
1050  auto len = get_len_and_skip();
1051  return std::make_pair(pbf_reader::const_int64_iterator(m_data-len, m_data),
1052  pbf_reader::const_int64_iterator(m_data, m_data));
1053 }
1054 
1055 std::pair<pbf_reader::const_uint64_iterator, pbf_reader::const_uint64_iterator> pbf_reader::get_packed_uint64() {
1056  protozero_assert(tag() != 0 && "call next() before accessing field value");
1057  auto len = get_len_and_skip();
1058  return std::make_pair(pbf_reader::const_uint64_iterator(m_data-len, m_data),
1059  pbf_reader::const_uint64_iterator(m_data, m_data));
1060 }
1061 
1062 std::pair<pbf_reader::const_sint64_iterator, pbf_reader::const_sint64_iterator> pbf_reader::get_packed_sint64() {
1063  protozero_assert(tag() != 0 && "call next() before accessing field value");
1064  auto len = get_len_and_skip();
1065  return std::make_pair(pbf_reader::const_sint64_iterator(m_data-len, m_data),
1066  pbf_reader::const_sint64_iterator(m_data, m_data));
1067 }
1068 
1069 } // end namespace protozero
1070 
1071 #endif // PROTOZERO_PBF_READER_HPP
int64_t get_sfixed64()
Definition: pbf_reader.hpp:977
uint32_t get_uint32()
Definition: pbf_reader.hpp:399
uint64_t get_fixed64()
Definition: pbf_reader.hpp:971
int32_t get_sfixed32()
Definition: pbf_reader.hpp:965
Definition: exception.hpp:48
uint64_t get_uint64()
Definition: pbf_reader.hpp:435
auto get_packed_double() -> decltype(packed_fixed< double >())
Definition: pbf_reader.hpp:827
int32_t get_int32()
Definition: pbf_reader.hpp:375
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:1041
auto get_packed_float() -> decltype(packed_fixed< float >())
Definition: pbf_reader.hpp:814
auto get_packed_fixed32() -> decltype(packed_fixed< uint32_t >())
Definition: pbf_reader.hpp:762
std::pair< const char *, pbf_length_type > get_data()
Definition: pbf_reader.hpp:1003
Contains macro checks for different configurations.
bool has_wire_type(pbf_wire_type type) const noexcept
Definition: pbf_reader.hpp:905
void skip()
Definition: pbf_reader.hpp:922
const_varint_iterator< uint32_t > const_uint32_iterator
Forward iterator for iterating over uint32 (varint) values.
Definition: pbf_reader.hpp:649
pbf_reader get_message()
Definition: pbf_reader.hpp:529
pbf_reader() noexcept=default
std::pair< pbf_reader::const_bool_iterator, pbf_reader::const_bool_iterator > get_packed_bool()
Definition: pbf_reader.hpp:1019
auto get_packed_sfixed64() -> decltype(packed_fixed< int64_t >())
Definition: pbf_reader.hpp:801
auto get_packed_sfixed32() -> decltype(packed_fixed< int32_t >())
Definition: pbf_reader.hpp:775
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:901
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:1027
int64_t get_sint64()
Definition: pbf_reader.hpp:423
auto get_packed_fixed64() -> decltype(packed_fixed< uint64_t >())
Definition: pbf_reader.hpp:788
Contains functions to swap bytes in values (for different endianness).
int32_t get_sint32()
Definition: pbf_reader.hpp:387
std::string get_bytes()
Definition: pbf_reader.hpp:1010
double get_double()
Definition: pbf_reader.hpp:989
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:655
bool get_bool()
Definition: pbf_reader.hpp:995
std::string get_string()
Definition: pbf_reader.hpp:1015
const_varint_iterator< int32_t > const_enum_iterator
Forward iterator for iterating over enum (int32 varint) values.
Definition: pbf_reader.hpp:640
Contains the exceptions used in the protozero library.
uint32_t get_fixed32()
Definition: pbf_reader.hpp:959
pbf_tag_type tag() const noexcept
Definition: pbf_reader.hpp:897
const_varint_iterator< int32_t > const_int32_iterator
Forward iterator for iterating over int32 (varint) values.
Definition: pbf_reader.hpp:643
std::pair< pbf_reader::const_int64_iterator, pbf_reader::const_int64_iterator > get_packed_int64()
Definition: pbf_reader.hpp:1048
const_varint_iterator< int32_t > const_bool_iterator
Forward iterator for iterating over bool (int32 varint) values.
Definition: pbf_reader.hpp:637
int32_t get_enum()
Definition: pbf_reader.hpp:363
Definition: pbf_reader.hpp:61
const_varint_iterator< uint64_t > const_uint64_iterator
Forward iterator for iterating over uint64 (varint) values.
Definition: pbf_reader.hpp:658
float get_float()
Definition: pbf_reader.hpp:983
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:652
std::pair< pbf_reader::const_uint64_iterator, pbf_reader::const_uint64_iterator > get_packed_uint64()
Definition: pbf_reader.hpp:1055
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:1023
const_svarint_iterator< int32_t > const_sint32_iterator
Forward iterator for iterating over sint32 (varint) values.
Definition: pbf_reader.hpp:646
bool next()
Definition: pbf_reader.hpp:860
size_t length() const noexcept
Definition: pbf_reader.hpp:250
int64_t get_int64()
Definition: pbf_reader.hpp:411
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:1062
All parts of the protozero header-only library are in this namespace.
Definition: byteswap.hpp:24
std::pair< pbf_reader::const_uint32_iterator, pbf_reader::const_uint32_iterator > get_packed_uint32()
Definition: pbf_reader.hpp:1034