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
27 {
28 typedef std::forward_iterator_tag iterator_category;
29 typedef DirEntry value_type;
30 typedef std::ptrdiff_t difference_type;
31 typedef DirEntry* pointer;
32 typedef DirEntry& reference;
33
34 iterator() // end() it
35 : m_dirp(0), m_dirh(0), m_eoi(true)
36 {
37 }
38 iterator(Directory* dirp) // begin() it
39 : m_dirp(dirp), m_eoi(false)
40 {
41 m_dirh = opendir(m_dirp->m_path.c_str());
42 if(m_dirh)
43 {
44 m_dirent = readdir(m_dirh);
45 setDirent(m_dirent);
46 } else {
47 // opendir error, set equal to end()
48 m_dirp = 0;
49 m_dirh = 0;
50 m_eoi = true;
51 }
52 }
53 ~iterator()
54 {
55 if(m_dirh)
56 closedir(m_dirh);
57 }
58 const DirEntry& operator*() const
59 {
60 return m_de;
61 }
62 const DirEntry* operator->() const
63 {
64 return &m_de;
65 }
66 iterator& operator++()
67 {
68 if((m_dirent = readdir(m_dirh)) == NULL)
69 {
70 m_eoi = true;
71 return *this;
72 }
73 setDirent(m_dirent);
74 return *this;
75 }
76 iterator operator++(int) // postfix
77 {
78 iterator it = *this;
79 ++*this;
80 return it;
81 }
82 bool operator==(const iterator& right)
83 {
84 if(m_eoi && right.m_eoi)
85 return true;
86
87 return
88 m_eoi == right.m_eoi &&
89 m_dirp->m_path == right.m_dirp->m_path &&
90 m_dirent && right.m_dirent &&
91 #ifdef _DIRENT_HAVE_D_TYPE
92 m_dirent->d_type == right.m_dirent->d_type &&
93 #endif
94 std::string(m_dirent->d_name) == right.m_dirent->d_name;
95 }
96 bool operator!=(const iterator& right)
97 {
98 return !operator==(right);
99 }
100 private:
101 void setDirent(struct dirent* dent)
102 {
103 m_de.name = dent->d_name;
104 m_de.type = DirEntry::Unknown;
105 #ifdef _DIRENT_HAVE_D_TYPE
106 switch(dent->d_type)
107 {
108 case DT_DIR:
109 m_de.type = DirEntry::Directory;
110 break;
111 case DT_REG:
112 m_de.type = DirEntry::RegularFile;
113 break;
114 case DT_LNK:
115 m_de.type = DirEntry::Link;
116 break;
117 }
118 #endif
119 }
120 Directory* m_dirp;
121 DIR* m_dirh;
122 bool m_eoi;
123 DirEntry m_de;
124 struct dirent* m_dirent;
125 };
126
127 Directory(const std::string& dir)
128 : m_path(dir)
129 {
130 }
131 ~Directory()
132 {
133 }
134 iterator begin()
135 { return iterator(this); }
136 iterator end()
137 { return iterator(); };
138 bool exists() const
139 {
140 struct stat st;
141 return stat(m_path.c_str(), &st) == 0 && S_ISDIR(st.st_mode);
142 }
143 static bool exists(const std::string& dname)
144 {
145 struct stat st;
146 return stat(dname.c_str(), &st) == 0 && S_ISDIR(st.st_mode);
147 }
148 static bool create(const std::string& dname)
149 {
150 if(!exists(dname))
151 return mkdir(dname.c_str(), 0755) == 0;
152 else
153 return 0;
154 }
155 static bool remove(const std::string& dname)
156 {
157 if(!exists(dname))
158 return 0;
159 else
160 return rmdir(dname.c_str()) == 0;
161 }
162 const std::string& path() const
163 {
164 return m_path;
165 }
166private:
167 std::string m_path;
168};
169
170}
171
172#endif
173
Definition body.h:18