readVarint method

int readVarint()

Reads a varint, signed as protobuf encodes int32 and int64.

Implementation

int readVarint() {
  var lo = 0; // bits 0..31
  var hi = 0; // bits 32..63
  var shift = 0;
  while (true) {
    if (_offset >= _bytes.length || shift >= 64) {
      throw const FormatException(
        'Malformed protobuf: unterminated or truncated varint',
      );
    }
    final byte = _bytes[_offset++];
    final bits = byte & 0x7F;
    if (shift < 32) {
      lo |= (bits << shift) & 0xFFFFFFFF;
      // A group straddling bit 32 spills its top bits into the high half.
      if (shift > 25) hi |= bits >> (32 - shift);
    } else {
      hi |= (bits << (shift - 32)) & 0xFFFFFFFF;
    }
    if ((byte & 0x80) == 0) break;
    shift += 7;
  }
  lo &= 0xFFFFFFFF;
  hi &= 0xFFFFFFFF;
  // Bit 63 set: the two's complement of a negative int32/int64.
  if ((hi & 0x80000000) != 0) {
    final invLo = (~lo) & 0xFFFFFFFF;
    final invHi = (~hi) & 0xFFFFFFFF;
    final magLo = (invLo + 1) & 0xFFFFFFFF;
    final carry = (invLo + 1) > 0xFFFFFFFF ? 1 : 0;
    return -(((invHi + carry) & 0xFFFFFFFF) * 0x100000000 + magLo);
  }
  return hi * 0x100000000 + lo;
}