System.Uri.Uri.Reduce C# (CSharp) Method

Reduce() private static method

private static Reduce ( string path, bool compact_escaped ) : string
path string
compact_escaped bool
return string
		private static string Reduce (string path, bool compact_escaped)
		{
			// quick out, allocation-free, for a common case
			if (path == "/")
				return path;

			StringBuilder res = new StringBuilder();

			if (compact_escaped) {
				// replace '\', %5C ('\') and %2f ('/') into '/'
				// other escaped values seems to survive this step
				for (int i=0; i < path.Length; i++) {
					char c = path [i];
					switch (c) {
					case '\\':
						res.Append ('/');
						break;
					case '%':
						if (i < path.Length - 2) {
							char c1 = path [i + 1];
							char c2 = Char.ToUpper (path [i + 2]);
							if (((c1 == '2') && (c2 == 'F')) || ((c1 == '5') && (c2 == 'C'))) {
								res.Append ('/');
								i += 2;
							} else {
								res.Append (c);
							}
						} else {
							res.Append (c);
						}
						break;
					default:
						res.Append (c);
						break;
					}
				}
				path = res.ToString ();
			} else {
				path = path.Replace ('\\', '/');
			}

			ArrayList result = new ArrayList ();

			bool begin = true;
			for (int startpos = 0; startpos < path.Length; ) {
				int endpos = path.IndexOf('/', startpos);
				if (endpos == -1) endpos = path.Length;
				string current = path.Substring (startpos, endpos-startpos);
				startpos = endpos + 1;
				if ((begin && current.Length == 0) || current == "." )
					continue;

				begin = false;
				if (current == "..") {
					int resultCount = result.Count;
#if NET_2_0
					// in 2.0 profile, skip leading ".." parts
					if (resultCount == 0) {
						continue;
					}

					result.RemoveAt (resultCount - 1);
					continue;
#else
					// in 1.x profile, retain leading ".." parts, and only reduce
					// URI is previous part is not ".."
					if (resultCount > 0) {
						if ((string) result[resultCount - 1] != "..") {
							result.RemoveAt (resultCount - 1);
							continue;
						}
					}
#endif
				}

				result.Add (current);
			}

			if (result.Count == 0)
				return "/";

			res.Length = 0;
			if (path [0] == '/')
				res.Append ('/');

			bool first = true;
			foreach (string part in result) {
				if (first) {
					first = false;
				} else {
					res.Append ('/');
				}
				res.Append(part);
			}

			if (path.EndsWith ("/"))
				res.Append ('/');
				
			return res.ToString();
		}