MySQLBinaryResultSetRowPacket.decode constructor

MySQLBinaryResultSetRowPacket.decode(
  1. Uint8List buffer,
  2. List<MySQLColumnDefinitionPacket> colDefs, {
  3. List<bool>? textualColumns,
})

Decodifica um pacote de linha de result set no modo binário.

buffer é o pacote recebido do servidor. colDefs é a lista de definições de coluna que contém os tipos de cada coluna.

Retorna uma instância de MySQLBinaryResultSetRowPacket com os valores decodificados.

Lança MySQLProtocolException se o header do pacote não for 0x00.

Implementation

factory MySQLBinaryResultSetRowPacket.decode(
    Uint8List buffer, List<MySQLColumnDefinitionPacket> colDefs,
    {List<bool>? textualColumns}) {
  if (buffer.isEmpty) {
    throw const MySQLProtocolException(
      'Cannot decode MySQLBinaryResultSetRowPacket: empty packet buffer',
    );
  }

  // O primeiro byte do pacote deve ser 0x00 (header).
  if (buffer[0] != 0) {
    throw const MySQLProtocolException(
      'Cannot decode MySQLBinaryResultSetRowPacket: packet type is not 0x00',
    );
  }

  final numCols = colDefs.length;
  // Inicializa a lista de valores (pode conter diferentes tipos).
  final values = List<dynamic>.filled(numCols, null, growable: false);
  if (numCols == 0) {
    return MySQLBinaryResultSetRowPacket(values: values);
  }

  // Calcula o tamanho do null bitmap.
  // O tamanho do bitmap é determinado por: ((numCols + 9) / 8).floor()
  final nullBitmapSize = (numCols + 9) >> 3;
  const nullBitmapOffset = 1;
  var offset = nullBitmapOffset + nullBitmapSize;
  if (offset > buffer.length) {
    throw const MySQLProtocolException(
      'Cannot decode MySQLBinaryResultSetRowPacket: truncated null bitmap',
    );
  }

  final byteData = ByteData.sublistView(buffer);

  // Itera sobre cada coluna para decodificar os dados.
  for (var x = 0; x < numCols; x++) {
    // Determina qual byte e bit verificar no bitmap.
    final bit = x + 2;
    final byteToCheck = buffer[nullBitmapOffset + (bit >> 3)];
    if ((byteToCheck & (1 << (bit & 7))) != 0) {
      // Já inicializado com null.
      continue;
    }

    final knownTextual = (textualColumns != null && x < textualColumns.length)
        ? textualColumns[x]
        : null;
    final decoded = _decodeBinaryRowColumn(
      colDefs[x],
      byteData,
      buffer,
      offset,
      knownTextual,
    );
    values[x] = decoded.value;
    offset = decoded.nextOffset;
  }

  return MySQLBinaryResultSetRowPacket(
    values: values,
  );
}