* System.dll.sources: added new files.
* System_test.dll.sources: added new test.
* System.IO/DefaultWatcher.cs: stub for the default watcher.
* System.IO/WindowsWatcher.cs: stub for the windows watcher.
* System.IO/FAMWatcher.cs: FAM watcher.
* System.IO/FileAction.cs: enum with event types.
* System.IO/FileSystemEventArgs.cs: added SetName property.
* System.IO/FileSystemWatcher.cs: added support for the 3 watchers.
* System.IO/IFileWatcher.cs: interface implemented by the watchers.
* System.IO/SearchPattern.cs: copied from corlib.
* Test/System.IO/FileSystemWatcherTest.cs: new test.
svn path=/trunk/mcs/; revision=22139
+2004-01-16 Gonzalo Paniagua Javier <gonzalo@ximian.com>
+
+ * System.dll.sources: added new files.
+
+ * System_test.dll.sources: added new test.
+
2004-01-01 Nick Drochak <ndrochak@gol.com>
* Makefile: Suppress warnings about multiple Regex defs and obsolete
+2004-01-16 Gonzalo Paniagua Javier <gonzalo@ximian.com>
+
+ * DefaultWatcher.cs: stub for the default watcher.
+ * WindowsWatcher.cs: stub for the windows watcher.
+
+ * FAMWatcher.cs: FAM watcher.
+
+ * FileAction.cs: enum with event types.
+
+ * FileSystemEventArgs.cs: added SetName property.
+ * FileSystemWatcher.cs: added support for the 3 watchers.
+
+ * IFileWatcher.cs: interface implemented by the watchers.
+ * SearchPattern.cs: copied from corlib.
+
2003-07-17 Andreas Nahr <ClassDevelopment@A-SoftTech.com>
- * FileSystemWatcher.cs: Reworked attributes based on the new Consts scheme
+ * FileSystemWatcher.cs: Reworked attributes based on the new Consts
+ scheme
2003-07-13 Andreas Nahr <ClassDevelopment@A-SoftTech.com>
--- /dev/null
+//
+// System.IO.DefaultWatcher.cs: windows IFileWatcher
+//
+// Authors:
+// Gonzalo Paniagua Javier (gonzalo@ximian.com)
+//
+// (c) 2004 Novell, Inc. (http://www.novell.com)
+//
+
+namespace System.IO {
+ class DefaultWatcher : IFileWatcher
+ {
+ private DefaultWatcher ()
+ {
+ }
+
+ public static bool GetInstance (out IFileWatcher watcher)
+ {
+ throw new NotSupportedException ();
+ }
+
+ public void StartDispatching (FileSystemWatcher fsw)
+ {
+ }
+
+ public void StopDispatching (FileSystemWatcher fsw)
+ {
+ }
+ }
+}
+
--- /dev/null
+//
+// System.IO.FAM.cs: interface with libfam
+//
+// Authors:
+// Gonzalo Paniagua Javier (gonzalo@ximian.com)
+//
+// (c) 2004 Novell, Inc. (http://www.novell.com)
+//
+
+using System;
+using System.Collections;
+using System.ComponentModel;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Text;
+using System.Threading;
+
+namespace System.IO {
+ struct FAMConnection {
+ public int FD;
+ IntPtr opaque;
+ }
+
+ struct FAMRequest {
+ public int ReqNum;
+ }
+
+ enum FAMCodes {
+ Changed = 1,
+ Deleted = 2,
+ StartExecuting = 3,
+ StopExecuting = 4,
+ Created = 5,
+ Moved = 6,
+ Acknowledge = 7,
+ Exists = 8,
+ EndExist = 9
+ };
+
+ class FAMData {
+ public FileSystemWatcher FSW;
+ public string Directory;
+ public string FileMask;
+ public bool IncludeSubdirs;
+ public bool Enabled;
+ public FAMRequest Request;
+ }
+
+ class FAMWatcher : IFileWatcher
+ {
+ static bool failed;
+ static FAMWatcher instance;
+ static Hashtable watches;
+ static Hashtable requests;
+ static FAMConnection conn;
+ static Thread thread;
+ static bool stop;
+
+ private FAMWatcher ()
+ {
+ }
+
+ public static bool GetInstance (out IFileWatcher watcher)
+ {
+ lock (typeof (FAMWatcher)) {
+ if (failed == true) {
+ watcher = null;
+ return false;
+ }
+
+ if (instance != null) {
+ watcher = instance;
+ return true;
+ }
+
+ watches = new Hashtable ();
+ requests = new Hashtable ();
+ if (FAMOpen (out conn) == -1) {
+ failed = true;
+ watcher = null;
+ return false;
+ }
+
+ instance = new FAMWatcher ();
+ watcher = instance;
+ return true;
+ }
+ }
+
+ public void StartDispatching (FileSystemWatcher fsw)
+ {
+ FAMData data;
+ lock (this) {
+ if (thread == null) {
+ thread = new Thread (new ThreadStart (Monitor));
+ thread.IsBackground = true;
+ thread.Start ();
+ }
+
+ data = (FAMData) watches [fsw];
+ }
+
+ if (data == null) {
+ data = new FAMData ();
+ data.FSW = fsw;
+ data.Directory = fsw.FullPath;
+ data.FileMask = fsw.Filter;
+ data.IncludeSubdirs = fsw.IncludeSubdirectories;
+ data.Enabled = true;
+ lock (this) {
+ StartMonitoringDirectory (data);
+ watches [fsw] = data;
+ requests [data.Request.ReqNum] = data;
+ }
+ }
+ }
+
+ static void StartMonitoringDirectory (FAMData data)
+ {
+ FAMRequest fr;
+ if (FAMMonitorDirectory (ref conn, data.Directory, out fr, IntPtr.Zero) == -1)
+ throw new Win32Exception ();
+
+ data.Request = fr;
+ }
+
+ public void StopDispatching (FileSystemWatcher fsw)
+ {
+ FAMData data;
+ lock (this) {
+ data = (FAMData) watches [fsw];
+ if (data == null)
+ return;
+
+ StopMonitoringDirectory (data);
+ watches.Remove (fsw);
+ requests.Remove (data.Request.ReqNum);
+ if (watches.Count == 0)
+ stop = true;
+ }
+ }
+
+ static void StopMonitoringDirectory (FAMData data)
+ {
+ FAMRequest fr;
+ if (FAMCancelMonitor (ref conn, ref data.Request) == -1)
+ throw new Win32Exception ();
+ }
+
+ void Monitor ()
+ {
+ while (!stop) {
+ int haveEvents;
+ lock (this) {
+ haveEvents = FAMPending (ref conn);
+ }
+
+ if (haveEvents > 0) {
+ ProcessEvents ();
+ } else {
+ Thread.Sleep (500);
+ }
+ }
+
+ lock (this) {
+ thread = null;
+ stop = false;
+ }
+ }
+
+ const NotifyFilters changed = NotifyFilters.Attributes |
+ NotifyFilters.LastAccess |
+ NotifyFilters.Size |
+ NotifyFilters.LastWrite;
+
+ void ProcessEvents ()
+ {
+ lock (this) {
+ do {
+ int code;
+ string filename;
+ int requestNumber;
+ FileSystemWatcher fsw;
+
+ if (InternalFAMNextEvent (ref conn, out filename,
+ out code, out requestNumber) != 1)
+ return;
+
+ bool found = false;
+ switch ((FAMCodes) code) {
+ case FAMCodes.Changed:
+ case FAMCodes.Deleted:
+ case FAMCodes.Created:
+ found = requests.ContainsKey (requestNumber);
+ break;
+ case FAMCodes.Moved:
+ case FAMCodes.StartExecuting:
+ case FAMCodes.StopExecuting:
+ case FAMCodes.Acknowledge:
+ case FAMCodes.Exists:
+ case FAMCodes.EndExist:
+ default:
+ found = false;
+ break;
+ }
+
+ if (!found)
+ continue;
+
+ FAMData data = (FAMData) requests [requestNumber];
+ if (!data.Enabled)
+ continue;
+
+ fsw = data.FSW;
+ NotifyFilters flt = fsw.NotifyFilter;
+ RenamedEventArgs renamed = null;
+ FileAction fa = 0;
+ if (code == (int) FAMCodes.Changed && (flt & changed) != 0)
+ fa = FileAction.Modified;
+ else if (code == (int) FAMCodes.Deleted)
+ fa = FileAction.Removed;
+ else if (code == (int) FAMCodes.Created)
+ fa = FileAction.Added;
+
+ if (fa != 0) {
+ if (filename != data.Directory && !fsw.Pattern.IsMatch (filename))
+ continue;
+
+ lock (fsw) {
+ fsw.DispatchEvents (fa, filename, ref renamed);
+ if (fsw.Waiting) {
+ fsw.Waiting = false;
+ System.Threading.Monitor.PulseAll (fsw);
+ }
+ }
+ }
+
+ } while (FAMPending (ref conn) > 0);
+ }
+ }
+
+ [DllImport ("fam")]
+ extern static int FAMOpen (out FAMConnection fc);
+
+ [DllImport ("fam")]
+ extern static int FAMClose (ref FAMConnection fc);
+
+ [DllImport ("fam")]
+ extern static int FAMMonitorDirectory (ref FAMConnection fc, string filename,
+ out FAMRequest fr, IntPtr user_data);
+
+ [DllImport ("fam")]
+ extern static int FAMCancelMonitor (ref FAMConnection fc, ref FAMRequest fr);
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ extern static int InternalFAMNextEvent (ref FAMConnection fc, out string filename,
+ out int code, out int reqnum);
+
+ [DllImport ("fam")]
+ extern static int FAMPending (ref FAMConnection fc);
+ }
+}
+
--- /dev/null
+//
+// System.IO.FileAction.cs
+//
+// Authors:
+// Gonzalo Paniagua Javier (gonzalo@ximian.com)
+//
+// (c) 2004 Novell, Inc. (http://www.novell.com)
+//
+
+namespace System.IO {
+ enum FileAction {
+ Added = 1,
+ Removed = 2,
+ Modified = 3,
+ RenamedOldName = 4,
+ RenamedNewName = 5
+ }
+}
this.name = name;\r
}\r
\r
+ internal void SetName (string name)\r
+ {\r
+ this.name = name;\r
+ }\r
#endregion // Constructors\r
\r
#region Properties\r
//
// Copyright (C) Tim Coleman, 2002
// (c) 2003 Ximian, Inc. (http://www.ximian.com)
+// (c) 2004 Novell, Inc. (http://www.novell.com)
//
using System;
using System.ComponentModel;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
using System.Threading;
namespace System.IO {
int internalBufferSize;
NotifyFilters notifyFilter;
string path;
- ISite site;
+ string fullpath;
ISynchronizeInvoke synchronizingObject;
+ bool disposed;
+ WaitForChangedResult lastData;
+ bool waiting;
+ SearchPattern2 pattern;
+ static IFileWatcher watcher;
#endregion // Fields
this.includeSubdirectories = false;
this.internalBufferSize = 8192;
this.path = "";
+ InitWatcher ();
}
public FileSystemWatcher (string path)
- : this (path, String.Empty)
+ : this (path, "*.*")
{
}
this.notifyFilter = NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.DirectoryName;
this.path = path;
this.synchronizingObject = null;
+ InitWatcher ();
+ }
+
+ void InitWatcher ()
+ {
+ lock (typeof (FileSystemWatcher)) {
+ if (watcher != null)
+ return;
+
+ int mode = InternalSupportsFSW ();
+ bool ok = false;
+ if (mode == 2)
+ ok = FAMWatcher.GetInstance (out watcher);
+ else if (mode == 1)
+ ok = WindowsWatcher.GetInstance (out watcher);
+
+ if (mode == 0 || !ok)
+ DefaultWatcher.GetInstance (out watcher);
+ }
}
#endregion // Constructors
#region Properties
+ /* If this is enabled, we Pulse this instance */
+ internal bool Waiting {
+ get { return waiting; }
+ set { waiting = value; }
+ }
+
+ internal SearchPattern2 Pattern {
+ get {
+ if (pattern == null) {
+ string f = Filter;
+ if (f == "*.*" && !(watcher.GetType () == typeof (WindowsWatcher)))
+ f = "*";
+
+ pattern = new SearchPattern2 (f);
+ }
+ return pattern;
+ }
+ }
+
+ internal string FullPath {
+ get {
+ if (fullpath == null) {
+ if (path == null || path == "")
+ fullpath = Environment.CurrentDirectory;
+ else
+ fullpath = System.IO.Path.GetFullPath (path);
+ }
+
+ return fullpath;
+ }
+ }
+
[DefaultValue(false)]
[IODescription("Flag to indicate if this instance is active")]
public bool EnableRaisingEvents {
get { return enableRaisingEvents; }
- set { enableRaisingEvents = value; }
+ set {
+ if (value == enableRaisingEvents)
+ return; // Do nothing
+
+ enableRaisingEvents = value;
+ if (value) {
+ Start ();
+ } else {
+ Stop ();
+ }
+ }
}
[DefaultValue("*.*")]
public string Filter {
get { return filter; }
set {
- filter = value;
- if (filter == null || filter == "")
- filter = "*.*";
+ if (value == null || value == "")
+ value = "*.*";
+
+ if (filter != value) {
+ filter = value;
+ pattern = null;
+ }
}
}
[IODescription("Flag to indicate we want to watch subdirectories")]
public bool IncludeSubdirectories {
get { return includeSubdirectories; }
- set { includeSubdirectories = value; }
+ set {
+ if (includeSubdirectories == value)
+ return;
+
+ includeSubdirectories = value;
+ if (value && enableRaisingEvents) {
+ Stop ();
+ Start ();
+ }
+ }
}
[Browsable(false)]
[DefaultValue(8192)]
public int InternalBufferSize {
get { return internalBufferSize; }
- set { internalBufferSize = value; }
+ set {
+ if (internalBufferSize == value)
+ return;
+
+ if (value < 4196)
+ value = 4196;
+
+ internalBufferSize = value;
+ if (enableRaisingEvents) {
+ Stop ();
+ Start ();
+ }
+ }
}
[DefaultValue(NotifyFilters.FileName | NotifyFilters.DirectoryName | NotifyFilters.LastWrite)]
[IODescription("Flag to indicate which change event we want to monitor")]
public NotifyFilters NotifyFilter {
get { return notifyFilter; }
- [MonoTODO ("Perform validation.")]
- set { notifyFilter = value; }
+ set {
+ if (notifyFilter == value)
+ return;
+
+ notifyFilter = value;
+ if (enableRaisingEvents) {
+ Stop ();
+ Start ();
+ }
+ }
}
[DefaultValue("")]
public string Path {
get { return path; }
set {
+ if (path == value)
+ return;
+
bool exists = false;
Exception exc = null;
try {
exists = Directory.Exists (value);
} catch (Exception e) {
- exists = false;
exc = e;
}
throw new ArgumentException ("Directory does not exists", "value");
path = value;
+ fullpath = null;
+ if (enableRaisingEvents) {
+ Stop ();
+ Start ();
+ }
}
}
[Browsable(false)]
public override ISite Site {
- get { return site; }
- set { site = value; }
+ get { return base.Site; }
+ set { base.Site = value; }
}
[DefaultValue(null)]
throw new NotImplementedException ();
}
- [MonoTODO]
protected override void Dispose (bool disposing)
{
if (disposing) {
- //
+ Stop ();
}
+ disposed = true;
base.Dispose (disposing);
}
return WaitForChanged (changeType, Timeout.Infinite);
}
- [MonoTODO]
public WaitForChangedResult WaitForChanged (WatcherChangeTypes changeType, int timeout)
{
- throw new NotImplementedException ();
+ WaitForChangedResult result = new WaitForChangedResult ();
+ bool prevEnabled = EnableRaisingEvents;
+ if (!prevEnabled)
+ EnableRaisingEvents = true;
+
+ bool gotData;
+ lock (this) {
+ waiting = true;
+ gotData = Monitor.Wait (this, timeout);
+ if (gotData)
+ result = this.lastData;
+ }
+
+ EnableRaisingEvents = prevEnabled;
+ if (!gotData)
+ result.TimedOut = true;
+
+ return result;
}
+ internal void DispatchEvents (FileAction act, string filename, ref RenamedEventArgs renamed)
+ {
+ if (waiting) {
+ lastData = new WaitForChangedResult ();
+ }
+
+ switch (act) {
+ case FileAction.Added:
+ lastData.Name = filename;
+ lastData.ChangeType = WatcherChangeTypes.Created;
+ OnCreated (new FileSystemEventArgs (WatcherChangeTypes.Created, path, filename));
+ break;
+ case FileAction.Removed:
+ lastData.Name = filename;
+ lastData.ChangeType = WatcherChangeTypes.Deleted;
+ OnDeleted (new FileSystemEventArgs (WatcherChangeTypes.Deleted, path, filename));
+ break;
+ case FileAction.Modified:
+ lastData.Name = filename;
+ lastData.ChangeType = WatcherChangeTypes.Changed;
+ OnChanged (new FileSystemEventArgs (WatcherChangeTypes.Changed, path, filename));
+ break;
+ case FileAction.RenamedOldName:
+ if (renamed != null) {
+ OnRenamed (renamed);
+ }
+ lastData.OldName = filename;
+ lastData.ChangeType = WatcherChangeTypes.Renamed;
+ renamed = new RenamedEventArgs (WatcherChangeTypes.Renamed, path, null, filename);
+ break;
+ case FileAction.RenamedNewName:
+ lastData.Name = filename;
+ lastData.ChangeType = WatcherChangeTypes.Renamed;
+ if (renamed != null) {
+ renamed.SetName (filename);
+ } else {
+ renamed = new RenamedEventArgs (WatcherChangeTypes.Renamed, path, filename, null);
+ }
+ OnRenamed (renamed);
+ renamed = null;
+ break;
+ default:
+ break;
+ }
+ }
+
+ void Start ()
+ {
+ watcher.StartDispatching (this);
+ }
+
+ void Stop ()
+ {
+ watcher.StopDispatching (this);
+ }
#endregion // Methods
#region Events and Delegates
public event RenamedEventHandler Renamed;
#endregion // Events and Delegates
+
+ /* 0 -> not supported */
+ /* 1 -> windows */
+ /* 2 -> FAM */
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ static extern int InternalSupportsFSW ();
+
+ /*[MethodImplAttribute(MethodImplOptions.InternalCall)]
+ static extern IntPtr InternalOpenDirectory (string path, IntPtr reserved);
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ static extern IntPtr InternalCloseDirectory (IntPtr handle);
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ static extern bool InternalReadDirectoryChanges (IntPtr handle,
+ byte [] buffer,
+ bool includeSubdirectories,
+ NotifyFilters notifyFilter,
+ out NativeOverlapped overlap,
+ OverlappedHandler overlappedCallback);
+
+ */
}
}
--- /dev/null
+//
+// System.IO.IFileWatcher.cs
+//
+// Authors:
+// Gonzalo Paniagua Javier (gonzalo@ximian.com)
+//
+// (c) 2004 Novell, Inc. (http://www.novell.com)
+//
+
+namespace System.IO {
+ interface IFileWatcher {
+ void StartDispatching (FileSystemWatcher fsw);
+ void StopDispatching (FileSystemWatcher fsw);
+ }
+}
+
--- /dev/null
+//
+// System.IO.SearchPattern2.cs: Filename glob support.
+//
+// Author:
+// Dan Lewis (dihlewis@yahoo.co.uk)
+//
+// (C) 2002
+//
+
+// Copied from corlib/System.IO/SearchPatter.cs
+using System;
+
+namespace System.IO {
+
+ // FIXME: there's a complication with this algorithm under windows.
+ // the pattern '*.*' matches all files (i think . matches the extension),
+ // whereas under UNIX it should only match files containing the '.' character.
+
+ class SearchPattern2 {
+ public SearchPattern2 (string pattern) : this (pattern, false) { }
+
+ public SearchPattern2 (string pattern, bool ignore)
+ {
+ this.ignore = ignore;
+ Compile (pattern);
+ }
+
+ public bool IsMatch (string text)
+ {
+ return Match (ops, text, 0);
+ }
+
+ // private
+
+ private Op ops; // the compiled pattern
+ private bool ignore; // ignore case
+
+ private void Compile (string pattern)
+ {
+ if (pattern == null || pattern.IndexOfAny (InvalidChars) >= 0)
+ throw new ArgumentException ("Invalid search pattern.");
+
+ if (pattern == "*") { // common case
+ ops = new Op (OpCode.True);
+ return;
+ }
+
+ ops = null;
+
+ int ptr = 0;
+ Op last_op = null;
+ while (ptr < pattern.Length) {
+ Op op;
+
+ switch (pattern [ptr]) {
+ case '?':
+ op = new Op (OpCode.AnyChar);
+ ++ ptr;
+ break;
+
+ case '*':
+ op = new Op (OpCode.AnyString);
+ ++ ptr;
+ break;
+
+ default:
+ op = new Op (OpCode.ExactString);
+ int end = pattern.IndexOfAny (WildcardChars, ptr);
+ if (end < 0)
+ end = pattern.Length;
+
+ op.Argument = pattern.Substring (ptr, end - ptr);
+ if (ignore)
+ op.Argument = op.Argument.ToLower ();
+
+ ptr = end;
+ break;
+ }
+
+ if (last_op == null)
+ ops = op;
+ else
+ last_op.Next = op;
+
+ last_op = op;
+ }
+
+ if (last_op == null)
+ ops = new Op (OpCode.End);
+ else
+ last_op.Next = new Op (OpCode.End);
+ }
+
+ private bool Match (Op op, string text, int ptr)
+ {
+ while (op != null) {
+ switch (op.Code) {
+ case OpCode.True:
+ return true;
+
+ case OpCode.End:
+ if (ptr == text.Length)
+ return true;
+
+ return false;
+
+ case OpCode.ExactString:
+ int length = op.Argument.Length;
+ if (ptr + length > text.Length)
+ return false;
+
+ string str = text.Substring (ptr, length);
+ if (ignore)
+ str = str.ToLower ();
+
+ if (str != op.Argument)
+ return false;
+
+ ptr += length;
+ break;
+
+ case OpCode.AnyChar:
+ if (++ ptr > text.Length)
+ return false;
+ break;
+
+ case OpCode.AnyString:
+ while (ptr <= text.Length) {
+ if (Match (op.Next, text, ptr))
+ return true;
+
+ ++ ptr;
+ }
+
+ return false;
+ }
+
+ op = op.Next;
+ }
+
+ return true;
+ }
+
+ // private static
+
+ internal static readonly char [] WildcardChars = { '*', '?' };
+ internal static readonly char [] InvalidChars = { Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar };
+
+ private class Op {
+ public Op (OpCode code)
+ {
+ this.Code = code;
+ this.Argument = null;
+ this.Next = null;
+ }
+
+ public OpCode Code;
+ public string Argument;
+ public Op Next;
+ }
+
+ private enum OpCode {
+ ExactString, // literal
+ AnyChar, // ?
+ AnyString, // *
+ End, // end of pattern
+ True // always succeeds
+ };
+ }
+}
--- /dev/null
+//
+// System.IO.WindowsWatcher.cs: windows IFileWatcher
+//
+// Authors:
+// Gonzalo Paniagua Javier (gonzalo@ximian.com)
+//
+// (c) 2004 Novell, Inc. (http://www.novell.com)
+//
+
+namespace System.IO {
+ class WindowsWatcher : IFileWatcher
+ {
+ private WindowsWatcher ()
+ {
+ }
+
+ public static bool GetInstance (out IFileWatcher watcher)
+ {
+ throw new NotSupportedException ();
+ }
+
+ public void StartDispatching (FileSystemWatcher fsw)
+ {
+ }
+
+ public void StopDispatching (FileSystemWatcher fsw)
+ {
+ }
+ }
+}
+
System.Diagnostics/TraceListenerCollection.cs
System.Diagnostics/TraceListener.cs
System.Diagnostics/TraceSwitch.cs
+System.IO/DefaultWatcher.cs
System.IO/ErrorEventArgs.cs
System.IO/ErrorEventHandler.cs
+System.IO/FAMWatcher.cs
+System.IO/FileAction.cs
System.IO/FileSystemEventArgs.cs
System.IO/FileSystemEventHandler.cs
System.IO/FileSystemWatcher.cs
+System.IO/IFileWatcher.cs
System.IO/InternalBufferOverflowException.cs
System.IO/IODescriptionAttribute.cs
System.IO/MonoIO.cs
System.IO/NotifyFilters.cs
System.IO/RenamedEventArgs.cs
System.IO/RenamedEventHandler.cs
+System.IO/SearchPattern.cs
System.IO/WaitForChangedResult.cs
System.IO/WatcherChangeTypes.cs
+System.IO/WindowsWatcher.cs
System.Net/AuthenticationManager.cs
System.Net/Authorization.cs
System.Net/BasicClient.cs
System.Diagnostics/TraceTest.cs
System.Diagnostics/SwitchesTest.cs
System.Diagnostics/DiagnosticsConfigurationHandlerTest.cs
+System.IO/FileSystemWatcherTest.cs
System.Net/CookieCollectionTest.cs
System.Net/CookieTest.cs
System.Net/CredentialCacheTest.cs
--- /dev/null
+2004-01-16 Gonzalo Paniagua Javier <gonzalo@ximian.com>
+
+ * FileSystemWatcherTest.cs: new test.
+
--- /dev/null
+// FileSystemWatcherTest.cs - NUnit Test Cases for the System.IO.FileSystemWatcher class
+//
+// Authors:
+// Gonzalo Paniagua Javier (gonzalo@ximian.com)
+//
+// (C) 2004 Novell, Inc. http://www.novell.com
+//
+
+using NUnit.Framework;
+using System;
+using System.IO;
+
+namespace MonoTests.System.IO
+{
+ [TestFixture]
+ public class FileSystemWatcherTest : Assertion
+ {
+ [Test]
+ public void CheckDefaults ()
+ {
+ FileSystemWatcher fw = new FileSystemWatcher ();
+ AssertEquals ("#01", fw.EnableRaisingEvents, false);
+ AssertEquals ("#02", fw.Filter, "*.*");
+ AssertEquals ("#03", fw.IncludeSubdirectories, false);
+ AssertEquals ("#04", fw.InternalBufferSize, 8192);
+ AssertEquals ("#05", fw.NotifyFilter, NotifyFilters.FileName | NotifyFilters.DirectoryName | NotifyFilters.LastWrite);
+ AssertEquals ("#06", fw.Path, "");
+ }
+
+ [Test]
+ [ExpectedException (typeof (ArgumentNullException))]
+ public void CheckCtor1 ()
+ {
+ FileSystemWatcher fw = new FileSystemWatcher (null);
+ }
+
+ [Test]
+ [ExpectedException (typeof (ArgumentException))]
+ public void CheckCtor2 ()
+ {
+ FileSystemWatcher fw = new FileSystemWatcher ("");
+ }
+
+ [Test]
+ [ExpectedException (typeof (ArgumentException))]
+ public void CheckCtor3 ()
+ {
+ FileSystemWatcher fw = new FileSystemWatcher ("notexistsblahblah");
+ }
+
+ [Test]
+ [ExpectedException (typeof (ArgumentNullException))]
+ public void CheckCtor4 ()
+ {
+ FileSystemWatcher fw = new FileSystemWatcher (Path.GetTempPath (), null);
+ }
+
+ [Test]
+ // Doesn't throw here :-?
+ // [ExpectedException (typeof (ArgumentException))]
+ public void CheckCtor5 ()
+ {
+ FileSystemWatcher fw = new FileSystemWatcher (Path.GetTempPath (), "invalidpath|");
+ fw = new FileSystemWatcher (Path.GetTempPath (), "*");
+ }
+
+ [Test]
+ // ...But here it does...
+ [ExpectedException (typeof (ArgumentException))]
+ public void CheckInvalidPath ()
+ {
+ FileSystemWatcher fw = new FileSystemWatcher (Path.GetTempPath (), "invalidpath|");
+ fw.Path = "invalidpath|";
+ }
+
+ [Test]
+ // ...and here too
+ [ExpectedException (typeof (ArgumentException))]
+ public void CheckPathWildcard ()
+ {
+ FileSystemWatcher fw = new FileSystemWatcher (Path.GetTempPath (), "*");
+ fw.Path = "*";
+ }
+ }
+}
+