protozero
Minimalistic protocol buffer decoder and encoder in C++.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Macros Pages
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 <cstddef>
20 #include <cstdint>
21 #include <cstring>
22 #include <iterator>
23 #include <limits>
24 #include <string>
25 #include <utility>
26 
27 #include <protozero/config.hpp>
28 #include <protozero/types.hpp>
29 #include <protozero/varint.hpp>
30 
31 #if PROTOZERO_BYTE_ORDER != PROTOZERO_LITTLE_ENDIAN
32 # include <protozero/byteswap.hpp>
33 #endif
34 
35 namespace protozero {
36 
37 namespace detail {
38 
39  template <typename T> class packed_field_varint;
40  template <typename T> class packed_field_svarint;
41  template <typename T> class packed_field_fixed;
42 
43 } // end namespace detail
44 
51 class pbf_writer {
52 
53  // A pointer to a string buffer holding the data already written to the
54  // PBF message. For default constructed writers or writers that have been
55  // rolled back, this is a nullptr.
56  std::string* m_data;
57 
58  // A pointer to a parent writer object if this is a submessage. If this
59  // is a top-level writer, it is a nullptr.
60  pbf_writer* m_parent_writer;
61 
62  // This is usually 0. If there is an open submessage, this is set in the
63  // parent to the rollback position, ie. the last position before the
64  // submessage was started. This is the position where the header of the
65  // submessage starts.
66  std::size_t m_rollback_pos = 0;
67 
68  // This is usually 0. If there is an open submessage, this is set in the
69  // parent to the position where the data of the submessage is written to.
70  std::size_t m_pos = 0;
71 
72  void add_varint(uint64_t value) {
73  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");
74  protozero_assert(m_data);
75  write_varint(std::back_inserter(*m_data), value);
76  }
77 
78  void add_field(pbf_tag_type tag, pbf_wire_type type) {
79  protozero_assert(((tag > 0 && tag < 19000) || (tag > 19999 && tag <= ((1 << 29) - 1))) && "tag out of range");
80  const uint32_t b = (tag << 3) | uint32_t(type);
81  add_varint(b);
82  }
83 
84  void add_tagged_varint(pbf_tag_type tag, uint64_t value) {
85  add_field(tag, pbf_wire_type::varint);
86  add_varint(value);
87  }
88 
89  template <typename T>
90  void add_fixed(T value) {
91  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");
92  protozero_assert(m_data);
93 #if PROTOZERO_BYTE_ORDER != PROTOZERO_LITTLE_ENDIAN
94  detail::byteswap_inplace(&value);
95 #endif
96  m_data->append(reinterpret_cast<const char*>(&value), sizeof(T));
97  }
98 
99  template <typename T, typename It>
100  void add_packed_fixed(pbf_tag_type tag, It first, It last, std::input_iterator_tag) {
101  if (first == last) {
102  return;
103  }
104 
105  pbf_writer sw(*this, tag);
106 
107  while (first != last) {
108  sw.add_fixed<T>(*first++);
109  }
110  }
111 
112  template <typename T, typename It>
113  void add_packed_fixed(pbf_tag_type tag, It first, It last, std::forward_iterator_tag) {
114  if (first == last) {
115  return;
116  }
117 
118  const auto length = std::distance(first, last);
119  add_length_varint(tag, sizeof(T) * pbf_length_type(length));
120  reserve(sizeof(T) * std::size_t(length));
121 
122  while (first != last) {
123  add_fixed<T>(*first++);
124  }
125  }
126 
127  template <typename It>
128  void add_packed_varint(pbf_tag_type tag, It first, It last) {
129  if (first == last) {
130  return;
131  }
132 
133  pbf_writer sw(*this, tag);
134 
135  while (first != last) {
136  sw.add_varint(uint64_t(*first++));
137  }
138  }
139 
140  template <typename It>
141  void add_packed_svarint(pbf_tag_type tag, It first, It last) {
142  if (first == last) {
143  return;
144  }
145 
146  pbf_writer sw(*this, tag);
147 
148  while (first != last) {
149  sw.add_varint(encode_zigzag64(*first++));
150  }
151  }
152 
153  // The number of bytes to reserve for the varint holding the length of
154  // a length-delimited field. The length has to fit into pbf_length_type,
155  // and a varint needs 8 bit for every 7 bit.
156  enum constant_reserve_bytes : int {
157  reserve_bytes = sizeof(pbf_length_type) * 8 / 7 + 1
158  };
159 
160  // If m_rollpack_pos is set to this special value, it means that when
161  // the submessage is closed, nothing needs to be done, because the length
162  // of the submessage has already been written correctly.
163  enum constant_size_is_known : std::size_t {
164  size_is_known = std::numeric_limits<std::size_t>::max()
165  };
166 
167  void open_submessage(pbf_tag_type tag, std::size_t size) {
168  protozero_assert(m_pos == 0);
169  protozero_assert(m_data);
170  if (size == 0) {
171  m_rollback_pos = m_data->size();
172  add_field(tag, pbf_wire_type::length_delimited);
173  m_data->append(std::size_t(reserve_bytes), '\0');
174  } else {
175  m_rollback_pos = size_is_known;
176  add_length_varint(tag, pbf_length_type(size));
177  reserve(size);
178  }
179  m_pos = m_data->size();
180  }
181 
182  void rollback_submessage() {
183  protozero_assert(m_pos != 0);
184  protozero_assert(m_rollback_pos != size_is_known);
185  protozero_assert(m_data);
186  m_data->resize(m_rollback_pos);
187  m_pos = 0;
188  }
189 
190  void commit_submessage() {
191  protozero_assert(m_pos != 0);
192  protozero_assert(m_rollback_pos != size_is_known);
193  protozero_assert(m_data);
194  const auto length = pbf_length_type(m_data->size() - m_pos);
195 
196  protozero_assert(m_data->size() >= m_pos - reserve_bytes);
197  const auto n = write_varint(m_data->begin() + long(m_pos) - reserve_bytes, length);
198 
199  m_data->erase(m_data->begin() + long(m_pos) - reserve_bytes + n, m_data->begin() + long(m_pos));
200  m_pos = 0;
201  }
202 
203  void close_submessage() {
204  protozero_assert(m_data);
205  if (m_pos == 0 || m_rollback_pos == size_is_known) {
206  return;
207  }
208  if (m_data->size() - m_pos == 0) {
209  rollback_submessage();
210  } else {
211  commit_submessage();
212  }
213  }
214 
215  void add_length_varint(pbf_tag_type tag, pbf_length_type length) {
216  add_field(tag, pbf_wire_type::length_delimited);
217  add_varint(length);
218  }
219 
220 public:
221 
227  explicit pbf_writer(std::string& data) noexcept :
228  m_data(&data),
229  m_parent_writer(nullptr),
230  m_pos(0) {
231  }
232 
237  pbf_writer() noexcept :
238  m_data(nullptr),
239  m_parent_writer(nullptr),
240  m_pos(0) {
241  }
242 
253  pbf_writer(pbf_writer& parent_writer, pbf_tag_type tag, std::size_t size=0) :
254  m_data(parent_writer.m_data),
255  m_parent_writer(&parent_writer),
256  m_pos(0) {
257  m_parent_writer->open_submessage(tag, size);
258  }
259 
261  pbf_writer(const pbf_writer&) noexcept = default;
262 
264  pbf_writer& operator=(const pbf_writer&) noexcept = default;
265 
267  pbf_writer(pbf_writer&&) noexcept = default;
268 
270  pbf_writer& operator=(pbf_writer&&) noexcept = default;
271 
272  ~pbf_writer() {
273  if (m_parent_writer) {
274  m_parent_writer->close_submessage();
275  }
276  }
277 
283  void swap(pbf_writer& other) noexcept {
284  using std::swap;
285  swap(m_data, other.m_data);
286  swap(m_parent_writer, other.m_parent_writer);
287  swap(m_rollback_pos, other.m_rollback_pos);
288  swap(m_pos, other.m_pos);
289  }
290 
299  void reserve(std::size_t size) {
300  protozero_assert(m_data);
301  m_data->reserve(m_data->size() + size);
302  }
303 
311  void rollback() {
312  protozero_assert(m_parent_writer && "you can't call rollback() on a pbf_writer without a parent");
313  protozero_assert(m_pos == 0 && "you can't call rollback() on a pbf_writer that has an open nested submessage");
314  m_parent_writer->rollback_submessage();
315  m_data = nullptr;
316  }
317 
319 
329  void add_bool(pbf_tag_type tag, bool value) {
330  add_field(tag, pbf_wire_type::varint);
331  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");
332  protozero_assert(m_data);
333  m_data->append(1, value);
334  }
335 
342  void add_enum(pbf_tag_type tag, int32_t value) {
343  add_tagged_varint(tag, uint64_t(value));
344  }
345 
352  void add_int32(pbf_tag_type tag, int32_t value) {
353  add_tagged_varint(tag, uint64_t(value));
354  }
355 
362  void add_sint32(pbf_tag_type tag, int32_t value) {
363  add_tagged_varint(tag, encode_zigzag32(value));
364  }
365 
372  void add_uint32(pbf_tag_type tag, uint32_t value) {
373  add_tagged_varint(tag, value);
374  }
375 
382  void add_int64(pbf_tag_type tag, int64_t value) {
383  add_tagged_varint(tag, uint64_t(value));
384  }
385 
392  void add_sint64(pbf_tag_type tag, int64_t value) {
393  add_tagged_varint(tag, encode_zigzag64(value));
394  }
395 
402  void add_uint64(pbf_tag_type tag, uint64_t value) {
403  add_tagged_varint(tag, value);
404  }
405 
412  void add_fixed32(pbf_tag_type tag, uint32_t value) {
413  add_field(tag, pbf_wire_type::fixed32);
414  add_fixed<uint32_t>(value);
415  }
416 
423  void add_sfixed32(pbf_tag_type tag, int32_t value) {
424  add_field(tag, pbf_wire_type::fixed32);
425  add_fixed<int32_t>(value);
426  }
427 
434  void add_fixed64(pbf_tag_type tag, uint64_t value) {
435  add_field(tag, pbf_wire_type::fixed64);
436  add_fixed<uint64_t>(value);
437  }
438 
445  void add_sfixed64(pbf_tag_type tag, int64_t value) {
446  add_field(tag, pbf_wire_type::fixed64);
447  add_fixed<int64_t>(value);
448  }
449 
456  void add_float(pbf_tag_type tag, float value) {
457  add_field(tag, pbf_wire_type::fixed32);
458  add_fixed<float>(value);
459  }
460 
467  void add_double(pbf_tag_type tag, double value) {
468  add_field(tag, pbf_wire_type::fixed64);
469  add_fixed<double>(value);
470  }
471 
479  void add_bytes(pbf_tag_type tag, const char* value, std::size_t size) {
480  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");
481  protozero_assert(m_data);
482  protozero_assert(size <= std::numeric_limits<pbf_length_type>::max());
483  add_length_varint(tag, pbf_length_type(size));
484  m_data->append(value, size);
485  }
486 
493  void add_bytes(pbf_tag_type tag, const data_view& value) {
494  add_bytes(tag, value.data(), value.size());
495  }
496 
503  void add_bytes(pbf_tag_type tag, const std::string& value) {
504  add_bytes(tag, value.data(), value.size());
505  }
506 
514  void add_string(pbf_tag_type tag, const char* value, std::size_t size) {
515  add_bytes(tag, value, size);
516  }
517 
524  void add_string(pbf_tag_type tag, const data_view& value) {
525  add_bytes(tag, value.data(), value.size());
526  }
527 
534  void add_string(pbf_tag_type tag, const std::string& value) {
535  add_bytes(tag, value.data(), value.size());
536  }
537 
545  void add_string(pbf_tag_type tag, const char* value) {
546  add_bytes(tag, value, std::strlen(value));
547  }
548 
556  void add_message(pbf_tag_type tag, const char* value, std::size_t size) {
557  add_bytes(tag, value, size);
558  }
559 
566  void add_message(pbf_tag_type tag, const data_view& value) {
567  add_bytes(tag, value.data(), value.size());
568  }
569 
576  void add_message(pbf_tag_type tag, const std::string& value) {
577  add_bytes(tag, value.data(), value.size());
578  }
579 
581 
583 
596  template <typename InputIterator>
597  void add_packed_bool(pbf_tag_type tag, InputIterator first, InputIterator last) {
598  add_packed_varint(tag, first, last);
599  }
600 
610  template <typename InputIterator>
611  void add_packed_enum(pbf_tag_type tag, InputIterator first, InputIterator last) {
612  add_packed_varint(tag, first, last);
613  }
614 
624  template <typename InputIterator>
625  void add_packed_int32(pbf_tag_type tag, InputIterator first, InputIterator last) {
626  add_packed_varint(tag, first, last);
627  }
628 
638  template <typename InputIterator>
639  void add_packed_sint32(pbf_tag_type tag, InputIterator first, InputIterator last) {
640  add_packed_svarint(tag, first, last);
641  }
642 
652  template <typename InputIterator>
653  void add_packed_uint32(pbf_tag_type tag, InputIterator first, InputIterator last) {
654  add_packed_varint(tag, first, last);
655  }
656 
666  template <typename InputIterator>
667  void add_packed_int64(pbf_tag_type tag, InputIterator first, InputIterator last) {
668  add_packed_varint(tag, first, last);
669  }
670 
680  template <typename InputIterator>
681  void add_packed_sint64(pbf_tag_type tag, InputIterator first, InputIterator last) {
682  add_packed_svarint(tag, first, last);
683  }
684 
694  template <typename InputIterator>
695  void add_packed_uint64(pbf_tag_type tag, InputIterator first, InputIterator last) {
696  add_packed_varint(tag, first, last);
697  }
698 
708  template <typename InputIterator>
709  void add_packed_fixed32(pbf_tag_type tag, InputIterator first, InputIterator last) {
710  add_packed_fixed<uint32_t, InputIterator>(tag, first, last,
711  typename std::iterator_traits<InputIterator>::iterator_category());
712  }
713 
723  template <typename InputIterator>
724  void add_packed_sfixed32(pbf_tag_type tag, InputIterator first, InputIterator last) {
725  add_packed_fixed<int32_t, InputIterator>(tag, first, last,
726  typename std::iterator_traits<InputIterator>::iterator_category());
727  }
728 
738  template <typename InputIterator>
739  void add_packed_fixed64(pbf_tag_type tag, InputIterator first, InputIterator last) {
740  add_packed_fixed<uint64_t, InputIterator>(tag, first, last,
741  typename std::iterator_traits<InputIterator>::iterator_category());
742  }
743 
753  template <typename InputIterator>
754  void add_packed_sfixed64(pbf_tag_type tag, InputIterator first, InputIterator last) {
755  add_packed_fixed<int64_t, InputIterator>(tag, first, last,
756  typename std::iterator_traits<InputIterator>::iterator_category());
757  }
758 
768  template <typename InputIterator>
769  void add_packed_float(pbf_tag_type tag, InputIterator first, InputIterator last) {
770  add_packed_fixed<float, InputIterator>(tag, first, last,
771  typename std::iterator_traits<InputIterator>::iterator_category());
772  }
773 
783  template <typename InputIterator>
784  void add_packed_double(pbf_tag_type tag, InputIterator first, InputIterator last) {
785  add_packed_fixed<double, InputIterator>(tag, first, last,
786  typename std::iterator_traits<InputIterator>::iterator_category());
787  }
788 
790 
791  template <typename T> friend class detail::packed_field_varint;
792  template <typename T> friend class detail::packed_field_svarint;
793  template <typename T> friend class detail::packed_field_fixed;
794 
795 }; // class pbf_writer
796 
803 inline void swap(pbf_writer& lhs, pbf_writer& rhs) noexcept {
804  lhs.swap(rhs);
805 }
806 
807 namespace detail {
808 
809  class packed_field {
810 
811  protected:
812 
813  pbf_writer m_writer;
814 
815  public:
816 
817  packed_field(pbf_writer& parent_writer, pbf_tag_type tag) :
818  m_writer(parent_writer, tag) {
819  }
820 
821  packed_field(pbf_writer& parent_writer, pbf_tag_type tag, std::size_t size) :
822  m_writer(parent_writer, tag, size) {
823  }
824 
825  void rollback() {
826  m_writer.rollback();
827  }
828 
829  }; // class packed_field
830 
831  template <typename T>
832  class packed_field_fixed : public packed_field {
833 
834  public:
835 
836  packed_field_fixed(pbf_writer& parent_writer, pbf_tag_type tag) :
837  packed_field(parent_writer, tag) {
838  }
839 
840  packed_field_fixed(pbf_writer& parent_writer, pbf_tag_type tag, std::size_t size) :
841  packed_field(parent_writer, tag, size * sizeof(T)) {
842  }
843 
844  void add_element(T value) {
845  m_writer.add_fixed<T>(value);
846  }
847 
848  }; // class packed_field_fixed
849 
850  template <typename T>
851  class packed_field_varint : public packed_field {
852 
853  public:
854 
855  packed_field_varint(pbf_writer& parent_writer, pbf_tag_type tag) :
856  packed_field(parent_writer, tag) {
857  }
858 
859  void add_element(T value) {
860  m_writer.add_varint(uint64_t(value));
861  }
862 
863  }; // class packed_field_varint
864 
865  template <typename T>
866  class packed_field_svarint : public packed_field {
867 
868  public:
869 
870  packed_field_svarint(pbf_writer& parent_writer, pbf_tag_type tag) :
871  packed_field(parent_writer, tag) {
872  }
873 
874  void add_element(T value) {
875  m_writer.add_varint(encode_zigzag64(value));
876  }
877 
878  }; // class packed_field_svarint
879 
880 } // end namespace detail
881 
883 using packed_field_bool = detail::packed_field_varint<bool>;
884 
886 using packed_field_enum = detail::packed_field_varint<int32_t>;
887 
889 using packed_field_int32 = detail::packed_field_varint<int32_t>;
890 
892 using packed_field_sint32 = detail::packed_field_svarint<int32_t>;
893 
895 using packed_field_uint32 = detail::packed_field_varint<uint32_t>;
896 
898 using packed_field_int64 = detail::packed_field_varint<int64_t>;
899 
901 using packed_field_sint64 = detail::packed_field_svarint<int64_t>;
902 
904 using packed_field_uint64 = detail::packed_field_varint<uint64_t>;
905 
907 using packed_field_fixed32 = detail::packed_field_fixed<uint32_t>;
908 
910 using packed_field_sfixed32 = detail::packed_field_fixed<int32_t>;
911 
913 using packed_field_fixed64 = detail::packed_field_fixed<uint64_t>;
914 
916 using packed_field_sfixed64 = detail::packed_field_fixed<int64_t>;
917 
919 using packed_field_float = detail::packed_field_fixed<float>;
920 
922 using packed_field_double = detail::packed_field_fixed<double>;
923 
924 } // end namespace protozero
925 
926 #endif // PROTOZERO_PBF_WRITER_HPP
void add_packed_fixed64(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: pbf_writer.hpp:739
void add_packed_sint32(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: pbf_writer.hpp:639
detail::packed_field_fixed< float > packed_field_float
Class for generating packed repeated float fields.
Definition: pbf_writer.hpp:919
void add_packed_sint64(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: pbf_writer.hpp:681
void add_string(pbf_tag_type tag, const char *value)
Definition: pbf_writer.hpp:545
void add_packed_sfixed64(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: pbf_writer.hpp:754
void rollback()
Definition: pbf_writer.hpp:311
void add_packed_sfixed32(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: pbf_writer.hpp:724
void reserve(std::size_t size)
Definition: pbf_writer.hpp:299
uint64_t encode_zigzag64(int64_t value) noexcept
Definition: varint.hpp:167
void add_sint64(pbf_tag_type tag, int64_t value)
Definition: pbf_writer.hpp:392
void add_message(pbf_tag_type tag, const char *value, std::size_t size)
Definition: pbf_writer.hpp:556
detail::packed_field_varint< int64_t > packed_field_int64
Class for generating packed repeated int64 fields.
Definition: pbf_writer.hpp:898
void add_sfixed64(pbf_tag_type tag, int64_t value)
Definition: pbf_writer.hpp:445
void add_uint32(pbf_tag_type tag, uint32_t value)
Definition: pbf_writer.hpp:372
void add_bytes(pbf_tag_type tag, const std::string &value)
Definition: pbf_writer.hpp:503
void add_string(pbf_tag_type tag, const char *value, std::size_t size)
Definition: pbf_writer.hpp:514
void add_packed_enum(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: pbf_writer.hpp:611
detail::packed_field_fixed< int64_t > packed_field_sfixed64
Class for generating packed repeated sfixed64 fields.
Definition: pbf_writer.hpp:916
void add_message(pbf_tag_type tag, const data_view &value)
Definition: pbf_writer.hpp:566
Definition: pbf_writer.hpp:51
void add_int64(pbf_tag_type tag, int64_t value)
Definition: pbf_writer.hpp:382
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:883
detail::packed_field_fixed< double > packed_field_double
Class for generating packed repeated double fields.
Definition: pbf_writer.hpp:922
Contains the declaration of low-level types used in the pbf format.
void add_int32(pbf_tag_type tag, int32_t value)
Definition: pbf_writer.hpp:352
void add_string(pbf_tag_type tag, const std::string &value)
Definition: pbf_writer.hpp:534
int write_varint(T data, uint64_t value)
Definition: varint.hpp:144
void add_uint64(pbf_tag_type tag, uint64_t value)
Definition: pbf_writer.hpp:402
constexpr std::size_t size() const noexcept
Return length of data in bytes.
Definition: types.hpp:126
void add_string(pbf_tag_type tag, const data_view &value)
Definition: pbf_writer.hpp:524
detail::packed_field_varint< int32_t > packed_field_int32
Class for generating packed repeated int32 fields.
Definition: pbf_writer.hpp:889
pbf_wire_type
Definition: types.hpp:39
void add_message(pbf_tag_type tag, const std::string &value)
Definition: pbf_writer.hpp:576
void add_float(pbf_tag_type tag, float value)
Definition: pbf_writer.hpp:456
void swap(pbf_writer &other) noexcept
Definition: pbf_writer.hpp:283
void add_enum(pbf_tag_type tag, int32_t value)
Definition: pbf_writer.hpp:342
detail::packed_field_svarint< int64_t > packed_field_sint64
Class for generating packed repeated sint64 fields.
Definition: pbf_writer.hpp:901
void add_packed_uint64(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: pbf_writer.hpp:695
pbf_writer() noexcept
Definition: pbf_writer.hpp:237
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:653
uint32_t encode_zigzag32(int32_t value) noexcept
Definition: varint.hpp:160
void add_packed_int64(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: pbf_writer.hpp:667
void add_fixed64(pbf_tag_type tag, uint64_t value)
Definition: pbf_writer.hpp:434
uint32_t pbf_length_type
Definition: types.hpp:51
void add_bool(pbf_tag_type tag, bool value)
Definition: pbf_writer.hpp:329
void add_packed_bool(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: pbf_writer.hpp:597
detail::packed_field_fixed< uint64_t > packed_field_fixed64
Class for generating packed repeated fixed64 fields.
Definition: pbf_writer.hpp:913
detail::packed_field_fixed< int32_t > packed_field_sfixed32
Class for generating packed repeated sfixed32 fields.
Definition: pbf_writer.hpp:910
uint32_t pbf_tag_type
Definition: types.hpp:32
detail::packed_field_varint< uint32_t > packed_field_uint32
Class for generating packed repeated uint32 fields.
Definition: pbf_writer.hpp:895
void swap(pbf_writer &lhs, pbf_writer &rhs) noexcept
Definition: pbf_writer.hpp:803
void add_packed_double(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: pbf_writer.hpp:784
Definition: types.hpp:63
void add_packed_float(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: pbf_writer.hpp:769
detail::packed_field_varint< uint64_t > packed_field_uint64
Class for generating packed repeated uint64 fields.
Definition: pbf_writer.hpp:904
void add_packed_int32(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: pbf_writer.hpp:625
pbf_writer(pbf_writer &parent_writer, pbf_tag_type tag, std::size_t size=0)
Definition: pbf_writer.hpp:253
constexpr const char * data() const noexcept
Return pointer to data.
Definition: types.hpp:121
void add_sfixed32(pbf_tag_type tag, int32_t value)
Definition: pbf_writer.hpp:423
pbf_writer(std::string &data) noexcept
Definition: pbf_writer.hpp:227
Contains low-level varint and zigzag encoding and decoding functions.
void add_sint32(pbf_tag_type tag, int32_t value)
Definition: pbf_writer.hpp:362
detail::packed_field_varint< int32_t > packed_field_enum
Class for generating packed repeated enum fields.
Definition: pbf_writer.hpp:886
void add_fixed32(pbf_tag_type tag, uint32_t value)
Definition: pbf_writer.hpp:412
detail::packed_field_fixed< uint32_t > packed_field_fixed32
Class for generating packed repeated fixed32 fields.
Definition: pbf_writer.hpp:907
void add_bytes(pbf_tag_type tag, const data_view &value)
Definition: pbf_writer.hpp:493
void add_packed_fixed32(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: pbf_writer.hpp:709
void add_double(pbf_tag_type tag, double value)
Definition: pbf_writer.hpp:467
detail::packed_field_svarint< int32_t > packed_field_sint32
Class for generating packed repeated sint32 fields.
Definition: pbf_writer.hpp:892
void add_bytes(pbf_tag_type tag, const char *value, std::size_t size)
Definition: pbf_writer.hpp:479
All parts of the protozero header-only library are in this namespace.
Definition: byteswap.hpp:24