in lib/src/tokenizer.dart [169:256]
String consumeNumberEntity(bool isHex) {
var allowed = isDigit;
var radix = 10;
if (isHex) {
allowed = isHexDigit;
radix = 16;
}
final charStack = [];
// Consume all the characters that are in range while making sure we
// don't hit an EOF.
var c = stream.char();
while (allowed(c) && c != eof) {
charStack.add(c);
c = stream.char();
}
// Convert the set of characters consumed to an int.
final charAsInt = int.parse(charStack.join(), radix: radix);
// Certain characters get replaced with others
var char = replacementCharacters[charAsInt];
if (char != null) {
_addToken(ParseErrorToken('illegal-codepoint-for-numeric-entity',
messageParams: {'charAsInt': charAsInt}));
} else if ((0xD800 <= charAsInt && charAsInt <= 0xDFFF) ||
(charAsInt > 0x10FFFF)) {
char = '\uFFFD';
_addToken(ParseErrorToken('illegal-codepoint-for-numeric-entity',
messageParams: {'charAsInt': charAsInt}));
} else {
// Should speed up this check somehow (e.g. move the set to a constant)
if ((0x0001 <= charAsInt && charAsInt <= 0x0008) ||
(0x000E <= charAsInt && charAsInt <= 0x001F) ||
(0x007F <= charAsInt && charAsInt <= 0x009F) ||
(0xFDD0 <= charAsInt && charAsInt <= 0xFDEF) ||
const [
0x000B,
0xFFFE,
0xFFFF,
0x1FFFE,
0x1FFFF,
0x2FFFE,
0x2FFFF,
0x3FFFE,
0x3FFFF,
0x4FFFE,
0x4FFFF,
0x5FFFE,
0x5FFFF,
0x6FFFE,
0x6FFFF,
0x7FFFE,
0x7FFFF,
0x8FFFE,
0x8FFFF,
0x9FFFE,
0x9FFFF,
0xAFFFE,
0xAFFFF,
0xBFFFE,
0xBFFFF,
0xCFFFE,
0xCFFFF,
0xDFFFE,
0xDFFFF,
0xEFFFE,
0xEFFFF,
0xFFFFE,
0xFFFFF,
0x10FFFE,
0x10FFFF
].contains(charAsInt)) {
_addToken(ParseErrorToken('illegal-codepoint-for-numeric-entity',
messageParams: {'charAsInt': charAsInt}));
}
char = String.fromCharCodes([charAsInt]);
}
// Discard the ; if present. Otherwise, put it back on the queue and
// invoke parseError on parser.
if (c != ';') {
_addToken(ParseErrorToken('numeric-entity-without-semicolon'));
stream.unget(c);
}
return char;
}