parseUtf8 method
Implementation
(int, Event?) parseUtf8(List<int> buf) {
if (buf.isEmpty) return (0, null);
final b = buf[0];
// Control codes + DEL (0x7F).
if (b <= 0x1f || b == 0x7f) {
return (1, parseControl(b));
}
// ASCII printable characters.
if (b >= 0x20 && b < 0x7f) {
if (b >= 0x41 && b <= 0x5a) {
// Uppercase A-Z => lower code + shift modifier.
final lower = b + 0x20;
return (
1,
KeyPressEvent(
Key(
code: lower,
shiftedCode: b,
text: String.fromCharCode(b),
mod: KeyMod.shift,
),
),
);
}
return (1, KeyPressEvent(Key(code: b, text: String.fromCharCode(b))));
}
// UTF-8 grapheme clusters: decode runes until we have at least 2 clusters,
// then return the first one.
var consumed = 0;
final sb = StringBuffer();
while (consumed < buf.length) {
final decoded = _decodeOneRune(buf.sublist(consumed));
if (!decoded.ok) {
if (decoded.consumed == 0) return (0, null); // need more bytes
return (1, UnknownEvent(String.fromCharCode(b)));
}
consumed += decoded.consumed;
sb.writeCharCode(decoded.rune);
final s = sb.toString();
final it = uni.graphemes(s).iterator;
if (!it.moveNext()) continue;
final firstCluster = it.current;
if (it.moveNext()) {
final bytesConsumed = utf8.encode(firstCluster).length;
return (bytesConsumed, _keyFromCluster(firstCluster));
}
}
// Only one grapheme cluster in the available buffer.
final cluster = sb.toString();
return (consumed, _keyFromCluster(cluster));
}