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/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  using const_fixed_iterator = const T*;
98 
99  template <typename T>
100  inline std::pair<const_fixed_iterator<T>, const_fixed_iterator<T>> create_fixed_iterator_pair(const char* first, const char* last) {
101  return std::make_pair(reinterpret_cast<const T*>(first),
102  reinterpret_cast<const T*>(last));
103  }
104 
105 #else
106 
107  template <typename T>
108  class const_fixed_iterator : public std::iterator<std::forward_iterator_tag, T> {
109 
110  const char* m_data;
111  const char* m_end;
112 
113  public:
114 
115  const_fixed_iterator() noexcept :
116  m_data(nullptr),
117  m_end(nullptr) {
118  }
119 
120  const_fixed_iterator(const char *data, const char* end) noexcept :
121  m_data(data),
122  m_end(end) {
123  }
124 
125  const_fixed_iterator(const const_fixed_iterator&) noexcept = default;
126  const_fixed_iterator(const_fixed_iterator&&) noexcept = default;
127 
128  const_fixed_iterator& operator=(const const_fixed_iterator&) noexcept = default;
129  const_fixed_iterator& operator=(const_fixed_iterator&&) noexcept = default;
130 
131  ~const_fixed_iterator() noexcept = default;
132 
133  T operator*() {
134  T result;
135  copy_or_byteswap<sizeof(T)>(m_data , &result);
136  return result;
137  }
138 
139  const_fixed_iterator& operator++() {
140  m_data += sizeof(T);
141  return *this;
142  }
143 
144  const_fixed_iterator operator++(int) {
145  const const_fixed_iterator tmp(*this);
146  ++(*this);
147  return tmp;
148  }
149 
150  bool operator==(const const_fixed_iterator& rhs) const noexcept {
151  return m_data == rhs.m_data && m_end == rhs.m_end;
152  }
153 
154  bool operator!=(const const_fixed_iterator& rhs) const noexcept {
155  return !(*this == rhs);
156  }
157 
158  }; // class const_fixed_iterator
159 
160  template <typename T>
161  inline std::pair<const_fixed_iterator<T>, const_fixed_iterator<T>> create_fixed_iterator_pair(const char* first, const char* last) {
162  return std::make_pair(const_fixed_iterator<T>(first, last),
163  const_fixed_iterator<T>(last, last));
164  }
165 
166 #endif
167 
168  template <typename T>
169  inline std::pair<const_fixed_iterator<T>, const_fixed_iterator<T>> packed_fixed() {
170  protozero_assert(tag() != 0 && "call next() before accessing field value");
171  auto len = get_len_and_skip();
172  protozero_assert(len % sizeof(T) == 0);
173  return create_fixed_iterator_pair<T>(m_data-len, m_data);
174  }
175 
176  template <typename T> inline T get_varint();
177  template <typename T> inline T get_svarint();
178 
179  inline pbf_length_type get_length() { return get_varint<pbf_length_type>(); }
180 
181  inline void skip_bytes(pbf_length_type len);
182 
183  inline pbf_length_type get_len_and_skip();
184 
185 public:
186 
196  inline pbf_reader(const char *data, std::size_t length) noexcept;
197 
207  inline pbf_reader(std::pair<const char *, std::size_t> data) noexcept;
208 
219  inline pbf_reader(const std::string& data) noexcept;
220 
225  inline pbf_reader() noexcept = default;
226 
228  inline pbf_reader(const pbf_reader&) noexcept = default;
229 
231  inline pbf_reader(pbf_reader&&) noexcept = default;
232 
234  inline pbf_reader& operator=(const pbf_reader& other) noexcept = default;
235 
237  inline pbf_reader& operator=(pbf_reader&& other) noexcept = default;
238 
239  inline ~pbf_reader() = default;
240 
245  inline operator bool() const noexcept;
246 
256  std::size_t length() const noexcept {
257  return std::size_t(m_end - m_data);
258  }
259 
275  inline bool next();
276 
302  inline bool next(pbf_tag_type tag);
303 
313  inline pbf_tag_type tag() const noexcept;
314 
330  inline pbf_wire_type wire_type() const noexcept;
331 
338  inline bool has_wire_type(pbf_wire_type type) const noexcept;
339 
346  inline void skip();
347 
349 
360  inline bool get_bool();
361 
369  inline int32_t get_enum() {
370  protozero_assert(has_wire_type(pbf_wire_type::varint) && "not a varint");
371  return get_varint<int32_t>();
372  }
373 
381  inline int32_t get_int32() {
382  protozero_assert(has_wire_type(pbf_wire_type::varint) && "not a varint");
383  return get_varint<int32_t>();
384  }
385 
393  inline int32_t get_sint32() {
394  protozero_assert(has_wire_type(pbf_wire_type::varint) && "not a varint");
395  return get_svarint<int32_t>();
396  }
397 
405  inline uint32_t get_uint32() {
406  protozero_assert(has_wire_type(pbf_wire_type::varint) && "not a varint");
407  return get_varint<uint32_t>();
408  }
409 
417  inline int64_t get_int64() {
418  protozero_assert(has_wire_type(pbf_wire_type::varint) && "not a varint");
419  return get_varint<int64_t>();
420  }
421 
429  inline int64_t get_sint64() {
430  protozero_assert(has_wire_type(pbf_wire_type::varint) && "not a varint");
431  return get_svarint<int64_t>();
432  }
433 
441  inline uint64_t get_uint64() {
442  protozero_assert(has_wire_type(pbf_wire_type::varint) && "not a varint");
443  return get_varint<uint64_t>();
444  }
445 
453  inline uint32_t get_fixed32();
454 
462  inline int32_t get_sfixed32();
463 
471  inline uint64_t get_fixed64();
472 
480  inline int64_t get_sfixed64();
481 
489  inline float get_float();
490 
498  inline double get_double();
499 
508  inline std::pair<const char*, pbf_length_type> get_data();
509 
517  inline std::string get_bytes();
518 
526  inline std::string get_string();
527 
536  return pbf_reader(get_data());
537  }
538 
540 
541 private:
542 
543  template <typename T>
544  class const_varint_iterator : public std::iterator<std::forward_iterator_tag, T> {
545 
546  protected:
547 
548  const char* m_data;
549  const char* m_end;
550 
551  public:
552 
553  const_varint_iterator() noexcept :
554  m_data(nullptr),
555  m_end(nullptr) {
556  }
557 
558  const_varint_iterator(const char *data, const char* end) noexcept :
559  m_data(data),
560  m_end(end) {
561  }
562 
563  const_varint_iterator(const const_varint_iterator&) noexcept = default;
564  const_varint_iterator(const_varint_iterator&&) noexcept = default;
565 
566  const_varint_iterator& operator=(const const_varint_iterator&) noexcept = default;
567  const_varint_iterator& operator=(const_varint_iterator&&) noexcept = default;
568 
569  ~const_varint_iterator() noexcept = default;
570 
571  T operator*() {
572  const char* d = m_data; // will be thrown away
573  return static_cast<T>(decode_varint(&d, m_end));
574  }
575 
576  const_varint_iterator& operator++() {
577  // Ignore the result, we call decode_varint() just for the
578  // side-effect of updating m_data.
579  decode_varint(&m_data, m_end);
580  return *this;
581  }
582 
583  const_varint_iterator operator++(int) {
584  const const_varint_iterator tmp(*this);
585  ++(*this);
586  return tmp;
587  }
588 
589  bool operator==(const const_varint_iterator& rhs) const noexcept {
590  return m_data == rhs.m_data && m_end == rhs.m_end;
591  }
592 
593  bool operator!=(const const_varint_iterator& rhs) const noexcept {
594  return !(*this == rhs);
595  }
596 
597  }; // class const_varint_iterator
598 
599  template <typename T>
600  class const_svarint_iterator : public const_varint_iterator<T> {
601 
602  public:
603 
604  const_svarint_iterator() noexcept :
605  const_varint_iterator<T>() {
606  }
607 
608  const_svarint_iterator(const char *data, const char* end) noexcept :
609  const_varint_iterator<T>(data, end) {
610  }
611 
612  const_svarint_iterator(const const_svarint_iterator&) = default;
613  const_svarint_iterator(const_svarint_iterator&&) = default;
614 
615  const_svarint_iterator& operator=(const const_svarint_iterator&) = default;
616  const_svarint_iterator& operator=(const_svarint_iterator&&) = default;
617 
618  ~const_svarint_iterator() = default;
619 
620  T operator*() {
621  const char* d = this->m_data; // will be thrown away
622  return static_cast<T>(decode_zigzag64(decode_varint(&d, this->m_end)));
623  }
624 
625  const_svarint_iterator& operator++() {
626  // Ignore the result, we call decode_varint() just for the
627  // side-effect of updating m_data.
628  decode_varint(&this->m_data, this->m_end);
629  return *this;
630  }
631 
632  const_svarint_iterator operator++(int) {
633  const const_svarint_iterator tmp(*this);
634  ++(*this);
635  return tmp;
636  }
637 
638  }; // class const_svarint_iterator
639 
640 public:
641 
643  typedef const_varint_iterator< int32_t> const_bool_iterator;
644 
646  typedef const_varint_iterator< int32_t> const_enum_iterator;
647 
649  typedef const_varint_iterator< int32_t> const_int32_iterator;
650 
652  typedef const_svarint_iterator<int32_t> const_sint32_iterator;
653 
655  typedef const_varint_iterator<uint32_t> const_uint32_iterator;
656 
658  typedef const_varint_iterator< int64_t> const_int64_iterator;
659 
661  typedef const_svarint_iterator<int64_t> const_sint64_iterator;
662 
664  typedef const_varint_iterator<uint64_t> const_uint64_iterator;
665 
667 
680  inline std::pair<pbf_reader::const_bool_iterator, pbf_reader::const_bool_iterator> get_packed_bool();
681 
691  inline std::pair<pbf_reader::const_enum_iterator, pbf_reader::const_enum_iterator> get_packed_enum();
692 
702  inline std::pair<pbf_reader::const_int32_iterator, pbf_reader::const_int32_iterator> get_packed_int32();
703 
713  inline std::pair<pbf_reader::const_sint32_iterator, pbf_reader::const_sint32_iterator> get_packed_sint32();
714 
724  inline std::pair<pbf_reader::const_uint32_iterator, pbf_reader::const_uint32_iterator> get_packed_uint32();
725 
735  inline std::pair<pbf_reader::const_int64_iterator, pbf_reader::const_int64_iterator> get_packed_int64();
736 
746  inline std::pair<pbf_reader::const_sint64_iterator, pbf_reader::const_sint64_iterator> get_packed_sint64();
747 
757  inline std::pair<pbf_reader::const_uint64_iterator, pbf_reader::const_uint64_iterator> get_packed_uint64();
758 
768  inline auto get_packed_fixed32() -> decltype(packed_fixed<uint32_t>()) {
769  return packed_fixed<uint32_t>();
770  }
771 
781  inline auto get_packed_sfixed32() -> decltype(packed_fixed<int32_t>()) {
782  return packed_fixed<int32_t>();
783  }
784 
794  inline auto get_packed_fixed64() -> decltype(packed_fixed<uint64_t>()) {
795  return packed_fixed<uint64_t>();
796  }
797 
807  inline auto get_packed_sfixed64() -> decltype(packed_fixed<int64_t>()) {
808  return packed_fixed<int64_t>();
809  }
810 
820  inline auto get_packed_float() -> decltype(packed_fixed<float>()) {
821  return packed_fixed<float>();
822  }
823 
833  inline auto get_packed_double() -> decltype(packed_fixed<double>()) {
834  return packed_fixed<double>();
835  }
836 
838 
839 }; // class pbf_reader
840 
841 pbf_reader::pbf_reader(const char *data, std::size_t length) noexcept
842  : m_data(data),
843  m_end(data + length),
844  m_wire_type(pbf_wire_type::unknown),
845  m_tag(0) {
846 }
847 
848 pbf_reader::pbf_reader(std::pair<const char *, std::size_t> data) noexcept
849  : m_data(data.first),
850  m_end(data.first + data.second),
851  m_wire_type(pbf_wire_type::unknown),
852  m_tag(0) {
853 }
854 
855 pbf_reader::pbf_reader(const std::string& data) noexcept
856  : m_data(data.data()),
857  m_end(data.data() + data.size()),
858  m_wire_type(pbf_wire_type::unknown),
859  m_tag(0) {
860 }
861 
862 pbf_reader::operator bool() const noexcept {
863  return m_data < m_end;
864 }
865 
867  if (m_data == m_end) {
868  return false;
869  }
870 
871  auto value = get_varint<uint32_t>();
872  m_tag = value >> 3;
873 
874  // tags 0 and 19000 to 19999 are not allowed as per
875  // https://developers.google.com/protocol-buffers/docs/proto
876  protozero_assert(((m_tag > 0 && m_tag < 19000) || (m_tag > 19999 && m_tag <= ((1 << 29) - 1))) && "tag out of range");
877 
878  m_wire_type = pbf_wire_type(value & 0x07);
879  switch (m_wire_type) {
880  case pbf_wire_type::varint:
881  case pbf_wire_type::fixed64:
882  case pbf_wire_type::length_delimited:
883  case pbf_wire_type::fixed32:
884  break;
885  default:
887  }
888 
889  return true;
890 }
891 
892 bool pbf_reader::next(pbf_tag_type requested_tag) {
893  while (next()) {
894  if (m_tag == requested_tag) {
895  return true;
896  } else {
897  skip();
898  }
899  }
900  return false;
901 }
902 
903 pbf_tag_type pbf_reader::tag() const noexcept {
904  return m_tag;
905 }
906 
908  return m_wire_type;
909 }
910 
911 bool pbf_reader::has_wire_type(pbf_wire_type type) const noexcept {
912  return wire_type() == type;
913 }
914 
915 void pbf_reader::skip_bytes(pbf_length_type len) {
916  if (m_data + len > m_end) {
917  throw end_of_buffer_exception();
918  }
919  m_data += len;
920 
921 // In debug builds reset the tag to zero so that we can detect (some)
922 // wrong code.
923 #ifndef NDEBUG
924  m_tag = 0;
925 #endif
926 }
927 
929  protozero_assert(tag() != 0 && "call next() before calling skip()");
930  switch (wire_type()) {
931  case pbf_wire_type::varint:
932  (void)get_uint32(); // called for the side-effect of skipping value
933  break;
934  case pbf_wire_type::fixed64:
935  skip_bytes(8);
936  break;
937  case pbf_wire_type::length_delimited:
938  skip_bytes(get_length());
939  break;
940  case pbf_wire_type::fixed32:
941  skip_bytes(4);
942  break;
943  default:
944  protozero_assert(false && "can not be here because next() should have thrown already");
945  }
946 }
947 
948 pbf_length_type pbf_reader::get_len_and_skip() {
949  auto len = get_length();
950  skip_bytes(len);
951  return len;
952 }
953 
954 template <typename T>
955 T pbf_reader::get_varint() {
956  return static_cast<T>(decode_varint(&m_data, m_end));
957 }
958 
959 template <typename T>
960 T pbf_reader::get_svarint() {
961  protozero_assert((has_wire_type(pbf_wire_type::varint) || has_wire_type(pbf_wire_type::length_delimited)) && "not a varint");
962  return static_cast<T>(decode_zigzag64(decode_varint(&m_data, m_end)));
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<uint32_t>();
969 }
970 
972  protozero_assert(tag() != 0 && "call next() before accessing field value");
973  protozero_assert(has_wire_type(pbf_wire_type::fixed32) && "not a 32-bit fixed");
974  return get_fixed<int32_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<uint64_t>();
981 }
982 
984  protozero_assert(tag() != 0 && "call next() before accessing field value");
985  protozero_assert(has_wire_type(pbf_wire_type::fixed64) && "not a 64-bit fixed");
986  return get_fixed<int64_t>();
987 }
988 
990  protozero_assert(tag() != 0 && "call next() before accessing field value");
991  protozero_assert(has_wire_type(pbf_wire_type::fixed32) && "not a 32-bit fixed");
992  return get_fixed<float>();
993 }
994 
996  protozero_assert(tag() != 0 && "call next() before accessing field value");
997  protozero_assert(has_wire_type(pbf_wire_type::fixed64) && "not a 64-bit fixed");
998  return get_fixed<double>();
999 }
1000 
1002  protozero_assert(tag() != 0 && "call next() before accessing field value");
1003  protozero_assert(has_wire_type(pbf_wire_type::varint) && "not a varint");
1004  protozero_assert((*m_data & 0x80) == 0 && "not a 1 byte varint");
1005  skip_bytes(1);
1006  return m_data[-1] != 0; // -1 okay because we incremented m_data the line before
1007 }
1008 
1009 std::pair<const char*, pbf_length_type> pbf_reader::get_data() {
1010  protozero_assert(tag() != 0 && "call next() before accessing field value");
1011  protozero_assert(has_wire_type(pbf_wire_type::length_delimited) && "not of type string, bytes or message");
1012  auto len = get_len_and_skip();
1013  return std::make_pair(m_data-len, len);
1014 }
1015 
1016 std::string pbf_reader::get_bytes() {
1017  auto d = get_data();
1018  return std::string(d.first, d.second);
1019 }
1020 
1021 std::string pbf_reader::get_string() {
1022  return get_bytes();
1023 }
1024 
1025 std::pair<pbf_reader::const_bool_iterator, pbf_reader::const_bool_iterator> pbf_reader::get_packed_bool() {
1026  return get_packed_int32();
1027 }
1028 
1029 std::pair<pbf_reader::const_enum_iterator, pbf_reader::const_enum_iterator> pbf_reader::get_packed_enum() {
1030  return get_packed_int32();
1031 }
1032 
1033 std::pair<pbf_reader::const_int32_iterator, pbf_reader::const_int32_iterator> pbf_reader::get_packed_int32() {
1034  protozero_assert(tag() != 0 && "call next() before accessing field value");
1035  auto len = get_len_and_skip();
1036  return std::make_pair(pbf_reader::const_int32_iterator(m_data-len, m_data),
1037  pbf_reader::const_int32_iterator(m_data, m_data));
1038 }
1039 
1040 std::pair<pbf_reader::const_uint32_iterator, pbf_reader::const_uint32_iterator> pbf_reader::get_packed_uint32() {
1041  protozero_assert(tag() != 0 && "call next() before accessing field value");
1042  auto len = get_len_and_skip();
1043  return std::make_pair(pbf_reader::const_uint32_iterator(m_data-len, m_data),
1044  pbf_reader::const_uint32_iterator(m_data, m_data));
1045 }
1046 
1047 std::pair<pbf_reader::const_sint32_iterator, pbf_reader::const_sint32_iterator> pbf_reader::get_packed_sint32() {
1048  protozero_assert(tag() != 0 && "call next() before accessing field value");
1049  auto len = get_len_and_skip();
1050  return std::make_pair(pbf_reader::const_sint32_iterator(m_data-len, m_data),
1051  pbf_reader::const_sint32_iterator(m_data, m_data));
1052 }
1053 
1054 std::pair<pbf_reader::const_int64_iterator, pbf_reader::const_int64_iterator> pbf_reader::get_packed_int64() {
1055  protozero_assert(tag() != 0 && "call next() before accessing field value");
1056  auto len = get_len_and_skip();
1057  return std::make_pair(pbf_reader::const_int64_iterator(m_data-len, m_data),
1058  pbf_reader::const_int64_iterator(m_data, m_data));
1059 }
1060 
1061 std::pair<pbf_reader::const_uint64_iterator, pbf_reader::const_uint64_iterator> pbf_reader::get_packed_uint64() {
1062  protozero_assert(tag() != 0 && "call next() before accessing field value");
1063  auto len = get_len_and_skip();
1064  return std::make_pair(pbf_reader::const_uint64_iterator(m_data-len, m_data),
1065  pbf_reader::const_uint64_iterator(m_data, m_data));
1066 }
1067 
1068 std::pair<pbf_reader::const_sint64_iterator, pbf_reader::const_sint64_iterator> pbf_reader::get_packed_sint64() {
1069  protozero_assert(tag() != 0 && "call next() before accessing field value");
1070  auto len = get_len_and_skip();
1071  return std::make_pair(pbf_reader::const_sint64_iterator(m_data-len, m_data),
1072  pbf_reader::const_sint64_iterator(m_data, m_data));
1073 }
1074 
1075 } // end namespace protozero
1076 
1077 #endif // PROTOZERO_PBF_READER_HPP
int64_t get_sfixed64()
Definition: pbf_reader.hpp:983
uint32_t get_uint32()
Definition: pbf_reader.hpp:405
uint64_t get_fixed64()
Definition: pbf_reader.hpp:977
int32_t get_sfixed32()
Definition: pbf_reader.hpp:971
Definition: exception.hpp:48
uint64_t get_uint64()
Definition: pbf_reader.hpp:441
auto get_packed_double() -> decltype(packed_fixed< double >())
Definition: pbf_reader.hpp:833
int32_t get_int32()
Definition: pbf_reader.hpp:381
uint32_t pbf_length_type
Definition: types.hpp:45
std::pair< pbf_reader::const_sint32_iterator, pbf_reader::const_sint32_iterator > get_packed_sint32()
Definition: pbf_reader.hpp:1047
auto get_packed_float() -> decltype(packed_fixed< float >())
Definition: pbf_reader.hpp:820
auto get_packed_fixed32() -> decltype(packed_fixed< uint32_t >())
Definition: pbf_reader.hpp:768
std::pair< const char *, pbf_length_type > get_data()
Definition: pbf_reader.hpp:1009
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:911
std::size_t length() const noexcept
Definition: pbf_reader.hpp:256
void skip()
Definition: pbf_reader.hpp:928
const_varint_iterator< uint32_t > const_uint32_iterator
Forward iterator for iterating over uint32 (varint) values.
Definition: pbf_reader.hpp:655
pbf_reader get_message()
Definition: pbf_reader.hpp:535
pbf_reader() noexcept=default
std::pair< pbf_reader::const_bool_iterator, pbf_reader::const_bool_iterator > get_packed_bool()
Definition: pbf_reader.hpp:1025
auto get_packed_sfixed64() -> decltype(packed_fixed< int64_t >())
Definition: pbf_reader.hpp:807
auto get_packed_sfixed32() -> decltype(packed_fixed< int32_t >())
Definition: pbf_reader.hpp:781
pbf_wire_type
Definition: types.hpp:33
pbf_wire_type wire_type() const noexcept
Definition: pbf_reader.hpp:907
uint32_t pbf_tag_type
Definition: types.hpp:26
std::pair< pbf_reader::const_int32_iterator, pbf_reader::const_int32_iterator > get_packed_int32()
Definition: pbf_reader.hpp:1033
int64_t get_sint64()
Definition: pbf_reader.hpp:429
auto get_packed_fixed64() -> decltype(packed_fixed< uint64_t >())
Definition: pbf_reader.hpp:794
Contains functions to swap bytes in values (for different endianness).
int32_t get_sint32()
Definition: pbf_reader.hpp:393
std::string get_bytes()
Definition: pbf_reader.hpp:1016
double get_double()
Definition: pbf_reader.hpp:995
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:661
bool get_bool()
Definition: pbf_reader.hpp:1001
std::string get_string()
Definition: pbf_reader.hpp:1021
const_varint_iterator< int32_t > const_enum_iterator
Forward iterator for iterating over enum (int32 varint) values.
Definition: pbf_reader.hpp:646
Contains the exceptions used in the protozero library.
uint32_t get_fixed32()
Definition: pbf_reader.hpp:965
pbf_tag_type tag() const noexcept
Definition: pbf_reader.hpp:903
const_varint_iterator< int32_t > const_int32_iterator
Forward iterator for iterating over int32 (varint) values.
Definition: pbf_reader.hpp:649
std::pair< pbf_reader::const_int64_iterator, pbf_reader::const_int64_iterator > get_packed_int64()
Definition: pbf_reader.hpp:1054
const_varint_iterator< int32_t > const_bool_iterator
Forward iterator for iterating over bool (int32 varint) values.
Definition: pbf_reader.hpp:643
int32_t get_enum()
Definition: pbf_reader.hpp:369
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:664
float get_float()
Definition: pbf_reader.hpp:989
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:658
std::pair< pbf_reader::const_uint64_iterator, pbf_reader::const_uint64_iterator > get_packed_uint64()
Definition: pbf_reader.hpp:1061
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:1029
const_svarint_iterator< int32_t > const_sint32_iterator
Forward iterator for iterating over sint32 (varint) values.
Definition: pbf_reader.hpp:652
bool next()
Definition: pbf_reader.hpp:866
int64_t get_int64()
Definition: pbf_reader.hpp:417
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:1068
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:1040