recls-ruby 2.13.0.1 → 2.13.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9e34f60c35aebc4cf9cb1e217c1e7cf3e0211abee3eddb8e6306daa601c36461
4
- data.tar.gz: 888951b3419b4be2b453449a3f25b0ee725e78539449caf469c767bbc329fbd4
3
+ metadata.gz: 0da3b80a1f5ba1babc0fdfbd56abf30433e53d39f2996fe2661d0142ad4b386d
4
+ data.tar.gz: 47fca376aac5eb7559fe2b7e014b8a79d23bc828fcbd999b75ce133a52a4e255
5
5
  SHA512:
6
- metadata.gz: d0756416a3dc1d95aae37a46e7d3db1bbea1347e7b0cc369088910662698361dcedf718da31d818b976fc78b342766dd155c969fab8593f90e6c644e8cc44d04
7
- data.tar.gz: 85291a5a45c3b430f92fbed82f9033bc53d524fa67dde8fd40b6f85581032b625c0756e944ab57fb6a74c3b9f60e92264f05dd7cdd606f2e5ecd8f61b1cd774e
6
+ metadata.gz: b1c79afd72e02b47c8c9ce9291c08d1c825e96e5e66a826a36a004c08774b82e77aa5610edc0c986ebfa28b10c95f5baea75ed9bdfba12ac35a36a377fd7b747
7
+ data.tar.gz: dcdfee4db3cddd95879d7faf833def2daea1cdc8d91809981dfbbb3703dacc37ce77b4c1671b33dafb60d7ec446ffee6afe3a389b5de97d4063b157c5ace4b63
data/lib/recls/version.rb CHANGED
@@ -4,7 +4,7 @@
4
4
  # Purpose: Version for recls library
5
5
  #
6
6
  # Created: 14th February 2014
7
- # Updated: 21st April 2024
7
+ # Updated: 2nd April 2024
8
8
  #
9
9
  # Author: Matthew Wilson
10
10
  #
@@ -43,7 +43,7 @@
43
43
  module Recls
44
44
 
45
45
  # Current version of the recls.Ruby library
46
- VERSION = '2.13.0.1'
46
+ VERSION = '2.13.1'
47
47
 
48
48
  private
49
49
  # @!visibility private
@@ -4,7 +4,7 @@
4
4
  # Purpose: Windows-specific constructs for the recls library.
5
5
  #
6
6
  # Created: 19th February 2014
7
- # Updated: 21st April 2024
7
+ # Updated: 2nd June 2024
8
8
  #
9
9
  # Author: Matthew Wilson
10
10
  #
@@ -37,7 +37,14 @@
37
37
  # ######################################################################## #
38
38
 
39
39
 
40
- require 'Win32API'
40
+ if RUBY_VERSION >= '2'
41
+
42
+ require 'fiddle'
43
+ require 'fiddle/import'
44
+ else
45
+
46
+ require 'Win32API'
47
+ end
41
48
 
42
49
 
43
50
  =begin
@@ -49,46 +56,136 @@ module Recls
49
56
  module Ximpl # :nodoc: all
50
57
 
51
58
  # @!visibility private
52
- class FileStat < File::Stat # :nodoc:
59
+ module Kernel32
60
+
61
+ MAX_PATH = 260
62
+ NULL = 0x00000000
63
+ OPEN_EXISTING = 0x00000003
64
+ end # module Kernel32
65
+
66
+ if RUBY_VERSION >= '2'
67
+
68
+ module Kernel32
69
+ extend Fiddle::Importer
70
+
71
+ dlload 'kernel32.dll'
72
+
73
+ typealias 'BOOL', 'int'
74
+ typealias 'DWORD', 'unsigned long'
75
+ typealias 'HANDLE', 'void*'
76
+
77
+ BY_HANDLE_FILE_INFORMATION = struct [
78
+ 'DWORD dwFileAttributes',
79
+ 'DWORD ftCreationTime_0',
80
+ 'DWORD ftCreationTime_1',
81
+ 'DWORD ftLastAccessTime_0',
82
+ 'DWORD ftLastAccessTime_1',
83
+ 'DWORD ftLastWriteTime_0',
84
+ 'DWORD ftLastWriteTime_1',
85
+ 'DWORD dwVolumeSerialNumber',
86
+ 'DWORD nFileSizeHigh',
87
+ 'DWORD nFileSizeLow',
88
+ 'DWORD nNumberOfLinks',
89
+ 'DWORD nFileIndexHigh',
90
+ 'DWORD nFileIndexLow',
91
+ ]
92
+
93
+ extern 'BOOL CloseHandle(HANDLE)'
94
+ extern 'HANDLE CreateFileA(const char*, DWORD, DWORD, void*, DWORD, DWORD, HANDLE)'
95
+ extern 'DWORD GetFileAttributesA(const char*)'
96
+ extern 'BOOL GetFileInformationByHandle(HANDLE, BY_HANDLE_FILE_INFORMATION*)'
97
+ extern 'DWORD GetShortPathNameA(const char*, char*, DWORD)'
98
+
99
+ INVALID_HANDLE_VALUE = Fiddle::Pointer[-1]
100
+ end # module Kernel32
101
+
102
+ module Kernel32
103
+ def self.get_file_attributes(path)
104
+
105
+ attributes = GetFileAttributesA(path)
106
+
107
+ (0xFFFFFFFF == attributes) ? 0 : attributes
108
+ end
53
109
 
