private unsafe void GetHostViaCustomSyntax()
{
// A multithreading check
if (_info.Host != null)
return;
string host = _syntax.InternalGetComponents(this, UriComponents.Host, UriFormat.UriEscaped);
// ATTN: Check on whether recursion has not happened
if ((object)_info.Host == null)
{
if (host.Length >= c_MaxUriBufferSize)
throw GetException(ParsingError.SizeLimit);
ParsingError err = ParsingError.None;
Flags flags = _flags & ~Flags.HostTypeMask;
fixed (char* pHost = host)
{
string newHost = null;
if (CheckAuthorityHelper(pHost, 0, (ushort)host.Length, ref err, ref flags, _syntax, ref newHost) !=
(ushort)host.Length)
{
// We cannot parse the entire host string
flags &= ~Flags.HostTypeMask;
flags |= Flags.UnknownHostType;
}
}
if (err != ParsingError.None || (flags & Flags.HostTypeMask) == Flags.UnknownHostType)
{
// Well, custom parser has returned a not known host type, take it as Basic then.
_flags = (_flags & ~Flags.HostTypeMask) | Flags.BasicHostType;
}
else
{
host = CreateHostStringHelper(host, 0, (ushort)host.Length, ref flags, ref _info.ScopeId);
for (ushort i = 0; i < host.Length; ++i)
{
if ((_info.Offset.Host + i) >= _info.Offset.End || host[i] != _string[_info.Offset.Host + i])
{
_flags |= (Flags.HostNotCanonical | Flags.E_HostNotCanonical);
break;
}
}
_flags = (_flags & ~Flags.HostTypeMask) | (flags & Flags.HostTypeMask);
}
}
//
// This is a chance for a custom parser to report a different port value
//
string portStr = _syntax.InternalGetComponents(this, UriComponents.StrongPort, UriFormat.UriEscaped);
int port = 0;
if ((object)portStr == null || portStr.Length == 0)
{
// It's like no port
_flags &= ~Flags.NotDefaultPort;
_flags |= (Flags.PortNotCanonical | Flags.E_PortNotCanonical);
_info.Offset.PortValue = 0;
}
else
{
for (int idx = 0; idx < portStr.Length; ++idx)
{
int val = portStr[idx] - '0';
if (val < 0 || val > 9 || (port = (port * 10 + val)) > 0xFFFF)
throw new UriFormatException(SR.Format(SR.net_uri_PortOutOfRange, _syntax.GetType().ToString(), portStr));
}
if (port != _info.Offset.PortValue)
{
if (port == _syntax.DefaultPort)
_flags &= ~Flags.NotDefaultPort;
else
_flags |= Flags.NotDefaultPort;
_flags |= (Flags.PortNotCanonical | Flags.E_PortNotCanonical);
_info.Offset.PortValue = (ushort)port;
}
}
// This must be done as the last thing in this method
_info.Host = host;
}