MySQLPacketInitialHandshake.decode constructor
MySQLPacketInitialHandshake.decode(
- Uint8List buffer
Decodifica um buffer Uint8List recebido do servidor e retorna uma instância de MySQLPacketInitialHandshake.
A decodificação segue a especificação do protocolo MySQL:
- Protocol Version: 1 byte.
- Server Version: String terminada em null.
- Connection ID: 4 bytes (little-endian).
- Auth Plugin Data Part 1: 8 bytes, seguida de 1 byte de filler.
- Capability Flags (lower 2 bytes): 2 bytes.
- Character Set: 1 byte.
- Status Flags: 2 bytes.
- Capability Flags (upper 2 bytes): 2 bytes.
- Length of Auth Plugin Data: 1 byte (se a flag mysqlCapFlagClientPluginAuth estiver ativa).
- Reserved: 10 bytes (normalmente zeros).
- Auth Plugin Data Part 2: Número variável de bytes, se a flag mysqlCapFlagClientSecureConnection estiver ativa.
- Auth Plugin Name: String terminada em null, se a flag mysqlCapFlagClientPluginAuth estiver ativa.
Implementation
factory MySQLPacketInitialHandshake.decode(Uint8List buffer) {
final byteData = ByteData.sublistView(buffer);
int offset = 0;
// 1) Protocol Version (1 byte)
final protocolVersion = byteData.getUint8(offset);
offset += 1;
// 2) Server Version: String terminada em null
final serverVersion = buffer.getUtf8NullTerminatedString(offset);
offset += serverVersion.item2;
// 3) Connection ID (4 bytes, little-endian)
final connectionID = byteData.getUint32(offset, Endian.little);
offset += 4;
// 4) Auth Plugin Data Part 1 (8 bytes) e filler (1 byte)
final authPluginDataPart1 =
Uint8List.sublistView(buffer, offset, offset + 8);
offset += 9; // 8 bytes de dados + 1 byte de filler
// 5) Capability Flags (lower 2 bytes)
// Cria um buffer de 4 bytes para montar as flags completas.
final capabilitiesBytesData = ByteData(4);
// Armazena os 2 bytes inferiores nas posições 3 e 2 (big-endian para posterior conversão)
capabilitiesBytesData.setUint8(3, buffer[offset]);
capabilitiesBytesData.setUint8(2, buffer[offset + 1]);
offset += 2;
// 6) Character Set (1 byte)
final charset = byteData.getUint8(offset);
offset += 1;
// 7) Status Flags (2 bytes)
final statusFlags = Uint8List.sublistView(buffer, offset, offset + 2);
offset += 2;
// 8) Capability Flags (upper 2 bytes)
capabilitiesBytesData.setUint8(1, buffer[offset]);
capabilitiesBytesData.setUint8(0, buffer[offset + 1]);
offset += 2;
// Converte as 4 bytes para um inteiro (big-endian)
final capabilityFlags = capabilitiesBytesData.getUint32(0, Endian.big);
// 9) Length of Auth Plugin Data (1 byte)
int authPluginDataLength = 0;
if (capabilityFlags & mysqlCapFlagClientPluginAuth != 0) {
authPluginDataLength = byteData.getUint8(offset);
}
offset += 1;
// 10) Reserved: pula 10 bytes (normalmente zeros)
offset += 10;
// 11) Auth Plugin Data Part 2 (se aplicável)
Uint8List? authPluginDataPart2;
if (capabilityFlags & mysqlCapFlagClientSecureConnection != 0) {
// O comprimento é o máximo entre 13 e (authPluginDataLength - 8)
int length = max(13, authPluginDataLength - 8);
authPluginDataPart2 =
Uint8List.sublistView(buffer, offset, offset + length);
offset += length;
}
// 12) Auth Plugin Name (se aplicável)
String? authPluginName;
if (capabilityFlags & mysqlCapFlagClientPluginAuth != 0) {
authPluginName = buffer.getUtf8NullTerminatedString(offset).item1;
}
return MySQLPacketInitialHandshake(
protocolVersion: protocolVersion,
serverVersion: serverVersion.item1,
connectionID: connectionID,
authPluginDataPart1: authPluginDataPart1,
authPluginDataPart2: authPluginDataPart2,
capabilityFlags: capabilityFlags,
charset: charset,
statusFlags: statusFlags,
authPluginName: authPluginName,
);
}