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  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:
874  break;
875  default:
877  }
878 
879  return true;
880 }
881 
882 bool pbf_reader::next(pbf_tag_type requested_tag) {
883  while (next()) {
884  if (m_tag == requested_tag) {
885  return true;
886  } else {
887  skip();
888  }
889  }
890  return false;
891 }
892 
893 pbf_tag_type pbf_reader::tag() const noexcept {
894  return m_tag;
895 }
896 
898  return m_wire_type;
899 }
900 
901 bool pbf_reader::has_wire_type(pbf_wire_type type) const noexcept {
902  return wire_type() == type;
903 }
904 
905 void pbf_reader::skip_bytes(pbf_length_type len) {
906  if (m_data + len > m_end) {
907  throw end_of_buffer_exception();
908  }
909  m_data += len;
910 
911 // In debug builds reset the tag to zero so that we can detect (some)
912 // wrong code.
913 #ifndef NDEBUG
914  m_tag = 0;
915 #endif
916 }
917 
919  protozero_assert(tag() != 0 && "call next() before calling skip()");
920  switch (wire_type()) {
921  case pbf_wire_type::varint:
922  (void)get_uint32(); // called for the side-effect of skipping value
923  break;
924  case pbf_wire_type::fixed64:
925  skip_bytes(8);
926  break;
927  case pbf_wire_type::length_delimited:
928  skip_bytes(get_length());
929  break;
930  case pbf_wire_type::fixed32:
931  skip_bytes(4);
932  break;
933  default:
935  }
936 }
937 
938 pbf_length_type pbf_reader::get_len_and_skip() {
939  auto len = get_length();
940  skip_bytes(len);
941  return len;
942 }
943 
944 template <typename T>
945 T pbf_reader::get_varint() {
946  return static_cast<T>(decode_varint(&m_data, m_end));
947 }
948 
949 template <typename T>
950 T pbf_reader::get_svarint() {
951  protozero_assert((has_wire_type(pbf_wire_type::varint) || has_wire_type(pbf_wire_type::length_delimited)) && "not a varint");
952  return static_cast<T>(decode_zigzag64(decode_varint(&m_data, m_end)));
953 }
954 
956  protozero_assert(tag() != 0 && "call next() before accessing field value");
957  protozero_assert(has_wire_type(pbf_wire_type::fixed32) && "not a 32-bit fixed");
958  return get_fixed<uint32_t>();
959 }
960 
962  protozero_assert(tag() != 0 && "call next() before accessing field value");
963  protozero_assert(has_wire_type(pbf_wire_type::fixed32) && "not a 32-bit fixed");
964  return get_fixed<int32_t>();
965 }
966 
968  protozero_assert(tag() != 0 && "call next() before accessing field value");
969  protozero_assert(has_wire_type(pbf_wire_type::fixed64) && "not a 64-bit fixed");
970  return get_fixed<uint64_t>();
971 }
972 
974  protozero_assert(tag() != 0 && "call next() before accessing field value");
975  protozero_assert(has_wire_type(pbf_wire_type::fixed64) && "not a 64-bit fixed");
976  return get_fixed<int64_t>();
977 }
978 
980  protozero_assert(tag() != 0 && "call next() before accessing field value");
981  protozero_assert(has_wire_type(pbf_wire_type::fixed32) && "not a 32-bit fixed");
982  return get_fixed<float>();
983 }
984 
986  protozero_assert(tag() != 0 && "call next() before accessing field value");
987  protozero_assert(has_wire_type(pbf_wire_type::fixed64) && "not a 64-bit fixed");
988  return get_fixed<double>();
989 }
990 
992  protozero_assert(tag() != 0 && "call next() before accessing field value");
993  protozero_assert(has_wire_type(pbf_wire_type::varint) && "not a varint");
994  protozero_assert((*m_data & 0x80) == 0 && "not a 1 byte varint");
995  skip_bytes(1);
996  return m_data[-1] != 0; // -1 okay because we incremented m_data the line before
997 }
998 
999 std::pair<const char*, pbf_length_type> pbf_reader::get_data() {
1000  protozero_assert(tag() != 0 && "call next() before accessing field value");
1001  protozero_assert(has_wire_type(pbf_wire_type::length_delimited) && "not of type string, bytes or message");
1002  auto len = get_len_and_skip();
1003  return std::make_pair(m_data-len, len);
1004 }
1005 
1006 std::string pbf_reader::get_bytes() {
1007  auto d = get_data();
1008  return std::string(d.first, d.second);
1009 }
1010 
1011 std::string pbf_reader::get_string() {
1012  return get_bytes();
1013 }
1014 
1015 std::pair<pbf_reader::const_bool_iterator, pbf_reader::const_bool_iterator> pbf_reader::get_packed_bool() {
1016  return get_packed_int32();
1017 }
1018 
1019 std::pair<pbf_reader::const_enum_iterator, pbf_reader::const_enum_iterator> pbf_reader::get_packed_enum() {
1020  return get_packed_int32();
1021 }
1022 
1023 std::pair<pbf_reader::const_int32_iterator, pbf_reader::const_int32_iterator> pbf_reader::get_packed_int32() {
1024  protozero_assert(tag() != 0 && "call next() before accessing field value");
1025  auto len = get_len_and_skip();
1026  return std::make_pair(pbf_reader::const_int32_iterator(m_data-len, m_data),
1027  pbf_reader::const_int32_iterator(m_data, m_data));
1028 }
1029 
1030 std::pair<pbf_reader::const_uint32_iterator, pbf_reader::const_uint32_iterator> pbf_reader::get_packed_uint32() {
1031  protozero_assert(tag() != 0 && "call next() before accessing field value");
1032  auto len = get_len_and_skip();
1033  return std::make_pair(pbf_reader::const_uint32_iterator(m_data-len, m_data),
1034  pbf_reader::const_uint32_iterator(m_data, m_data));
1035 }
1036 
1037 std::pair<pbf_reader::const_sint32_iterator, pbf_reader::const_sint32_iterator> pbf_reader::get_packed_sint32() {
1038  protozero_assert(tag() != 0 && "call next() before accessing field value");
1039  auto len = get_len_and_skip();
1040  return std::make_pair(pbf_reader::const_sint32_iterator(m_data-len, m_data),
1041  pbf_reader::const_sint32_iterator(m_data, m_data));
1042 }
1043 
1044 std::pair<pbf_reader::const_int64_iterator, pbf_reader::const_int64_iterator> pbf_reader::get_packed_int64() {
1045  protozero_assert(tag() != 0 && "call next() before accessing field value");
1046  auto len = get_len_and_skip();
1047  return std::make_pair(pbf_reader::const_int64_iterator(m_data-len, m_data),
1048  pbf_reader::const_int64_iterator(m_data, m_data));
1049 }
1050 
1051 std::pair<pbf_reader::const_uint64_iterator, pbf_reader::const_uint64_iterator> pbf_reader::get_packed_uint64() {
1052  protozero_assert(tag() != 0 && "call next() before accessing field value");
1053  auto len = get_len_and_skip();
1054  return std::make_pair(pbf_reader::const_uint64_iterator(m_data-len, m_data),
1055  pbf_reader::const_uint64_iterator(m_data, m_data));
1056 }
1057 
1058 std::pair<pbf_reader::const_sint64_iterator, pbf_reader::const_sint64_iterator> pbf_reader::get_packed_sint64() {
1059  protozero_assert(tag() != 0 && "call next() before accessing field value");
1060  auto len = get_len_and_skip();
1061  return std::make_pair(pbf_reader::const_sint64_iterator(m_data-len, m_data),
1062  pbf_reader::const_sint64_iterator(m_data, m_data));
1063 }
1064 
1065 } // end namespace protozero
1066 
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