sbuild-dirstream.cc

Go to the documentation of this file.
00001 /* Copyright © 2003,2006  Roger Leigh <rleigh@debian.org>
00002  *
00003  * schroot is free software; you can redistribute it and/or modify it
00004  * under the terms of the GNU General Public License as published by
00005  * the Free Software Foundation; either version 2 of the License, or
00006  * (at your option) any later version.
00007  *
00008  * schroot is distributed in the hope that it will be useful, but
00009  * WITHOUT ANY WARRANTY; without even the implied warranty of
00010  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00011  * General Public License for more details.
00012  *
00013  * You should have received a copy of the GNU General Public License
00014  * along with this program; if not, write to the Free Software
00015  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
00016  * MA  02111-1307  USA
00017  *
00018  *********************************************************************/
00019 
00020 #include <config.h>
00021 
00022 #include "sbuild-dirstream.h"
00023 
00024 #include <cerrno>
00025 #include <cstring>
00026 
00027 using namespace sbuild;
00028 
00029 namespace
00030 {
00031 
00032   typedef std::pair<dirstream::error_code,const char *> emap;
00033 
00038   emap init_errors[] =
00039     {
00040       // TRANSLATORS: %1% = directory name
00041       emap(dirstream::DIR_OPEN,    N_("Failed to open directory '%1%'")),
00042       // TRANSLATORS: %1% = directory name
00043       emap(dirstream::DIR_READ,    N_("Failed to read directory '%1%'"))
00044     };
00045 
00046 }
00047 
00048 template<>
00049 error<dirstream::error_code>::map_type
00050 error<dirstream::error_code>::error_strings
00051 (init_errors,
00052  init_errors + (sizeof(init_errors) / sizeof(init_errors[0])));
00053 
00054 
00055 dirstream::dirstream(std::string const& dirname):
00056   dirname(),
00057   dir(0),
00058   data(),
00059   error_status(true),
00060   eof_status(true)
00061 {
00062   open(dirname);
00063 }
00064 
00065 
00066 dirstream::~dirstream()
00067 {
00068   close();
00069 }
00070 
00071 void
00072 dirstream::open(std::string const& dirname)
00073 {
00074   this->dir = opendir(dirname.c_str());
00075   if (this->dir == 0)
00076     {
00077       this->dirname.clear();
00078       this->error_status = true;
00079       this->eof_status = true;
00080       throw error(dirname, DIR_OPEN, strerror(errno));
00081     }
00082   this->dirname = dirname;
00083   this->error_status = false;
00084   this->eof_status = false;
00085   read();
00086 }
00087 
00088 void
00089 dirstream::read(int quantity)
00090 {
00091   int i;
00092 
00093   if (this->dir == 0)
00094     return;
00095 
00096   for (i = 0; i < quantity; ++i)
00097     {
00098       struct dirent* entry;
00099       errno = 0;
00100       entry = readdir(dir);
00101 
00102       if (entry == 0) // EOF or error
00103         {
00104           //std::cerr << "Directory read error: ";
00105           if (errno) // error
00106             {
00107               this->error_status = true;
00108               throw error(this->dirname, DIR_READ, strerror(errno));
00109             }
00110           return;
00111         }
00112 
00113       direntry newentry(entry); // make a direntry
00114       this->data.push_back(newentry); // push onto the end of the list
00115     }
00116 }
00117 
00118 void
00119 dirstream::close()
00120 {
00121   if (this->dir)
00122     closedir(this->dir); // don't throw an exception on failure -- it
00123                          // could be called in the destructor
00124   this->dir = 0;
00125   this->data.clear();    // clear all data
00126   this->dirname.clear();
00127   this->error_status = true;
00128   this->eof_status = true;
00129 }
00130 
00131 
00132 bool
00133 dirstream::eof() const
00134 {
00135   return this->eof_status;
00136 }
00137 
00138 bool
00139 dirstream::bad() const
00140 {
00141   return this->error_status;
00142 }
00143 
00144 sbuild::dirstream::operator bool ()
00145 {
00146   return !(bad() || eof());
00147 }
00148 
00149 bool
00150 sbuild::dirstream::operator ! ()
00151 {
00152   return bad() || eof();
00153 }
00154 
00155 
00156 dirstream&
00157 sbuild::operator >> (dirstream& stream,
00158                      direntry&  entry)
00159 {
00160   stream.read(); // read a new entry
00161   if (stream && !stream.data.empty()) // not at end of file or bad.
00162     {
00163       entry = stream.data.front(); // assign next direntry to entry
00164       stream.data.pop_front(); // remove the entry
00165     }
00166   else // blank the direntry and set EOF status
00167     {
00168       std::memset(&entry, 0, sizeof(direntry));
00169       stream.eof_status = true;
00170     }
00171 
00172   return stream;
00173 }

Generated on Sat Jan 27 16:11:03 2007 for schroot by  doxygen 1.5.1