Summary

Class:ICSharpCode.SharpZipLib.Core.FileSystemScanner
Assembly:ICSharpCode.SharpZipLib
File(s):C:\Users\Neil\Documents\Visual Studio 2015\Projects\icsharpcode\SZL_master\ICSharpCode.SharpZipLib\Core\FileSystemScanner.cs
Covered lines:33
Uncovered lines:49
Coverable lines:82
Total lines:475
Line coverage:40.2%
Branch coverage:32.3%

Metrics

MethodCyclomatic ComplexitySequence CoverageBranch Coverage
.ctor(...)100
.ctor(...)1100100
.ctor(...)100
.ctor(...)100
OnDirectoryFailure(...)200
OnFileFailure(...)200
OnProcessFile(...)210066.67
OnCompleteFile(...)200
OnProcessDirectory(...)25066.67
Scan(...)1100100
ScanDir(...)155040

File(s)

C:\Users\Neil\Documents\Visual Studio 2015\Projects\icsharpcode\SZL_master\ICSharpCode.SharpZipLib\Core\FileSystemScanner.cs

#LineLine coverage
 1using System;
 2
 3namespace ICSharpCode.SharpZipLib.Core
 4{
 5  #region EventArgs
 6  /// <summary>
 7  /// Event arguments for scanning.
 8  /// </summary>
 9  public class ScanEventArgs : EventArgs
 10  {
 11    #region Constructors
 12    /// <summary>
 13    /// Initialise a new instance of <see cref="ScanEventArgs"/>
 14    /// </summary>
 15    /// <param name="name">The file or directory name.</param>
 16    public ScanEventArgs(string name)
 17    {
 18      name_ = name;
 19    }
 20    #endregion
 21
 22    /// <summary>
 23    /// The file or directory name for this event.
 24    /// </summary>
 25    public string Name {
 26      get { return name_; }
 27    }
 28
 29    /// <summary>
 30    /// Get set a value indicating if scanning should continue or not.
 31    /// </summary>
 32    public bool ContinueRunning {
 33      get { return continueRunning_; }
 34      set { continueRunning_ = value; }
 35    }
 36
 37    #region Instance Fields
 38    string name_;
 39    bool continueRunning_ = true;
 40    #endregion
 41  }
 42
 43  /// <summary>
 44  /// Event arguments during processing of a single file or directory.
 45  /// </summary>
 46  public class ProgressEventArgs : EventArgs
 47  {
 48    #region Constructors
 49    /// <summary>
 50    /// Initialise a new instance of <see cref="ScanEventArgs"/>
 51    /// </summary>
 52    /// <param name="name">The file or directory name if known.</param>
 53    /// <param name="processed">The number of bytes processed so far</param>
 54    /// <param name="target">The total number of bytes to process, 0 if not known</param>
 55    public ProgressEventArgs(string name, long processed, long target)
 56    {
 57      name_ = name;
 58      processed_ = processed;
 59      target_ = target;
 60    }
 61    #endregion
 62
 63    /// <summary>
 64    /// The name for this event if known.
 65    /// </summary>
 66    public string Name {
 67      get { return name_; }
 68    }
 69
 70    /// <summary>
 71    /// Get set a value indicating wether scanning should continue or not.
 72    /// </summary>
 73    public bool ContinueRunning {
 74      get { return continueRunning_; }
 75      set { continueRunning_ = value; }
 76    }
 77
 78    /// <summary>
 79    /// Get a percentage representing how much of the <see cref="Target"></see> has been processed
 80    /// </summary>
 81    /// <value>0.0 to 100.0 percent; 0 if target is not known.</value>
 82    public float PercentComplete {
 83      get {
 84        float result;
 85        if (target_ <= 0) {
 86          result = 0;
 87        } else {
 88          result = ((float)processed_ / (float)target_) * 100.0f;
 89        }
 90        return result;
 91      }
 92    }
 93
 94    /// <summary>
 95    /// The number of bytes processed so far
 96    /// </summary>
 97    public long Processed {
 98      get { return processed_; }
 99    }
 100
 101    /// <summary>
 102    /// The number of bytes to process.
 103    /// </summary>
 104    /// <remarks>Target may be 0 or negative if the value isnt known.</remarks>
 105    public long Target {
 106      get { return target_; }
 107    }
 108
 109    #region Instance Fields
 110    string name_;
 111    long processed_;
 112    long target_;
 113    bool continueRunning_ = true;
 114    #endregion
 115  }
 116
 117  /// <summary>
 118  /// Event arguments for directories.
 119  /// </summary>
 120  public class DirectoryEventArgs : ScanEventArgs
 121  {
 122    #region Constructors
 123    /// <summary>
 124    /// Initialize an instance of <see cref="DirectoryEventArgs"></see>.
 125    /// </summary>
 126    /// <param name="name">The name for this directory.</param>
 127    /// <param name="hasMatchingFiles">Flag value indicating if any matching files are contained in this directory.</par
 128    public DirectoryEventArgs(string name, bool hasMatchingFiles)
 129      : base(name)
 130    {
 131      hasMatchingFiles_ = hasMatchingFiles;
 132    }
 133    #endregion
 134
 135    /// <summary>
 136    /// Get a value indicating if the directory contains any matching files or not.
 137    /// </summary>
 138    public bool HasMatchingFiles {
 139      get { return hasMatchingFiles_; }
 140    }
 141
 142    readonly
 143
 144    #region Instance Fields
 145    bool hasMatchingFiles_;
 146    #endregion
 147  }
 148
 149  /// <summary>
 150  /// Arguments passed when scan failures are detected.
 151  /// </summary>
 152  public class ScanFailureEventArgs : EventArgs
 153  {
 154    #region Constructors
 155    /// <summary>
 156    /// Initialise a new instance of <see cref="ScanFailureEventArgs"></see>
 157    /// </summary>
 158    /// <param name="name">The name to apply.</param>
 159    /// <param name="e">The exception to use.</param>
 160    public ScanFailureEventArgs(string name, Exception e)
 161    {
 162      name_ = name;
 163      exception_ = e;
 164      continueRunning_ = true;
 165    }
 166    #endregion
 167
 168    /// <summary>
 169    /// The applicable name.
 170    /// </summary>
 171    public string Name {
 172      get { return name_; }
 173    }
 174
 175    /// <summary>
 176    /// The applicable exception.
 177    /// </summary>
 178    public Exception Exception {
 179      get { return exception_; }
 180    }
 181
 182    /// <summary>
 183    /// Get / set a value indicating wether scanning should continue.
 184    /// </summary>
 185    public bool ContinueRunning {
 186      get { return continueRunning_; }
 187      set { continueRunning_ = value; }
 188    }
 189
 190    #region Instance Fields
 191    string name_;
 192    Exception exception_;
 193    bool continueRunning_;
 194    #endregion
 195  }
 196
 197  #endregion
 198
 199  #region Delegates
 200  /// <summary>
 201  /// Delegate invoked before starting to process a file.
 202  /// </summary>
 203  /// <param name="sender">The source of the event</param>
 204  /// <param name="e">The event arguments.</param>
 205  public delegate void ProcessFileHandler(object sender, ScanEventArgs e);
 206
 207  /// <summary>
 208  /// Delegate invoked during processing of a file or directory
 209  /// </summary>
 210  /// <param name="sender">The source of the event</param>
 211  /// <param name="e">The event arguments.</param>
 212  public delegate void ProgressHandler(object sender, ProgressEventArgs e);
 213
 214  /// <summary>
 215  /// Delegate invoked when a file has been completely processed.
 216  /// </summary>
 217  /// <param name="sender">The source of the event</param>
 218  /// <param name="e">The event arguments.</param>
 219  public delegate void CompletedFileHandler(object sender, ScanEventArgs e);
 220
 221  /// <summary>
 222  /// Delegate invoked when a directory failure is detected.
 223  /// </summary>
 224  /// <param name="sender">The source of the event</param>
 225  /// <param name="e">The event arguments.</param>
 226  public delegate void DirectoryFailureHandler(object sender, ScanFailureEventArgs e);
 227
 228  /// <summary>
 229  /// Delegate invoked when a file failure is detected.
 230  /// </summary>
 231  /// <param name="sender">The source of the event</param>
 232  /// <param name="e">The event arguments.</param>
 233  public delegate void FileFailureHandler(object sender, ScanFailureEventArgs e);
 234  #endregion
 235
 236  /// <summary>
 237  /// FileSystemScanner provides facilities scanning of files and directories.
 238  /// </summary>
 239  public class FileSystemScanner
 240  {
 241    #region Constructors
 242    /// <summary>
 243    /// Initialise a new instance of <see cref="FileSystemScanner"></see>
 244    /// </summary>
 245    /// <param name="filter">The <see cref="PathFilter">file filter</see> to apply when scanning.</param>
 0246    public FileSystemScanner(string filter)
 247    {
 0248      fileFilter_ = new PathFilter(filter);
 0249    }
 250
 251    /// <summary>
 252    /// Initialise a new instance of <see cref="FileSystemScanner"></see>
 253    /// </summary>
 254    /// <param name="fileFilter">The <see cref="PathFilter">file filter</see> to apply.</param>
 255    /// <param name="directoryFilter">The <see cref="PathFilter"> directory filter</see> to apply.</param>
 4256    public FileSystemScanner(string fileFilter, string directoryFilter)
 257    {
 4258      fileFilter_ = new PathFilter(fileFilter);
 4259      directoryFilter_ = new PathFilter(directoryFilter);
 4260    }
 261
 262    /// <summary>
 263    /// Initialise a new instance of <see cref="FileSystemScanner"></see>
 264    /// </summary>
 265    /// <param name="fileFilter">The file <see cref="IScanFilter">filter</see> to apply.</param>
 0266    public FileSystemScanner(IScanFilter fileFilter)
 267    {
 0268      fileFilter_ = fileFilter;
 0269    }
 270
 271    /// <summary>
 272    /// Initialise a new instance of <see cref="FileSystemScanner"></see>
 273    /// </summary>
 274    /// <param name="fileFilter">The file <see cref="IScanFilter">filter</see>  to apply.</param>
 275    /// <param name="directoryFilter">The directory <see cref="IScanFilter">filter</see>  to apply.</param>
 0276    public FileSystemScanner(IScanFilter fileFilter, IScanFilter directoryFilter)
 277    {
 0278      fileFilter_ = fileFilter;
 0279      directoryFilter_ = directoryFilter;
 0280    }
 281    #endregion
 282
 283    #region Delegates
 284    /// <summary>
 285    /// Delegate to invoke when a directory is processed.
 286    /// </summary>
 287    public event EventHandler<DirectoryEventArgs> ProcessDirectory;
 288
 289    /// <summary>
 290    /// Delegate to invoke when a file is processed.
 291    /// </summary>
 292    public ProcessFileHandler ProcessFile;
 293
 294    /// <summary>
 295    /// Delegate to invoke when processing for a file has finished.
 296    /// </summary>
 297    public CompletedFileHandler CompletedFile;
 298
 299    /// <summary>
 300    /// Delegate to invoke when a directory failure is detected.
 301    /// </summary>
 302    public DirectoryFailureHandler DirectoryFailure;
 303
 304    /// <summary>
 305    /// Delegate to invoke when a file failure is detected.
 306    /// </summary>
 307    public FileFailureHandler FileFailure;
 308    #endregion
 309
 310    /// <summary>
 311    /// Raise the DirectoryFailure event.
 312    /// </summary>
 313    /// <param name="directory">The directory name.</param>
 314    /// <param name="e">The exception detected.</param>
 315    bool OnDirectoryFailure(string directory, Exception e)
 316    {
 0317      DirectoryFailureHandler handler = DirectoryFailure;
 0318      bool result = (handler != null);
 0319       if (result) {
 0320        var args = new ScanFailureEventArgs(directory, e);
 0321        handler(this, args);
 0322        alive_ = args.ContinueRunning;
 323      }
 0324      return result;
 325    }
 326
 327    /// <summary>
 328    /// Raise the FileFailure event.
 329    /// </summary>
 330    /// <param name="file">The file name.</param>
 331    /// <param name="e">The exception detected.</param>
 332    bool OnFileFailure(string file, Exception e)
 333    {
 0334      FileFailureHandler handler = FileFailure;
 335
 0336      bool result = (handler != null);
 337
 0338       if (result) {
 0339        var args = new ScanFailureEventArgs(file, e);
 0340        FileFailure(this, args);
 0341        alive_ = args.ContinueRunning;
 342      }
 0343      return result;
 344    }
 345
 346    /// <summary>
 347    /// Raise the ProcessFile event.
 348    /// </summary>
 349    /// <param name="file">The file name.</param>
 350    void OnProcessFile(string file)
 351    {
 4352      ProcessFileHandler handler = ProcessFile;
 353
 4354       if (handler != null) {
 4355        var args = new ScanEventArgs(file);
 4356        handler(this, args);
 4357        alive_ = args.ContinueRunning;
 358      }
 4359    }
 360
 361    /// <summary>
 362    /// Raise the complete file event
 363    /// </summary>
 364    /// <param name="file">The file name</param>
 365    void OnCompleteFile(string file)
 366    {
 0367      CompletedFileHandler handler = CompletedFile;
 368
 0369       if (handler != null) {
 0370        var args = new ScanEventArgs(file);
 0371        handler(this, args);
 0372        alive_ = args.ContinueRunning;
 373      }
 0374    }
 375
 376    /// <summary>
 377    /// Raise the ProcessDirectory event.
 378    /// </summary>
 379    /// <param name="directory">The directory name.</param>
 380    /// <param name="hasMatchingFiles">Flag indicating if the directory has matching files.</param>
 381    void OnProcessDirectory(string directory, bool hasMatchingFiles)
 382    {
 4383      EventHandler<DirectoryEventArgs> handler = ProcessDirectory;
 384
 4385       if (handler != null) {
 0386        var args = new DirectoryEventArgs(directory, hasMatchingFiles);
 0387        handler(this, args);
 0388        alive_ = args.ContinueRunning;
 389      }
 4390    }
 391
 392    /// <summary>
 393    /// Scan a directory.
 394    /// </summary>
 395    /// <param name="directory">The base directory to scan.</param>
 396    /// <param name="recurse">True to recurse subdirectories, false to scan a single directory.</param>
 397    public void Scan(string directory, bool recurse)
 398    {
 4399      alive_ = true;
 4400      ScanDir(directory, recurse);
 4401    }
 402
 403    void ScanDir(string directory, bool recurse)
 404    {
 405
 406      try {
 4407        string[] names = System.IO.Directory.GetFiles(directory);
 4408        bool hasMatch = false;
 28302409         for (int fileIndex = 0; fileIndex < names.Length; ++fileIndex) {
 14147410           if (!fileFilter_.IsMatch(names[fileIndex])) {
 14143411            names[fileIndex] = null;
 14143412          } else {
 4413            hasMatch = true;
 414          }
 415        }
 416
 4417        OnProcessDirectory(directory, hasMatch);
 418
 4419         if (alive_ && hasMatch) {
 28302420          foreach (string fileName in names) {
 421            try {
 14147422               if (fileName != null) {
 4423                OnProcessFile(fileName);
 4424                 if (!alive_) {
 0425                  break;
 426                }
 427              }
 14147428            } catch (Exception e) {
 0429               if (!OnFileFailure(fileName, e)) {
 0430                throw;
 431              }
 0432            }
 433          }
 434        }
 4435      } catch (Exception e) {
 0436         if (!OnDirectoryFailure(directory, e)) {
 0437          throw;
 438        }
 0439      }
 440
 4441       if (alive_ && recurse) {
 442        try {
 0443          string[] names = System.IO.Directory.GetDirectories(directory);
 0444          foreach (string fulldir in names) {
 0445             if ((directoryFilter_ == null) || (directoryFilter_.IsMatch(fulldir))) {
 0446              ScanDir(fulldir, true);
 0447               if (!alive_) {
 448                break;
 449              }
 450            }
 451          }
 0452        } catch (Exception e) {
 0453           if (!OnDirectoryFailure(directory, e)) {
 0454            throw;
 455          }
 0456        }
 457      }
 4458    }
 459
 460    #region Instance Fields
 461    /// <summary>
 462    /// The file filter currently in use.
 463    /// </summary>
 464    IScanFilter fileFilter_;
 465    /// <summary>
 466    /// The directory filter currently in use.
 467    /// </summary>
 468    IScanFilter directoryFilter_;
 469    /// <summary>
 470    /// Flag indicating if scanning should continue running.
 471    /// </summary>
 472    bool alive_;
 473    #endregion
 474  }
 475}