decode static method

({int next, int value}) decode(
  1. Uint8List src,
  2. int offset,
  3. int end
)

Reads a varint starting at offset, not reading at or past end.

Accumulates into two 32-bit limbs instead of multiplying by 128 repeatedly. On the web every Dart int is a JS number, so a single bits * 128^shift product loses precision past 2^53; limb accumulation keeps each product below that limit and composes hi * 2^32 + lo exactly.

Implementation

static ({int value, int next}) decode(Uint8List src, int offset, int end) {
  var lo = 0;
  var hi = 0;
  var shift = 0;
  var i = offset;
  for (var count = 0; count < 10; count++) {
    if (i >= end) {
      throw VxsFormatException('truncated varint', offset: offset);
    }
    final byte = src[i++];
    final bits = byte & 0x7F;
    if (shift < 32) {
      lo += bits * _pow2[shift ~/ 7];
    } else {
      final k = shift - 32;
      if (k >= 32) {
        throw VxsFormatException('varint wider than 64 bits', offset: offset);
      }
      hi += bits * (1 << k);
    }
    if (byte < 0x80) {
      return (value: hi * 0x100000000 + lo, next: i);
    }
    shift += 7;
  }
  throw VxsFormatException('varint longer than 10 bytes', offset: offset);
}