Example #1
0
        /// <summary>
        /// Method that reads source file and places blocks into <paramref name="queue"/>. The receiver must return blocks to blockpool.
        ///
        /// This method is to be ran in a concurrent thread.
        ///
        /// If cancel is requested, aborts.
        ///
        /// If ioexception occurs, then sets op state to error.
        /// </summary>
        /// <param name="queue"></param>
        void ReadFile(BlockingCollection <Block> queue)
        {
            try
            {
                // CancelToken to monitor
                CancellationToken token = session.CancelSrc.Token;

                if (token.IsCancellationRequested)
                {
                    return;
                }

                // Open file
                Stream s = SrcFileSystem.Open(SrcPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite, srcOption.OptionIntersection(session.Option));
                try
                {
                    int len = 0;
                    do
                    {
                        // Cancelled, abort
                        if (token.IsCancellationRequested || CurrentState != OperationState.Running)
                        {
                            queue.Add(new Block {
                                data = null, count = -1                                                                                              /* cancellation */
                            }); return;
                        }
                        // Allocate block
                        byte[] data = session.BlockPool.Allocate();
                        // Read data to block
                        len = s.Read(data, 0, data.Length);
                        // Pass block
                        if (len > 0)
                        {
                            queue.Add(new Block {
                                data = data, count = len
                            });
                        }
                    } while (len > 0);
                    // Notify of eos with 0 length
                    queue.Add(new Block {
                        data = null, count = 0
                    });
                }
                finally
                {
                    s.Dispose();
                }
            }
            // Capture error and set state
            catch (Exception e)
            {
                // Set state of op to error
                SetError(e);
                // Notify of error with -2 length
                queue.Add(new Block {
                    data = null, count = -2
                });
            }
        }
Example #2
0
        /// <summary>Estimate viability of operation.</summary>
        /// <exception cref="FileNotFoundException">If <see cref="SrcPath"/> is not found.</exception>
        /// <exception cref="FileSystemExceptionEntryExists">If <see cref="Path"/> already exists.</exception>
        protected override void InnerEstimate()
        {
            // Cannot create
            if (!FileSystem.CanOpen() || !FileSystem.CanCreateFile())
            {
                throw new NotSupportedException("Copy");
            }

            // Test that source file exists
            if (SrcFileSystem.CanGetEntry())
            {
                try
                {
                    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;
                        }
                    }
                    // Set length
                    if (e.Length() > 0L)
                    {
                        this.TotalLength = e.Length();
                    }
                }
                catch (NotSupportedException)
                {
                    // GetEntry is not supported
                }
            }

            // Test that dest file doesn't exist
            if (FileSystem.CanGetEntry())
            {
                try
                {
                    IEntry dstEntry = dstFileSystem.GetEntry(Path, Option.OptionIntersection(session.Option));
                    prevExisted = dstEntry != null;
                    if (dstEntry != null)
                    {
                        // Dst exists
                        if (EffectivePolicy.HasFlag(OperationPolicy.DstThrow))
                        {
                            if (dstEntry.IsFile())
                            {
                                throw new FileSystemExceptionFileExists(FileSystem, Path);
                            }
                            else if (dstEntry.IsDirectory())
                            {
                                throw new FileSystemExceptionDirectoryExists(FileSystem, Path);
                            }
                            else
                            {
                                throw new FileSystemExceptionEntryExists(FileSystem, Path);
                            }
                        }

                        // Skip op
                        else if (EffectivePolicy.HasFlag(OperationPolicy.DstSkip))
                        {
                            SetState(OperationState.Skipped);
                            // Nothing to rollback, essentially ok
                            CanRollback = true;
                        }

                        // Overwrite
                        else if (EffectivePolicy.HasFlag(OperationPolicy.DstOverwrite))
                        {
                            // Cannot rollback
                            CanRollback = false;
                        }
                    }
                    else
                    {
                        // Prev file didn't exist, can be rollbacked
                        CanRollback = true;
                    }
                }
                catch (NotSupportedException)
                {
                    // GetEntry is not supported
                }
            }
        }