/[eiffelstudio]/FreeELKS/trunk/library/kernel/directory.e
ViewVC logotype

Contents of /FreeELKS/trunk/library/kernel/directory.e

Parent Directory Parent Directory | Revision Log Revision Log


Revision 91477 - (show annotations)
Sun Jan 14 09:47:13 2007 UTC (13 years ago) by ericb
File size: 11903 byte(s)
Synchronized with ISE 6.0.65740
1 indexing
2 description: "Directories, in the Unix sense, with creation and exploration features"
3 library: "Free implementation of ELKS library"
4 copyright: "Copyright (c) 1986-2004, Eiffel Software and others"
5 license: "Eiffel Forum License v2 (see forum.txt)"
6 date: "$Date$"
7 revision: "$Revision$"
8
9 class DIRECTORY
10
11 inherit
12 DISPOSABLE
13 export
14 {DIRECTORY} all
15 end
16
17 create
18 make, make_open_read
19
20 feature -- Initialization
21
22 make (dn: STRING) is
23 -- Create directory object for directory
24 -- of name `dn'.
25 require
26 string_exists: dn /= Void
27 do
28 name := dn
29 mode := Close_directory
30 end
31
32 make_open_read (dn: STRING) is
33 -- Create directory object for directory
34 -- of name `dn' and open it for reading.
35 require
36 string_exists: dn /= Void
37 do
38 make (dn)
39 open_read
40 end
41
42 create_dir is
43 -- Create a physical directory.
44 require
45 physical_not_exists: not exists
46 local
47 external_name: ANY
48 do
49 external_name := name.to_c
50 file_mkdir ($external_name)
51 end
52
53 feature -- Access
54
55 readentry is
56 -- Read next directory entry
57 -- make result available in `lastentry'.
58 -- Make result Void if all entries have been read.
59 require
60 is_opened: not is_closed
61 do
62 lastentry := dir_next (directory_pointer)
63 end
64
65 name: STRING
66 -- Directory name
67
68 has_entry (entry_name: STRING): BOOLEAN is
69 -- Has directory the entry `entry_name'?
70 -- The use of `dir_temp' is required not
71 -- to change the position in the current
72 -- directory entries list.
73 require
74 string_exists: entry_name /= Void
75 local
76 dir_temp: DIRECTORY
77 do
78 create dir_temp.make_open_read (name)
79 from
80 dir_temp.readentry
81 until
82 Result or dir_temp.lastentry = Void
83 loop
84 Result := dir_temp.lastentry.is_equal (entry_name)
85 dir_temp.readentry
86 end
87 dir_temp.close
88 end
89
90 open_read is
91 -- Open directory for reading.
92 local
93 external_name: ANY
94 do
95 external_name := name.to_c
96 directory_pointer := dir_open ($external_name)
97 mode := Read_directory
98 end
99
100 close is
101 -- Close directory.
102 require
103 is_open: not is_closed
104 do
105 dir_close (directory_pointer)
106 directory_pointer := default_pointer
107 mode := Close_directory
108 end
109
110 start is
111 -- Go to first entry of directory.
112 require
113 is_opened: not is_closed
114 do
115 dir_rewind (directory_pointer)
116 end
117
118 change_name (new_name: STRING) is
119 -- Change directory `name' to `new_name'.
120 require
121 new_name_not_void: new_name /= Void
122 directory_exists: exists
123 local
124 ext_old_name, ext_new_name: ANY
125 do
126 ext_old_name := name.to_c
127 ext_new_name := new_name.to_c
128 eif_dir_rename ($ext_old_name, $ext_new_name)
129 name := new_name
130 ensure
131 name_changed: name.is_equal (new_name)
132 end
133
134 feature -- Measurement
135
136 count: INTEGER is
137 -- Number of entries in directory.
138 require
139 directory_exists: exists
140 local
141 dir_temp: DIRECTORY
142 counter: INTEGER
143 do
144 create dir_temp.make_open_read (name)
145 from
146 dir_temp.start
147 dir_temp.readentry
148 until
149 dir_temp.lastentry = Void
150 loop
151 counter := counter + 1
152 dir_temp.readentry
153 end
154 Result := counter
155 dir_temp.close
156 end
157
158 feature -- Conversion
159
160 linear_representation: ARRAYED_LIST [STRING] is
161 -- The entries, in sequential format.
162 local
163 dir_temp: DIRECTORY
164 do
165 create dir_temp.make_open_read (name)
166 -- Arbitrary size for arrayed_list creation to avoid
167 -- querying `count' which traverses list of entries
168 -- in current directory as we do here, making current
169 -- less efficient if Current has a lot of entries.
170 create Result.make (16)
171 from
172 dir_temp.start
173 dir_temp.readentry
174 until
175 dir_temp.lastentry = Void
176 loop
177 Result.extend (dir_temp.lastentry)
178 dir_temp.readentry
179 end
180 dir_temp.close
181 end
182
183 feature -- Status report
184
185 lastentry: STRING
186 -- Last entry read by `readentry'
187
188 is_closed: BOOLEAN is
189 -- Is current directory closed?
190 do
191 Result := mode = Close_directory
192 end
193
194 is_empty: BOOLEAN is
195 -- Is directory empty?
196 require
197 directory_exists: exists
198 do
199 -- count = 2, since there are "." and ".." which
200 -- are symbolic representations but not effective directories.
201 Result := (count = 2)
202 end
203
204 empty: BOOLEAN is
205 -- Is directory empty?
206 obsolete
207 "Use `is_empty' instead"
208 do
209 Result := is_empty
210 end
211
212 exists: BOOLEAN is
213 -- Does the directory exist?
214 local
215 external_name: ANY
216 do
217 external_name := name.to_c
218 Result := eif_dir_exists ($external_name)
219 end
220
221 is_readable: BOOLEAN is
222 -- Is the directory readable?
223 require
224 directory_exists: exists
225 local
226 external_name: ANY
227 do
228 external_name := name.to_c
229 Result := eif_dir_is_readable ($external_name)
230 end
231
232 is_executable: BOOLEAN is
233 -- Is the directory executable?
234 require
235 directory_exists: exists
236 local
237 external_name: ANY
238 do
239 external_name := name.to_c
240 Result := eif_dir_is_executable ($external_name)
241 end
242
243 is_writable: BOOLEAN is
244 -- Is the directory writable?
245 require
246 directory_exists: exists
247 local
248 external_name: ANY
249 do
250 external_name := name.to_c
251 Result := eif_dir_is_writable ($external_name)
252 end
253
254 feature -- Removal
255
256 delete is
257 -- Delete directory if empty.
258 require
259 directory_exists: exists
260 empty_directory: is_empty
261 local
262 external_name: ANY
263 do
264 external_name := name.to_c
265 eif_dir_delete ($external_name)
266 end
267
268 delete_content is
269 -- Delete all files located in directory and subdirectories.
270 require
271 directory_exists: exists
272 local
273 l: LINEAR [STRING]
274 file_name: FILE_NAME
275 file: RAW_FILE
276 dir: DIRECTORY
277 do
278 l := linear_representation
279 from
280 l.start
281 until
282 l.after
283 loop
284 if
285 not l.item.same_string (".") and
286 not l.item.same_string ("..")
287 then
288 create file_name.make_from_string (name)
289 file_name.set_file_name (l.item)
290 create file.make (file_name)
291 if
292 file.exists and then
293 not file.is_symlink and then
294 file.is_directory
295 then
296 -- Start the recursion
297 create dir.make (file_name)
298 dir.recursive_delete
299 else
300 if file.exists and then file.is_writable then
301 file.delete
302 end
303 end
304 end
305 l.forth
306 end
307 end
308
309 recursive_delete is
310 -- Delete directory and all content contained within.
311 require
312 directory_exists: exists
313 do
314 delete_content
315 if is_empty then
316 delete
317 end
318 end
319
320 delete_content_with_action (
321 action: PROCEDURE [ANY, TUPLE]
322 is_cancel_requested: FUNCTION [ANY, TUPLE, BOOLEAN]
323 file_number: INTEGER)
324 is
325 -- Delete all files located in directory and subdirectories.
326 --
327 -- `action' is called each time `file_number' files has
328 -- been deleted and before the function exits.
329 -- `action' may be set to Void if you don't need it.
330 --
331 -- Same for `is_cancel_requested'.
332 -- Make it return `True' to cancel the operation.
333 -- `is_cancel_requested' may be set to Void if you don't need it.
334 require
335 directory_exists: exists
336 valid_file_number: file_number > 0
337 local
338 l: LINEAR [STRING]
339 file_name: FILE_NAME
340 file: RAW_FILE
341 dir: DIRECTORY
342 file_count: INTEGER
343 deleted_files: ARRAYED_LIST [STRING]
344 deleted_files_tuple: TUPLE [ARRAYED_LIST [STRING]]
345 current_directory: STRING
346 parent_directory: STRING
347 requested_cancel: BOOLEAN
348 do
349 file_count := 1
350 create deleted_files.make (file_number)
351 create deleted_files_tuple
352
353 l := linear_representation
354 current_directory := "."
355 parent_directory := ".."
356 from
357 l.start
358 until
359 l.after or requested_cancel
360 loop
361 if
362 not l.item.is_equal (current_directory) and
363 not l.item.is_equal (parent_directory)
364 then
365 create file_name.make_from_string (name)
366 file_name.set_file_name (l.item)
367 create file.make (file_name)
368 if
369 file.exists and then
370 not file.is_symlink and then
371 file.is_directory
372 then
373 -- Start the recursion
374 create dir.make (file_name)
375 dir.recursive_delete_with_action (action, is_cancel_requested, file_number)
376 else
377 if file.exists and then file.is_writable then
378 file.delete
379 end
380 end
381 -- Add the name of the deleted file to our array
382 -- of deleted files.
383 deleted_files.extend (file_name)
384 file_count := file_count + 1
385
386 -- If `file_number' has been reached, call `action'.
387 if file_count > file_number then
388 if action /= Void then
389 deleted_files_tuple.put (deleted_files, 1)
390 action.call (deleted_files_tuple)
391 end
392 if is_cancel_requested /= Void then
393 requested_cancel := is_cancel_requested.item (Void)
394 end
395 deleted_files.wipe_out
396 file_count := 1
397 end
398 end
399 l.forth
400 end
401 -- If there is more than one deleted file and no
402 -- agent has been called, call one now.
403 if file_count > 1 then
404 if action /= Void then
405 deleted_files_tuple.put (deleted_files, 1)
406 action.call (deleted_files_tuple)
407 end
408 deleted_files.wipe_out
409 file_count := 1
410 end
411 end
412
413 recursive_delete_with_action (
414 action: PROCEDURE [ANY, TUPLE]
415 is_cancel_requested: FUNCTION [ANY, TUPLE, BOOLEAN]
416 file_number: INTEGER)
417 is
418 -- Delete directory and all content contained within.
419 --
420 -- `action' is called each time `file_number' files has
421 -- been deleted and before the function exits.
422 require
423 directory_exists: exists
424 local
425 deleted_files: ARRAYED_LIST [STRING]
426 do
427 delete_content_with_action (action, is_cancel_requested, file_number)
428 if (is_cancel_requested = Void) or else (not is_cancel_requested.item (Void)) then
429 delete
430
431 -- Call the agent with the name of the directory
432 if action /= Void then
433 create deleted_files.make (1)
434 deleted_files.extend (name)
435 action.call ([deleted_files])
436 end
437 end
438 end
439
440 dispose is
441 -- Ensure this medium is closed when garbage collected.
442 do
443 if not is_closed then
444 close
445 end
446 end
447
448 feature {DIRECTORY} -- Implementation
449
450 directory_pointer: POINTER
451 -- Directory pointer as required in C
452
453 feature {NONE} -- Implementation
454
455 mode: INTEGER
456 -- Status mode of the directory.
457 -- Possible values are the following:
458
459 Close_directory: INTEGER is 1
460
461 Read_directory: INTEGER is 2
462
463 file_mkdir (dir_name: POINTER) is
464 -- Make directory `dir_name'.
465 external
466 "C signature (char *) use %"eif_file.h%""
467 end
468
469 dir_open (dir_name: POINTER): POINTER is
470 -- Open the directory `dir_name'.
471 external
472 "C signature (char *): EIF_POINTER use %"eif_dir.h%""
473 end
474
475 dir_rewind (dir_ptr: POINTER) is
476 -- Rewind the directory `dir_ptr'.
477 external
478 "C use %"eif_dir.h%""
479 end
480
481 dir_close (dir_ptr: POINTER) is
482 -- Close the directory `dir_ptr'.
483 external
484 "C use %"eif_dir.h%""
485 end
486
487 dir_next (dir_ptr: POINTER): STRING is
488 -- Return the next entry for directory 'dir_ptr'.
489 external
490 "C use %"eif_dir.h%""
491 end
492
493 eif_dir_delete (dir_name: POINTER) is
494 -- Delete the directory `dir_name'.
495 external
496 "C signature (char *) use %"eif_dir.h%""
497 end
498
499 eif_dir_exists (dir_name: POINTER): BOOLEAN is
500 -- Does the directory `dir_name' exist?
501 external
502 "C signature (char *): EIF_BOOLEAN use %"eif_dir.h%""
503 end
504
505 eif_dir_is_readable (dir_name: POINTER): BOOLEAN is
506 -- Is `dir_name' readable?
507 external
508 "C signature (char *): EIF_BOOLEAN use %"eif_dir.h%""
509 end
510
511 eif_dir_is_executable (dir_name: POINTER): BOOLEAN is
512 -- Is `dir_name' executable?
513 external
514 "C signature (char *): EIF_BOOLEAN use %"eif_dir.h%""
515 end
516
517 eif_dir_is_writable (dir_name: POINTER): BOOLEAN is
518 -- Is `dir_name' writable?
519 external
520 "C signature (char *): EIF_BOOLEAN use %"eif_dir.h%""
521 end
522
523 eif_dir_rename (old_name, new_name: POINTER) is
524 -- Change directory name from `old_name' to `new_name'.
525 external
526 "C signature (char *, char *) use %"eif_file.h%""
527 alias
528 "file_rename"
529 end
530
531 end

Properties

Name Value
svn:eol-style native
svn:keywords Author Date Id Revision

  ViewVC Help
Powered by ViewVC 1.1.23