00001 /*!@file Util/FileUtil.C Utility routines for working with filenames and files */ 00002 00003 // //////////////////////////////////////////////////////////////////// // 00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2000-2005 // 00005 // by the University of Southern California (USC) and the iLab at USC. // 00006 // See http://iLab.usc.edu for information about this project. // 00007 // //////////////////////////////////////////////////////////////////// // 00008 // Major portions of the iLab Neuromorphic Vision Toolkit are protected // 00009 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency // 00010 // in Visual Environments, and Applications'' by Christof Koch and // 00011 // Laurent Itti, California Institute of Technology, 2001 (patent // 00012 // pending; application number 09/912,225 filed July 23, 2001; see // 00013 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status). // 00014 // //////////////////////////////////////////////////////////////////// // 00015 // This file is part of the iLab Neuromorphic Vision C++ Toolkit. // 00016 // // 00017 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can // 00018 // redistribute it and/or modify it under the terms of the GNU General // 00019 // Public License as published by the Free Software Foundation; either // 00020 // version 2 of the License, or (at your option) any later version. // 00021 // // 00022 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope // 00023 // that it will be useful, but WITHOUT ANY WARRANTY; without even the // 00024 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // 00025 // PURPOSE. See the GNU General Public License for more details. // 00026 // // 00027 // You should have received a copy of the GNU General Public License // 00028 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write // 00029 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, // 00030 // Boston, MA 02111-1307 USA. // 00031 // //////////////////////////////////////////////////////////////////// // 00032 // 00033 // Primary maintainer for this file: Rob Peters <rjpeters at usc dot edu> 00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Util/FileUtil.C $ 00035 // $Id: FileUtil.C 8895 2007-10-24 22:14:24Z rjpeters $ 00036 // 00037 00038 #ifndef UTIL_FILEUTIL_C_DEFINED 00039 #define UTIL_FILEUTIL_C_DEFINED 00040 00041 #include "Util/FileUtil.H" 00042 00043 #include "Util/log.H" 00044 #include "rutz/bzip2stream.h" 00045 #include "rutz/gzstreambuf.h" 00046 #include "rutz/shared_ptr.h" 00047 00048 #include <cstring> 00049 #include <fstream> 00050 #include <sys/stat.h> // for mkdir(), stat() 00051 #include <sys/types.h> // for mkdir(), stat() 00052 #include <unistd.h> // for stat() 00053 00054 // ###################################################################### 00055 FILE* stdOutputFileOpen(const std::string& fname, bool* owned) 00056 { 00057 if (fname.compare("") == 0 00058 || fname.compare("-") == 0 00059 || fname.compare("stdout") == 0 00060 || fname.compare("STDOUT") == 0) 00061 { 00062 *owned = false; 00063 return stdout; 00064 } 00065 else if (fname.compare("stderr") == 0 00066 || fname.compare("STDERR") == 0) 00067 { 00068 *owned = false; 00069 return stderr; 00070 } 00071 00072 // else ... 00073 FILE* const result = fopen(fname.c_str(), "w"); 00074 00075 if (result == 0) 00076 LFATAL("couldn't open file '%s' for writing", 00077 fname.c_str()); 00078 00079 *owned = true; 00080 return result; 00081 } 00082 00083 // ###################################################################### 00084 bool hasExtension(const std::string& str, const std::string& ext) 00085 { 00086 if (ext.length() > str.length()) 00087 return false; 00088 00089 return (strcasecmp(str.c_str() + (str.length() - ext.length()), 00090 ext.c_str()) 00091 == 0); 00092 } 00093 00094 // ###################################################################### 00095 std::string dotExtension(const std::string& in) 00096 { 00097 std::string::size_type slash = in.rfind('/'); 00098 std::string::size_type dot = in.rfind('.'); 00099 00100 if (dot != in.npos && (slash == std::string::npos || dot > slash)) 00101 return in.substr(dot); 00102 // else ... 00103 return std::string(); 00104 } 00105 00106 // ###################################################################### 00107 std::string nodotExtension(const std::string& in, 00108 std::string* base_out) 00109 { 00110 std::string::size_type slash = in.rfind('/'); 00111 std::string::size_type dot = in.rfind('.'); 00112 00113 const bool valid = 00114 dot != std::string::npos 00115 && (slash == std::string::npos || dot > slash) 00116 && dot+1 < in.size(); 00117 00118 const std::string ext = 00119 valid 00120 ? in.substr(dot+1) 00121 : std::string(); 00122 00123 const std::string base = 00124 valid 00125 ? in.substr(0, dot) 00126 : in; 00127 00128 // don't modify *base_out until we're after done fiddling with in, 00129 // because the caller may have passed the same string object for 00130 // both args, as in nodotExtension(foo, &foo) 00131 if (base_out != 0) 00132 *base_out = base; 00133 00134 return ext; 00135 } 00136 00137 // ###################################################################### 00138 rutz::shared_ptr<std::istream> 00139 openMaybeCompressedFile(const std::string& fname) 00140 { 00141 if (hasExtension(fname, ".gz")) 00142 { 00143 return rutz::igzopen(fname.c_str()); 00144 } 00145 else if (hasExtension(fname, ".bz2")) 00146 { 00147 return rutz::ibzip2open(fname.c_str()); 00148 } 00149 // else... 00150 rutz::shared_ptr<std::ifstream> f = 00151 rutz::make_shared(new std::ifstream(fname.c_str())); 00152 00153 if (!f->is_open()) 00154 LFATAL("Couldn't open file '%s' for reading.", fname.c_str()); 00155 00156 return f; 00157 } 00158 00159 // ###################################################################### 00160 void splitPath(const std::string& fname, 00161 std::string& path, std::string& file) 00162 { 00163 std::string::size_type idx = fname.rfind('/'); 00164 if (idx == fname.npos) 00165 { 00166 path = ""; 00167 file = fname; 00168 } 00169 else 00170 { 00171 path = fname.substr(0, idx) + '/'; 00172 file = fname.substr(idx+1, fname.npos); 00173 } 00174 } 00175 00176 // ###################################################################### 00177 void makeDirectory(const std::string& dirname) 00178 { 00179 struct stat info; 00180 // see if the named file/directory exists 00181 if (stat(dirname.c_str(), &info) == 0) 00182 { 00183 if (S_ISDIR(info.st_mode)) 00184 return; 00185 else 00186 LFATAL("'%s' already exists but is not a directory", 00187 dirname.c_str()); 00188 } 00189 00190 if (mkdir(dirname.c_str(), S_IRWXU | S_IRWXG | S_IRWXO) != 0) 00191 LFATAL("couldn't mkdir '%s'", dirname.c_str()); 00192 } 00193 00194 // ###################################################################### 00195 bool isDirectory(const char* fname) 00196 { 00197 struct stat statbuf; 00198 errno = 0; 00199 if (stat(fname, &statbuf) != 0) 00200 { 00201 // OK, the stat itself failed, so fname can't be a directory: 00202 return false; 00203 } 00204 00205 return S_ISDIR(statbuf.st_mode); 00206 } 00207 00208 // ###################################################################### 00209 bool isDirectory(const struct dirent* dirp) 00210 { 00211 if (dirp == 0) 00212 return false; 00213 00214 #ifdef HAVE_STRUCT_DIRENT_D_TYPE 00215 return dirp->d_type == DT_DIR; 00216 #else 00217 return isDirectory(dirp->d_name); 00218 #endif 00219 } 00220 00221 // ###################################################################### 00222 ushort lockFile(const int fd, struct flock &fl) 00223 { 00224 if (fd < 0) 00225 { 00226 LFATAL("Attempt to lock an unopened file!"); 00227 } 00228 else 00229 { 00230 struct flock fl; 00231 fl.l_type = F_WRLCK; 00232 fl.l_whence = SEEK_SET; 00233 fl.l_start = 0; 00234 fl.l_len = 0; 00235 if (fcntl(fd, F_SETLK, &fl) == -1) 00236 { 00237 return errno; 00238 } 00239 } 00240 return 0; 00241 } 00242 00243 // ###################################################################### 00244 ushort unlockFile(const int fd, struct flock &fl) 00245 { 00246 fl.l_type = F_UNLCK; 00247 fl.l_whence = SEEK_SET; 00248 fl.l_start = 0; 00249 fl.l_len = 0; 00250 if (fcntl(fd, F_SETLK, &fl) == -1) 00251 { 00252 return 1; 00253 } 00254 00255 return 0; 00256 } 00257 00258 // ###################################################################### 00259 ushort lockFile(const std::string fileName, int &fd, struct flock &fl) 00260 { 00261 fd = open(fileName.c_str(), O_RDWR); 00262 return lockFile(fd,fl); 00263 } 00264 00265 // ###################################################################### 00266 ushort unlockFile(const std::string fileName, const int fd, struct flock &fl) 00267 { 00268 const ushort err = unlockFile(fd,fl); 00269 close(fd); 00270 return err; 00271 } 00272 00273 // ###################################################################### 00274 /* So things look consistent in everyone's emacs... */ 00275 /* Local Variables: */ 00276 /* mode: c++ */ 00277 /* indent-tabs-mode: nil */ 00278 /* End: */ 00279 00280 #endif // UTIL_FILEUTIL_C_DEFINED