1 #ifndef PROTOZERO_PBF_WRITER_HPP
2 #define PROTOZERO_PBF_WRITER_HPP
30 #if __BYTE_ORDER != __LITTLE_ENDIAN
35 #ifndef protozero_assert
36 # define protozero_assert(x) assert(x)
53 inline void add_varint(uint64_t value) {
54 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");
60 protozero_assert(((tag > 0 && tag < 19000) || (tag > 19999 && tag <= ((1 << 29) - 1))) &&
"tag out of range");
61 uint32_t b = (tag << 3) | uint32_t(type);
65 inline void add_tagged_varint(
pbf_tag_type tag, uint64_t value) {
66 add_field(tag, pbf_wire_type::varint);
71 inline void add_fixed(T value) {
72 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 #if __BYTE_ORDER == __LITTLE_ENDIAN
75 m_data->append(reinterpret_cast<const char*>(&value),
sizeof(T));
77 auto size = m_data->size();
78 m_data->resize(size +
sizeof(T));
79 byteswap<sizeof(T)>(
reinterpret_cast<const char*
>(&value), const_cast<char*>(m_data->data() + size));
83 template <
typename T,
typename It>
84 inline void add_packed_fixed(
pbf_tag_type tag, It first, It last, std::input_iterator_tag) {
91 while (first != last) {
92 sw.add_fixed<T>(*first++);
96 template <
typename T,
typename It>
97 inline void add_packed_fixed(
pbf_tag_type tag, It first, It last, std::forward_iterator_tag) {
102 add_length_varint(tag,
sizeof(T) *
pbf_length_type(std::distance(first, last)));
104 while (first != last) {
105 add_fixed<T>(*first++);
109 template <
typename It>
110 inline void add_packed_varint(
pbf_tag_type tag, It first, It last) {
117 while (first != last) {
118 sw.add_varint(uint64_t(*first++));
122 template <
typename It>
123 inline void add_packed_svarint(
pbf_tag_type tag, It first, It last) {
130 while (first != last) {
143 add_field(tag, pbf_wire_type::length_delimited);
144 m_data->append(
size_t(reserve_bytes),
'\0');
145 m_pos = m_data->size();
148 inline void close_submessage() {
154 auto n =
write_varint(m_data->begin() + long(m_pos) - reserve_bytes, length);
156 m_data->erase(m_data->begin() + long(m_pos) - reserve_bytes + n, m_data->begin() + long(m_pos));
161 add_field(tag, pbf_wire_type::length_delimited);
173 m_parent_writer(
nullptr),
183 m_parent_writer(
nullptr),
195 m_data(parent_writer.m_data),
196 m_parent_writer(&parent_writer),
198 m_parent_writer->open_submessage(tag);
214 if (m_parent_writer) {
215 m_parent_writer->close_submessage();
231 add_field(tag, pbf_wire_type::varint);
232 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");
234 m_data->append(1, value);
244 add_tagged_varint(tag, uint64_t(value));
254 add_tagged_varint(tag, uint64_t(value));
274 add_tagged_varint(tag, value);
284 add_tagged_varint(tag, uint64_t(value));
304 add_tagged_varint(tag, value);
314 add_field(tag, pbf_wire_type::fixed32);
315 add_fixed<uint32_t>(value);
325 add_field(tag, pbf_wire_type::fixed32);
326 add_fixed<int32_t>(value);
336 add_field(tag, pbf_wire_type::fixed64);
337 add_fixed<uint64_t>(value);
347 add_field(tag, pbf_wire_type::fixed64);
348 add_fixed<int64_t>(value);
358 add_field(tag, pbf_wire_type::fixed32);
359 add_fixed<float>(value);
369 add_field(tag, pbf_wire_type::fixed64);
370 add_fixed<double>(value);
381 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");
383 assert(size <= std::numeric_limits<pbf_length_type>::max());
385 m_data->append(value, size);
395 add_bytes(tag, value.data(), value.size());
416 add_bytes(tag, value.data(), value.size());
427 add_bytes(tag, value, std::strlen(value));
448 add_bytes(tag, value.data(), value.size());
467 template <
typename InputIterator>
469 add_packed_varint(tag, first, last);
481 template <
typename InputIterator>
483 add_packed_varint(tag, first, last);
495 template <
typename InputIterator>
497 add_packed_varint(tag, first, last);
509 template <
typename InputIterator>
511 add_packed_svarint(tag, first, last);
523 template <
typename InputIterator>
525 add_packed_varint(tag, first, last);
537 template <
typename InputIterator>
539 add_packed_varint(tag, first, last);
551 template <
typename InputIterator>
553 add_packed_svarint(tag, first, last);
565 template <
typename InputIterator>
567 add_packed_varint(tag, first, last);
579 template <
typename InputIterator>
581 add_packed_fixed<uint32_t, InputIterator>(tag, first, last,
582 typename std::iterator_traits<InputIterator>::iterator_category());
594 template <
typename InputIterator>
596 add_packed_fixed<int32_t, InputIterator>(tag, first, last,
597 typename std::iterator_traits<InputIterator>::iterator_category());
609 template <
typename InputIterator>
611 add_packed_fixed<uint64_t, InputIterator>(tag, first, last,
612 typename std::iterator_traits<InputIterator>::iterator_category());
624 template <
typename InputIterator>
626 add_packed_fixed<int64_t, InputIterator>(tag, first, last,
627 typename std::iterator_traits<InputIterator>::iterator_category());
639 template <
typename InputIterator>
641 add_packed_fixed<float, InputIterator>(tag, first, last,
642 typename std::iterator_traits<InputIterator>::iterator_category());
654 template <
typename InputIterator>
656 add_packed_fixed<double, InputIterator>(tag, first, last,
657 typename std::iterator_traits<InputIterator>::iterator_category());
666 #endif // PROTOZERO_PBF_WRITER_HPP
void add_packed_fixed64(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: pbf_writer.hpp:610
void add_packed_sint32(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: pbf_writer.hpp:510
void add_packed_sint64(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: pbf_writer.hpp:552
void add_string(pbf_tag_type tag, const char *value)
Definition: pbf_writer.hpp:426
void add_packed_sfixed64(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: pbf_writer.hpp:625
void add_packed_sfixed32(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: pbf_writer.hpp:595
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:293
void add_sfixed64(pbf_tag_type tag, int64_t value)
Definition: pbf_writer.hpp:346
void add_uint32(pbf_tag_type tag, uint32_t value)
Definition: pbf_writer.hpp:273
void add_bytes(pbf_tag_type tag, const std::string &value)
Definition: pbf_writer.hpp:394
#define protozero_assert(x)
Wrapper for assert() used for testing.
Definition: pbf_writer.hpp:36
void add_packed_enum(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: pbf_writer.hpp:482
Definition: pbf_writer.hpp:47
void add_int64(pbf_tag_type tag, int64_t value)
Definition: pbf_writer.hpp:283
void add_int32(pbf_tag_type tag, int32_t value)
Definition: pbf_writer.hpp:253
void add_string(pbf_tag_type tag, const std::string &value)
Definition: pbf_writer.hpp:415
void add_uint64(pbf_tag_type tag, uint64_t value)
Definition: pbf_writer.hpp:303
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:447
void add_float(pbf_tag_type tag, float value)
Definition: pbf_writer.hpp:357
uint32_t pbf_tag_type
Definition: pbf_types.hpp:26
void add_enum(pbf_tag_type tag, int32_t value)
Definition: pbf_writer.hpp:243
void add_packed_uint64(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: pbf_writer.hpp:566
pbf_writer() noexcept
Definition: pbf_writer.hpp:181
void add_bytes(pbf_tag_type tag, const char *value, size_t size)
Definition: pbf_writer.hpp:380
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:524
uint32_t encode_zigzag32(int32_t value) noexcept
Definition: varint.hpp:105
void add_packed_int64(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: pbf_writer.hpp:538
void add_string(pbf_tag_type tag, const char *value, size_t size)
Definition: pbf_writer.hpp:405
void add_fixed64(pbf_tag_type tag, uint64_t value)
Definition: pbf_writer.hpp:335
void add_bool(pbf_tag_type tag, bool value)
Definition: pbf_writer.hpp:230
void add_packed_bool(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: pbf_writer.hpp:468
void add_packed_double(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: pbf_writer.hpp:655
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:640
pbf_writer(pbf_writer &parent_writer, pbf_tag_type tag)
Definition: pbf_writer.hpp:194
void add_packed_int32(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: pbf_writer.hpp:496
void add_sfixed32(pbf_tag_type tag, int32_t value)
Definition: pbf_writer.hpp:324
pbf_writer(std::string &data) noexcept
Definition: pbf_writer.hpp:171
Contains low-level varint and zigzag encoding and decoding functions.
void add_sint32(pbf_tag_type tag, int32_t value)
Definition: pbf_writer.hpp:263
void add_fixed32(pbf_tag_type tag, uint32_t value)
Definition: pbf_writer.hpp:313
void add_packed_fixed32(pbf_tag_type tag, InputIterator first, InputIterator last)
Definition: pbf_writer.hpp:580
void add_message(pbf_tag_type tag, const char *value, size_t size)
Definition: pbf_writer.hpp:437
void add_double(pbf_tag_type tag, double value)
Definition: pbf_writer.hpp:368
All parts of the protozero header-only library are in this namespace.
Definition: byteswap.hpp:22