writeVarint method
Writes value as a varint; a negative one as the ten bytes of its
64-bit two's complement, as protobuf encodes int32 and int64.
Exact on the web: it never shifts past 32 bits.
Implementation
void writeVarint(int value) {
if (value >= 0) {
var v = value;
while (v >= 0x80) {
_out.addByte((v & 0x7F) | 0x80);
v = v ~/ 0x80;
}
_out.addByte(v & 0x7F);
return;
}
// The unsigned 64-bit two's complement, as 32-bit halves.
final magnitude = -value;
final magLo = magnitude & 0xFFFFFFFF;
final magHi = (magnitude ~/ 0x100000000) & 0xFFFFFFFF;
final invLo = (~magLo) & 0xFFFFFFFF;
final invHi = (~magHi) & 0xFFFFFFFF;
var lo = (invLo + 1) & 0xFFFFFFFF;
final carry = (invLo + 1) > 0xFFFFFFFF ? 1 : 0;
var hi = (invHi + carry) & 0xFFFFFFFF;
// Nine groups of seven bits, each step moving hi's low bits into lo.
for (var i = 0; i < 9; i++) {
_out.addByte((lo & 0x7F) | 0x80);
final carryBits = (hi & 0x7F) * 0x2000000; // hi[0..6] -> lo[25..31]
lo = ((lo ~/ 0x80) + carryBits) & 0xFFFFFFFF;
hi = hi ~/ 0x80;
}
_out.addByte(lo & 0x7F);
}