internal String NormalizeUrl() { DoDeferredParse(); StringBuilder builtUrl = StringBuilderCache.Acquire(); if (String.Compare(m_protocol, "file", StringComparison.OrdinalIgnoreCase) == 0) { #if !PLATFORM_UNIX builtUrl = builtUrl.AppendFormat("FILE:///{0}/{1}", m_localSite.ToString(), m_directory.ToString()); #else builtUrl = builtUrl.AppendFormat("FILE:///{0}", m_directory.ToString()); #endif // !PLATFORM_UNIX } else { builtUrl = builtUrl.AppendFormat("{0}://{1}{2}", m_protocol, m_userpass, m_siteString.ToString()); if (m_port != -1) { builtUrl = builtUrl.AppendFormat("{0}", m_port); } builtUrl = builtUrl.AppendFormat("/{0}", m_directory.ToString()); } return(StringBuilderCache.GetStringAndRelease(builtUrl).ToUpper(CultureInfo.InvariantCulture)); }
void ParseString(String url, bool parsed) { if (url == null) { throw new ArgumentNullException("url"); } if (url.Length == 0) { throw new FormatException(Environment.GetResourceString("Format_StringZeroLength")); } int index; String temp = url; String intermediate = ""; // If there are any hex or unicode characters in the url, translate those // into the proper character. if (!parsed) { do { index = temp.IndexOf('%'); if (index == -1) { intermediate += temp; break; } if (temp.Length - index < 1) { throw new ArgumentException(Environment.GetResourceString("Argument_InvalidUrl")); } if (temp[index + 1] == 'u' || temp[index + 1] == 'U') { if (temp.Length - index < 5) { throw new ArgumentException(Environment.GetResourceString("Argument_InvalidUrl")); } // We have a unicode character specified in hex char c = (char)(Hex.ConvertHexDigit(temp[index + 2]) << 12 | Hex.ConvertHexDigit(temp[index + 3]) << 8 | Hex.ConvertHexDigit(temp[index + 4]) << 4 | Hex.ConvertHexDigit(temp[index + 5])); intermediate += temp.Substring(0, index) + c; temp = temp.Substring(index + 6); } else { // we have a hex character. if (temp.Length - index < 2) { throw new ArgumentException(Environment.GetResourceString("Argument_InvalidUrl")); } char c = (char)(Hex.ConvertHexDigit(temp[index + 1]) << 4 | Hex.ConvertHexDigit(temp[index + 2])); intermediate += temp.Substring(0, index) + c; temp = temp.Substring(index + 3); } } while (true); temp = intermediate; url = temp; } // Search for the end of the protocol info and grab the actual protocol string // ex. http://www.microsoft.com/complus would have a protocol string of http index = temp.IndexOf(':'); if (index == 0) { throw new ArgumentException(Environment.GetResourceString("Argument_InvalidUrl")); } else if (index != -1 && temp.Length > index + 1) { if (String.Compare(temp.Substring(0, index), "file", true, CultureInfo.InvariantCulture) == 0) { m_protocol = "file"; temp = temp.Substring(index + 1); } else if (temp[index + 1] != '\\') { if (temp.Length > index + 2 && temp[index + 1] == '/' && temp[index + 2] == '/') { m_protocol = url.Substring(0, index); for (int i = 0; i < m_protocol.Length; ++i) { char c = m_protocol[i]; if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) { continue; } else { throw new ArgumentException(Environment.GetResourceString("Argument_InvalidUrl")); } } temp = url.Substring(index + 3); } else { throw new ArgumentException(Environment.GetResourceString("Argument_InvalidUrl")); } } else { m_protocol = m_defaultProtocol; temp = url; } } else { m_protocol = m_defaultProtocol; temp = url; } // Parse out the site info. // In the general case we parse of the site and create a SiteString out of it // (which supports our wildcarding scheme). In the case of files we don't support // wildcarding and furthermore SiteString doesn't like ':' and '|' which can appear // in file urls so we just keep that info in a separate string and set the // SiteString to null. // // ex. http://www.microsoft.com/complus -> m_siteString = "www.microsoft.com" m_localSite = null // ex. file:///c:/complus/mscorlib.dll -> m_siteString = null m_localSite = "c:" // ex. file:///c|/complus/mscorlib.dll -> m_siteString = null m_localSite = "c:" bool fileProtocol; if (String.Compare(m_protocol, "file", true, CultureInfo.InvariantCulture) == 0) { index = temp.IndexOfAny(m_fileEnd); fileProtocol = true; if (String.Compare(temp, 0, "\\\\?\\", 0, 4, true, CultureInfo.InvariantCulture) == 0 || String.Compare(temp, 0, "\\\\.\\", 0, 4, true, CultureInfo.InvariantCulture) == 0) { temp = temp.Substring(4); } } else { index = temp.IndexOfAny(m_siteEnd); fileProtocol = false; } temp = temp.Replace('\\', '/'); // If we find a '/' in the first character of the string and we are using the 'file' // protocol, just ignore it. if (fileProtocol) { // Remove any '/' before the local site information. // ex. file://///d:/complus // ex. file:///d:/complus temp = temp.TrimStart(new char[] { '/' }); index = temp.IndexOfAny(m_fileEnd, 0); if (index != -1 && ((index == 2 && temp[index - 1] != ':' && temp[index - 1] != '|') || index != 2) && index != temp.Length - 1) { int tempIndex = temp.Substring(index + 1).IndexOfAny(m_fileEnd); if (tempIndex != -1) { index = tempIndex + index + 1; } else { index = -1; } } } // Check if there is a port number and parse that out. if (index != -1 && temp[index] == ':') { int tempIndex = temp.IndexOf('/'); if (tempIndex == -1) { m_port = Int32.Parse(temp.Substring(index + 1)); if (m_port < 0) { throw new ArgumentException(Environment.GetResourceString("Argument_InvalidUrl")); } temp = temp.Substring(0, index); index = -1; } else { m_port = Int32.Parse(temp.Substring(index + 1, tempIndex - index - 1)); temp = temp.Substring(0, index) + temp.Substring(tempIndex); } } if (index == -1) { if (fileProtocol) { String localSite = temp; int i; bool spacesAllowed; if (localSite[0] == '\\' && localSite[1] == '\\') { spacesAllowed = true; i = 2; } else { i = 0; spacesAllowed = false; } bool useSmallCharToUpper = true; for (; i < localSite.Length; ++i) { char c = localSite[i]; if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || (c == '-') || (c == '/') || (c == ':') || (c == '|') || (c == '.') || (c == '*') || (c == '$') || (spacesAllowed && c == ' ')) { continue; } else { useSmallCharToUpper = false; break; } } if (useSmallCharToUpper) { localSite = String.SmallCharToUpper(localSite); } else { localSite = localSite.ToUpper(CultureInfo.InvariantCulture); } m_siteString = null; m_localSite = new LocalSiteString(localSite); if (localSite[localSite.Length - 1] == '*') { m_directory = new DirectoryString("*", false); } else { m_directory = new DirectoryString(); } } else { m_localSite = null; m_siteString = new SiteString(temp); m_directory = new DirectoryString(); } } else { String site = temp.Substring(0, index); if (fileProtocol) { String localSite = site; int i; bool spacesAllowed; if (localSite[0] == '\\' && localSite[1] == '\\') { spacesAllowed = true; i = 2; } else { i = 0; spacesAllowed = false; } bool useSmallCharToUpper = true; for (; i < localSite.Length; ++i) { char c = localSite[i]; if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '-' && c <= ':') || (c == '|') || (c == '$') || (c == '_') || (spacesAllowed && c == ' ')) { continue; } else { useSmallCharToUpper = false; break; } } if (useSmallCharToUpper) { localSite = String.SmallCharToUpper(localSite); } else { localSite = localSite.ToUpper(CultureInfo.InvariantCulture); } m_siteString = null; m_localSite = new LocalSiteString(localSite); } else { m_localSite = null; m_siteString = new SiteString(site); } // Finally we parse out the directory string // ex. http://www.microsoft.com/complus -> m_directory = "complus" String directoryString = temp.Substring(index + 1); if (directoryString.Length == 0) { m_directory = new DirectoryString(); } else { m_directory = new DirectoryString(directoryString, fileProtocol); } } String builtUrl; if (fileProtocol) { String directory = m_directory.ToString(); String localSite = m_localSite.ToString(); builtUrl = "file://" + localSite; if (directory != null && !directory.Equals("") && (!directory.Equals("*") || localSite.IndexOf('*') == -1)) { builtUrl += "/" + directory; } } else { builtUrl = m_protocol + "://" + m_siteString.ToString(); if (m_port != -1) { builtUrl += ":" + m_port; } builtUrl += "/" + m_directory.ToString(); } m_fullurl = builtUrl; }