protozero: include/protozero/basic_pbf_writer.hpp Source File

protozero 1.8.2 Minimalistic protocol buffer decoder and encoder in C++.

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