54
- private
55
- GetFileAttributes = Win32API.new('kernel32', 'GetFileAttributes', [ 'P' ], 'I')
56
- GetFileInformationByHandle = Win32API.new('kernel32', 'GetFileInformationByHandle', [ 'L', 'P' ], 'I')
57
- GetShortPathName = Win32API.new('kernel32', 'GetShortPathName', [ 'P', 'P', 'L' ], 'L')
58
- CreateFile = Win32API.new('kernel32', 'CreateFile', [ 'P', 'L', 'L', 'L', 'L', 'L', 'L' ], 'L')
59
- CloseHandle = Win32API.new('kernel32', 'CloseHandle', [ 'L' ], 'L')
60
- FILE_ATTRIBUTE_READONLY = 0x00000001
61
- FILE_ATTRIBUTE_HIDDEN = 0x00000002
62
- FILE_ATTRIBUTE_SYSTEM = 0x00000004
63
- FILE_ATTRIBUTE_DIRECTORY = 0x00000010
64
- FILE_ATTRIBUTE_ARCHIVE = 0x00000020
65
- FILE_ATTRIBUTE_DEVICE = 0x00000040
66
- FILE_ATTRIBUTE_NORMAL = 0x00000080
67
- FILE_ATTRIBUTE_TEMPORARY = 0x00000100
68
- FILE_ATTRIBUTE_COMPRESSED = 0x00000800
69
- FILE_ATTRIBUTE_ENCRYPTED = 0x00004000
110
+ def self.get_short_path_name(path)
70
111
 
71
- OPEN_EXISTING = 0x00000003
72
- FILE_FLAG_OVERLAPPED = 0x40000000
73
- NULL = 0x00000000
74
- INVALID_HANDLE_VALUE = 0xFFFFFFFF
112
+ buff = ' ' * MAX_PATH
75
113
 
76
- MAX_PATH = 260
114
+ buf = Fiddle::Pointer[buff]
77
115
 
78
- BHFI_pack_string = 'LQQQLLLLLL'
116
+ n = GetShortPathNameA(path, buf, buf.size)
79
117
 
80
- # @!visibility private
81
- class ByHandleInformation # :nodoc:
118
+ (0 == n) ? nil : buff[0...n]
119
+ end
82
120
 
83
- # @!visibility private
84
- def initialize(path) # :nodoc:
121
+ def self.get_stat_shared(path)
122
+
123
+ volume_id = 0
124
+ file_index = 0
125
+ num_links = 0
85
126
 
