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

wvdiriter.cc

Go to the documentation of this file.
00001 /* 00002 * Worldvisions Weaver Software: 00003 * Copyright (C) 1997-2002 Net Integration Technologies, Inc. 00004 * 00005 * Directory iterator. Recursively uses opendir and readdir, so you don't 00006 * have to. Basically implements 'find'. 00007 * 00008 */ 00009 00010 #include "wvdiriter.h" 00011 00012 #ifdef _WIN32 00013 #define S_ISDIR(x) (_S_IFDIR | (x)) 00014 #define lstat stat 00015 #endif 00016 00017 WvDirIter::WvDirIter( WvStringParm dirname, 00018 bool _recurse, bool _skip_mounts, size_t sizeof_stat ) 00019 : relpath(""), dir(dirs) 00020 /****************************************************************************/ 00021 { 00022 // if this assertion fails, then you probably used different compiler 00023 // options for the wvstreams library and the calling program. Check 00024 // for defines like _FILE_OFFSET_BITS=64 and _LARGEFILE_SOURCE. 00025 assert(sizeof_stat == sizeof(struct stat)); 00026 00027 recurse = _recurse; 00028 go_up = false; 00029 skip_mounts = _skip_mounts; 00030 found_top = false; 00031 00032 DIR * d = opendir( dirname ); 00033 if( d ) { 00034 Dir * dd = new Dir( d, dirname ); 00035 dirs.prepend( dd, true ); 00036 } 00037 } 00038 00039 WvDirIter::~WvDirIter() 00040 /*********************/ 00041 { 00042 dirs.zap(); 00043 } 00044 00045 bool WvDirIter::isok() const 00046 /**************************/ 00047 { 00048 return( dirs.count() > 0 ); 00049 } 00050 00051 bool WvDirIter::isdir() const 00052 /***************************/ 00053 { 00054 return( S_ISDIR( info.st_mode ) ); 00055 } 00056 00057 void WvDirIter::rewind() 00058 /**********************/ 00059 { 00060 // have to closedir() everything that isn't the one we started with, 00061 // and rewind that. 00062 while( dirs.count() > 1 ) { 00063 dir.rewind(); 00064 dir.next(); 00065 dir.unlink(); 00066 } 00067 00068 if( isok() ) { 00069 dir.rewind(); 00070 dir.next(); 00071 rewinddir( dir->d ); 00072 } 00073 } 00074 00075 00076 bool WvDirIter::next() 00077 /********************/ 00078 // use readdir... and if that returns a directory, opendir() it and prepend 00079 // it to dirs, so we start reading it until it's done. 00080 { 00081 struct dirent * dent = NULL; 00082 00083 if( !isok() ) 00084 return( false ); 00085 00086 bool tryagain; 00087 do { 00088 bool ok = false; 00089 tryagain = false; 00090 00091 // unrecurse if the user wants to 00092 if( go_up ) { 00093 go_up = false; 00094 if( dirs.count() > 1 ) { 00095 dir.unlink(); 00096 dir.rewind(); 00097 dir.next(); 00098 } else 00099 return( false ); 00100 } 00101 00102 do { 00103 dent = readdir( dir->d ); 00104 if( dent ) { 00105 info.fullname = WvString( "%s/%s", dir->dirname, dent->d_name ); 00106 info.name = dent->d_name; 00107 00108 if (relpath == "") 00109 info.relname = info.name; 00110 else 00111 info.relname = WvString("%s%s", relpath, info.name); 00112 00113 ok = ( lstat( info.fullname, &info ) == 0 00114 && strcmp( dent->d_name, "." ) 00115 && strcmp( dent->d_name, ".." ) ); 00116 00117 if (ok && !found_top) 00118 { 00119 lstat(info.fullname, &topdir); 00120 topdir.fullname = info.fullname; 00121 topdir.name = info.name; 00122 topdir.relname = info.relname; 00123 found_top = true; 00124 } 00125 } 00126 } while( dent && !ok ); 00127 00128 if( dent ) { 00129 // recurse? 00130 if( recurse && S_ISDIR( info.st_mode ) && 00131 ( !skip_mounts || info.st_dev == topdir.st_dev) ) { 00132 DIR * d = opendir( info.fullname ); 00133 if( d ) { 00134 relpath = WvString( "%s%s/", relpath, info.name ); 00135 Dir * dd = new Dir( d, info.fullname ); 00136 dirs.prepend( dd, true ); 00137 dir.rewind(); 00138 dir.next(); 00139 } 00140 } 00141 } else { 00142 // end of directory. if we recursed, unlink it and go up a 00143 // notch. if this is the top level, DON'T close it, so that 00144 // the user can ::rewind() again if he wants. 00145 if( dirs.count() > 1 ) { 00146 if (dirs.count() == 2) 00147 relpath = WvString(""); 00148 else 00149 relpath = WvString( "%s/", getdirname(relpath) ); 00150 00151 dir.unlink(); 00152 dir.rewind(); 00153 dir.next(); 00154 tryagain = true; 00155 } 00156 } 00157 00158 } while( tryagain ); 00159 00160 return( dent != NULL ); 00161 } 00162

Generated on Tue Oct 5 01:09:20 2004 for WvStreams by doxygen 1.3.7