Example #1
0
        /// <summary>
        /// Represents an open file in the runtime of Kuriimu.
        /// </summary>
        /// <param name="filePlugin">The entry class of the plugin for this file.</param>
        /// <param name="pluginState">The plugin state of this file.</param>
        /// <param name="parentState">The parent state for this file.</param>
        /// <param name="fileSystem">The file system around the initially opened file.</param>
        /// <param name="filePath">The path of the file to be opened in the file system.</param>
        /// <param name="streamManager">The stream manager used for this opened state.</param>
        /// <param name="pluginManager">The plugin manager for this state.</param>
        public StateInfo(IFilePlugin filePlugin, IPluginState pluginState, IStateInfo parentState,
                         IFileSystem fileSystem, UPath filePath,
                         IStreamManager streamManager, IPluginManager pluginManager)
        {
            ContractAssertions.IsNotNull(filePlugin, nameof(filePlugin));
            ContractAssertions.IsNotNull(pluginState, nameof(pluginState));
            ContractAssertions.IsNotNull(fileSystem, nameof(fileSystem));
            ContractAssertions.IsNotNull(streamManager, nameof(streamManager));
            ContractAssertions.IsNotNull(pluginManager, nameof(pluginManager));

            if (filePath == UPath.Empty || filePath.IsDirectory)
            {
                throw new InvalidOperationException($"'{filePath}' has to be a path to a file.");
            }
            if (!fileSystem.FileExists(filePath))
            {
                throw FileSystemExceptionHelper.NewFileNotFoundException(filePath);
            }

            FilePlugin    = filePlugin;
            PluginState   = pluginState;
            FilePath      = filePath;
            FileSystem    = fileSystem;
            StreamManager = streamManager;
            PluginManager = pluginManager;

            ParentStateInfo = parentState;

            ArchiveChildren = new List <IStateInfo>();
        }
Example #2
0
        /// <inheritdoc />
        public void ReplaceFile(UPath srcPath, UPath destPath, UPath destBackupPath, bool ignoreMetadataErrors)
        {
            AssertNotDisposed();
            AssertTrue(CanReplaceFiles, nameof(ReplaceFile));
            srcPath        = ValidatePath(srcPath, nameof(srcPath));
            destPath       = ValidatePath(destPath, nameof(destPath));
            destBackupPath = ValidatePath(destBackupPath, nameof(destBackupPath), true);

            if (!FileExistsImpl(srcPath))
            {
                throw FileSystemExceptionHelper.NewFileNotFoundException(srcPath);
            }

            if (!FileExistsImpl(destPath))
            {
                throw FileSystemExceptionHelper.NewFileNotFoundException(srcPath);
            }

            if (destBackupPath == srcPath)
            {
                throw new IOException($"The source and backup cannot have the same path `{srcPath}`");
            }

            ReplaceFileImpl(srcPath, destPath, destBackupPath, ignoreMetadataErrors);
        }
Example #3
0
 /// <summary>
 /// Initializes a new instance of the <see cref="SubFileSystem"/> class.
 /// </summary>
 /// <param name="fileSystem">The file system to create a view from.</param>
 /// <param name="subPath">The sub path view to create filesystem.</param>
 /// <param name="owned">True if <paramref name="fileSystem"/> should be disposed when this instance is disposed.</param>
 /// <exception cref="DirectoryNotFoundException">If the directory subPath does not exist in the delegate FileSystem</exception>
 public SubFileSystem(IFileSystem fileSystem, UPath subPath, bool owned = true) : base(fileSystem, owned)
 {
     SubPath = subPath.AssertAbsolute(nameof(subPath));
     if (!fileSystem.DirectoryExists(SubPath))
     {
         throw FileSystemExceptionHelper.NewDirectoryNotFoundException(SubPath);
     }
 }
Example #4
0
        /// <inheritdoc />
        protected override void DeleteDirectoryImpl(UPath path, bool isRecursive)
        {
            if (IsWithinSpecialDirectory(path))
            {
                if (!SpecialDirectoryExists(path))
                {
                    throw FileSystemExceptionHelper.NewDirectoryNotFoundException(path);
                }
                throw new UnauthorizedAccessException($"Cannot delete directory `{path}`");
            }

            Directory.Delete(ConvertPathToInternal(path), isRecursive);
        }
