1 #ifndef PROTOZERO_PBF_READER_HPP 2 #define PROTOZERO_PBF_READER_HPP 30 #if PROTOZERO_BYTE_ORDER != PROTOZERO_LITTLE_ENDIAN 63 const char* m_data =
nullptr;
66 const char* m_end =
nullptr;
77 skip_bytes(
sizeof(T));
78 std::memcpy(&result, m_data -
sizeof(T),
sizeof(T));
79 #if PROTOZERO_BYTE_ORDER != PROTOZERO_LITTLE_ENDIAN 80 detail::byteswap_inplace(&result);
87 protozero_assert(
tag() != 0 &&
"call next() before accessing field value");
88 const auto len = get_len_and_skip();
89 protozero_assert(len %
sizeof(T) == 0);
106 return get_varint<pbf_length_type>();
110 if (m_data + len > m_end) {
123 const auto len = get_length();
128 template <
typename T>
130 protozero_assert(
tag() != 0 &&
"call next() before accessing field value");
131 const auto len = get_len_and_skip();
149 : m_data(view.data()),
150 m_end(view.data() + view.size()),
151 m_wire_type(pbf_wire_type::unknown),
168 m_wire_type(pbf_wire_type::unknown),
182 pbf_reader(
const std::pair<const char*, std::size_t>& data) noexcept
183 : m_data(data.first),
184 m_end(data.first + data.second),
185 m_wire_type(pbf_wire_type::unknown),
200 : m_data(data.data()),
201 m_end(data.data() + data.size()),
202 m_wire_type(pbf_wire_type::unknown),
233 swap(m_data, other.m_data);
234 swap(m_end, other.m_end);
235 swap(m_wire_type, other.m_wire_type);
236 swap(m_tag, other.m_tag);
244 operator bool() const noexcept {
245 return m_data < m_end;
258 return std::size_t(m_end - m_data);
277 if (m_data == m_end) {
281 const auto value = get_varint<uint32_t>();
286 protozero_assert(((m_tag > 0 && m_tag < 19000) ||
287 (m_tag > 19999 && m_tag <= ((1 << 29) - 1))) &&
"tag out of range");
290 switch (m_wire_type) {
291 case pbf_wire_type::varint:
292 case pbf_wire_type::fixed64:
293 case pbf_wire_type::length_delimited:
294 case pbf_wire_type::fixed32:
333 if (m_tag == next_tag) {
372 if (m_tag == next_tag && m_wire_type == wire_type) {
456 protozero_assert(
tag() != 0 &&
"call next() before calling skip()");
458 case pbf_wire_type::varint:
461 case pbf_wire_type::fixed64:
464 case pbf_wire_type::length_delimited:
465 skip_bytes(get_length());
467 case pbf_wire_type::fixed32:
471 protozero_assert(
false &&
"can not be here because next() should have thrown already");
488 protozero_assert(
tag() != 0 &&
"call next() before accessing field value");
489 protozero_assert(
has_wire_type(pbf_wire_type::varint) &&
"not a varint");
490 protozero_assert((*m_data & 0x80) == 0 &&
"not a 1 byte varint");
492 return m_data[-1] != 0;
503 protozero_assert(
has_wire_type(pbf_wire_type::varint) &&
"not a varint");
504 return get_varint<int32_t>();
515 protozero_assert(
has_wire_type(pbf_wire_type::varint) &&
"not a varint");
516 return get_varint<int32_t>();
527 protozero_assert(
has_wire_type(pbf_wire_type::varint) &&
"not a varint");
528 return get_svarint<int32_t>();
539 protozero_assert(
has_wire_type(pbf_wire_type::varint) &&
"not a varint");
540 return get_varint<uint32_t>();
551 protozero_assert(
has_wire_type(pbf_wire_type::varint) &&
"not a varint");
552 return get_varint<int64_t>();
563 protozero_assert(
has_wire_type(pbf_wire_type::varint) &&
"not a varint");
564 return get_svarint<int64_t>();
575 protozero_assert(
has_wire_type(pbf_wire_type::varint) &&
"not a varint");
576 return get_varint<uint64_t>();
587 protozero_assert(
tag() != 0 &&
"call next() before accessing field value");
588 protozero_assert(
has_wire_type(pbf_wire_type::fixed32) &&
"not a 32-bit fixed");
589 return get_fixed<uint32_t>();
600 protozero_assert(
tag() != 0 &&
"call next() before accessing field value");
601 protozero_assert(
has_wire_type(pbf_wire_type::fixed32) &&
"not a 32-bit fixed");
602 return get_fixed<int32_t>();
613 protozero_assert(
tag() != 0 &&
"call next() before accessing field value");
614 protozero_assert(
has_wire_type(pbf_wire_type::fixed64) &&
"not a 64-bit fixed");
615 return get_fixed<uint64_t>();
626 protozero_assert(
tag() != 0 &&
"call next() before accessing field value");
627 protozero_assert(
has_wire_type(pbf_wire_type::fixed64) &&
"not a 64-bit fixed");
628 return get_fixed<int64_t>();
639 protozero_assert(
tag() != 0 &&
"call next() before accessing field value");
640 protozero_assert(
has_wire_type(pbf_wire_type::fixed32) &&
"not a 32-bit fixed");
641 return get_fixed<float>();
652 protozero_assert(
tag() != 0 &&
"call next() before accessing field value");
653 protozero_assert(
has_wire_type(pbf_wire_type::fixed64) &&
"not a 64-bit fixed");
654 return get_fixed<double>();
667 protozero_assert(
tag() != 0 &&
"call next() before accessing field value");
668 protozero_assert(
has_wire_type(pbf_wire_type::length_delimited) &&
"not of type string, bytes or message");
669 const auto len = get_len_and_skip();
673 #ifndef PROTOZERO_STRICT_API 682 std::pair<const char*, pbf_length_type>
get_data() {
683 protozero_assert(
tag() != 0 &&
"call next() before accessing field value");
684 protozero_assert(
has_wire_type(pbf_wire_type::length_delimited) &&
"not of type string, bytes or message");
685 const auto len = get_len_and_skip();
686 return std::make_pair(m_data - len, len);
764 return get_packed<pbf_reader::const_bool_iterator>();
777 return get_packed<pbf_reader::const_enum_iterator>();
790 return get_packed<pbf_reader::const_int32_iterator>();
803 return get_packed<pbf_reader::const_sint32_iterator>();
816 return get_packed<pbf_reader::const_uint32_iterator>();
829 return get_packed<pbf_reader::const_int64_iterator>();
842 return get_packed<pbf_reader::const_sint64_iterator>();
855 return get_packed<pbf_reader::const_uint64_iterator>();
868 return packed_fixed<uint32_t>();
881 return packed_fixed<int32_t>();