WvStreams
wvdiriter.h
00001 /* -*- Mode: C++ -*-
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 #ifndef __WVDIRITER_H
00011 #define __WVDIRITER_H
00012 
00013 #ifdef ISDARWIN
00014 # include <sys/types.h>
00015 #endif
00016 
00017 #include <dirent.h>
00018 #include <sys/stat.h>
00019 #include <sys/types.h>
00020 
00021 #include "wvstring.h"
00022 #include "wvlinklist.h"
00023 #include "strutils.h"
00024 
00025 struct WvDirEnt : public stat
00026 /***************************/
00027 {
00028     // we already have everything from struct stat, but let's also include
00029     // some variations on the filename for convenience.
00030     WvString        fullname; // contains: startdir/path/file
00031     WvString        name;     // contains: file
00032     WvString        relname;  // contains: path/file
00033 };
00034 
00035 class WvDirIter
00036 /*************/
00037 {
00038 private:
00039     bool        recurse;
00040     bool        go_up;
00041     bool        skip_mounts;
00042     bool        found_top;
00043 
00044     WvDirEnt        topdir;
00045     WvDirEnt        info;
00046     WvString        relpath;
00047 
00048     struct Dir {
00049         Dir( DIR * _d, WvString _dirname )
00050             : d( _d ), dirname( _dirname )
00051             {}
00052         ~Dir()
00053             { if( d ) closedir( d ); }
00054 
00055         DIR *    d;
00056         WvString dirname;
00057     };
00058 
00059     DeclareWvList( Dir );
00060     DirList       dirs;
00061     DirList::Iter dir;
00062     
00063 public:
00064     // the sizeof(stat) helps an assert() in wvdiriter.cc.
00065     WvDirIter( WvStringParm dirname,
00066                bool _recurse = true, bool _skip_mounts = false,
00067                size_t sizeof_stat = sizeof(struct stat) );
00068     
00069     ~WvDirIter();
00070 
00071     bool isok() const;
00072     bool isdir() const;
00073     void rewind();
00074     bool next();
00075 
00076     // calling up() will abandon the current level of recursion, if, for
00077     // example, you decide you don't want to continue reading the contents
00078     // of the directory you're in.  After up(), next() will return the next
00079     // entry after the directory you've abandoned, in its parent.
00080     void up()
00081         { go_up = true; }
00082     
00083     const WvDirEnt *ptr() const { return &info; }
00084     WvIterStuff(const WvDirEnt);
00085     
00086     int depth() const
00087         { return( dirs.count() ); }
00088 };
00089 
00090 #endif