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 <cassert>
20 #include <cstddef>
21 #include <cstdint>
22 #include <cstring>
23 #include <iterator>
24 #include <string>
25 #include <utility>
26 
27 #include <protozero/pbf_types.hpp>
28 #include <protozero/exception.hpp>
29 #include <protozero/varint.hpp>
30 
31 #if __BYTE_ORDER != __LITTLE_ENDIAN
32 # include <protozero/byteswap.hpp>
33 #endif
34 
36 #ifndef protozero_assert
37 # define protozero_assert(x) assert(x)
38 #endif
39 
40 namespace protozero {
41 
66 class pbf_reader {
67 
68  // A pointer to the next unread data.
69  const char *m_data = nullptr;
70 
71  // A pointer to one past the end of data.
72  const char *m_end = nullptr;
73 
74  // The wire type of the current field.
75  pbf_wire_type m_wire_type = pbf_wire_type::unknown;
76 
77  // The tag of the current field.
78  pbf_tag_type m_tag = 0;
79 
80  template <typename T>
81  inline T get_fixed() {
82  T result;
83  skip_bytes(sizeof(T));
84 #if __BYTE_ORDER == __LITTLE_ENDIAN
85  memcpy(&result, m_data - sizeof(T), sizeof(T));
86 #else
87  byteswap<sizeof(T)>(m_data - sizeof(T), reinterpret_cast<char*>(&result));
88 #endif
89  return result;
90  }
91 
92 #if __BYTE_ORDER == __LITTLE_ENDIAN
93  template <typename T>
94  inline std::pair<const T*, const T*> packed_fixed() {
95  protozero_assert(tag() != 0 && "call next() before accessing field value");
96  auto len = get_len_and_skip();
97  protozero_assert(len % sizeof(T) == 0);
98  return std::make_pair(reinterpret_cast<const T*>(m_data-len), reinterpret_cast<const T*>(m_data));
99  }
100 
101 #else
102 
103  template <typename T>
104  class const_fixed_iterator : public std::iterator<std::forward_iterator_tag, T> {
105 
106  const char* m_data;
107  const char* m_end;
108 
109  public:
110 
111  const_fixed_iterator() noexcept :
112  m_data(nullptr),
113  m_end(nullptr) {
114  }
115 
116  const_fixed_iterator(const char *data, const char* end) noexcept :
117  m_data(data),
118  m_end(end) {
119  }
120 
121  const_fixed_iterator(const const_fixed_iterator&) noexcept = default;
122  const_fixed_iterator(const_fixed_iterator&&) noexcept = default;
123 
124  const_fixed_iterator& operator=(const const_fixed_iterator&) noexcept = default;
125  const_fixed_iterator& operator=(const_fixed_iterator&&) noexcept = default;
126 
127  ~const_fixed_iterator() noexcept = default;
128 
129  T operator*() {
130  T result;
131  byteswap<sizeof(T)>(m_data, reinterpret_cast<char*>(&result));
132  return result;
133  }
134 
135  const_fixed_iterator& operator++() {
136  m_data += sizeof(T);
137  return *this;
138  }
139 
140  const_fixed_iterator operator++(int) {
141  const const_fixed_iterator tmp(*this);
142  ++(*this);
143  return tmp;
144  }
145 
146  bool operator==(const const_fixed_iterator& rhs) const noexcept {
147  return m_data == rhs.m_data && m_end == rhs.m_end;
148  }
149 
150  bool operator!=(const const_fixed_iterator& rhs) const noexcept {
151  return !(*this == rhs);
152  }
153 
154  }; // class const_fixed_iterator
155 
156  template <typename T>
157  inline std::pair<const_fixed_iterator<T>, const_fixed_iterator<T>> packed_fixed() {
158  protozero_assert(tag() != 0 && "call next() before accessing field value");
159  auto len = get_len_and_skip();
160  protozero_assert(len % sizeof(T) == 0);
161  return std::make_pair(const_fixed_iterator<T>(m_data-len, m_data),
162  const_fixed_iterator<T>(m_data, m_data));
163  }
164 #endif
165 
166  template <typename T> inline T get_varint();
167  template <typename T> inline T get_svarint();
168 
169  inline pbf_length_type get_length() { return get_varint<pbf_length_type>(); }
170 
171  inline void skip_bytes(pbf_length_type len);
172 
173  inline pbf_length_type get_len_and_skip();
174 
175 public:
176 
186  inline pbf_reader(const char *data, size_t length) noexcept;
187 
197  inline pbf_reader(std::pair<const char *, size_t> data) noexcept;
198 
209  inline pbf_reader(const std::string& data) noexcept;
210 
215  inline pbf_reader() noexcept = default;
216 
218  inline pbf_reader(const pbf_reader&) noexcept = default;
219 
221  inline pbf_reader(pbf_reader&&) noexcept = default;
222 
224  inline pbf_reader& operator=(const pbf_reader& other) noexcept = default;
225 
227  inline pbf_reader& operator=(pbf_reader&& other) noexcept = default;
228 
229  inline ~pbf_reader() = default;
230 
235  inline operator bool() const noexcept;
236 
246  size_t length() const noexcept {
247  return size_t(m_end - m_data);
248  }
249 
265  inline bool next();
266 
292  inline bool next(pbf_tag_type tag);
293 
303  inline pbf_tag_type tag() const noexcept;
304 
320  inline pbf_wire_type wire_type() const noexcept;
321 
328  inline bool has_wire_type(pbf_wire_type type) const noexcept;
329 
336  inline void skip();
337 
339 
350  inline bool get_bool();
351 
359  inline int32_t get_enum() {
360  protozero_assert(has_wire_type(pbf_wire_type::varint) && "not a varint");
361  return get_varint<int32_t>();
362  }
363 
371  inline int32_t get_int32() {
372  protozero_assert(has_wire_type(pbf_wire_type::varint) && "not a varint");
373  return get_varint<int32_t>();
374  }
375 
383  inline int32_t get_sint32() {
384  protozero_assert(has_wire_type(pbf_wire_type::varint) && "not a varint");
385  return get_svarint<int32_t>();
386  }
387 
395  inline uint32_t get_uint32() {
396  protozero_assert(has_wire_type(pbf_wire_type::varint) && "not a varint");
397  return get_varint<uint32_t>();
398  }
399 
407  inline int64_t get_int64() {
408  protozero_assert(has_wire_type(pbf_wire_type::varint) && "not a varint");
409  return get_varint<int64_t>();
410  }
411 
419  inline int64_t get_sint64() {
420  protozero_assert(has_wire_type(pbf_wire_type::varint) && "not a varint");
421  return get_svarint<int64_t>();
422  }
423 
431  inline uint64_t get_uint64() {
432  protozero_assert(has_wire_type(pbf_wire_type::varint) && "not a varint");
433  return get_varint<uint64_t>();
434  }
435 
443  inline uint32_t get_fixed32();
444 
452  inline int32_t get_sfixed32();
453 
461  inline uint64_t get_fixed64();
462 
470  inline int64_t get_sfixed64();
471 
479  inline float get_float();
480 
488  inline double get_double();
489 
498  inline std::pair<const char*, pbf_length_type> get_data();
499 
507  inline std::string get_bytes();
508 
516  inline std::string get_string();
517 
526  return pbf_reader(get_data());
527  }
528 
530 
531 private:
532 
533  template <typename T>
534  class const_varint_iterator : public std::iterator<std::forward_iterator_tag, T> {
535 
536  protected:
537 
538  const char* m_data;
539  const char* m_end;
540 
541  public:
542 
543  const_varint_iterator() noexcept :
544  m_data(nullptr),
545  m_end(nullptr) {
546  }
547 
548  const_varint_iterator(const char *data, const char* end) noexcept :
549  m_data(data),
550  m_end(end) {
551  }
552 
553  const_varint_iterator(const const_varint_iterator&) noexcept = default;
554  const_varint_iterator(const_varint_iterator&&) noexcept = default;
555 
556  const_varint_iterator& operator=(const const_varint_iterator&) noexcept = default;
557  const_varint_iterator& operator=(const_varint_iterator&&) noexcept = default;
558 
559  ~const_varint_iterator() noexcept = default;
560 
561  T operator*() {
562  const char* d = m_data; // will be thrown away
563  return static_cast<T>(decode_varint(&d, m_end));
564  }
565 
566  const_varint_iterator& operator++() {
567  // Ignore the result, we call decode_varint() just for the
568  // side-effect of updating m_data.
569  decode_varint(&m_data, m_end);
570  return *this;
571  }
572 
573  const_varint_iterator operator++(int) {
574  const const_varint_iterator tmp(*this);
575  ++(*this);
576  return tmp;
577  }
578 
579  bool operator==(const const_varint_iterator& rhs) const noexcept {
580  return m_data == rhs.m_data && m_end == rhs.m_end;
581  }
582 
583  bool operator!=(const const_varint_iterator& rhs) const noexcept {
584  return !(*this == rhs);
585  }
586 
587  }; // class const_varint_iterator
588 
589  template <typename T>
590  class const_svarint_iterator : public const_varint_iterator<T> {
591 
592  public:
593 
594  const_svarint_iterator() noexcept :
595  const_varint_iterator<T>() {
596  }
597 
598  const_svarint_iterator(const char *data, const char* end) noexcept :
599  const_varint_iterator<T>(data, end) {
600  }
601 
602  const_svarint_iterator(const const_svarint_iterator&) = default;
603  const_svarint_iterator(const_svarint_iterator&&) = default;
604 
605  const_svarint_iterator& operator=(const const_svarint_iterator&) = default;
606  const_svarint_iterator& operator=(const_svarint_iterator&&) = default;
607 
608  ~const_svarint_iterator() = default;
609 
610  T operator*() {
611  const char* d = this->m_data; // will be thrown away
612  return static_cast<T>(decode_zigzag64(decode_varint(&d, this->m_end)));
613  }
614 
615  const_svarint_iterator& operator++() {
616  // Ignore the result, we call decode_varint() just for the
617  // side-effect of updating m_data.
618  decode_varint(&this->m_data, this->m_end);
619  return *this;
620  }
621 
622  const_svarint_iterator operator++(int) {
623  const const_svarint_iterator tmp(*this);
624  ++(*this);
625  return tmp;
626  }
627 
628  }; // class const_svarint_iterator
629 
630 public:
631 
633  typedef const_varint_iterator< int32_t> const_bool_iterator;
634 
636  typedef const_varint_iterator< int32_t> const_enum_iterator;
637 
639  typedef const_varint_iterator< int32_t> const_int32_iterator;
640 
642  typedef const_svarint_iterator<int32_t> const_sint32_iterator;
643 
645  typedef const_varint_iterator<uint32_t> const_uint32_iterator;
646 
648  typedef const_varint_iterator< int64_t> const_int64_iterator;
649 
651  typedef const_svarint_iterator<int64_t> const_sint64_iterator;
652 
654  typedef const_varint_iterator<uint64_t> const_uint64_iterator;
655 
657 
670  inline std::pair<pbf_reader::const_bool_iterator, pbf_reader::const_bool_iterator> get_packed_bool();
671 
681  inline std::pair<pbf_reader::const_enum_iterator, pbf_reader::const_enum_iterator> get_packed_enum();
682 
692  inline std::pair<pbf_reader::const_int32_iterator, pbf_reader::const_int32_iterator> get_packed_int32();
693 
703  inline std::pair<pbf_reader::const_sint32_iterator, pbf_reader::const_sint32_iterator> get_packed_sint32();
704 
714  inline std::pair<pbf_reader::const_uint32_iterator, pbf_reader::const_uint32_iterator> get_packed_uint32();
715 
725  inline std::pair<pbf_reader::const_int64_iterator, pbf_reader::const_int64_iterator> get_packed_int64();
726 
736  inline std::pair<pbf_reader::const_sint64_iterator, pbf_reader::const_sint64_iterator> get_packed_sint64();
737 
747  inline std::pair<pbf_reader::const_uint64_iterator, pbf_reader::const_uint64_iterator> get_packed_uint64();
748 
758  inline auto get_packed_fixed32() -> decltype(packed_fixed<uint32_t>()) {
759  return packed_fixed<uint32_t>();
760  }
761 
771  inline auto get_packed_sfixed32() -> decltype(packed_fixed<int32_t>()) {
772  return packed_fixed<int32_t>();
773  }
774 
784  inline auto get_packed_fixed64() -> decltype(packed_fixed<uint64_t>()) {
785  return packed_fixed<uint64_t>();
786  }
787 
797  inline auto get_packed_sfixed64() -> decltype(packed_fixed<int64_t>()) {
798  return packed_fixed<int64_t>();
799  }
800 
810  inline auto get_packed_float() -> decltype(packed_fixed<float>()) {
811  return packed_fixed<float>();
812  }
813 
823  inline auto get_packed_double() -> decltype(packed_fixed<double>()) {
824  return packed_fixed<double>();
825  }
826 
828 
829 }; // class pbf_reader
830 
831 pbf_reader::pbf_reader(const char *data, size_t length) noexcept
832  : m_data(data),
833  m_end(data + length),
834  m_wire_type(pbf_wire_type::unknown),
835  m_tag(0) {
836 }
837 
838 pbf_reader::pbf_reader(std::pair<const char *, size_t> data) noexcept
839  : m_data(data.first),
840  m_end(data.first + data.second),
841  m_wire_type(pbf_wire_type::unknown),
842  m_tag(0) {
843 }
844 
845 pbf_reader::pbf_reader(const std::string& data) noexcept
846  : m_data(data.data()),
847  m_end(data.data() + data.size()),
848  m_wire_type(pbf_wire_type::unknown),
849  m_tag(0) {
850 }
851 
852 pbf_reader::operator bool() const noexcept {
853  return m_data < m_end;
854 }
855 
857  if (m_data == m_end) {
858  return false;
859  }
860 
861  auto value = get_varint<uint32_t>();
862  m_tag = value >> 3;
863 
864  // tags 0 and 19000 to 19999 are not allowed as per
865  // https://developers.google.com/protocol-buffers/docs/proto
866  protozero_assert(((m_tag > 0 && m_tag < 19000) || (m_tag > 19999 && m_tag <= ((1 << 29) - 1))) && "tag out of range");
867 
868  m_wire_type = pbf_wire_type(value & 0x07);
869 // XXX do we want this check? or should it throw an exception?
870 // protozero_assert((m_wire_type <=2 || m_wire_type == 5) && "illegal wire type");
871  return true;
872 }
873 
874 bool pbf_reader::next(pbf_tag_type requested_tag) {
875  while (next()) {
876  if (m_tag == requested_tag) {
877  return true;
878  } else {
879  skip();
880  }
881  }
882  return false;
883 }
884 
885 pbf_tag_type pbf_reader::tag() const noexcept {
886  return m_tag;
887 }
888 
890  return m_wire_type;
891 }
892 
893 bool pbf_reader::has_wire_type(pbf_wire_type type) const noexcept {
894  return wire_type() == type;
895 }
896 
897 void pbf_reader::skip_bytes(pbf_length_type len) {
898  if (m_data + len > m_end) {
899  throw end_of_buffer_exception();
900  }
901  m_data += len;
902 
903 // In debug builds reset the tag to zero so that we can detect (some)
904 // wrong code.
905 #ifndef NDEBUG
906  m_tag = 0;
907 #endif
908 }
909 
911  protozero_assert(tag() != 0 && "call next() before calling skip()");
912  switch (wire_type()) {
913  case pbf_wire_type::varint:
914  (void)get_uint32(); // called for the side-effect of skipping value
915  break;
916  case pbf_wire_type::fixed64:
917  skip_bytes(8);
918  break;
919  case pbf_wire_type::length_delimited:
920  skip_bytes(get_length());
921  break;
922  case pbf_wire_type::fixed32:
923  skip_bytes(4);
924  break;
925  default:
927  }
928 }
929 
930 pbf_length_type pbf_reader::get_len_and_skip() {
931  auto len = get_length();
932  skip_bytes(len);
933  return len;
934 }
935 
936 template <typename T>
937 T pbf_reader::get_varint() {
938  return static_cast<T>(decode_varint(&m_data, m_end));
939 }
940 
941 template <typename T>
942 T pbf_reader::get_svarint() {
943  protozero_assert((has_wire_type(pbf_wire_type::varint) || has_wire_type(pbf_wire_type::length_delimited)) && "not a varint");
944  return static_cast<T>(decode_zigzag64(decode_varint(&m_data, m_end)));
945 }
946 
948  protozero_assert(tag() != 0 && "call next() before accessing field value");
949  protozero_assert(has_wire_type(pbf_wire_type::fixed32) && "not a 32-bit fixed");
950  return get_fixed<uint32_t>();
951 }
952 
954  protozero_assert(tag() != 0 && "call next() before accessing field value");
955  protozero_assert(has_wire_type(pbf_wire_type::fixed32) && "not a 32-bit fixed");
956  return get_fixed<int32_t>();
957 }
958 
960  protozero_assert(tag() != 0 && "call next() before accessing field value");
961  protozero_assert(has_wire_type(pbf_wire_type::fixed64) && "not a 64-bit fixed");
962  return get_fixed<uint64_t>();
963 }
964 
966  protozero_assert(tag() != 0 && "call next() before accessing field value");
967  protozero_assert(has_wire_type(pbf_wire_type::fixed64) && "not a 64-bit fixed");
968  return get_fixed<int64_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<float>();
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<double>();
981 }
982 
984  protozero_assert(tag() != 0 && "call next() before accessing field value");
985  protozero_assert(has_wire_type(pbf_wire_type::varint) && "not a varint");
986  protozero_assert((*m_data & 0x80) == 0 && "not a 1 byte varint");
987  skip_bytes(1);
988  return m_data[-1] != 0; // -1 okay because we incremented m_data the line before
989 }
990 
991 std::pair<const char*, pbf_length_type> pbf_reader::get_data() {
992  protozero_assert(tag() != 0 && "call next() before accessing field value");
993  protozero_assert(has_wire_type(pbf_wire_type::length_delimited) && "not of type string, bytes or message");
994  auto len = get_len_and_skip();
995  return std::make_pair(m_data-len, len);
996 }
997 
998 std::string pbf_reader::get_bytes() {
999  auto d = get_data();
1000  return std::string(d.first, d.second);
1001 }
1002 
1003 std::string pbf_reader::get_string() {
1004  return get_bytes();
1005 }
1006 
1007 std::pair<pbf_reader::const_bool_iterator, pbf_reader::const_bool_iterator> pbf_reader::get_packed_bool() {
1008  return get_packed_int32();
1009 }
1010 
1011 std::pair<pbf_reader::const_enum_iterator, pbf_reader::const_enum_iterator> pbf_reader::get_packed_enum() {
1012  return get_packed_int32();
1013 }
1014 
1015 std::pair<pbf_reader::const_int32_iterator, pbf_reader::const_int32_iterator> pbf_reader::get_packed_int32() {
1016  protozero_assert(tag() != 0 && "call next() before accessing field value");
1017  auto len = get_len_and_skip();
1018  return std::make_pair(pbf_reader::const_int32_iterator(m_data-len, m_data),
1019  pbf_reader::const_int32_iterator(m_data, m_data));
1020 }
1021 
1022 std::pair<pbf_reader::const_uint32_iterator, pbf_reader::const_uint32_iterator> pbf_reader::get_packed_uint32() {
1023  protozero_assert(tag() != 0 && "call next() before accessing field value");
1024  auto len = get_len_and_skip();
1025  return std::make_pair(pbf_reader::const_uint32_iterator(m_data-len, m_data),
1026  pbf_reader::const_uint32_iterator(m_data, m_data));
1027 }
1028 
1029 std::pair<pbf_reader::const_sint32_iterator, pbf_reader::const_sint32_iterator> pbf_reader::get_packed_sint32() {
1030  protozero_assert(tag() != 0 && "call next() before accessing field value");
1031  auto len = get_len_and_skip();
1032  return std::make_pair(pbf_reader::const_sint32_iterator(m_data-len, m_data),
1033  pbf_reader::const_sint32_iterator(m_data, m_data));
1034 }
1035 
1036 std::pair<pbf_reader::const_int64_iterator, pbf_reader::const_int64_iterator> pbf_reader::get_packed_int64() {
1037  protozero_assert(tag() != 0 && "call next() before accessing field value");
1038  auto len = get_len_and_skip();
1039  return std::make_pair(pbf_reader::const_int64_iterator(m_data-len, m_data),
1040  pbf_reader::const_int64_iterator(m_data, m_data));
1041 }
1042 
1043 std::pair<pbf_reader::const_uint64_iterator, pbf_reader::const_uint64_iterator> pbf_reader::get_packed_uint64() {
1044  protozero_assert(tag() != 0 && "call next() before accessing field value");
1045  auto len = get_len_and_skip();
1046  return std::make_pair(pbf_reader::const_uint64_iterator(m_data-len, m_data),
1047  pbf_reader::const_uint64_iterator(m_data, m_data));
1048 }
1049 
1050 std::pair<pbf_reader::const_sint64_iterator, pbf_reader::const_sint64_iterator> pbf_reader::get_packed_sint64() {
1051  protozero_assert(tag() != 0 && "call next() before accessing field value");
1052  auto len = get_len_and_skip();
1053  return std::make_pair(pbf_reader::const_sint64_iterator(m_data-len, m_data),
1054  pbf_reader::const_sint64_iterator(m_data, m_data));
1055 }
1056 
1057 } // end namespace protozero
1058 
1059 #endif // PROTOZERO_PBF_READER_HPP
int64_t get_sfixed64()
Definition: pbf_reader.hpp:965
uint32_t get_uint32()
Definition: pbf_reader.hpp:395
uint64_t get_fixed64()
Definition: pbf_reader.hpp:959
int32_t get_sfixed32()
Definition: pbf_reader.hpp:953
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:1029
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:991
bool has_wire_type(pbf_wire_type type) const noexcept
Definition: pbf_reader.hpp:893
void skip()
Definition: pbf_reader.hpp:910
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:1007
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:889
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:1015
#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
int32_t get_sint32()
Definition: pbf_reader.hpp:383
std::string get_bytes()
Definition: pbf_reader.hpp:998
double get_double()
Definition: pbf_reader.hpp:977
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:983
std::string get_string()
Definition: pbf_reader.hpp:1003
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:947
pbf_tag_type tag() const noexcept
Definition: pbf_reader.hpp:885
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:1036
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:971
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:1043
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:1011
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:1050
All parts of the protozero header-only library are in this namespace.
Definition: byteswap.hpp:15
std::pair< pbf_reader::const_uint32_iterator, pbf_reader::const_uint32_iterator > get_packed_uint32()
Definition: pbf_reader.hpp:1022