• Main Page
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

ibrcommon/ibrcommon/data/File.cpp

Go to the documentation of this file.
00001 /*
00002  * File.cpp
00003  *
00004  *  Created on: 20.11.2009
00005  *      Author: morgenro
00006  */
00007 
00008 #include "ibrcommon/config.h"
00009 #include "ibrcommon/data/File.h"
00010 #include <sstream>
00011 #include <errno.h>
00012 #include <sys/stat.h>
00013 #include <stdio.h>
00014 #include <string.h>
00015 #include <stdlib.h>
00016 #include <fcntl.h>
00017 
00018 namespace ibrcommon
00019 {
00020         File::File()
00021          : _path(), _type(DT_UNKNOWN)
00022         {
00023         }
00024 
00025         File::File(const string path, const unsigned char t)
00026          : _path(path), _type(t)
00027         {
00028                 resolveAbsolutePath();
00029                 removeSlash();
00030         }
00031 
00032         File::File(const string path)
00033          : _path(path), _type(DT_UNKNOWN)
00034         {
00035                 resolveAbsolutePath();
00036                 removeSlash();
00037                 update();
00038         }
00039 
00040         void File::removeSlash()
00041         {
00042                 std::string::iterator iter = _path.end(); iter--;
00043 
00044                 if ((*iter) == '/')
00045                 {
00046                         _path.erase(iter);
00047                 }
00048         }
00049 
00050         void File::resolveAbsolutePath()
00051         {
00052                 std::string::iterator iter = _path.begin();
00053 
00054                 if ((*iter) != '/')
00055                 {
00056                         _path = "./" + _path;
00057                 }
00058         }
00059 
00060         bool File::exists() const
00061         {
00062                 struct stat st;
00063                 if( stat(_path.c_str(), &st ) == 0)
00064                         return true;
00065 
00066                 return false;
00067         }
00068 
00069         void File::update()
00070         {
00071                 struct stat s;
00072                 int type;
00073 
00074                 if ( stat(_path.c_str(), &s) == 0 )
00075                 {
00076                         type = s.st_mode & S_IFMT;
00077 
00078                         switch (type)
00079                         {
00080                                 case S_IFREG:
00081                                         _type = DT_REG;
00082                                         break;
00083 
00084                                 case S_IFLNK:
00085                                         _type = DT_LNK;
00086                                         break;
00087 
00088                                 case S_IFDIR:
00089                                         _type = DT_DIR;
00090                                         break;
00091 
00092                                 default:
00093                                         _type = DT_UNKNOWN;
00094                                         break;
00095                         }
00096                 }
00097         }
00098 
00099         File::~File()
00100         {}
00101 
00102         unsigned char File::getType() const
00103         {
00104                 return _type;
00105         }
00106 
00107         int File::getFiles(list<File> &files)
00108         {
00109                 if (!isDirectory()) return -1;
00110 
00111                 DIR *dp;
00112                 struct dirent *dirp;
00113                 if((dp = opendir(_path.c_str())) == NULL) {
00114                         return errno;
00115                 }
00116 
00117                 while ((dirp = readdir(dp)) != NULL)
00118                 {
00119                         string name = string(dirp->d_name);
00120                         stringstream ss; ss << getPath() << "/" << name;
00121                         File file(ss.str(), dirp->d_type);
00122                         files.push_back(file);
00123                 }
00124                 closedir(dp);
00125 
00126                 return 0;
00127         }
00128 
00129         bool File::isSystem() const
00130         {
00131                 try {
00132                         if ((_path.substr(_path.length() - 2, 2) == "..") || (_path.substr(_path.length() - 1, 1) == ".")) return true;
00133                 } catch (std::out_of_range) {
00134                         return false;
00135                 }
00136                 return false;
00137         }
00138 
00139         bool File::isDirectory() const
00140         {
00141                 if (_type == DT_DIR) return true;
00142                 return false;
00143         }
00144 
00145         string File::getPath() const
00146         {
00147                 return _path;
00148         }
00149 
00150         File File::get(string filename) const
00151         {
00152                 stringstream ss; ss << getPath() << "/" << filename;
00153                 File file(ss.str());
00154 
00155                 return file;
00156         }
00157 
00158         int File::remove(bool recursive)
00159         {
00160                 int ret;
00161 
00162                 if (isSystem()) return -1;
00163                 if (_type == DT_UNKNOWN) return -1;
00164 
00165                 if (isDirectory())
00166                 {
00167                         if (recursive)
00168                         {
00169                                 // container for all files
00170                                 list<File> files;
00171 
00172                                 // get all files in this directory
00173                                 if ((ret = getFiles(files)) < 0)
00174                                         return ret;
00175 
00176                                 for (list<File>::iterator iter = files.begin(); iter != files.end(); iter++)
00177                                 {
00178                                         if (!(*iter).isSystem())
00179                                         {
00180                                                 if ((ret = (*iter).remove(recursive)) < 0)
00181                                                         return ret;
00182                                         }
00183                                 }
00184                         }
00185 
00186                         ::rmdir(getPath().c_str());
00187                 }
00188                 else
00189                 {
00190 			::remove(getPath().c_str());
00191                 }
00192 
00193                 return 0;
00194         }
00195 
00196         File File::getParent() const
00197         {
00198                 size_t pos = _path.find_last_of('/');
00199                 return File(_path.substr(0, pos));
00200         }
00201 
00202         void File::createDirectory(File &path)
00203         {
00204                 if (!path.exists())
00205                 {
00206                         File parent = path.getParent();
00207                         File::createDirectory(parent);
00208 
00209                         // create path
00210                         ::mkdir(path.getPath().c_str(), 0700);
00211 
00212                         // update file information
00213                         path.update();
00214                 }
00215         }
00216 
00217         size_t File::size() const
00218         {
00219                 struct stat filestatus;
00220                 stat( getPath().c_str(), &filestatus );
00221                 return filestatus.st_size;
00222         }
00223 
00224         TemporaryFile::TemporaryFile(const File &path, const std::string prefix)
00225          : File(tmpname(path, prefix))
00226         {
00227         }
00228 
00229         TemporaryFile::~TemporaryFile()
00230         {
00231         }
00232 
00233         std::string TemporaryFile::tmpname(const File &path, const std::string prefix)
00234         {
00235                 std::string pattern = path.getPath() + "/" + prefix + "XXXXXXXX";
00236                 char name[pattern.length()];
00237                 ::strcpy(name, pattern.c_str());
00238 
00239                 int fd = mkstemp(name);
00240                 if (fd == -1) throw ibrcommon::IOException("Could not create a temporary name.");
00241                 ::close(fd);
00242 
00243                 return std::string(name);
00244         }
00245 
00246         locked_ifstream::locked_ifstream(File &file, ios_base::openmode mode)
00247 #ifdef USE_FILE_LOCKING
00248          : _buf(NULL), _stream(NULL), _fd(0)
00249 #endif
00250         {
00251                 open(file, mode);
00252         }
00253 
00254         locked_ifstream::~locked_ifstream()
00255         {
00256                 close();
00257         }
00258 
00259         void locked_ifstream::open(File &file, ios_base::openmode mode)
00260         {
00261 #ifdef USE_FILE_LOCKING
00262                 _fd = ::open(file.getPath().c_str(), locked_fstream::getopts(mode));
00263 
00264                 flock lock = { F_RDLCK, SEEK_SET, 0, 0, 0 };
00265                 fcntl(_fd, F_SETLKW, &lock);
00266 
00267                 _buf = new __gnu_cxx::stdio_filebuf<char>(_fd, mode);
00268                 _stream = new std::istream(_buf);
00269 #else
00270                 _stream.open(file.getPath().c_str(), mode);
00271 #endif
00272         }
00273 
00274         bool locked_ifstream::is_open()
00275         {
00276 #ifdef USE_FILE_LOCKING
00277                 return (_stream != NULL);
00278 #else
00279                 return _stream.is_open();
00280 #endif
00281         }
00282 
00283         void locked_ifstream::close()
00284         {
00285                 if (!is_open()) return;
00286 
00287 #ifdef USE_FILE_LOCKING
00288                 flock lock1 = { F_UNLCK, SEEK_SET, 0, 0, 0 };
00289                 fcntl(_fd, F_SETLKW, &lock1);
00290 
00291                 delete _stream; _stream = NULL;
00292                 delete _buf; _buf = NULL;
00293 		::close(_fd);
00294 #else
00295                 _stream.close();
00296 #endif
00297         }
00298 
00299         std::istream& locked_ifstream::operator*()
00300         {
00301                 if (!is_open()) throw ibrcommon::IOException("no file open");
00302 #ifdef USE_FILE_LOCKING
00303                 return *_stream;
00304 #else
00305                 return _stream;
00306 #endif
00307         }
00308 
00309         locked_ofstream::locked_ofstream(File &file, ios_base::openmode mode)
00310 #ifdef USE_FILE_LOCKING
00311          : _buf(NULL), _stream(NULL), _fd(0)
00312 #endif
00313         {
00314                 open(file, mode);
00315         }
00316 
00317         locked_ofstream::~locked_ofstream()
00318         {
00319                 close();
00320         }
00321 
00322         void locked_ofstream::open(File &file, ios_base::openmode mode)
00323         {
00324 #ifdef USE_FILE_LOCKING
00325                 _fd = ::open(file.getPath().c_str(), locked_fstream::getopts(mode));
00326 
00327                 flock lock = { F_WRLCK, SEEK_SET, 0, 0, 0 };
00328                 fcntl(_fd, F_SETLKW, &lock);
00329 
00330                 _buf = new __gnu_cxx::stdio_filebuf<char>(_fd, mode);
00331                 _stream = new std::ostream(_buf);
00332 
00333                 if (mode & ios_base::ate)
00334                 {
00335                         _stream->seekp(0, ios::end);
00336                 }
00337 #else
00338                 _stream.open(file.getPath().c_str(), mode);
00339 #endif
00340         }
00341 
00342         bool locked_ofstream::is_open()
00343         {
00344 #ifdef USE_FILE_LOCKING
00345                 return (_stream != NULL);
00346 #else
00347                 return _stream.is_open();
00348 #endif
00349         }
00350 
00351         void locked_ofstream::close()
00352         {
00353 #ifdef USE_FILE_LOCKING
00354                 if (!is_open()) return;
00355 
00356                 flock lock1 = { F_UNLCK, SEEK_SET, 0, 0, 0 };
00357                 fcntl(_fd, F_SETLKW, &lock1);
00358 
00359                 delete _stream; _stream = NULL;
00360                 delete _buf; _buf = NULL;
00361 		::close(_fd);
00362 #else
00363                 _stream.close();
00364 #endif
00365         }
00366 
00367         std::ostream& locked_ofstream::operator*()
00368         {
00369                 if (!is_open()) throw ibrcommon::IOException("no file open");
00370 #ifdef USE_FILE_LOCKING
00371                 return *_stream;
00372 #else
00373                 return _stream;
00374 #endif
00375         }
00376 
00377         locked_fstream::locked_fstream()
00378 #ifdef USE_FILE_LOCKING
00379          : _buf(NULL), _stream(NULL), _fd(0)
00380 #endif
00381         {
00382         }
00383 
00384         locked_fstream::locked_fstream(File &file, ios_base::openmode mode)
00385 #ifdef USE_FILE_LOCKING
00386          : _buf(NULL), _stream(NULL), _fd(0)
00387 #endif
00388         {
00389                 open(file, mode);
00390         }
00391 
00392         locked_fstream::~locked_fstream()
00393         {
00394                 close();
00395         }
00396 
00397         void locked_fstream::open(File &file, ios_base::openmode mode)
00398         {
00399 #ifdef USE_FILE_LOCKING
00400                 _fd = ::open(file.getPath().c_str(), locked_fstream::getopts(mode));
00401 
00402                 flock lock = { F_WRLCK, SEEK_SET, 0, 0, 0 };
00403                 fcntl(_fd, F_SETLKW, &lock);
00404 
00405                 _buf = new __gnu_cxx::stdio_filebuf<char>(_fd, mode);
00406                 _stream = new std::iostream(_buf);
00407 
00408                 if (mode & ios_base::ate)
00409                 {
00410                         _stream->seekp(0, ios::end);
00411                 }
00412 #else
00413                 _stream.open(file.getPath().c_str(), mode);
00414 #endif
00415         }
00416 
00417         bool locked_fstream::is_open()
00418         {
00419 #ifdef USE_FILE_LOCKING
00420                 return (_stream != NULL);
00421 #else
00422                 return _stream.is_open();
00423 #endif
00424         }
00425 
00426         void locked_fstream::close()
00427         {
00428                 if (!is_open()) return;
00429 
00430 #ifdef USE_FILE_LOCKING
00431                 flock lock1 = { F_UNLCK, SEEK_SET, 0, 0, 0 };
00432                 fcntl(_fd, F_SETLKW, &lock1);
00433 
00434                 delete _stream; _stream = NULL;
00435                 delete _buf; _buf = NULL;
00436 		::close(_fd);
00437 #else
00438                 _stream.close();
00439 #endif
00440         }
00441 
00442         std::iostream& locked_fstream::operator*()
00443         {
00444                 if (!is_open()) throw ibrcommon::IOException("no file open");
00445 #ifdef USE_FILE_LOCKING
00446                 return *_stream;
00447 #else
00448                 return _stream;
00449 #endif
00450         }
00451 
00452 #ifdef USE_FILE_LOCKING
00453         unsigned int locked_fstream::getopts(ios_base::openmode mode)
00454         {
00455                 unsigned int ret = 0;
00456                 if (mode & ios_base::app) ret += O_APPEND;
00457                 if (mode & ios_base::trunc) ret += O_TRUNC;
00458 
00459                 if (mode & (ios_base::in | ios_base::out)) ret += O_RDWR;
00460                 else
00461                 {
00462                         if (mode & ios_base::in) ret += O_RDONLY;
00463                         else if (mode & ios_base::out) ret += O_WRONLY;
00464                 }
00465 
00466                 // No translation for this!
00467                 //if (mode & ios_base::binary) ret += 0;
00468 
00469                 return ret;
00470         }
00471 #endif
00472 
00473 }

Generated on Thu Nov 11 2010 09:49:47 for IBR-DTNSuite by  doxygen 1.7.1