private string ScanUriEscapes(Mark start)
{
// Decode the required number of characters.
byte[] charBytes = null;
int nextInsertionIndex = 0;
int width = 0;
do
{
// Check for a URI-escaped octet.
if (!(analyzer.Check('%') && analyzer.IsHex(1) && analyzer.IsHex(2)))
{
throw new SyntaxErrorException(start, cursor.Mark(), "While parsing a tag, did not find URI escaped octet.");
}
// Get the octet.
int octet = (analyzer.AsHex(1) << 4) + analyzer.AsHex(2);
// If it is the leading octet, determine the length of the UTF-8 sequence.
if (width == 0)
{
width = (octet & 0x80) == 0x00 ? 1 :
(octet & 0xE0) == 0xC0 ? 2 :
(octet & 0xF0) == 0xE0 ? 3 :
(octet & 0xF8) == 0xF0 ? 4 : 0;
if (width == 0)
{
throw new SyntaxErrorException(start, cursor.Mark(), "While parsing a tag, find an incorrect leading UTF-8 octet.");
}
charBytes = new byte[width];
}
else
{
// Check if the trailing octet is correct.
if ((octet & 0xC0) != 0x80)
{
throw new SyntaxErrorException(start, cursor.Mark(), "While parsing a tag, find an incorrect trailing UTF-8 octet.");
}
}
// Copy the octet and move the pointers.
charBytes[nextInsertionIndex++] = (byte)octet;
Skip();
Skip();
Skip();
}
while (--width > 0);
var result = Encoding.UTF8.GetString(charBytes, 0, nextInsertionIndex);
if (result.Length == 0 || result.Length > 2)
{
throw new SyntaxErrorException(start, cursor.Mark(), "While parsing a tag, find an incorrect UTF-8 sequence.");
}
return result;
}