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 
12 namespace mimetic
13 {
14 
15 class Directory
16 {
17 public:
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  }
160 private:
161  std::string m_path;
162 };
163 
164 }
165 
166 #endif
167