protozero
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 <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  m_data->append(reinterpret_cast<const char*>(&value), sizeof(T));
95 #else
96  const auto size = m_data->size();
97  m_data->resize(size + sizeof(T));
98  byteswap<sizeof(T)>(reinterpret_cast<const char*>(&value), const_cast<char*>(m_data->data() + size));
99 #endif
100  }
101 
102  template <typename T, typename It>
103  void add_packed_fixed(pbf_tag_type tag, It first, It last, std::input_iterator_tag) {
104  if (first == last) {
105  return;
106  }
107 
108  pbf_writer sw(*this, tag);
109 
110  while (first != last) {
111  sw.add_fixed<T>(*first++);
112  }
113  }
114 
115  template <typename T, typename It>
116  void add_packed_fixed(pbf_tag_type tag, It first, It last, std::forward_iterator_tag) {
117  if (first == last) {
118  return;
119  }
120 
121  const auto length = std::distance(first, last);
122  add_length_varint(tag, sizeof(T) * pbf_length_type(length));
123  reserve(sizeof(T) * std::size_t(length));
124 
125  while (first != last) {
126  add_fixed<T>(*first++);
127  }
128  }
129 
130  template <typename It>
131  void add_packed_varint(pbf_tag_type tag, It first, It last) {
132  if (first == last) {
133  return;
134  }
135 
136  pbf_writer sw(*this, tag);
137 
138  while (first != last) {
139  sw.add_varint(uint64_t(*first++));
140  }
141  }
142 
143  template <typename It>
144  void add_packed_svarint(pbf_tag_type tag, It first, It last) {
145  if (first == last) {
146  return;
147  }
148 
149  pbf_writer sw(*this, tag);
150 
151  while (first != last) {
152  sw.add_varint(encode_zigzag64(*first++));
153  }
154  }
155 
156  // The number of bytes to reserve for the varint holding the length of
157  // a length-delimited field. The length has to fit into pbf_length_type,
158  // and a varint needs 8 bit for every 7 bit.
159  enum constant_reserve_bytes : int {
160  reserve_bytes = sizeof(pbf_length_type) * 8 / 7 + 1
161  };
162 
163  // If m_rollpack_pos is set to this special value, it means that when
164  // the submessage is closed, nothing needs to be done, because the length
165  // of the submessage has already been written correctly.
166  enum constant_size_is_known : std::size_t {
167  size_is_known = std::numeric_limits<std::size_t>::max()
168  };
169 
170  void open_submessage(pbf_tag_type tag, std::size_t size) {
171  protozero_assert(m_pos == 0);
172  protozero_assert(m_data);
173  if (size == 0) {
174  m_rollback_pos = m_data->size();
175  add_field(tag, pbf_wire_type::length_delimited);
176  m_data->append(std::size_t(reserve_bytes), '\0');
177  } else {
178  m_rollback_pos = size_is_known;
179  add_length_varint(tag, pbf_length_type(size));
180  reserve(size);
181  }
182  m_pos = m_data->size();
183  }
184 
185  void rollback_submessage() {
186  protozero_assert(m_pos != 0);
187  protozero_assert(m_rollback_pos != size_is_known);
188  protozero_assert(m_data);
189  m_data->resize(m_rollback_pos);
190  m_pos = 0;
191  }
192 
193  void commit_submessage() {
194  protozero_assert(m_pos != 0);
195  protozero_assert(m_rollback_pos != size_is_known);
196  protozero_assert(m_data);
197  const auto length = pbf_length_type(m_data->size() - m_pos);
198 
199  protozero_assert(m_data->size() >= m_pos - reserve_bytes);
200  const auto n = write_varint(m_data->begin() + long(m_pos) - reserve_bytes, length);
201 
202  m_data->erase(m_data->begin() + long(m_pos) - reserve_bytes + n, m_data->begin() + long(m_pos));
203  m_pos = 0;
204  }
205 
206  void close_submessage() {
207  protozero_assert(m_data);
208  if (m_pos == 0 || m_rollback_pos == size_is_known) {
209  return;
210  }
211  if (m_data->size() - m_pos == 0) {
212  rollback_submessage();
213  } else {
214  commit_submessage();
215  }
216  }
217 
218  void add_length_varint(pbf_tag_type tag, pbf_length_type length) {
219  add_field(tag, pbf_wire_type::length_delimited);
220  add_varint(length);
221  }
222 
223 public:
224 
230  explicit pbf_writer(std::string& data) noexcept :
231  m_data(&data),
232  m_parent_writer(nullptr),
233  m_pos(0) {
234  }
235 
240  pbf_writer() noexcept :
241  m_data(nullptr),
242  m_parent_writer(nullptr),
243  m_pos(0) {
244  }
245 
256  pbf_writer(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_pos(0) {
260  m_parent_writer->open_submessage(tag, size);
261  }
262 
264  pbf_writer(const pbf_writer&) noexcept = default;
265 
267  pbf_writer& operator=(const pbf_writer&) noexcept = default;
268 
270  pbf_writer(pbf_writer&&) noexcept = default;
271 
273  pbf_writer& operator=(pbf_writer&&) noexcept = default;
274 
275  ~pbf_writer() {
276  if (m_parent_writer) {
277  m_parent_writer->close_submessage();
278  }
279  }
280 
286  void swap(pbf_writer& other) noexcept {
287  using std::swap;
288  swap(m_data, other.m_data);
289  swap(m_parent_writer, other.m_parent_writer);
290  swap(m_rollback_pos, other.m_rollback_pos);
291  swap(m_pos, other.m_pos);
292  }
293 
302  void reserve(std::size_t size) {
303  protozero_assert(m_data);
304  m_data->reserve(m_data->size() + size);
305  }
306 
314  void rollback() {
315  protozero_assert(m_parent_writer && "you can't call rollback() on a pbf_writer without a parent");
316  protozero_assert(m_pos == 0 && "you can't call rollback() on a pbf_writer that has an open nested submessage");
317  m_parent_writer->rollback_submessage();
318  m_data = nullptr;
319  }
320 
322 
332  void add_bool(pbf_tag_type tag, bool value) {
333  add_field(tag, pbf_wire_type::varint);
334  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");
335  protozero_assert(m_data);
336  m_data->append(1, value);
337  }
338 
345  void add_enum(pbf_tag_type tag, int32_t value) {
346  add_tagged_varint(tag, uint64_t(value));
347  }
348 
355  void add_int32(pbf_tag_type tag, int32_t value) {
356  add_tagged_varint(tag, uint64_t(value));
357  }
358 
365  void add_sint32(pbf_tag_type tag, int32_t value) {
366  add_tagged_varint(tag, encode_zigzag32(value));
367  }
368 
375  void add_uint32(pbf_tag_type tag, uint32_t value) {
376  add_tagged_varint(tag, value);
377  }
378 
385  void add_int64(pbf_tag_type tag, int64_t value) {
386  add_tagged_varint(tag, uint64_t(value));
387  }
388 
395  void add_sint64(pbf_tag_type tag, int64_t value) {
396  add_tagged_varint(tag, encode_zigzag64(value));
397  }
398 
405  void add_uint64(pbf_tag_type tag, uint64_t value) {
406  add_tagged_varint(tag, value);
407  }
408 
415  void add_fixed32(pbf_tag_type tag, uint32_t value) {
416  add_field(tag, pbf_wire_type::fixed32);
417  add_fixed<uint32_t>(value);
418  }
419 
426  void add_sfixed32(pbf_tag_type tag, int32_t value) {
427  add_field(tag, pbf_wire_type::fixed32);
428  add_fixed<int32_t>(value);
429  }
430 
437  void add_fixed64(pbf_tag_type tag, uint64_t value) {
438  add_field(tag, pbf_wire_type::fixed64);
439  add_fixed<uint64_t>(value);
440  }
441 
448  void add_sfixed64(pbf_tag_type tag, int64_t value) {
449  add_field(tag, pbf_wire_type::fixed64);
450  add_fixed<int64_t>(value);
451  }
452 
459  void add_float(pbf_tag_type tag, float value) {
460  add_field(tag, pbf_wire_type::fixed32);
461  add_fixed<float>(value);
462  }
463 
470  void add_double(pbf_tag_type tag, double value) {
471  add_field(tag, pbf_wire_type::fixed64);
472  add_fixed<double>(value);
473  }
474 
482  void add_bytes(pbf_tag_type tag, const char* value, std::size_t size) {
483  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");
484  protozero_assert(m_data);
485  protozero_assert(size <= std::numeric_limits<pbf_length_type>::max());
486  add_length_varint(tag, pbf_length_type(size));
487  m_data->append(value, size);
488  }
489 
496  void add_bytes(pbf_tag_type tag, const data_view& value) {
497  add_bytes(tag, value.data(), value.size());
498  }
499 
506  void add_bytes(pbf_tag_type tag, const std::string& value) {
507  add_bytes(tag, value.data(), value.size());
508  }
509 
517  void add_string(pbf_tag_type tag, const char* value, std::size_t size) {
518  add_bytes(tag, value, size);
519  }
520 
527  void add_string(pbf_tag_type tag, const data_view& value) {
528  add_bytes(tag, value.data(), value.size());
529  }
530 
537  void add_string(pbf_tag_type tag, const std::string& value) {
538  add_bytes(tag, value.data(), value.size());
539  }
540 
548  void add_string(pbf_tag_type tag, const char* value) {
549  add_bytes(tag, value, std::strlen(value));
550  }
551 
559  void add_message(pbf_tag_type tag, const char* value, std::size_t size) {
560  add_bytes(tag, value, size);
561  }
562 
569  void add_message(pbf_tag_type tag, const data_view& value) {
570  add_bytes(tag, value.data(), value.size());
571  }
572 
579  void add_message(pbf_tag_type tag, const std::string& value) {
580  add_bytes(tag, value.data(), value.size());
581  }
582 
584 
586 
599  template <typename InputIterator>
600  void add_packed_bool(pbf_tag_type tag, InputIterator first, InputIterator last) {
601  add_packed_varint(tag, first, last);
602  }
603 
613  template <typename InputIterator>
614  void add_packed_enum(pbf_tag_type tag, InputIterator first, InputIterator last) {
615  add_packed_varint(tag, first, last);
616  }
617 
627  template <typename InputIterator>
628  void add_packed_int32(pbf_tag_type tag, InputIterator first, InputIterator last) {
629  add_packed_varint(tag, first, last);
630  }
631 
641  template <typename InputIterator>
642  void add_packed_sint32(pbf_tag_type tag, InputIterator first, InputIterator last) {
643  add_packed_svarint(tag, first, last);
644  }
645 
655  template <typename InputIterator>
656  void add_packed_uint32(pbf_tag_type tag, InputIterator first, InputIterator last) {
657  add_packed_varint(tag, first, last);
658  }
659 
669  template <typename InputIterator>
670  void add_packed_int64(pbf_tag_type tag, InputIterator first, InputIterator last) {
671  add_packed_varint(tag, first, last);
672  }
673 
683  template <typename InputIterator>
684  void add_packed_sint64(pbf_tag_type tag, InputIterator first, InputIterator last) {
685  add_packed_svarint(tag, first, last);
686  }
687 
697  template <typename InputIterator>
698  void add_packed_uint64(pbf_tag_type tag, InputIterator first, InputIterator last) {
699  add_packed_varint(tag, first, last);
700  }
701 
711  template <typename InputIterator>
712  void add_packed_fixed32(pbf_tag_type tag, InputIterator first, InputIterator last) {
713  add_packed_fixed<uint32_t, InputIterator>(tag, first, last,
714  typename std::iterator_traits<InputIterator>::iterator_category());
715  }
716 
726  template <typename InputIterator>
727  void add_packed_sfixed32(pbf_tag_type tag, InputIterator first, InputIterator last) {
728  add_packed_fixed<int32_t, InputIterator>(tag, first, last,
729  typename std::iterator_traits<InputIterator>::iterator_category());
730  }
731 
741  template <typename InputIterator>
742  void add_packed_fixed64(pbf_tag_type tag, InputIterator first, InputIterator last) {
743  add_packed_fixed<uint64_t, InputIterator>(tag, first, last,
744  typename std::iterator_traits<InputIterator>::iterator_category());
745  }
746 
756  template <typename InputIterator>
757  void add_packed_sfixed64(pbf_tag_type tag, InputIterator first, InputIterator last) {
758  add_packed_fixed<int64_t, InputIterator>(tag, first, last,
759  typename std::iterator_traits<InputIterator>::iterator_category());
760  }
761 
771  template <typename InputIterator>
772  void add_packed_float(pbf_tag_type tag, InputIterator first, InputIterator last) {
773  add_packed_fixed<float, InputIterator>(tag, first, last,
774  typename std::iterator_traits<InputIterator>::iterator_category());
775  }
776 
786  template <typename InputIterator>
787  void add_packed_double(pbf_tag_type tag, InputIterator first, InputIterator last) {
788  add_packed_fixed<double, InputIterator>(tag, first, last,
789  typename std::iterator_traits<InputIterator>::iterator_category());
790  }
791 
793 
794  template <typename T> friend class detail::packed_field_varint;
795  template <typename T> friend class detail::packed_field_svarint;
796  template <typename T> friend class detail::packed_field_fixed;
797 
798 }; // class pbf_writer
799 
806 inline void swap(pbf_writer& lhs, pbf_writer& rhs) noexcept {
807  lhs.swap(rhs);
808 }
809 
810 namespace detail {
811 
812  class packed_field {
813 
814  protected:
815 
816  pbf_writer m_writer;
817 
818  public:
819 
820  packed_field(pbf_writer& parent_writer, pbf_tag_type tag) :
821  m_writer(parent_writer, tag) {
822  }
823 
824  packed_field(pbf_writer& parent_writer, pbf_tag_type tag, std::size_t size) :
825  m_writer(parent_writer, tag, size) {
826  }
827 
828  void rollback() {
829  m_writer.rollback();
830  }
831 
832  }; // class packed_field
833 
834  template <typename T>
835  class packed_field_fixed : public packed_field {
836 
837  public:
838 
839  packed_field_fixed(pbf_writer& parent_writer, pbf_tag_type tag) :
840  packed_field(parent_writer, tag) {
841  }
842 
843  packed_field_fixed(pbf_writer& parent_writer, pbf_tag_type tag, std::size_t size) :
844  packed_field(parent_writer, tag, size * sizeof(T)) {
845  }
846 
847  void add_element(T value) {
848  m_writer.add_fixed<T>(value);
849  }
850 
851  }; // class packed_field_fixed
852 
853  template <typename T>
854  class packed_field_varint : public packed_field {
855 
856  public:
857 
858  packed_field_varint(pbf_writer& parent_writer, pbf_tag_type tag) :
859  packed_field(parent_writer, tag) {
860  }
861 
862  void add_element(T value) {
863  m_writer.add_varint(uint64_t(value));
864  }
865 
866  }; // class packed_field_varint
867 
868  template <typename T>
869  class packed_field_svarint : public packed_field {
870 
871  public:
872 
873  packed_field_svarint(pbf_writer& parent_writer, pbf_tag_type tag) :
874  packed_field(parent_writer, tag) {
875  }
876 
877  void add_element(T value) {
878  m_writer.add_varint(encode_zigzag64(value));
879  }
880 
881  }; // class packed_field_svarint
882 
883 } // end namespace detail
884 
886 using packed_field_bool = detail::packed_field_varint<bool>;
887 
889 using packed_field_enum = detail::packed_field_varint<int32_t>;
890 
892 using packed_field_int32 = detail::packed_field_varint<int32_t>;
893 
895 using packed_field_sint32 = detail::packed_field_svarint<int32_t>;
896 
898 using packed_field_uint32 = detail::packed_field_varint<uint32_t>;
899 
901 using packed_field_int64 = detail::packed_field_varint<int64_t>;
902 
904 using packed_field_sint64 = detail::packed_field_svarint<int64_t>;
905 
907 using packed_field_uint64 = detail::packed_field_varint<uint64_t>;
908 
910 using packed_field_fixed32 = detail::packed_field_fixed<uint32_t>;
911 
913 using packed_field_sfixed32 = detail::packed_field_fixed<int32_t>;
914 
916 using packed_field_fixed64 = detail::packed_field_fixed<uint64_t>;
917 
919 using packed_field_sfixed64 = detail::packed_field_fixed<int64_t>;
920 
922 using packed_field_float = detail::packed_field_fixed<float>;
923 
925 using packed_field_double = detail::packed_field_fixed<double>;
926 
927 } // end namespace protozero
928 
929 #endif // PROTOZERO_PBF_WRITER_HPP
void add_packed_fixed64(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: pbf_writer.hpp:742
void add_packed_sint32(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: pbf_writer.hpp:642
detail::packed_field_fixed< float > packed_field_float
Class for generating packed repeated float fields.
Definition: pbf_writer.hpp:922
void add_packed_sint64(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: pbf_writer.hpp:684
void add_string(pbf_tag_type tag, const char *value)
Definition: pbf_writer.hpp:548
void add_packed_sfixed64(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: pbf_writer.hpp:757
void rollback()
Definition: pbf_writer.hpp:314
void add_packed_sfixed32(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: pbf_writer.hpp:727
void reserve(std::size_t size)
Definition: pbf_writer.hpp:302
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:395
void add_message(pbf_tag_type tag, const char *value, std::size_t size)
Definition: pbf_writer.hpp:559
detail::packed_field_varint< int64_t > packed_field_int64
Class for generating packed repeated int64 fields.
Definition: pbf_writer.hpp:901
void add_sfixed64(pbf_tag_type tag, int64_t value)
Definition: pbf_writer.hpp:448
void add_uint32(pbf_tag_type tag, uint32_t value)
Definition: pbf_writer.hpp:375
void add_bytes(pbf_tag_type tag, const std::string &value)
Definition: pbf_writer.hpp:506
void add_string(pbf_tag_type tag, const char *value, std::size_t size)
Definition: pbf_writer.hpp:517
void add_packed_enum(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: pbf_writer.hpp:614
detail::packed_field_fixed< int64_t > packed_field_sfixed64
Class for generating packed repeated sfixed64 fields.
Definition: pbf_writer.hpp:919
void add_message(pbf_tag_type tag, const data_view &value)
Definition: pbf_writer.hpp:569
Definition: pbf_writer.hpp:51
void add_int64(pbf_tag_type tag, int64_t value)
Definition: pbf_writer.hpp:385
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:886
detail::packed_field_fixed< double > packed_field_double
Class for generating packed repeated double fields.
Definition: pbf_writer.hpp:925
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:355
void add_string(pbf_tag_type tag, const std::string &value)
Definition: pbf_writer.hpp:537
int write_varint(T data, uint64_t value)
Definition: varint.hpp:144
void swap(iterator_range< T > &lhs, iterator_range< T > &rhs) noexcept
Definition: iterators.hpp:152
void add_uint64(pbf_tag_type tag, uint64_t value)
Definition: pbf_writer.hpp:405
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:527
detail::packed_field_varint< int32_t > packed_field_int32
Class for generating packed repeated int32 fields.
Definition: pbf_writer.hpp:892
pbf_wire_type
Definition: types.hpp:39
void add_message(pbf_tag_type tag, const std::string &value)
Definition: pbf_writer.hpp:579
void add_float(pbf_tag_type tag, float value)
Definition: pbf_writer.hpp:459
void swap(pbf_writer &other) noexcept
Definition: pbf_writer.hpp:286
void add_enum(pbf_tag_type tag, int32_t value)
Definition: pbf_writer.hpp:345
detail::packed_field_svarint< int64_t > packed_field_sint64
Class for generating packed repeated sint64 fields.
Definition: pbf_writer.hpp:904
void add_packed_uint64(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: pbf_writer.hpp:698
pbf_writer() noexcept
Definition: pbf_writer.hpp:240
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:656
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:670
void add_fixed64(pbf_tag_type tag, uint64_t value)
Definition: pbf_writer.hpp:437
uint32_t pbf_length_type
Definition: types.hpp:51
void add_bool(pbf_tag_type tag, bool value)
Definition: pbf_writer.hpp:332
void add_packed_bool(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: pbf_writer.hpp:600
detail::packed_field_fixed< uint64_t > packed_field_fixed64
Class for generating packed repeated fixed64 fields.
Definition: pbf_writer.hpp:916
detail::packed_field_fixed< int32_t > packed_field_sfixed32
Class for generating packed repeated sfixed32 fields.
Definition: pbf_writer.hpp:913
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:898
void swap(pbf_writer &lhs, pbf_writer &rhs) noexcept
Definition: pbf_writer.hpp:806
void add_packed_double(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: pbf_writer.hpp:787
Definition: types.hpp:63
void add_packed_float(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: pbf_writer.hpp:772
detail::packed_field_varint< uint64_t > packed_field_uint64
Class for generating packed repeated uint64 fields.
Definition: pbf_writer.hpp:907
void add_packed_int32(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: pbf_writer.hpp:628
pbf_writer(pbf_writer &parent_writer, pbf_tag_type tag, std::size_t size=0)
Definition: pbf_writer.hpp:256
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:426
pbf_writer(std::string &data) noexcept
Definition: pbf_writer.hpp:230
Contains low-level varint and zigzag encoding and decoding functions.
void add_sint32(pbf_tag_type tag, int32_t value)
Definition: pbf_writer.hpp:365
detail::packed_field_varint< int32_t > packed_field_enum
Class for generating packed repeated enum fields.
Definition: pbf_writer.hpp:889
void add_fixed32(pbf_tag_type tag, uint32_t value)
Definition: pbf_writer.hpp:415
detail::packed_field_fixed< uint32_t > packed_field_fixed32
Class for generating packed repeated fixed32 fields.
Definition: pbf_writer.hpp:910
void add_bytes(pbf_tag_type tag, const data_view &value)
Definition: pbf_writer.hpp:496
void add_packed_fixed32(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: pbf_writer.hpp:712
void add_double(pbf_tag_type tag, double value)
Definition: pbf_writer.hpp:470
detail::packed_field_svarint< int32_t > packed_field_sint32
Class for generating packed repeated sint32 fields.
Definition: pbf_writer.hpp:895
void add_bytes(pbf_tag_type tag, const char *value, std::size_t size)
Definition: pbf_writer.hpp:482
All parts of the protozero header-only library are in this namespace.
Definition: byteswap.hpp:24