MySQLBinaryResultSetRowPacket.decode constructor

MySQLBinaryResultSetRowPacket.decode(
  1. Uint8List buffer,
  2. List<MySQLColumnDefinitionPacket> colDefs
)

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,
) {
  final byteData = ByteData.sublistView(buffer);
  int offset = 0;

  // O primeiro byte do pacote deve ser 0x00 (header).
  final type = byteData.getUint8(offset);
  offset += 1;
  if (type != 0) {
    throw MySQLProtocolException(
      "Cannot decode MySQLBinaryResultSetRowPacket: packet type is not 0x00",
    );
  }

  // Inicializa a lista de valores (pode conter diferentes tipos).
  List<dynamic> values = [];

  // Calcula o tamanho do null bitmap.
  // O tamanho do bitmap é determinado por: ((numCols + 9) / 8).floor()
  int nullBitmapSize = ((colDefs.length + 9) / 8).floor();

  // Obtém o null bitmap a partir do buffer.
  final nullBitmap = Uint8List.sublistView(
    buffer,
    offset,
    offset + nullBitmapSize,
  );
  offset += nullBitmapSize;

  // Itera sobre cada coluna para decodificar os dados.
  for (int x = 0; x < colDefs.length; x++) {
    // Determina qual byte e bit verificar no bitmap.
    final bitmapByteIndex = ((x + 2) / 8).floor();
    final bitmapBitIndex = (x + 2) % 8;
    final byteToCheck = nullBitmap[bitmapByteIndex];
    final isNull = (byteToCheck & (1 << bitmapBitIndex)) != 0;

    if (isNull) {
      // Se o bit correspondente está setado, o valor da coluna é NULL.
      values.add(null);
    } else {
      // Caso contrário, chama a função parseBinaryColumnData para ler o valor.
      final parseResult = parseBinaryColumnData(
        colDefs[x].type.intVal,
        byteData,
        buffer,
        offset,
      );
      // Avança o offset de acordo com o número de bytes lidos.
      offset += parseResult.item2;
      values.add(parseResult.item1);
    }
  }

  return MySQLBinaryResultSetRowPacket(
    values: values,
  );
}