コード例 #1
0
        private void CleanUpRoute()
        {
            NameHelper.EnsureValidFilenameCharacters(_parts);

            // NB: process all inner special directories of the route segments
            // ""	-> remove empty segments
            // "."	-> reference to current folder, remove unless it is the first segment of a relative path
            // ".."	-> reference parent folder, remove this and parent folder, as long as the parent is not first segment or special too

            var ring = _parts.ToRing();

            var link = ring.Head.Next; // first item path segment

            while (link != ring.Head)
            {
                Ring.Link previous = link.Previous;
                Ring.Link next     = link.Next;
                switch ((string)link.Value)
                {
                case "":
                    ring.RemoveLink(link);
                    link = next;
                    break;

                case ".":
                    if (IsRelativePath && previous == ring.Head)
                    {
                        link = next;
                        break;
                    }
                    ring.RemoveLink(link);
                    link = next;
                    break;

                case "..":
                    if (previous == ring.Head)
                    {
                        if (IsRelativePath)
                        {
                            link = next;
                            break;
                        }
                        throw new Exception("Attempt to reference parent above absolute root.");
                    }
                    if ((string)previous.Value == ".")
                    {
                        ring.RemoveLink(previous);
                        link = next;
                        break;
                    }
                    if ((string)previous.Value == "..")
                    {
                        link = next;
                        break;
                    }
                    ring.RemoveLink(previous);
                    ring.RemoveLink(link);
                    link = next;
                    break;

                default:
                    link = link.Next;
                    break;
                }
            }

            if (_parts.Count < 1)
            {
                throw new Exception("Empty path is not valid.");
            }
            if (_parts.Count == 1)
            {
                if (IsFolderPath && IsAbsolutePath)
                {
                    //a single root folder is allowed.
                    return;
                }
                throw new Exception("Empty path is not valid.");
            }

            // .\ and ..\ required for relative path part[1]
            // .\ and ..\ illegal for absolute path[1]
            var  firstPart = (string)ring.Head.Next.Value;
            bool startsWithRelativeSpecialPart = RelativePath.IsRelativeSpecialPart(firstPart);

            if (IsAbsolutePath)
            {
                if (startsWithRelativeSpecialPart)
                {
                    throw new Exception("Not a valid absolute path.");
                }
            }
            else
            {
                if (!startsWithRelativeSpecialPart)
                {
                    throw new Exception("Not a valid relative path.");
                }
            }

            if ((IsFilePath) && ((IsAbsolutePath && _parts.Count == 1) || (IsRelativePath && _parts.Count == 2)))
            {
                throw new Exception("No file name specified.");
            }
        }