86
- @volume_id = 0
87
- @file_index = 0
88
- @num_links = 0
127
+ hFile = CreateFileA(path, 0, 0, NULL, OPEN_EXISTING, 0, NULL)
128
+
129
+ if INVALID_HANDLE_VALUE != hFile
130
+
131
+ begin
132
+ bhfi = BY_HANDLE_FILE_INFORMATION.malloc
133
+
134
+ if GetFileInformationByHandle(hFile, bhfi)
135
+
136
+ volume_id = bhfi.dwVolumeSerialNumber
137
+ file_index = (bhfi.nFileIndexHigh << 32) | bhfi.nFileIndexLow
138
+ num_links = bhfi.nNumberOfLinks
139
+ end
140
+ ensure
141
+
142
+ CloseHandle(hFile)
143
+ end
144
+ end
145
+
146
+ [ volume_id, file_index, num_links ]
147
+ end
148
+ end # module Kernel32
149
+ else
150
+
151
+ module Kernel32
152
+
153
+ CloseHandle = Win32API.new('kernel32', 'CloseHandle', [ 'L' ], 'L')
154
+ CreateFile = Win32API.new('kernel32', 'CreateFile', [ 'P', 'L', 'L', 'L', 'L', 'L', 'L' ], 'L')
155
+ GetFileAttributes = Win32API.new('kernel32', 'GetFileAttributes', [ 'P' ], 'I')
156
+ GetFileInformationByHandle = Win32API.new('kernel32', 'GetFileInformationByHandle', [ 'L', 'P' ], 'I')
157
+ GetShortPathName = Win32API.new('kernel32', 'GetShortPathName', [ 'P', 'P', 'L' ], 'L')
158
+
159
+ INVALID_HANDLE_VALUE = -1
160
+
161
+ BHFI_pack_string = 'LQQQLLLLLL'
162
+ end # module Kernel32
163
+
164
+ module Kernel32
165
+ def self.get_file_attributes(path)
166
+
167
+ attributes = GetFileAttributes.call(path)
168
+
169
+ (0xFFFFFFFF == attributes) ? 0 : attributes
170
+ end
171
+
172
+ def self.get_short_path_name(path)
173
+
174
+ buff = ' ' * MAX_PATH
175
+
176
+ n = GetShortPathName.call(path, buff, buff.length)
177
+
178
+ (0 == n) ? nil : buff[0...n]
179
+ end
180
+
181
+ def self.get_stat_shared(path)
182
+
183
+ volume_id = 0
184
+ file_index = 0
185
+ num_links = 0
186
+
187
+ hFile = CreateFile.call(path, 0, 0, NULL, OPEN_EXISTING, 0, NULL)
89
188
 
90
- # for some reason not forcing this new string causes 'can't modify frozen string (TypeError)' (in Ruby 1.8.x)
91
- hFile = CreateFile.call("#{path}", 0, 0, NULL, OPEN_EXISTING, 0, NULL);
92
189
  if INVALID_HANDLE_VALUE != hFile
93
190
 
94
191
  begin
@@ -99,15 +196,43 @@ module Recls
99
196
 
100
197
  bhfi = bhfi.unpack(BHFI_pack_string)
101
198
 
102
- @volume_id = bhfi[4]
103
- @file_index = (bhfi[8] << 32) | bhfi[9]
104
- @num_links = bhfi[7]
105
- else
199
+ volume_id = bhfi[4]
200
+ file_index = (bhfi[8] << 32) | bhfi[9]
201
+ num_links = bhfi[7]
106
202
  end
107
203
  ensure
204
+
108
205
  CloseHandle.call(hFile)
109
206
  end
110
207
  end
208
+
209
+ [ volume_id, file_index, num_links ]
210
+ end
211
+ end # module Kernel32
212
+ end
213
+
214
+ # @!visibility private
215
+ class FileStat < File::Stat # :nodoc:
216
+
217
+ private
218
+ FILE_ATTRIBUTE_READONLY = 0x00000001
219
+ FILE_ATTRIBUTE_HIDDEN = 0x00000002
220
+ FILE_ATTRIBUTE_SYSTEM = 0x00000004
221
+ FILE_ATTRIBUTE_DIRECTORY = 0x00000010
222
+ FILE_ATTRIBUTE_ARCHIVE = 0x00000020
223
+ FILE_ATTRIBUTE_DEVICE = 0x00000040
224
+ FILE_ATTRIBUTE_NORMAL = 0x00000080
225
+ FILE_ATTRIBUTE_TEMPORARY = 0x00000100
226
+ FILE_ATTRIBUTE_COMPRESSED = 0x00000800
227
+ FILE_ATTRIBUTE_ENCRYPTED = 0x00004000
228
+
229
+ # @!visibility private
230
+ class ByHandleInformation # :nodoc:
231
+
232
+ # @!visibility private
233
+ def initialize(path) # :nodoc:
234
+
235
+ @volume_id, @file_index, @num_links = Kernel32.get_stat_shared(path)
111
236
  end
