Main Page   Class Hierarchy   Compound List   File List   Compound Members   File Members  

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 WvDirIter::WvDirIter( WvString dirname, bool _recurse )
00013 /*****************************************************/
00014 : dir( dirs )
00015 {
00016     recurse = _recurse;
00017 
00018     DIR * d = opendir( dirname );
00019     if( d ) {
00020         Dir * dd = new Dir( d, dirname );
00021         dirs.prepend( dd, true );
00022     }
00023 }
00024 
00025 WvDirIter::~WvDirIter()
00026 /*********************/
00027 {
00028     dirs.zap();
00029 }
00030 
00031 bool WvDirIter::isok() const
00032 /**************************/
00033 {
00034     return( dirs.count() > 0 );
00035 }
00036 
00037 void WvDirIter::rewind()
00038 /**********************/
00039 {
00040     // have to closedir() everything that isn't the one we started with,
00041     // and rewind that.
00042     while( dirs.count() > 1 ) {
00043         dir.rewind();
00044         dir.next();
00045         dir.unlink();
00046     }
00047 
00048     if( isok() ) {
00049         dir.rewind();
00050         dir.next();
00051         rewinddir( dir->d );
00052     }
00053 }
00054 
00055 
00056 bool WvDirIter::next()
00057 /********************/
00058 // use readdir... and if that returns a directory, opendir() it and prepend
00059 // it to dirs, so we start reading it until it's done.
00060 {
00061     struct dirent * dent = NULL;
00062 
00063     if( !isok() )
00064         return( false );
00065 
00066     bool tryagain;
00067     do {
00068         bool ok = false;
00069         tryagain = false;
00070         do {
00071             dent = readdir( dir->d );
00072             if( dent ) {
00073                 info.fullname = WvString( "%s/%s", dir->dirname, dent->d_name );
00074                 info.name = dent->d_name;
00075                 info.name.unique();
00076                 ok = ( lstat( info.fullname, &info ) == 0
00077                             && strcmp( dent->d_name, "." )
00078                             && strcmp( dent->d_name, ".." ) );
00079             }
00080         } while( dent && !ok );
00081 
00082         if( dent ) {
00083             // recurse?
00084             if( recurse && S_ISDIR( info.st_mode ) ) {
00085                 DIR * d = opendir( info.fullname );
00086                 if( d ) {
00087                     Dir * dd = new Dir( d, info.fullname );
00088                     dirs.prepend( dd, true );
00089                     dir.rewind();
00090                     dir.next();
00091                 }
00092             }
00093         } else {
00094             // end of directory.  if we recursed, unlink it and go up a 
00095             // notch.  if this is the top level, DON'T close it, so that
00096             // the user can ::rewind() again if he wants.
00097             if( dirs.count() > 1 ) {
00098                 dir.unlink();
00099                 dir.rewind();
00100                 tryagain = dir.next();
00101             }
00102         }
00103 
00104     } while( tryagain );
00105 
00106     return( dent != NULL );
00107 }
00108 

Generated on Sun Aug 25 02:29:30 2002 for WvStreams by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002