|
|
|
@ -1,4 +1,3 @@ |
|
|
|
|
|
|
|
|
|
/** @file
|
|
|
|
|
|
|
|
|
|
$Id$ |
|
|
|
@ -10,6 +9,9 @@ |
|
|
|
|
@license LGPL, see file <a href="license.html">COPYING</a> |
|
|
|
|
|
|
|
|
|
$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 |
|
|
|
|
correection in documentation |
|
|
|
|
|
|
|
|
@ -27,6 +29,7 @@ |
|
|
|
|
#define __MRW_FILE_HPP__ |
|
|
|
|
|
|
|
|
|
#include <mrw/exception.hpp> |
|
|
|
|
#include <mrw/errno.hpp> |
|
|
|
|
#include <string> |
|
|
|
|
#include <fstream> |
|
|
|
|
#include <sys/types.h> |
|
|
|
@ -154,15 +157,42 @@ namespace mrw { |
|
|
|
|
+filename+"'"); |
|
|
|
|
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 { |
|
|
|
|
|
|
|
|
|
//............................................................... typedefs
|
|
|
|
|
public: |
|
|
|
|
|
|
|
|
|
//------------------------------------------------------------------ Entry
|
|
|
|
|
/** @brief a directory entry
|
|
|
|
|
|
|
|
|
|
A Directory Entry. */ |
|
|
|
|
class Entry { |
|
|
|
|
|
|
|
|
|
//........................................................... typedefs
|
|
|
|
@ -173,9 +203,11 @@ namespace mrw { |
|
|
|
|
The type of the actual file. |
|
|
|
|
|
|
|
|
|
@note On some systems UNKNOWN is the only |
|
|
|
|
value returned. |
|
|
|
|
value returned. This is i.e. true on |
|
|
|
|
LINUX... |
|
|
|
|
*/ |
|
|
|
|
enum FileType { |
|
|
|
|
#ifdef _DIRENT_HAVE_D_TYPE |
|
|
|
|
UNKNOWN = DT_UNKNOWN, ///< The type is unknown.
|
|
|
|
|
REGULAR = DT_REG, ///< A regular file.
|
|
|
|
|
DIR = DT_DIR, ///< A directory.
|
|
|
|
@ -183,6 +215,9 @@ namespace mrw { |
|
|
|
|
SOCKET = DT_SOCK, ///< A local-domain socket.
|
|
|
|
|
CHAR = DT_CHR, ///< A character device.
|
|
|
|
|
BLOCK = DT_BLK ///< A block device.
|
|
|
|
|
#else |
|
|
|
|
UNKNOWN, REGULAR, DIR, FIFO, SOCKET, CHAR, BLOCK // dummy
|
|
|
|
|
#endif |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
//............................................................ methods
|
|
|
|
@ -191,7 +226,16 @@ namespace mrw { |
|
|
|
|
Entry(): _new(true) {} |
|
|
|
|
|
|
|
|
|
/// 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
|
|
|
|
|
_new = false; |
|
|
|
|
_name = _dirent.d.d_name; |
|
|
|
@ -205,22 +249,57 @@ namespace mrw { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/// 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); |
|
|
|
|
#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
|
|
|
|
|
private: |
|
|
|
|
|
|
|
|
|
friend class Dir; |
|
|
|
|
|
|
|
|
|
#ifdef NAME_MAX |
|
|
|
|
union { // for portability reasons, see "info readdir_r"
|
|
|
|
|
dirent d; |
|
|
|
|
char b[offsetof (struct dirent, d_name) + NAME_MAX + 1]; |
|
|
|
|
} _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; |
|
|
|
|
std::string _name; |
|
|
|
|
mutable bool _new; |
|
|
|
|
mutable std::string _name; |
|
|
|
|
|
|
|
|
|
//............................................................ methods
|
|
|
|
|
private: |
|
|
|
@ -241,7 +320,7 @@ namespace mrw { |
|
|
|
|
|
|
|
|
|
@throw mrw::invalid_argument if directory cannot be opened |
|
|
|
|
@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) |
|
|
|
|
*/ |
|
|
|
|
Dir(const std::string& dir, bool ignoreDots=true) throw(std::exception): |
|
|
|
@ -275,8 +354,10 @@ namespace mrw { |
|
|
|
|
operator bool() throw() { |
|
|
|
|
static const std::string D("."), DD(".."); |
|
|
|
|
static dirent* fake; |
|
|
|
|
if (readdir_r(_dir, &_entry.entry(), &fake)) return false; |
|
|
|
|
if (_ignoreDots && _entry==Entry::DIR && (D==_entry() || D==_entry())) |
|
|
|
|
if (readdir_r(_dir, &_entry.entry(), &fake) || !fake) return false; |
|
|
|
|
if (_ignoreDots |
|
|
|
|
&& (_entry.type()==Entry::UNKNOWN || _entry.type()==Entry::DIR) |
|
|
|
|
&& (D==_entry() || DD==_entry())) |
|
|
|
|
return operator bool(); |
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|