Changeset 1515


Ignore:
Timestamp:
01/13/10 04:29:25 (5 years ago)
Author:
lowjoel
Message:

Merged the SpeedMeter? branch to trunk. Fixes #90: Generic speed meter

Location:
trunk/eraser6
Files:
11 edited
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/eraser6

  • trunk/eraser6/Eraser.Manager/DirectExecutor.cs

    r1496 r1515  
    251251 
    252252                        //Run the task 
    253                         TaskProgressManager progress = new TaskProgressManager(task); 
    254253                        foreach (ErasureTarget target in task.Targets) 
    255254                            try 
    256255                            { 
    257                                 progress.Event.CurrentTarget = target; 
    258                                 ++progress.Event.CurrentTargetIndex; 
    259  
    260256                                UnusedSpaceTarget unusedSpaceTarget = 
    261257                                    target as UnusedSpaceTarget; 
     
    264260 
    265261                                if (unusedSpaceTarget != null) 
    266                                     EraseUnusedSpace(task, unusedSpaceTarget, progress); 
     262                                    EraseUnusedSpace(task, unusedSpaceTarget); 
    267263                                else if (fileSystemObjectTarget != null) 
    268                                     EraseFilesystemObject(task, fileSystemObjectTarget, progress); 
     264                                    EraseFilesystemObject(task, fileSystemObjectTarget); 
    269265                                else 
    270266                                    throw new ArgumentException(S._("Unknown erasure target.")); 
     
    324320 
    325321        /// <summary> 
    326         /// Manages the progress for any operation. 
    327         /// </summary> 
    328         private class ProgressManager 
    329         { 
    330             /// <summary> 
    331             /// Starts measuring the speed of the task. 
    332             /// </summary> 
    333             public void Start() 
    334             { 
    335                 startTime = DateTime.Now; 
    336             } 
    337  
    338             /// <summary> 
    339             /// Tracks the amount of the operation completed. 
    340             /// </summary> 
    341             public long Completed 
    342             { 
    343                 get 
    344                 { 
    345                     return completed; 
    346                 } 
    347                 set 
    348                 { 
    349                     lastCompleted += value - completed; 
    350                     completed = value; 
    351                 } 
    352             } 
    353  
    354             /// <summary> 
    355             /// The amount to reach before the operation completes. 
    356             /// </summary> 
    357             public long Total 
    358             { 
    359                 get 
    360                 { 
    361                     return total; 
    362                 } 
    363                 set 
    364                 { 
    365                     total = value; 
    366                 } 
    367             } 
    368  
    369             /// <summary> 
    370             /// Gets the percentage of the operation completed. 
    371             /// </summary> 
    372             public float Progress 
    373             { 
    374                 get 
    375                 { 
    376                     return (float)((double)Completed / Total); 
    377                 } 
    378             } 
    379  
    380             /// <summary> 
    381             /// Computes the speed of the erase, in units of completion per second, 
    382             /// based on the information collected in the previous 15 seconds. 
    383             /// </summary> 
    384             public int Speed 
    385             { 
    386                 get 
    387                 { 
    388                     if (DateTime.Now == startTime) 
    389                         return 0; 
    390  
    391                     if ((DateTime.Now - lastSpeedCalc).Seconds < 5 && lastSpeed != 0) 
    392                         return lastSpeed; 
    393  
    394                     //Calculate how much time has passed 
    395                     double timeElapsed = (DateTime.Now - lastSpeedCalc).TotalSeconds; 
    396                     if (timeElapsed == 0.0) 
    397                         return 0; 
    398  
    399                     //Then compute the speed of the calculation 
    400                     lastSpeed = (int)(lastCompleted / timeElapsed); 
    401                     lastSpeedCalc = DateTime.Now; 
    402                     lastCompleted = 0; 
    403                     return lastSpeed; 
    404                 } 
    405             } 
    406  
    407             /// <summary> 
    408             /// Calculates the estimated amount of time left based on the total 
    409             /// amount of information to erase and the current speed of the erase 
    410             /// </summary> 
    411             public TimeSpan TimeLeft 
    412             { 
    413                 get 
    414                 { 
    415                     if (Speed == 0) 
    416                         return new TimeSpan(0, 0, -1); 
    417                     return new TimeSpan(0, 0, (int)((Total - Completed) / Speed)); 
    418                 } 
    419             } 
    420  
    421             /// <summary> 
    422             /// The starting time of the operation, used to determine average speed. 
    423             /// </summary> 
    424             private DateTime startTime; 
    425  
    426             /// <summary> 
    427             /// The last time a speed calculation was computed so that speed is not 
    428             /// computed too often. 
    429             /// </summary> 
    430             private DateTime lastSpeedCalc; 
    431  
    432             /// <summary> 
    433             /// The last calculated speed of the operation. 
    434             /// </summary> 
    435             private int lastSpeed; 
    436  
    437             /// <summary> 
    438             /// The amount of the operation completed since the last speed computation. 
    439             /// </summary> 
    440             private long lastCompleted; 
    441  
    442             /// <summary> 
    443             /// The amount of the operation completed. 
    444             /// </summary> 
    445             private long completed; 
    446  
    447             /// <summary> 
    448             /// The amount to reach before the operation is completed. 
    449             /// </summary> 
    450             private long total; 
    451         } 
    452  
    453         /// <summary> 
    454         /// Provides a common interface to track the progress made by the Erase functions. 
    455         /// </summary> 
    456         private class TaskProgressManager : ProgressManager 
    457         { 
    458             /// <summary> 
    459             /// Constructor. 
    460             /// </summary> 
    461             public TaskProgressManager(Task task) 
    462             { 
    463                 foreach (ErasureTarget target in task.Targets) 
    464                     Total += target.TotalData; 
    465  
    466                 Event = new TaskProgressEventArgs(task); 
    467                 Start(); 
    468             } 
    469  
    470             /// <summary> 
    471             /// The TaskProgressEventArgs object representing the progress of the current 
    472             /// task. 
    473             /// </summary> 
    474             public TaskProgressEventArgs Event 
    475             { 
    476                 get 
    477                 { 
    478                     return evt; 
    479                 } 
    480                 set 
    481                 { 
    482                     evt = value; 
    483                 } 
    484             } 
    485  
    486             private TaskProgressEventArgs evt; 
    487         } 
    488  
    489         /// <summary> 
    490322        /// Executes a unused space erase. 
    491323        /// </summary> 
    492324        /// <param name="task">The task currently being executed</param> 
    493325        /// <param name="target">The target of the unused space erase.</param> 
    494         /// <param name="progress">The progress manager object managing the progress of the task</param> 
    495         private void EraseUnusedSpace(Task task, UnusedSpaceTarget target, TaskProgressManager progress) 
     326        private void EraseUnusedSpace(Task task, UnusedSpaceTarget target) 
    496327        { 
    497328            //Check for sufficient privileges to run the unused space erasure. 
     
    532363            VolumeInfo volInfo = VolumeInfo.FromMountpoint(target.Drive); 
    533364            FileSystem fsManager = FileSystemManager.Get(volInfo); 
    534              
     365 
     366            //Start sampling the speed of the task. 
     367            SteppedProgressManager progress = new SteppedProgressManager(); 
     368            target.Progress = progress; 
     369            task.Progress.Steps.Add(new SteppedProgressManager.Step( 
     370                progress, 1.0f / task.Targets.Count)); 
     371 
    535372            //Erase the cluster tips of every file on the drive. 
    536373            if (target.EraseClusterTips) 
    537374            { 
    538                 progress.Event.CurrentTargetStatus = S._("Searching for files' cluster tips..."); 
    539                 progress.Event.CurrentTargetTotalPasses = method.Passes; 
    540                 progress.Event.CurrentItemProgress = -1.0f; 
    541                 progress.Event.TimeLeft = new TimeSpan(0, 0, -1); 
    542  
    543                 //Start counting statistics 
     375                //Define the callback handlers 
     376                ProgressManager tipSearch = new ProgressManager(); 
     377                progress.Steps.Add(new SteppedProgressManager.Step(tipSearch,  
     378                    0.0f, S._("Searching for files' cluster tips..."))); 
     379                tipSearch.Total = 1; 
     380                ClusterTipsSearchProgress searchProgress = delegate(string path) 
     381                    { 
     382                        if (currentTask.Canceled) 
     383                            throw new OperationCanceledException(S._("The task was cancelled.")); 
     384 
     385                        task.OnProgressChanged(target, 
     386                            new ProgressChangedEventArgs(tipSearch, 
     387                                new TaskProgressChangedEventArgs(path, 0, 0))); 
     388                    }; 
     389 
    544390                ProgressManager tipProgress = new ProgressManager(); 
    545                 tipProgress.Start(); 
    546  
    547                 //Define the callback handlers 
    548                 ClusterTipsSearchProgress searchProgress = delegate(string path) 
    549                     { 
    550                         progress.Event.CurrentItemName = path; 
    551                         task.OnProgressChanged(progress.Event); 
     391                progress.Steps.Add(new SteppedProgressManager.Step(tipProgress, 0.1f, 
     392                    S._("Erasing cluster tips..."))); 
     393                ClusterTipsEraseProgress eraseProgress = 
     394                    delegate(int currentFile, int totalFiles, string currentFilePath) 
     395                    { 
     396                        tipSearch.Completed = tipSearch.Total; 
     397                        tipProgress.Total = totalFiles; 
     398                        tipProgress.Completed = currentFile; 
     399                        task.OnProgressChanged(target, 
     400                            new ProgressChangedEventArgs(tipProgress, 
     401                                new TaskProgressChangedEventArgs(currentFilePath, 0, 0))); 
    552402 
    553403                        if (currentTask.Canceled) 
     
    555405                    }; 
    556406 
    557                 ClusterTipsEraseProgress eraseProgress = 
    558                     delegate(int currentFile, int totalFiles, string currentFilePath) 
    559                     { 
    560                         tipProgress.Total = totalFiles; 
    561                         tipProgress.Completed = currentFile; 
    562  
    563                         progress.Event.CurrentTargetStatus = S._("Erasing cluster tips..."); 
    564                         progress.Event.CurrentItemName = currentFilePath; 
    565                         progress.Event.CurrentItemProgress = tipProgress.Progress; 
    566                         progress.Event.CurrentTargetProgress = progress.Event.CurrentItemProgress / 10; 
    567                         progress.Event.TimeLeft = tipProgress.TimeLeft; 
    568                         task.OnProgressChanged(progress.Event); 
    569  
    570                         if (currentTask.Canceled) 
    571                             throw new OperationCanceledException(S._("The task was cancelled.")); 
    572                     }; 
    573  
     407                //Start counting statistics 
    574408                fsManager.EraseClusterTips(VolumeInfo.FromMountpoint(target.Drive), 
    575409                    method, task.Log, searchProgress, eraseProgress); 
     
    585419                    Eraser.Util.File.SetCompression(info.FullName, false); 
    586420 
     421                ProgressManager mainProgress = new ProgressManager(); 
     422                progress.Steps.Add(new SteppedProgressManager.Step(mainProgress, 
     423                    target.EraseClusterTips ? 0.8f : 0.9f, S._("Erasing unused space..."))); 
     424 
    587425                //Continue creating files while there is free space. 
    588                 progress.Event.CurrentTargetStatus = S._("Erasing unused space..."); 
    589                 progress.Event.CurrentItemName = target.Drive; 
    590                 task.OnProgressChanged(progress.Event); 
    591426                while (volInfo.AvailableFreeSpace > 0) 
    592427                { 
     
    600435                        //Set the length of the file to be the amount of free space left 
    601436                        //or the maximum size of one of these dumps. 
     437                        mainProgress.Total = mainProgress.Completed + volInfo.AvailableFreeSpace; 
    602438                        long streamLength = Math.Min(ErasureMethod.FreeSpaceFileUnit, 
    603                             volInfo.AvailableFreeSpace); 
     439                            mainProgress.Total); 
    604440 
    605441                        //Handle IO exceptions gracefully, because the filesystem 
     
    624460                            delegate(long lastWritten, long totalData, int currentPass) 
    625461                            { 
    626                                 progress.Completed = Math.Min(progress.Total, 
    627                                     progress.Completed + lastWritten); 
    628                                 progress.Event.CurrentItemPass = currentPass; 
    629                                 progress.Event.CurrentItemProgress = progress.Progress; 
    630                                 if (target.EraseClusterTips) 
    631                                     progress.Event.CurrentTargetProgress = (float) 
    632                                         (0.1f + progress.Event.CurrentItemProgress * 0.8f); 
    633                                 else 
    634                                     progress.Event.CurrentTargetProgress = (float) 
    635                                         (progress.Event.CurrentItemProgress * 0.9f); 
    636                                 progress.Event.TimeLeft = progress.TimeLeft; 
    637                                 task.OnProgressChanged(progress.Event); 
     462                                mainProgress.Completed += lastWritten; 
     463                                task.OnProgressChanged(target, 
     464                                    new ProgressChangedEventArgs(mainProgress, 
     465                                        new TaskProgressChangedEventArgs(target.Drive, currentPass, method.Passes))); 
    638466 
    639467                                if (currentTask.Canceled) 
     
    644472                } 
    645473 
     474                //Mark the main bulk of the progress as complete 
     475                mainProgress.Completed = mainProgress.Total; 
     476 
    646477                //Erase old resident file system table files 
    647                 progress.Event.CurrentItemName = S._("Old resident file system table files"); 
    648                 task.OnProgressChanged(progress.Event); 
    649                 ProgressManager residentFilesProgress = new ProgressManager(); 
    650                 residentFilesProgress.Start(); 
     478                ProgressManager residentProgress = new ProgressManager(); 
     479                progress.Steps.Add(new SteppedProgressManager.Step(residentProgress, 
     480                    0.05f, S._("Old resident file system table files"))); 
    651481                fsManager.EraseOldFileSystemResidentFiles(volInfo, info, method, 
    652482                    delegate(int currentFile, int totalFiles) 
    653483                    { 
    654                         residentFilesProgress.Completed = currentFile; 
    655                         residentFilesProgress.Total = totalFiles; 
    656                         progress.Event.CurrentItemProgress = residentFilesProgress.Progress; 
    657                         progress.Event.TimeLeft = residentFilesProgress.TimeLeft; 
    658                         task.OnProgressChanged(progress.Event); 
     484                        residentProgress.Completed = currentFile; 
     485                        residentProgress.Total = totalFiles; 
     486                        task.OnProgressChanged(target, 
     487                            new ProgressChangedEventArgs(residentProgress, 
     488                                new TaskProgressChangedEventArgs(string.Empty, 0, 0))); 
    659489 
    660490                        if (currentTask.Canceled) 
     
    662492                    } 
    663493                ); 
     494 
     495                residentProgress.Completed = residentProgress.Total = 1; 
    664496            } 
    665497            finally 
    666498            { 
    667499                //Remove the folder holding all our temporary files. 
    668                 progress.Event.CurrentTargetStatus = S._("Removing temporary files..."); 
    669                 task.OnProgressChanged(progress.Event); 
     500                ProgressManager tempFiles = new ProgressManager(); 
     501                progress.Steps.Add(new SteppedProgressManager.Step(tempFiles, 
     502                    0.0f, S._("Removing temporary files..."))); 
     503                task.OnProgressChanged(target, new ProgressChangedEventArgs(tempFiles, 
     504                    new TaskProgressChangedEventArgs(string.Empty, 0, 0))); 
    670505                fsManager.DeleteFolder(info); 
     506                tempFiles.Completed = tempFiles.Total = 1; 
    671507            } 
    672508 
    673509            //Then clean the old file system entries 
    674             progress.Event.CurrentTargetStatus = S._("Erasing unused directory structures..."); 
    675             ProgressManager fsEntriesProgress = new ProgressManager(); 
    676             fsEntriesProgress.Start(); 
     510            ProgressManager structureProgress = new ProgressManager(); 
     511            progress.Steps.Add(new SteppedProgressManager.Step(structureProgress, 
     512                0.05f, S._("Erasing unused directory structures..."))); 
    677513            fsManager.EraseDirectoryStructures(volInfo, 
    678514                delegate(int currentFile, int totalFiles) 
     
    682518 
    683519                    //Compute the progress 
    684                     fsEntriesProgress.Total = totalFiles; 
    685                     fsEntriesProgress.Completed = currentFile; 
     520                    structureProgress.Total = totalFiles; 
     521                    structureProgress.Completed = currentFile; 
    686522 
    687523                    //Set the event parameters, then broadcast the progress event. 
    688                     progress.Event.TimeLeft = fsEntriesProgress.TimeLeft; 
    689                     progress.Event.CurrentItemProgress = fsEntriesProgress.Progress; 
    690                     progress.Event.CurrentTargetProgress = (float)( 
    691                         0.9 + progress.Event.CurrentItemProgress / 10); 
    692                     task.OnProgressChanged(progress.Event); 
     524                    task.OnProgressChanged(target, 
     525                        new ProgressChangedEventArgs(structureProgress, 
     526                            new TaskProgressChangedEventArgs(string.Empty, 0, 0))); 
    693527                } 
    694528            ); 
    695         } 
    696  
    697         /// <summary> 
    698         /// Traverses the given folder and deletes it securely only if it is 
    699         /// empty. 
    700         /// </summary> 
    701         /// <param name="info">The folder to check.</param> 
    702         private delegate void FolderEraseDelegate(DirectoryInfo info); 
     529 
     530            structureProgress.Completed = structureProgress.Total; 
     531            target.Progress = null; 
     532        } 
    703533 
    704534        /// <summary> 
     
    708538        /// <param name="target">The target of the erasure.</param> 
    709539        /// <param name="progress">The progress manager for the current task.</param> 
    710         private void EraseFilesystemObject(Task task, FileSystemObjectTarget target, 
    711             TaskProgressManager progress) 
     540        private void EraseFilesystemObject(Task task, FileSystemObjectTarget target) 
    712541        { 
    713542            //Retrieve the list of files to erase. 
     
    719548 
    720549            //Calculate the total amount of data required to finish the wipe. 
    721             dataTotal = method.CalculateEraseDataSize(paths, dataTotal); 
     550            //dataTotal = method.CalculateEraseDataSize(paths, dataTotal); 
    722551 
    723552            //Set the event's current target status. 
    724             progress.Event.CurrentTargetStatus = S._("Erasing files..."); 
     553            TaskEventArgs eventArgs = new TaskEventArgs(task); 
     554            SteppedProgressManager progress = new SteppedProgressManager(); 
     555            target.Progress = progress; 
     556            task.Progress.Steps.Add(new SteppedProgressManager.Step(progress, 1.0f / task.Targets.Count)); 
    725557 
    726558            //Iterate over every path, and erase the path. 
     
    728560            { 
    729561                //Update the task progress 
    730                 progress.Event.CurrentTargetProgress = i / (float)paths.Count; 
    731                 progress.Event.CurrentTarget = target; 
    732                 progress.Event.CurrentItemName = paths[i]; 
    733                 progress.Event.CurrentItemProgress = 0; 
    734                 progress.Event.CurrentTargetTotalPasses = method.Passes; 
    735                 task.OnProgressChanged(progress.Event); 
     562                ProgressManager step = new ProgressManager(); 
     563                progress.Steps.Add(new SteppedProgressManager.Step(step, 
     564                    1.0f / paths.Count, S._("Erasing files..."))); 
     565                task.OnProgressChanged(target, 
     566                    new ProgressChangedEventArgs(step, 
     567                        new TaskProgressChangedEventArgs(paths[i], 0, method.Passes))); 
    736568                 
    737569                //Get the filesystem provider to handle the secure file erasures 
     
    768600                    } 
    769601 
    770                     long itemWritten = 0; 
    771602                    fsManager.EraseFileSystemObject(info, method, 
    772603                        delegate(long lastWritten, long totalData, int currentPass) 
    773604                        { 
    774                             dataTotal -= lastWritten; 
    775                             progress.Completed += lastWritten; 
    776                             progress.Event.CurrentItemPass = currentPass; 
    777                             progress.Event.CurrentItemProgress = (float) 
    778                                 ((itemWritten += lastWritten) / (float)totalData); 
    779                             progress.Event.CurrentTargetProgress = 
    780                                 (i + progress.Event.CurrentItemProgress) / 
    781                                 (float)paths.Count; 
    782                             progress.Event.TimeLeft = progress.TimeLeft; 
    783                             task.OnProgressChanged(progress.Event); 
    784  
    785605                            if (currentTask.Canceled) 
    786606                                throw new OperationCanceledException(S._("The task was cancelled.")); 
     607 
     608                            step.Completed += lastWritten; 
     609                            step.Total = totalData; 
     610                            task.OnProgressChanged(target, 
     611                                new ProgressChangedEventArgs(step, 
     612                                    new TaskProgressChangedEventArgs(info.FullName, currentPass, method.Passes))); 
    787613                        }); 
    788614 
     
    791617                    if (fileInfo != null) 
    792618                        fsManager.DeleteFile(fileInfo); 
     619                    step.Completed = step.Total = 1; 
    793620                } 
    794621                catch (UnauthorizedAccessException) 
     
    828655            if (target is FolderTarget) 
    829656            { 
    830                 progress.Event.CurrentTargetStatus = S._("Removing folders..."); 
     657                ProgressManager step = new ProgressManager(); 
     658                progress.Steps.Add(new SteppedProgressManager.Step(step, 
     659                    0.0f, S._("Removing folders..."))); 
    831660                 
    832661                //Remove all subfolders which are empty. 
    833662                FolderTarget fldr = (FolderTarget)target; 
    834663                FileSystem fsManager = FileSystemManager.Get(VolumeInfo.FromMountpoint(fldr.Path)); 
    835                 FolderEraseDelegate eraseEmptySubFolders = null; 
     664                Action<DirectoryInfo> eraseEmptySubFolders = null; 
    836665                eraseEmptySubFolders = delegate(DirectoryInfo info) 
    837666                { 
    838                     foreach (DirectoryInfo subDir in info.GetDirectories()) 
    839                         eraseEmptySubFolders(subDir); 
    840  
    841                     progress.Event.CurrentItemName = info.FullName; 
    842                     task.OnProgressChanged(progress.Event); 
    843  
    844                     FileSystemInfo[] files = info.GetFileSystemInfos(); 
    845                     if (files.Length == 0) 
    846                         fsManager.DeleteFolder(info); 
     667                     foreach (DirectoryInfo subDir in info.GetDirectories()) 
     668                         eraseEmptySubFolders(subDir); 
     669                     task.OnProgressChanged(target, 
     670                         new ProgressChangedEventArgs(step, 
     671                             new TaskProgressChangedEventArgs(info.FullName, 0, 0))); 
     672 
     673                     FileSystemInfo[] files = info.GetFileSystemInfos(); 
     674                     if (files.Length == 0) 
     675                         fsManager.DeleteFolder(info); 
    847676                }; 
    848677                eraseEmptySubFolders(new DirectoryInfo(fldr.Path)); 
     
    851680                { 
    852681                    DirectoryInfo info = new DirectoryInfo(fldr.Path); 
    853                     progress.Event.CurrentItemName = info.FullName; 
    854                     task.OnProgressChanged(progress.Event); 
     682                    task.OnProgressChanged(target, 
     683                        new ProgressChangedEventArgs(step, 
     684                            new TaskProgressChangedEventArgs(info.FullName, 0, 0))); 
    855685 
    856686                    //See if this is the root of a volume. 
     
    871701            if (target is RecycleBinTarget) 
    872702            { 
    873                 progress.Event.CurrentTargetStatus = S._("Emptying recycle bin..."); 
    874                 task.OnProgressChanged(progress.Event); 
     703                ProgressManager step = new ProgressManager(); 
     704                progress.Steps.Add(new SteppedProgressManager.Step(step, 
     705                    0.0f, S._("Emptying recycle bin..."))); 
     706                task.OnProgressChanged(target, 
     707                    new ProgressChangedEventArgs(step, 
     708                        new TaskProgressChangedEventArgs(string.Empty, 0, 0))); 
    875709 
    876710                ShellApi.EmptyRecycleBin(EmptyRecycleBinOptions.NoConfirmation | 
    877711                    EmptyRecycleBinOptions.NoProgressUI | EmptyRecycleBinOptions.NoSound); 
    878712            } 
     713 
     714            target.Progress = null; 
    879715        } 
    880716 
  • trunk/eraser6/Eraser.Manager/Eraser.Manager.csproj

    r1334 r1515  
    6161    <Compile Include="Plugins.cs" /> 
    6262    <Compile Include="PRNG.cs" /> 
     63    <Compile Include="ProgressManager.cs" /> 
    6364    <Compile Include="Properties\AssemblyInfo.cs" /> 
    6465    <Compile Include="RemoteExecutor.cs" /> 
  • trunk/eraser6/Eraser.Manager/Task.cs

    r1498 r1515  
    161161        public bool Canceled 
    162162        { 
    163             get 
    164             { 
    165                 return canceled; 
    166             } 
    167  
    168             internal set 
    169             { 
    170                 canceled = value; 
    171             } 
     163            get; 
     164            internal set; 
    172165        } 
    173166 
     
    206199        public Logger Log { get; private set; } 
    207200 
     201        /// <summary> 
     202        /// The progress manager object which manages the progress of this task. 
     203        /// </summary> 
     204        public SteppedProgressManager Progress 
     205        { 
     206            get 
     207            { 
     208                if (!Executing) 
     209                    throw new InvalidOperationException("The progress of an erasure can only " + 
     210                        "be queried when the task is being executed."); 
     211 
     212                return progress; 
     213            } 
     214            private set 
     215            { 
     216                progress = value; 
     217            } 
     218        } 
     219 
    208220        private Schedule schedule; 
    209  
    210         /// <see cref="Canceled"/> 
    211         private volatile bool canceled; 
     221        private SteppedProgressManager progress; 
    212222 
    213223        #region Events 
     
    225235        /// The event object holding all event handlers. 
    226236        /// </summary> 
    227         public EventHandler<TaskProgressEventArgs> ProgressChanged { get; set; } 
     237        public EventHandler<ProgressChangedEventArgs> ProgressChanged { get; set; } 
    228238 
    229239        /// <summary> 
     
    250260                TaskStarted(this, e); 
    251261            Executing = true; 
    252         } 
    253  
    254         /// <summary> 
    255         /// Broadcasts a ProgressChanged event. 
    256         /// </summary> 
     262            Progress = new SteppedProgressManager(); 
     263        } 
     264 
     265        /// <summary> 
     266        /// Broadcasts a ProgressChanged event. The sender will be the erasure target 
     267        /// which broadcast this event; e.UserState will contain extra information 
     268        /// about the progress which is stored as a TaskProgressChangedEventArgs 
     269        /// object. 
     270        /// </summary> 
     271        /// <param name="sender">The <see cref="ErasureTarget"/> which is reporting 
     272        /// progress.</param> 
    257273        /// <param name="e">The new progress value.</param> 
    258         internal void OnProgressChanged(TaskProgressEventArgs e) 
    259         { 
     274        /// <exception cref="ArgumentException">e.UserState must be of the type 
     275        /// <see cref="TaskProgressEventargs"/></exception> 
     276        /// <exception cref="ArgumentNullException">Both sender and e cannot be null.</exception> 
     277        internal void OnProgressChanged(ErasureTarget sender, ProgressChangedEventArgs e) 
     278        { 
     279            if (sender == null) 
     280                throw new ArgumentNullException("sender"); 
     281            if (e == null) 
     282                throw new ArgumentNullException("sender"); 
     283            if (e.UserState.GetType() != typeof(TaskProgressChangedEventArgs)) 
     284                throw new ArgumentException("The Task.OnProgressChanged event expects a " + 
     285                    "TaskProgressEventArgs argument for the ProgressChangedEventArgs' UserState " + 
     286                    "object.", "e"); 
     287 
    260288            if (ProgressChanged != null) 
    261                 ProgressChanged(this, e); 
     289                ProgressChanged(sender, e); 
    262290        } 
    263291 
     
    271299                TaskFinished(this, e); 
    272300            Executing = false; 
     301            Progress = null; 
    273302        } 
    274303        #endregion 
     
    358387        /// </summary> 
    359388        private ErasureMethod method; 
     389 
     390        /// <summary> 
     391        /// The progress of this target. 
     392        /// </summary> 
     393        public ProgressManagerBase Progress 
     394        { 
     395            get; 
     396            internal set; 
     397        } 
    360398    } 
    361399 
     
    9891027 
    9901028    /// <summary> 
    991     /// A Event argument object containing the progress of the task. 
     1029    /// Stores extra information in the <see cref="ProgressChangedEventArgs"/> 
     1030    /// structure that is not conveyed in the ProgressManagerBase classes. 
    9921031    /// </summary> 
    993     public class TaskProgressEventArgs : TaskEventArgs 
     1032    public class TaskProgressChangedEventArgs 
    9941033    { 
    9951034        /// <summary> 
    9961035        /// Constructor. 
    9971036        /// </summary> 
    998         /// <param name="task">The task being run.</param> 
    999         public TaskProgressEventArgs(Task task) 
    1000             : base(task) 
    1001         { 
    1002             CurrentItemPass = 1; 
    1003         } 
    1004  
    1005         /// <summary> 
    1006         /// A number from 0 to 1 detailing the overall progress of the task. 
    1007         /// </summary> 
    1008         public float OverallProgress 
    1009         { 
    1010             get { return overallProgress; } 
    1011         } 
    1012  
    1013         /// <summary> 
    1014         /// The amount of time left for the operation to complete, in seconds. 
    1015         /// </summary> 
    1016         public TimeSpan TimeLeft { get; internal set; } 
    1017  
    1018         /// <summary> 
    1019         /// The current erasure target - the current item being erased. 
    1020         /// </summary> 
    1021         public ErasureTarget CurrentTarget { get; internal set; } 
    1022  
    1023         /// <summary> 
    1024         /// The current index of the target. 
    1025         /// </summary> 
    1026         public int CurrentTargetIndex { get; internal set; } 
     1037        /// <param name="itemName">The item whose erasure progress is being erased.</param> 
     1038        /// <param name="itemPass">The current pass number for this item.</param> 
     1039        /// <param name="itemTotalPasses">The total number of passes to complete erasure 
     1040        /// of this item.</param> 
     1041        public TaskProgressChangedEventArgs(string itemName, int itemPass, 
     1042            int itemTotalPasses) 
     1043        { 
     1044            ItemName = itemName; 
     1045            ItemPass = itemPass; 
     1046            ItemTotalPasses = itemTotalPasses; 
     1047        } 
     1048 
     1049        /// <summary> 
     1050        /// The file name of the item being erased. 
     1051        /// </summary> 
     1052        public string ItemName { get; private set; } 
     1053 
     1054        /// <summary> 
     1055        /// The pass number of a multi-pass erasure method. 
     1056        /// </summary> 
     1057        public int ItemPass { get; private set; } 
    10271058 
    10281059        /// <summary> 
     
    10301061        /// completed. 
    10311062        /// </summary> 
    1032         public int CurrentTargetTotalPasses { get; internal set; } 
    1033  
    1034         /// <summary> 
    1035         /// The stage of the erasure the executor is at. 
    1036         /// </summary> 
    1037         public string CurrentTargetStatus { get; internal set; } 
    1038  
    1039         /// <summary> 
    1040         /// A number from 0 to 1 detailing the overall progress of the item. 
    1041         /// Negative numbers indicate indeterminate progress. 
    1042         /// </summary> 
    1043         public float CurrentItemProgress { get; internal set; } 
    1044  
    1045         /// <summary> 
    1046         /// The file name of the item being erased. 
    1047         /// </summary> 
    1048         public string CurrentItemName { get; internal set; } 
    1049  
    1050         /// <summary> 
    1051         /// The pass number of a multi-pass erasure method. 
    1052         /// </summary> 
    1053         public int CurrentItemPass { get; internal set; } 
    1054  
    1055         /// <summary> 
    1056         /// The progress made by the current target. 
    1057         /// </summary> 
    1058         internal float CurrentTargetProgress 
    1059         { 
    1060             set 
    1061             { 
    1062                 overallProgress = Math.Min( 
    1063                     (value + (float)(CurrentTargetIndex - 1)) / Task.Targets.Count, 
    1064                     1.0f); 
    1065             } 
    1066         } 
    1067  
    1068         private float overallProgress; 
     1063        public int ItemTotalPasses { get; private set; } 
    10691064    } 
    10701065} 
  • trunk/eraser6/Eraser/ProgressForm.cs

    r1360 r1515  
    3131using Eraser.Util; 
    3232using System.Globalization; 
     33using ProgressChangedEventArgs = Eraser.Manager.ProgressChangedEventArgs; 
    3334 
    3435namespace Eraser 
     
    5152            task.ProgressChanged += task_ProgressChanged; 
    5253            task.TaskFinished += task_TaskFinished; 
     54 
     55            //Set the current progress 
     56            if (task.Progress.CurrentStep != null) 
     57                UpdateProgress((SteppedProgressManager)task.Progress.CurrentStep.Progress, 
     58                    new ProgressChangedEventArgs(task.Progress.CurrentStep.Progress, null)); 
    5359        } 
    5460 
     
    5965        } 
    6066 
    61         private void task_ProgressChanged(object sender, TaskProgressEventArgs e) 
     67        private void task_ProgressChanged(object sender, ProgressChangedEventArgs e) 
    6268        { 
    6369            if (InvokeRequired) 
     
    6874 
    6975                lastUpdate = DateTime.Now; 
    70                 Invoke(new EventHandler<TaskProgressEventArgs>(task_ProgressChanged), sender, e); 
    71                 return; 
    72             } 
    73  
    74             status.Text = e.CurrentTargetStatus; 
    75             item.Text = WrapItemName(e.CurrentItemName); 
    76             pass.Text = e.CurrentTargetTotalPasses != 0 ? 
    77                 S._("{0} out of {1}", e.CurrentItemPass, e.CurrentTargetTotalPasses) : 
    78                 e.CurrentItemPass.ToString(CultureInfo.CurrentCulture); 
    79  
    80             if (e.TimeLeft >= TimeSpan.Zero) 
    81                 timeLeft.Text = S._("About {0:T} left", e.TimeLeft); 
    82             else 
    83                 timeLeft.Text = S._("Unknown"); 
    84  
    85             if (e.CurrentItemProgress >= 0.0f) 
    86             { 
    87                 itemProgress.Style = ProgressBarStyle.Continuous; 
    88                 itemProgress.Value = (int)(e.CurrentItemProgress * 1000); 
    89                 itemProgressLbl.Text = e.CurrentItemProgress.ToString("#0%", 
    90                     CultureInfo.CurrentCulture); 
    91             } 
    92             else 
    93             { 
    94                 itemProgress.Style = ProgressBarStyle.Marquee; 
    95                 itemProgressLbl.Text = string.Empty; 
    96             } 
    97  
    98             overallProgress.Value = (int)(e.OverallProgress * 1000); 
    99             overallProgressLbl.Text = S._("Total: {0,2:#0.00%}", e.OverallProgress); 
     76                Invoke((EventHandler<ProgressChangedEventArgs>)task_ProgressChanged, sender, e); 
     77                return; 
     78            } 
     79 
     80            ErasureTarget target = sender as ErasureTarget; 
     81            if (target == null) 
     82                return; 
     83 
     84            SteppedProgressManager progress = target.Progress as SteppedProgressManager; 
     85            if (progress == null) 
     86                return; 
     87 
     88            UpdateProgress(progress, e); 
    10089        } 
    10190 
     
    155144                task.Cancel(); 
    156145            Close(); 
     146        } 
     147 
     148        private void UpdateProgress(SteppedProgressManager targetProgress, ProgressChangedEventArgs e) 
     149        { 
     150            TaskProgressChangedEventArgs e2 = (TaskProgressChangedEventArgs)e.UserState; 
     151 
     152            status.Text = targetProgress.CurrentStep.Name; 
     153            if (e2 != null) 
     154            { 
     155                item.Text = WrapItemName(e2.ItemName); 
     156                pass.Text = e2.ItemTotalPasses != 0 ? 
     157                    S._("{0} out of {1}", e2.ItemPass, e2.ItemTotalPasses) : 
     158                    e2.ItemPass.ToString(CultureInfo.CurrentCulture); 
     159            } 
     160 
     161            if (targetProgress.TimeLeft >= TimeSpan.Zero) 
     162                timeLeft.Text = S._("About {0} left", RoundToSeconds(targetProgress.TimeLeft)); 
     163            else 
     164                timeLeft.Text = S._("Unknown"); 
     165 
     166            if (targetProgress.Progress >= 0.0f) 
     167            { 
     168                itemProgress.Style = ProgressBarStyle.Continuous; 
     169                itemProgress.Value = (int)(targetProgress.Progress * 1000); 
     170                itemProgressLbl.Text = targetProgress.Progress.ToString("#0%", 
     171                    CultureInfo.CurrentCulture); 
     172            } 
     173            else 
     174            { 
     175                itemProgress.Style = ProgressBarStyle.Marquee; 
     176                itemProgressLbl.Text = string.Empty; 
     177            } 
     178 
     179            overallProgress.Value = (int)(task.Progress.Progress * 1000); 
     180            overallProgressLbl.Text = S._("Total: {0,2:#0.00%}", task.Progress.Progress); 
    157181        } 
    158182 
     
    185209            return result.ToString(); 
    186210        } 
     211 
     212        private TimeSpan RoundToSeconds(TimeSpan span) 
     213        { 
     214            return new TimeSpan(span.Ticks - span.Ticks % TimeSpan.TicksPerSecond); 
     215        } 
    187216    } 
    188217} 
  • trunk/eraser6/Eraser/SchedulerPanel.cs

    r1495 r1515  
    2222using System; 
    2323using System.Collections.Generic; 
    24 using System.ComponentModel; 
    2524using System.Data; 
    2625using System.Drawing; 
     
    3534using System.IO; 
    3635using System.Runtime.Serialization; 
     36using System.ComponentModel; 
     37using ProgressChangedEventArgs = Eraser.Manager.ProgressChangedEventArgs; 
    3738 
    3839namespace Eraser 
     
    207208        /// Handles the progress event by the task. 
    208209        /// </summary> 
    209         void task_ProgressChanged(object sender, TaskProgressEventArgs e) 
     210        void task_ProgressChanged(object sender, ProgressChangedEventArgs e) 
    210211        { 
    211212            //Make sure we handle the event in the main thread as this requires 
     
    213214            if (scheduler.InvokeRequired) 
    214215            { 
    215                 Invoke(new EventHandler<TaskProgressEventArgs>(task_ProgressChanged), sender, e); 
     216                Invoke((EventHandler<ProgressChangedEventArgs>)task_ProgressChanged, sender, e); 
    216217                return; 
    217218            } 
    218219 
    219220            //Update the progress bar 
    220             schedulerProgress.Value = (int)(e.OverallProgress * 1000.0); 
     221            ErasureTarget target = (ErasureTarget)sender; 
     222            schedulerProgress.Value = (int)(target.Task.Progress.Progress * 1000.0); 
    221223        } 
    222224 
  • trunk/eraser6/Eraser/Strings.NL.resx

    r1485 r1515  
    154154    <value>(Untranslated)</value> 
    155155  </data> 
     156  <data name="Total: {0,2:#0.00%}" xml:space="preserve"> 
     157    <value>(Untranslated)</value> 
     158  </data> 
     159  <data name="Completed with warnings" xml:space="preserve"> 
     160    <value>Afgerond met waarschuwingen</value> 
     161  </data> 
     162  <data name="Completed with errors" xml:space="preserve"> 
     163    <value>Afgerond met fouten</value> 
     164  </data> 
     165  <data name="Not completed" xml:space="preserve"> 
     166    <value>Niet afgerond</value> 
     167  </data> 
     168  <data name="Completed" xml:space="preserve"> 
     169    <value>Afgerond</value> 
     170  </data> 
     171  <data name="Close" xml:space="preserve"> 
     172    <value>Sluiten</value> 
     173  </data> 
    156174  <data name="{0} out of {1}" xml:space="preserve"> 
    157175    <value>{0} van {1}</value> 
    158176  </data> 
    159   <data name="About {0:T} left" xml:space="preserve"> 
     177  <data name="About {0} left" xml:space="preserve"> 
    160178    <value>(Untranslated)</value> 
    161179  </data> 
    162180  <data name="Unknown" xml:space="preserve"> 
    163181    <value>(Untranslated)</value> 
    164   </data> 
    165   <data name="Total: {0,2:#0.00%}" xml:space="preserve"> 
    166     <value>(Untranslated)</value> 
    167   </data> 
    168   <data name="Completed with warnings" xml:space="preserve"> 
    169     <value>Afgerond met waarschuwingen</value> 
    170   </data> 
    171   <data name="Completed with errors" xml:space="preserve"> 
    172     <value>Afgerond met fouten</value> 
    173   </data> 
    174   <data name="Not completed" xml:space="preserve"> 
    175     <value>Niet afgerond</value> 
    176   </data> 
    177   <data name="Completed" xml:space="preserve"> 
    178     <value>Afgerond</value> 
    179   </data> 
    180   <data name="Close" xml:space="preserve"> 
    181     <value>Sluiten</value> 
    182182  </data> 
    183183  <data name="Queued for execution" xml:space="preserve"> 
  • trunk/eraser6/Eraser/Strings.en.resx

    r1485 r1515  
    154154    <value>Another instance of Eraser is already running but it is running with higher privileges than this instance of Eraser.\n\nEraser will now exit.</value> 
    155155  </data> 
     156  <data name="Total: {0,2:#0.00%}" xml:space="preserve"> 
     157    <value>Total: {0,2:#0.00%}</value> 
     158  </data> 
     159  <data name="Completed with warnings" xml:space="preserve"> 
     160    <value>Completed with warnings</value> 
     161  </data> 
     162  <data name="Completed with errors" xml:space="preserve"> 
     163    <value>Completed with errors</value> 
     164  </data> 
     165  <data name="Not completed" xml:space="preserve"> 
     166    <value>Not completed</value> 
     167  </data> 
     168  <data name="Completed" xml:space="preserve"> 
     169    <value>Completed</value> 
     170  </data> 
     171  <data name="Close" xml:space="preserve"> 
     172    <value>Close</value> 
     173  </data> 
    156174  <data name="{0} out of {1}" xml:space="preserve"> 
    157175    <value>{0} out of {1}</value> 
    158176  </data> 
    159   <data name="About {0:T} left" xml:space="preserve"> 
    160     <value>About {0:T} left</value> 
     177  <data name="About {0} left" xml:space="preserve"> 
     178    <value>About {0} left</value> 
    161179  </data> 
    162180  <data name="Unknown" xml:space="preserve"> 
    163181    <value>Unknown</value> 
    164182  </data> 
    165   <data name="Total: {0,2:#0.00%}" xml:space="preserve"> 
    166     <value>Total: {0,2:#0.00%}</value> 
    167   </data> 
    168   <data name="Completed with warnings" xml:space="preserve"> 
    169     <value>Completed with warnings</value> 
    170   </data> 
    171   <data name="Completed with errors" xml:space="preserve"> 
    172     <value>Completed with errors</value> 
    173   </data> 
    174   <data name="Not completed" xml:space="preserve"> 
    175     <value>Not completed</value> 
    176   </data> 
    177   <data name="Completed" xml:space="preserve"> 
    178     <value>Completed</value> 
    179   </data> 
    180   <data name="Close" xml:space="preserve"> 
    181     <value>Close</value> 
    182   </data> 
    183183  <data name="Queued for execution" xml:space="preserve"> 
    184184    <value>Queued for execution</value> 
  • trunk/eraser6/Eraser/Strings.it.resx

    r1485 r1515  
    154154    <value>Un'altra occorrenza di Eraser è già in esecuzione, ma con privilegi più elevati di questa.\n\nEraser adesso si chiuderà.</value> 
    155155  </data> 
     156  <data name="Total: {0,2:#0.00%}" xml:space="preserve"> 
     157    <value>Totale: {0,2:#0.00%}</value> 
     158  </data> 
     159  <data name="Completed with warnings" xml:space="preserve"> 
     160    <value>Completata con avvisi</value> 
     161  </data> 
     162  <data name="Completed with errors" xml:space="preserve"> 
     163    <value>Completata con errori</value> 
     164  </data> 
     165  <data name="Not completed" xml:space="preserve"> 
     166    <value>Non completata</value> 
     167  </data> 
     168  <data name="Completed" xml:space="preserve"> 
     169    <value>Completata</value> 
     170  </data> 
     171  <data name="Close" xml:space="preserve"> 
     172    <value>Chiudi</value> 
     173  </data> 
    156174  <data name="{0} out of {1}" xml:space="preserve"> 
    157175    <value>{0} di {1}</value> 
    158176  </data> 
    159   <data name="About {0:T} left" xml:space="preserve"> 
    160     <value>Circa {0:T} rimasti</value> 
     177  <data name="About {0} left" xml:space="preserve"> 
     178    <value>Circa {0} rimasti</value> 
    161179  </data> 
    162180  <data name="Unknown" xml:space="preserve"> 
    163181    <value>Sconosciuto</value> 
    164182  </data> 
    165   <data name="Total: {0,2:#0.00%}" xml:space="preserve"> 
    166     <value>Totale: {0,2:#0.00%}</value> 
    167   </data> 
    168   <data name="Completed with warnings" xml:space="preserve"> 
    169     <value>Completata con avvisi</value> 
    170   </data> 
    171   <data name="Completed with errors" xml:space="preserve"> 
    172     <value>Completata con errori</value> 
    173   </data> 
    174   <data name="Not completed" xml:space="preserve"> 
    175     <value>Non completata</value> 
    176   </data> 
    177   <data name="Completed" xml:space="preserve"> 
    178     <value>Completata</value> 
    179   </data> 
    180   <data name="Close" xml:space="preserve"> 
    181     <value>Chiudi</value> 
    182   </data> 
    183183  <data name="Queued for execution" xml:space="preserve"> 
    184184    <value>Pianificata per l'esecuzione</value> 
  • trunk/eraser6/Eraser/Strings.resx

    r1485 r1515  
    154154    <value>Another instance of Eraser is already running but it is running with higher privileges than this instance of Eraser.\n\nEraser will now exit.</value> 
    155155  </data> 
     156  <data name="Total: {0,2:#0.00%}" xml:space="preserve"> 
     157    <value>Total: {0,2:#0.00%}</value> 
     158  </data> 
     159  <data name="Completed with warnings" xml:space="preserve"> 
     160    <value>Completed with warnings</value> 
     161  </data> 
     162  <data name="Completed with errors" xml:space="preserve"> 
     163    <value>Completed with errors</value> 
     164  </data> 
     165  <data name="Not completed" xml:space="preserve"> 
     166    <value>Not completed</value> 
     167  </data> 
     168  <data name="Completed" xml:space="preserve"> 
     169    <value>Completed</value> 
     170  </data> 
     171  <data name="Close" xml:space="preserve"> 
     172    <value>Close</value> 
     173  </data> 
    156174  <data name="{0} out of {1}" xml:space="preserve"> 
    157175    <value>{0} out of {1}</value> 
    158176  </data> 
    159   <data name="About {0:T} left" xml:space="preserve"> 
    160     <value>About {0:T} left</value> 
     177  <data name="About {0} left" xml:space="preserve"> 
     178    <value>About {0} left</value> 
    161179  </data> 
    162180  <data name="Unknown" xml:space="preserve"> 
    163181    <value>Unknown</value> 
    164182  </data> 
    165   <data name="Total: {0,2:#0.00%}" xml:space="preserve"> 
    166     <value>Total: {0,2:#0.00%}</value> 
    167   </data> 
    168   <data name="Completed with warnings" xml:space="preserve"> 
    169     <value>Completed with warnings</value> 
    170   </data> 
    171   <data name="Completed with errors" xml:space="preserve"> 
    172     <value>Completed with errors</value> 
    173   </data> 
    174   <data name="Not completed" xml:space="preserve"> 
    175     <value>Not completed</value> 
    176   </data> 
    177   <data name="Completed" xml:space="preserve"> 
    178     <value>Completed</value> 
    179   </data> 
    180   <data name="Close" xml:space="preserve"> 
    181     <value>Close</value> 
    182   </data> 
    183183  <data name="Queued for execution" xml:space="preserve"> 
    184184    <value>Queued for execution</value> 
  • trunk/eraser6/Eraser/UpdateForm.cs

    r1495 r1515  
    536536                    Assembly.GetExecutingAssembly().GetName().Version.ToString())); 
    537537             
    538             using (WebResponse resp = req.GetResponse()) 
    539             using (Stream strm = resp.GetResponseStream()) 
    540             { 
     538            using (WebResponse response = req.GetResponse()) 
     539            using (Stream responseStream = response.GetResponseStream()) 
     540            using (MemoryStream memoryStream = new MemoryStream()) 
     541            { 
     542                Manager.ProgressManager progress = new Manager.ProgressManager(); 
     543                progress.Total = response.ContentLength; 
     544 
    541545                //Download the response 
    542                 int bytesRead = 0; 
     546                int lastRead = 0; 
    543547                byte[] buffer = new byte[16384]; 
    544                 List<byte> responseBuffer = new List<byte>(); 
    545                 while ((bytesRead = strm.Read(buffer, 0, buffer.Length)) != 0) 
     548                while ((lastRead = responseStream.Read(buffer, 0, buffer.Length)) != 0) 
    546549                { 
    547                     byte[] tmpDest = new byte[bytesRead]; 
    548                     Buffer.BlockCopy(buffer, 0, tmpDest, 0, bytesRead); 
    549                     responseBuffer.AddRange(tmpDest); 
    550  
    551                     float progress = responseBuffer.Count / (float)resp.ContentLength; 
    552                     OnProgress(new ProgressEventArgs(progress, progress, null, 
     550                    memoryStream.Write(buffer, 0, lastRead); 
     551                    progress.Completed = memoryStream.Position; 
     552                    OnProgress(new ProgressEventArgs(progress.Progress, progress.Progress, null, 
    553553                        S._("{0} of {1} downloaded", 
    554                             Util.File.GetHumanReadableFilesize(responseBuffer.Count), 
    555                             Util.File.GetHumanReadableFilesize(resp.ContentLength)))); 
     554                            Util.File.GetHumanReadableFilesize(progress.Completed), 
     555                            Util.File.GetHumanReadableFilesize(progress.Total)))); 
    556556                } 
    557557 
    558558                //Parse it. 
    559                 using (MemoryStream mStrm = new MemoryStream(responseBuffer.ToArray())) 
    560                     ParseUpdateList(mStrm); 
     559                memoryStream.Position = 0; 
     560                ParseUpdateList(memoryStream); 
    561561            } 
    562562        } 
     
    671671            int currUpdate = 0; 
    672672            Dictionary<string, UpdateInfo> tempFilesMap = new Dictionary<string, UpdateInfo>(); 
     673            Manager.SteppedProgressManager progress = new Manager.SteppedProgressManager(); 
    673674            foreach (UpdateInfo update in downloadQueue) 
    674675            { 
    675676                try 
    676677                { 
     678                    //Add the update to the overall progress. 
     679                    Manager.ProgressManager step = new Eraser.Manager.ProgressManager(); 
     680                    progress.Steps.Add(new Manager.SteppedProgressManager.Step( 
     681                        step, 1.0f / downloadQueue.Count)); 
     682 
    677683                    //Decide on the URL to connect to. The Link of the update may 
    678684                    //be a relative path (relative to the selected mirror) or an 
     
    701707                                UriFormat.Unescaped)) : contentDisposition.FileName)); 
    702708 
    703                         byte[] tempBuffer = new byte[16384]; 
    704                         using (Stream strm = resp.GetResponseStream()) 
    705                         using (FileStream tempStrm = new FileStream(tempFilePath, FileMode.CreateNew)) 
    706                         using (BufferedStream bufStrm = new BufferedStream(tempStrm)) 
     709                        using (Stream responseStream = resp.GetResponseStream()) 
     710                        using (FileStream fileStream = new FileStream(tempFilePath, FileMode.CreateNew)) 
    707711                        { 
     712                            //Update the progress of this step 
     713                            step.Total = resp.ContentLength; 
     714 
    708715                            //Copy the information into the file stream 
    709                             int readBytes = 0; 
    710                             while ((readBytes = strm.Read(tempBuffer, 0, tempBuffer.Length)) != 0) 
     716                            int lastRead = 0; 
     717                            byte[] buffer = new byte[16384]; 
     718                            while ((lastRead = responseStream.Read(buffer, 0, buffer.Length)) != 0) 
    711719                            { 
    712                                 bufStrm.Write(tempBuffer, 0, readBytes); 
     720                                fileStream.Write(buffer, 0, lastRead); 
    713721 
    714722                                //Compute progress 
    715                                 float itemProgress = tempStrm.Position / (float)resp.ContentLength; 
    716                                 float overallProgress = (currUpdate - 1 + itemProgress) / downloadQueue.Count; 
    717                                 OnProgress(new ProgressEventArgs(itemProgress, overallProgress, 
     723                                step.Completed = fileStream.Position; 
     724                                OnProgress(new ProgressEventArgs(step.Progress, progress.Progress, 
    718725                                    update, S._("Downloading: {0}", update.Name))); 
    719726                            } 
     
    724731 
    725732                        //Let the event handler know the download is complete. 
    726                         OnProgress(new ProgressEventArgs(1.0f, (float)currUpdate / downloadQueue.Count, 
     733                        step.Completed = step.Total; 
     734                        OnProgress(new ProgressEventArgs(step.Progress, progress.Progress, 
    727735                            update, S._("Downloaded: {0}", update.Name))); 
    728736                    } 
     
    747755        public void InstallUpdates(object value) 
    748756        { 
     757            Manager.ProgressManager progress = new Manager.ProgressManager(); 
    749758            Dictionary<string, UpdateInfo> tempFiles = (Dictionary<string, UpdateInfo>)value; 
    750759            Dictionary<string, UpdateInfo>.KeyCollection files = tempFiles.Keys; 
    751             int currItem = 0; 
    752760 
    753761            try 
    754762            { 
     763                progress.Total = files.Count; 
    755764                foreach (string path in files) 
    756765                { 
    757766                    UpdateInfo item = tempFiles[path]; 
    758                     float progress = (float)currItem++ / files.Count; 
    759                     OnProgress(new ProgressEventArgs(0.0f, progress, 
     767                    ++progress.Completed; 
     768                    OnProgress(new ProgressEventArgs(0.0f, progress.Progress, 
    760769                        item, S._("Installing {0}", item.Name))); 
    761770 
     
    767776                    process.WaitForExit(Int32.MaxValue); 
    768777                    if (process.ExitCode == 0) 
    769                         OnProgress(new ProgressEventArgs(1.0f, progress, 
     778                        OnProgress(new ProgressEventArgs(1.0f, progress.Progress, 
    770779                            item, S._("Installed {0}", item.Name))); 
    771780                    else 
    772781                        OnProgress(new ProgressErrorEventArgs(new ProgressEventArgs(1.0f, 
    773                             progress, item, S._("Error installing {0}", item.Name)), 
     782                            progress.Progress, item, S._("Error installing {0}", item.Name)), 
    774783                            new ApplicationException(S._("The installer exited with an error code {0}", 
    775784                                process.ExitCode)))); 
Note: See TracChangeset for help on using the changeset viewer.