private static bool ParseEscapeCode(Encoding/*!*/ encoding, string/*!*/ str, ref int pos, ref char ch, ref bool escaped)
{
//Debug.Assert(encoding != null && str != null && pos >= 0 && pos < str.Length && str[pos] == '\\');
if (pos + 3 >= str.Length) return false;
int number = 0;
if (str[pos + 1] == 'x')
{
if (str[pos + 2] == '{')
{
// hexadecimal number encoding a Unicode character:
int i = pos + 3;
while (i < str.Length && str[i] != '}' && number < Char.MaxValue)
{
int digit = AlphaNumericToDigit(str[i]);
if (digit > 16) return false;
number = (number << 4) + digit;
i++;
}
if (number > Char.MaxValue || i >= str.Length) return false;
pos = i;
ch = (char)number;
escaped = IsCharRegexSpecial(ch);
}
else
{
// hexadecimal number encoding single-byte character:
for (int i = pos + 2; i < pos + 4; i++)
{
//Debug.Assert(i < str.Length);
int digit = AlphaNumericToDigit(str[i]);
if (digit > 16) return false;
number = (number << 4) + digit;
}
pos += 3;
char[] chars = encoding.GetChars(new byte[] { (byte)number });
if (chars.Length == 1)
ch = chars[0];
else
ch = (char)number;
escaped = IsCharRegexSpecial(ch);
}
return true;
}
else if (str[pos + 1] >= '0' && str[pos + 1] <= '7')
{
// octal number:
for (int i = pos + 1; i < pos + 4; i++)
{
//Debug.Assert(i < str.Length);
int digit = AlphaNumericToDigit(str[i]);
if (digit > 8) return false;
number = (number << 3) + digit;
}
pos += 3;
ch = encoding.GetChars(new byte[] { (byte)number })[0];
escaped = IsCharRegexSpecial(ch);
return true;
}
else if (str[pos + 1] == 'p' || str[pos + 1] == 'P')
{
bool complement = str[pos + 1] == 'P';
int cat_start;
if (str[pos + 2] == '{')
{
if (!complement && str[pos + 3] == '^')
{
complement = true;
cat_start = pos + 4;
}
else
cat_start = pos + 3;
}
else
{
cat_start = pos + 2;
}
//UnicodeCategoryGroup group;
//UnicodeCategory category;
//int cat_length = StringUtils.ParseUnicodeDesignation(str, cat_start, out group, out category);
int cat_length = str.Length;
int cat_end = cat_start + cat_length - 1;
// unknown category:
//if (cat_length == 0) return false;
// check closing brace:
if (str[pos + 2] == '{' && (cat_end + 1 >= str.Length || str[cat_end + 1] != '}'))
return false;
// TODO: custom categories on .NET 2?
// Unicode category:
// ?? if (complement) pos = pos;
return false;
}
else if (str[pos + 1] == 'X')
{
return false;
}
return false;
}