filename.h | documentation |
#charset "us-ascii" #pragma once /* * Copyright (c) 2001, 2006 Michael J. Roberts * * This file is part of TADS 3. * * This header defines the FileName intrinsic class. */ /* include our base class definition */ #include "systype.h" /* if we're using FileName objects, we probably want File objects as well */ #include "file.h" /* ------------------------------------------------------------------------ */ /* * A FileName represents the name of a file in the local operating * system. The File object methods that take filename specifications * accept FileName objects as well as ordinary strings. * * It's easier to write portable code if you manipulate filenames using * the FileName class rather than using ordinary strings. TADS runs on * several different operating systems with differing syntax rules for * constructing file names and directory paths. The FileName class * handles the different rules that apply on each system. * * Construction: * *. new FileName() - creates a FileName object representing the working *. directory (e.g., '.' on Unix or Windows) * *. new FileName(str) - creates a FileName from a string 'str' giving a *. file path in local filename syntax. * *. new FileName(path, name) - creates a FileName from a path and *. a file name. 'path' and 'name' can each be a FileName *. object or a string using local filename syntax. The *. new object represents the combined path * *. new FileName(specialID) - creates a FileName from one of the special *. file identifiers defined in file.h. * * You can also use the fromUniversal() static method, which creates a * FileName from a path in universal (URL-style) notation. * * String conversions: using a FileName object in a context where a * string is required (such as displaying it) automatically converts the * object to a string giving the local file name path. * * Operators: * *. FileName + string => yields a new FileName object combining *. the path given by FileName and the string naming a file, *. in local naming conventions. * *. FileName + FileName => yields a new FileName object combining *. the two names, treating the first as a directory path. * *. FileName == string (or !=) OR *. FileName == FileName *. Compares the FileName to the string or other filename path. *. This does a superficial comparison of the path contents, *. without attempting to correlate the path to the actual file *. system layout. For example, it doesn't resolve symbolic *. links on Unix or apply working directories to local paths. */ intrinsic class FileName 'filename/030000' : Object { /* * Get the filename. This returns a string with the filename this * object represents, in the local syntax used by the host operating * system, including the path and base filename portions. (This is * the same string returned for toString(self), and the same string * used if the filename is displayed as though it were a string, such * as with "<< >>".) */ getName(); /* * Get the base filename portion, without the path. This returns a * string giving the filename without any directory location * information; for a Unix-style path or Windows-style path, this is * simply the last element of the path. */ getBaseName(); /* * Get the path portion name, without the file name. This returns a * FileName object containing the path portion of the file name, with * the last path element removed. If the path only contains one path * element (so it contains only a file name, not a directory path), * this returns nil. */ getPath(); /* * Create a new FileName object from a path in universal URL-style * syntax. Path elements are separated with "/" characters. The * universal path syntax is converted to the local path notation for * the new FileName object. */ static fromUniversal(path); /* * Get the universal URL-style notation for this file name. Returns * a string giving the universal notation for the file name * (including any path portion). */ toUniversal(); /* * Add a path element (a string or FileName object) to the end of * this filename, yielding a new FileName object with the combined * path. Uses the correct local syntax to combine the path elements. * This yields the same results as FileName + element. * * The new FileName object is in canonical form, meaning that any * internal relative path elements (e.g., Unix "." and "..") are * processed by combining them with adjacent elements as appropriate. * For example, adding ".." to the Unix path "a/b/c" yields "a/b". */ addToPath(element); /* * Is this an absolute path on the local system? An absolute path is * one that contains a root folder specification, such as a Unix path * starting with "/", Windows path starting with "C:\", or a Windows * UNC name such as "\\SERVER\SHARE". * * Note that a Windows path can start with a drive letter without * being absolute, as in "C:path\file" (that's relative to the * working folder on the C: drive), and can start with a backslash * without being absolute, as in "\path\file" (that's relative to the * working drive letter). Similar subtleties might apply to other * systems; this routine figures it out using local conventions. */ isAbsolute(); /* * Get a FileName giving the absolute path to this file. This * applies the current working directory and/or volume (e.g., drive * letter on Windows) to produce the full path in absolute notation, * using the appropriate syntax for the local operating system. If * the name is already in absolute format, the result will usually be * unchanged, although the exact syntax might be modified on some * systems to change the name to a more canonical format. * * If it's not possible to convert the filename into an absolute * path, returns nil. */ getAbsolutePath(); /* * Get the list of root directories on the local system. Returns a * list of FileName objects representing the root directories. The * list only includes roots that are accessible under the file safety * settings for getFileInfo(); note that other operations, such as * listing the directory contents, might not be allowed even if the * metdata are accessible. * * Most Unix-like systems only have one root directory, usually * called '/'. Many other systems have a separate root directory for * each volume or device; for example, Windows has a root folder for * each drive letter, so the root list might contain paths like C:\, * D:\, etc. Some systems have no concept of a root directory at * all, in which case the result will be an empty list; this is the * case for the network storage server. */ static getRootDirs(); /* * Get the type of the file. If the file named by this object exists, * returns an integer with a bitwise combination of FileTypeXxx values * indicating the type of the file. If the file doesn't exist, or * can't be accessed due to file system permissions or some other * operating system error, the return value is nil. Note that it's * also possible for the return value to be zero, which means * something different from nil: zero means that the file exists, but * it doesn't fit any of the FileTypeXxx classifications. * * If the file is a symbolic link, the method's behavior depends on * 'asLink'. A symbolic link is a special type of file supported on * some operating systems that serves as a pointer or proxy for * another file. If the file is a link, and 'asLink' is omitted or * nil, the method returns information on the target of the link; this * is the default because symbolic links in generally act as * transparent proxies for their targets, so for most purposes a * caller should be interested in the target file's metadata. * However, a symbolic link also has a separate identity of its own as * a link, so callers might sometimes be interested in the metadata * for the link rather than its target. To get information on the * link itself, set 'asLink' to true. 'asLink' has no effect for * ordinary non-link files, and also has no effect for "hard" links on * systems that support those as well. * * Most of the FileTypeXxx bits are mutually exclusive, but it's * possible that more than one bit will be set, so test using '&' * (e.g., (f.getFileType() & FileTypeDir)). * * The file safety settings must allow read access to the file. */ getFileType(followLinks?); /* * Get extended information on the file named by this object. This * retrieves the size of the file, timestamps, and the file's type, * and returns the information as a FileInfo object (see file.t). If * the file doesn't exist, or can't be accessed for some other reason * at the operating system level, returns nil. * * 'asLink' has the same meaning as in getFileType(), and has no * effect at all unless the file named is a symbolic link. * * The file safety settings must allow read access to the file. */ getFileInfo(followLinks?); /* * Delete the disk file named by this object. The file safety level * must allow write access to the file; a file safety exception is * thrown if not. */ deleteFile(); /* * Rename or move the file. This changes the name and/or file path * location of the file named by 'self' to the given new path, which * can be a string giving a filename in local path notation, or a * FileName object with the new name. The file safety settings must * allow write access to both the original file and the new file. * The new file must not already exist. */ renameFile(newname); /* * Get a list of files in the directory named by this object. Returns * a list of FileName objects giving the names of the files. * * The file safety settings must allow read access to the directory's * contents. * * On systems where the file system has special directory entries for * relative links, such as "." and ".." on Windows and Unix-likes, the * listing that this method returns will include entries for those * relative links. Be careful with these when performing recursive * directory traversals, since recursing into "." or ".." would cause * an infinite loop. You can test an entry in the returned list to see * if it's one of these special links by calling its getFileInfo() * method, and testing the specialLink property of the returned * information object. Not that if you're performing a recursive * directory traversal, it might be easier to use forEachFile() with * the 'recurse' argument flag set to true. */ listDir(); /* * Invoke a callback for each file in the directory named by this * object. 'func' is a callback function; for each file in the * directory, this is invoked as func(f), where 'f' is a FileName * object describing the file. If 'recursive' is true, the method * recursively scans the contents of subdirectories; if 'recursive' * is nil or is omitted, only the direct contents of the directory * are scanned. */ forEachFile(func, recursive?); /* * Create a directory with the name contained in this object. The * file safety settings must allow write access to the parent folder. * * If 'createParents' is specified, it's a true or nil value * specifying whether or not to create intermediate parent * directories. The default is nil if it's omitted. If it's true, * and 'dirname' contains multiple path elements, any parents of the * named directory that don't already exist will be created as well. * For example, on Linux, if dirname is '/a/b/c', and directory '/a' * exists but not '/a/b', the routine will first create '/a/b' and * then create '/a/b/c'. */ createDirectory(createParents?); /* * Remove the directory named by this object. The file safety settings * must allow write access to the directory. * * If 'removeContents' is provided, it's a true or nil value specifying * whether or not to delete the contents of the directory before * deleting the directory itself. If this is true, and the directory * contains any files or subdirectories, the routine will attempt to * delete those contents before deleting the directory itself. Any * subdirectories will be recursively emptied and removed. For obvious * reasons, use caution when using this flag. If any of the contents * can't be deleted, the function will stop and throw an error. Note * that if this occurs, the function might have successfully deleted * some of the contents of the directory before encountering the error; * those deletions won't be undone. * * If 'removeContents' is omitted or nil, and the directory isn't * already empty, the method simply returns nil (indicating failure) * without deleting anything. This is the default because it helps * avoid accidentally deleting contents that the application didn't * explicitly choose to remove. (Special system files that are always * present, such as "." and ".." on Unix, don't count when determining * if the directory is empty.) */ removeDirectory(removeContents?); } /* ------------------------------------------------------------------------ */ /* * File type constants. These are returned from getFileType(), and from * getFileInfo() in the fileType property. These are bit flags, so test * for them using (fileType & FileTypeXxx). */ /* ordinary file (on disk or similar storage device) */ #define FileTypeFile 0x0001 /* directory (folder) */ #define FileTypeDir 0x0002 /* character-mode device (e.g., console) */ #define FileTypeChar 0x0004 /* block-mode device (e.g., Linux raw disk device) */ #define FileTypeBlock 0x0008 /* pipe (sometimes called a FIFO) or similar interprocess channel */ #define FileTypePipe 0x0010 /* network socket */ #define FileTypeSocket 0x0020 /* symbolic link (a filename that links to another file or directory) */ #define FileTypeLink 0x0040 /* special system-defined directory link to self (such as Unix ".") */ #define FileTypeSelfLink 0x0080 /* special system-defined parent directory link (such as Unix "..") */ #define FileTypeParentLink 0x0100 /* ------------------------------------------------------------------------ */ /* * File attribute constants. These are returned from getFileInfo() in the * fileAttrs property. These are bit flags, so test for them using * (fileAttrs & FileAttrXxx). */ /* * Hidden file. When this attribute is set, the file should be omitted * from default views in the user interface and from wildcard matches in * user commands (e.g., "rm *"). On some systems, a naming convention is * used to mark files as hidden, such as ".xxx" files on Unix; on other * systems, there's formal file system metadata corresponding to this * attribute, such as on Windows. Note that actually hiding files marked * as hidden is up to the user interface; at a programmatic level, hidden * files are treated the same as any other file, and in particular they're * included in listDir() results. It's up to the caller to decide whether * or not to filter hidden files out of listDir() results, and if so to do * the filtering. The hidden attribute isn't enforced as a security or * permissions mechanism in the file system; it doesn't prevent a user from * explicitly viewing or deleting a file. It's merely designed as a * convenience for the user, to reduce clutter in normal directory listings * by filtering out system or application files (such as preference files, * caches, or indices) that the user doesn't normally access directly. */ #define FileAttrHidden 0x0001 /* * System file. This is a file system attribute on some systems (notably * Windows) that marks a file as belonging to or being part of the * operating system. For practical purposes, system files should be * treated the same as hidden files; the only reason we distinguish * "system" as a separate attribute from "hidden" is to allow applications * to display the two attributes separately when presenting file * information to the user, who might expect to see both attributes on * systems where both exist. There's no equivalent of this attribute on * most systems other than DOS and Windows; it won't ever appear in a * file's attributes on systems where there's no equivalent. */ #define FileAttrSystem 0x0002 /* * The file is readable by the current process. If this is set, it means * that the program has the necessary ownership and access privileges to * read the file. It's not guaranteed that a given attempt to read the * file will actually succeed, since other conditions could arise, such as * physical media errors or locking by another process that prevents * concurrent access. */ #define FileAttrRead 0x0004 /* * The file is writable by the current process. If this is set, it means * that the program has the necessary ownership and access privileges to * write to the file. It's not guaranteed that a given attempt to write to * the file will actually succeed, since other conditions could arise, such * as insufficient disk space, physical media errors, or locking by another * process that prevents concurrent access. */ #define FileAttrWrite 0x0008
TADS 3 Library Manual
Generated on 5/16/2013 from TADS version 3.1.3
Generated on 5/16/2013 from TADS version 3.1.3