1 #ifndef PROTOZERO_PBF_WRITER_HPP 2 #define PROTOZERO_PBF_WRITER_HPP 30 #if PROTOZERO_BYTE_ORDER != PROTOZERO_LITTLE_ENDIAN 48 inline void add_varint(uint64_t value) {
49 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");
50 protozero_assert(m_data);
55 protozero_assert(((tag > 0 && tag < 19000) || (tag > 19999 && tag <= ((1 << 29) - 1))) &&
"tag out of range");
56 uint32_t b = (tag << 3) | uint32_t(type);
60 inline void add_tagged_varint(
pbf_tag_type tag, uint64_t value) {
61 add_field(tag, pbf_wire_type::varint);
66 inline void add_fixed(T value) {
67 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");
68 protozero_assert(m_data);
69 #if PROTOZERO_BYTE_ORDER == PROTOZERO_LITTLE_ENDIAN 70 m_data->append(reinterpret_cast<const char*>(&value),
sizeof(T));
72 auto size = m_data->size();
73 m_data->resize(size +
sizeof(T));
74 byteswap<sizeof(T)>(
reinterpret_cast<const char*
>(&value), const_cast<char*>(m_data->data() + size));
78 template <
typename T,
typename It>
79 inline void add_packed_fixed(
pbf_tag_type tag, It first, It last, std::input_iterator_tag) {
86 while (first != last) {
87 sw.add_fixed<T>(*first++);
91 template <
typename T,
typename It>
92 inline void add_packed_fixed(
pbf_tag_type tag, It first, It last, std::forward_iterator_tag) {
97 add_length_varint(tag,
sizeof(T) *
pbf_length_type(std::distance(first, last)));
99 while (first != last) {
100 add_fixed<T>(*first++);
104 template <
typename It>
105 inline void add_packed_varint(
pbf_tag_type tag, It first, It last) {
112 while (first != last) {
113 sw.add_varint(uint64_t(*first++));
117 template <
typename It>
118 inline void add_packed_svarint(
pbf_tag_type tag, It first, It last) {
125 while (first != last) {
136 protozero_assert(m_pos == 0);
137 protozero_assert(m_data);
138 add_field(tag, pbf_wire_type::length_delimited);
139 m_data->append(
size_t(reserve_bytes),
'\0');
140 m_pos = m_data->size();
143 inline void close_submessage() {
144 protozero_assert(m_pos != 0);
145 protozero_assert(m_data);
148 protozero_assert(m_data->size() >= m_pos - reserve_bytes);
149 auto n =
write_varint(m_data->begin() + long(m_pos) - reserve_bytes, length);
151 m_data->erase(m_data->begin() + long(m_pos) - reserve_bytes + n, m_data->begin() + long(m_pos));
156 add_field(tag, pbf_wire_type::length_delimited);
168 m_parent_writer(
nullptr),
178 m_parent_writer(
nullptr),
190 m_data(parent_writer.m_data),
191 m_parent_writer(&parent_writer),
193 m_parent_writer->open_submessage(tag);
209 if (m_parent_writer) {
210 m_parent_writer->close_submessage();
226 add_field(tag, pbf_wire_type::varint);
227 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");
228 protozero_assert(m_data);
229 m_data->append(1, value);
239 add_tagged_varint(tag, uint64_t(value));
249 add_tagged_varint(tag, uint64_t(value));
269 add_tagged_varint(tag, value);
279 add_tagged_varint(tag, uint64_t(value));
299 add_tagged_varint(tag, value);
309 add_field(tag, pbf_wire_type::fixed32);
310 add_fixed<uint32_t>(value);
320 add_field(tag, pbf_wire_type::fixed32);
321 add_fixed<int32_t>(value);
331 add_field(tag, pbf_wire_type::fixed64);
332 add_fixed<uint64_t>(value);
342 add_field(tag, pbf_wire_type::fixed64);
343 add_fixed<int64_t>(value);
353 add_field(tag, pbf_wire_type::fixed32);
354 add_fixed<float>(value);
364 add_field(tag, pbf_wire_type::fixed64);
365 add_fixed<double>(value);
376 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");
377 protozero_assert(m_data);
378 protozero_assert(size <= std::numeric_limits<pbf_length_type>::max());
380 m_data->append(value, size);
390 add_bytes(tag, value.data(), value.size());
411 add_bytes(tag, value.data(), value.size());
422 add_bytes(tag, value, std::strlen(value));
443 add_bytes(tag, value.data(), value.size());
462 template <
typename InputIterator>
464 add_packed_varint(tag, first, last);
476 template <
typename InputIterator>
478 add_packed_varint(tag, first, last);
490 template <
typename InputIterator>
492 add_packed_varint(tag, first, last);
504 template <
typename InputIterator>
506 add_packed_svarint(tag, first, last);
518 template <
typename InputIterator>
520 add_packed_varint(tag, first, last);
532 template <
typename InputIterator>
534 add_packed_varint(tag, first, last);
546 template <
typename InputIterator>
548 add_packed_svarint(tag, first, last);
560 template <
typename InputIterator>
562 add_packed_varint(tag, first, last);
574 template <
typename InputIterator>
576 add_packed_fixed<uint32_t, InputIterator>(tag, first, last,
577 typename std::iterator_traits<InputIterator>::iterator_category());
589 template <
typename InputIterator>
591 add_packed_fixed<int32_t, InputIterator>(tag, first, last,
592 typename std::iterator_traits<InputIterator>::iterator_category());
604 template <
typename InputIterator>
606 add_packed_fixed<uint64_t, InputIterator>(tag, first, last,
607 typename std::iterator_traits<InputIterator>::iterator_category());
619 template <
typename InputIterator>
621 add_packed_fixed<int64_t, InputIterator>(tag, first, last,
622 typename std::iterator_traits<InputIterator>::iterator_category());
634 template <
typename InputIterator>
636 add_packed_fixed<float, InputIterator>(tag, first, last,
637 typename std::iterator_traits<InputIterator>::iterator_category());
649 template <
typename InputIterator>
651 add_packed_fixed<double, InputIterator>(tag, first, last,
652 typename std::iterator_traits<InputIterator>::iterator_category());
661 #endif // PROTOZERO_PBF_WRITER_HPP void add_packed_fixed64(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: pbf_writer.hpp:605
void add_packed_sint32(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: pbf_writer.hpp:505
void add_packed_sint64(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: pbf_writer.hpp:547
void add_string(pbf_tag_type tag, const char *value)
Definition: pbf_writer.hpp:421
void add_packed_sfixed64(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: pbf_writer.hpp:620
void add_packed_sfixed32(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: pbf_writer.hpp:590
uint32_t pbf_length_type
Definition: pbf_types.hpp:45
uint64_t encode_zigzag64(int64_t value) noexcept
Definition: varint.hpp:112
void add_sint64(pbf_tag_type tag, int64_t value)
Definition: pbf_writer.hpp:288
void add_sfixed64(pbf_tag_type tag, int64_t value)
Definition: pbf_writer.hpp:341
void add_uint32(pbf_tag_type tag, uint32_t value)
Definition: pbf_writer.hpp:268
void add_bytes(pbf_tag_type tag, const std::string &value)
Definition: pbf_writer.hpp:389
void add_packed_enum(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: pbf_writer.hpp:477
Definition: pbf_writer.hpp:42
void add_int64(pbf_tag_type tag, int64_t value)
Definition: pbf_writer.hpp:278
Contains macro checks for different configurations.
void add_int32(pbf_tag_type tag, int32_t value)
Definition: pbf_writer.hpp:248
void add_string(pbf_tag_type tag, const std::string &value)
Definition: pbf_writer.hpp:410
void add_uint64(pbf_tag_type tag, uint64_t value)
Definition: pbf_writer.hpp:298
pbf_wire_type
Definition: pbf_types.hpp:33
Contains the declaration of low-level types used in the pbf format.
void add_message(pbf_tag_type tag, const std::string &value)
Definition: pbf_writer.hpp:442
void add_float(pbf_tag_type tag, float value)
Definition: pbf_writer.hpp:352
uint32_t pbf_tag_type
Definition: pbf_types.hpp:26
void add_enum(pbf_tag_type tag, int32_t value)
Definition: pbf_writer.hpp:238
void add_packed_uint64(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: pbf_writer.hpp:561
pbf_writer() noexcept
Definition: pbf_writer.hpp:176
void add_bytes(pbf_tag_type tag, const char *value, size_t size)
Definition: pbf_writer.hpp:375
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:519
uint32_t encode_zigzag32(int32_t value) noexcept
Definition: varint.hpp:105
pbf_writer & operator=(const pbf_writer &) noexcept=default
A pbf_writer object can be copied.
void add_packed_int64(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: pbf_writer.hpp:533
void add_string(pbf_tag_type tag, const char *value, size_t size)
Definition: pbf_writer.hpp:400
void add_fixed64(pbf_tag_type tag, uint64_t value)
Definition: pbf_writer.hpp:330
void add_bool(pbf_tag_type tag, bool value)
Definition: pbf_writer.hpp:225
void add_packed_bool(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: pbf_writer.hpp:463
void add_packed_double(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: pbf_writer.hpp:650
int write_varint(OutputIterator data, uint64_t value)
Definition: varint.hpp:89
void add_packed_float(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: pbf_writer.hpp:635
pbf_writer(pbf_writer &parent_writer, pbf_tag_type tag)
Definition: pbf_writer.hpp:189
void add_packed_int32(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: pbf_writer.hpp:491
void add_sfixed32(pbf_tag_type tag, int32_t value)
Definition: pbf_writer.hpp:319
pbf_writer(std::string &data) noexcept
Definition: pbf_writer.hpp:166
Contains low-level varint and zigzag encoding and decoding functions.
void add_sint32(pbf_tag_type tag, int32_t value)
Definition: pbf_writer.hpp:258
void add_fixed32(pbf_tag_type tag, uint32_t value)
Definition: pbf_writer.hpp:308
void add_packed_fixed32(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: pbf_writer.hpp:575
void add_message(pbf_tag_type tag, const char *value, size_t size)
Definition: pbf_writer.hpp:432
void add_double(pbf_tag_type tag, double value)
Definition: pbf_writer.hpp:363
All parts of the protozero header-only library are in this namespace.
Definition: byteswap.hpp:24