Main Page   Class Hierarchy   Alphabetical List   Compound List   Examples  

directory.h

00001 #ifndef _MIMETIC_OS_DIRECTORY_H_
00002 #define _MIMETIC_OS_DIRECTORY_H_
00003 #include <string>
00004 #include <iterator>
00005 #include <mimetic/config.h>
00006 #ifdef HAVE_DIRENT_H
00007 #include <dirent.h>
00008 #endif
00009 #include <unistd.h>
00010 #include <sys/stat.h>
00011 
00012 namespace mimetic
00013 {
00014 
00015 class Directory
00016 {
00017 public:
00018     struct DirEntry
00019     {
00020         enum Type { Unknown, RegularFile, Directory, Link };
00021         DirEntry(): type(Unknown) {}
00022         std::string name;
00023         Type type;
00024     };
00025     friend class iterator;
00026     struct iterator: public std::iterator<std::forward_iterator_tag, DirEntry>
00027     {
00028         iterator() // end() it
00029         : m_dirp(0), m_dirh(0), m_eoi(true)
00030         {
00031         }
00032         iterator(Directory* dirp) // begin() it
00033         : m_dirp(dirp), m_eoi(false)
00034         {
00035             m_dirh = opendir(m_dirp->m_path.c_str());
00036             if(m_dirh)
00037             {
00038                 m_dirent = readdir(m_dirh);
00039                 setDirent(m_dirent);
00040             } else {
00041                 // opendir error, set equal to end()
00042                 m_dirp = 0;
00043                 m_dirh = 0;
00044                 m_eoi = true;
00045             }
00046         }
00047         ~iterator()
00048         {
00049             if(m_dirh)
00050                 closedir(m_dirh);
00051         }
00052         const DirEntry& operator*() const
00053         {
00054             return m_de;
00055         }
00056         const DirEntry* operator->() const
00057         {
00058             return &m_de;
00059         }
00060         iterator& operator++()
00061         {
00062             if((m_dirent = readdir(m_dirh)) == NULL)
00063             {
00064                 m_eoi = true;
00065                 return *this;
00066             }
00067             setDirent(m_dirent);
00068             return *this;
00069         }
00070         iterator operator++(int) // postfix
00071         {
00072             iterator it = *this;
00073             ++*this;
00074             return it;
00075         }
00076         bool operator==(const iterator& right)
00077         {
00078             if(m_eoi && right.m_eoi)
00079                 return true;
00080             
00081             return 
00082             m_eoi == right.m_eoi &&
00083             m_dirp->m_path == right.m_dirp->m_path &&
00084             m_dirent && right.m_dirent &&
00085             #ifdef _DIRENT_HAVE_D_TYPE
00086             m_dirent->d_type == right.m_dirent->d_type &&
00087             #endif
00088             std::string(m_dirent->d_name) == right.m_dirent->d_name;
00089         }
00090         bool operator!=(const iterator& right)
00091         {
00092             return !operator==(right);
00093         }
00094     private:
00095         void setDirent(struct dirent* dent)
00096         {
00097             m_de.name = dent->d_name;
00098             m_de.type = DirEntry::Unknown;
00099             #ifdef _DIRENT_HAVE_D_TYPE
00100             switch(dent->d_type)
00101             {
00102             case DT_DIR:
00103                 m_de.type = DirEntry::Directory;
00104                 break;
00105             case DT_REG:
00106                 m_de.type = DirEntry::RegularFile;
00107                 break;
00108             case DT_LNK:
00109                 m_de.type = DirEntry::Link;
00110                 break;
00111             }
00112             #endif
00113         }
00114         Directory* m_dirp;
00115         DIR* m_dirh;
00116         bool m_eoi;
00117         DirEntry m_de;
00118         struct dirent* m_dirent;
00119     };
00120 
00121     Directory(const std::string& dir)
00122     : m_path(dir)
00123     {
00124     }
00125     ~Directory()
00126     {
00127     }
00128     iterator begin()
00129     {    return iterator(this);    }
00130     iterator end()
00131     {    return iterator();    };
00132     bool exists() const
00133     {
00134         struct stat st;
00135         return stat(m_path.c_str(), &st) == 0 && S_ISDIR(st.st_mode);
00136     }
00137     static bool exists(const std::string& dname)
00138     {
00139         struct stat st;
00140         return stat(dname.c_str(), &st) == 0 && S_ISDIR(st.st_mode);
00141     }
00142     static bool create(const std::string& dname)
00143     {
00144         if(!exists(dname))
00145             return mkdir(dname.c_str(), 0755) == 0;
00146         else
00147             return 0;
00148     }
00149     static bool remove(const std::string& dname)
00150     {
00151         if(!exists(dname))
00152             return 0;
00153         else
00154             return rmdir(dname.c_str()) == 0;
00155     }
00156     const std::string& path() const
00157     {
00158         return m_path;
00159     }
00160 private:
00161     std::string m_path;
00162 };
00163 
00164 }
00165 
00166 #endif
00167