1 // src/Directory.cc
2 // This file is part of libpbe; see http://decimail.org
3 // (C) 2004 Philip Endecott
4
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 2 of the License, or
8 // any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19 #include "Directory.hh"
20
21 #include "Exception.hh"
22
23 #include <unistd.h>
24
25 using namespace std;
26
27 namespace pbe {
28
29
Directory(string dirname_)30 Directory::Directory(string dirname_):
31 dirname(dirname_)
32 {}
33
34
~Directory()35 Directory::~Directory()
36 {}
37
38
operator ++(void)39 void Directory::const_iterator::operator++(void)
40 {
41 read_next();
42 }
43
44
operator ==(const const_iterator & rhs) const45 bool Directory::const_iterator::operator==(const const_iterator& rhs) const
46 {
47 if (!at_end && !rhs.at_end) {
48 throw "Cannot compare these Directory::const_iterators";
49 }
50 return at_end==rhs.at_end;
51 }
52
53
const_iterator(void)54 Directory::const_iterator::const_iterator(void):
55 dir(NULL), at_end(true)
56 {}
57
58
const_iterator(string dirname_)59 Directory::const_iterator::const_iterator(string dirname_):
60 dirname(dirname_), at_end(false)
61 {
62 dir = opendir(dirname.c_str());
63 if (!dir) {
64 throw_ErrnoException("opendir("+dirname+")");
65 }
66 read_next();
67 }
68
69
~const_iterator()70 Directory::const_iterator::~const_iterator()
71 {
72 if (dir) {
73 int ret = closedir(dir);
74 if (ret==-1) {
75 // throw_ErrnoException("closing a directory");
76 // Don't throw an exception from a destructor, in case it is being invoked
77 // during exception processing.
78 // (TODO is there a better fix for this?)
79 }
80 }
81 }
82
83
read_next(void)84 void Directory::const_iterator::read_next(void)
85 {
86 struct dirent* ent_p = readdir(dir);
87 if (!ent_p) {
88 at_end=true;
89 } else {
90 this_entry.leafname = ent_p->d_name;
91 if (this_entry.leafname=="." || this_entry.leafname=="..") {
92 read_next();
93 return;
94 }
95 this_entry.pathname = dirname + '/' + this_entry.leafname;
96 }
97 }
98
99
begin(void) const100 Directory::const_iterator Directory::begin(void) const
101 {
102 return const_iterator(dirname);
103 }
104
105
end(void) const106 Directory::const_iterator Directory::end(void) const
107 {
108 return const_iterator();
109 }
110
111 };
112
113