-
Notifications
You must be signed in to change notification settings - Fork 73
/
CDEvent.h
408 lines (383 loc) · 13.2 KB
/
CDEvent.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
/**
* CDEvents
*
* Copyright (c) 2010-2013 Aron Cedercrantz
* http://github.com/rastersize/CDEvents/
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
/**
* @headerfile CDEvent.h CDEvents/CDEvent.h
* A class that wraps the data from a FSEvents event callback.
*
* A class that wraps the data from a FSEvents event callback. Inspired and
* based upon the open source project SCEvents created by Stuart Connolly
* http://stuconnolly.com/projects/code/
*/
#import <Foundation/Foundation.h>
#import <CoreServices/CoreServices.h>
#pragma mark -
#pragma mark CDEvent types
/**
* The event identifier type.
*
* @since 1.0.0
*/
typedef FSEventStreamEventId CDEventIdentifier;
/**
* The event stream event flags type.
*
* @since 1.0.1
*/
typedef FSEventStreamEventFlags CDEventFlags;
#pragma mark -
#pragma mark CDEvent interface
/**
* An Objective-C wrapper for a <code>FSEvents</code> event data.
*
* @note Inspired by <code>SCEvent</code> class of the <code>SCEvents</code> project by Stuart Connolly.
* @note The class is immutable.
*
* @see FSEvents.h in CoreServices
*
* @since 1.0.0
*/
@interface CDEvent : NSObject <NSCoding, NSCopying> {}
#pragma mark Properties
/** @name Getting Event Properties */
/**
* The event identifier.
*
* The event identifier as returned by <code>FSEvents</code>.
*
* @return The event identifier.
*
* @since 1.0.0
*/
@property (readonly) CDEventIdentifier identifier;
/**
* An approximate date and time the event occured.
*
* @return The approximate date and time the event occured.
*
* @since 1.0.0
*/
@property (strong, readonly) NSDate *date;
/**
* The URL of the item which changed.
*
* @return The URL of the item which changed.
*
* @since 1.0.0
*/
@property (strong, readonly) NSURL *URL;
/** @name Getting Event Flags */
/**
* The flags of the event.
*
* The flags of the event as returned by <code>FSEvents</code>.
*
* @return The flags of the event.
*
* @see FSEventStreamEventFlags
*
* @since 1.0.0
*/
@property (readonly) CDEventFlags flags;
#pragma mark Specific flag properties
/**
* Wheter there was some change in the directory at the specific path supplied in this event.
*
* @return <code>YES</code> if there was some change in the directory, otherwise <code>NO</code>.
*
* @see kFSEventStreamEventFlagNone
* @see flags
* @see mustRescanSubDirectories
* @see isUserDropped
* @see isKernelDropped
* @see isEventIdentifiersWrapped
* @see isHistoryDone
* @see isRootChanged
* @see didVolumeMount
* @see didVolumeUnmount
*
* @since 1.1.0
*/
@property (readonly) BOOL isGenericChange;
/**
* Wheter you must rescan the whole URL including its children.
*
* Wheter your application must rescan not just the URL given in the event, but
* all its children, recursively. This can happen if there was a problem whereby
* events were coalesced hierarchically. For example, an event in
* <code>/Users/jsmith/Music</code> and an event in
* <code>/Users/jsmith/Pictures</code> might be coalesced into an event with
* this flag set and URL <code>= /Users/jsmith</code>. If this flag is set
* you may be able to get an idea of whether the bottleneck happened in the
* kernel (less likely) or in your client (more likely) by checking if
* isUserDropped or isKernelDropped returns <code>YES</code>.
*
* @return <code>YES</code> if you must rescan the whole directory including its children, otherwise <code>NO</code>.
*
* @see kFSEventStreamEventFlagMustScanSubDirs
* @see flags
* @see isGenericChange
* @see isUserDropped
* @see isKernelDropped
* @see isEventIdentifiersWrapped
* @see isHistoryDone
* @see isRootChanged
* @see didVolumeMount
* @see didVolumeUnmount
*
* @since 1.1.0
*/
@property (readonly) BOOL mustRescanSubDirectories;
/**
* Provides some information as to what might have caused the need to rescan the URL including its children.
*
* @return <code>YES</code> if mustRescanSubDirectories returns <code>YES</code> and the cause were in userland, otherwise <code>NO</code>.
*
* @see kFSEventStreamEventFlagUserDropped
* @see flags
* @see isGenericChange
* @see mustRescanSubDirectories
* @see isKernelDropped
* @see isEventIdentifiersWrapped
* @see isHistoryDone
* @see isRootChanged
* @see didVolumeMount
* @see didVolumeUnmount
*
* @since 1.1.0
*/
@property (readonly) BOOL isUserDropped;
/**
* Provides some information as to what might have caused the need to rescan the URL including its children.
*
* @return <code>YES</code> if mustRescanSubDirectories returns <code>YES</code> and the cause were in kernelspace, otherwise <code>NO</code>.
*
* @see kFSEventStreamEventFlagKernelDropped
* @see flags
* @see isGenericChange
* @see mustRescanSubDirectories
* @see isUserDropped
* @see isEventIdentifiersWrapped
* @see isHistoryDone
* @see isRootChanged
* @see didVolumeMount
* @see didVolumeUnmount
*
* @since 1.1.0
*/
@property (readonly) BOOL isKernelDropped;
/**
* Wheter the 64-bit event identifier counter has wrapped around.
*
* Wheter the 64-bit event identifier counter has wrapped around. As a result,
* previously-issued event identifiers are no longer valid arguments for the
* sinceEventIdentifier parameter of the CDEvents init methods.
*
* @return <code>YES</code> if the 64-bit event identifier counter has wrapped around, otherwise <code>NO</code>.
*
* @see kFSEventStreamEventFlagEventIdsWrapped
* @see flags
* @see isGenericChange
* @see mustRescanSubDirectories
* @see isUserDropped
* @see isKernelDropped
* @see isHistoryDone
* @see isRootChanged
* @see didVolumeMount
* @see didVolumeUnmount
*
* @since 1.1.0
*/
@property (readonly) BOOL isEventIdentifiersWrapped;
/**
* Denotes a sentinel event sent to mark the end of the "historical" events sent.
*
* Denotes a sentinel event sent to mark the end of the "historical" events sent
* as a result of specifying a <i>sinceEventIdentifier</i> argument other than
* kCDEventsSinceEventNow with the CDEvents init methods.
*
* @return <code>YES</code> if if the event is sent to mark the end of the "historical" events sent, otherwise <code>NO</code>.
*
* @see kFSEventStreamEventFlagHistoryDone
* @see flags
* @see isGenericChange
* @see mustRescanSubDirectories
* @see isUserDropped
* @see isKernelDropped
* @see isEventIdentifiersWrapped
* @see isRootChanged
* @see didVolumeMount
* @see didVolumeUnmount
* @see kCDEventsSinceEventNow
* @see CDEvents
*
* @since 1.1.0
*/
@property (readonly) BOOL isHistoryDone;
/**
* Denotes a special event sent when there is a change to one of the URLs you asked to watch.
*
* Denotes a special event sent when there is a change to one of the URLs you
* asked to watch. When this method returns <code>YES</code>, the event
* identifier is zero and the <code>URL</code> corresponds to one of the URLs
* you asked to watch (specifically, the one that changed). The URL may no
* longer exist because it or one of its parents was deleted or renamed. Events
* with this flag set will only be sent if you passed the flag
* <code>kFSEventStreamCreateFlagWatchRoot</code> to the CDEvents.
*
* @return <code>YES</code> if there is a change to one of the URLs you asked to watch, otherwise <code>NO</code>.
*
* @see kFSEventStreamEventFlagRootChanged
* @see flags
* @see isGenericChange
* @see mustRescanSubDirectories
* @see isUserDropped
* @see isKernelDropped
* @see isEventIdentifiersWrapped
* @see isHistoryDone
* @see didVolumeMount
* @see didVolumeUnmount
* @see CDEvents
* @see kCDEventsDefaultEventStreamFlags
*
* @since 1.1.0
*/
@property (readonly) BOOL isRootChanged;
/**
* Denotes a special event sent when a volume is mounted underneath one of the URLs being watched.
*
* Denotes a special event sent when a volume is mounted underneath one of the
* URLs being watched. The URL in the event is the URL to the newly-mounted
* volume. You will receive one of these notifications for every volume mount
* event inside the kernel (independent of DiskArbitration). Beware that a
* newly-mounted volume could contain an arbitrarily large directory hierarchy.
* Avoid pitfalls like triggering a recursive scan of a non-local filesystem,
* which you can detect by checking for the absence of the
* <code>MNT_LOCAL</code> flag in the <code>f_flags</code> returned by statfs().
* Also be aware of the <code>MNT_DONTBROWSE</code> flag that is set for volumes
* which should not be displayed by user interface elements.
*
* @return <code>YES</code> if a volumen is mounted underneath one of the URLs being watched, otherwise <code>NO</code>.
*
* @see kFSEventStreamEventFlagMount
* @see flags
* @see isGenericChange
* @see mustRescanSubDirectories
* @see isUserDropped
* @see isKernelDropped
* @see isEventIdentifiersWrapped
* @see isHistoryDone
* @see isRootChanged
* @see didVolumeUnmount
*
* @since 1.1.0
*/
@property (readonly) BOOL didVolumeMount;
/**
* Denotes a special event sent when a volume is unmounted underneath one of the URLs being watched.
*
* Denotes a special event sent when a volume is unmounted underneath one of the
* URLs being watched. The URL in the event is the URL to the directory from
* which the volume was unmounted. You will receive one of these notifications
* for every volume unmount event inside the kernel. This is not a substitute
* for the notifications provided by the DiskArbitration framework; you only get
* notified after the unmount has occurred. Beware that unmounting a volume
* could uncover an arbitrarily large directory hierarchy, although Mac OS X
* never does that.
*
* @return <code>YES</code> if a volume is unmounted underneath one of the URLs being watched, otherwise <code>NO</code>.
*
* @see kFSEventStreamEventFlagUnmount
* @see flags
* @see isGenericChange
* @see mustRescanSubDirectories
* @see isUserDropped
* @see isKernelDropped
* @see isEventIdentifiersWrapped
* @see isHistoryDone
* @see isRootChanged
* @see didVolumeMount
*
* @since 1.1.0
*/
@property (readonly) BOOL didVolumeUnmount;
/**
* The entirety of the documentation on file level events in lion is 3 sentences
* long. Rename behavior is odd, making the combination of events and flags
* somewhat confusing for atomic writes. It also appears possible to get a
* singular event where a file has been created, modified, and removed.
*/
@property (readonly) BOOL isCreated;
@property (readonly) BOOL isRemoved;
@property (readonly) BOOL isInodeMetadataModified;
@property (readonly) BOOL isRenamed;
@property (readonly) BOOL isModified;
@property (readonly) BOOL isFinderInfoModified;
@property (readonly) BOOL didChangeOwner;
@property (readonly) BOOL isXattrModified;
@property (readonly) BOOL isFile;
@property (readonly) BOOL isDir;
@property (readonly) BOOL isSymlink;
#pragma mark Class object creators
/** @name Creating CDEvent Objects */
/**
* Returns an <code>CDEvent</code> created with the given identifier, date, URL and flags.
*
* @param identifier The identifier of the the event.
* @param date The date when the event occured.
* @param URL The URL of the item the event concerns.
* @param flags The flags of the event.
* @return An <code>CDEvent</code> created with the given identifier, date, URL and flags.
*
* @see FSEventStreamEventFlags
* @see initWithIdentifier:date:URL:flags:
*
* @since 1.0.0
*/
+ (CDEvent *)eventWithIdentifier:(NSUInteger)identifier
date:(NSDate *)date
URL:(NSURL *)URL
flags:(CDEventFlags)flags;
#pragma mark Init methods
/**
* Returns an <code>CDEvent</code> object initialized with the given identifier, date, URL and flags.
*
* @param identifier The identifier of the the event.
* @param date The date when the event occured.
* @param URL The URL of the item the event concerns.
* @param flags The flags of the event.
* @return An <code>CDEvent</code> object initialized with the given identifier, date, URL and flags.
* @see FSEventStreamEventFlags
* @see eventWithIdentifier:date:URL:flags:
*
* @since 1.0.0
*/
- (id)initWithIdentifier:(NSUInteger)identifier
date:(NSDate *)date
URL:(NSURL *)URL
flags:(CDEventFlags)flags;
@end