Пример #1
0
        public IReadOnlyDirectory Mount(IDisposableDirectory autoDisposingDirectory, string mountRoot)
        {
            IDirectory mountDir;

            if ((mountRoot == "/" || mountRoot == "") &&
                !autoDisposingDirectory.EnumerateFiles().Any() &&
                !autoDisposingDirectory.EnumerateDirectories().Any())
            {
                mountDir = autoDisposingDirectory;
            }
            // ContainsFile checks for directories as well.
            else if (!autoDisposingDirectory.ContainsFile(mountRoot))
            {
                mountDir = autoDisposingDirectory.OpenDirectory(mountRoot);
            }
            else
            {
                throw new IOException("Can not mount projection on an non-empty directory or already existing mount point.");
            }

            if (this.Parent != null)
            {
                throw new InvalidOperationException("Can not mount subtreee of projection.");
            }

            var activeDir = mountDir;

            foreach (var(name, file) in this.ProjectionState)
            {
                switch (file)
                {
                case DirectoryInfo dirInfo:
                    activeDir.LinkFrom(dirInfo, name);
                    break;

                case FileInfo fileInfo:
                    activeDir.LinkFrom(fileInfo, name);
                    break;
                }
            }

            Stack <(string, DirectoryProjection)> projectionsToProcess = new(this.Children.Select((kvp) => (kvp.Key, kvp.Value)));

            while (projectionsToProcess.Count > 0)
            {
                var(projectionName, projectionLevel) = projectionsToProcess.Pop();
                activeDir = activeDir.OpenDirectory(projectionName);
                foreach (var(name, file) in projectionLevel.ProjectionState)
                {
                    switch (file)
                    {
                    case DirectoryInfo dirInfo:
                        activeDir.LinkFrom(dirInfo, name);
                        break;

                    case FileInfo fileInfo:
                        activeDir.LinkFrom(fileInfo, name);
                        break;
                    }
                }
                foreach (var(name, childProjection) in projectionLevel.Children)
                {
                    projectionsToProcess.Push((name, childProjection));
                }
            }
            return(mountDir.AsReadOnly());
        }
Пример #2
0
 public IReadOnlyDirectory Mount(IDisposableDirectory autoDisposingDirectory)
 => this.Mount(autoDisposingDirectory, "");