INTERFACE DirOp; (***************************************************************************) (* Copyright (C) Olivetti 1989 *) (* All Rights reserved *) (* *) (* Use and copy of this software and preparation of derivative works based *) (* upon this software are permitted to any person, provided this same *) (* copyright notice and the following Olivetti warranty disclaimer are *) (* included in any copy of the software or any modification thereof or *) (* derivative work therefrom made by any person. *) (* *) (* This software is made available AS IS and Olivetti disclaims all *) (* warranties with respect to this software, whether expressed or implied *) (* under any law, including all implied warranties of merchantibility and *) (* fitness for any purpose. In no event shall Olivetti be liable for any *) (* damages whatsoever resulting from loss of use, data or profits or *) (* otherwise arising out of or in connection with the use or performance *) (* of this software. *) (***************************************************************************) IMPORT Text; IMPORT OSError, FileOp; (* First routines for directory iteration *) TYPE T <: REFANY; Entry <: FileOp.Info; PROCEDURE Open(name: Text.T; mustExist := TRUE): T RAISES {OSError.E}; (* Open the named directory and return a handle to it. If named directory cannot be opened raises 'OSError.E'. The only exception to this rule occurs if 'mustExist' is FALSE and the attempt to open 'name' fails because 'name' does not exist. In this case no exception is raised and 'Open' returns NIL. If 'name' is the null text 'Open' attempts to open the current directory. If 'name' is NIL a checked runtime error will occur *) PROCEDURE Name(t: T): Text.T RAISES {}; (* Return the name of 't' (the name which was given to the 'Open' call which created 't'). It is a checked runtime error if 't' is closed *) PROCEDURE Close(VAR t: T) RAISES {}; (* Close the directory handle and set 't' to NIL. Marks the handle as invalid so it is useless even if the user retains another reference to it. *) (* The following routines provide a way of finding entries in the directory. The type representing a directory entry is a subtype of 'FileOp.Info' and has methods which provide information about the entry type, size etc. There are also some routines exported by this interface which are specific to directory entries. If the directory is updated between a call of 'Open' and 'Close' the effect is undefined - no guarantee is made the the routines which find directory entries will work "correctly". Some implementations may make a snapshot of the directory at 'Open' time; on other systems there may be a good reason not to do this. *) PROCEDURE Find(t: T; name: Text.T; VAR e: Entry): BOOLEAN RAISES {}; (* Find an entry with the given name. The name is relative to the directory represented by 't' i.e. it is NOT a full path name. If successful returns TRUE and sets 'e' to be a handle on the entry. Otherwise returns FALSE and sets 'e' to NIL. It is a checked runtime error if 't' has been closed *) TYPE Iterator <: REFANY; PROCEDURE Next(t: T; VAR i: Iterator; VAR e: Entry): BOOLEAN RAISES {}; (* An iterator for entries. A typical use would be: VAR t := DirOp.Open("somedir"); i: DirOp.Iterator := NIL; e: DirOp.Entry; BEGIN WHILE DirOp.Next(t, i, e) DO (* use 'e' *) END; END; If 'i' is NIL the iteration is started from the beginning of the directory. If there is a next entry 'Next' returns TRUE, steps 'i' forward and sets 'e' to the next entry. When there are no more entries 'Next' returns FALSE and sets both 'i' and 'e' to NIL. It is a checked runtime error to use 'Next' if 't' has been closed. It is a checked runtime error to use a value of 'i' which was created via a call to 'Next' on a different directory handle. *) (* Enquiry operations for entries. Remember that 'Entry' is a subtype of 'FileOp.Info' and has enquiry methods as well. It is a checked error to use an entry enquiry operation or method if the directory in which the entry was found has been closed. *) PROCEDURE AccessibleEntry(e: Entry): BOOLEAN RAISES {}; (* On some systems it may be possible to lookup or find by iteration a directory entry and then have little access to that entry. To handle this 'rare' case 'AccessibleEntry' is provided. If 'AccessibleEntry' returns TRUE all the normal entry operations (those defined here and in 'FileOp') are available. If 'AccessibleEntry' is FALSE none of the operations should be used (if they are used a checked runtime error will result). It would be possible to implement a less restrictive (and more complex) scheme where 'AccessibleEntry' returned a list of available operations. This does not seem worth it given the rarity of the problem - 'AccessibleEntry' will always return TRUE on most systems. *) PROCEDURE EntryName(e: Entry): Text.T RAISES {}; (* Return the name of 'e' relative to the directory in which it was found. Useful when iterating through a directory using 'Next'. The path name for 'e', including the directory name, can be returned by the 'e.name' method. *) (* Other directory operations, not related to directory iteration *) <*INLINE*> PROCEDURE Accessible(name: Text.T): BOOLEAN RAISES {}; (* Checks if an object called 'name' exists in the file systems is accessible in some way. Makes no promises as to how accessible 'name' is!. 'name' may be null, indicating the current directory, but may not be NIL. If it is a checked runtime error will occur. This function is just another way of calling 'FileOp.Accessible'. *) PROCEDURE Create(name: Text.T) RAISES {OSError.E}; (* Creates a directory with the given name. Raises 'OSError.E' if the operation fails. *) PROCEDURE Remove(name: Text.T; mustExist := TRUE) RAISES {OSError.E}; (* Remove the named directory, which must be empty. Raises 'OSError.E' if the operation fails. If 'mustExist' is FALSE and the remove fails because 'name' does not exist no exception is raised. If 'name' is a file name the effect of 'Remove' is undefined. The 'FileOp' interface provides a file 'Remove' operation. *) PROCEDURE Rename(from, to: Text.T) RAISES {OSError.E}; (* Rename 'from' as 'to'. Raises 'OSError.E' if the operation fails. If 'from' and 'to' are file names the effect of 'Rename' is undefined. The 'FileOp' interface provides a file 'Rename' operation. *) END DirOp.