FileMgr Class Reference

#include <filemgr.h>

Inheritance diagram for FileMgr:
Inheritance graph
[legend]
Collaboration diagram for FileMgr:
Collaboration graph
[legend]

List of all members.

Public Member Functions

void close (FileDesc *file)
 FileMgr (int maxFiles=35)
virtual void flush ()
virtual long lastAccess ()
FileDescopen (const char *path, int mode, int perms=IREAD|IWRITE, bool tryDowngrade=false)
FileDescopen (const char *path, int mode, bool tryDowngrade)
virtual long resourceConsumption ()
signed char trunc (FileDesc *file)
 ~FileMgr ()

Static Public Member Functions

static int copyDir (const char *srcDir, const char *destDir)
static int copyFile (const char *srcFile, const char *destFile)
static int createParent (const char *pName)
static int createPathAndFile (const char *fName)
static signed char existsDir (const char *ipath, const char *idirName=0)
static signed char existsFile (const char *ipath, const char *ifileName=0)
static char getLine (FileDesc *fDesc, SWBuf &line)
static FileMgrgetSystemFileMgr ()
static char isDirectory (const char *path)
static int openFileReadOnly (const char *fName)
static int removeDir (const char *targetDir)
static int removeFile (const char *fName)
static void setSystemFileMgr (FileMgr *newFileMgr)

Public Attributes

int maxFiles

Static Public Attributes

static int APPEND = O_APPEND
static int CREAT = O_CREAT
static int IREAD = S_IREAD
static int IWRITE = S_IWRITE
static int RDONLY = O_RDONLY
static int RDWR = O_RDWR
static int TRUNC = O_TRUNC
static int WRONLY = O_WRONLY

Static Protected Attributes

static FileMgrsystemFileMgr = 0

Private Member Functions

int sysOpen (FileDesc *file)

Private Attributes

FileDescfiles

Friends

class __staticsystemFileMgr
class FileDesc

Detailed Description

This class ist used make file access operations easier. It keeps a list of all open files internally and closes them when the destructor is called.

Definition at line 85 of file filemgr.h.


Constructor & Destructor Documentation

FileMgr::FileMgr ( int  maxFiles = 35  ) 

Constructor.

Parameters:
maxFiles The number of files that this FileMgr may open in parallel, if necessary.

Definition at line 157 of file filemgr.cpp.

00157                              {
00158     this->maxFiles = maxFiles;      // must be at least 2
00159     files = 0;
00160 }

FileMgr::~FileMgr (  ) 

Destructor. Clean things up. Will close all files opened by this FileMgr object.

Definition at line 163 of file filemgr.cpp.

00163                   {
00164     FileDesc *tmp;
00165     
00166     while(files) {
00167         tmp = files->next;
00168         delete files;
00169         files = tmp;
00170     }
00171 }


Member Function Documentation

void FileMgr::close ( FileDesc file  ) 

Close a given file and delete its FileDesc object. Will only close the file if it was created by this FileMgr object.

Parameters:
file The file to close.

Definition at line 195 of file filemgr.cpp.

00195                                   {
00196     FileDesc **loop;
00197     
00198     for (loop = &files; *loop; loop = &((*loop)->next)) {
00199         if (*loop == file) {
00200             *loop = (*loop)->next;
00201             delete file;
00202             break;
00203         }
00204     }
00205 }

int FileMgr::copyDir ( const char *  srcDir,
const char *  destDir 
) [static]

Definition at line 508 of file filemgr.cpp.

00508                                                             {
00509     DIR *dir;
00510     struct dirent *ent;
00511     if ((dir = opendir(srcDir))) {
00512         rewinddir(dir);
00513         while ((ent = readdir(dir))) {
00514             if ((strcmp(ent->d_name, ".")) && (strcmp(ent->d_name, ".."))) {
00515                 SWBuf srcPath  = (SWBuf)srcDir  + (SWBuf)"/" + ent->d_name;
00516                 SWBuf destPath = (SWBuf)destDir + (SWBuf)"/" + ent->d_name;
00517                 if (!isDirectory(srcPath.c_str())) {
00518                     copyFile(srcPath.c_str(), destPath.c_str());
00519                 }
00520                 else {
00521                     copyDir(srcPath.c_str(), destPath.c_str());
00522                 }
00523             }
00524         }
00525         closedir(dir);
00526     }
00527     return 0;
00528 }

