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  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  }
231 
236  pbf_writer() noexcept :
237  m_data(nullptr),
238  m_parent_writer(nullptr) {
239  }
240 
251  pbf_writer(pbf_writer& parent_writer, pbf_tag_type tag, std::size_t size=0) :
252  m_data(parent_writer.m_data),
253  m_parent_writer(&parent_writer) {
254  m_parent_writer->open_submessage(tag, size);
255  }
256 
258  pbf_writer(const pbf_writer&) noexcept = default;
259 
261  pbf_writer& operator=(const pbf_writer&) noexcept = default;
262 
264  pbf_writer(pbf_writer&&) noexcept = default;
265 
267  pbf_writer& operator=(pbf_writer&&) noexcept = default;
268 
269  ~pbf_writer() {
270  if (m_parent_writer) {
271  m_parent_writer->close_submessage();
272  }
273  }
274 
280  void swap(pbf_writer& other) noexcept {
281  using std::swap;
282  swap(m_data, other.m_data);
283  swap(m_parent_writer, other.m_parent_writer);
284  swap(m_rollback_pos, other.m_rollback_pos);
285  swap(m_pos, other.m_pos);
286  }
287 
296  void reserve(std::size_t size) {
297  protozero_assert(m_data);
298  m_data->reserve(m_data->size() + size);
299  }
300 
308  void rollback() {
309  protozero_assert(m_parent_writer && "you can't call rollback() on a pbf_writer without a parent");
310  protozero_assert(m_pos == 0 && "you can't call rollback() on a pbf_writer that has an open nested submessage");
311  m_parent_writer->rollback_submessage();
312  m_data = nullptr;
313  }
314 
316 
326  void add_bool(pbf_tag_type tag, bool value) {
327  add_field(tag, pbf_wire_type::varint);
328  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");
329  protozero_assert(m_data);
330  m_data->append(1, value);
331  }
332 
339  void add_enum(pbf_tag_type tag, int32_t value) {
340  add_tagged_varint(tag, uint64_t(value));
341  }
342 
349  void add_int32(pbf_tag_type tag, int32_t value) {
350  add_tagged_varint(tag, uint64_t(value));
351  }
352 
359  void add_sint32(pbf_tag_type tag, int32_t value) {
360  add_tagged_varint(tag, encode_zigzag32(value));
361  }
362 
369  void add_uint32(pbf_tag_type tag, uint32_t value) {
370  add_tagged_varint(tag, value);
371  }
372 
379  void add_int64(pbf_tag_type tag, int64_t value) {
380  add_tagged_varint(tag, uint64_t(value));
381  }
382 
389  void add_sint64(pbf_tag_type tag, int64_t value) {
390  add_tagged_varint(tag, encode_zigzag64(value));
391  }
392 
399  void add_uint64(pbf_tag_type tag, uint64_t value) {
400  add_tagged_varint(tag, value);
401  }
402 
409  void add_fixed32(pbf_tag_type tag, uint32_t value) {
410  add_field(tag, pbf_wire_type::fixed32);
411  add_fixed<uint32_t>(value);
412  }
413 
420  void add_sfixed32(pbf_tag_type tag, int32_t value) {
421  add_field(tag, pbf_wire_type::fixed32);
422  add_fixed<int32_t>(value);
423  }
424 
431  void add_fixed64(pbf_tag_type tag, uint64_t value) {
432  add_field(tag, pbf_wire_type::fixed64);
433  add_fixed<uint64_t>(value);
434  }
435 
442  void add_sfixed64(pbf_tag_type tag, int64_t value) {
443  add_field(tag, pbf_wire_type::fixed64);
444  add_fixed<int64_t>(value);
445  }
446 
453  void add_float(pbf_tag_type tag, float value) {
454  add_field(tag, pbf_wire_type::fixed32);
455  add_fixed<float>(value);
456  }
457 
464  void add_double(pbf_tag_type tag, double value) {
465  add_field(tag, pbf_wire_type::fixed64);
466  add_fixed<double>(value);
467  }
468 
476  void add_bytes(pbf_tag_type tag, const char* value, std::size_t size) {
477  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");
478  protozero_assert(m_data);
479  protozero_assert(size <= std::numeric_limits<pbf_length_type>::max());
480  add_length_varint(tag, pbf_length_type(size));
481  m_data->append(value, size);
482  }
483 
490  void add_bytes(pbf_tag_type tag, const data_view& value) {
491  add_bytes(tag, value.data(), value.size());
492  }
493 
500  void add_bytes(pbf_tag_type tag, const std::string& value) {
501  add_bytes(tag, value.data(), value.size());
502  }
503 
523  template <typename... Ts>
524  void add_bytes_vectored(pbf_tag_type tag, Ts&&... values) {
525  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");
526  protozero_assert(m_data);
527  size_t sum_size = 0;
528  (void)std::initializer_list<size_t>{sum_size += values.size()...};
529  protozero_assert(sum_size <= std::numeric_limits<pbf_length_type>::max());
530  add_length_varint(tag, pbf_length_type(sum_size));
531  m_data->reserve(m_data->size() + sum_size);
532  (void)std::initializer_list<int>{(m_data->append(values.data(), values.size()), 0)...};
533  }
534 
542  void add_string(pbf_tag_type tag, const char* value, std::size_t size) {
543  add_bytes(tag, value, size);
544  }
545 
552  void add_string(pbf_tag_type tag, const data_view& value) {
553  add_bytes(tag, value.data(), value.size());
554  }
555 
562  void add_string(pbf_tag_type tag, const std::string& value) {
563  add_bytes(tag, value.data(), value.size());
564  }
565 
573  void add_string(pbf_tag_type tag, const char* value) {
574  add_bytes(tag, value, std::strlen(value));
575  }
576 
584  void add_message(pbf_tag_type tag, const char* value, std::size_t size) {
585  add_bytes(tag, value, size);
586  }
587 
594  void add_message(pbf_tag_type tag, const data_view& value) {
595  add_bytes(tag, value.data(), value.size());
596  }
597 
604  void add_message(pbf_tag_type tag, const std::string& value) {
605  add_bytes(tag, value.data(), value.size());
606  }
607 
609 
611 
624  template <typename InputIterator>
625  void add_packed_bool(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_enum(pbf_tag_type tag, InputIterator first, InputIterator last) {
640  add_packed_varint(tag, first, last);
641  }
642 
652  template <typename InputIterator>
653  void add_packed_int32(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_sint32(pbf_tag_type tag, InputIterator first, InputIterator last) {
668  add_packed_svarint(tag, first, last);
669  }
670 
680  template <typename InputIterator>
681  void add_packed_uint32(pbf_tag_type tag, InputIterator first, InputIterator last) {
682  add_packed_varint(tag, first, last);
683  }
684 
694  template <typename InputIterator>
695  void add_packed_int64(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_sint64(pbf_tag_type tag, InputIterator first, InputIterator last) {
710  add_packed_svarint(tag, first, last);
711  }
712 
722  template <typename InputIterator>
723  void add_packed_uint64(pbf_tag_type tag, InputIterator first, InputIterator last) {
724  add_packed_varint(tag, first, last);
725  }
726 
736  template <typename InputIterator>
737  void add_packed_fixed32(pbf_tag_type tag, InputIterator first, InputIterator last) {
738  add_packed_fixed<uint32_t, InputIterator>(tag, first, last,
739  typename std::iterator_traits<InputIterator>::iterator_category());
740  }
741 
751  template <typename InputIterator>
752  void add_packed_sfixed32(pbf_tag_type tag, InputIterator first, InputIterator last) {
753  add_packed_fixed<int32_t, InputIterator>(tag, first, last,
754  typename std::iterator_traits<InputIterator>::iterator_category());
755  }
756 
766  template <typename InputIterator>
767  void add_packed_fixed64(pbf_tag_type tag, InputIterator first, InputIterator last) {
768  add_packed_fixed<uint64_t, InputIterator>(tag, first, last,
769  typename std::iterator_traits<InputIterator>::iterator_category());
770  }
771 
781  template <typename InputIterator>
782  void add_packed_sfixed64(pbf_tag_type tag, InputIterator first, InputIterator last) {
783  add_packed_fixed<int64_t, InputIterator>(tag, first, last,
784  typename std::iterator_traits<InputIterator>::iterator_category());
785  }
786 
796  template <typename InputIterator>
797  void add_packed_float(pbf_tag_type tag, InputIterator first, InputIterator last) {
798  add_packed_fixed<float, InputIterator>(tag, first, last,
799  typename std::iterator_traits<InputIterator>::iterator_category());
800  }
801 
811  template <typename InputIterator>
812  void add_packed_double(pbf_tag_type tag, InputIterator first, InputIterator last) {
813  add_packed_fixed<double, InputIterator>(tag, first, last,
814  typename std::iterator_traits<InputIterator>::iterator_category());
815  }
816 
818 
819  template <typename T> friend class detail::packed_field_varint;
820  template <typename T> friend class detail::packed_field_svarint;
821  template <typename T> friend class detail::packed_field_fixed;
822 
823 }; // class pbf_writer
824 
831 inline void swap(pbf_writer& lhs, pbf_writer& rhs) noexcept {
832  lhs.swap(rhs);
833 }
834 
835 namespace detail {
836 
837  class packed_field {
838 
839  protected:
840 
841  pbf_writer m_writer;
842 
843  public:
844 
845  packed_field(const packed_field&) = delete;
846  packed_field& operator=(const packed_field&) = delete;
847 
848  packed_field(packed_field&&) = default;
849  packed_field& operator=(packed_field&&) = default;
850 
851  packed_field(pbf_writer& parent_writer, pbf_tag_type tag) :
852  m_writer(parent_writer, tag) {
853  }
854 
855  packed_field(pbf_writer& parent_writer, pbf_tag_type tag, std::size_t size) :
856  m_writer(parent_writer, tag, size) {
857  }
858 
859  void rollback() {
860  m_writer.rollback();
861  }
862 
863  }; // class packed_field
864 
865  template <typename T>
866  class packed_field_fixed : public packed_field {
867 
868  public:
869 
870  template <typename P>
871  packed_field_fixed(pbf_writer& parent_writer, P tag) :
872  packed_field(parent_writer, static_cast<pbf_tag_type>(tag)) {
873  }
874 
875  template <typename P>
876  packed_field_fixed(pbf_writer& parent_writer, P tag, std::size_t size) :
877  packed_field(parent_writer, static_cast<pbf_tag_type>(tag), size * sizeof(T)) {
878  }
879 
880  void add_element(T value) {
881  m_writer.add_fixed<T>(value);
882  }
883 
884  }; // class packed_field_fixed
885 
886  template <typename T>
887  class packed_field_varint : public packed_field {
888 
889  public:
890 
891  template <typename P>
892  packed_field_varint(pbf_writer& parent_writer, P tag) :
893  packed_field(parent_writer, static_cast<pbf_tag_type>(tag)) {
894  }
895 
896  void add_element(T value) {
897  m_writer.add_varint(uint64_t(value));
898  }
899 
900  }; // class packed_field_varint
901 
902  template <typename T>
903  class packed_field_svarint : public packed_field {
904 
905  public:
906 
907  template <typename P>
908  packed_field_svarint(pbf_writer& parent_writer, P tag) :
909  packed_field(parent_writer, static_cast<pbf_tag_type>(tag)) {
910  }
911 
912  void add_element(T value) {
913  m_writer.add_varint(encode_zigzag64(value));
914  }
915 
916  }; // class packed_field_svarint
917 
918 } // end namespace detail
919 
921 using packed_field_bool = detail::packed_field_varint<bool>;
922 
924 using packed_field_enum = detail::packed_field_varint<int32_t>;
925 
927 using packed_field_int32 = detail::packed_field_varint<int32_t>;
928 
930 using packed_field_sint32 = detail::packed_field_svarint<int32_t>;
931 
933 using packed_field_uint32 = detail::packed_field_varint<uint32_t>;
934 
936 using packed_field_int64 = detail::packed_field_varint<int64_t>;
937 
939 using packed_field_sint64 = detail::packed_field_svarint<int64_t>;
940 
942 using packed_field_uint64 = detail::packed_field_varint<uint64_t>;
943 
945 using packed_field_fixed32 = detail::packed_field_fixed<uint32_t>;
946 
948 using packed_field_sfixed32 = detail::packed_field_fixed<int32_t>;
949 
951 using packed_field_fixed64 = detail::packed_field_fixed<uint64_t>;
952 
954 using packed_field_sfixed64 = detail::packed_field_fixed<int64_t>;
955 
957 using packed_field_float = detail::packed_field_fixed<float>;
958 
960 using packed_field_double = detail::packed_field_fixed<double>;
961 
962 } // end namespace protozero
963 
964 #endif // PROTOZERO_PBF_WRITER_HPP
void add_packed_fixed64(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: pbf_writer.hpp:767
void add_packed_sint32(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: pbf_writer.hpp:667
detail::packed_field_fixed< float > packed_field_float
Class for generating packed repeated float fields.
Definition: pbf_writer.hpp:957
void add_packed_sint64(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: pbf_writer.hpp:709
void add_string(pbf_tag_type tag, const char *value)
Definition: pbf_writer.hpp:573
void add_packed_sfixed64(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: pbf_writer.hpp:782
void rollback()
Definition: pbf_writer.hpp:308
void add_packed_sfixed32(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: pbf_writer.hpp:752
constexpr uint64_t encode_zigzag64(int64_t value) noexcept
Definition: varint.hpp:167
void reserve(std::size_t size)
Definition: pbf_writer.hpp:296
void add_sint64(pbf_tag_type tag, int64_t value)
Definition: pbf_writer.hpp:389
void add_message(pbf_tag_type tag, const char *value, std::size_t size)
Definition: pbf_writer.hpp:584
detail::packed_field_varint< int64_t > packed_field_int64
Class for generating packed repeated int64 fields.
Definition: pbf_writer.hpp:936
void add_sfixed64(pbf_tag_type tag, int64_t value)
Definition: pbf_writer.hpp:442
void add_uint32(pbf_tag_type tag, uint32_t value)
Definition: pbf_writer.hpp:369
void add_bytes(pbf_tag_type tag, const std::string &value)
Definition: pbf_writer.hpp:500
void add_string(pbf_tag_type tag, const char *value, std::size_t size)
Definition: pbf_writer.hpp:542
void add_packed_enum(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: pbf_writer.hpp:639
detail::packed_field_fixed< int64_t > packed_field_sfixed64
Class for generating packed repeated sfixed64 fields.
Definition: pbf_writer.hpp:954
void add_message(pbf_tag_type tag, const data_view &value)
Definition: pbf_writer.hpp:594
Definition: pbf_writer.hpp:51
void add_int64(pbf_tag_type tag, int64_t value)
Definition: pbf_writer.hpp:379
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:921
detail::packed_field_fixed< double > packed_field_double
Class for generating packed repeated double fields.
Definition: pbf_writer.hpp:960
Contains the declaration of low-level types used in the pbf format.
constexpr uint32_t encode_zigzag32(int32_t value) noexcept
Definition: varint.hpp:160
void add_int32(pbf_tag_type tag, int32_t value)
Definition: pbf_writer.hpp:349
void add_string(pbf_tag_type tag, const std::string &value)
Definition: pbf_writer.hpp:562
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:137
void add_uint64(pbf_tag_type tag, uint64_t value)
Definition: pbf_writer.hpp:399
constexpr std::size_t size() const noexcept
Return length of data in bytes.
Definition: types.hpp:137
void add_string(pbf_tag_type tag, const data_view &value)
Definition: pbf_writer.hpp:552
detail::packed_field_varint< int32_t > packed_field_int32
Class for generating packed repeated int32 fields.
Definition: pbf_writer.hpp:927
pbf_wire_type
Definition: types.hpp:39
void add_message(pbf_tag_type tag, const std::string &value)
Definition: pbf_writer.hpp:604
void add_float(pbf_tag_type tag, float value)
Definition: pbf_writer.hpp:453
void swap(pbf_writer &other) noexcept
Definition: pbf_writer.hpp:280
void add_enum(pbf_tag_type tag, int32_t value)
Definition: pbf_writer.hpp:339
detail::packed_field_svarint< int64_t > packed_field_sint64
Class for generating packed repeated sint64 fields.
Definition: pbf_writer.hpp:939
void add_packed_uint64(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: pbf_writer.hpp:723
pbf_writer() noexcept
Definition: pbf_writer.hpp:236
void add_bytes_vectored(pbf_tag_type tag, Ts &&... values)
Definition: pbf_writer.hpp:524
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:681
void add_packed_int64(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: pbf_writer.hpp:695
void add_fixed64(pbf_tag_type tag, uint64_t value)
Definition: pbf_writer.hpp:431
uint32_t pbf_length_type
Definition: types.hpp:62
void add_bool(pbf_tag_type tag, bool value)
Definition: pbf_writer.hpp:326
void add_packed_bool(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: pbf_writer.hpp:625
detail::packed_field_fixed< uint64_t > packed_field_fixed64
Class for generating packed repeated fixed64 fields.
Definition: pbf_writer.hpp:951
detail::packed_field_fixed< int32_t > packed_field_sfixed32
Class for generating packed repeated sfixed32 fields.
Definition: pbf_writer.hpp:948
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:933
void swap(pbf_writer &lhs, pbf_writer &rhs) noexcept
Definition: pbf_writer.hpp:831
void add_packed_double(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: pbf_writer.hpp:812
Definition: types.hpp:74
void add_packed_float(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: pbf_writer.hpp:797
detail::packed_field_varint< uint64_t > packed_field_uint64
Class for generating packed repeated uint64 fields.
Definition: pbf_writer.hpp:942
void add_packed_int32(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: pbf_writer.hpp:653
pbf_writer(pbf_writer &parent_writer, pbf_tag_type tag, std::size_t size=0)
Definition: pbf_writer.hpp:251
constexpr const char * data() const noexcept
Return pointer to data.
Definition: types.hpp:132
void add_sfixed32(pbf_tag_type tag, int32_t value)
Definition: pbf_writer.hpp:420
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:359
detail::packed_field_varint< int32_t > packed_field_enum
Class for generating packed repeated enum fields.
Definition: pbf_writer.hpp:924
void add_fixed32(pbf_tag_type tag, uint32_t value)
Definition: pbf_writer.hpp:409
detail::packed_field_fixed< uint32_t > packed_field_fixed32
Class for generating packed repeated fixed32 fields.
Definition: pbf_writer.hpp:945
void add_bytes(pbf_tag_type tag, const data_view &value)
Definition: pbf_writer.hpp:490
void add_packed_fixed32(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: pbf_writer.hpp:737
void add_double(pbf_tag_type tag, double value)
Definition: pbf_writer.hpp:464
detail::packed_field_svarint< int32_t > packed_field_sint32
Class for generating packed repeated sint32 fields.
Definition: pbf_writer.hpp:930
void add_bytes(pbf_tag_type tag, const char *value, std::size_t size)
Definition: pbf_writer.hpp:476
All parts of the protozero header-only library are in this namespace.
Definition: byteswap.hpp:24