void Callback (IntPtr streamRef, IntPtr clientCallBackInfo, int numEvents, IntPtr eventPaths, IntPtr eventFlags, IntPtr eventIds) { var paths = new string[numEvents]; var actions = new FSEventStreamEventFlagItem[numEvents]; var ids = new UInt64[numEvents]; unsafe { var eventPathsPointer = (char**)eventPaths.ToPointer (); var eventFlagsPointer = (uint*)eventFlags.ToPointer (); var eventIdsPointer = (ulong*)eventIds.ToPointer (); for (var i = 0; i < numEvents; i++) { paths [i] = Marshal.PtrToStringAuto (new IntPtr (eventPathsPointer [i])); actions[i] = (FSEventStreamEventFlagItem)eventFlagsPointer[i]; ids [i] = eventIdsPointer [i]; } } if( numEvents == 2 ) { var renameCount = 0; for (var i = 0; i < numEvents; i++) { if( (actions[i] & FSEventStreamEventFlagItem.Renamed) == FSEventStreamEventFlagItem.Renamed ) renameCount++; } if( renameCount == 2 ) { var before = (File)paths[0]; var after = (File)paths[1]; NotifySubscribers(FileChange.Deleted, before); NotifySubscribers(FileChange.Added, after); return; } } for (var i = 0; i < numEvents; i++) { var action = actions[i]; var path = paths[i]; var file = (File)path; var fileChange = TranslateAction(file, action); NotifySubscribers(fileChange, file); } }
private void Callback(IntPtr streamRef, IntPtr clientCallBackInfo, int numEvents, IntPtr eventPaths, IntPtr eventFlags, IntPtr eventIds) { string[] paths = new string[numEvents]; FSEventStreamEventFlagItem[] flags = new FSEventStreamEventFlagItem[numEvents]; UInt64[] ids = new UInt64[numEvents]; unsafe { char** eventPathsPointer = (char**)eventPaths.ToPointer (); uint* eventFlagsPointer = (uint*)eventFlags.ToPointer (); ulong* eventIdsPointer = (ulong*)eventIds.ToPointer (); for (int i = 0; i < numEvents; i++) { paths [i] = Marshal.PtrToStringAuto (new IntPtr (eventPathsPointer [i])); flags [i] = (FSEventStreamEventFlagItem)eventFlagsPointer [i]; ids [i] = eventIdsPointer [i]; } } ChangedEventHandler handler = Changed; for (int i = 0; i < numEvents; i++) { if (paths [i] == repo.Path || paths [i] + Path.DirectorySeparatorChar.ToString () == repo.Path) return; if(!paths[i].Substring(paths[i].LastIndexOf(Path.DirectorySeparatorChar)+1).StartsWith(".")){ string search = paths [i]; if(flags [i].HasFlag (FSEventStreamEventFlagItem.IsDir)) search += Path.DirectorySeparatorChar; bool ignore = false; lock(_bagLock){ if (ignoreBag.Contains (search)) ignore = true; } if (!ignore) { Event e = new Event (repo); List<Event> subEvents = new List<Event> (); string key = repo.RemoteFolder + paths [i].Substring (repo.Path.Length); if (flags [i].HasFlag (FSEventStreamEventFlagItem.IsDir) && !key.EndsWith (Path.DirectorySeparatorChar.ToString())) key += Path.DirectorySeparatorChar; e.Item = RepositoryItem.CreateInstance (repo, key); if ( flags [i].HasFlag (FSEventStreamEventFlagItem.Created) && ((flags [i].HasFlag (FSEventStreamEventFlagItem.IsFile) && !flags[i].HasFlag (FSEventStreamEventFlagItem.Renamed)) || (flags [i].HasFlag (FSEventStreamEventFlagItem.IsDir) && !flags[i].HasFlag (FSEventStreamEventFlagItem.Renamed))) ) { e.EventType = EventType.CREATE; List<RepositoryItem> items = new List<RepositoryItem>(); if(e.Item.IsFolder){ items = physicalController.GetItems (e.Item.LocalAbsolutePath); } if (items.Count > 0) { foreach(RepositoryItem item in items){ Event e2 = new Event (repo); e2.EventType = EventType.CREATE; e2.Item = item; subEvents.Add (e2); } } } else if (flags [i].HasFlag (FSEventStreamEventFlagItem.Removed)) { e.EventType = EventType.DELETE; } else if (flags [i].HasFlag (FSEventStreamEventFlagItem.Modified)) { if (flags [i].HasFlag (FSEventStreamEventFlagItem.IsDir) && !Directory.Exists (paths[i])) { e.EventType = EventType.DELETE; } else if (flags [i].HasFlag (FSEventStreamEventFlagItem.IsFile) && !File.Exists (paths[i])) { e.EventType = EventType.DELETE; } else { e.EventType = EventType.UPDATE; } } else if (flags [i].HasFlag (FSEventStreamEventFlagItem.Renamed)) { if ((i + 1) < numEvents && (ids [i] == ids [i+1] - 1)) { e.EventType = EventType.MOVE; i++; string key2 = repo.RemoteFolder + paths [i].Substring (repo.Path.Length); if (flags [i].HasFlag (FSEventStreamEventFlagItem.IsDir) && !key2.EndsWith (Path.DirectorySeparatorChar.ToString())) key2 += Path.DirectorySeparatorChar; e.Item.BuildResultItem (key2); } else if (flags [i].HasFlag (FSEventStreamEventFlagItem.IsDir) && !Directory.Exists (paths[i])) { e.EventType = EventType.DELETE; } else if (flags [i].HasFlag (FSEventStreamEventFlagItem.IsFile) && !File.Exists (paths[i])) { e.EventType = EventType.DELETE; } else { if (flags [i].HasFlag (FSEventStreamEventFlagItem.IsFile)) { e.EventType = EventType.UPDATE; } } } else { return; } handler (e); foreach(Event e2 in subEvents){ handler(e2); } } } } }
FileChange TranslateAction(IFile file, FSEventStreamEventFlagItem action) { if( !System.IO.File.Exists (file.FullPath) || (action & FSEventStreamEventFlagItem.Removed) == FSEventStreamEventFlagItem.Removed ) return FileChange.Deleted; if( (action & FSEventStreamEventFlagItem.Renamed) == FSEventStreamEventFlagItem.Renamed ) return FileChange.Renamed; if( (action & FSEventStreamEventFlagItem.Created) == FSEventStreamEventFlagItem.Created ) return FileChange.Added; if( (action & FSEventStreamEventFlagItem.Modified ) == FSEventStreamEventFlagItem.Modified ) return FileChange.Modified; return FileChange.Unknown; }