toBytes static method

List<int> toBytes(
  1. int val, {
  2. int? length,
  3. Endian byteOrder = Endian.big,
  4. bool sign = false,
})

Converts an integer to a byte list with the given length and byte order. Pass sign: true to allow/encode negative values as two's complement. Length auto-sizing (when length is omitted) uses the same sign convention, so the result always round-trips correctly.

Implementation

static List<int> toBytes(
  int val, {
  int? length,
  Endian byteOrder = Endian.big,
  bool sign = false,
}) {
  if (val < 0 && !sign) {
    throw ArgumentException.invalidOperationArguments(
      'toBytes',
      name: 'val',
      reason: 'Negative value requires sign: true.',
    );
  }

  length ??= bitlengthInBytes(val, sign: sign);
  assert(length > 0);

  if (length > 6) {
    return BigintUtils.toBytes(
      BigInt.from(val),
      length: length,
      byteOrder: byteOrder,
      sign: sign,
    );
  }

  // Fold negative values into their two's-complement magnitude up front;
  // length*8 <= 48 here, well within safe-int shift range.
  final int unsigned = val < 0 ? (1 << (length * 8)) + val : val;

  if (length > 4) {
    final int lowerPart = unsigned & BinaryOps.mask32;
    final int upperPart = (unsigned ~/ 0x100000000) & BinaryOps.mask32;
    final bytes = [
      ..._toBytesUpTo4(upperPart, length - 4),
      ..._toBytesUpTo4(lowerPart, 4),
    ];
    return byteOrder == Endian.little ? bytes.reversed.toList() : bytes;
  }

  return _toBytesUpTo4(unsigned, length, byteOrder: byteOrder);
}