27namespace kcenon {
namespace monitoring {
namespace protobuf_wire {
39inline void encode_varint(std::vector<std::uint8_t>& out, std::uint64_t value) {
40 while (value >= 0x80) {
41 out.push_back(
static_cast<std::uint8_t
>((value & 0x7F) | 0x80));
44 out.push_back(
static_cast<std::uint8_t
>(value));
51 std::uint32_t field_number,
54 (
static_cast<std::uint64_t
>(field_number) << 3) |
55 static_cast<std::uint64_t
>(wt));
61inline void encode_fixed64(std::vector<std::uint8_t>& out, std::uint64_t value) {
62 for (
int i = 0; i < 8; ++i) {
63 out.push_back(
static_cast<std::uint8_t
>((value >> (i * 8)) & 0xFF));
71 const std::uint8_t* data,
74 out.insert(out.end(), data, data + size);
79 std::uint32_t field_number,
80 const std::string& value) {
87 reinterpret_cast<const std::uint8_t*
>(value.data()),
93 std::uint32_t field_number,
94 const std::vector<std::uint8_t>& value) {
104 std::uint32_t field_number,
105 std::uint64_t value) {
115 std::uint32_t field_number,
116 std::uint64_t value) {
123 std::uint32_t field_number,
124 std::int32_t value) {
134 std::uint32_t field_number,
145 std::uint32_t field_number,
146 std::uint64_t value) {
156 std::uint32_t field_number,
157 const std::vector<std::uint8_t>& serialized) {
179 std::uint64_t result = 0;
183 result |=
static_cast<std::uint64_t
>(
byte & 0x7F) << shift;
184 if ((
byte & 0x80) == 0) {
199 std::uint64_t result = 0;
200 for (
int i = 0; i < 8; ++i) {
201 result |=
static_cast<std::uint64_t
>(
data_[
pos_++]) << (i * 8);
210 std::uint32_t result = 0;
211 for (
int i = 0; i < 4; ++i) {
212 result |=
static_cast<std::uint32_t
>(
data_[
pos_++]) << (i * 8);
223 std::size_t* out_len) {
225 if (!len)
return false;
228 *out_len =
static_cast<std::size_t
>(*len);
234 const std::uint8_t* ptr =
nullptr;
237 out.assign(
reinterpret_cast<const char*
>(ptr), len);
242 const std::uint8_t* ptr =
nullptr;
245 out.assign(ptr, ptr + len);
257 const std::uint8_t* ptr;
277 std::uint32_t& field_number,
280 if (!tag)
return false;
281 field_number =
static_cast<std::uint32_t
>(*tag >> 3);
282 wt =
static_cast<wire_type>(*tag & 0x07);
295 auto nibble = [](
char c) ->
int {
296 if (c >=
'0' && c <=
'9')
return c -
'0';
297 if (c >=
'a' && c <=
'f')
return 10 + (c -
'a');
298 if (c >=
'A' && c <=
'F')
return 10 + (c -
'A');
302 if (s.size() % 2 == 1) {
303 s.insert(s.begin(),
'0');
305 std::vector<std::uint8_t> out;
306 out.reserve(s.size() / 2);
307 for (std::size_t i = 0; i < s.size(); i += 2) {
308 int hi = nibble(s[i]);
309 int lo = nibble(s[i + 1]);
310 if (hi < 0 || lo < 0) {
313 out.push_back(
static_cast<std::uint8_t
>((hi << 4) | lo));
321inline std::string
bytes_to_hex(
const std::vector<std::uint8_t>& bytes) {
322 static const char hex_chars[] =
"0123456789abcdef";
324 out.reserve(bytes.size() * 2);
325 for (std::uint8_t b : bytes) {
326 out.push_back(hex_chars[(b >> 4) & 0x0F]);
327 out.push_back(hex_chars[b & 0x0F]);
336inline std::vector<std::uint8_t>
left_pad(
const std::vector<std::uint8_t>& in,
338 if (in.size() >= width)
return in;
339 std::vector<std::uint8_t> out(width, 0);
340 std::memcpy(out.data() + (width - in.size()), in.data(), in.size());
Minimal protobuf wire reader used for round-trip tests.
std::optional< std::uint64_t > read_fixed64()
std::size_t position() const
std::optional< std::uint32_t > read_fixed32()
bool read_string(std::string &out)
bool read_bytes(std::vector< std::uint8_t > &out)
std::optional< std::uint64_t > read_varint()
const std::uint8_t * data_
reader(const std::uint8_t *data, std::size_t size)
bool read_length_delimited(const std::uint8_t **out_ptr, std::size_t *out_len)
Read a length-delimited payload. Returns pointer into the underlying buffer and the length....
bool skip_field(wire_type wt)
Skip a field whose wire type is given.
void encode_fixed64_field(std::vector< std::uint8_t > &out, std::uint32_t field_number, std::uint64_t value)
Encode a fixed64 field.
void encode_string_field(std::vector< std::uint8_t > &out, std::uint32_t field_number, const std::string &value)
Encode a string field.
void encode_bool_field(std::vector< std::uint8_t > &out, std::uint32_t field_number, bool value)
Encode a bool field (proto3 skips false).
bool decode_tag(reader &r, std::uint32_t &field_number, wire_type &wt)
Decode a tag into (field_number, wire_type).
std::vector< std::uint8_t > left_pad(const std::vector< std::uint8_t > &in, std::size_t width)
Left-pad bytes to a target width. Used to normalize 8-byte trace IDs to Jaeger's 16-byte on-wire widt...
void encode_uint64_field(std::vector< std::uint8_t > &out, std::uint32_t field_number, std::uint64_t value)
Encode a uint32 / uint64 / int64 varint field (skips zero).
void encode_enum_field(std::vector< std::uint8_t > &out, std::uint32_t field_number, std::int32_t value)
Encode an enum field (always written when nonzero).
void encode_bytes_field(std::vector< std::uint8_t > &out, std::uint32_t field_number, const std::vector< std::uint8_t > &value)
Encode a bytes field.
std::string bytes_to_hex(const std::vector< std::uint8_t > &bytes)
Encode raw bytes as a lowercase hex string.
void encode_message_field(std::vector< std::uint8_t > &out, std::uint32_t field_number, const std::vector< std::uint8_t > &serialized)
Encode an embedded message field given its pre-serialized bytes.
void encode_tag(std::vector< std::uint8_t > &out, std::uint32_t field_number, wire_type wt)
Encode a tag (field_number << 3 | wire_type) as a varint.
void encode_varint(std::vector< std::uint8_t > &out, std::uint64_t value)
Encode an unsigned varint into the buffer.
std::vector< std::uint8_t > hex_to_bytes(const std::string &hex)
Decode a hexadecimal string into bytes. Odd-length strings are zero-padded on the left; non-hex chara...
void encode_uint64_field_always(std::vector< std::uint8_t > &out, std::uint32_t field_number, std::uint64_t value)
Encode a uint32 field that is not allowed to be skipped even if zero.
@ varint
int32/int64/uint32/uint64/sint*/bool/enum
@ length_delimited
string/bytes/embedded messages/packed repeated
@ fixed32
fixed32/sfixed32/float
@ fixed64
fixed64/sfixed64/double
void encode_fixed64(std::vector< std::uint8_t > &out, std::uint64_t value)
Encode a fixed64 little-endian value (used for Zipkin timestamps).
void encode_length_delimited(std::vector< std::uint8_t > &out, const std::uint8_t *data, std::size_t size)
Encode a length-delimited byte sequence.