int FileMgr::copyFile ( const char *  srcFile,
const char *  destFile 
) [static]

Definition at line 410 of file filemgr.cpp.

00410                                                                     {
00411     int sfd, dfd, len;
00412     char buf[4096];
00413 
00414     if ((sfd = ::open(sourceFile, O_RDONLY|O_BINARY, S_IREAD|S_IWRITE|S_IRGRP|S_IROTH)) < 1)
00415         return -1;
00416     if ((dfd = createPathAndFile(targetFile)) < 1)
00417         return -1;
00418 
00419     do {
00420         len = read(sfd, buf, 4096);
00421         if (write(dfd, buf, len) != len) break;
00422     }
00423     while(len == 4096);	
00424 	::close(dfd);
00425 	::close(sfd);
00426     
00427     return 0;
00428 }

int FileMgr::createParent ( const char *  pName  )  [static]

Definition at line 358 of file filemgr.cpp.

00358                                            {
00359     char *buf = new char [ strlen(pName) + 1 ];
00360     int retCode = 0;
00361     
00362     strcpy(buf, pName);
00363     int end = strlen(buf) - 1;
00364     while (end) {
00365         if ((buf[end] == '/') || (buf[end] == '\\'))
00366             break;
00367         end--;
00368     }
00369     buf[end] = 0;
00370     if (strlen(buf)>0) {
00371         if (access(buf, 02)) {  // not exists with write access?
00372             if ((retCode = mkdir(buf
00373 #ifndef WIN32
00374                     , 0755
00375 #endif
00376                     ))) {
00377                 createParent(buf);
00378                 retCode = mkdir(buf
00379 #ifndef WIN32
00380                     , 0755
00381 #endif
00382                     );
00383             }
00384         }
00385     }
00386     else retCode = -1;
00387     delete [] buf;
00388     return retCode;
00389 }

int FileMgr::createPathAndFile ( const char *  fName  )  [static]

Definition at line 398 of file filemgr.cpp.

00398                                                 {
00399     int fd;
00400     
00401     fd = ::open(fName, O_CREAT|O_WRONLY|O_BINARY, S_IREAD|S_IWRITE|S_IRGRP|S_IROTH);
00402     if (fd < 1) {
00403         createParent(fName);
00404         fd = ::open(fName, O_CREAT|O_WRONLY|O_BINARY, S_IREAD|S_IWRITE|S_IRGRP|S_IROTH);
00405     }
00406     return fd;
00407 }

signed char FileMgr::existsDir ( const char *  ipath,
const char *  idirName = 0 
) [static]

Checks for the existence of a directory.

Parameters:
ipath Path to directory.
idirName Name of directory to check for.

Definition at line 336 of file filemgr.cpp.

00337 {
00338     char *ch;
00339     int len = strlen(ipath) + ((idirName)?strlen(idirName):0) + 1;
00340     if (idirName)
00341         len +=  strlen(idirName);
00342     char *path = new char [ len ];
00343     strcpy(path, ipath);
00344     
00345     if ((path[strlen(path)-1] == '\\') || (path[strlen(path)-1] == '/'))
00346         path[strlen(path)-1] = 0;
00347     
00348     if (idirName) {
00349         ch = path + strlen(path);
00350         sprintf(ch, "/%s", idirName);
00351     }
00352     signed char retVal = !access(path, 04);
00353     delete [] path;
00354     return retVal;
00355 }

signed char FileMgr::existsFile ( const char *  ipath,
const char *  ifileName = 0 
) [static]

Checks for the existence of a file.

Parameters:
ipath Path to file.
ifileName Name of file to check for.

Definition at line 316 of file filemgr.cpp.

00317 {
00318     int len = strlen(ipath) + ((ifileName)?strlen(ifileName):0) + 3;
00319     char *ch;
00320     char *path = new char [ len ];
00321     strcpy(path, ipath);
00322     
00323     if ((path[strlen(path)-1] == '\\') || (path[strlen(path)-1] == '/'))
00324         path[strlen(path)-1] = 0;
00325     
00326     if (ifileName) {
00327         ch = path + strlen(path);
00328         sprintf(ch, "/%s", ifileName);
00329     }
00330     signed char retVal = !access(path, 04);
00331     delete [] path;
00332     return retVal;
00333 }

void FileMgr::flush (  )  [virtual]

