Implementation
@override
set payload(Uint8List? payload) {
var stream = ByteStream(payload!);
int flag = stream.readByte();
int languagePayloadLength = flag & 0x3F;
assert(languagePayloadLength != 0, "language code length can not be zero");
if (flag >> 7 == 1) {
encoding = TextEncoding.UTF16;
} else {
encoding = TextEncoding.UTF8;
}
var languagePayload = stream.readBytes(languagePayloadLength);
var textPayload = stream.readAll();
language = utf8.decode(languagePayload);
if (encoding == TextEncoding.UTF8) {
text = utf8.decode(textPayload);
} else if (encoding == TextEncoding.UTF16) {
// decode UTF-16 manually
var bytes = textPayload;
Endianness end;
if (bytes[0] == 0xFF) {
end = Endianness.Little;
} else if (bytes[1] == 0xFE) {
end = Endianness.Big;
} else {
throw ArgumentError("Unknown BOM in UTF-16 encoded string.");
}
StringBuffer buffer = StringBuffer();
for (int i = 2; i < bytes.length;) {
int firstWord = end == Endianness.Little
? (bytes[i + 1] << 8) + bytes[i]
: (bytes[i] << 8) + bytes[i + 1];
if (0xD800 <= firstWord && firstWord <= 0xDBFF) {
int secondWord = end == Endianness.Little
? (bytes[i + 3] << 8) + bytes[i + 2]
: (bytes[i + 2] << 8) + bytes[i + 3];
int charCode =
((firstWord - 0xD800) << 10) + (secondWord - 0xDC00) + 0x10000;
buffer.writeCharCode(charCode);
i += 4;
} else {
buffer.writeCharCode(firstWord);
i += 2;
}
}
text = buffer.toString();
}
}