Пример #1
0
        /// <summary>Estimate viability of operation.</summary>
        /// <exception cref="FileNotFoundException">If <see cref="SrcPath"/> is not found.</exception>
        /// <exception cref="FileSystemExceptionFileExists">If <see cref="Path"/> already exists.</exception>
        protected override void InnerEstimate()
        {
            PathConverter pathConverter = new PathConverter(SrcPath, Path);
            List <IEntry> queue         = new List <IEntry>();

            // Src
            IEntry e = SrcFileSystem.GetEntry(SrcPath, srcOption.OptionIntersection(session.Option));

            // Src not found
            if (e == null)
            {
                // Throw
                if (EffectivePolicy.HasFlag(OperationPolicy.SrcThrow))
                {
                    throw new FileNotFoundException(SrcPath);
                }
                // Skip
                if (EffectivePolicy.HasFlag(OperationPolicy.SrcSkip))
                {
                    SetState(OperationState.Skipped); return;
                }
                // Fail anyway
                throw new FileNotFoundException(SrcPath);
            }

            queue.Add(e);
            while (queue.Count > 0)
            {
                try
                {
                    // Next entry
                    int    lastIx = queue.Count - 1;
                    IEntry entry  = queue[lastIx];
                    queue.RemoveAt(lastIx);

                    // Omit package mounts
                    if (session.Policy.HasFlag(OperationPolicy.OmitMountedPackages) && entry.IsPackageMount())
                    {
                        continue;
                    }

                    // Process directory
                    if (entry.IsDirectory())
                    {
                        // Browse children
                        IDirectoryContent content = SrcFileSystem.Browse(entry.Path, srcOption.OptionIntersection(session.Option));
                        // Assert children don't refer to the parent of the parent
                        foreach (IEntry child in content)
                        {
                            if (entry.Path.StartsWith(child.Path))
                            {
                                throw new IOException($"{child.Path} cannot be child of {entry.Path}");
                            }
                        }
                        // Visit child
                        for (int i = content.Count - 1; i >= 0; i--)
                        {
                            queue.Add(content[i]);
                        }
                        // Convert path
                        string _dstPath;
                        if (!pathConverter.ParentToChild(entry.Path, out _dstPath))
                        {
                            throw new Exception("Failed to convert path");
                        }
                        // Add op
                        if (_dstPath != "")
                        {
                            Ops.Add(new CreateDirectory(session, FileSystem, _dstPath, Option.OptionIntersection(session.Option), OpPolicy));
                        }
                    }

                    // Process file
                    else if (entry.IsFile())
                    {
                        // Convert path
                        string _dstPath;
                        if (!pathConverter.ParentToChild(entry.Path, out _dstPath))
                        {
                            throw new Exception("Failed to convert path");
                        }
                        // Add op
                        Ops.Add(new CopyFile(session, SrcFileSystem, entry.Path, FileSystem, _dstPath, srcOption.OptionIntersection(session.Option), Option.OptionIntersection(session.Option), OpPolicy));
                    }
                }
                catch (Exception error) when(SetError(error))
                {
                }
            }

            base.InnerEstimate();
        }