Cacher methods overridden

Reimplemented from SWCacher.

Definition at line 560 of file filemgr.cpp.

00560                     {
00561     FileDesc **loop;
00562     
00563     for (loop = &files; *loop; loop = &((*loop)->next)) {
00564         if ((*loop)->fd > 0) {
00565             (*loop)->offset = lseek((*loop)->fd, 0, SEEK_CUR);
00566 			::close((*loop)->fd);
00567             (*loop)->fd = -77;
00568         }
00569     }
00570 }

char FileMgr::getLine ( FileDesc fDesc,
SWBuf line 
) [static]

Definition at line 435 of file filemgr.cpp.

00435                                                   {
00436     int len;
00437     bool more = true;
00438     char chunk[255];
00439 
00440     line = "";
00441 
00442     // assert we have a valid file handle
00443     if (fDesc->getFd() < 1)
00444         return 0;
00445 
00446     while (more) {
00447         more = false;
00448         long index = fDesc->seek(0, SEEK_CUR);
00449         len = fDesc->read(chunk, 254);
00450 
00451         // assert we have a readable file (not a directory)
00452         if (len < 1)
00453             break;
00454 
00455         int start = 0;
00456         // clean up any preceding white space if we're at the beginning of line
00457         if (!line.length()) {
00458             for (;start < len; start++) {
00459                 if ((chunk[start] != 13) && (chunk[start] != ' ') && (chunk[start] != '\t'))
00460                     break;
00461             }
00462         }
00463 
00464         // find the end
00465         int end;
00466         for (end = start; ((end < (len-1)) && (chunk[end] != 10)); end++);
00467     
00468         if ((chunk[end] != 10) && (len == 254)) {
00469             more = true;
00470         }
00471         index += (end + 1);
00472 
00473         // reposition to next valid place to read
00474         fDesc->seek(index, SEEK_SET);
00475 
00476         // clean up any trailing junk on line if we're at the end
00477         if (!more) {
00478             for (; end > start; end--) {
00479                 if ((chunk[end] != 10) && (chunk[end] != 13) && (chunk[end] != ' ') && (chunk[end] != '\t')) {
00480                     if (chunk[end] == '\\') {
00481                         more = true;
00482                         end--;
00483                     }
00484                     break;
00485                 }
00486             }
00487         }
00488         
00489         int size = (end - start) + 1;
00490 
00491         if (size > 0) {
00492             // line.appendFormatted("%.*s", size, chunk+start);
00493             line.append(chunk+start, size);
00494         }
00495     }
00496     return ((len > 0) || line.length());
00497 }

FileMgr * FileMgr::getSystemFileMgr (  )  [static]

Definition at line 95 of file filemgr.cpp.

00095                                    {
00096     if (!systemFileMgr)
00097         systemFileMgr = new FileMgr();
00098 
00099     return systemFileMgr;
00100 }

char FileMgr::isDirectory ( const char *  path  )  [static]

Definition at line 500 of file filemgr.cpp.

00500                                           {
00501     struct stat stats;
00502     if (stat(path, &stats))
00503         return 0;
00504     return ((stats.st_mode & S_IFDIR) == S_IFDIR);
00505 }

long SWCacher::lastAccess (  )  [virtual, inherited]

Definition at line 43 of file swcacher.cpp.

00043                           {
00044     return 0;
00045 }

FileDesc * FileMgr::open ( const char *  path,
int  mode,
int  perms = IREAD | IWRITE,
bool  tryDowngrade = false 
)

Open a file and return a FileDesc for it. The file itself will only be opened when FileDesc::getFd() is called.

Parameters:
path Filename.
mode File access mode.
perms Permissions.
tryDowngrade 
Returns:
FileDesc object for the requested file.

Definition at line 179 of file filemgr.cpp.

00179                                                                                 {
00180     FileDesc **tmp, *tmp2;
00181     
00182     for (tmp = &files; *tmp; tmp = &((*tmp)->next)) {
00183         if ((*tmp)->fd < 0)     // insert as first non-system_open file
00184             break;
00185     }
00186 
00187     tmp2 = new FileDesc(this, path, mode, perms, tryDowngrade);
00188     tmp2->next = *tmp;
00189     *tmp = tmp2;
00190     
00191     return tmp2;
00192 }

FileDesc * FileMgr::open ( const char *  path,
int  mode,
bool  tryDowngrade 
)

