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