Example #5
0
        /// <inheritdoc />
        protected override void MoveDirectoryImpl(UPath srcPath, UPath destPath)
        {
            if (IsOnWindows)
            {
                if (IsWithinSpecialDirectory(srcPath))
                {
                    if (!SpecialDirectoryExists(srcPath))
                    {
                        throw FileSystemExceptionHelper.NewDirectoryNotFoundException(srcPath);
                    }

                    throw new UnauthorizedAccessException($"Cannot move the special directory `{srcPath}`");
                }

                if (IsWithinSpecialDirectory(destPath))
                {
                    if (!SpecialDirectoryExists(destPath))
                    {
                        throw FileSystemExceptionHelper.NewDirectoryNotFoundException(destPath);
                    }
                    throw new UnauthorizedAccessException($"Cannot move to the special directory `{destPath}`");
                }
            }

            var systemSrcPath  = ConvertPathToInternal(srcPath);
            var systemDestPath = ConvertPathToInternal(destPath);

            // If the source path is a file
            var fileInfo = new FileInfo(systemSrcPath);

            if (fileInfo.Exists)
            {
                throw new IOException($"The source `{srcPath}` is not a directory");
            }

            Directory.Move(systemSrcPath, systemDestPath);
        }
Example #6
0
        // ----------------------------------------------
        // Search API
        // ----------------------------------------------

        /// <inheritdoc />
        protected override IEnumerable <UPath> EnumeratePathsImpl(UPath path, string searchPattern, SearchOption searchOption, SearchTarget searchTarget)
        {
            // Special case for Windows as we need to provide list for:
            // - the root folder / (which should just return the /drive folder)
            // - the drive folders /drive/c, drive/e...etc.
            var search = SearchPattern.Parse(ref path, ref searchPattern);

            if (IsOnWindows)
            {
                if (IsWithinSpecialDirectory(path))
                {
                    if (!SpecialDirectoryExists(path))
                    {
                        throw FileSystemExceptionHelper.NewDirectoryNotFoundException(path);
                    }

                    var searchForDirectory = searchTarget == SearchTarget.Both || searchTarget == SearchTarget.Directory;

                    // Only sub folder "/drive/" on root folder /
                    if (path == UPath.Root)
                    {
                        if (!searchForDirectory)
                        {
                            yield break;
                        }

                        yield return(PathDrivePrefixOnWindows);

                        if (searchOption != SearchOption.AllDirectories)
                        {
                            yield break;
                        }

                        foreach (var subPath in EnumeratePathsImpl(PathDrivePrefixOnWindows, searchPattern, searchOption, searchTarget))
                        {
                            yield return(subPath);
                        }

                        yield break;
                    }

                    // When listing for /drive, return the list of drives available
                    if (path == PathDrivePrefixOnWindows)
                    {
                        var pathDrives = new List <UPath>();
                        foreach (var drive in DriveInfo.GetDrives())
                        {
                            if (drive.Name.Length < 2 || drive.Name[1] != ':')
                            {
                                continue;
                            }

                            var pathDrive = PathDrivePrefixOnWindows / char.ToLowerInvariant(drive.Name[0]).ToString();

                            if (search.Match(pathDrive))
                            {
                                pathDrives.Add(pathDrive);

                                if (searchForDirectory)
                                {
                                    yield return(pathDrive);
                                }
                            }
                        }

                        if (searchOption == SearchOption.AllDirectories)
                        {
                            foreach (var pathDrive in pathDrives)
                            {
                                foreach (var subPath in EnumeratePathsImpl(pathDrive, searchPattern, searchOption, searchTarget))
                                {
                                    yield return(subPath);
                                }
                            }
                        }

                        yield break;
                    }
                }
            }

            IEnumerable <string> results;

            switch (searchTarget)
            {
            case SearchTarget.File:
                results = Directory.EnumerateFiles(ConvertPathToInternal(path), searchPattern, searchOption);
                break;

            case SearchTarget.Directory:
                results = Directory.EnumerateDirectories(ConvertPathToInternal(path), searchPattern, searchOption);
                break;

            case SearchTarget.Both:
                results = Directory.EnumerateFileSystemEntries(ConvertPathToInternal(path), searchPattern, searchOption);
                break;

            default:
                yield break;
            }

            foreach (var subPath in results)
            {
                // Windows will truncate the search pattern's extension to three characters if the filesystem
                // has 8.3 paths enabled. This means searching for *.docx will list *.doc as well which is
                // not what we want. Check against the search pattern again to filter out those false results.
                if (!IsOnWindows || search.Match(Path.GetFileName(subPath)))
                {
                    yield return(ConvertPathFromInternal(subPath));
                }
            }
        }