Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members

file.h

Go to the documentation of this file.
00001 #ifndef DV_UTIL_FILE_H 00002 #define DV_UTIL_FILE_H 00003 // $Id: file.h,v 1.28 2004/12/22 10:41:43 dvermeir Exp $ 00004 #include <sys/types.h> 00005 #include <sys/stat.h> 00006 #include <string> 00007 #include <vector> 00008 #include <stdexcept> 00009 #include <iostream> 00010 00011 00012 /** \file 00013 * 00014 * A \ref Dv::Util::File class object represents a pathname, possibly 00015 * associated with an existing file. 00016 * 00017 * Member functions are provided for retrieving or altering properties 00018 * such as existence, permissions, ownership etc. In addition, 00019 * memory-mapping the contents of a File is also supported. 00020 * A \ref Dv::Util::Directory class object represents a pathname, 00021 * possibly associated with an existing directory. It provides similar 00022 * functionality as File, augmented with the retrieval of the 00023 * directory's contents. 00024 */ 00025 namespace Dv { 00026 namespace Util { 00027 /** 00028 * A runtime exception thrown by some File operations. 00029 */ 00030 class FileError: public std::runtime_error { 00031 public: 00032 /** 00033 * Name of class, is prepended to each message argument of the constructor. 00034 */ 00035 static const std::string NAME; 00036 /** 00037 * Constructor, prepends NAME to message to obtain runtime_error::what(). 00038 */ 00039 FileError(const std::string& message): std::runtime_error(NAME+": "+message) {} 00040 }; 00041 00042 /** 00043 * A File objects represents a pathname, possibly an existing file. 00044 * 00045 * Example usage: 00046 * 00047 * \code 00048 * const char* name; 00049 * File f(name); 00050 * if (f.exists()) { 00051 * Date d(f.last_modified()); 00052 * 00053 * cout << f.str() << endl; 00054 * cout << std::string(d) << endl; 00055 * 00056 * const char* pc = static_cast<const char*>(f.map()); 00057 * 00058 * if (pc) // note: pc is not necessarily a C string 00059 * for (unsigned int i=0;(i<f.size());++i,++pc) 00060 * cout << *pc; 00061 * } 00062 * else 00063 * f.touch(); // make it exist 00064 * \endcode 00065 */ 00066 00067 class File { 00068 public: 00069 /** 00070 * Type of file, note NONEXISTENT for pathnames that do not refer to 00071 * a file. 00072 */ 00073 enum Type { REGULAR, SYMLINK, DIRECTORY, SPECIALCHAR, 00074 SPECIALBLOCK, FIFO, SOCKET, OTHER, NONEXISTENT }; 00075 /** 00076 * File permissions, you can use the | operator to combine them. 00077 */ 00078 enum Mode { READ_OWNER = 0400, WRITE_OWNER = 0200, EXEC_OWNER = 0100, 00079 READ_GROUP = 040, WRITE_GROUP = 020, EXEC_GROUP = 010, 00080 READ_OTHER = 04, WRITE_OTHER = 02, EXEC_OTHER = 01, 00081 SETUID = 04000, SETGID = 02000, 00082 RWX_OWNER = 0700, RWX_GROUP = 070, RWX_OTHER = 07, 00083 RW_OWNER = 0600, RW_GROUP = 060, RW_OTHER = 06 00084 }; 00085 00086 /** 00087 * Constructor, argument can be a relative or an absolute path. 00088 * \param path absolute or relative path 00089 */ 00090 File(const std::string& path) throw (FileError); 00091 /** 00092 * Copy constructor. 00093 * \param f existing File object 00094 * \warning 00095 * \code 00096 * File f(g); 00097 * \endcode 00098 * is equivalent with 00099 * \code 00100 * File f(g.str()); 00101 * \endcode 00102 */ 00103 File(const File& f) throw (FileError); 00104 /** 00105 * Assignment. 00106 * \param f existing File object 00107 * \warning 00108 * \code 00109 * f = g; 00110 * \endcode 00111 * is, if \a &f!=&g , equivalent with 00112 * \code 00113 * File f(g.str()); 00114 * \endcode 00115 */ 00116 File& operator=(const File& f) throw (FileError); 00117 /** 00118 * Virtual destructor, calls unmap(). 00119 */ 00120 virtual ~File(); 00121 /** 00122 * Change File object to a non-symbolic link file by 00123 * expanding symbolic links, if any. 00124 * \return reference to \a *this. 00125 * \exception FileError 00126 * e.g. if there are too many symbolic links to follow. 00127 */ 00128 File& expand() throw (FileError); 00129 00130 /** Return string representation of File::Type. */ 00131 static const std::string& typestr(Type) throw (FileError); 00132 /** Check existence of file. */ 00133 bool exists() const throw (FileError) { refresh(); return exist_; } 00134 /** Delegates to exists(). */ 00135 operator bool() const throw (FileError) { return exists(); } 00136 00137 /** Returns a full, clean, absolute path as given by ::realpath(3C). 00138 * @warning For symbolic links the path used in the constructor is returned. 00139 */ 00140 std::string str() const { return path_; } 00141 /** Returns a full, clean, absolute path as given by ::realpath(3C). 00142 * @warning For symbolic links the path used in the constructor is returned. 00143 */ 00144 static std::string absolute_path(const std::string& path) throw (FileError); 00145 00146 /** Delegates to str(). */ 00147 operator const char*() const { return path_.c_str(); } 00148 /** 00149 * Identical to str().c_str(). 00150 * \return \a str().c_str() 00151 * \warning 00152 * For symbolic links the path used in the constructor is returned. 00153 */ 00154 const char* path() const { return path_.c_str(); } 00155 /** 00156 * Retrieve full path without resolving symbolic links. 00157 * The result is absolute and does not contain '..' or '.' 00158 * components and no superfluous '/' chars. 00159 * \param path relative or absolute path 00160 * \param resolved_path (output) 00161 * \return reference to second parameter 00162 * \exception if the full path would climb up from \a '/', 00163 * e.g. '/..' would throw an exception. 00164 * An empty \a path will also throw an exception. 00165 */ 00166 static std::string& fullpath(std::string path, std::string& resolved_path) 00167 throw (FileError); 00168 00169 /** 00170 * Retrieve full path without resolving symbolic links. 00171 * The result is absolute and does not contain '..' or '.' 00172 * components and no superfluous '/' chars. 00173 * \return resolved path. 00174 * \exception if the full path would climb up from \a '/', 00175 * e.g. '/..' would throw an exception. 00176 * An empty \a path will also throw an exception. 00177 */ 00178 std::string fullpath() const throw (FileError); 00179 00180 /** Only useful for symbolic links. */ 00181 std::string realpath() const throw (FileError); 00182 /** 00183 * Return path relative to from, which must be absolute. 00184 * \param from path such that \a from/relpath(from) 00185 * refers to this file 00186 * \return relative path \a x such that \a from/x refers to 00187 * this file 00188 */ 00189 std::string relpath(const std::string& from) const throw (FileError); 00190 /** 00191 * Return path relative to Directory::pwd() 00192 * \return relpath(pwd()) 00193 */ 00194 std::string relpath() const throw (FileError); 00195 /** Return type of file (possibly File::NONEXISTENT). */ 00196 Type type() const throw (FileError); 00197 /** Return true iff type() == File::DIRECTORY. */ 00198 bool isdir() const throw (FileError) { return type() == DIRECTORY; } 00199 /** Return size in bytes of file, 0 if \a !exists(). */ 00200 size_t size() const throw (FileError); 00201 /** 00202 * Return time of last modification of file, or 0 if it does not 00203 * exist. 00204 */ 00205 time_t last_modified() const throw (FileError); 00206 /** 00207 * Return time of last access to file, or 0 if it does not exist. 00208 */ 00209 time_t last_accessed() const throw (FileError); 00210 /** 00211 * Return permissions of file, \sa File::Mode. 00212 */ 00213 mode_t mode() const throw (FileError); 00214 /** Return uid of owner of file \sa Dv::Util::User. */ 00215 uid_t owner() const throw (FileError); 00216 /** Return gid of group-owner of file \sa Dv::Util::User. */ 00217 gid_t group() const throw (FileError); 00218 00219 /** 00220 * Change the ownership of an existing file, return true iff successful. 00221 * \param uid id of new owner. 00222 * \return true iff new owner is \a uid. 00223 */ 00224 bool chown(uid_t uid) const throw (FileError); 00225 /** 00226 * Change group-ownership of an existing file, return true iff successful. 00227 * \param groupname of new group owner. 00228 * \return true iff new group owner is \a groupname. 00229 */ 00230 bool chgrp(const char* groupname) const throw (FileError); 00231 /** 00232 * Change permissions on an existing file. 00233 * \param mode representing permissions. 00234 * \return true iff permissions where succesfully set. 00235 * \sa File::Mode 00236 */ 00237 bool chmod(int mode=0755) throw (FileError); 00238 /** 00239 * Remove a file, for directories, rmdir is used. 00240 * \return true if \a exists() false afterwards. 00241 */ 00242 bool rm() throw (FileError); 00243 /** Like rm -fr. Throws FileError if exists() afterwards. */ 00244 void rmfr() throw (FileError); 00245 /** 00246 * Rename file, return true iff succeeds, also renames *this. 00247 * \param newpath new name of file. 00248 * \return true iff rename succeeded. 00249 */ 00250 bool mv(const std::string& newpath) throw (FileError); 00251 /** Creates or updates modification time of file. */ 00252 bool touch(int mode=0644) throw (FileError); 00253 /** Create a directory str(), precondition is !exists(). */ 00254 bool mkdir(int mode=0755) throw (FileError); 00255 /** Create a hard link to path, precondition is !exists(). */ 00256 bool mklink(const std::string& path) throw (FileError); 00257 /** 00258 * Create a symbolic link to path. 00259 * \return false if the file already exists, true if 00260 * the link was succesfully created. 00261 * \pre exists() returns false 00262 * \warning 00263 * There is no check on the path parameter. 00264 */ 00265 bool mksymlink(const std::string& path) throw (FileError); 00266 00267 /** 00268 * Compare File objects. 00269 * 00270 * File comparison is independent of the name, the operator 00271 * compares i-nodes and devices. Nonexistent File objects 00272 * are never equal. 00273 * \warning This function does not expand symbolic links. 00274 * Thus, if \a s is a symbolic link to \a f, \a s and 00275 * \a f will be different. 00276 */ 00277 friend bool operator==(const File&,const File&); 00278 /** 00279 * Compare File objects. 00280 * 00281 * File comparison is independent of the name, the operator 00282 * compares i-nodes and devices. Nonexistent File objects 00283 * are never equal. 00284 * \warning This function does not expand symbolic links. 00285 * Thus, if \a s is a symbolic link to \a f, \a s and 00286 * \a f will be different. 00287 */ 00288 friend bool operator!=(const File& f1,const File& f2) { return ! (f1==f2); } 00289 /** 00290 * Compare File objects. 00291 * 00292 * File comparison is independent of the name, the operator 00293 * compares i-nodes and devices. Nonexistent File objects 00294 * are never equal. 00295 * \warning This function does not expand symbolic links. 00296 * Thus, if \a s is a symbolic link to \a f, \a s and 00297 * \a f will be different. 00298 */ 00299 friend bool operator<(const File&,const File&); 00300 00301 /** 00302 * Map the contents of an existing file into memory. Return 0 upon failure. 00303 * Map() returns a pointer to the contents of the file, mapped into 00304 * virtual memory 00305 * \warning the returned pointer is not a C string, use size() to 00306 * obtain the size of the map. 00307 */ 00308 const void* map() throw (FileError); 00309 /** 00310 * Release a mapping, if any, obtained by File::map(). 00311 * Unmapping a file that is not mapped is a noop. 00312 * File::unmap() is automatically called by the destructor. 00313 * \exception throws a FileError iff munmap(2) failed. 00314 */ 00315 void unmap() throw (FileError); 00316 /** @return address of map for mapped file, or 0 otherwise. */ 00317 const void* mapped() const { return addr_; } 00318 00319 /** Append contents of file to string. 00320 * @param s string to append to 00321 * @return reference to s 00322 */ 00323 std::string& content(std::string& s) const throw (FileError); 00324 00325 /** Return contents of file to string. 00326 * @return contents of file 00327 */ 00328 std::string content() const throw (FileError); 00329 00330 protected: 00331 /** Updates private data members, exist_ and type_. */ 00332 virtual void refresh() const throw (FileError); 00333 /** True iff there is a file with pathname str(). */ 00334 bool exist_; // updated by refresh() 00335 /** Type of file. */ 00336 Type type_; 00337 private: 00338 struct stat stats_; // updated by refresh() 00339 std::string path_; 00340 void* addr_; 00341 }; 00342 00343 /** 00344 * A Directory represents a pathname that refers to a possibly 00345 * non-existing directory. It is privately derived from File, 00346 * relevant File members are available, 00347 * in addition tot the files() member that retrieves the files in an 00348 * existing directory. 00349 * 00350 * \par 00351 * The following File members are available also in Directory: 00352 * 00353 * File::exists, 00354 * File::mkdir, 00355 * File::path, 00356 * File::str, 00357 * File::realpath, 00358 * File::relpath, 00359 * File::last_modified, 00360 * File::last_accessed, 00361 * File::touch, 00362 * File::chown, 00363 * File::chgrp, 00364 * File::chmod, 00365 * File::rm, 00366 * File::mv, 00367 * File::rmfr 00368 */ 00369 class Directory: private File { 00370 public: // a directory always exists 00371 /** Constructor, note that path may not exist. */ 00372 Directory(const std::string& path) throw (FileError); 00373 /** Equivalent to Directory(file.str()); */ 00374 Directory(const File& file) throw (FileError); 00375 /** Destructor. */ 00376 ~Directory(); 00377 00378 /** 00379 * Return files (only filenames, not absolute paths) in the directory. 00380 * If the directory does not exist, the vector is empty. 00381 * The directory entries ``.'' and ``..'' are not included 00382 * in the output of Directory::files(). 00383 */ 00384 const std::vector<std::string>& files() const throw (FileError) { 00385 refresh(); return files_; } 00386 /** 00387 * Return str()+"/"+filename, i.e. a pathname for a filename in directory. 00388 */ 00389 std::string file(const std::string& filename) const; 00390 /** 00391 * Return \a str()+"/"+temp_filename, where \a temp_filename starts 00392 * with \a prefix, i.e. a pathname for a temporary file in the directory. 00393 * @param prefix of name of file to be created in this directory. 00394 * @return the filename 00395 * \warning This function calls mkstemp() which will actually create 00396 * the corresponding file. 00397 */ 00398 std::string tempfile(const std::string& prefix) const throw (FileError); 00399 00400 /** 00401 * Return @a str()+"/"+temp_dirname, where \a temp_dirname starts 00402 * with @a prefix, i.e. a pathname for a temporary subdirectory in the directory. 00403 * @param prefix of name of file to be created in this directory. 00404 * @return the directoryname 00405 * @warning This function calls mkdtemp() which will actually create 00406 * the corresponding directory. 00407 */ 00408 std::string tempdir(const std::string& prefix) const throw (FileError); 00409 00410 /** Change working directory. */ 00411 bool cd() const throw (FileError); 00412 /** Return absolute pathname of current working directory. */ 00413 static std::string pwd() throw (FileError); 00414 00415 /** \sa File::exists */ 00416 using File::exists; 00417 /** \sa File::mkdir */ 00418 using File::mkdir; 00419 /** \sa File::path */ 00420 using File::path; 00421 /** \sa File::str */ 00422 using File::str; 00423 /** \sa File::realpath */ 00424 using File::realpath; 00425 /** \sa File::relpath */ 00426 using File::relpath; 00427 /** \sa File::last_modified */ 00428 using File::last_modified; 00429 /** \sa File::last_accessed */ 00430 using File::last_accessed; 00431 /** \sa File::touch */ 00432 using File::touch; 00433 /** \sa File::chown */ 00434 using File::chown; 00435 /** \sa File::chgrp */ 00436 using File::chgrp; 00437 /** \sa File::chmod */ 00438 using File::chmod; 00439 /** \sa File::rm */ 00440 using File::rm; 00441 /** \sa File::mv */ 00442 using File::mv; 00443 /** \sa File::rmfr */ 00444 using File::rmfr; 00445 00446 00447 private: 00448 void refresh() const throw (FileError); 00449 void init() const throw (FileError); 00450 00451 std::vector<std::string> files_; 00452 }; 00453 }} 00454 #endif

dvutil-0.13.15 [30 December, 2004]