parseBinaryColumnData function
Função auxiliar para analisar dados de coluna em formato binário.
columnType: O tipo da coluna (valor inteiro representando o tipo MySQL).
data: Um ByteData que fornece acesso aos bytes do buffer.
buffer: O Uint8List original contendo os dados.
startOffset: A posição inicial no buffer para leitura.
Retorna um record (dynamic, int) contendo:
$1: O valor lido da coluna (geralmente convertido para string ou, em casos binários, um Uint8List).$2: O número de bytes consumidos durante a leitura.
Caso o tipo da coluna não seja implementado, lança MySQLProtocolException.
Implementation
(dynamic, int) parseBinaryColumnData(
int columnType,
ByteData data,
Uint8List buffer,
int startOffset, {
bool unsigned = false,
}) {
final limit =
data.lengthInBytes < buffer.length ? data.lengthInBytes : buffer.length;
if (startOffset < 0) {
throw const MySQLProtocolException(
'Invalid negative startOffset while parsing binary column data',
);
}
// [unsigned] comes from the column's UNSIGNED flag: without it a
// TINYINT UNSIGNED 200 was read as -56 (and so on for every width).
switch (columnType) {
case mysqlColumnTypeTiny:
_requireBinaryBytes(startOffset, 1, limit);
final value =
unsigned ? data.getUint8(startOffset) : data.getInt8(startOffset);
return (value.toString(), 1);
case mysqlColumnTypeShort:
_requireBinaryBytes(startOffset, 2, limit);
final value = unsigned
? data.getUint16(startOffset, Endian.little)
: data.getInt16(startOffset, Endian.little);
return (value.toString(), 2);
case mysqlColumnTypeLong:
case mysqlColumnTypeInt24:
_requireBinaryBytes(startOffset, 4, limit);
final value = unsigned
? data.getUint32(startOffset, Endian.little)
: data.getInt32(startOffset, Endian.little);
return (value.toString(), 4);
case mysqlColumnTypeLongLong:
return _parseBinaryLongLong(data, startOffset, limit, unsigned);
case mysqlColumnTypeFloat:
_requireBinaryBytes(startOffset, 4, limit);
final value = data.getFloat32(startOffset, Endian.little);
return (value.toString(), 4);
case mysqlColumnTypeDouble:
_requireBinaryBytes(startOffset, 8, limit);
final value = data.getFloat64(startOffset, Endian.little);
return (value.toString(), 8);
case mysqlColumnTypeDate:
case mysqlColumnTypeDateTime:
case mysqlColumnTypeTimestamp:
return _parseBinaryDateTime(data, startOffset, limit);
case mysqlColumnTypeTime:
case mysqlColumnTypeTime2:
return _parseBinaryTime(data, startOffset, limit);
case mysqlColumnTypeString:
case mysqlColumnTypeVarString:
case mysqlColumnTypeVarChar:
case mysqlColumnTypeEnum:
case mysqlColumnTypeSet:
case mysqlColumnTypeJson:
case mysqlColumnTypeDecimal:
case mysqlColumnTypeNewDecimal:
final slice = readLengthEncodedSlice(
buffer,
startOffset,
limit,
allowNullMarker: false,
);
final strValue = utf8.decode(slice.bytes!, allowMalformed: true);
return (strValue, slice.nextOffset - startOffset);
case mysqlColumnTypeLongBlob:
case mysqlColumnTypeMediumBlob:
case mysqlColumnTypeBlob:
case mysqlColumnTypeTinyBlob:
case mysqlColumnTypeGeometry:
case mysqlColumnTypeBit:
final slice = readLengthEncodedSlice(
buffer,
startOffset,
limit,
allowNullMarker: false,
);
return (slice.bytes!, slice.nextOffset - startOffset);
case mysqlColumnTypeYear:
_requireBinaryBytes(startOffset, 2, limit);
final yearValue = data.getUint16(startOffset, Endian.little);
return (yearValue.toString(), 2);
}
throw MySQLProtocolException(
"Can not parse binary column data: column type $columnType is not implemented",
);
}