rb-fchange 0.0.2 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +3 -2
- data/lib/rb-fchange/native.rb +15 -40
- data/lib/rb-fchange/notifier.rb +10 -3
- data/lib/rb-fchange/watcher.rb +22 -3
- data/rb-fchange.gemspec +4 -4
- metadata +34 -54
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# rb-fchange
|
2
2
|
|
3
|
-
Code
|
3
|
+
Code is working. But there is still a lot of work.
|
4
4
|
This is a simple wrapper over the Windows Kernel functions for monitoring the specified directory or subtree.
|
5
5
|
|
6
6
|
Example
|
@@ -28,4 +28,5 @@ Example
|
|
28
28
|
- default flag for events :all_events
|
29
29
|
- rework interface (should more look like rb-fsevent)
|
30
30
|
- add specs (can use specs from rb-fsevent)
|
31
|
-
-
|
31
|
+
- add none-ANSI path support
|
32
|
+
- add jRuby support
|
data/lib/rb-fchange/native.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require '
|
1
|
+
require 'ffi'
|
2
2
|
|
3
3
|
module FChange
|
4
4
|
# This module contains the low-level foreign-function.
|
@@ -6,65 +6,40 @@ module FChange
|
|
6
6
|
#
|
7
7
|
# @private
|
8
8
|
module Native
|
9
|
+
extend FFI::Library
|
10
|
+
ffi_lib 'kernel32'
|
11
|
+
ffi_convention :stdcall
|
9
12
|
|
10
|
-
#
|
11
|
-
|
13
|
+
# HANDLE FindFirstChangeNotification(
|
14
|
+
# LPCTSTR lpPathName, // directory name
|
15
|
+
# BOOL bWatchSubtree, // monitoring option
|
16
|
+
# DWORD dwNotifyFilter // filter conditions
|
17
|
+
#);
|
18
|
+
attach_function :FindFirstChangeNotificationW, [:pointer, :int, :long], :long
|
12
19
|
|
13
|
-
#
|
14
|
-
WAIT_OBJECT_0 = 0x00000000
|
15
|
-
|
16
20
|
# HANDLE FindFirstChangeNotification(
|
17
21
|
# LPCTSTR lpPathName, // directory name
|
18
22
|
# BOOL bWatchSubtree, // monitoring option
|
19
23
|
# DWORD dwNotifyFilter // filter conditions
|
20
24
|
#);
|
21
|
-
|
22
|
-
Win32::API.new('FindFirstChangeNotification', ['P', 'I', 'L'], 'L')
|
25
|
+
attach_function :FindFirstChangeNotificationA, [:pointer, :int, :long], :long
|
23
26
|
|
24
|
-
# @return handle
|
25
|
-
def k32FindFirstChangeNotification(path, recursive, flag)
|
26
|
-
@_k32FindFirstChangeNotification.call(path, recursive ? 1 : 0, flag)
|
27
|
-
end
|
28
|
-
|
29
|
-
module_function "k32FindFirstChangeNotification"
|
30
|
-
|
31
27
|
# BOOL FindNextChangeNotification(
|
32
28
|
# HANDLE hChangeHandle // handle to change notification
|
33
29
|
# );
|
34
|
-
|
35
|
-
Win32::API.new('FindNextChangeNotification', ['L'], 'I')
|
36
|
-
|
37
|
-
def k32FindNextChangeNotification(handle)
|
38
|
-
@_k32FindNextChangeNotification.call(handle)
|
39
|
-
end
|
40
|
-
|
41
|
-
module_function "k32FindNextChangeNotification"
|
30
|
+
attach_function :FindNextChangeNotification, [:long], :int
|
42
31
|
|
43
|
-
#
|
32
|
+
# DAORD WaitForMultipleObjects(
|
44
33
|
# DWORD nCount, // number of handles in array
|
45
34
|
# CONST HANDLE *lpHandles, // object-handle array
|
46
35
|
# BOOL bWaitAll, // wait option
|
47
36
|
# DWORD dwMilliseconds // time-out interval
|
48
37
|
# );
|
49
|
-
|
50
|
-
Win32::API.new('WaitForMultipleObjects', ['L', 'P', 'I', 'L'], 'L')
|
51
|
-
|
52
|
-
def k32WaitForMultipleObjects(count, handles, wait_all, time)
|
53
|
-
@_k32WaitForMultipleObjects.call(count, handles, wait_all, time)
|
54
|
-
end
|
55
|
-
|
56
|
-
module_function "k32WaitForMultipleObjects"
|
38
|
+
attach_function :WaitForMultipleObjects, [:long, :pointer, :int, :long], :long
|
57
39
|
|
58
40
|
# BOOL FindCloseChangeNotification(
|
59
41
|
# HANDLE hChangeHandle
|
60
42
|
# );
|
61
|
-
|
62
|
-
Win32::API.new('FindCloseChangeNotification', ['L'], 'I')
|
63
|
-
|
64
|
-
def k32FindCloseChangeNotification(handle)
|
65
|
-
@_k32FindCloseChangeNotification.call(handle)
|
66
|
-
end
|
67
|
-
|
68
|
-
module_function "k32FindCloseChangeNotification"
|
43
|
+
attach_function :FindCloseChangeNotification, [:long], :int
|
69
44
|
end
|
70
45
|
end
|
data/lib/rb-fchange/notifier.rb
CHANGED
@@ -15,6 +15,13 @@ module FChange
|
|
15
15
|
# # Nothing happens until you run the notifier!
|
16
16
|
# notifier.run
|
17
17
|
class Notifier
|
18
|
+
|
19
|
+
#
|
20
|
+
INFINITE = 0xFFFFFFFF
|
21
|
+
|
22
|
+
#
|
23
|
+
WAIT_OBJECT_0 = 0x00000000
|
24
|
+
|
18
25
|
# A hash from {Watcher} ids to the instances themselves.
|
19
26
|
#
|
20
27
|
# @private
|
@@ -110,19 +117,19 @@ module FChange
|
|
110
117
|
def read_events
|
111
118
|
|
112
119
|
# can return WAIT_TIMEOUT = 0x00000102
|
113
|
-
dwWaitStatus = Native.
|
120
|
+
dwWaitStatus = Native.WaitForMultipleObjects(@dwChangeHandles.count,
|
114
121
|
@lp_dwChangeHandles, 0, 500)
|
115
122
|
|
116
123
|
events = []
|
117
124
|
|
118
125
|
# this call blocks all threads completely.
|
119
126
|
@dwChangeHandles.each_index do |index|
|
120
|
-
if dwWaitStatus ==
|
127
|
+
if dwWaitStatus == WAIT_OBJECT_0 + index
|
121
128
|
|
122
129
|
ev = Event.new(@watchers[@dwChangeHandles[index]])
|
123
130
|
events << ev
|
124
131
|
|
125
|
-
r = Native.
|
132
|
+
r = Native.FindNextChangeNotification(@dwChangeHandles[index])
|
126
133
|
if r == 0
|
127
134
|
raise SystemCallError.new("Failed to watch", r)
|
128
135
|
end
|
data/lib/rb-fchange/watcher.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
|
1
3
|
module FChange
|
2
4
|
# Watchers monitor a single path for changes,
|
3
5
|
# specified by {FChange::Notifier#watch event flags}.
|
@@ -50,12 +52,26 @@ module FChange
|
|
50
52
|
#
|
51
53
|
# @raise [SystemCallError] if the watch fails to be disabled for some reason
|
52
54
|
def close
|
53
|
-
r = Native.
|
55
|
+
r = Native.FindCloseChangeNotification(@id)
|
54
56
|
#@notifier.remove_watcher(self)
|
55
57
|
return if r == 0
|
56
58
|
raise SystemCallError.new("Failed to stop watching #{@path.inspect}", r)
|
57
59
|
end
|
58
60
|
|
61
|
+
# see http://msdn.microsoft.com/en-us/library/aa365247(v=vs.85).aspx
|
62
|
+
def normalize_path(path)
|
63
|
+
if(path.size > 256)
|
64
|
+
path = "\\\\?\\" + Pathname.new(path).realpath.to_s
|
65
|
+
end
|
66
|
+
# require 'rchardet'
|
67
|
+
# require 'iconv'
|
68
|
+
# cd = CharDet.detect(path)
|
69
|
+
# encoding = cd['encoding']
|
70
|
+
# converter = Iconv.new("UTF-16LE", encoding)
|
71
|
+
# converter.iconv(path)
|
72
|
+
# path.encode!("UTF-16LE")
|
73
|
+
end
|
74
|
+
|
59
75
|
# Creates a new {Watcher}.
|
60
76
|
#
|
61
77
|
# @private
|
@@ -65,9 +81,12 @@ module FChange
|
|
65
81
|
@callback = callback || proc {}
|
66
82
|
@path = path
|
67
83
|
@flags = flags
|
68
|
-
@recursive = recursive
|
69
|
-
|
84
|
+
@recursive = recursive ? 1 : 0
|
85
|
+
|
86
|
+
@id = Native.FindFirstChangeNotificationA(path, @recursive,
|
70
87
|
Native::Flags.to_mask(flags));
|
88
|
+
# @id = Native.FindFirstChangeNotificationW(normalize_path(path), @recursive,
|
89
|
+
# Native::Flags.to_mask(flags));
|
71
90
|
|
72
91
|
unless @id < 0
|
73
92
|
@notifier.add_watcher(self)
|
data/rb-fchange.gemspec
CHANGED
@@ -6,10 +6,10 @@ Gem::Specification.new do |s|
|
|
6
6
|
s.name = %q{rb-fchange}
|
7
7
|
s.version = FChange::VERSION
|
8
8
|
s.platform = Gem::Platform::RUBY
|
9
|
-
s.authors
|
10
|
-
s.date = %q{2011-
|
9
|
+
s.authors = ["stereobooster"]
|
10
|
+
s.date = %q{2011-05-15}
|
11
11
|
s.description = %q{A Ruby wrapper for Windows Kernel functions for monitoring the specified directory or subtree}
|
12
|
-
s.email =
|
12
|
+
s.email = ["stereobooster@gmail.com"]
|
13
13
|
s.extra_rdoc_files = [
|
14
14
|
"README.md"
|
15
15
|
]
|
@@ -28,5 +28,5 @@ Gem::Specification.new do |s|
|
|
28
28
|
s.require_paths = ["lib"]
|
29
29
|
s.rubygems_version = %q{1.3.7}
|
30
30
|
s.summary = %q{A Ruby wrapper for Windows Kernel functions for monitoring the specified directory or subtree}
|
31
|
-
s.add_dependency('
|
31
|
+
s.add_dependency('ffi')
|
32
32
|
end
|
metadata
CHANGED
@@ -1,48 +1,37 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: rb-fchange
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.4
|
5
5
|
prerelease:
|
6
|
-
segments:
|
7
|
-
- 0
|
8
|
-
- 0
|
9
|
-
- 2
|
10
|
-
version: 0.0.2
|
11
6
|
platform: ruby
|
12
|
-
authors:
|
7
|
+
authors:
|
13
8
|
- stereobooster
|
14
9
|
autorequire:
|
15
10
|
bindir: bin
|
16
11
|
cert_chain: []
|
17
|
-
|
18
|
-
date: 2011-04-28 00:00:00 +03:00
|
12
|
+
date: 2011-05-15 00:00:00.000000000 +03:00
|
19
13
|
default_executable:
|
20
|
-
dependencies:
|
21
|
-
- !ruby/object:Gem::Dependency
|
22
|
-
name:
|
23
|
-
|
24
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: ffi
|
17
|
+
requirement: &24277536 !ruby/object:Gem::Requirement
|
25
18
|
none: false
|
26
|
-
requirements:
|
27
|
-
- -
|
28
|
-
- !ruby/object:Gem::Version
|
29
|
-
|
30
|
-
segments:
|
31
|
-
- 1
|
32
|
-
- 4
|
33
|
-
- 8
|
34
|
-
version: 1.4.8
|
19
|
+
requirements:
|
20
|
+
- - ! '>='
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '0'
|
35
23
|
type: :runtime
|
36
|
-
|
37
|
-
|
38
|
-
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: *24277536
|
26
|
+
description: A Ruby wrapper for Windows Kernel functions for monitoring the specified
|
27
|
+
directory or subtree
|
28
|
+
email:
|
29
|
+
- stereobooster@gmail.com
|
39
30
|
executables: []
|
40
|
-
|
41
31
|
extensions: []
|
42
|
-
|
43
|
-
extra_rdoc_files:
|
32
|
+
extra_rdoc_files:
|
44
33
|
- README.md
|
45
|
-
files:
|
34
|
+
files:
|
46
35
|
- README.md
|
47
36
|
- Rakefile
|
48
37
|
- lib/rb-fchange.rb
|
@@ -55,36 +44,27 @@ files:
|
|
55
44
|
has_rdoc: true
|
56
45
|
homepage: http://github.com/stereobooster/rb-fchange
|
57
46
|
licenses: []
|
58
|
-
|
59
47
|
post_install_message:
|
60
48
|
rdoc_options: []
|
61
|
-
|
62
|
-
require_paths:
|
49
|
+
require_paths:
|
63
50
|
- lib
|
64
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
51
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
65
52
|
none: false
|
66
|
-
requirements:
|
67
|
-
- -
|
68
|
-
- !ruby/object:Gem::Version
|
69
|
-
|
70
|
-
|
71
|
-
- 0
|
72
|
-
version: "0"
|
73
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
53
|
+
requirements:
|
54
|
+
- - ! '>='
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: '0'
|
57
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
74
58
|
none: false
|
75
|
-
requirements:
|
76
|
-
- -
|
77
|
-
- !ruby/object:Gem::Version
|
78
|
-
|
79
|
-
segments:
|
80
|
-
- 0
|
81
|
-
version: "0"
|
59
|
+
requirements:
|
60
|
+
- - ! '>='
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '0'
|
82
63
|
requirements: []
|
83
|
-
|
84
64
|
rubyforge_project:
|
85
65
|
rubygems_version: 1.5.2
|
86
66
|
signing_key:
|
87
67
|
specification_version: 3
|
88
|
-
summary: A Ruby wrapper for Windows Kernel functions for monitoring the specified
|
68
|
+
summary: A Ruby wrapper for Windows Kernel functions for monitoring the specified
|
69
|
+
directory or subtree
|
89
70
|
test_files: []
|
90
|
-
|