Main Page   Class Hierarchy   Alphabetical List   Compound List   Examples  
directory.h
1#ifndef _MIMETIC_OS_DIRECTORY_H_
2#define _MIMETIC_OS_DIRECTORY_H_
3#include <string>
4#include <iterator>
5#include <mimetic/libconfig.h>
6#ifdef HAVE_DIRENT_H
7#include <dirent.h>
8#endif
9#include <unistd.h>
10#include <sys/stat.h>
11
12namespace mimetic
13{
14
15class Directory
16{
17public:
18 struct DirEntry
19 {
20 enum Type { Unknown, RegularFile, Directory, Link };
21 DirEntry(): type(Unknown) {}
22 std::string name;
23 Type type;
24 };
25 friend class iterator;
26 struct iterator: public std::iterator<std::forward_iterator_tag, DirEntry>
27 {
28 iterator() // end() it
29 : m_dirp(0), m_dirh(0), m_eoi(true)
30 {
31 }
32 iterator(Directory* dirp) // begin() it
33 : m_dirp(dirp), m_eoi(false)
34 {
35 m_dirh = opendir(m_dirp->m_path.c_str());
36 if(m_dirh)
37 {
38 m_dirent = readdir(m_dirh);
39 setDirent(m_dirent);
40 } else {
41 // opendir error, set equal to end()
42 m_dirp = 0;
43 m_dirh = 0;
44 m_eoi = true;
45 }
46 }
47 ~iterator()
48 {
49 if(m_dirh)
50 closedir(m_dirh);
51 }
52 const DirEntry& operator*() const
53 {
54 return m_de;
55 }
56 const DirEntry* operator->() const
57 {
58 return &m_de;
59 }
60 iterator& operator++()
61 {
62 if((m_dirent = readdir(m_dirh)) == NULL)
63 {
64 m_eoi = true;
65 return *this;
66 }
67 setDirent(m_dirent);
68 return *this;
69 }
70 iterator operator++(int) // postfix
71 {
72 iterator it = *this;
73 ++*this;
74 return it;
75 }
76 bool operator==(const iterator& right)
77 {
78 if(m_eoi && right.m_eoi)
79 return true;
80
81 return
82 m_eoi == right.m_eoi &&
83 m_dirp->m_path == right.m_dirp->m_path &&
84 m_dirent && right.m_dirent &&
85 #ifdef _DIRENT_HAVE_D_TYPE
86 m_dirent->d_type == right.m_dirent->d_type &&
87 #endif
88 std::string(m_dirent->d_name) == right.m_dirent->d_name;
89 }
90 bool operator!=(const iterator& right)
91 {
92 return !operator==(right);
93 }
94 private:
95 void setDirent(struct dirent* dent)
96 {
97 m_de.name = dent->d_name;
98 m_de.type = DirEntry::Unknown;
99 #ifdef _DIRENT_HAVE_D_TYPE
100 switch(dent->d_type)
101 {
102 case DT_DIR:
103 m_de.type = DirEntry::Directory;
104 break;
105 case DT_REG:
106 m_de.type = DirEntry::RegularFile;
107 break;
108 case DT_LNK:
109 m_de.type = DirEntry::Link;
110 break;
111 }
112 #endif
113 }
114 Directory* m_dirp;
115 DIR* m_dirh;
116 bool m_eoi;
117 DirEntry m_de;
118 struct dirent* m_dirent;
119 };
120
121 Directory(const std::string& dir)
122 : m_path(dir)
123 {
124 }
125 ~Directory()
126 {
127 }
128 iterator begin()
129 { return iterator(this); }
130 iterator end()
131 { return iterator(); };
132 bool exists() const
133 {
134 struct stat st;
135 return stat(m_path.c_str(), &st) == 0 && S_ISDIR(st.st_mode);
136 }
137 static bool exists(const std::string& dname)
138 {
139 struct stat st;
140 return stat(dname.c_str(), &st) == 0 && S_ISDIR(st.st_mode);
141 }
142 static bool create(const std::string& dname)
143 {
144 if(!exists(dname))
145 return mkdir(dname.c_str(), 0755) == 0;
146 else
147 return 0;
148 }
149 static bool remove(const std::string& dname)
150 {
151 if(!exists(dname))
152 return 0;
153 else
154 return rmdir(dname.c_str()) == 0;
155 }
156 const std::string& path() const
157 {
158 return m_path;
159 }
160private:
161 std::string m_path;
162};
163
164}
165
166#endif
167
Definition: body.h:18