public static string DecodeName(string name)
{
if (name == null || name.Length == 0)
return name;
StringBuilder bufBld = null;
int length = name.Length;
int copyPosition = 0;
int underscorePos = name.IndexOf('_');
MatchCollection mc = null;
IEnumerator en = null;
if (underscorePos >= 0)
{
if (s_decodeCharPattern == null)
{
s_decodeCharPattern = new Regex("_[Xx]([0-9a-fA-F]{4}|[0-9a-fA-F]{8})_");
}
mc = s_decodeCharPattern.Matches(name, underscorePos);
en = mc.GetEnumerator();
}
else
{
return name;
}
int matchPos = -1;
if (en != null && en.MoveNext())
{
Match m = (Match)en.Current;
matchPos = m.Index;
}
for (int position = 0; position < length - s_encodedCharLength + 1; position++)
{
if (position == matchPos)
{
if (en.MoveNext())
{
Match m = (Match)en.Current;
matchPos = m.Index;
}
if (bufBld == null)
{
bufBld = new StringBuilder(length + 20);
}
bufBld.Append(name, copyPosition, position - copyPosition);
if (name[position + 6] != '_')
{ //_x1234_
Int32 u =
FromHex(name[position + 2]) * 0x10000000 +
FromHex(name[position + 3]) * 0x1000000 +
FromHex(name[position + 4]) * 0x100000 +
FromHex(name[position + 5]) * 0x10000 +
FromHex(name[position + 6]) * 0x1000 +
FromHex(name[position + 7]) * 0x100 +
FromHex(name[position + 8]) * 0x10 +
FromHex(name[position + 9]);
if (u >= 0x00010000)
{
if (u <= 0x0010ffff)
{ //convert to two chars
copyPosition = position + s_encodedCharLength + 4;
char lowChar, highChar;
XmlCharType.SplitSurrogateChar(u, out lowChar, out highChar);
bufBld.Append(highChar);
bufBld.Append(lowChar);
}
//else bad ucs-4 char don't convert
}
else
{ //convert to single char
copyPosition = position + s_encodedCharLength + 4;
bufBld.Append((char)u);
}
position += s_encodedCharLength - 1 + 4; //just skip
}
else
{
copyPosition = position + s_encodedCharLength;
bufBld.Append((char)(
FromHex(name[position + 2]) * 0x1000 +
FromHex(name[position + 3]) * 0x100 +
FromHex(name[position + 4]) * 0x10 +
FromHex(name[position + 5])));
position += s_encodedCharLength - 1;
}
}
}
if (copyPosition == 0)
{
return name;
}
else
{
if (copyPosition < length)
{
bufBld.Append(name, copyPosition, length - copyPosition);
}
return bufBld.ToString();
}
}