11#![ allow( non_upper_case_globals, dead_code) ]
2- // via https://github.com/octplane/ fsevent-rust
2+ extern crate fsevent as fse ;
33
44use fsevent_sys:: core_foundation as cf;
55use fsevent_sys:: fsevent as fs;
66use std:: slice;
7- use std:: ffi:: CString ;
87use std:: mem:: transmute;
98use std:: slice:: from_raw_parts_mut;
109use std:: str:: from_utf8;
@@ -18,74 +17,6 @@ use super::{Error, Event, op, Watcher};
1817use std:: path:: { Path , PathBuf } ;
1918use libc;
2019
21-
22- // TODO: add this to fsevent_sys
23- const kCFStringEncodingUTF8: u32 = 0x08000100 ;
24- pub type CFStringEncoding = u32 ;
25-
26- const kCFCompareEqualTo: i32 = 0 ;
27- pub type CFComparisonResult = i32 ;
28-
29- // MacOS uses Case Insensitive path
30- const kCFCompareCaseInsensitive: u32 = 1 ;
31- pub type CFStringCompareFlags = u32 ;
32-
33- #[ link( name = "CoreServices" , kind = "framework" ) ]
34- extern "C" {
35- pub fn FSEventStreamInvalidate ( streamRef : fs:: FSEventStreamRef ) ;
36- pub fn FSEventStreamRelease ( streamRef : fs:: FSEventStreamRef ) ;
37- pub fn FSEventStreamUnscheduleFromRunLoop ( streamRef : fs:: FSEventStreamRef , runLoop : cf:: CFRunLoopRef , runLoopMode : cf:: CFStringRef ) ;
38-
39- pub fn CFRunLoopStop ( rl : cf:: CFRunLoopRef ) ;
40- pub fn CFShowStr ( str : cf:: CFStringRef ) ;
41- pub fn CFStringGetCStringPtr ( theString : cf:: CFStringRef , encoding : CFStringEncoding ) -> * const libc:: c_char ;
42- pub fn CFStringCompare ( theString1 : cf:: CFStringRef , theString2 : cf:: CFStringRef , compareOptions : CFStringCompareFlags ) -> CFComparisonResult ;
43- pub fn CFArrayRemoveValueAtIndex ( theArray : cf:: CFMutableArrayRef , idx : cf:: CFIndex ) ;
44- }
45-
46- pub const NULL : cf:: CFRef = cf:: NULL ;
47-
48- unsafe fn str_path_to_cfstring_ref ( source : & str ) -> cf:: CFStringRef {
49- let c_path = CString :: new ( source) . unwrap ( ) ;
50- let c_len = libc:: strlen ( c_path. as_ptr ( ) ) ;
51- let mut url = cf:: CFURLCreateFromFileSystemRepresentation ( cf:: kCFAllocatorDefault, c_path. as_ptr ( ) , c_len as i64 , false ) ;
52- let mut placeholder = cf:: CFURLCopyAbsoluteURL ( url) ;
53- cf:: CFRelease ( url) ;
54-
55- let imaginary: cf:: CFRef = cf:: CFArrayCreateMutable ( cf:: kCFAllocatorDefault, 0 , & cf:: kCFTypeArrayCallBacks) ;
56-
57- while !cf:: CFURLResourceIsReachable ( placeholder, cf:: kCFAllocatorDefault) {
58- let child = cf:: CFURLCopyLastPathComponent ( placeholder) ;
59- cf:: CFArrayInsertValueAtIndex ( imaginary, 0 , child) ;
60- cf:: CFRelease ( child) ;
61-
62- url = cf:: CFURLCreateCopyDeletingLastPathComponent ( cf:: kCFAllocatorDefault, placeholder) ;
63- cf:: CFRelease ( placeholder) ;
64- placeholder = url;
65- }
66-
67- url = cf:: CFURLCreateFileReferenceURL ( cf:: kCFAllocatorDefault, placeholder, cf:: kCFAllocatorDefault) ;
68- cf:: CFRelease ( placeholder) ;
69- placeholder = cf:: CFURLCreateFilePathURL ( cf:: kCFAllocatorDefault, url, cf:: kCFAllocatorDefault) ;
70- cf:: CFRelease ( url) ;
71-
72- if imaginary != cf:: kCFAllocatorDefault {
73- let mut count = 0 ;
74- while count < cf:: CFArrayGetCount ( imaginary) {
75- let component = cf:: CFArrayGetValueAtIndex ( imaginary, count) ;
76- url = cf:: CFURLCreateCopyAppendingPathComponent ( cf:: kCFAllocatorDefault, placeholder, component, false ) ;
77- cf:: CFRelease ( placeholder) ;
78- placeholder = url;
79- count = count + 1 ;
80- }
81- cf:: CFRelease ( imaginary) ;
82- }
83-
84- let cf_path = cf:: CFURLCopyFileSystemPath ( placeholder, cf:: kCFURLPOSIXPathStyle) ;
85- cf:: CFRelease ( placeholder) ;
86- cf_path
87- }
88-
8920pub struct FsEventWatcher {
9021 paths : cf:: CFMutableArrayRef ,
9122 since_when : fs:: FSEventStreamEventId ,
@@ -96,63 +27,26 @@ pub struct FsEventWatcher {
9627 context : Option < StreamContextInfo > ,
9728}
9829
99- bitflags ! {
100- flags StreamFlags : u32 {
101- const NONE = 0x00000000 ,
102- const MUST_SCAN_SUB_DIRS = 0x00000001 ,
103- const USER_DROPPED = 0x00000002 ,
104- const KERNEL_DROPPED = 0x00000004 ,
105- const IDS_WRAPPED = 0x00000008 ,
106- const HISTORY_DONE = 0x00000010 ,
107- const ROOT_CHANGED = 0x00000020 ,
108- const MOUNT = 0x00000040 ,
109- const UNMOUNT = 0x00000080 ,
110- const ITEM_CREATED = 0x00000100 ,
111- const ITEM_REMOVED = 0x00000200 ,
112- const ITEM_INODE_META_MOD = 0x00000400 ,
113- const ITEM_RENAMED = 0x00000800 ,
114- const ITEM_MODIFIED = 0x00001000 ,
115- const ITEM_FINDER_INFO_MOD = 0x00002000 ,
116- const ITEM_CHANGE_OWNER = 0x00004000 ,
117- const ITEM_XATTR_MOD = 0x00008000 ,
118- const ITEM_IS_FILE = 0x00010000 ,
119- const ITEM_IS_DIR = 0x00020000 ,
120- const ITEM_IS_SYMLIMK = 0x00040000 ,
121- }
122- }
123-
124- fn translate_flags ( flags : StreamFlags ) -> op:: Op {
30+ fn translate_flags ( flags : fse:: StreamFlags ) -> op:: Op {
12531 let mut ret = op:: Op :: empty ( ) ;
126- if flags. contains ( ITEM_XATTR_MOD ) {
32+ if flags. contains ( fse :: ITEM_XATTR_MOD ) {
12733 ret. insert ( op:: CHMOD ) ;
12834 }
129- if flags. contains ( ITEM_CREATED ) {
35+ if flags. contains ( fse :: ITEM_CREATED ) {
13036 ret. insert ( op:: CREATE ) ;
13137 }
132- if flags. contains ( ITEM_REMOVED ) {
38+ if flags. contains ( fse :: ITEM_REMOVED ) {
13339 ret. insert ( op:: REMOVE ) ;
13440 }
135- if flags. contains ( ITEM_RENAMED ) {
41+ if flags. contains ( fse :: ITEM_RENAMED ) {
13642 ret. insert ( op:: RENAME ) ;
13743 }
138- if flags. contains ( ITEM_MODIFIED ) {
44+ if flags. contains ( fse :: ITEM_MODIFIED ) {
13945 ret. insert ( op:: WRITE ) ;
14046 }
14147 ret
14248}
14349
144-
145- pub fn is_api_available ( ) -> Result < ( ) , String > {
146- let ma = cf:: system_version_major ( ) ;
147- let mi = cf:: system_version_minor ( ) ;
148-
149- if ma == 10 && mi < 5 {
150- Err ( "This version of OSX does not support the FSEvent library, cannot proceed" . to_string ( ) )
151- } else {
152- Ok ( ( ) )
153- }
154- }
155-
15650struct StreamContextInfo {
15751 sender : Sender < Event > ,
15852 done : Receiver < ( ) >
@@ -173,7 +67,7 @@ impl FsEventWatcher {
17367 if let Some ( runloop) = runloop. clone ( ) {
17468 unsafe {
17569 let runloop = runloop as * mut libc:: c_void ;
176- CFRunLoopStop ( runloop) ;
70+ cf :: CFRunLoopStop ( runloop) ;
17771 }
17872 }
17973 }
@@ -187,17 +81,18 @@ impl FsEventWatcher {
18781 }
18882 }
18983
84+
19085 self . context = None ;
19186 }
19287
19388 fn remove_path ( & mut self , source : & str ) {
19489 unsafe {
195- let cf_path = str_path_to_cfstring_ref ( source) ;
90+ let cf_path = cf :: str_path_to_cfstring_ref ( source) ;
19691
19792 for idx in 0 .. cf:: CFArrayGetCount ( self . paths ) {
19893 let item = cf:: CFArrayGetValueAtIndex ( self . paths , idx) ;
199- if CFStringCompare ( item, cf_path, kCFCompareCaseInsensitive) == kCFCompareEqualTo {
200- CFArrayRemoveValueAtIndex ( self . paths , idx) ;
94+ if cf :: CFStringCompare ( item, cf_path, cf :: kCFCompareCaseInsensitive) == cf :: kCFCompareEqualTo {
95+ cf :: CFArrayRemoveValueAtIndex ( self . paths , idx) ;
20196 }
20297 }
20398 }
@@ -206,7 +101,7 @@ impl FsEventWatcher {
206101 // https://github.com/thibaudgg/rb-fsevent/blob/master/ext/fsevent_watch/main.c
207102 fn append_path ( & mut self , source : & str ) {
208103 unsafe {
209- let cf_path = str_path_to_cfstring_ref ( source) ;
104+ let cf_path = cf :: str_path_to_cfstring_ref ( source) ;
210105 cf:: CFArrayAppendValue ( self . paths , cf_path) ;
211106 cf:: CFRelease ( cf_path) ;
212107 }
@@ -262,8 +157,8 @@ impl FsEventWatcher {
262157 // the calling to CFRunLoopRun will be terminated by CFRunLoopStop call in drop()
263158 cf:: CFRunLoopRun ( ) ;
264159 fs:: FSEventStreamStop ( stream) ;
265- FSEventStreamInvalidate ( stream) ;
266- FSEventStreamRelease ( stream) ;
160+ fs :: FSEventStreamInvalidate ( stream) ;
161+ fs :: FSEventStreamRelease ( stream) ;
267162 let _d = done_tx. send ( ( ) ) . unwrap ( ) ;
268163 } ) ;
269164 }
@@ -293,7 +188,7 @@ pub extern "C" fn callback(
293188
294189 for p in ( 0 ..num) {
295190 let i = CStr :: from_ptr ( paths[ p] ) . to_bytes ( ) ;
296- let flag: StreamFlags = StreamFlags :: from_bits ( flags[ p] as u32 )
191+ let flag = fse :: StreamFlags :: from_bits ( flags[ p] as u32 )
297192 . expect ( format ! ( "Unable to decode StreamFlags: {}" , flags[ p] as u32 ) . as_ref ( ) ) ;
298193
299194 let path = PathBuf :: from ( from_utf8 ( i) . ok ( ) . expect ( "Invalid UTF8 string." ) ) ;
0 commit comments