/// <summary> /// Create intersection with another option /// </summary> /// <param name="option"></param> /// <returns>this if <paramref name="option"/> is null or new instance with intersection</returns> public virtual AllOptions Intersection(IOption option) { if (option == null) { return(this); } AllOptions result = new AllOptions(); result.CanBrowse = this.CanBrowse | option.CanBrowse(); result.CanGetEntry = this.CanGetEntry | option.CanGetEntry(); result.CanObserve = this.CanObserve | option.CanObserve(); result.CanOpen = this.CanOpen | option.CanOpen(); result.CanRead = this.CanRead | option.CanRead(); result.CanWrite = this.CanWrite | option.CanWrite(); result.CanCreateFile = this.CanCreateFile | option.CanCreateFile(); result.CanDelete = this.CanDelete | option.CanDelete(); result.CanSetFileAttribute = this.CanSetFileAttribute | option.CanSetFileAttribute(); result.CanMount = this.CanMount | option.CanMount(); result.CanCreateFile = this.CanCreateFile | option.CanCreateFile(); result.CanDelete = this.CanDelete | option.CanDelete(); result.CanMove = this.CanMove | option.CanMove(); result.CanCreateDirectory = this.CanCreateDirectory | option.CanCreateDirectory(); result.CanMount = this.CanMount | option.CanMount(); result.CanUnmount = this.CanUnmount | option.CanUnmount(); result.CanListMountPoints = this.CanListMountPoints | option.CanListMountPoints(); result.SubPath = this.SubPath ?? option.SubPath(); return(result); }
/// <summary> /// Read options from <paramref name="option"/> and return flattened object. /// </summary> /// <param name="option"></param> /// <returns></returns> public virtual void ReadFrom(IOption option) { this.CanBrowse = option.CanBrowse(); this.CanGetEntry = option.CanGetEntry(); this.CanObserve = option.CanObserve(); this.CanOpen = option.CanOpen(); this.CanRead = option.CanRead(); this.CanWrite = option.CanWrite(); this.CanCreateFile = option.CanCreateFile(); this.CanDelete = option.CanDelete(); this.CanMove = option.CanMove(); this.CanCreateDirectory = option.CanCreateDirectory(); this.CanMount = option.CanMount(); this.CanUnmount = option.CanUnmount(); this.CanListMountPoints = option.CanListMountPoints(); this.SubPath = option.SubPath(); this.CanSetFileAttribute = option.CanSetFileAttribute(); }
/// <summary> /// Attach an <paramref name="observer"/> on to a single file or directory. /// Observing a directory will observe the whole subtree. /// /// WARNING: The Observe implementation browses the subtree of the watched directory path in order to create delta of changes. /// </summary> /// <param name="filter">path to file or directory. The directory separator is "/". The root is without preceding slash "", e.g. "dir/dir2"</param> /// <param name="observer"></param> /// <param name="state">(optional) </param> /// <param name="eventDispatcher">(optional) event dispatcher</param> /// <param name="option">(optional) operation specific option; capability constraint, a session, security token or credential. Used for authenticating, authorizing or restricting the operation.</param> /// <returns>dispose handle</returns> /// <exception cref="IOException">On unexpected IO error</exception> /// <exception cref="SecurityException">If caller did not have permission</exception> /// <exception cref="ArgumentNullException"><paramref name="filter"/> is null</exception> /// <exception cref="ArgumentException"><paramref name="filter"/> contains only white space, or contains one or more invalid characters</exception> /// <exception cref="NotSupportedException">The <see cref="IFileSystem"/> doesn't support observe</exception> /// <exception cref="UnauthorizedAccessException">The access requested is not permitted by the operating system for the specified path.</exception> /// <exception cref="PathTooLongException">The specified path, file name, or both exceed the system-defined maximum length. For example, on Windows-based platforms, paths must be less than 248 characters, and file names must be less than 260 characters.</exception> /// <exception cref="InvalidOperationException">If <paramref name="filter"/> refers to a non-file device, such as "con:", "com1:", "lpt1:", etc.</exception> /// <exception cref="ObjectDisposedException"/> public virtual IFileSystemObserver Observe(string filter, IObserver <IEvent> observer, object state = null, IEventDispatcher eventDispatcher = default, IOption option = null) { // Assert observe is enabled. if (!CanObserve || !option.CanObserve(true)) { throw new NotSupportedException(nameof(Observe)); } // Assert not diposed IFileProvider fp = fileProvider; if (fp == null) { return(new DummyObserver(this, filter, observer, state, eventDispatcher)); } // Parse filter GlobPatternInfo patternInfo = new GlobPatternInfo(filter); // Monitor single file (or dir, we don't know "dir") if (patternInfo.SuffixDepth == 0) { // Create observer that watches one file FileObserver handle = new FileObserver(this, filter, observer, state, eventDispatcher, option.OptionIntersection(this.options)); // Send handle observer.OnNext(new StartEvent(handle, DateTimeOffset.UtcNow)); // Return handle return(handle); } else // Has wildcards, e.g. "**/file.txt" { // Create handle PatternObserver handle = new PatternObserver(this, patternInfo, observer, state, eventDispatcher); // Send handle observer.OnNext(new StartEvent(handle, DateTimeOffset.UtcNow)); // Return handle return(handle); } }