~ubuntu-branches/ubuntu/intrepid/schroot/intrepid

« back to all changes in this revision

Viewing changes to sbuild/sbuild-dirstream.h

  • Committer: Bazaar Package Importer
  • Author(s): Reinhard Tartler
  • Date: 2006-07-08 18:33:28 UTC
  • mfrom: (1.1.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20060708183328-rlo4mpldmyoda55q
Tags: 0.99.2-2ubuntu1
* remerge ubuntu changes:
  + debian/control: libpam-dev (>> 0.79-3ubuntu6)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright © 2003,2006  Roger Leigh <rleigh@debian.org>
 
2
 *
 
3
 * schroot is free software; you can redistribute it and/or modify it
 
4
 * under the terms of the GNU General Public License as published by
 
5
 * the Free Software Foundation; either version 2 of the License, or
 
6
 * (at your option) any later version.
 
7
 *
 
8
 * schroot is distributed in the hope that it will be useful, but
 
9
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
11
 * General Public License for more details.
 
12
 *
 
13
 * You should have received a copy of the GNU General Public License
 
14
 * along with this program; if not, write to the Free Software
 
15
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 
16
 * MA  02111-1307  USA
 
17
 *
 
18
 *********************************************************************/
 
19
 
 
20
#ifndef SBUILD_DIRSTREAM_H
 
21
#define SBUILD_DIRSTREAM_H
 
22
 
 
23
#include <sbuild/sbuild-custom-error.h>
 
24
 
 
25
#include <iostream>
 
26
#include <deque>
 
27
#include <string>
 
28
 
 
29
#include <sys/types.h>
 
30
#include <dirent.h>
 
31
 
 
32
namespace sbuild
 
33
{
 
34
 
 
35
  /**
 
36
   * An entry in a dirstream.  It is a wrapper around the dirent
 
37
   * structure declared in dirent.h
 
38
   *
 
39
   * The direntry is only valid during the lifetime of an open
 
40
   * dirstream.  Once the directory is closed, when the dirstream
 
41
   * is destroyed, or its close() method called, the direntry can
 
42
   * no longer be safely used.  On many systems, including Linux,
 
43
   * this does not matter, but the Single UNIX Specification makes
 
44
   * no garuantees about this.
 
45
   */
 
46
  class direntry
 
47
  {
 
48
  public:
 
49
    /// The constructor.
 
50
    direntry()
 
51
    { std::memset(&this->data, 0, sizeof(struct dirent)); }
 
52
 
 
53
    /**
 
54
     * The constructor.
 
55
     *
 
56
     * @param entry the dirent to initialise the class with.
 
57
     */
 
58
    direntry(const struct dirent *entry)
 
59
    { std::memcpy(&this->data, entry, sizeof(struct dirent)); }
 
60
 
 
61
    /**
 
62
     * The copy constructor.
 
63
     *
 
64
     * @param orig the class to copy.
 
65
     */
 
66
    direntry(direntry const& orig)
 
67
    { memcpy(&this->data, &orig.data, sizeof(struct dirent)); }
 
68
 
 
69
    /// The destructor.
 
70
    virtual ~direntry()
 
71
    {}
 
72
 
 
73
    /**
 
74
     * Get the dirent inode number (d_ino).
 
75
     *
 
76
     * @returns the inode number.
 
77
     */
 
78
    long inode() const
 
79
    { return this->data.d_ino; }
 
80
 
 
81
    /**
 
82
     * Get the file type (d_type).
 
83
     *
 
84
     * @returns the file type.
 
85
     */
 
86
    unsigned char type() const
 
87
    { return this->data.d_type; }
 
88
 
 
89
    /**
 
90
     * Get the file name (d_name).
 
91
     *
 
92
     * @returns a reference to a string containing the name.
 
93
     */
 
94
    std::string name() const
 
95
    { return this->data.d_name; }
 
96
 
 
97
    /**
 
98
     * Get the dirent.
 
99
     *
 
100
     * @returns a reference to the underlying dirent.
 
101
     */
 
102
    struct dirent const& dirent()
 
103
    { return this->data; }
 
104
 
 
105
  private:
 
106
    /// The underlying dirent the class is wrapping.
 
107
    struct dirent data;
 
108
  }; // class direntry
 
109
 
 
110
  /**
 
111
   * Access directories.  This is a wrapper around the opendir(3),
 
112
   * readdir(3) and closedir(3) functions, which are used to read a
 
113
   * stream of "dirents" through multiple readdir() calls.
 
114
   *
 
115
   * dirstream calls opendir() and closedir() automatically, and
 
116
   * represents each dirent as a dirstream::direntry.  Like reading
 
117
   * from and istream by pulling data out with the >> "extraction
 
118
   * operator", direntries are also extracted from the dirstream with
 
119
   * the >> operator.
 
120
   */
 
121
  class dirstream
 
122
    {
 
123
    public:
 
124
      /// Error codes.
 
125
      enum error_code
 
126
        {
 
127
          DIR_OPEN, ///< Failed to open directory.
 
128
          DIR_READ  ///< Failed to read directory.
 
129
        };
 
130
 
 
131
    /// Exception type.
 
132
    typedef custom_error<error_code> error;
 
133
 
 
134
      /**
 
135
       * The constructor.
 
136
       *
 
137
       * @param dir the directory to read.
 
138
       */
 
139
      dirstream(std::string const& dir);
 
140
 
 
141
      /// The destructor.
 
142
      virtual ~dirstream();
 
143
 
 
144
      /**
 
145
       * Open a directory for reading.  This uses the opendir(3) call to
 
146
       * open the underlying DIR stream.  Any previously open directory is
 
147
       * closed before opening the new one.  The dirstream error state is
 
148
       * set if the open fails, and an exception will be thrown.
 
149
       *
 
150
       * @param dirname the directory to read.
 
151
       * @see close()
 
152
       */
 
153
      void open(std::string const& dirname);
 
154
 
 
155
      /**
 
156
       * Close the directory.  This uses the closedir(3) call to close the
 
157
       * underlying DIR stream.  All cached data is deleted and the error
 
158
       * state set until open() is called.
 
159
       *
 
160
       * @see open()
 
161
       */
 
162
      void close();
 
163
 
 
164
      /**
 
165
       * Check for End Of File.  Note that the end of file status is
 
166
       * only set adter a read fails, so this should be checked after
 
167
       * each read.
 
168
       *
 
169
       * @returns true if the dirstream is empty, otherwise false.
 
170
       */
 
171
      bool eof() const;
 
172
 
 
173
      /**
 
174
       * Check for errors.  If there is an error, the dirstream is
 
175
       * unusable until the next open() call.
 
176
       *
 
177
       * @returns true if the dirstream is in an error state, otherwise
 
178
       * false.
 
179
       */
 
180
      bool bad() const;
 
181
 
 
182
      /**
 
183
       * Check if the dirstream status is good.
 
184
       *
 
185
       * @returns true if the status is good (eof() and bad() both
 
186
       * return false).
 
187
       */
 
188
      operator bool ();
 
189
 
 
190
      /**
 
191
       * Check if the dirstream status is bad.
 
192
       *
 
193
       * @returns true if the status is bad (eof() or bad() return
 
194
       * true).
 
195
       */
 
196
      bool
 
197
      operator ! ();
 
198
 
 
199
      /**
 
200
       * The overloaded extraction operator.  This is used to pull
 
201
       * direntries from a dirstream.
 
202
       */
 
203
      friend dirstream&
 
204
      operator >> (dirstream& stream,
 
205
                   direntry&  entry);
 
206
 
 
207
    private:
 
208
      /**
 
209
       * Read dirents from the underlying DIR stream into the data
 
210
       * deque.  If the read fails, the error state will be set, and
 
211
       * an exception will be thrown.
 
212
       *
 
213
       * @param quantity the number of dirents to read.
 
214
       */
 
215
      void read (int quantity=1);
 
216
 
 
217
      /// The directory name.
 
218
      std::string dirname;
 
219
 
 
220
      /// The underlying DIR stream.
 
221
      DIR *dir;
 
222
 
 
223
      /**
 
224
       * A list of direntries represents the directory stream as a LIFO
 
225
       * stack.
 
226
       */
 
227
      std::deque<direntry> data;
 
228
 
 
229
      /// Error status.
 
230
      bool error_status;
 
231
 
 
232
      /// End of File status.
 
233
      bool eof_status;
 
234
  };
 
235
 
 
236
}
 
237
 
 
238
#endif /* SBUILD_DIRSTREAM_H */
 
239
 
 
240
/*
 
241
 * Local Variables:
 
242
 * mode:C++
 
243
 * End:
 
244
 */