protozero  1.6.8
Minimalistic protocol buffer decoder and encoder in C++.
pbf_writer.hpp
Go to the documentation of this file.
1 #ifndef PROTOZERO_PBF_WRITER_HPP
2 #define PROTOZERO_PBF_WRITER_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 <protozero/config.hpp>
20 #include <protozero/data_view.hpp>
21 #include <protozero/types.hpp>
22 #include <protozero/varint.hpp>
23 
24 #if PROTOZERO_BYTE_ORDER != PROTOZERO_LITTLE_ENDIAN
25 # include <protozero/byteswap.hpp>
26 #endif
27 
28 #include <cstddef>
29 #include <cstdint>
30 #include <cstring>
31 #include <initializer_list>
32 #include <iterator>
33 #include <limits>
34 #include <string>
35 #include <utility>
36 
37 namespace protozero {
38 
39 namespace detail {
40 
41  template <typename T> class packed_field_varint;
42  template <typename T> class packed_field_svarint;
43  template <typename T> class packed_field_fixed;
44 
45 } // end namespace detail
46 
53 class pbf_writer {
54 
55  // A pointer to a string buffer holding the data already written to the
56  // PBF message. For default constructed writers or writers that have been
57  // rolled back, this is a nullptr.
58  std::string* m_data = nullptr;
59 
60  // A pointer to a parent writer object if this is a submessage. If this
61  // is a top-level writer, it is a nullptr.
62  pbf_writer* m_parent_writer = nullptr;
63 
64  // This is usually 0. If there is an open submessage, this is set in the
65  // parent to the rollback position, ie. the last position before the
66  // submessage was started. This is the position where the header of the
67  // submessage starts.
68  std::size_t m_rollback_pos = 0;
69 
70  // This is usually 0. If there is an open submessage, this is set in the
71  // parent to the position where the data of the submessage is written to.
72  std::size_t m_pos = 0;
73 
74  void add_varint(uint64_t value) {
75  protozero_assert(m_pos == 0 && "you can't add fields to a parent pbf_writer if there is an existing pbf_writer for a submessage");
76  protozero_assert(m_data);
77  write_varint(std::back_inserter(*m_data), value);
78  }
79 
80  void add_field(pbf_tag_type tag, pbf_wire_type type) {
81  protozero_assert(((tag > 0 && tag < 19000) || (tag > 19999 && tag <= ((1U << 29U) - 1))) && "tag out of range");
82  const uint32_t b = (tag << 3U) | uint32_t(type);
83  add_varint(b);
84  }
85 
86  void add_tagged_varint(pbf_tag_type tag, uint64_t value) {
87  add_field(tag, pbf_wire_type::varint);
88  add_varint(value);
89  }
90 
91  template <typename T>
92  void add_fixed(T value) {
93  protozero_assert(m_pos == 0 && "you can't add fields to a parent pbf_writer if there is an existing pbf_writer for a submessage");
94  protozero_assert(m_data);
95 #if PROTOZERO_BYTE_ORDER != PROTOZERO_LITTLE_ENDIAN
96  byteswap_inplace(&value);
97 #endif
98  m_data->append(reinterpret_cast<const char*>(&value), sizeof(T));
99  }
100 
101  template <typename T, typename It>
102  void add_packed_fixed(pbf_tag_type tag, It first, It last, std::input_iterator_tag /*unused*/) {
103  if (first == last) {
104  return;
105  }
106 
107  pbf_writer sw{*this, tag};
108 
109  while (first != last) {
110  sw.add_fixed<T>(*first++);
111  }
112  }
113 
114  template <typename T, typename It>
115  void add_packed_fixed(pbf_tag_type tag, It first, It last, std::forward_iterator_tag /*unused*/) {
116  if (first == last) {
117  return;
118  }
119 
120  const auto length = std::distance(first, last);
121  add_length_varint(tag, sizeof(T) * pbf_length_type(length));
122  reserve(sizeof(T) * std::size_t(length));
123 
124  while (first != last) {
125  add_fixed<T>(*first++);
126  }
127  }
128 
129  template <typename It>
130  void add_packed_varint(pbf_tag_type tag, It first, It last) {
131  if (first == last) {
132  return;
133  }
134 
135  pbf_writer sw{*this, tag};
136 
137  while (first != last) {
138  sw.add_varint(uint64_t(*first++));
139  }
140  }
141 
142  template <typename It>
143  void add_packed_svarint(pbf_tag_type tag, It first, It last) {
144  if (first == last) {
145  return;
146  }
147 
148  pbf_writer sw{*this, tag};
149 
150  while (first != last) {
151  sw.add_varint(encode_zigzag64(*first++));
152  }
153  }
154 
155  // The number of bytes to reserve for the varint holding the length of
156  // a length-delimited field. The length has to fit into pbf_length_type,
157  // and a varint needs 8 bit for every 7 bit.
158  enum constant_reserve_bytes : int {
159  reserve_bytes = sizeof(pbf_length_type) * 8 / 7 + 1
160  };
161 
162  // If m_rollpack_pos is set to this special value, it means that when
163  // the submessage is closed, nothing needs to be done, because the length
164  // of the submessage has already been written correctly.
165  enum constant_size_is_known : std::size_t {
166  size_is_known = std::numeric_limits<std::size_t>::max()
167  };
168 
169  void open_submessage(pbf_tag_type tag, std::size_t size) {
170  protozero_assert(m_pos == 0);
171  protozero_assert(m_data);
172  if (size == 0) {
173  m_rollback_pos = m_data->size();
174  add_field(tag, pbf_wire_type::length_delimited);
175  m_data->append(std::size_t(reserve_bytes), '\0');
176  } else {
177  m_rollback_pos = size_is_known;
178  add_length_varint(tag, pbf_length_type(size));
179  reserve(size);
180  }
181  m_pos = m_data->size();
182  }
183 
184  void rollback_submessage() {
185  protozero_assert(m_pos != 0);
186  protozero_assert(m_rollback_pos != size_is_known);
187  protozero_assert(m_data);
188  m_data->resize(m_rollback_pos);
189  m_pos = 0;
190  }
191 
192  void commit_submessage() {
193  protozero_assert(m_pos != 0);
194  protozero_assert(m_rollback_pos != size_is_known);
195  protozero_assert(m_data);
196  const auto length = pbf_length_type(m_data->size() - m_pos);
197 
198  protozero_assert(m_data->size() >= m_pos - reserve_bytes);
199  const auto n = write_varint(m_data->begin() + int64_t(m_pos) - reserve_bytes, length);
200 
201  m_data->erase(m_data->begin() + int64_t(m_pos) - reserve_bytes + n, m_data->begin() + int64_t(m_pos));
202  m_pos = 0;
203  }
204 
205  void close_submessage() {
206  protozero_assert(m_data);
207  if (m_pos == 0 || m_rollback_pos == size_is_known) {
208  return;
209  }
210  if (m_data->size() - m_pos == 0) {
211  rollback_submessage();
212  } else {
213  commit_submessage();
214  }
215  }
216 
217  void add_length_varint(pbf_tag_type tag, pbf_length_type length) {
218  add_field(tag, pbf_wire_type::length_delimited);
219  add_varint(length);
220  }
221 
222 public:
223 
229  explicit pbf_writer(std::string& data) noexcept :
230  m_data{&data} {
231  }
232 
237  pbf_writer() noexcept = default;
238 
249  pbf_writer(pbf_writer& parent_writer, pbf_tag_type tag, std::size_t size=0) :
250  m_data{parent_writer.m_data},
251  m_parent_writer{&parent_writer} {
252  m_parent_writer->open_submessage(tag, size);
253  }
254 
256  pbf_writer(const pbf_writer&) = delete;
257 
259  pbf_writer& operator=(const pbf_writer&) = delete;
260 
265  pbf_writer(pbf_writer&& other) noexcept :
266  m_data{other.m_data},
267  m_parent_writer{other.m_parent_writer},
268  m_rollback_pos{other.m_rollback_pos},
269  m_pos{other.m_pos} {
270  other.m_data = nullptr;
271  other.m_parent_writer = nullptr;
272  other.m_rollback_pos = 0;
273  other.m_pos = 0;
274  }
275 
280  pbf_writer& operator=(pbf_writer&& other) noexcept {
281  m_data = other.m_data;
282  m_parent_writer = other.m_parent_writer;
283  m_rollback_pos = other.m_rollback_pos;
284  m_pos = other.m_pos;
285  other.m_data = nullptr;
286  other.m_parent_writer = nullptr;
287  other.m_rollback_pos = 0;
288  other.m_pos = 0;
289  return *this;
290  }
291 
292  ~pbf_writer() noexcept {
293  try {
294  if (m_parent_writer != nullptr) {
295  m_parent_writer->close_submessage();
296  }
297  } catch (...) {
298  // This try/catch is used to make the destructor formally noexcept.
299  // close_submessage() is not noexcept, but will not throw the way
300  // it is called here, so we are good. But to be paranoid, call...
301  std::terminate();
302  }
303  }
304 
310  bool valid() const noexcept {
311  return m_data != nullptr;
312  }
313 
319  void swap(pbf_writer& other) noexcept {
320  using std::swap;
321  swap(m_data, other.m_data);
322  swap(m_parent_writer, other.m_parent_writer);
323  swap(m_rollback_pos, other.m_rollback_pos);
324  swap(m_pos, other.m_pos);
325  }
326 
335  void reserve(std::size_t size) {
336  protozero_assert(m_data);
337  m_data->reserve(m_data->size() + size);
338  }
339 
348  void commit() {
349  protozero_assert(m_parent_writer && "you can't call commit() on a pbf_writer without a parent");
350  protozero_assert(m_pos == 0 && "you can't call commit() on a pbf_writer that has an open nested submessage");
351  m_parent_writer->close_submessage();
352  m_parent_writer = nullptr;
353  m_data = nullptr;
354  }
355 
364  void rollback() {
365  protozero_assert(m_parent_writer && "you can't call rollback() on a pbf_writer without a parent");
366  protozero_assert(m_pos == 0 && "you can't call rollback() on a pbf_writer that has an open nested submessage");
367  m_parent_writer->rollback_submessage();
368  m_parent_writer = nullptr;
369  m_data = nullptr;
370  }
371 
373 
383  void add_bool(pbf_tag_type tag, bool value) {
384  add_field(tag, pbf_wire_type::varint);
385  protozero_assert(m_pos == 0 && "you can't add fields to a parent pbf_writer if there is an existing pbf_writer for a submessage");
386  protozero_assert(m_data);
387  m_data->append(1, char(value));
388  }
389 
396  void add_enum(pbf_tag_type tag, int32_t value) {
397  add_tagged_varint(tag, uint64_t(value));
398  }
399 
406  void add_int32(pbf_tag_type tag, int32_t value) {
407  add_tagged_varint(tag, uint64_t(value));
408  }
409 
416  void add_sint32(pbf_tag_type tag, int32_t value) {
417  add_tagged_varint(tag, encode_zigzag32(value));
418  }
419 
426  void add_uint32(pbf_tag_type tag, uint32_t value) {
427  add_tagged_varint(tag, value);
428  }
429 
436  void add_int64(pbf_tag_type tag, int64_t value) {
437  add_tagged_varint(tag, uint64_t(value));
438  }
439 
446  void add_sint64(pbf_tag_type tag, int64_t value) {
447  add_tagged_varint(tag, encode_zigzag64(value));
448  }
449 
456  void add_uint64(pbf_tag_type tag, uint64_t value) {
457  add_tagged_varint(tag, value);
458  }
459 
466  void add_fixed32(pbf_tag_type tag, uint32_t value) {
467  add_field(tag, pbf_wire_type::fixed32);
468  add_fixed<uint32_t>(value);
469  }
470 
477  void add_sfixed32(pbf_tag_type tag, int32_t value) {
478  add_field(tag, pbf_wire_type::fixed32);
479  add_fixed<int32_t>(value);
480  }
481 
488  void add_fixed64(pbf_tag_type tag, uint64_t value) {
489  add_field(tag, pbf_wire_type::fixed64);
490  add_fixed<uint64_t>(value);
491  }
492 
499  void add_sfixed64(pbf_tag_type tag, int64_t value) {
500  add_field(tag, pbf_wire_type::fixed64);
501  add_fixed<int64_t>(value);
502  }
503 
510  void add_float(pbf_tag_type tag, float value) {
511  add_field(tag, pbf_wire_type::fixed32);
512  add_fixed<float>(value);
513  }
514 
521  void add_double(pbf_tag_type tag, double value) {
522  add_field(tag, pbf_wire_type::fixed64);
523  add_fixed<double>(value);
524  }
525 
533  void add_bytes(pbf_tag_type tag, const char* value, std::size_t size) {
534  protozero_assert(m_pos == 0 && "you can't add fields to a parent pbf_writer if there is an existing pbf_writer for a submessage");
535  protozero_assert(m_data);
536  protozero_assert(size <= std::numeric_limits<pbf_length_type>::max());
537  add_length_varint(tag, pbf_length_type(size));
538  m_data->append(value, size);
539  }
540 
547  void add_bytes(pbf_tag_type tag, const data_view& value) {
548  add_bytes(tag, value.data(), value.size());
549  }
550 
557  void add_bytes(pbf_tag_type tag, const std::string& value) {
558  add_bytes(tag, value.data(), value.size());
559  }
560 
568  void add_bytes(pbf_tag_type tag, const char* value) {
569  add_bytes(tag, value, std::strlen(value));
570  }
571 
591  template <typename... Ts>
592  void add_bytes_vectored(pbf_tag_type tag, Ts&&... values) {
593  protozero_assert(m_pos == 0 && "you can't add fields to a parent pbf_writer if there is an existing pbf_writer for a submessage");
594  protozero_assert(m_data);
595  size_t sum_size = 0;
596  (void)std::initializer_list<size_t>{sum_size += values.size()...};
597  protozero_assert(sum_size <= std::numeric_limits<pbf_length_type>::max());
598  add_length_varint(tag, pbf_length_type(sum_size));
599  m_data->reserve(m_data->size() + sum_size);
600  (void)std::initializer_list<int>{(m_data->append(values.data(), values.size()), 0)...};
601  }
602 
610  void add_string(pbf_tag_type tag, const char* value, std::size_t size) {
611  add_bytes(tag, value, size);
612  }
613 
620  void add_string(pbf_tag_type tag, const data_view& value) {
621  add_bytes(tag, value.data(), value.size());
622  }
623 
630  void add_string(pbf_tag_type tag, const std::string& value) {
631  add_bytes(tag, value.data(), value.size());
632  }
633 
641  void add_string(pbf_tag_type tag, const char* value) {
642  add_bytes(tag, value, std::strlen(value));
643  }
644 
652  void add_message(pbf_tag_type tag, const char* value, std::size_t size) {
653  add_bytes(tag, value, size);
654  }
655 
662  void add_message(pbf_tag_type tag, const data_view& value) {
663  add_bytes(tag, value.data(), value.size());
664  }
665 
672  void add_message(pbf_tag_type tag, const std::string& value) {
673  add_bytes(tag, value.data(), value.size());
674  }
675 
677 
679 
692  template <typename InputIterator>
693  void add_packed_bool(pbf_tag_type tag, InputIterator first, InputIterator last) {
694  add_packed_varint(tag, first, last);
695  }
696 
706  template <typename InputIterator>
707  void add_packed_enum(pbf_tag_type tag, InputIterator first, InputIterator last) {
708  add_packed_varint(tag, first, last);
709  }
710 
720  template <typename InputIterator>
721  void add_packed_int32(pbf_tag_type tag, InputIterator first, InputIterator last) {
722  add_packed_varint(tag, first, last);
723  }
724 
734  template <typename InputIterator>
735  void add_packed_sint32(pbf_tag_type tag, InputIterator first, InputIterator last) {
736  add_packed_svarint(tag, first, last);
737  }
738 
748  template <typename InputIterator>
749  void add_packed_uint32(pbf_tag_type tag, InputIterator first, InputIterator last) {
750  add_packed_varint(tag, first, last);
751  }
752 
762  template <typename InputIterator>
763  void add_packed_int64(pbf_tag_type tag, InputIterator first, InputIterator last) {
764  add_packed_varint(tag, first, last);
765  }
766 
776  template <typename InputIterator>
777  void add_packed_sint64(pbf_tag_type tag, InputIterator first, InputIterator last) {
778  add_packed_svarint(tag, first, last);
779  }
780 
790  template <typename InputIterator>
791  void add_packed_uint64(pbf_tag_type tag, InputIterator first, InputIterator last) {
792  add_packed_varint(tag, first, last);
793  }
794 
812  template <typename ValueType, typename InputIterator>
813  void add_packed_fixed(pbf_tag_type tag, InputIterator first, InputIterator last) {
814  static_assert(std::is_same<ValueType, uint32_t>::value ||
815  std::is_same<ValueType, int32_t>::value ||
816  std::is_same<ValueType, int64_t>::value ||
817  std::is_same<ValueType, uint64_t>::value ||
818  std::is_same<ValueType, double>::value ||
819  std::is_same<ValueType, float>::value, "Only some types are allowed");
820  add_packed_fixed<ValueType, InputIterator>(tag, first, last,
821  typename std::iterator_traits<InputIterator>::iterator_category{});
822  }
823 
833  template <typename InputIterator>
834  void add_packed_fixed32(pbf_tag_type tag, InputIterator first, InputIterator last) {
835  add_packed_fixed<uint32_t, InputIterator>(tag, first, last,
836  typename std::iterator_traits<InputIterator>::iterator_category{});
837  }
838 
848  template <typename InputIterator>
849  void add_packed_sfixed32(pbf_tag_type tag, InputIterator first, InputIterator last) {
850  add_packed_fixed<int32_t, InputIterator>(tag, first, last,
851  typename std::iterator_traits<InputIterator>::iterator_category{});
852  }
853 
863  template <typename InputIterator>
864  void add_packed_fixed64(pbf_tag_type tag, InputIterator first, InputIterator last) {
865  add_packed_fixed<uint64_t, InputIterator>(tag, first, last,
866  typename std::iterator_traits<InputIterator>::iterator_category{});
867  }
868 
878  template <typename InputIterator>
879  void add_packed_sfixed64(pbf_tag_type tag, InputIterator first, InputIterator last) {
880  add_packed_fixed<int64_t, InputIterator>(tag, first, last,
881  typename std::iterator_traits<InputIterator>::iterator_category{});
882  }
883 
893  template <typename InputIterator>
894  void add_packed_float(pbf_tag_type tag, InputIterator first, InputIterator last) {
895  add_packed_fixed<float, InputIterator>(tag, first, last,
896  typename std::iterator_traits<InputIterator>::iterator_category{});
897  }
898 
908  template <typename InputIterator>
909  void add_packed_double(pbf_tag_type tag, InputIterator first, InputIterator last) {
910  add_packed_fixed<double, InputIterator>(tag, first, last,
911  typename std::iterator_traits<InputIterator>::iterator_category{});
912  }
913 
915 
916  template <typename T> friend class detail::packed_field_varint;
917  template <typename T> friend class detail::packed_field_svarint;
918  template <typename T> friend class detail::packed_field_fixed;
919 
920 }; // class pbf_writer
921 
928 inline void swap(pbf_writer& lhs, pbf_writer& rhs) noexcept {
929  lhs.swap(rhs);
930 }
931 
932 namespace detail {
933 
934  class packed_field {
935 
936  protected:
937 
938  pbf_writer m_writer{}; // NOLINT(misc-non-private-member-variables-in-classes, cppcoreguidelines-non-private-member-variables-in-classes,-warnings-as-errors)
939 
940  public:
941 
942  packed_field(const packed_field&) = delete;
943  packed_field& operator=(const packed_field&) = delete;
944 
945  packed_field(packed_field&&) noexcept = default;
946  packed_field& operator=(packed_field&&) noexcept = default;
947 
948  packed_field() = default;
949 
950  packed_field(pbf_writer& parent_writer, pbf_tag_type tag) :
951  m_writer{parent_writer, tag} {
952  }
953 
954  packed_field(pbf_writer& parent_writer, pbf_tag_type tag, std::size_t size) :
955  m_writer{parent_writer, tag, size} {
956  }
957 
958  ~packed_field() noexcept = default;
959 
960  bool valid() const noexcept {
961  return m_writer.valid();
962  }
963 
964  void commit() {
965  m_writer.commit();
966  }
967 
968  void rollback() {
969  m_writer.rollback();
970  }
971 
972  }; // class packed_field
973 
974  template <typename T>
975  class packed_field_fixed : public packed_field {
976 
977  public:
978 
979  packed_field_fixed() :
980  packed_field{} {
981  }
982 
983  template <typename P>
984  packed_field_fixed(pbf_writer& parent_writer, P tag) :
985  packed_field{parent_writer, static_cast<pbf_tag_type>(tag)} {
986  }
987 
988  template <typename P>
989  packed_field_fixed(pbf_writer& parent_writer, P tag, std::size_t size) :
990  packed_field{parent_writer, static_cast<pbf_tag_type>(tag), size * sizeof(T)} {
991  }
992 
993  void add_element(T value) {
994  m_writer.add_fixed<T>(value);
995  }
996 
997  }; // class packed_field_fixed
998 
999  template <typename T>
1000  class packed_field_varint : public packed_field {
1001 
1002  public:
1003 
1004  packed_field_varint() :
1005  packed_field{} {
1006  }
1007 
1008  template <typename P>
1009  packed_field_varint(pbf_writer& parent_writer, P tag) :
1010  packed_field{parent_writer, static_cast<pbf_tag_type>(tag)} {
1011  }
1012 
1013  void add_element(T value) {
1014  m_writer.add_varint(uint64_t(value));
1015  }
1016 
1017  }; // class packed_field_varint
1018 
1019  template <typename T>
1020  class packed_field_svarint : public packed_field {
1021 
1022  public:
1023 
1024  packed_field_svarint() :
1025  packed_field{} {
1026  }
1027 
1028  template <typename P>
1029  packed_field_svarint(pbf_writer& parent_writer, P tag) :
1030  packed_field{parent_writer, static_cast<pbf_tag_type>(tag)} {
1031  }
1032 
1033  void add_element(T value) {
1034  m_writer.add_varint(encode_zigzag64(value));
1035  }
1036 
1037  }; // class packed_field_svarint
1038 
1039 } // end namespace detail
1040 
1042 using packed_field_bool = detail::packed_field_varint<bool>;
1043 
1045 using packed_field_enum = detail::packed_field_varint<int32_t>;
1046 
1048 using packed_field_int32 = detail::packed_field_varint<int32_t>;
1049 
1051 using packed_field_sint32 = detail::packed_field_svarint<int32_t>;
1052 
1054 using packed_field_uint32 = detail::packed_field_varint<uint32_t>;
1055 
1057 using packed_field_int64 = detail::packed_field_varint<int64_t>;
1058 
1060 using packed_field_sint64 = detail::packed_field_svarint<int64_t>;
1061 
1063 using packed_field_uint64 = detail::packed_field_varint<uint64_t>;
1064 
1066 using packed_field_fixed32 = detail::packed_field_fixed<uint32_t>;
1067 
1069 using packed_field_sfixed32 = detail::packed_field_fixed<int32_t>;
1070 
1072 using packed_field_fixed64 = detail::packed_field_fixed<uint64_t>;
1073 
1075 using packed_field_sfixed64 = detail::packed_field_fixed<int64_t>;
1076 
1078 using packed_field_float = detail::packed_field_fixed<float>;
1079 
1081 using packed_field_double = detail::packed_field_fixed<double>;
1082 
1083 } // end namespace protozero
1084 
1085 #endif // PROTOZERO_PBF_WRITER_HPP
protozero::pbf_writer::add_bytes
void add_bytes(pbf_tag_type tag, const data_view &value)
Definition: pbf_writer.hpp:547
protozero::pbf_writer::add_packed_int32
void add_packed_int32(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: pbf_writer.hpp:721
protozero::pbf_writer::add_packed_sfixed32
void add_packed_sfixed32(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: pbf_writer.hpp:849
protozero::pbf_writer::pbf_writer
pbf_writer(pbf_writer &&other) noexcept
Definition: pbf_writer.hpp:265
protozero::pbf_writer::add_bytes
void add_bytes(pbf_tag_type tag, const std::string &value)
Definition: pbf_writer.hpp:557
protozero::pbf_wire_type
pbf_wire_type
Definition: types.hpp:40
protozero::swap
void swap(pbf_writer &lhs, pbf_writer &rhs) noexcept
Definition: pbf_writer.hpp:928
protozero::pbf_writer::valid
bool valid() const noexcept
Definition: pbf_writer.hpp:310
config.hpp
Contains macro checks for different configurations.
protozero::packed_field_sint64
detail::packed_field_svarint< int64_t > packed_field_sint64
Class for generating packed repeated sint64 fields.
Definition: pbf_writer.hpp:1060
protozero::pbf_writer::add_bool
void add_bool(pbf_tag_type tag, bool value)
Definition: pbf_writer.hpp:383
protozero::pbf_writer::swap
void swap(pbf_writer &other) noexcept
Definition: pbf_writer.hpp:319
protozero
All parts of the protozero header-only library are in this namespace.
Definition: byteswap.hpp:23
byteswap.hpp
Contains functions to swap bytes in values (for different endianness).
types.hpp
Contains the declaration of low-level types used in the pbf format.
protozero::pbf_writer::add_double
void add_double(pbf_tag_type tag, double value)
Definition: pbf_writer.hpp:521
protozero::packed_field_uint64
detail::packed_field_varint< uint64_t > packed_field_uint64
Class for generating packed repeated uint64 fields.
Definition: pbf_writer.hpp:1063
protozero::packed_field_sfixed64
detail::packed_field_fixed< int64_t > packed_field_sfixed64
Class for generating packed repeated sfixed64 fields.
Definition: pbf_writer.hpp:1075
protozero::packed_field_sint32
detail::packed_field_svarint< int32_t > packed_field_sint32
Class for generating packed repeated sint32 fields.
Definition: pbf_writer.hpp:1051
protozero::pbf_writer::add_packed_int64
void add_packed_int64(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: pbf_writer.hpp:763
protozero::pbf_writer::add_fixed32
void add_fixed32(pbf_tag_type tag, uint32_t value)
Definition: pbf_writer.hpp:466
protozero::pbf_writer::add_packed_sfixed64
void add_packed_sfixed64(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: pbf_writer.hpp:879
protozero::pbf_writer::add_string
void add_string(pbf_tag_type tag, const data_view &value)
Definition: pbf_writer.hpp:620
protozero::pbf_writer::add_sfixed32
void add_sfixed32(pbf_tag_type tag, int32_t value)
Definition: pbf_writer.hpp:477
protozero::data_view::size
constexpr std::size_t size() const noexcept
Return length of data in bytes.
Definition: data_view.hpp:99
protozero::packed_field_double
detail::packed_field_fixed< double > packed_field_double
Class for generating packed repeated double fields.
Definition: pbf_writer.hpp:1081
protozero::pbf_writer::operator=
pbf_writer & operator=(pbf_writer &&other) noexcept
Definition: pbf_writer.hpp:280
protozero::packed_field_enum
detail::packed_field_varint< int32_t > packed_field_enum
Class for generating packed repeated enum fields.
Definition: pbf_writer.hpp:1045
protozero::encode_zigzag64
constexpr uint64_t encode_zigzag64(int64_t value) noexcept
Definition: varint.hpp:185
protozero::pbf_writer::pbf_writer
pbf_writer() noexcept=default
protozero::pbf_writer::add_message
void add_message(pbf_tag_type tag, const std::string &value)
Definition: pbf_writer.hpp:672
protozero::pbf_writer::add_bytes
void add_bytes(pbf_tag_type tag, const char *value, std::size_t size)
Definition: pbf_writer.hpp:533
protozero::pbf_writer::add_sfixed64
void add_sfixed64(pbf_tag_type tag, int64_t value)
Definition: pbf_writer.hpp:499
protozero::write_varint
int write_varint(T data, uint64_t value)
Definition: varint.hpp:145
protozero::pbf_writer::pbf_writer
pbf_writer(std::string &data) noexcept
Definition: pbf_writer.hpp:229
protozero::packed_field_float
detail::packed_field_fixed< float > packed_field_float
Class for generating packed repeated float fields.
Definition: pbf_writer.hpp:1078
protozero::packed_field_fixed64
detail::packed_field_fixed< uint64_t > packed_field_fixed64
Class for generating packed repeated fixed64 fields.
Definition: pbf_writer.hpp:1072
protozero::pbf_writer::add_packed_double
void add_packed_double(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: pbf_writer.hpp:909
protozero::pbf_writer::add_packed_sint64
void add_packed_sint64(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: pbf_writer.hpp:777
protozero::pbf_writer::add_sint32
void add_sint32(pbf_tag_type tag, int32_t value)
Definition: pbf_writer.hpp:416
protozero::pbf_writer::operator=
pbf_writer & operator=(const pbf_writer &)=delete
A pbf_writer object can not be copied.
protozero::pbf_writer::add_string
void add_string(pbf_tag_type tag, const std::string &value)
Definition: pbf_writer.hpp:630
protozero::pbf_tag_type
uint32_t pbf_tag_type
Definition: types.hpp:33
protozero::pbf_writer
Definition: pbf_writer.hpp:53
protozero::pbf_writer::add_message
void add_message(pbf_tag_type tag, const data_view &value)
Definition: pbf_writer.hpp:662
protozero::encode_zigzag32
constexpr uint32_t encode_zigzag32(int32_t value) noexcept
Definition: varint.hpp:178
protozero::pbf_writer::add_sint64
void add_sint64(pbf_tag_type tag, int64_t value)
Definition: pbf_writer.hpp:446
protozero::swap
void swap(data_view &lhs, data_view &rhs) noexcept
Definition: data_view.hpp:165
protozero::packed_field_sfixed32
detail::packed_field_fixed< int32_t > packed_field_sfixed32
Class for generating packed repeated sfixed32 fields.
Definition: pbf_writer.hpp:1069
protozero::pbf_writer::reserve
void reserve(std::size_t size)
Definition: pbf_writer.hpp:335
protozero::pbf_writer::add_message
void add_message(pbf_tag_type tag, const char *value, std::size_t size)
Definition: pbf_writer.hpp:652
protozero::packed_field_int32
detail::packed_field_varint< int32_t > packed_field_int32
Class for generating packed repeated int32 fields.
Definition: pbf_writer.hpp:1048
protozero::data_view
Definition: data_view.hpp:39
protozero::pbf_writer::add_uint64
void add_uint64(pbf_tag_type tag, uint64_t value)
Definition: pbf_writer.hpp:456
protozero::byteswap_inplace
void byteswap_inplace(uint32_t *ptr) noexcept
byteswap the data pointed to by ptr in-place.
Definition: byteswap.hpp:55
protozero::pbf_writer::add_packed_fixed64
void add_packed_fixed64(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: pbf_writer.hpp:864
protozero::pbf_writer::add_packed_fixed
void add_packed_fixed(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: pbf_writer.hpp:813
protozero::pbf_writer::add_packed_fixed32
void add_packed_fixed32(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: pbf_writer.hpp:834
protozero::packed_field_uint32
detail::packed_field_varint< uint32_t > packed_field_uint32
Class for generating packed repeated uint32 fields.
Definition: pbf_writer.hpp:1054
protozero::pbf_writer::add_enum
void add_enum(pbf_tag_type tag, int32_t value)
Definition: pbf_writer.hpp:396
protozero::pbf_writer::add_bytes_vectored
void add_bytes_vectored(pbf_tag_type tag, Ts &&... values)
Definition: pbf_writer.hpp:592
protozero::pbf_writer::add_packed_enum
void add_packed_enum(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: pbf_writer.hpp:707
protozero::pbf_writer::commit
void commit()
Definition: pbf_writer.hpp:348
protozero::pbf_writer::add_packed_bool
void add_packed_bool(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: pbf_writer.hpp:693
protozero::pbf_writer::add_float
void add_float(pbf_tag_type tag, float value)
Definition: pbf_writer.hpp:510
protozero::pbf_writer::add_uint32
void add_uint32(pbf_tag_type tag, uint32_t value)
Definition: pbf_writer.hpp:426
protozero::pbf_writer::add_packed_uint32
void add_packed_uint32(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: pbf_writer.hpp:749
protozero::pbf_writer::rollback
void rollback()
Definition: pbf_writer.hpp:364
protozero::pbf_writer::add_bytes
void add_bytes(pbf_tag_type tag, const char *value)
Definition: pbf_writer.hpp:568
protozero::pbf_writer::add_packed_float
void add_packed_float(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: pbf_writer.hpp:894
protozero::pbf_writer::add_string
void add_string(pbf_tag_type tag, const char *value)
Definition: pbf_writer.hpp:641
protozero::pbf_length_type
uint32_t pbf_length_type
Definition: types.hpp:62
protozero::pbf_writer::add_int64
void add_int64(pbf_tag_type tag, int64_t value)
Definition: pbf_writer.hpp:436
varint.hpp
Contains low-level varint and zigzag encoding and decoding functions.
protozero::packed_field_fixed32
detail::packed_field_fixed< uint32_t > packed_field_fixed32
Class for generating packed repeated fixed32 fields.
Definition: pbf_writer.hpp:1066
protozero::pbf_writer::add_fixed64
void add_fixed64(pbf_tag_type tag, uint64_t value)
Definition: pbf_writer.hpp:488
protozero::pbf_writer::add_string
void add_string(pbf_tag_type tag, const char *value, std::size_t size)
Definition: pbf_writer.hpp:610
protozero::pbf_writer::add_packed_sint32
void add_packed_sint32(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: pbf_writer.hpp:735
protozero::packed_field_bool
detail::packed_field_varint< bool > packed_field_bool
Class for generating packed repeated bool fields.
Definition: pbf_writer.hpp:1042
protozero::pbf_writer::add_int32
void add_int32(pbf_tag_type tag, int32_t value)
Definition: pbf_writer.hpp:406
protozero::packed_field_int64
detail::packed_field_varint< int64_t > packed_field_int64
Class for generating packed repeated int64 fields.
Definition: pbf_writer.hpp:1057
data_view.hpp
Contains the implementation of the data_view class.
protozero::pbf_writer::add_packed_uint64
void add_packed_uint64(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: pbf_writer.hpp:791
protozero::data_view::data
constexpr const char * data() const noexcept
Return pointer to data.
Definition: data_view.hpp:94