Dir is now usable and compilable, also added fixes for Solaris

master
Marc Wäckerlin 20 years ago
parent 2e0aec1d9f
commit 4b33857ed1
  1. 99
      mrw/file.hpp

@ -1,4 +1,3 @@
/** @file /** @file
$Id$ $Id$
@ -10,6 +9,9 @@
@license LGPL, see file <a href="license.html">COPYING</a> @license LGPL, see file <a href="license.html">COPYING</a>
$Log$ $Log$
Revision 1.4 2005/02/28 07:17:24 marc
Dir is now usable and compilable, also added fixes for Solaris
Revision 1.3 2005/02/18 15:52:20 marc Revision 1.3 2005/02/18 15:52:20 marc
correection in documentation correection in documentation
@ -27,6 +29,7 @@
#define __MRW_FILE_HPP__ #define __MRW_FILE_HPP__
#include <mrw/exception.hpp> #include <mrw/exception.hpp>
#include <mrw/errno.hpp>
#include <string> #include <string>
#include <fstream> #include <fstream>
#include <sys/types.h> #include <sys/types.h>
@ -154,15 +157,42 @@ namespace mrw {
+filename+"'"); +filename+"'");
return sz; return sz;
} }
/** @brief Remove a file
Remove a file
@throw mrw::unix_error in case of failure,
i.e. if the file does not exist
@param file the file name
*/
static void remove(const std::string& file) throw(std::exception) {
if (unlink(file.c_str()))
throw mrw::unix_error("Cannot remove file "+file);
}
}; };
//============================================================================ //============================================================================
/** @brief Directory access
Parse through directories:
@code
mrw::Dir dir(mrw::ifelse(getenv("HOME"), ""));
while (dir) {
std::cout<<"Found ["<<dir().typestr()<<"] "<<dir().name()<<std::endl;
}
@endcode
*/
class Dir { class Dir {
//............................................................... typedefs //............................................................... typedefs
public: public:
//------------------------------------------------------------------ Entry //------------------------------------------------------------------ Entry
/** @brief a directory entry
A Directory Entry. */
class Entry { class Entry {
//........................................................... typedefs //........................................................... typedefs
@ -173,9 +203,11 @@ namespace mrw {
The type of the actual file. The type of the actual file.
@note On some systems UNKNOWN is the only @note On some systems UNKNOWN is the only
value returned. value returned. This is i.e. true on
LINUX...
*/ */
enum FileType { enum FileType {
#ifdef _DIRENT_HAVE_D_TYPE
UNKNOWN = DT_UNKNOWN, ///< The type is unknown. UNKNOWN = DT_UNKNOWN, ///< The type is unknown.
REGULAR = DT_REG, ///< A regular file. REGULAR = DT_REG, ///< A regular file.
DIR = DT_DIR, ///< A directory. DIR = DT_DIR, ///< A directory.
@ -183,6 +215,9 @@ namespace mrw {
SOCKET = DT_SOCK, ///< A local-domain socket. SOCKET = DT_SOCK, ///< A local-domain socket.
CHAR = DT_CHR, ///< A character device. CHAR = DT_CHR, ///< A character device.
BLOCK = DT_BLK ///< A block device. BLOCK = DT_BLK ///< A block device.
#else
UNKNOWN, REGULAR, DIR, FIFO, SOCKET, CHAR, BLOCK // dummy
#endif
}; };
//............................................................ methods //............................................................ methods
@ -191,7 +226,16 @@ namespace mrw {
Entry(): _new(true) {} Entry(): _new(true) {}
/// Get the name of the actual file. /// Get the name of the actual file.
operator const std::string&() throw(std::bad_exception) { operator const std::string&() const throw(std::bad_exception) {
if (_new) { // only convert to string once
_new = false;
_name = _dirent.d.d_name;
}
return _name;
}
/// Get the name of the actual file.
const std::string& name() const throw(std::bad_exception) {
if (_new) { // only convert to string once if (_new) { // only convert to string once
_new = false; _new = false;
_name = _dirent.d.d_name; _name = _dirent.d.d_name;
@ -205,22 +249,57 @@ namespace mrw {
} }
/// Get the type of the actual file. /// Get the type of the actual file.
operator FileType() const throw() { FileType type() const throw() {
#ifdef _DIRENT_HAVE_D_TYPE
return FileType(_dirent.d.d_type); return FileType(_dirent.d.d_type);
#else
return UNKNOWN:
#endif
} }
/// Get the type of the actual file as string.
const std::string& typestr() const throw() {
#ifdef _DIRENT_HAVE_D_TYPE
static const std::string UNKNOWN_("UNKNOWN");
static const std::string REGULAR_("REGULAR");
static const std::string DIR_("DIR");
static const std::string FIFO_("FIFO");
static const std::string SOCKET_("SOCKET");
static const std::string CHAR_("CHAR");
static const std::string BLOCK_("BLOCK");
switch (_dirent.d.d_type) {
case UNKNOWN: return UNKNOWN_;
case REGULAR: return REGULAR_;
case DIR: return DIR_;
case FIFO: return FIFO_;
case SOCKET: return SOCKET_;
case CHAR: return CHAR_;
case BLOCK: return BLOCK_;
}
abort(); // this line is never reached
#else
return "UNKNOWN";
#endif
}
//.......................................................... variables //.......................................................... variables
private: private:
friend class Dir; friend class Dir;
#ifdef NAME_MAX
union { // for portability reasons, see "info readdir_r" union { // for portability reasons, see "info readdir_r"
dirent d; dirent d;
char b[offsetof (struct dirent, d_name) + NAME_MAX + 1]; char b[offsetof (struct dirent, d_name) + NAME_MAX + 1];
} _dirent; } _dirent;
#else
union { // for portability reasons, see "info readdir_r"
dirent d;
char b[offsetof (struct dirent, d_name) + 1000 + 1];
} _dirent;
#endif
bool _new; mutable bool _new;
std::string _name; mutable std::string _name;
//............................................................ methods //............................................................ methods
private: private:
@ -241,7 +320,7 @@ namespace mrw {
@throw mrw::invalid_argument if directory cannot be opened @throw mrw::invalid_argument if directory cannot be opened
@param dir name of the directory to open @param dir name of the directory to open
@param ignoreDots ignore directories <code>.<code> and @param ignoreDots ignore directories <code>.</code> and
<code>..</code> (self anf top) <code>..</code> (self anf top)
*/ */
Dir(const std::string& dir, bool ignoreDots=true) throw(std::exception): Dir(const std::string& dir, bool ignoreDots=true) throw(std::exception):
@ -275,8 +354,10 @@ namespace mrw {
operator bool() throw() { operator bool() throw() {
static const std::string D("."), DD(".."); static const std::string D("."), DD("..");
static dirent* fake; static dirent* fake;
if (readdir_r(_dir, &_entry.entry(), &fake)) return false; if (readdir_r(_dir, &_entry.entry(), &fake) || !fake) return false;
if (_ignoreDots && _entry==Entry::DIR && (D==_entry() || D==_entry())) if (_ignoreDots
&& (_entry.type()==Entry::UNKNOWN || _entry.type()==Entry::DIR)
&& (D==_entry() || DD==_entry()))
return operator bool(); return operator bool();
return true; return true;
} }

Loading…
Cancel
Save