protozero  1.7.0
Minimalistic protocol buffer decoder and encoder in C++.
basic_pbf_writer.hpp
Go to the documentation of this file.
1 #ifndef PROTOZERO_BASIC_PBF_WRITER_HPP
2 #define PROTOZERO_BASIC_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 "buffer_tmpl.hpp"
20 #include "config.hpp"
21 #include "data_view.hpp"
22 #include "types.hpp"
23 #include "varint.hpp"
24 
25 #if PROTOZERO_BYTE_ORDER != PROTOZERO_LITTLE_ENDIAN
26 # include <protozero/byteswap.hpp>
27 #endif
28 
29 #include <cstddef>
30 #include <cstdint>
31 #include <cstring>
32 #include <initializer_list>
33 #include <iterator>
34 #include <limits>
35 #include <string>
36 #include <utility>
37 
38 namespace protozero {
39 
40 namespace detail {
41 
42  template <typename B, typename T> class packed_field_varint;
43  template <typename B, typename T> class packed_field_svarint;
44  template <typename B, typename T> class packed_field_fixed;
45 
46 } // end namespace detail
47 
58 template <typename TBuffer>
60 
61  // A pointer to a buffer holding the data already written to the PBF
62  // message. For default constructed writers or writers that have been
63  // rolled back, this is a nullptr.
64  TBuffer* m_data = nullptr;
65 
66  // A pointer to a parent writer object if this is a submessage. If this
67  // is a top-level writer, it is a nullptr.
68  basic_pbf_writer* m_parent_writer = nullptr;
69 
70  // This is usually 0. If there is an open submessage, this is set in the
71  // parent to the rollback position, ie. the last position before the
72  // submessage was started. This is the position where the header of the
73  // submessage starts.
74  std::size_t m_rollback_pos = 0;
75 
76  // This is usually 0. If there is an open submessage, this is set in the
77  // parent to the position where the data of the submessage is written to.
78  std::size_t m_pos = 0;
79 
80  void add_varint(uint64_t value) {
81  protozero_assert(m_pos == 0 && "you can't add fields to a parent basic_pbf_writer if there is an existing basic_pbf_writer for a submessage");
82  protozero_assert(m_data);
83  add_varint_to_buffer(m_data, value);
84  }
85 
86  void add_field(pbf_tag_type tag, pbf_wire_type type) {
87  protozero_assert(((tag > 0 && tag < 19000) || (tag > 19999 && tag <= ((1U << 29U) - 1))) && "tag out of range");
88  const uint32_t b = (tag << 3U) | uint32_t(type);
89  add_varint(b);
90  }
91 
92  void add_tagged_varint(pbf_tag_type tag, uint64_t value) {
93  add_field(tag, pbf_wire_type::varint);
94  add_varint(value);
95  }
96 
97  template <typename T>
98  void add_fixed(T value) {
99  protozero_assert(m_pos == 0 && "you can't add fields to a parent basic_pbf_writer if there is an existing basic_pbf_writer for a submessage");
100  protozero_assert(m_data);
101 #if PROTOZERO_BYTE_ORDER != PROTOZERO_LITTLE_ENDIAN
102  byteswap_inplace(&value);
103 #endif
104  buffer_customization<TBuffer>::append(m_data, reinterpret_cast<const char*>(&value), sizeof(T));
105  }
106 
107  template <typename T, typename It>
108  void add_packed_fixed(pbf_tag_type tag, It first, It last, std::input_iterator_tag /*unused*/) {
109  if (first == last) {
110  return;
111  }
112 
113  basic_pbf_writer sw{*this, tag};
114 
115  while (first != last) {
116  sw.add_fixed<T>(*first++);
117  }
118  }
119 
120  template <typename T, typename It>
121  void add_packed_fixed(pbf_tag_type tag, It first, It last, std::forward_iterator_tag /*unused*/) {
122  if (first == last) {
123  return;
124  }
125 
126  const auto length = std::distance(first, last);
127  add_length_varint(tag, sizeof(T) * pbf_length_type(length));
128  reserve(sizeof(T) * std::size_t(length));
129 
130  while (first != last) {
131  add_fixed<T>(*first++);
132  }
133  }
134 
135  template <typename It>
136  void add_packed_varint(pbf_tag_type tag, It first, It last) {
137  if (first == last) {
138  return;
139  }
140 
141  basic_pbf_writer sw{*this, tag};
142 
143  while (first != last) {
144  sw.add_varint(uint64_t(*first++));
145  }
146  }
147 
148  template <typename It>
149  void add_packed_svarint(pbf_tag_type tag, It first, It last) {
150  if (first == last) {
151  return;
152  }
153 
154  basic_pbf_writer sw{*this, tag};
155 
156  while (first != last) {
157  sw.add_varint(encode_zigzag64(*first++));
158  }
159  }
160 
161  // The number of bytes to reserve for the varint holding the length of
162  // a length-delimited field. The length has to fit into pbf_length_type,
163  // and a varint needs 8 bit for every 7 bit.
164  enum : int {
165  reserve_bytes = sizeof(pbf_length_type) * 8 / 7 + 1
166  };
167 
168  // If m_rollpack_pos is set to this special value, it means that when
169  // the submessage is closed, nothing needs to be done, because the length
170  // of the submessage has already been written correctly.
171  enum : std::size_t {
172  size_is_known = std::numeric_limits<std::size_t>::max()
173  };
174 
175  void open_submessage(pbf_tag_type tag, std::size_t size) {
176  protozero_assert(m_pos == 0);
177  protozero_assert(m_data);
178  if (size == 0) {
179  m_rollback_pos = buffer_customization<TBuffer>::size(m_data);
180  add_field(tag, pbf_wire_type::length_delimited);
181  buffer_customization<TBuffer>::append_zeros(m_data, std::size_t(reserve_bytes));
182  } else {
183  m_rollback_pos = size_is_known;
184  add_length_varint(tag, pbf_length_type(size));
185  reserve(size);
186  }
187  m_pos = buffer_customization<TBuffer>::size(m_data);
188  }
189 
190  void rollback_submessage() {
191  protozero_assert(m_pos != 0);
192  protozero_assert(m_rollback_pos != size_is_known);
193  protozero_assert(m_data);
194  buffer_customization<TBuffer>::resize(m_data, m_rollback_pos);
195  m_pos = 0;
196  }
197 
198  void commit_submessage() {
199  protozero_assert(m_pos != 0);
200  protozero_assert(m_rollback_pos != size_is_known);
201  protozero_assert(m_data);
202  const auto length = pbf_length_type(buffer_customization<TBuffer>::size(m_data) - m_pos);
203 
204  protozero_assert(buffer_customization<TBuffer>::size(m_data) >= m_pos - reserve_bytes);
205  const auto n = add_varint_to_buffer(buffer_customization<TBuffer>::at_pos(m_data, m_pos - reserve_bytes), length);
206 
207  buffer_customization<TBuffer>::erase_range(m_data, m_pos - reserve_bytes + n, m_pos);
208  m_pos = 0;
209  }
210 
211  void close_submessage() {
212  protozero_assert(m_data);
213  if (m_pos == 0 || m_rollback_pos == size_is_known) {
214  return;
215  }
216  if (buffer_customization<TBuffer>::size(m_data) - m_pos == 0) {
217  rollback_submessage();
218  } else {
219  commit_submessage();
220  }
221  }
222 
223  void add_length_varint(pbf_tag_type tag, pbf_length_type length) {
224  add_field(tag, pbf_wire_type::length_delimited);
225  add_varint(length);
226  }
227 
228 public:
229 
236  explicit basic_pbf_writer(TBuffer& buffer) noexcept :
237  m_data{&buffer} {
238  }
239 
244  basic_pbf_writer() noexcept = default;
245 
256  basic_pbf_writer(basic_pbf_writer& parent_writer, pbf_tag_type tag, std::size_t size = 0) :
257  m_data{parent_writer.m_data},
258  m_parent_writer{&parent_writer} {
259  m_parent_writer->open_submessage(tag, size);
260  }
261 
263  basic_pbf_writer(const basic_pbf_writer&) = delete;
264 
266  basic_pbf_writer& operator=(const basic_pbf_writer&) = delete;
267 
272  basic_pbf_writer(basic_pbf_writer&& other) noexcept :
273  m_data{other.m_data},
274  m_parent_writer{other.m_parent_writer},
275  m_rollback_pos{other.m_rollback_pos},
276  m_pos{other.m_pos} {
277  other.m_data = nullptr;
278  other.m_parent_writer = nullptr;
279  other.m_rollback_pos = 0;
280  other.m_pos = 0;
281  }
282 
288  m_data = other.m_data;
289  m_parent_writer = other.m_parent_writer;
290  m_rollback_pos = other.m_rollback_pos;
291  m_pos = other.m_pos;
292  other.m_data = nullptr;
293  other.m_parent_writer = nullptr;
294  other.m_rollback_pos = 0;
295  other.m_pos = 0;
296  return *this;
297  }
298 
299  ~basic_pbf_writer() noexcept {
300  try {
301  if (m_parent_writer != nullptr) {
302  m_parent_writer->close_submessage();
303  }
304  } catch (...) {
305  // This try/catch is used to make the destructor formally noexcept.
306  // close_submessage() is not noexcept, but will not throw the way
307  // it is called here, so we are good. But to be paranoid, call...
308  std::terminate();
309  }
310  }
311 
317  bool valid() const noexcept {
318  return m_data != nullptr;
319  }
320 
326  void swap(basic_pbf_writer& other) noexcept {
327  using std::swap;
328  swap(m_data, other.m_data);
329  swap(m_parent_writer, other.m_parent_writer);
330  swap(m_rollback_pos, other.m_rollback_pos);
331  swap(m_pos, other.m_pos);
332  }
333 
342  void reserve(std::size_t size) {
343  protozero_assert(m_data);
344  buffer_customization<TBuffer>::reserve_additional(m_data, size);
345  }
346 
355  void commit() {
356  protozero_assert(m_parent_writer && "you can't call commit() on a basic_pbf_writer without a parent");
357  protozero_assert(m_pos == 0 && "you can't call commit() on a basic_pbf_writer that has an open nested submessage");
358  m_parent_writer->close_submessage();
359  m_parent_writer = nullptr;
360  m_data = nullptr;
361  }
362 
371  void rollback() {
372  protozero_assert(m_parent_writer && "you can't call rollback() on a basic_pbf_writer without a parent");
373  protozero_assert(m_pos == 0 && "you can't call rollback() on a basic_pbf_writer that has an open nested submessage");
374  m_parent_writer->rollback_submessage();
375  m_parent_writer = nullptr;
376  m_data = nullptr;
377  }
378 
380 
390  void add_bool(pbf_tag_type tag, bool value) {
391  add_field(tag, pbf_wire_type::varint);
392  protozero_assert(m_pos == 0 && "you can't add fields to a parent basic_pbf_writer if there is an existing basic_pbf_writer for a submessage");
393  protozero_assert(m_data);
394  m_data->push_back(char(value));
395  }
396 
403  void add_enum(pbf_tag_type tag, int32_t value) {
404  add_tagged_varint(tag, uint64_t(value));
405  }
406 
413  void add_int32(pbf_tag_type tag, int32_t value) {
414  add_tagged_varint(tag, uint64_t(value));
415  }
416 
423  void add_sint32(pbf_tag_type tag, int32_t value) {
424  add_tagged_varint(tag, encode_zigzag32(value));
425  }
426 
433  void add_uint32(pbf_tag_type tag, uint32_t value) {
434  add_tagged_varint(tag, value);
435  }
436 
443  void add_int64(pbf_tag_type tag, int64_t value) {
444  add_tagged_varint(tag, uint64_t(value));
445  }
446 
453  void add_sint64(pbf_tag_type tag, int64_t value) {
454  add_tagged_varint(tag, encode_zigzag64(value));
455  }
456 
463  void add_uint64(pbf_tag_type tag, uint64_t value) {
464  add_tagged_varint(tag, value);
465  }
466 
473  void add_fixed32(pbf_tag_type tag, uint32_t value) {
474  add_field(tag, pbf_wire_type::fixed32);
475  add_fixed<uint32_t>(value);
476  }
477 
484  void add_sfixed32(pbf_tag_type tag, int32_t value) {
485  add_field(tag, pbf_wire_type::fixed32);
486  add_fixed<int32_t>(value);
487  }
488 
495  void add_fixed64(pbf_tag_type tag, uint64_t value) {
496  add_field(tag, pbf_wire_type::fixed64);
497  add_fixed<uint64_t>(value);
498  }
499 
506  void add_sfixed64(pbf_tag_type tag, int64_t value) {
507  add_field(tag, pbf_wire_type::fixed64);
508  add_fixed<int64_t>(value);
509  }
510 
517  void add_float(pbf_tag_type tag, float value) {
518  add_field(tag, pbf_wire_type::fixed32);
519  add_fixed<float>(value);
520  }
521 
528  void add_double(pbf_tag_type tag, double value) {
529  add_field(tag, pbf_wire_type::fixed64);
530  add_fixed<double>(value);
531  }
532 
540  void add_bytes(pbf_tag_type tag, const char* value, std::size_t size) {
541  protozero_assert(m_pos == 0 && "you can't add fields to a parent basic_pbf_writer if there is an existing basic_pbf_writer for a submessage");
542  protozero_assert(m_data);
543  protozero_assert(size <= std::numeric_limits<pbf_length_type>::max());
544  add_length_varint(tag, pbf_length_type(size));
545  buffer_customization<TBuffer>::append(m_data, value, size);
546  }
547 
554  void add_bytes(pbf_tag_type tag, const data_view& value) {
555  add_bytes(tag, value.data(), value.size());
556  }
557 
564  void add_bytes(pbf_tag_type tag, const std::string& value) {
565  add_bytes(tag, value.data(), value.size());
566  }
567 
575  void add_bytes(pbf_tag_type tag, const char* value) {
576  add_bytes(tag, value, std::strlen(value));
577  }
578 
598  template <typename... Ts>
599  void add_bytes_vectored(pbf_tag_type tag, Ts&&... values) {
600  protozero_assert(m_pos == 0 && "you can't add fields to a parent basic_pbf_writer if there is an existing basic_pbf_writer for a submessage");
601  protozero_assert(m_data);
602  size_t sum_size = 0;
603  (void)std::initializer_list<size_t>{sum_size += values.size()...};
604  protozero_assert(sum_size <= std::numeric_limits<pbf_length_type>::max());
605  add_length_varint(tag, pbf_length_type(sum_size));
606  buffer_customization<TBuffer>::reserve_additional(m_data, sum_size);
607  (void)std::initializer_list<int>{(buffer_customization<TBuffer>::append(m_data, values.data(), values.size()), 0)...};
608  }
609 
617  void add_string(pbf_tag_type tag, const char* value, std::size_t size) {
618  add_bytes(tag, value, size);
619  }
620 
627  void add_string(pbf_tag_type tag, const data_view& value) {
628  add_bytes(tag, value.data(), value.size());
629  }
630 
637  void add_string(pbf_tag_type tag, const std::string& value) {
638  add_bytes(tag, value.data(), value.size());
639  }
640 
648  void add_string(pbf_tag_type tag, const char* value) {
649  add_bytes(tag, value, std::strlen(value));
650  }
651 
659  void add_message(pbf_tag_type tag, const char* value, std::size_t size) {
660  add_bytes(tag, value, size);
661  }
662 
669  void add_message(pbf_tag_type tag, const data_view& value) {
670  add_bytes(tag, value.data(), value.size());
671  }
672 
679  void add_message(pbf_tag_type tag, const std::string& value) {
680  add_bytes(tag, value.data(), value.size());
681  }
682 
684 
686 
699  template <typename InputIterator>
700  void add_packed_bool(pbf_tag_type tag, InputIterator first, InputIterator last) {
701  add_packed_varint(tag, first, last);
702  }
703 
713  template <typename InputIterator>
714  void add_packed_enum(pbf_tag_type tag, InputIterator first, InputIterator last) {
715  add_packed_varint(tag, first, last);
716  }
717 
727  template <typename InputIterator>
728  void add_packed_int32(pbf_tag_type tag, InputIterator first, InputIterator last) {
729  add_packed_varint(tag, first, last);
730  }
731 
741  template <typename InputIterator>
742  void add_packed_sint32(pbf_tag_type tag, InputIterator first, InputIterator last) {
743  add_packed_svarint(tag, first, last);
744  }
745 
755  template <typename InputIterator>
756  void add_packed_uint32(pbf_tag_type tag, InputIterator first, InputIterator last) {
757  add_packed_varint(tag, first, last);
758  }
759 
769  template <typename InputIterator>
770  void add_packed_int64(pbf_tag_type tag, InputIterator first, InputIterator last) {
771  add_packed_varint(tag, first, last);
772  }
773 
783  template <typename InputIterator>
784  void add_packed_sint64(pbf_tag_type tag, InputIterator first, InputIterator last) {
785  add_packed_svarint(tag, first, last);
786  }
787 
797  template <typename InputIterator>
798  void add_packed_uint64(pbf_tag_type tag, InputIterator first, InputIterator last) {
799  add_packed_varint(tag, first, last);
800  }
801 
819  template <typename ValueType, typename InputIterator>
820  void add_packed_fixed(pbf_tag_type tag, InputIterator first, InputIterator last) {
821  static_assert(std::is_same<ValueType, uint32_t>::value ||
822  std::is_same<ValueType, int32_t>::value ||
823  std::is_same<ValueType, int64_t>::value ||
824  std::is_same<ValueType, uint64_t>::value ||
825  std::is_same<ValueType, double>::value ||
826  std::is_same<ValueType, float>::value, "Only some types are allowed");
827  add_packed_fixed<ValueType, InputIterator>(tag, first, last,
828  typename std::iterator_traits<InputIterator>::iterator_category{});
829  }
830 
840  template <typename InputIterator>
841  void add_packed_fixed32(pbf_tag_type tag, InputIterator first, InputIterator last) {
842  add_packed_fixed<uint32_t, InputIterator>(tag, first, last,
843  typename std::iterator_traits<InputIterator>::iterator_category{});
844  }
845 
855  template <typename InputIterator>
856  void add_packed_sfixed32(pbf_tag_type tag, InputIterator first, InputIterator last) {
857  add_packed_fixed<int32_t, InputIterator>(tag, first, last,
858  typename std::iterator_traits<InputIterator>::iterator_category{});
859  }
860 
870  template <typename InputIterator>
871  void add_packed_fixed64(pbf_tag_type tag, InputIterator first, InputIterator last) {
872  add_packed_fixed<uint64_t, InputIterator>(tag, first, last,
873  typename std::iterator_traits<InputIterator>::iterator_category{});
874  }
875 
885  template <typename InputIterator>
886  void add_packed_sfixed64(pbf_tag_type tag, InputIterator first, InputIterator last) {
887  add_packed_fixed<int64_t, InputIterator>(tag, first, last,
888  typename std::iterator_traits<InputIterator>::iterator_category{});
889  }
890 
900  template <typename InputIterator>
901  void add_packed_float(pbf_tag_type tag, InputIterator first, InputIterator last) {
902  add_packed_fixed<float, InputIterator>(tag, first, last,
903  typename std::iterator_traits<InputIterator>::iterator_category{});
904  }
905 
915  template <typename InputIterator>
916  void add_packed_double(pbf_tag_type tag, InputIterator first, InputIterator last) {
917  add_packed_fixed<double, InputIterator>(tag, first, last,
918  typename std::iterator_traits<InputIterator>::iterator_category{});
919  }
920 
922 
923  template <typename B, typename T> friend class detail::packed_field_varint;
924  template <typename B, typename T> friend class detail::packed_field_svarint;
925  template <typename B, typename T> friend class detail::packed_field_fixed;
926 
927 }; // class basic_pbf_writer
928 
935 template <typename TBuffer>
936 inline void swap(basic_pbf_writer<TBuffer>& lhs, basic_pbf_writer<TBuffer>& rhs) noexcept {
937  lhs.swap(rhs);
938 }
939 
940 namespace detail {
941 
942  template <typename TBuffer>
943  class packed_field {
944 
945  basic_pbf_writer<TBuffer> m_writer{};
946 
947  public:
948 
949  packed_field(const packed_field&) = delete;
950  packed_field& operator=(const packed_field&) = delete;
951 
952  packed_field(packed_field&&) noexcept = default;
953  packed_field& operator=(packed_field&&) noexcept = default;
954 
955  packed_field() = default;
956 
957  packed_field(basic_pbf_writer<TBuffer>& parent_writer, pbf_tag_type tag) :
958  m_writer{parent_writer, tag} {
959  }
960 
961  packed_field(basic_pbf_writer<TBuffer>& parent_writer, pbf_tag_type tag, std::size_t size) :
962  m_writer{parent_writer, tag, size} {
963  }
964 
965  ~packed_field() noexcept = default;
966 
967  bool valid() const noexcept {
968  return m_writer.valid();
969  }
970 
971  void commit() {
972  m_writer.commit();
973  }
974 
975  void rollback() {
976  m_writer.rollback();
977  }
978 
979  basic_pbf_writer<TBuffer>& writer() noexcept {
980  return m_writer;
981  }
982 
983  }; // class packed_field
984 
985  template <typename TBuffer, typename T>
986  class packed_field_fixed : public packed_field<TBuffer> {
987 
988  public:
989 
990  packed_field_fixed() :
991  packed_field<TBuffer>{} {
992  }
993 
994  template <typename P>
995  packed_field_fixed(basic_pbf_writer<TBuffer>& parent_writer, P tag) :
996  packed_field<TBuffer>{parent_writer, static_cast<pbf_tag_type>(tag)} {
997  }
998 
999  template <typename P>
1000  packed_field_fixed(basic_pbf_writer<TBuffer>& parent_writer, P tag, std::size_t size) :
1001  packed_field<TBuffer>{parent_writer, static_cast<pbf_tag_type>(tag), size * sizeof(T)} {
1002  }
1003 
1004  void add_element(T value) {
1005  this->writer().template add_fixed<T>(value);
1006  }
1007 
1008  }; // class packed_field_fixed
1009 
1010  template <typename TBuffer, typename T>
1011  class packed_field_varint : public packed_field<TBuffer> {
1012 
1013  public:
1014 
1015  packed_field_varint() :
1016  packed_field<TBuffer>{} {
1017  }
1018 
1019  template <typename P>
1020  packed_field_varint(basic_pbf_writer<TBuffer>& parent_writer, P tag) :
1021  packed_field<TBuffer>{parent_writer, static_cast<pbf_tag_type>(tag)} {
1022  }
1023 
1024  void add_element(T value) {
1025  this->writer().add_varint(uint64_t(value));
1026  }
1027 
1028  }; // class packed_field_varint
1029 
1030  template <typename TBuffer, typename T>
1031  class packed_field_svarint : public packed_field<TBuffer> {
1032 
1033  public:
1034 
1035  packed_field_svarint() :
1036  packed_field<TBuffer>{} {
1037  }
1038 
1039  template <typename P>
1040  packed_field_svarint(basic_pbf_writer<TBuffer>& parent_writer, P tag) :
1041  packed_field<TBuffer>{parent_writer, static_cast<pbf_tag_type>(tag)} {
1042  }
1043 
1044  void add_element(T value) {
1045  this->writer().add_varint(encode_zigzag64(value));
1046  }
1047 
1048  }; // class packed_field_svarint
1049 
1050 } // end namespace detail
1051 
1052 } // end namespace protozero
1053 
1054 #endif // PROTOZERO_BASIC_PBF_WRITER_HPP
protozero::basic_pbf_writer::add_string
void add_string(pbf_tag_type tag, const char *value, std::size_t size)
Definition: basic_pbf_writer.hpp:617
protozero::basic_pbf_writer::add_sfixed32
void add_sfixed32(pbf_tag_type tag, int32_t value)
Definition: basic_pbf_writer.hpp:484
protozero::basic_pbf_writer::add_uint64
void add_uint64(pbf_tag_type tag, uint64_t value)
Definition: basic_pbf_writer.hpp:463
protozero::pbf_wire_type
pbf_wire_type
Definition: types.hpp:40
protozero::basic_pbf_writer::add_packed_sint32
void add_packed_sint32(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: basic_pbf_writer.hpp:742
protozero::basic_pbf_writer::add_string
void add_string(pbf_tag_type tag, const char *value)
Definition: basic_pbf_writer.hpp:648
config.hpp
Contains macro checks for different configurations.
protozero
All parts of the protozero header-only library are in this namespace.
Definition: basic_pbf_builder.hpp:24
protozero::basic_pbf_writer::add_bytes_vectored
void add_bytes_vectored(pbf_tag_type tag, Ts &&... values)
Definition: basic_pbf_writer.hpp:599
byteswap.hpp
Contains functions to swap bytes in values (for different endianness).
protozero::basic_pbf_writer::add_double
void add_double(pbf_tag_type tag, double value)
Definition: basic_pbf_writer.hpp:528
protozero::basic_pbf_writer::add_packed_bool
void add_packed_bool(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: basic_pbf_writer.hpp:700
types.hpp
Contains the declaration of low-level types used in the pbf format.
protozero::basic_pbf_writer
Definition: basic_pbf_writer.hpp:59
protozero::basic_pbf_writer::add_packed_float
void add_packed_float(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: basic_pbf_writer.hpp:901
protozero::basic_pbf_writer::add_message
void add_message(pbf_tag_type tag, const char *value, std::size_t size)
Definition: basic_pbf_writer.hpp:659
protozero::basic_pbf_writer::add_packed_fixed32
void add_packed_fixed32(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: basic_pbf_writer.hpp:841
protozero::basic_pbf_writer::basic_pbf_writer
basic_pbf_writer() noexcept=default
protozero::data_view::size
constexpr std::size_t size() const noexcept
Return length of data in bytes.
Definition: data_view.hpp:99
protozero::encode_zigzag64
constexpr uint64_t encode_zigzag64(int64_t value) noexcept
Definition: varint.hpp:225
protozero::basic_pbf_writer::swap
void swap(basic_pbf_writer &other) noexcept
Definition: basic_pbf_writer.hpp:326
protozero::basic_pbf_writer::add_sint32
void add_sint32(pbf_tag_type tag, int32_t value)
Definition: basic_pbf_writer.hpp:423
protozero::basic_pbf_writer::add_packed_int32
void add_packed_int32(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: basic_pbf_writer.hpp:728
protozero::basic_pbf_writer::operator=
basic_pbf_writer & operator=(basic_pbf_writer &&other) noexcept
Definition: basic_pbf_writer.hpp:287
protozero::basic_pbf_writer::add_bool
void add_bool(pbf_tag_type tag, bool value)
Definition: basic_pbf_writer.hpp:390
protozero::basic_pbf_writer::add_packed_enum
void add_packed_enum(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: basic_pbf_writer.hpp:714
protozero::basic_pbf_writer::add_bytes
void add_bytes(pbf_tag_type tag, const data_view &value)
Definition: basic_pbf_writer.hpp:554
protozero::basic_pbf_writer::add_bytes
void add_bytes(pbf_tag_type tag, const char *value, std::size_t size)
Definition: basic_pbf_writer.hpp:540
protozero::swap
void swap(basic_pbf_writer< TBuffer > &lhs, basic_pbf_writer< TBuffer > &rhs) noexcept
Definition: basic_pbf_writer.hpp:936
protozero::basic_pbf_writer::add_bytes
void add_bytes(pbf_tag_type tag, const std::string &value)
Definition: basic_pbf_writer.hpp:564
protozero::basic_pbf_writer::add_fixed32
void add_fixed32(pbf_tag_type tag, uint32_t value)
Definition: basic_pbf_writer.hpp:473
protozero::basic_pbf_writer::valid
bool valid() const noexcept
Definition: basic_pbf_writer.hpp:317
protozero::basic_pbf_writer::add_packed_int64
void add_packed_int64(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: basic_pbf_writer.hpp:770
protozero::basic_pbf_writer::basic_pbf_writer
basic_pbf_writer(TBuffer &buffer) noexcept
Definition: basic_pbf_writer.hpp:236
protozero::basic_pbf_writer::add_message
void add_message(pbf_tag_type tag, const data_view &value)
Definition: basic_pbf_writer.hpp:669
protozero::basic_pbf_writer::add_packed_sfixed32
void add_packed_sfixed32(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: basic_pbf_writer.hpp:856
protozero::pbf_tag_type
uint32_t pbf_tag_type
Definition: types.hpp:33
protozero::basic_pbf_writer::add_message
void add_message(pbf_tag_type tag, const std::string &value)
Definition: basic_pbf_writer.hpp:679
protozero::add_varint_to_buffer
void add_varint_to_buffer(TBuffer *buffer, uint64_t value)
Definition: varint.hpp:170
protozero::basic_pbf_writer::add_sfixed64
void add_sfixed64(pbf_tag_type tag, int64_t value)
Definition: basic_pbf_writer.hpp:506
protozero::encode_zigzag32
constexpr uint32_t encode_zigzag32(int32_t value) noexcept
Definition: varint.hpp:218
protozero::basic_pbf_writer::add_packed_uint64
void add_packed_uint64(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: basic_pbf_writer.hpp:798
protozero::basic_pbf_writer::basic_pbf_writer
basic_pbf_writer(basic_pbf_writer &&other) noexcept
Definition: basic_pbf_writer.hpp:272
protozero::basic_pbf_writer::add_packed_uint32
void add_packed_uint32(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: basic_pbf_writer.hpp:756
protozero::basic_pbf_writer::reserve
void reserve(std::size_t size)
Definition: basic_pbf_writer.hpp:342
protozero::basic_pbf_writer::add_int32
void add_int32(pbf_tag_type tag, int32_t value)
Definition: basic_pbf_writer.hpp:413
protozero::data_view
Definition: data_view.hpp:39
protozero::byteswap_inplace
void byteswap_inplace(uint32_t *ptr) noexcept
byteswap the data pointed to by ptr in-place.
Definition: byteswap.hpp:55
protozero::basic_pbf_writer::add_packed_fixed64
void add_packed_fixed64(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: basic_pbf_writer.hpp:871
protozero::basic_pbf_writer::add_packed_double
void add_packed_double(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: basic_pbf_writer.hpp:916
protozero::basic_pbf_writer::add_string
void add_string(pbf_tag_type tag, const data_view &value)
Definition: basic_pbf_writer.hpp:627
protozero::basic_pbf_writer::add_int64
void add_int64(pbf_tag_type tag, int64_t value)
Definition: basic_pbf_writer.hpp:443
protozero::basic_pbf_writer::add_string
void add_string(pbf_tag_type tag, const std::string &value)
Definition: basic_pbf_writer.hpp:637
protozero::basic_pbf_writer::add_fixed64
void add_fixed64(pbf_tag_type tag, uint64_t value)
Definition: basic_pbf_writer.hpp:495
protozero::basic_pbf_writer::add_float
void add_float(pbf_tag_type tag, float value)
Definition: basic_pbf_writer.hpp:517
protozero::basic_pbf_writer::add_uint32
void add_uint32(pbf_tag_type tag, uint32_t value)
Definition: basic_pbf_writer.hpp:433
protozero::basic_pbf_writer::rollback
void rollback()
Definition: basic_pbf_writer.hpp:371
protozero::basic_pbf_writer::add_packed_fixed
void add_packed_fixed(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: basic_pbf_writer.hpp:820
protozero::basic_pbf_writer::add_enum
void add_enum(pbf_tag_type tag, int32_t value)
Definition: basic_pbf_writer.hpp:403
protozero::basic_pbf_writer::operator=
basic_pbf_writer & operator=(const basic_pbf_writer &)=delete
A basic_pbf_writer object can not be copied.
protozero::basic_pbf_writer::add_packed_sint64
void add_packed_sint64(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: basic_pbf_writer.hpp:784
protozero::basic_pbf_writer::add_packed_sfixed64
void add_packed_sfixed64(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: basic_pbf_writer.hpp:886
protozero::pbf_length_type
uint32_t pbf_length_type
Definition: types.hpp:62
protozero::basic_pbf_writer::add_sint64
void add_sint64(pbf_tag_type tag, int64_t value)
Definition: basic_pbf_writer.hpp:453
protozero::basic_pbf_writer::add_bytes
void add_bytes(pbf_tag_type tag, const char *value)
Definition: basic_pbf_writer.hpp:575
varint.hpp
Contains low-level varint and zigzag encoding and decoding functions.
protozero::basic_pbf_writer::commit
void commit()
Definition: basic_pbf_writer.hpp:355
buffer_tmpl.hpp
Contains the customization points for buffer implementations.
data_view.hpp
Contains the implementation of the data_view class.
protozero::data_view::data
constexpr const char * data() const noexcept
Return pointer to data.
Definition: data_view.hpp:94