private static QualifiedName ParseName(
StringReader reader,
bool referenceName)
{
ushort namespaceIndex = 0;
// extract namespace index if present.
StringBuilder buffer = new StringBuilder();
int last = reader.Peek();
for (int next = last; next != -1; next = reader.Peek())
{
last = next;
if (!Char.IsDigit((char)next))
{
if (next == ':')
{
reader.Read();
namespaceIndex = Convert.ToUInt16(buffer.ToString(), CultureInfo.InvariantCulture);
buffer.Length = 0;
// fetch next character.
last = reader.Peek();
}
break;
}
buffer.Append((char)next);
reader.Read();
}
// extract rest of name.
for (int next = last; next != -1; next = reader.Peek())
{
last = next;
// check for terminator.
if (referenceName)
{
if (next == '>')
{
reader.Read();
break;
}
}
else
{
if (next == '<' || next == '/' || next == '.')
{
break;
}
}
// check for invalid character.
if (next == '!' || next == ':' || next == '<' || next == '>' || next == '/' || next == '.')
{
throw new ServiceResultException(
StatusCodes.BadSyntaxError,
Utils.Format("Unexpected character '{0}' in browse path.", next));
}
// check for escape character.
if (next == '&')
{
next = reader.Read();
next = reader.Read();
buffer.Append((char)next);
continue;
}
// append character.
buffer.Append((char)next);
reader.Read();
}
// check for enclosing bracket.
if (referenceName)
{
if (last != '>')
{
throw new ServiceResultException(
StatusCodes.BadSyntaxError,
Utils.Format("Missing file '>' for reference type name in browse path."));
}
}
if (buffer.Length == 0)
{
if (referenceName)
{
throw new ServiceResultException(
StatusCodes.BadSyntaxError,
Utils.Format("Reference type name is null in browse path."));
}
if (namespaceIndex == 0)
{
return null;
}
}
return new QualifiedName(buffer.ToString(), namespaceIndex);
}