FileUtil.C

Go to the documentation of this file.
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
Generated on Sun May 8 08:42:26 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3