#include "binary_wireformat.h" #include #include #include #include #include "absl/strings/string_view.h" #include "google/protobuf/endian.h" #include "google/protobuf/wire_format_lite.h" namespace google { namespace protobuf { namespace conformance { namespace { // The maximum number of bytes that it takes to encode a 64-bit varint. #define VARINT_MAX_LEN 10 size_t vencode64(uint64_t val, int over_encoded_bytes, char* buf) { if (val == 0) { buf[0] = 0; return 1; } size_t i = 0; while (val) { uint8_t byte = val & 0x7fU; val >>= 7; if (val || over_encoded_bytes) byte |= 0x80U; buf[i++] = byte; } while (over_encoded_bytes--) { assert(i < 10); uint8_t byte = over_encoded_bytes ? 0x80 : 0; buf[i++] = byte; } return i; } Wire MakeFixed32(void* data) { uint32_t data_le; std::memcpy(&data_le, data, 4); data_le = ::google::protobuf::internal::little_endian::FromHost(data_le); return Wire(std::string(reinterpret_cast(&data_le), 4)); } Wire MakeFixed64(void* data) { uint64_t data_le; std::memcpy(&data_le, data, 8); data_le = ::google::protobuf::internal::little_endian::FromHost(data_le); return Wire(std::string(reinterpret_cast(&data_le), 8)); } } // namespace Wire Varint(uint64_t x) { char buf[VARINT_MAX_LEN]; size_t len = vencode64(x, 0, buf); return Wire(std::string(buf, len)); } // Encodes a varint that is |extra| bytes longer than it needs to be, but still // valid. Wire LongVarint(uint64_t x, int extra) { char buf[VARINT_MAX_LEN]; size_t len = vencode64(x, extra, buf); return Wire(std::string(buf, len)); } Wire SInt32(int32_t x) { return Varint(::google::protobuf::internal::WireFormatLite::ZigZagEncode32(x)); } Wire SInt64(int64_t x) { return Varint(::google::protobuf::internal::WireFormatLite::ZigZagEncode64(x)); } Wire Fixed32(uint32_t x) { return MakeFixed32(&x); } Wire Fixed64(uint64_t x) { return MakeFixed64(&x); } Wire Float(float f) { return MakeFixed32(&f); } Wire Double(double d) { return MakeFixed64(&d); } Wire LengthPrefixed(absl::string_view data) { return Wire(Varint(data.size()), data); } Wire Tag(uint32_t fieldnum, WireType wire_type) { return Varint((fieldnum << 3) | static_cast(wire_type)); } } // namespace conformance } // namespace protobuf } // namespace google