112
237
 
113
238
  # @!visibility private
@@ -129,27 +254,18 @@ module Recls
129
254
  # @!visibility private
130
255
  def initialize(path) # :nodoc:
131
256
 
132
- @path = path
133
-
134
- # for some reason not forcing this new string causes 'can't modify frozen string (TypeError)'
135
- attributes = GetFileAttributes.call("#{path}")
257
+ path = path.to_str
136
258
 
137
- if 0xffffffff == attributes
259
+ @path = path
138
260
 
139
- @attributes = 0
140
- else
141
-
142
- @attributes = attributes
143
- end
261
+ @attributes = Kernel32.get_file_attributes(path)
144
262
 
145
263
  super(path)
146
264
 
147
265
  @by_handle_information = ByHandleInformation.new(path)
148
266
 
149
- buff = ' ' * MAX_PATH
150
- # not forcing this new string causes 'can't modify frozen string (TypeError)'
151
- n = GetShortPathName.call("#{path}", buff, buff.length)
152
- @short_path = (0 == n) ? nil : buff[0...n]
267
+ @short_path = Kernel32.get_short_path_name(path)
268
+
153
269
  end
154
270
 
155
271
  public
@@ -165,7 +281,7 @@ module Recls
165
281
  # @!visibility private
166
282
  def hidden? # :nodoc:
167
283
 
168
- 0 != (FILE_ATTRIBUTE_HIDDEN & @attributes)
284
+ has_attribute_? FILE_ATTRIBUTE_HIDDEN
169
285
  end
170
286
 
171
287
  # Windows-specific attributes
@@ -215,7 +331,7 @@ module Recls
215
331
 
216
332
  public
217
333
  # @!visibility private
218
- def FileStat.stat(path) # :nodoc:
334
+ def self.stat(path) # :nodoc:
219
335
 
220
336
  Recls::Ximpl::FileStat.new(path)
221
337
  end
@@ -19,7 +19,7 @@ class Test_Recls_entry < Test::Unit::TestCase
19
19
 
20
20
  def setup
21
21
 
22
- @cwd = Dir.pwd
22
+ @cwd = Dir.pwd.freeze
23
23
  end
24
24
 
25
25
  def test_entry_does_not_mark_directory
@@ -51,5 +51,22 @@ class Test_Recls_entry < Test::Unit::TestCase
51
51
 
52
52
  assert_not_equal cwd.object_id, cwd2.object_id
53
53
  end
54
+
55
+ if Recls.windows?
56
+
57
+ def test_entry_file_short_name
58
+
59
+ cwd = Recls.stat @cwd
60
+
61
+ if cwd.file_short_name
62
+
63
+ if cwd.file_full_name != cwd.file_short_name
64
+
65
+ assert cwd.file_short_name =~ /^.{0,8}\..{0,3}$/, "'#{cwd.file_short_name}' does not match expected 8.3 form"
66
+ assert_equal cwd.file_short_name.upcase, cwd.file_short_name, "'#{cwd.file_short_name}' is not uppercase as expected"
67
+ end
68
+ end
69
+ end
70
+ end
54
71
  end
55
72
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: recls-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.13.0.1
4
+ version: 2.13.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matt Wilson
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-04-21 00:00:00.000000000 Z
11
+ date: 2024-06-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: xqsr3
@@ -26,7 +26,7 @@ dependencies:
26
26
  version: '0.31'
27
27
  description: 'RECursive LS for Ruby
28
28
 
29
- '
29
+ '
30
30
  email: matthew@synesis.com.au
31
31
  executables: []
32
32
  extensions: []
@@ -83,7 +83,7 @@ homepage: http://github.com/synesissoftware/recls.Ruby
83
83
  licenses:
84
84
  - BSD-3-Clause
85
85
  metadata: {}
86
- post_install_message:
86
+ post_install_message:
87
87
  rdoc_options: []
88
88
  require_paths:
89
89
  - lib
@@ -98,8 +98,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
98
98
  - !ruby/object:Gem::Version
99
99
  version: '0'
100
100
  requirements: []
101
- rubygems_version: 3.0.3.1
102
- signing_key:
101
+ rubygems_version: 3.3.7
102
+ signing_key:
103
103
  specification_version: 4
104
104
  summary: recls.Ruby
105
105
  test_files: []