Open a file and return a FileDesc for it. The file itself will only be opened when FileDesc::getFd() is called.

Parameters:
path Filename.
mode File access mode.
tryDowngrade 
Returns:
FileDesc object for the requested file.

Definition at line 174 of file filemgr.cpp.

00174                                                                      {
00175     return open(path, mode, S_IREAD|S_IWRITE|S_IRGRP|S_IROTH, tryDowngrade);
00176 }

int FileMgr::openFileReadOnly ( const char *  fName  )  [static]

attempts to open a file readonly

Parameters:
fName filename to open
Returns:
fd; < 0 = error

Definition at line 392 of file filemgr.cpp.

00392                                                {
00393     int fd = ::open(fName, O_RDONLY|O_BINARY, S_IREAD|S_IWRITE|S_IRGRP|S_IROTH);
00394     return fd;
00395 }

int FileMgr::removeDir ( const char *  targetDir  )  [static]

Definition at line 531 of file filemgr.cpp.

00531                                             {
00532     DIR *dir = opendir(targetDir);
00533     struct dirent *ent;
00534     if (dir) {
00535         rewinddir(dir);
00536         while ((ent = readdir(dir))) {
00537             if ((strcmp(ent->d_name, ".")) && (strcmp(ent->d_name, ".."))) {
00538                 SWBuf targetPath = (SWBuf)targetDir + (SWBuf)"/" + ent->d_name;
00539                 if (!isDirectory(targetPath.c_str())) {
00540                     FileMgr::removeFile(targetPath.c_str());
00541                 }
00542                 else {
00543                     FileMgr::removeDir(targetPath.c_str());
00544                 }
00545             }
00546         }
00547         closedir(dir);
00548         FileMgr::removeFile(targetDir);
00549 /*
00550         int status = FileMgr::removeFile(targetDir);
00551           int stuff = errno;
00552           char *err = strerror(errno);
00553           int x = stuff;
00554 */
00555     }
00556     return 0;
00557 }

int FileMgr::removeFile ( const char *  fName  )  [static]

Definition at line 431 of file filemgr.cpp.

00431                                          {
00432     return ::remove(fName);
00433 }

long FileMgr::resourceConsumption (  )  [virtual]

Reimplemented from SWCacher.

Definition at line 572 of file filemgr.cpp.

00572                                   {
00573     long count = 0;
00574     FileDesc **loop;
00575     for (loop = &files; *loop; loop = &((*loop)->next)) {
00576         if ((*loop)->fd > 0) {
00577             count++;
00578         }
00579     }
00580     return count;
00581 }

void FileMgr::setSystemFileMgr ( FileMgr newFileMgr  )  [static]

Definition at line 103 of file filemgr.cpp.

00103                                                   {
00104     if (systemFileMgr)
00105         delete systemFileMgr;
00106     systemFileMgr = newFileMgr;
00107 }

int FileMgr::sysOpen ( FileDesc file  )  [private]

Definition at line 208 of file filemgr.cpp.

00208                                    {
00209     FileDesc **loop;
00210     int openCount = 1;      // because we are presently opening 1 file, and we need to be sure to close files to accomodate, if necessary
00211     
00212     for (loop = &files; *loop; loop = &((*loop)->next)) {
00213 
00214         if ((*loop)->fd > 0) {
00215             if (++openCount > maxFiles) {
00216                 (*loop)->offset = lseek((*loop)->fd, 0, SEEK_CUR);
00217 				::close((*loop)->fd);
00218                 (*loop)->fd = -77;
00219             }
00220         }
00221 
00222         if (*loop == file) {
00223             if (*loop != files) {
00224                 *loop = (*loop)->next;
00225                 file->next = files;
00226                 files = file;
00227             }
00228             if ((!access(file->path, 04)) || ((file->mode & O_CREAT) == O_CREAT)) { // check for at least file exists / read access before we try to open
00229                 char tries = (((file->mode & O_RDWR) == O_RDWR) && (file->tryDowngrade)) ? 2 : 1;  // try read/write if possible
00230                 for (int i = 0; i < tries; i++) {
00231                     if (i > 0) {
00232                         file->mode = (file->mode & ~O_RDWR);    // remove write access
00233                         file->mode = (file->mode | O_RDONLY);// add read access
00234                     }
00235                     file->fd = ::open(file->path, file->mode|O_BINARY, file->perms);
00236 
00237                     if (file->fd >= 0)
00238                         break;
00239                 }
00240 
00241                 if (file->fd >= 0)
00242                     lseek(file->fd, file->offset, SEEK_SET);
00243             }
00244             else file->fd = -1;
00245             if (!*loop)
00246                 break;
00247         }
00248     }
00249     return file->fd;
00250 }

