mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-12-11 17:02:25 +00:00
ed1136e49e
rename variant=>varint.
364 lines
8.5 KiB
C++
364 lines
8.5 KiB
C++
#include <cassert>
|
|
#include <Formats/ProtobufSimpleWriter.h>
|
|
#include <IO/WriteHelpers.h>
|
|
|
|
namespace DB
|
|
{
|
|
namespace
|
|
{
|
|
// Note: We cannot simply use writeVarUInt() from IO/VarInt.h here because there is one small difference:
|
|
// Google protobuf's representation of 64-bit integer contains from 1 to 10 bytes, whileas writeVarUInt() writes from 1 to 9 bytes
|
|
// because it omits the tenth byte (which is not necessary to decode actually).
|
|
void writePbVarUInt(UInt64 value, WriteBuffer & buf)
|
|
{
|
|
while (value >= 0x80)
|
|
{
|
|
buf.write(static_cast<char>(value | 0x80));
|
|
value >>= 7;
|
|
}
|
|
buf.write(static_cast<char>(value));
|
|
}
|
|
|
|
void writePbVarInt(Int64 value, WriteBuffer & buf)
|
|
{
|
|
writePbVarUInt((static_cast<UInt64>(value) << 1) ^ static_cast<UInt64>(value >> 63), buf);
|
|
}
|
|
|
|
void writePbVarIntNoZigZagEncoding(Int64 value, WriteBuffer & buf) { writePbVarUInt(static_cast<UInt64>(value), buf); }
|
|
}
|
|
|
|
|
|
enum ProtobufSimpleWriter::WireType : UInt32
|
|
{
|
|
VARINT = 0,
|
|
BITS64 = 1,
|
|
LENGTH_DELIMITED = 2,
|
|
BITS32 = 5
|
|
};
|
|
|
|
ProtobufSimpleWriter::ProtobufSimpleWriter(WriteBuffer & out_) : out(out_)
|
|
{
|
|
}
|
|
|
|
ProtobufSimpleWriter::~ProtobufSimpleWriter()
|
|
{
|
|
finishCurrentMessage();
|
|
}
|
|
|
|
void ProtobufSimpleWriter::newMessage()
|
|
{
|
|
finishCurrentMessage();
|
|
were_messages = true;
|
|
}
|
|
|
|
void ProtobufSimpleWriter::finishCurrentMessage()
|
|
{
|
|
if (!were_messages)
|
|
return;
|
|
finishCurrentField();
|
|
current_field_number = 0;
|
|
StringRef str = message_buffer.stringRef();
|
|
writePbVarUInt(str.size, out);
|
|
out.write(str.data, str.size);
|
|
message_buffer.restart();
|
|
}
|
|
|
|
void ProtobufSimpleWriter::setCurrentField(UInt32 field_number)
|
|
{
|
|
finishCurrentField();
|
|
assert(current_field_number < field_number);
|
|
current_field_number = field_number;
|
|
num_normal_values = 0;
|
|
num_packed_values = 0;
|
|
}
|
|
|
|
void ProtobufSimpleWriter::finishCurrentField()
|
|
{
|
|
if (num_packed_values)
|
|
{
|
|
assert(!num_normal_values);
|
|
StringRef str = repeated_packing_buffer.stringRef();
|
|
if (str.size)
|
|
{
|
|
writeKey(LENGTH_DELIMITED, message_buffer);
|
|
writePbVarUInt(str.size, message_buffer);
|
|
message_buffer.write(str.data, str.size);
|
|
repeated_packing_buffer.restart();
|
|
}
|
|
}
|
|
}
|
|
|
|
void ProtobufSimpleWriter::writeKey(WireType wire_type, WriteBuffer & buf)
|
|
{
|
|
writePbVarUInt((current_field_number << 3) | wire_type, buf);
|
|
}
|
|
|
|
void ProtobufSimpleWriter::writeInt32(Int32 value)
|
|
{
|
|
assert(current_field_number);
|
|
writeKey(VARINT, message_buffer);
|
|
writePbVarIntNoZigZagEncoding(value, message_buffer);
|
|
++num_normal_values;
|
|
}
|
|
|
|
void ProtobufSimpleWriter::writeUInt32(UInt32 value)
|
|
{
|
|
assert(current_field_number);
|
|
writeKey(VARINT, message_buffer);
|
|
writePbVarUInt(value, message_buffer);
|
|
++num_normal_values;
|
|
}
|
|
|
|
void ProtobufSimpleWriter::writeSInt32(Int32 value)
|
|
{
|
|
assert(current_field_number);
|
|
writeKey(VARINT, message_buffer);
|
|
writePbVarInt(value, message_buffer);
|
|
++num_normal_values;
|
|
}
|
|
|
|
void ProtobufSimpleWriter::writeInt64(Int64 value)
|
|
{
|
|
assert(current_field_number);
|
|
writeKey(VARINT, message_buffer);
|
|
writePbVarIntNoZigZagEncoding(value, message_buffer);
|
|
++num_normal_values;
|
|
}
|
|
|
|
void ProtobufSimpleWriter::writeUInt64(UInt64 value)
|
|
{
|
|
assert(current_field_number);
|
|
writeKey(VARINT, message_buffer);
|
|
writePbVarUInt(value, message_buffer);
|
|
++num_normal_values;
|
|
}
|
|
|
|
void ProtobufSimpleWriter::writeSInt64(Int64 value)
|
|
{
|
|
assert(current_field_number);
|
|
writeKey(VARINT, message_buffer);
|
|
writePbVarInt(value, message_buffer);
|
|
++num_normal_values;
|
|
}
|
|
|
|
void ProtobufSimpleWriter::writeFixed32(UInt32 value)
|
|
{
|
|
assert(current_field_number);
|
|
writeKey(BITS32, message_buffer);
|
|
writePODBinary(value, message_buffer);
|
|
++num_normal_values;
|
|
}
|
|
|
|
void ProtobufSimpleWriter::writeSFixed32(Int32 value)
|
|
{
|
|
assert(current_field_number);
|
|
writeKey(BITS32, message_buffer);
|
|
writePODBinary(value, message_buffer);
|
|
++num_normal_values;
|
|
}
|
|
|
|
void ProtobufSimpleWriter::writeFloat(float value)
|
|
{
|
|
assert(current_field_number);
|
|
writeKey(BITS32, message_buffer);
|
|
writePODBinary(value, message_buffer);
|
|
++num_normal_values;
|
|
}
|
|
|
|
void ProtobufSimpleWriter::writeFixed64(UInt64 value)
|
|
{
|
|
assert(current_field_number);
|
|
writeKey(BITS64, message_buffer);
|
|
writePODBinary(value, message_buffer);
|
|
++num_normal_values;
|
|
}
|
|
|
|
void ProtobufSimpleWriter::writeSFixed64(Int64 value)
|
|
{
|
|
assert(current_field_number);
|
|
writeKey(BITS64, message_buffer);
|
|
writePODBinary(value, message_buffer);
|
|
++num_normal_values;
|
|
}
|
|
|
|
void ProtobufSimpleWriter::writeDouble(double value)
|
|
{
|
|
assert(current_field_number);
|
|
writeKey(BITS64, message_buffer);
|
|
writePODBinary(value, message_buffer);
|
|
++num_normal_values;
|
|
}
|
|
|
|
void ProtobufSimpleWriter::writeString(const StringRef & str)
|
|
{
|
|
assert(current_field_number);
|
|
++num_normal_values;
|
|
writeKey(LENGTH_DELIMITED, message_buffer);
|
|
writePbVarUInt(str.size, message_buffer);
|
|
message_buffer.write(str.data, str.size);
|
|
}
|
|
|
|
void ProtobufSimpleWriter::writeInt32IfNonZero(Int32 value)
|
|
{
|
|
if (value)
|
|
writeInt32(value);
|
|
}
|
|
|
|
void ProtobufSimpleWriter::writeUInt32IfNonZero(UInt32 value)
|
|
{
|
|
if (value)
|
|
writeUInt32(value);
|
|
}
|
|
|
|
void ProtobufSimpleWriter::writeSInt32IfNonZero(Int32 value)
|
|
{
|
|
if (value)
|
|
writeSInt32(value);
|
|
}
|
|
|
|
void ProtobufSimpleWriter::writeInt64IfNonZero(Int64 value)
|
|
{
|
|
if (value)
|
|
writeInt64(value);
|
|
}
|
|
|
|
void ProtobufSimpleWriter::writeUInt64IfNonZero(UInt64 value)
|
|
{
|
|
if (value)
|
|
writeUInt64(value);
|
|
}
|
|
|
|
void ProtobufSimpleWriter::writeSInt64IfNonZero(Int64 value)
|
|
{
|
|
if (value)
|
|
writeSInt64(value);
|
|
}
|
|
|
|
void ProtobufSimpleWriter::writeFixed32IfNonZero(UInt32 value)
|
|
{
|
|
if (value)
|
|
writeFixed32(value);
|
|
}
|
|
|
|
void ProtobufSimpleWriter::writeSFixed32IfNonZero(Int32 value)
|
|
{
|
|
if (value)
|
|
writeSFixed32(value);
|
|
}
|
|
|
|
void ProtobufSimpleWriter::writeFloatIfNonZero(float value)
|
|
{
|
|
if (value != 0)
|
|
writeFloat(value);
|
|
}
|
|
|
|
void ProtobufSimpleWriter::writeFixed64IfNonZero(UInt64 value)
|
|
{
|
|
if (value)
|
|
writeFixed64(value);
|
|
}
|
|
|
|
void ProtobufSimpleWriter::writeSFixed64IfNonZero(Int64 value)
|
|
{
|
|
if (value)
|
|
writeSFixed64(value);
|
|
}
|
|
|
|
void ProtobufSimpleWriter::writeDoubleIfNonZero(double value)
|
|
{
|
|
if (value != 0)
|
|
writeDouble(value);
|
|
}
|
|
|
|
void ProtobufSimpleWriter::writeStringIfNotEmpty(const StringRef & str)
|
|
{
|
|
if (str.size)
|
|
writeString(str);
|
|
}
|
|
|
|
void ProtobufSimpleWriter::packRepeatedInt32(Int32 value)
|
|
{
|
|
assert(current_field_number);
|
|
writePbVarIntNoZigZagEncoding(value, repeated_packing_buffer);
|
|
++num_packed_values;
|
|
}
|
|
|
|
void ProtobufSimpleWriter::packRepeatedUInt32(UInt32 value)
|
|
{
|
|
assert(current_field_number);
|
|
writePbVarUInt(value, repeated_packing_buffer);
|
|
++num_packed_values;
|
|
}
|
|
|
|
void ProtobufSimpleWriter::packRepeatedSInt32(Int32 value)
|
|
{
|
|
assert(current_field_number);
|
|
writePbVarInt(value, repeated_packing_buffer);
|
|
++num_packed_values;
|
|
}
|
|
|
|
void ProtobufSimpleWriter::packRepeatedInt64(Int64 value)
|
|
{
|
|
assert(current_field_number);
|
|
writePbVarIntNoZigZagEncoding(value, repeated_packing_buffer);
|
|
++num_packed_values;
|
|
}
|
|
|
|
void ProtobufSimpleWriter::packRepeatedUInt64(UInt64 value)
|
|
{
|
|
assert(current_field_number);
|
|
writePbVarUInt(value, repeated_packing_buffer);
|
|
++num_packed_values;
|
|
}
|
|
|
|
void ProtobufSimpleWriter::packRepeatedSInt64(Int64 value)
|
|
{
|
|
assert(current_field_number);
|
|
writePbVarInt(value, repeated_packing_buffer);
|
|
++num_packed_values;
|
|
}
|
|
|
|
void ProtobufSimpleWriter::packRepeatedFixed32(UInt32 value)
|
|
{
|
|
assert(current_field_number);
|
|
writePODBinary(value, repeated_packing_buffer);
|
|
++num_packed_values;
|
|
}
|
|
|
|
void ProtobufSimpleWriter::packRepeatedSFixed32(Int32 value)
|
|
{
|
|
assert(current_field_number);
|
|
writePODBinary(value, repeated_packing_buffer);
|
|
++num_packed_values;
|
|
}
|
|
|
|
void ProtobufSimpleWriter::packRepeatedFloat(float value)
|
|
{
|
|
assert(current_field_number);
|
|
writePODBinary(value, repeated_packing_buffer);
|
|
++num_packed_values;
|
|
}
|
|
|
|
void ProtobufSimpleWriter::packRepeatedFixed64(UInt64 value)
|
|
{
|
|
assert(current_field_number);
|
|
writePODBinary(value, repeated_packing_buffer);
|
|
++num_packed_values;
|
|
}
|
|
|
|
void ProtobufSimpleWriter::packRepeatedSFixed64(Int64 value)
|
|
{
|
|
assert(current_field_number);
|
|
writePODBinary(value, repeated_packing_buffer);
|
|
++num_packed_values;
|
|
}
|
|
|
|
void ProtobufSimpleWriter::packRepeatedDouble(double value)
|
|
{
|
|
assert(current_field_number);
|
|
writePODBinary(value, repeated_packing_buffer);
|
|
++num_packed_values;
|
|
}
|
|
|
|
}
|