protozero  1.6.3
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() {
293  if (m_parent_writer != nullptr) {
294  m_parent_writer->close_submessage();
295  }
296  }
297 
303  bool valid() const noexcept {
304  return m_data != nullptr;
305  }
306 
312  void swap(pbf_writer& other) noexcept {
313  using std::swap;
314  swap(m_data, other.m_data);
315  swap(m_parent_writer, other.m_parent_writer);
316  swap(m_rollback_pos, other.m_rollback_pos);
317  swap(m_pos, other.m_pos);
318  }
319 
328  void reserve(std::size_t size) {
329  protozero_assert(m_data);
330  m_data->reserve(m_data->size() + size);
331  }
332 
341  void commit() {
342  protozero_assert(m_parent_writer && "you can't call commit() on a pbf_writer without a parent");
343  protozero_assert(m_pos == 0 && "you can't call commit() on a pbf_writer that has an open nested submessage");
344  m_parent_writer->close_submessage();
345  m_parent_writer = nullptr;
346  m_data = nullptr;
347  }
348 
357  void rollback() {
358  protozero_assert(m_parent_writer && "you can't call rollback() on a pbf_writer without a parent");
359  protozero_assert(m_pos == 0 && "you can't call rollback() on a pbf_writer that has an open nested submessage");
360  m_parent_writer->rollback_submessage();
361  m_parent_writer = nullptr;
362  m_data = nullptr;
363  }
364 
366 
376  void add_bool(pbf_tag_type tag, bool value) {
377  add_field(tag, pbf_wire_type::varint);
378  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");
379  protozero_assert(m_data);
380  m_data->append(1, char(value));
381  }
382 
389  void add_enum(pbf_tag_type tag, int32_t value) {
390  add_tagged_varint(tag, uint64_t(value));
391  }
392 
399  void add_int32(pbf_tag_type tag, int32_t value) {
400  add_tagged_varint(tag, uint64_t(value));
401  }
402 
409  void add_sint32(pbf_tag_type tag, int32_t value) {
410  add_tagged_varint(tag, encode_zigzag32(value));
411  }
412 
419  void add_uint32(pbf_tag_type tag, uint32_t value) {
420  add_tagged_varint(tag, value);
421  }
422 
429  void add_int64(pbf_tag_type tag, int64_t value) {
430  add_tagged_varint(tag, uint64_t(value));
431  }
432 
439  void add_sint64(pbf_tag_type tag, int64_t value) {
440  add_tagged_varint(tag, encode_zigzag64(value));
441  }
442 
449  void add_uint64(pbf_tag_type tag, uint64_t value) {
450  add_tagged_varint(tag, value);
451  }
452 
459  void add_fixed32(pbf_tag_type tag, uint32_t value) {
460  add_field(tag, pbf_wire_type::fixed32);
461  add_fixed<uint32_t>(value);
462  }
463 
470  void add_sfixed32(pbf_tag_type tag, int32_t value) {
471  add_field(tag, pbf_wire_type::fixed32);
472  add_fixed<int32_t>(value);
473  }
474 
481  void add_fixed64(pbf_tag_type tag, uint64_t value) {
482  add_field(tag, pbf_wire_type::fixed64);
483  add_fixed<uint64_t>(value);
484  }
485 
492  void add_sfixed64(pbf_tag_type tag, int64_t value) {
493  add_field(tag, pbf_wire_type::fixed64);
494  add_fixed<int64_t>(value);
495  }
496 
503  void add_float(pbf_tag_type tag, float value) {
504  add_field(tag, pbf_wire_type::fixed32);
505  add_fixed<float>(value);
506  }
507 
514  void add_double(pbf_tag_type tag, double value) {
515  add_field(tag, pbf_wire_type::fixed64);
516  add_fixed<double>(value);
517  }
518 
526  void add_bytes(pbf_tag_type tag, const char* value, std::size_t size) {
527  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");
528  protozero_assert(m_data);
529  protozero_assert(size <= std::numeric_limits<pbf_length_type>::max());
530  add_length_varint(tag, pbf_length_type(size));
531  m_data->append(value, size);
532  }
533 
540  void add_bytes(pbf_tag_type tag, const data_view& value) {
541  add_bytes(tag, value.data(), value.size());
542  }
543 
550  void add_bytes(pbf_tag_type tag, const std::string& value) {
551  add_bytes(tag, value.data(), value.size());
552  }
553 
561  void add_bytes(pbf_tag_type tag, const char* value) {
562  add_bytes(tag, value, std::strlen(value));
563  }
564 
584  template <typename... Ts>
585  void add_bytes_vectored(pbf_tag_type tag, Ts&&... values) {
586  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");
587  protozero_assert(m_data);
588  size_t sum_size = 0;
589  (void)std::initializer_list<size_t>{sum_size += values.size()...};
590  protozero_assert(sum_size <= std::numeric_limits<pbf_length_type>::max());
591  add_length_varint(tag, pbf_length_type(sum_size));
592  m_data->reserve(m_data->size() + sum_size);
593  (void)std::initializer_list<int>{(m_data->append(values.data(), values.size()), 0)...};
594  }
595 
603  void add_string(pbf_tag_type tag, const char* value, std::size_t size) {
604  add_bytes(tag, value, size);
605  }
606 
613  void add_string(pbf_tag_type tag, const data_view& value) {
614  add_bytes(tag, value.data(), value.size());
615  }
616 
623  void add_string(pbf_tag_type tag, const std::string& value) {
624  add_bytes(tag, value.data(), value.size());
625  }
626 
634  void add_string(pbf_tag_type tag, const char* value) {
635  add_bytes(tag, value, std::strlen(value));
636  }
637 
645  void add_message(pbf_tag_type tag, const char* value, std::size_t size) {
646  add_bytes(tag, value, size);
647  }
648 
655  void add_message(pbf_tag_type tag, const data_view& value) {
656  add_bytes(tag, value.data(), value.size());
657  }
658 
665  void add_message(pbf_tag_type tag, const std::string& value) {
666  add_bytes(tag, value.data(), value.size());
667  }
668 
670 
672 
685  template <typename InputIterator>
686  void add_packed_bool(pbf_tag_type tag, InputIterator first, InputIterator last) {
687  add_packed_varint(tag, first, last);
688  }
689 
699  template <typename InputIterator>
700  void add_packed_enum(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_int32(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_sint32(pbf_tag_type tag, InputIterator first, InputIterator last) {
729  add_packed_svarint(tag, first, last);
730  }
731 
741  template <typename InputIterator>
742  void add_packed_uint32(pbf_tag_type tag, InputIterator first, InputIterator last) {
743  add_packed_varint(tag, first, last);
744  }
745 
755  template <typename InputIterator>
756  void add_packed_int64(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_sint64(pbf_tag_type tag, InputIterator first, InputIterator last) {
771  add_packed_svarint(tag, first, last);
772  }
773 
783  template <typename InputIterator>
784  void add_packed_uint64(pbf_tag_type tag, InputIterator first, InputIterator last) {
785  add_packed_varint(tag, first, last);
786  }
787 
797  template <typename InputIterator>
798  void add_packed_fixed32(pbf_tag_type tag, InputIterator first, InputIterator last) {
799  add_packed_fixed<uint32_t, InputIterator>(tag, first, last,
800  typename std::iterator_traits<InputIterator>::iterator_category());
801  }
802 
812  template <typename InputIterator>
813  void add_packed_sfixed32(pbf_tag_type tag, InputIterator first, InputIterator last) {
814  add_packed_fixed<int32_t, InputIterator>(tag, first, last,
815  typename std::iterator_traits<InputIterator>::iterator_category());
816  }
817 
827  template <typename InputIterator>
828  void add_packed_fixed64(pbf_tag_type tag, InputIterator first, InputIterator last) {
829  add_packed_fixed<uint64_t, InputIterator>(tag, first, last,
830  typename std::iterator_traits<InputIterator>::iterator_category());
831  }
832 
842  template <typename InputIterator>
843  void add_packed_sfixed64(pbf_tag_type tag, InputIterator first, InputIterator last) {
844  add_packed_fixed<int64_t, InputIterator>(tag, first, last,
845  typename std::iterator_traits<InputIterator>::iterator_category());
846  }
847 
857  template <typename InputIterator>
858  void add_packed_float(pbf_tag_type tag, InputIterator first, InputIterator last) {
859  add_packed_fixed<float, InputIterator>(tag, first, last,
860  typename std::iterator_traits<InputIterator>::iterator_category());
861  }
862 
872  template <typename InputIterator>
873  void add_packed_double(pbf_tag_type tag, InputIterator first, InputIterator last) {
874  add_packed_fixed<double, InputIterator>(tag, first, last,
875  typename std::iterator_traits<InputIterator>::iterator_category());
876  }
877 
879 
880  template <typename T> friend class detail::packed_field_varint;
881  template <typename T> friend class detail::packed_field_svarint;
882  template <typename T> friend class detail::packed_field_fixed;
883 
884 }; // class pbf_writer
885 
892 inline void swap(pbf_writer& lhs, pbf_writer& rhs) noexcept {
893  lhs.swap(rhs);
894 }
895 
896 namespace detail {
897 
898  class packed_field {
899 
900  protected:
901 
902  pbf_writer m_writer{};
903 
904  public:
905 
906  packed_field(const packed_field&) = delete;
907  packed_field& operator=(const packed_field&) = delete;
908 
909  packed_field(packed_field&&) noexcept = default;
910  packed_field& operator=(packed_field&&) noexcept = default;
911 
912  packed_field() = default;
913 
914  packed_field(pbf_writer& parent_writer, pbf_tag_type tag) :
915  m_writer(parent_writer, tag) {
916  }
917 
918  packed_field(pbf_writer& parent_writer, pbf_tag_type tag, std::size_t size) :
919  m_writer(parent_writer, tag, size) {
920  }
921 
922  ~packed_field() noexcept = default;
923 
924  bool valid() const noexcept {
925  return m_writer.valid();
926  }
927 
928  void commit() {
929  m_writer.commit();
930  }
931 
932  void rollback() {
933  m_writer.rollback();
934  }
935 
936  }; // class packed_field
937 
938  template <typename T>
939  class packed_field_fixed : public packed_field {
940 
941  public:
942 
943  packed_field_fixed() :
944  packed_field() {
945  }
946 
947  template <typename P>
948  packed_field_fixed(pbf_writer& parent_writer, P tag) :
949  packed_field(parent_writer, static_cast<pbf_tag_type>(tag)) {
950  }
951 
952  template <typename P>
953  packed_field_fixed(pbf_writer& parent_writer, P tag, std::size_t size) :
954  packed_field(parent_writer, static_cast<pbf_tag_type>(tag), size * sizeof(T)) {
955  }
956 
957  void add_element(T value) {
958  m_writer.add_fixed<T>(value);
959  }
960 
961  }; // class packed_field_fixed
962 
963  template <typename T>
964  class packed_field_varint : public packed_field {
965 
966  public:
967 
968  packed_field_varint() :
969  packed_field() {
970  }
971 
972  template <typename P>
973  packed_field_varint(pbf_writer& parent_writer, P tag) :
974  packed_field(parent_writer, static_cast<pbf_tag_type>(tag)) {
975  }
976 
977  void add_element(T value) {
978  m_writer.add_varint(uint64_t(value));
979  }
980 
981  }; // class packed_field_varint
982 
983  template <typename T>
984  class packed_field_svarint : public packed_field {
985 
986  public:
987 
988  packed_field_svarint() :
989  packed_field() {
990  }
991 
992  template <typename P>
993  packed_field_svarint(pbf_writer& parent_writer, P tag) :
994  packed_field(parent_writer, static_cast<pbf_tag_type>(tag)) {
995  }
996 
997  void add_element(T value) {
998  m_writer.add_varint(encode_zigzag64(value));
999  }
1000 
1001  }; // class packed_field_svarint
1002 
1003 } // end namespace detail
1004 
1006 using packed_field_bool = detail::packed_field_varint<bool>;
1007 
1009 using packed_field_enum = detail::packed_field_varint<int32_t>;
1010 
1012 using packed_field_int32 = detail::packed_field_varint<int32_t>;
1013 
1015 using packed_field_sint32 = detail::packed_field_svarint<int32_t>;
1016 
1018 using packed_field_uint32 = detail::packed_field_varint<uint32_t>;
1019 
1021 using packed_field_int64 = detail::packed_field_varint<int64_t>;
1022 
1024 using packed_field_sint64 = detail::packed_field_svarint<int64_t>;
1025 
1027 using packed_field_uint64 = detail::packed_field_varint<uint64_t>;
1028 
1030 using packed_field_fixed32 = detail::packed_field_fixed<uint32_t>;
1031 
1033 using packed_field_sfixed32 = detail::packed_field_fixed<int32_t>;
1034 
1036 using packed_field_fixed64 = detail::packed_field_fixed<uint64_t>;
1037 
1039 using packed_field_sfixed64 = detail::packed_field_fixed<int64_t>;
1040 
1042 using packed_field_float = detail::packed_field_fixed<float>;
1043 
1045 using packed_field_double = detail::packed_field_fixed<double>;
1046 
1047 } // end namespace protozero
1048 
1049 #endif // PROTOZERO_PBF_WRITER_HPP
void add_packed_fixed64(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: pbf_writer.hpp:828
void add_packed_sint32(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: pbf_writer.hpp:728
detail::packed_field_fixed< float > packed_field_float
Class for generating packed repeated float fields.
Definition: pbf_writer.hpp:1042
void add_packed_sint64(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: pbf_writer.hpp:770
void add_string(pbf_tag_type tag, const char *value)
Definition: pbf_writer.hpp:634
void add_packed_sfixed64(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: pbf_writer.hpp:843
void rollback()
Definition: pbf_writer.hpp:357
void add_packed_sfixed32(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: pbf_writer.hpp:813
constexpr uint64_t encode_zigzag64(int64_t value) noexcept
Definition: varint.hpp:168
pbf_writer & operator=(const pbf_writer &)=delete
A pbf_writer object can not be copied.
void reserve(std::size_t size)
Definition: pbf_writer.hpp:328
void add_sint64(pbf_tag_type tag, int64_t value)
Definition: pbf_writer.hpp:439
void add_message(pbf_tag_type tag, const char *value, std::size_t size)
Definition: pbf_writer.hpp:645
pbf_writer(pbf_writer &&other) noexcept
Definition: pbf_writer.hpp:265
detail::packed_field_varint< int64_t > packed_field_int64
Class for generating packed repeated int64 fields.
Definition: pbf_writer.hpp:1021
void add_sfixed64(pbf_tag_type tag, int64_t value)
Definition: pbf_writer.hpp:492
void add_uint32(pbf_tag_type tag, uint32_t value)
Definition: pbf_writer.hpp:419
void add_bytes(pbf_tag_type tag, const std::string &value)
Definition: pbf_writer.hpp:550
void add_string(pbf_tag_type tag, const char *value, std::size_t size)
Definition: pbf_writer.hpp:603
void add_packed_enum(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: pbf_writer.hpp:700
Definition: iterators.hpp:416
detail::packed_field_fixed< int64_t > packed_field_sfixed64
Class for generating packed repeated sfixed64 fields.
Definition: pbf_writer.hpp:1039
void add_message(pbf_tag_type tag, const data_view &value)
Definition: pbf_writer.hpp:655
Definition: pbf_writer.hpp:53
void add_int64(pbf_tag_type tag, int64_t value)
Definition: pbf_writer.hpp:429
Contains macro checks for different configurations.
detail::packed_field_varint< bool > packed_field_bool
Class for generating packed repeated bool fields.
Definition: pbf_writer.hpp:1006
detail::packed_field_fixed< double > packed_field_double
Class for generating packed repeated double fields.
Definition: pbf_writer.hpp:1045
Contains the declaration of low-level types used in the pbf format.
constexpr uint32_t encode_zigzag32(int32_t value) noexcept
Definition: varint.hpp:161
void add_int32(pbf_tag_type tag, int32_t value)
Definition: pbf_writer.hpp:399
void add_string(pbf_tag_type tag, const std::string &value)
Definition: pbf_writer.hpp:623
pbf_writer & operator=(pbf_writer &&other) noexcept
Definition: pbf_writer.hpp:280
int write_varint(T data, uint64_t value)
Definition: varint.hpp:145
void add_uint64(pbf_tag_type tag, uint64_t value)
Definition: pbf_writer.hpp:449
constexpr std::size_t size() const noexcept
Return length of data in bytes.
Definition: data_view.hpp:99
void add_string(pbf_tag_type tag, const data_view &value)
Definition: pbf_writer.hpp:613
detail::packed_field_varint< int32_t > packed_field_int32
Class for generating packed repeated int32 fields.
Definition: pbf_writer.hpp:1012
pbf_wire_type
Definition: types.hpp:40
void add_message(pbf_tag_type tag, const std::string &value)
Definition: pbf_writer.hpp:665
void add_float(pbf_tag_type tag, float value)
Definition: pbf_writer.hpp:503
Contains the implementation of the data_view class.
void swap(pbf_writer &other) noexcept
Definition: pbf_writer.hpp:312
void add_enum(pbf_tag_type tag, int32_t value)
Definition: pbf_writer.hpp:389
detail::packed_field_svarint< int64_t > packed_field_sint64
Class for generating packed repeated sint64 fields.
Definition: pbf_writer.hpp:1024
void add_packed_uint64(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: pbf_writer.hpp:784
void add_bytes_vectored(pbf_tag_type tag, Ts &&... values)
Definition: pbf_writer.hpp:585
Contains functions to swap bytes in values (for different endianness).
void add_packed_uint32(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: pbf_writer.hpp:742
void add_packed_int64(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: pbf_writer.hpp:756
void add_fixed64(pbf_tag_type tag, uint64_t value)
Definition: pbf_writer.hpp:481
uint32_t pbf_length_type
Definition: types.hpp:62
void add_bool(pbf_tag_type tag, bool value)
Definition: pbf_writer.hpp:376
void add_packed_bool(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: pbf_writer.hpp:686
detail::packed_field_fixed< uint64_t > packed_field_fixed64
Class for generating packed repeated fixed64 fields.
Definition: pbf_writer.hpp:1036
detail::packed_field_fixed< int32_t > packed_field_sfixed32
Class for generating packed repeated sfixed32 fields.
Definition: pbf_writer.hpp:1033
uint32_t pbf_tag_type
Definition: types.hpp:33
detail::packed_field_varint< uint32_t > packed_field_uint32
Class for generating packed repeated uint32 fields.
Definition: pbf_writer.hpp:1018
void commit()
Definition: pbf_writer.hpp:341
void swap(pbf_writer &lhs, pbf_writer &rhs) noexcept
Definition: pbf_writer.hpp:892
void add_packed_double(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: pbf_writer.hpp:873
Definition: data_view.hpp:39
void add_packed_float(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: pbf_writer.hpp:858
detail::packed_field_varint< uint64_t > packed_field_uint64
Class for generating packed repeated uint64 fields.
Definition: pbf_writer.hpp:1027
void add_packed_int32(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: pbf_writer.hpp:714
constexpr const char * data() const noexcept
Return pointer to data.
Definition: data_view.hpp:94
void add_sfixed32(pbf_tag_type tag, int32_t value)
Definition: pbf_writer.hpp:470
pbf_writer(std::string &data) noexcept
Definition: pbf_writer.hpp:229
Contains low-level varint and zigzag encoding and decoding functions.
void add_sint32(pbf_tag_type tag, int32_t value)
Definition: pbf_writer.hpp:409
detail::packed_field_varint< int32_t > packed_field_enum
Class for generating packed repeated enum fields.
Definition: pbf_writer.hpp:1009
void add_fixed32(pbf_tag_type tag, uint32_t value)
Definition: pbf_writer.hpp:459
detail::packed_field_fixed< uint32_t > packed_field_fixed32
Class for generating packed repeated fixed32 fields.
Definition: pbf_writer.hpp:1030
void add_bytes(pbf_tag_type tag, const data_view &value)
Definition: pbf_writer.hpp:540
bool valid() const noexcept
Definition: pbf_writer.hpp:303
void add_packed_fixed32(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: pbf_writer.hpp:798
void add_double(pbf_tag_type tag, double value)
Definition: pbf_writer.hpp:514
detail::packed_field_svarint< int32_t > packed_field_sint32
Class for generating packed repeated sint32 fields.
Definition: pbf_writer.hpp:1015
void add_bytes(pbf_tag_type tag, const char *value)
Definition: pbf_writer.hpp:561
void add_bytes(pbf_tag_type tag, const char *value, std::size_t size)
Definition: pbf_writer.hpp:526
All parts of the protozero header-only library are in this namespace.
Definition: byteswap.hpp:23
pbf_writer() noexcept=default
void swap(data_view &lhs, data_view &rhs) noexcept
Definition: data_view.hpp:165