author | ca |
Thu, 18 Dec 2008 17:16:20 +0100 | |
changeset 2078 | a196d0ebe6fc |
parent 2074 | 8a4ffdd9fddc |
child 2079 | 1e481f917bfb |
permissions | -rw-r--r-- |
583 | 1 |
" |
2 |
COPYRIGHT (c) 1997 by eXept Software AG |
|
3 |
All Rights Reserved |
|
4 |
||
5 |
This software is furnished under a license and may be used |
|
6 |
only in accordance with the terms of that license and with the |
|
7 |
inclusion of the above copyright notice. This software may not |
|
8 |
be provided or otherwise made available to, or used by, any |
|
9 |
other person. No title to or ownership of the software is |
|
10 |
hereby transferred. |
|
11 |
" |
|
904 | 12 |
"{ Package: 'stx:libbasic2' }" |
13 |
||
583 | 14 |
Object subclass:#DirectoryContents |
2078 | 15 |
instanceVariableNames:'directory timeStamp contents isReadable isRootDirectory' |
957 | 16 |
classVariableNames:'CachedDirectories LockSema ReadersList' |
583 | 17 |
poolDictionaries:'' |
18 |
category:'System-Support' |
|
19 |
! |
|
20 |
||
1093 | 21 |
Object subclass:#DirectoryContentsItem |
1099 | 22 |
instanceVariableNames:'info fileName' |
1431
049b89c5bf60
cache mountPoints; faster directoryRead & sort
Claus Gittinger <cg@exept.de>
parents:
1393
diff
changeset
|
23 |
classVariableNames:'CachedRemoteMountPoints CachedRemoteMountPointsTimeStamp' |
1093 | 24 |
poolDictionaries:'' |
25 |
privateIn:DirectoryContents |
|
26 |
! |
|
27 |
||
583 | 28 |
!DirectoryContents class methodsFor:'documentation'! |
29 |
||
30 |
copyright |
|
31 |
" |
|
32 |
COPYRIGHT (c) 1997 by eXept Software AG |
|
33 |
All Rights Reserved |
|
34 |
||
35 |
This software is furnished under a license and may be used |
|
36 |
only in accordance with the terms of that license and with the |
|
37 |
inclusion of the above copyright notice. This software may not |
|
38 |
be provided or otherwise made available to, or used by, any |
|
39 |
other person. No title to or ownership of the software is |
|
40 |
hereby transferred. |
|
41 |
" |
|
42 |
||
43 |
||
44 |
! |
|
45 |
||
46 |
documentation |
|
47 |
" |
|
48 |
DirectoryContents provides a cached view onto a fileDirectory. |
|
49 |
||
50 |
||
51 |
Notice: |
|
52 |
This class is not available in other ST-systems; |
|
53 |
Applications using it may not be portable. |
|
54 |
||
55 |
[author:] |
|
56 |
Claus Atzkern |
|
57 |
||
58 |
[see also:] |
|
59 |
Filename |
|
60 |
FileStream DirectoryStream OperatingSystem |
|
61 |
" |
|
62 |
||
63 |
! ! |
|
64 |
||
957 | 65 |
!DirectoryContents class methodsFor:'initialization'! |
66 |
||
67 |
initialize |
|
68 |
"setup lock-mechanism |
|
69 |
" |
|
70 |
LockSema := RecursionLock new. |
|
71 |
ReadersList := Dictionary new. |
|
72 |
! ! |
|
73 |
||
1093 | 74 |
!DirectoryContents class methodsFor:'instance creation'! |
75 |
||
76 |
new |
|
77 |
^ self basicNew initialize |
|
78 |
! ! |
|
79 |
||
583 | 80 |
!DirectoryContents class methodsFor:'accessing'! |
81 |
||
957 | 82 |
directoryNamed:aDirectory |
583 | 83 |
"returns the DirectoryContents for a directory named |
957 | 84 |
aDirectoryName, aString, nil or Filename |
583 | 85 |
" |
957 | 86 |
|directory contents max lockRead pathName addToList| |
583 | 87 |
|
2078 | 88 |
aDirectory isNil ifTrue:[^ nil]. |
89 |
||
90 |
directory := aDirectory asFilename. |
|
91 |
directory exists ifFalse:[ ^ nil ]. |
|
92 |
||
1105 | 93 |
directory := directory asAbsoluteFilename. |
957 | 94 |
contents := nil. |
620 | 95 |
|
957 | 96 |
LockSema critical:[ |
97 |
CachedDirectories notNil ifTrue:[ |
|
98 |
contents := self directoryAt:directory. |
|
99 |
||
100 |
contents isNil ifTrue:[ |
|
2078 | 101 |
CachedDirectories := CachedDirectories select:[:aDir| aDir isObsolete not ]. |
102 |
||
957 | 103 |
max := self maxCachedDirectories. |
583 | 104 |
|
957 | 105 |
CachedDirectories size > max ifTrue:[ |
2078 | 106 |
CachedDirectories select:[:aDir| aDir size > 64 ]. |
107 |
||
108 |
[ CachedDirectories size > max ] whileTrue:[ |
|
109 |
CachedDirectories removeFirst |
|
110 |
]. |
|
957 | 111 |
]. |
112 |
]. |
|
583 | 113 |
]. |
2078 | 114 |
|
957 | 115 |
contents isNil ifTrue:[ |
116 |
ReadersList isNil ifTrue:[ReadersList := Dictionary new]. |
|
117 |
pathName := directory pathName. |
|
118 |
lockRead := ReadersList at:pathName ifAbsentPut:[Semaphore forMutualExclusion]. |
|
119 |
] |
|
120 |
]. |
|
121 |
contents notNil ifTrue:[^ contents]. |
|
122 |
addToList := false. |
|
583 | 123 |
|
957 | 124 |
lockRead critical:[ |
1431
049b89c5bf60
cache mountPoints; faster directoryRead & sort
Claus Gittinger <cg@exept.de>
parents:
1393
diff
changeset
|
125 |
[ "/ test whether another task got the semaphore and |
957 | 126 |
"/ has read the directory contents |
127 |
(contents := self directoryAt:directory) isNil ifTrue:[ |
|
128 |
"/ read the directory contents |
|
129 |
contents := self new directory:directory. |
|
130 |
"/ only cache if the mod'Time is valid. |
|
131 |
addToList := contents timeStamp notNil. |
|
132 |
] |
|
1022
6a288db5312a
#valueNowOrOnUnwindDo: -> #ensure:
Claus Gittinger <cg@exept.de>
parents:
974
diff
changeset
|
133 |
] ensure:[ |
957 | 134 |
LockSema critical:[ |
135 |
addToList ifTrue:[ |
|
136 |
CachedDirectories isNil ifTrue:[ |
|
137 |
CachedDirectories := OrderedCollection new |
|
138 |
]. |
|
139 |
CachedDirectories add:contents |
|
140 |
]. |
|
141 |
(lockRead isEmpty and:[ReadersList notNil]) ifTrue:[ |
|
142 |
ReadersList removeKey:pathName ifAbsent:nil |
|
143 |
] |
|
583 | 144 |
] |
145 |
] |
|
957 | 146 |
]. |
620 | 147 |
|
957 | 148 |
^ contents |
583 | 149 |
! ! |
150 |
||
616
cb0377b446bd
flush cachedDirectory list when saving a snapshot
Claus Gittinger <cg@exept.de>
parents:
583
diff
changeset
|
151 |
!DirectoryContents class methodsFor:'cache flushing'! |
cb0377b446bd
flush cachedDirectory list when saving a snapshot
Claus Gittinger <cg@exept.de>
parents:
583
diff
changeset
|
152 |
|
880 | 153 |
flushCache |
154 |
"flush list of rememebred directory contents" |
|
155 |
||
957 | 156 |
LockSema critical:[ CachedDirectories := nil ]. |
880 | 157 |
|
158 |
" |
|
159 |
self flushCache |
|
160 |
" |
|
161 |
||
162 |
"Created: / 11.2.2000 / 00:13:59 / cg" |
|
163 |
! |
|
164 |
||
1105 | 165 |
flushCachedDirectoryFor:aDirectoryOrString |
958 | 166 |
"remove directory from cache |
167 |
" |
|
2078 | 168 |
|directory contents| |
958 | 169 |
|
2078 | 170 |
aDirectoryOrString isNil ifTrue:[^ self ]. |
958 | 171 |
|
2078 | 172 |
directory := aDirectoryOrString asFilename. |
173 |
directory isSymbolicLink ifTrue:[^ self]. |
|
958 | 174 |
|
2078 | 175 |
contents := self directoryAt:directory. |
176 |
||
177 |
contents notNil ifTrue:[ |
|
178 |
contents itemsDo:[:each| each resetAttributes ]. |
|
958 | 179 |
]. |
180 |
! |
|
181 |
||
695
368ddb719976
only cache dir if its mod'time is known (for win32)
Claus Gittinger <cg@exept.de>
parents:
679
diff
changeset
|
182 |
lowSpaceCleanup |
1575 | 183 |
"flush list of remembered directory contents when low on memory" |
695
368ddb719976
only cache dir if its mod'time is known (for win32)
Claus Gittinger <cg@exept.de>
parents:
679
diff
changeset
|
184 |
|
1134 | 185 |
self flushCache |
695
368ddb719976
only cache dir if its mod'time is known (for win32)
Claus Gittinger <cg@exept.de>
parents:
679
diff
changeset
|
186 |
|
368ddb719976
only cache dir if its mod'time is known (for win32)
Claus Gittinger <cg@exept.de>
parents:
679
diff
changeset
|
187 |
" |
368ddb719976
only cache dir if its mod'time is known (for win32)
Claus Gittinger <cg@exept.de>
parents:
679
diff
changeset
|
188 |
self lowSpaceCleanup |
368ddb719976
only cache dir if its mod'time is known (for win32)
Claus Gittinger <cg@exept.de>
parents:
679
diff
changeset
|
189 |
" |
368ddb719976
only cache dir if its mod'time is known (for win32)
Claus Gittinger <cg@exept.de>
parents:
679
diff
changeset
|
190 |
|
368ddb719976
only cache dir if its mod'time is known (for win32)
Claus Gittinger <cg@exept.de>
parents:
679
diff
changeset
|
191 |
"Created: / 18.2.1998 / 18:17:05 / cg" |
368ddb719976
only cache dir if its mod'time is known (for win32)
Claus Gittinger <cg@exept.de>
parents:
679
diff
changeset
|
192 |
"Modified: / 24.9.1998 / 17:51:15 / cg" |
368ddb719976
only cache dir if its mod'time is known (for win32)
Claus Gittinger <cg@exept.de>
parents:
679
diff
changeset
|
193 |
! |
368ddb719976
only cache dir if its mod'time is known (for win32)
Claus Gittinger <cg@exept.de>
parents:
679
diff
changeset
|
194 |
|
616
cb0377b446bd
flush cachedDirectory list when saving a snapshot
Claus Gittinger <cg@exept.de>
parents:
583
diff
changeset
|
195 |
preSnapshot |
1919 | 196 |
"flush list of cached directory contents before saving a snapshot" |
616
cb0377b446bd
flush cachedDirectory list when saving a snapshot
Claus Gittinger <cg@exept.de>
parents:
583
diff
changeset
|
197 |
|
1349 | 198 |
self flushCache. |
616
cb0377b446bd
flush cachedDirectory list when saving a snapshot
Claus Gittinger <cg@exept.de>
parents:
583
diff
changeset
|
199 |
! ! |
cb0377b446bd
flush cachedDirectory list when saving a snapshot
Claus Gittinger <cg@exept.de>
parents:
583
diff
changeset
|
200 |
|
583 | 201 |
!DirectoryContents class methodsFor:'constants'! |
202 |
||
203 |
maxCachedDirectories |
|
204 |
"returns number of maximum cached directories |
|
205 |
" |
|
616
cb0377b446bd
flush cachedDirectory list when saving a snapshot
Claus Gittinger <cg@exept.de>
parents:
583
diff
changeset
|
206 |
^ 20 |
cb0377b446bd
flush cachedDirectory list when saving a snapshot
Claus Gittinger <cg@exept.de>
parents:
583
diff
changeset
|
207 |
|
cb0377b446bd
flush cachedDirectory list when saving a snapshot
Claus Gittinger <cg@exept.de>
parents:
583
diff
changeset
|
208 |
"Modified: / 25.2.1998 / 19:56:24 / cg" |
583 | 209 |
! ! |
210 |
||
211 |
!DirectoryContents class methodsFor:'private'! |
|
212 |
||
2078 | 213 |
directoryAt:aFileOrString |
583 | 214 |
"checks whether directory already exists and is valid. |
215 |
If true the directory is returned otherwise nil |
|
216 |
" |
|
2078 | 217 |
|index directory filename nm| |
218 |
||
219 |
aFileOrString isNil ifTrue:[^ nil ]. |
|
220 |
||
221 |
aFileOrString isFilename ifTrue:[ nm := aFileOrString nameString ] |
|
222 |
ifFalse:[ nm := aFileOrString ]. |
|
583 | 223 |
|
2078 | 224 |
"/ fast check before calling asAbsoluteFilename |
225 |
"/ remove last separator from nameString |
|
226 |
||
227 |
(nm size > 1 and:[(nm last == $/ or:[nm last == $\])]) ifTrue:[ |
|
228 |
filename := (nm copyWithoutLast:1) asFilename. |
|
229 |
] ifFalse:[ |
|
230 |
filename := aFileOrString asFilename. |
|
231 |
]. |
|
957 | 232 |
directory := nil. |
233 |
||
234 |
LockSema critical:[ |
|
235 |
CachedDirectories notNil ifTrue:[ |
|
2078 | 236 |
index := CachedDirectories findFirst:[:d| d directory = filename ]. |
237 |
index == 0 ifTrue:[ |
|
238 |
filename := filename asAbsoluteFilename. |
|
239 |
index := CachedDirectories findFirst:[:d| d directory = filename ]. |
|
240 |
]. |
|
583 | 241 |
|
957 | 242 |
index ~~ 0 ifTrue:[ |
2078 | 243 |
directory := CachedDirectories removeAtIndex:index. |
583 | 244 |
|
957 | 245 |
directory isObsolete ifTrue:[ |
246 |
directory := nil. |
|
2078 | 247 |
] ifFalse:[ |
248 |
"/ keep the last accessed directory at end |
|
249 |
CachedDirectories add:directory. |
|
250 |
]. |
|
957 | 251 |
] |
583 | 252 |
] |
253 |
]. |
|
957 | 254 |
^ directory |
583 | 255 |
! ! |
256 |
||
257 |
!DirectoryContents class methodsFor:'queries'! |
|
258 |
||
259 |
directoryNamed:aDirectoryName detect:aTwoArgBlock |
|
260 |
"evaluate the block, [:filename :isDirectory] on the directory |
|
261 |
contents of a directory named aDirectoryName, until the block |
|
262 |
returns true. If nothing detected false is returned |
|
263 |
" |
|
2078 | 264 |
^ self directoryNamed:aDirectoryName detect:aTwoArgBlock onOpenErrorDo:nil |
265 |
! |
|
266 |
||
267 |
directoryNamed:aDirectoryName detect:aTwoArgBlock onOpenErrorDo:exceptionBlock |
|
268 |
"evaluate the block, [:filename :isDirectory] on the directory |
|
269 |
contents of a directory named aDirectoryName, until the block |
|
270 |
returns true. If nothing detected false is returned. |
|
271 |
||
272 |
if the directory cannot be open, the exceptionBlock is processed |
|
273 |
with the filename. |
|
274 |
" |
|
275 |
|directory contents isReadable file| |
|
583 | 276 |
|
277 |
directory := aDirectoryName asFilename. |
|
2078 | 278 |
contents := self directoryAt:directory. |
620 | 279 |
|
2078 | 280 |
contents notNil ifTrue:[ |
281 |
(isReadable := contents isReadable) ifTrue:[ |
|
282 |
contents contentsDo:[:aFile :isDir| |
|
283 |
(aTwoArgBlock value:aFile value:isDir) ifTrue:[^ true] |
|
284 |
]. |
|
285 |
^ false. |
|
1155
edcf3cfe1e93
Handle openErrorSignal in preparition for change openErrorSignal
Stefan Vogel <sv@exept.de>
parents:
1147
diff
changeset
|
286 |
]. |
2078 | 287 |
] ifFalse:[ |
288 |
(isReadable := directory exists) ifTrue:[ |
|
289 |
[ |
|
290 |
directory directoryContentsDo:[:fn | |
|
291 |
file := directory construct:fn. |
|
292 |
(aTwoArgBlock value:file value:(file isDirectory)) ifTrue:[ |
|
293 |
^ true |
|
294 |
] |
|
295 |
]. |
|
296 |
] on:FileStream openErrorSignal do:[:ex| |
|
297 |
isReadable := false. |
|
298 |
]. |
|
299 |
]. |
|
583 | 300 |
]. |
2078 | 301 |
(isReadable not and:[exceptionBlock notNil]) ifTrue:[ |
302 |
exceptionBlock value:directory. |
|
303 |
]. |
|
583 | 304 |
^ false |
305 |
! ! |
|
306 |
||
1102 | 307 |
!DirectoryContents class methodsFor:'utilities'! |
308 |
||
309 |
contentsItemForFileName:aFilenameOrString |
|
310 |
| aFilename directory directoryContents| |
|
311 |
||
312 |
aFilename := aFilenameOrString asFilename. |
|
313 |
directory := aFilename directory. |
|
2078 | 314 |
|
315 |
directoryContents := self directoryAt:directory. |
|
316 |
||
317 |
directoryContents notNil ifTrue:[ |
|
318 |
directoryContents itemsDo:[:fileItemThere | |
|
319 |
fileItemThere fileName = aFilename ifTrue:[ |
|
320 |
^ fileItemThere. |
|
321 |
]. |
|
1393
bb7048aaf86a
care for directory without parent (network-dirs on WIN32)
Claus Gittinger <cg@exept.de>
parents:
1352
diff
changeset
|
322 |
]. |
bb7048aaf86a
care for directory without parent (network-dirs on WIN32)
Claus Gittinger <cg@exept.de>
parents:
1352
diff
changeset
|
323 |
]. |
1252
933afe6d5bd6
care for directory being removed
Claus Gittinger <cg@exept.de>
parents:
1198
diff
changeset
|
324 |
|
2078 | 325 |
aFilename exists ifFalse:[ |
326 |
directoryContents notNil ifTrue:[ directoryContents beObsolete ]. |
|
327 |
^ nil |
|
1102 | 328 |
]. |
1105 | 329 |
^ (DirectoryContentsItem new fileName:aFilename) info:aFilename info. |
1102 | 330 |
! ! |
331 |
||
583 | 332 |
!DirectoryContents methodsFor:'accessing'! |
333 |
||
334 |
directory |
|
335 |
"returns the directoy name as Filename |
|
336 |
" |
|
337 |
^ directory |
|
338 |
! |
|
339 |
||
340 |
modificationTime |
|
341 |
"get the last modification time of the directory |
|
342 |
" |
|
2078 | 343 |
|modifyTime| |
344 |
||
2071 | 345 |
timeStamp isNil ifTrue:[^ nil ]. |
346 |
||
2078 | 347 |
isRootDirectory ifTrue:[ |
348 |
directory exists ifTrue:[^ timeStamp ]. |
|
349 |
] ifFalse:[ |
|
350 |
modifyTime := directory modificationTime. |
|
351 |
modifyTime notNil ifTrue:[^ modifyTime ]. |
|
2071 | 352 |
]. |
2078 | 353 |
isReadable := false. |
354 |
self beObsolete. |
|
355 |
^ nil |
|
951 | 356 |
! |
357 |
||
358 |
timeStamp |
|
359 |
"get the last timeStamp (when the directory info was read) of the directory |
|
360 |
" |
|
583 | 361 |
^ timeStamp |
362 |
! ! |
|
363 |
||
364 |
!DirectoryContents methodsFor:'enumerating'! |
|
365 |
||
366 |
contentsAndBaseNamesDo:aThreeArgBlock |
|
367 |
"evaluate the block on each file; the argument to the block is the |
|
368 |
filename, the baseName and true in case of a directory |
|
369 |
block arguments: [:fileName :aBaseName :isDirectory| |
|
370 |
" |
|
1350 | 371 |
|
1093 | 372 |
self itemsDo:[:eachItem | |
373 |
aThreeArgBlock |
|
374 |
value:(eachItem fileName) |
|
375 |
value:(eachItem baseName ) |
|
376 |
value:(eachItem isDirectory) |
|
583 | 377 |
]. |
378 |
! |
|
379 |
||
380 |
contentsDo:aTwoArgBlock |
|
381 |
"evaluate the block on each file; the argument to the block is the |
|
382 |
filename and true in case of a directory |
|
383 |
block arguments: [:fileName :isDirectory| |
|
384 |
" |
|
1350 | 385 |
|
1093 | 386 |
self itemsDo:[:eachItem | |
387 |
aTwoArgBlock |
|
388 |
value:(eachItem fileName) |
|
389 |
value:(eachItem isDirectory) |
|
583 | 390 |
]. |
391 |
! |
|
392 |
||
393 |
directoriesAndBasenamesDo:aTwoArgBlock |
|
394 |
"evaluate block on each directory; a Filename and Basename. |
|
395 |
The directories are sorted |
|
396 |
" |
|
1350 | 397 |
|
1093 | 398 |
self itemsDo:[:eachItem | |
399 |
eachItem isDirectory ifTrue:[ |
|
400 |
aTwoArgBlock value:(eachItem fileName) value:(eachItem baseName) |
|
583 | 401 |
] |
402 |
] |
|
403 |
! |
|
404 |
||
405 |
directoriesDo:aOneArgBlock |
|
406 |
"evaluate block on each directory; a Filename. The directories are sorted |
|
407 |
" |
|
1350 | 408 |
|
1093 | 409 |
self itemsDo:[:eachItem | |
410 |
eachItem isDirectory ifTrue:[ |
|
1350 | 411 |
aOneArgBlock value:(eachItem fileName) |
583 | 412 |
] |
1093 | 413 |
]. |
583 | 414 |
! |
415 |
||
416 |
filesAndBasenamesDo:aTwoArgBlock |
|
417 |
"evaluate block on each file; a Filename and a Basename. |
|
418 |
The files are sorted. |
|
419 |
" |
|
1350 | 420 |
|
1093 | 421 |
self itemsDo:[:eachItem | |
1324 | 422 |
eachItem isDirectory ifFalse:[ |
1093 | 423 |
aTwoArgBlock value:(eachItem fileName) value:(eachItem baseName) |
583 | 424 |
] |
425 |
] |
|
426 |
! |
|
427 |
||
428 |
filesDo:aOneArgBlock |
|
429 |
"evaluate block on each file; a Filename. The files are sorted. |
|
430 |
" |
|
1350 | 431 |
|
1093 | 432 |
self itemsDo:[:eachItem | |
1324 | 433 |
eachItem isDirectory ifFalse:[ |
1093 | 434 |
aOneArgBlock value:(eachItem fileName) |
583 | 435 |
] |
436 |
] |
|
1093 | 437 |
! |
438 |
||
439 |
itemsDo:aBlock |
|
440 |
"evaluate the block on each contentsItem, which contains the fileName and type info" |
|
441 |
||
1350 | 442 |
contents do:[:eachItem | |
443 |
aBlock value:eachItem. |
|
444 |
]. |
|
583 | 445 |
! ! |
446 |
||
447 |
!DirectoryContents methodsFor:'instance creation'! |
|
448 |
||
449 |
directory:aFilename |
|
1155
edcf3cfe1e93
Handle openErrorSignal in preparition for change openErrorSignal
Stefan Vogel <sv@exept.de>
parents:
1147
diff
changeset
|
450 |
"instance creation; setup attributes" |
edcf3cfe1e93
Handle openErrorSignal in preparition for change openErrorSignal
Stefan Vogel <sv@exept.de>
parents:
1147
diff
changeset
|
451 |
|
edcf3cfe1e93
Handle openErrorSignal in preparition for change openErrorSignal
Stefan Vogel <sv@exept.de>
parents:
1147
diff
changeset
|
452 |
|t dircontents| |
edcf3cfe1e93
Handle openErrorSignal in preparition for change openErrorSignal
Stefan Vogel <sv@exept.de>
parents:
1147
diff
changeset
|
453 |
|
2078 | 454 |
contents := #(). |
455 |
directory := aFilename asFilename. |
|
456 |
isRootDirectory := directory isRootDirectory. |
|
457 |
isReadable := true. |
|
458 |
||
459 |
"/Transcript showCR:('Readdir: %1' bindWith:(directory pathName)). |
|
460 |
||
1435
5895158e7491
Use Timestamp/#asTimestamp instead of AbsoluteTime/#asAbsoluteTime
Stefan Vogel <sv@exept.de>
parents:
1431
diff
changeset
|
461 |
t := Timestamp now. "/ directory modificationTime. |
1155
edcf3cfe1e93
Handle openErrorSignal in preparition for change openErrorSignal
Stefan Vogel <sv@exept.de>
parents:
1147
diff
changeset
|
462 |
[ |
1431
049b89c5bf60
cache mountPoints; faster directoryRead & sort
Claus Gittinger <cg@exept.de>
parents:
1393
diff
changeset
|
463 |
dircontents := directory directoryContents. |
049b89c5bf60
cache mountPoints; faster directoryRead & sort
Claus Gittinger <cg@exept.de>
parents:
1393
diff
changeset
|
464 |
dircontents sort. |
049b89c5bf60
cache mountPoints; faster directoryRead & sort
Claus Gittinger <cg@exept.de>
parents:
1393
diff
changeset
|
465 |
|
2078 | 466 |
contents := dircontents collect:[:eachBasename | |
467 |
DirectoryContentsItem new fileName:(directory construct:eachBasename) |
|
468 |
]. |
|
1155
edcf3cfe1e93
Handle openErrorSignal in preparition for change openErrorSignal
Stefan Vogel <sv@exept.de>
parents:
1147
diff
changeset
|
469 |
] on:FileStream openErrorSignal do:[:ex| |
2078 | 470 |
contents := #(). |
471 |
isReadable := false. |
|
1093 | 472 |
]. |
1101 | 473 |
timeStamp := t. |
1093 | 474 |
! ! |
475 |
||
2078 | 476 |
!DirectoryContents methodsFor:'obsolete'! |
477 |
||
478 |
updateContents |
|
479 |
<resource:#obsolete> |
|
480 |
||
481 |
"ensure that the file-info os present for every item |
|
482 |
** obsolete - access info if required" |
|
483 |
||
484 |
"/ contents do:[:eachItem | eachItem updateInfo ]. |
|
485 |
! ! |
|
486 |
||
1093 | 487 |
!DirectoryContents methodsFor:'printing'! |
488 |
||
489 |
printOn:aStream |
|
490 |
aStream nextPutAll:'DirectoryContents of: '. |
|
2078 | 491 |
aStream nextPutAll:(directory pathName). |
583 | 492 |
! ! |
493 |
||
494 |
!DirectoryContents methodsFor:'queries'! |
|
495 |
||
2078 | 496 |
beObsolete |
497 |
"mark self as obsolete |
|
498 |
clear contents and reset time" |
|
499 |
||
500 |
|saveCont| |
|
501 |
||
502 |
timeStamp := nil. |
|
503 |
saveCont := contents. |
|
504 |
contents := #(). |
|
505 |
||
506 |
saveCont notEmptyOrNil ifTrue:[ |
|
507 |
"/ clear the info - if someone has a reference to the item |
|
508 |
saveCont do:[:eachItem | eachItem resetInfo ]. |
|
509 |
]. |
|
510 |
! |
|
511 |
||
583 | 512 |
isObsolete |
1350 | 513 |
"returns true if the directory contents represented by the receiver is obsolete |
514 |
(i.e. if the fileSystems directory has been changed in the meanwhile) |
|
583 | 515 |
" |
974
c4be514ddd96
fix for windows bug (directory has no modification time)
Claus Gittinger <cg@exept.de>
parents:
958
diff
changeset
|
516 |
|mt| |
679 | 517 |
|
974
c4be514ddd96
fix for windows bug (directory has no modification time)
Claus Gittinger <cg@exept.de>
parents:
958
diff
changeset
|
518 |
timeStamp isNil ifTrue:[^ true]. |
2071 | 519 |
|
520 |
mt := self modificationTime. |
|
521 |
mt isNil ifTrue:[^ true ]. |
|
522 |
||
523 |
timeStamp < mt ifTrue:[ |
|
524 |
timeStamp getSeconds < mt getSeconds ifTrue:[ |
|
2078 | 525 |
self beObsolete. |
2071 | 526 |
^ true. |
527 |
]. |
|
528 |
]. |
|
974
c4be514ddd96
fix for windows bug (directory has no modification time)
Claus Gittinger <cg@exept.de>
parents:
958
diff
changeset
|
529 |
^ false |
2071 | 530 |
! |
974
c4be514ddd96
fix for windows bug (directory has no modification time)
Claus Gittinger <cg@exept.de>
parents:
958
diff
changeset
|
531 |
|
2078 | 532 |
isReadable |
533 |
"answer true if the directory is readable |
|
534 |
no open error raised during reading the directory" |
|
535 |
||
536 |
^ isReadable |
|
537 |
! |
|
538 |
||
2071 | 539 |
isRootDirectory |
2078 | 540 |
^ isRootDirectory |
906 | 541 |
! |
542 |
||
543 |
size |
|
544 |
"get number of files including directories in the directory |
|
545 |
" |
|
1093 | 546 |
^ contents size |
904 | 547 |
! ! |
548 |
||
549 |
!DirectoryContents methodsFor:'testing'! |
|
550 |
||
551 |
isEmpty |
|
552 |
"retuirns true if directory is empty |
|
553 |
" |
|
1093 | 554 |
^ contents size == 0 |
583 | 555 |
! |
556 |
||
557 |
notEmpty |
|
558 |
"returns true if directory is not empty |
|
559 |
" |
|
1093 | 560 |
^ contents size ~~ 0 |
561 |
! ! |
|
562 |
||
563 |
!DirectoryContents::DirectoryContentsItem methodsFor:'accessing'! |
|
564 |
||
565 |
baseName |
|
566 |
^ fileName baseName |
|
567 |
! |
|
568 |
||
569 |
fileName |
|
570 |
^ fileName |
|
571 |
! |
|
572 |
||
573 |
fileName:something |
|
574 |
"set the value of the instance variable 'fileName' (automatically generated)" |
|
575 |
||
576 |
fileName := something. |
|
577 |
! |
|
578 |
||
1100 | 579 |
info |
1350 | 580 |
info isNil ifTrue:[ |
581 |
self updateInfo. |
|
582 |
]. |
|
1100 | 583 |
info isSymbol ifTrue:[^ nil]. "/ a remote directory |
584 |
^ info |
|
585 |
! |
|
586 |
||
1099 | 587 |
info:something |
588 |
"set the value of the instance variable 'type' (automatically generated)" |
|
589 |
||
590 |
info := something. |
|
591 |
! |
|
592 |
||
1093 | 593 |
type |
1350 | 594 |
info isNil ifTrue:[ |
595 |
self updateInfo. |
|
596 |
]. |
|
1099 | 597 |
info isSymbol ifTrue:[^ info]. |
598 |
^ info type |
|
1093 | 599 |
! ! |
600 |
||
1350 | 601 |
!DirectoryContents::DirectoryContentsItem methodsFor:'misc'! |
602 |
||
1431
049b89c5bf60
cache mountPoints; faster directoryRead & sort
Claus Gittinger <cg@exept.de>
parents:
1393
diff
changeset
|
603 |
cachedRemoteMountPoints |
049b89c5bf60
cache mountPoints; faster directoryRead & sort
Claus Gittinger <cg@exept.de>
parents:
1393
diff
changeset
|
604 |
|mountPoints now| |
049b89c5bf60
cache mountPoints; faster directoryRead & sort
Claus Gittinger <cg@exept.de>
parents:
1393
diff
changeset
|
605 |
|
049b89c5bf60
cache mountPoints; faster directoryRead & sort
Claus Gittinger <cg@exept.de>
parents:
1393
diff
changeset
|
606 |
mountPoints := CachedRemoteMountPoints. |
049b89c5bf60
cache mountPoints; faster directoryRead & sort
Claus Gittinger <cg@exept.de>
parents:
1393
diff
changeset
|
607 |
|
049b89c5bf60
cache mountPoints; faster directoryRead & sort
Claus Gittinger <cg@exept.de>
parents:
1393
diff
changeset
|
608 |
(mountPoints isNil |
049b89c5bf60
cache mountPoints; faster directoryRead & sort
Claus Gittinger <cg@exept.de>
parents:
1393
diff
changeset
|
609 |
or:[ CachedRemoteMountPointsTimeStamp isNil |
049b89c5bf60
cache mountPoints; faster directoryRead & sort
Claus Gittinger <cg@exept.de>
parents:
1393
diff
changeset
|
610 |
or:[ now := Timestamp now. |
049b89c5bf60
cache mountPoints; faster directoryRead & sort
Claus Gittinger <cg@exept.de>
parents:
1393
diff
changeset
|
611 |
(now - CachedRemoteMountPointsTimeStamp) > 30 |
049b89c5bf60
cache mountPoints; faster directoryRead & sort
Claus Gittinger <cg@exept.de>
parents:
1393
diff
changeset
|
612 |
]]) ifTrue:[ |
049b89c5bf60
cache mountPoints; faster directoryRead & sort
Claus Gittinger <cg@exept.de>
parents:
1393
diff
changeset
|
613 |
CachedRemoteMountPointsTimeStamp := now. |
049b89c5bf60
cache mountPoints; faster directoryRead & sort
Claus Gittinger <cg@exept.de>
parents:
1393
diff
changeset
|
614 |
mountPoints := OperatingSystem mountPoints. |
049b89c5bf60
cache mountPoints; faster directoryRead & sort
Claus Gittinger <cg@exept.de>
parents:
1393
diff
changeset
|
615 |
mountPoints := mountPoints select:[:mp | mp isRemote]. |
049b89c5bf60
cache mountPoints; faster directoryRead & sort
Claus Gittinger <cg@exept.de>
parents:
1393
diff
changeset
|
616 |
CachedRemoteMountPoints := mountPoints. |
049b89c5bf60
cache mountPoints; faster directoryRead & sort
Claus Gittinger <cg@exept.de>
parents:
1393
diff
changeset
|
617 |
]. |
049b89c5bf60
cache mountPoints; faster directoryRead & sort
Claus Gittinger <cg@exept.de>
parents:
1393
diff
changeset
|
618 |
|
049b89c5bf60
cache mountPoints; faster directoryRead & sort
Claus Gittinger <cg@exept.de>
parents:
1393
diff
changeset
|
619 |
^ mountPoints. |
049b89c5bf60
cache mountPoints; faster directoryRead & sort
Claus Gittinger <cg@exept.de>
parents:
1393
diff
changeset
|
620 |
! |
049b89c5bf60
cache mountPoints; faster directoryRead & sort
Claus Gittinger <cg@exept.de>
parents:
1393
diff
changeset
|
621 |
|
2078 | 622 |
resetAttributes |
623 |
"reset the attributes... done if I'am a normal file" |
|
624 |
||
625 |
(info isNil or:[info isSymbol]) ifTrue:[^ self ]. |
|
626 |
||
627 |
self isDirectory ifFalse:[ |
|
628 |
info := nil. |
|
629 |
]. |
|
630 |
! |
|
631 |
||
632 |
resetInfo |
|
633 |
info := nil. |
|
634 |
! |
|
635 |
||
1350 | 636 |
updateInfo |
2047 | 637 |
"ensure that the file-info is present |
638 |
DirectoryContents flushCache |
|
639 |
" |
|
1468
476e360d4aeb
#linkInfo now returns the info also for files that are not a symlink
Stefan Vogel <sv@exept.de>
parents:
1435
diff
changeset
|
640 |
|
2047 | 641 |
|mountPoints mountPoint nameString linkName| |
1350 | 642 |
|
643 |
info isNil ifTrue:[ |
|
644 |
nameString := fileName name. |
|
1468
476e360d4aeb
#linkInfo now returns the info also for files that are not a symlink
Stefan Vogel <sv@exept.de>
parents:
1435
diff
changeset
|
645 |
self assert:[fileName isAbsolute]. |
1431
049b89c5bf60
cache mountPoints; faster directoryRead & sort
Claus Gittinger <cg@exept.de>
parents:
1393
diff
changeset
|
646 |
mountPoints := self cachedRemoteMountPoints. |
1468
476e360d4aeb
#linkInfo now returns the info also for files that are not a symlink
Stefan Vogel <sv@exept.de>
parents:
1435
diff
changeset
|
647 |
info := fileName linkInfo. |
2047 | 648 |
|
1468
476e360d4aeb
#linkInfo now returns the info also for files that are not a symlink
Stefan Vogel <sv@exept.de>
parents:
1435
diff
changeset
|
649 |
(info notNil and:[info isSymbolicLink]) ifTrue:[ |
2047 | 650 |
OperatingSystem isMSWINDOWSlike ifFalse:[ |
651 |
linkName := info path. |
|
2046 | 652 |
|
2047 | 653 |
linkName notNil ifTrue:[ |
654 |
"have to check for both link and link target" |
|
655 |
mountPoint := mountPoints |
|
656 |
detect:[:mInfo | |p| |
|
657 |
p := mInfo mountPointPath. |
|
658 |
((linkName startsWith:p) and:[ linkName startsWith:(p , '/') ]) |
|
659 |
] |
|
660 |
ifNone:nil. |
|
661 |
||
662 |
info := fileName info. "get the info of the link target" |
|
663 |
]. |
|
664 |
]. |
|
1351
9741c3cbc395
avoid blocking on mounted directories;
Claus Gittinger <cg@exept.de>
parents:
1350
diff
changeset
|
665 |
] ifFalse:[ |
1468
476e360d4aeb
#linkInfo now returns the info also for files that are not a symlink
Stefan Vogel <sv@exept.de>
parents:
1435
diff
changeset
|
666 |
"have to check for mountPoint only" |
1351
9741c3cbc395
avoid blocking on mounted directories;
Claus Gittinger <cg@exept.de>
parents:
1350
diff
changeset
|
667 |
mountPoint := mountPoints |
1468
476e360d4aeb
#linkInfo now returns the info also for files that are not a symlink
Stefan Vogel <sv@exept.de>
parents:
1435
diff
changeset
|
668 |
detect:[:mInfo | mInfo mountPointPath = nameString ] |
476e360d4aeb
#linkInfo now returns the info also for files that are not a symlink
Stefan Vogel <sv@exept.de>
parents:
1435
diff
changeset
|
669 |
ifNone:nil. |
1351
9741c3cbc395
avoid blocking on mounted directories;
Claus Gittinger <cg@exept.de>
parents:
1350
diff
changeset
|
670 |
]. |
2047 | 671 |
mountPoint notNil ifTrue:[ |
1350 | 672 |
info := #remoteDirectory. |
673 |
] ifFalse:[ |
|
674 |
info isNil ifTrue:[ |
|
675 |
"/ broken symbolic link |
|
676 |
info := #symbolicLink. |
|
677 |
] |
|
678 |
]. |
|
679 |
]. |
|
680 |
! ! |
|
681 |
||
1093 | 682 |
!DirectoryContents::DirectoryContentsItem methodsFor:'printing'! |
683 |
||
684 |
printOn:aStream |
|
685 |
aStream nextPutAll:'DirectoryContentsItem for: '. |
|
686 |
fileName printOn:aStream. |
|
687 |
! ! |
|
688 |
||
689 |
!DirectoryContents::DirectoryContentsItem methodsFor:'queries'! |
|
690 |
||
691 |
isDirectory |
|
1099 | 692 |
|t| |
693 |
||
694 |
t := self type. |
|
695 |
^ (t == #directory or:[t == #remoteDirectory]) |
|
1093 | 696 |
! |
697 |
||
698 |
isRemoteDirectory |
|
2074 | 699 |
^ self type == #remoteDirectory |
700 |
! |
|
701 |
||
702 |
isSymbolicLink |
|
703 |
^ self type == #isymbolicLink |
|
583 | 704 |
! ! |
705 |
||
706 |
!DirectoryContents class methodsFor:'documentation'! |
|
707 |
||
708 |
version |
|
2078 | 709 |
^ '$Header: /cvs/stx/stx/libbasic2/DirectoryContents.st,v 1.47 2008-12-18 16:16:20 ca Exp $' |
583 | 710 |
! ! |
1093 | 711 |
|
957 | 712 |
DirectoryContents initialize! |