signed char FileMgr::trunc ( FileDesc file  ) 

Truncate a file at its current position leaving byte at current possition intact deleting everything afterward.

Parameters:
file The file to operate on.

Definition at line 256 of file filemgr.cpp.

00256                                          {
00257 
00258     static const char *writeTest = "x";
00259     long size = file->seek(1, SEEK_CUR);
00260     if (size == 1) // was empty
00261         size = 0;
00262     char nibble [ 32767 ];
00263     bool writable = file->write(writeTest, 1);
00264     int bytes = 0;
00265 
00266     if (writable) {
00267         // get tmpfilename
00268         char *buf = new char [ strlen(file->path) + 10 ];
00269         int i;
00270         for (i = 0; i < 9999; i++) {
00271             sprintf(buf, "%stmp%.4d", file->path, i);
00272             if (!existsFile(buf))
00273                 break;
00274         }
00275         if (i == 9999)
00276             return -2;
00277 
00278         int fd = ::open(buf, O_CREAT|O_RDWR, S_IREAD|S_IWRITE|S_IRGRP|S_IROTH);
00279         if (fd < 0)
00280             return -3;
00281     
00282         file->seek(0, SEEK_SET);
00283         while (size > 0) {   
00284             bytes = file->read(nibble, 32767);
00285             bytes = (bytes < size)?bytes:size;
00286             if (write(fd, nibble, bytes) != bytes) { break; }
00287             size -= bytes;
00288         }
00289         if (size < 1) {
00290             // zero out the file
00291 			::close(file->fd);
00292             file->fd = ::open(file->path, O_TRUNC, S_IREAD|S_IWRITE|S_IRGRP|S_IROTH);
00293 			::close(file->fd);
00294             file->fd = -77; // force file open by filemgr
00295             // copy tmp file back (dumb, but must preserve file permissions)
00296             lseek(fd, 0, SEEK_SET);
00297             do {
00298                 bytes = read(fd, nibble, 32767);
00299                 file->write(nibble, bytes);
00300             } while (bytes == 32767);
00301         }
00302 		
00303 		::close(fd);
00304 		::close(file->fd);
00305         removeFile(buf);        // remove our tmp file
00306         file->fd = -77; // causes file to be swapped out forcing open on next call to getFd()
00307     }
00308     else { // put offset back and return failure
00309         file->seek(-1, SEEK_CUR);
00310         return -1;
00311     }
00312     return 0;
00313 }


Friends And Related Function Documentation

friend class __staticsystemFileMgr [friend]

Definition at line 88 of file filemgr.h.

friend class FileDesc [friend]

Definition at line 87 of file filemgr.h.


Member Data Documentation

int FileMgr::APPEND = O_APPEND [static]

Definition at line 96 of file filemgr.h.

SWORD_NAMESPACE_START int FileMgr::CREAT = O_CREAT [static]

Definition at line 95 of file filemgr.h.

Definition at line 90 of file filemgr.h.

int FileMgr::IREAD = S_IREAD [static]

Definition at line 101 of file filemgr.h.

int FileMgr::IWRITE = S_IWRITE [static]

Definition at line 102 of file filemgr.h.

Maximum number of open files set in the constructor. determines the max number of real system files that filemgr will open. Adjust for tuning.

Definition at line 108 of file filemgr.h.

int FileMgr::RDONLY = O_RDONLY [static]

Definition at line 98 of file filemgr.h.

int FileMgr::RDWR = O_RDWR [static]

Definition at line 99 of file filemgr.h.

FileMgr * FileMgr::systemFileMgr = 0 [static, protected]

Definition at line 93 of file filemgr.h.

int FileMgr::TRUNC = O_TRUNC [static]

Definition at line 97 of file filemgr.h.

int FileMgr::WRONLY = O_WRONLY [static]

Definition at line 100 of file filemgr.h.


The documentation for this class was generated from the following files:

Generated on 18 Mar 2013 for The SWORD Project by  doxygen 1.6.1