Beispiel #1
0
        public static async Task <SearchResult <IUnixFileSystemEntry> > SearchEntryAsync(this IUnixFileSystem fileSystem, [NotNull, ItemNotNull] Stack <IUnixDirectoryEntry> currentPath, [NotNull, ItemNotNull] IReadOnlyList <string> pathElements, CancellationToken cancellationToken)
        {
            var sourceDir = await GetDirectoryAsync(fileSystem, currentPath, new ListSegment <string>(pathElements, 0, pathElements.Count - 1), cancellationToken);

            if (sourceDir == null)
            {
                return(null);
            }
            IUnixFileSystemEntry foundEntry;
            var fileName = pathElements[pathElements.Count - 1];

            switch (fileName)
            {
            case "":
                currentPath.Clear();
                fileName   = null;
                foundEntry = fileSystem.Root;
                break;

            case ".":
                if (currentPath.Count != 0)
                {
                    foundEntry = currentPath.Pop();
                    fileName   = foundEntry.Name;
                }
                else
                {
                    foundEntry = fileSystem.Root;
                    fileName   = null;
                }
                break;

            case "..":
                if (currentPath.Count != 0)
                {
                    currentPath.Pop();
                }
                if (currentPath.Count != 0)
                {
                    foundEntry = currentPath.Pop();
                    fileName   = foundEntry.Name;
                }
                else
                {
                    foundEntry = fileSystem.Root;
                    fileName   = null;
                }
                break;

            default:
                foundEntry = await fileSystem.GetEntryByNameAsync(sourceDir, fileName, cancellationToken);

                break;
            }
            return(new SearchResult <IUnixFileSystemEntry>(sourceDir, foundEntry, fileName));
        }
Beispiel #2
0
        public static async Task <SearchResult <IUnixFileEntry> > SearchFileAsync(this IUnixFileSystem fileSystem, [NotNull, ItemNotNull] Stack <IUnixDirectoryEntry> currentPath, [NotNull, ItemNotNull] IReadOnlyList <string> pathElements, CancellationToken cancellationToken)
        {
            var sourceDir = await GetDirectoryAsync(fileSystem, currentPath, new ListSegment <string>(pathElements, 0, pathElements.Count - 1), cancellationToken);

            if (sourceDir == null)
            {
                return(null);
            }
            var fileName   = pathElements[pathElements.Count - 1];
            var foundEntry = await fileSystem.GetEntryByNameAsync(sourceDir, fileName, cancellationToken);

            var foundFileEntry = foundEntry as IUnixFileEntry;

            if (foundEntry != null && foundFileEntry == null)
            {
                return(null);
            }
            return(new SearchResult <IUnixFileEntry>(sourceDir, foundFileEntry, fileName));
        }
Beispiel #3
0
        public static async Task <IUnixDirectoryEntry> GetDirectoryAsync([NotNull] this IUnixFileSystem fileSystem, [NotNull, ItemNotNull] Stack <IUnixDirectoryEntry> currentPath, [NotNull, ItemNotNull] IReadOnlyList <string> pathElements, CancellationToken cancellationToken)
        {
            IUnixDirectoryEntry currentDir = currentPath.Count == 0 ? fileSystem.Root : currentPath.Peek();

            foreach (var pathElement in pathElements)
            {
                if (pathElement == string.Empty)
                {
                    currentDir = fileSystem.Root;
                    currentPath.Clear();
                    continue;
                }

                if (pathElement == ".")
                {
                    continue;
                }

                if (pathElement == "..")
                {
                    if (currentPath.Count != 0)
                    {
                        currentPath.Pop();
                        currentDir = currentPath.Count == 0 ? fileSystem.Root : currentPath.Peek();
                    }
                    continue;
                }

                var foundEntry = await fileSystem.GetEntryByNameAsync(currentDir, pathElement, cancellationToken).ConfigureAwait(false);

                if (!(foundEntry is IUnixDirectoryEntry foundDirEntry))
                {
                    return(null);
                }

                currentPath.Push(foundDirEntry);
                currentDir = foundDirEntry;
            }

            return(currentDir);
        }
        /// <summary>
        /// Tries to select the given <paramref name="path"/>.
        /// </summary>
        /// <param name="fileSystem">The file system.</param>
        /// <param name="pathEntries">The current path (entries).</param>
        /// <param name="path">The path to select.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns>The result of the selection.</returns>
        public static async Task <PathSelectionResult> SelectAsync(
            this IUnixFileSystem fileSystem,
            IEnumerable <IUnixDirectoryEntry> pathEntries,
            string?path,
            CancellationToken cancellationToken)
        {
            var currentDirectoryEntries = new Stack <IUnixDirectoryEntry>(pathEntries);
            IUnixDirectoryEntry currentDirectoryEntry;

            if (currentDirectoryEntries.Count == 0)
            {
                currentDirectoryEntry = fileSystem.Root;
                currentDirectoryEntries.Push(currentDirectoryEntry);
            }
            else
            {
                currentDirectoryEntry = currentDirectoryEntries.Peek();
            }

            var pathSegments = new PathEnumerator(path)
                               .NormalizePath(GetPathEntryNames(currentDirectoryEntries))
                               .ToArray();

            for (var pathSegmentIndex = 0; pathSegmentIndex != pathSegments.Length; ++pathSegmentIndex)
            {
                var pathSegment = pathSegments[pathSegmentIndex];

                if (pathSegment == "/")
                {
                    currentDirectoryEntries.Clear();
                    currentDirectoryEntry = fileSystem.Root;
                    currentDirectoryEntries.Push(currentDirectoryEntry);
                    continue;
                }

                var isDirectoryExpected = pathSegment.EndsWith("/");
                var childName           = isDirectoryExpected ? pathSegment.Substring(0, pathSegment.Length - 1) : pathSegment;
                var nextEntry           = await fileSystem.GetEntryByNameAsync(
                    currentDirectoryEntry,
                    childName,
                    cancellationToken)
                                          .ConfigureAwait(false);

                if (nextEntry == null)
                {
                    // Entry not found
                    var missingPathSegments = pathSegments.Skip(pathSegmentIndex).ToArray();
                    var lastIsDirectory     = missingPathSegments[missingPathSegments.Length - 1].EndsWith("/");
                    if (lastIsDirectory)
                    {
                        return(PathSelectionResult.CreateMissingDirectory(
                                   currentDirectoryEntries,
                                   missingPathSegments));
                    }

                    return(PathSelectionResult.CreateMissingFileOrDirectory(
                               currentDirectoryEntries,
                               missingPathSegments));
                }

                var isDirectory = nextEntry is IUnixDirectoryEntry;
                if (isDirectoryExpected && !isDirectory)
                {
                    // File instead of directory found
                    var missingPathSegments = pathSegments.Skip(pathSegmentIndex).ToArray();
                    return(PathSelectionResult.CreateMissingDirectory(
                               currentDirectoryEntries,
                               missingPathSegments));
                }

                if (!isDirectory)
                {
                    return(PathSelectionResult.Create(
                               currentDirectoryEntries,
                               (IUnixFileEntry)nextEntry));
                }

                currentDirectoryEntry = (IUnixDirectoryEntry)nextEntry;
                currentDirectoryEntries.Push(currentDirectoryEntry);
            }

            // Found directory
            return(PathSelectionResult.Create(
                       currentDirectoryEntries));
        }