Rivet  1.8.0
osdir.hh
00001 
00019 #ifndef OSLINK_OSDIR_HEADER_H_
00020 #define OSLINK_OSDIR_HEADER_H_
00021 
00023 
00024 #if defined(unix) || defined(__unix) || defined(__unix__)
00025 #define OSLINK_OSDIR_POSIX
00026 #elif defined(_WIN32)
00027 #define OSLINK_OSDIR_WINDOWS
00028 #else
00029 #define OSLINK_OSDIR_NOTSUPPORTED
00030 #endif
00031 
00032 #include <string>
00033 
00034 #if defined(OSLINK_OSDIR_NOTSUPPORTED)
00035 
00036 namespace oslink
00037 {
00038         class directory
00039         {
00040                 public:
00041                         directory(const std::string&)           { }
00042                         operator void*() const                          { return (void*)0; }
00043                         std::string next()                                      { return ""; }
00044         };
00045 }
00046 
00047 #elif defined(OSLINK_OSDIR_POSIX)
00048 
00049 #include <sys/types.h>
00050 #include <dirent.h>
00051 
00052 namespace oslink
00053 {
00054         class directory
00055         {
00056                 public:
00057                         directory(const std::string& aName)
00058                                 : handle(opendir(aName.c_str())), willfail(false)
00059                                 {
00060                                         if (!handle)
00061                                                 willfail = true;
00062                                         else
00063                                         {
00064                                                 dirent* entry = readdir(handle);
00065                                                 if (entry)
00066                                                         current = entry->d_name;
00067                                                 else
00068                                                         willfail = true;
00069                                         }
00070                                 }
00071                         ~directory()
00072                                 {
00073                                         if (handle)
00074                                                 closedir(handle);
00075                                 }
00076                         operator void*() const
00077                                 {
00078                                         return willfail ? (void*)0:(void*)(-1);
00079                                 }
00080                         std::string next()
00081                                 {
00082                                         std::string prev(current);
00083                                         dirent* entry = readdir(handle);
00084                                         if (entry)
00085                                                 current = entry->d_name;
00086                                         else
00087                                                 willfail = true;
00088                                         return prev;
00089                                 }
00090                 private:
00091                         DIR* handle;
00092                         bool willfail;
00093                         std::string current;
00094         };
00095 }
00096 
00097 #elif defined(OSLINK_OSDIR_WINDOWS)
00098 
00099 #include <windows.h>
00100 #include <winbase.h>
00101 
00102 namespace oslink
00103 {
00104         class directory
00105         {
00106                 public:
00107                         directory(const std::string& aName)
00108                                 : handle(INVALID_HANDLE_VALUE), willfail(false)
00109                                 {
00110                                         // First check the attributes trying to access a non-directory with
00111                                         // FindFirstFile takes ages
00112                                         DWORD attrs = GetFileAttributes(aName.c_str());
00113                                         if ( (attrs == 0xFFFFFFFF) || ((attrs && FILE_ATTRIBUTE_DIRECTORY) == 0) )
00114                                         {
00115                                                 willfail = true;
00116                                                 return;
00117                                         }
00118                                         std::string Full(aName);
00119                                         // Circumvent a problem in FindFirstFile with c:\\* as parameter
00120                                         if ( (Full.length() > 0) && (Full[Full.length()-1] != '\\') )
00121                                                 Full += "\\";
00122                                         WIN32_FIND_DATA entry;
00123                                         handle = FindFirstFile( (Full+"*").c_str(), &entry);
00124                                         if (handle == INVALID_HANDLE_VALUE)
00125                                                 willfail = true;
00126                                         else
00127                                                 current = entry.cFileName;
00128                                 }
00129                         ~directory()
00130                                 {
00131                                         if (handle != INVALID_HANDLE_VALUE)
00132                                                 FindClose(handle);
00133                                 }
00134 
00135                         operator void*() const
00136                                 {
00137                                         return willfail ? (void*)0:(void*)(-1);
00138                                 }
00139                         std::string next()
00140                                 {
00141                                         std::string prev = current;
00142                                         WIN32_FIND_DATA entry;
00143                                         int ok = FindNextFile(handle, &entry);
00144                                         if (!ok)
00145                                                 willfail = true;
00146                                         else
00147                                                 current = entry.cFileName;
00148                                         return current;
00149                                 }
00150                 private:
00151                         HANDLE  handle;
00152                         bool    willfail;
00153                         std::string current;
00154         };
00155 }
00156 
00157 
00158 #endif
00159 
00161 
00162 #endif
00163