Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "utilite/UDirectory.h"
00023
00024 #ifdef WIN32
00025 #include <Windows.h>
00026 #include <direct.h>
00027 #include <algorithm>
00028 #include <conio.h>
00029 #else
00030 #include <dirent.h>
00031 #include <sys/stat.h>
00032 #include <sys/types.h>
00033 #include <sys/param.h>
00034 #include <sys/dir.h>
00035 #include <unistd.h>
00036 #include <stdlib.h>
00037 #include <string.h>
00038 #endif
00039
00040 #include "utilite/UStl.h"
00041 #include "utilite/UFile.h"
00042 #include "utilite/UDirectory.h"
00043 #include "utilite/UConversion.h"
00044
00045 #ifdef WIN32
00046
00047 bool sortCallback(const std::string & a, const std::string & b)
00048 {
00049 return uStrNumCmp(a,b) < 0;
00050 }
00051 #elif __APPLE__
00052 int sortCallback(const struct dirent ** a, const struct dirent ** b)
00053 {
00054 return uStrNumCmp((*a)->d_name, (*b)->d_name);
00055 }
00056 #else
00057 int sortCallback( const dirent ** a, const dirent ** b)
00058 {
00059 return uStrNumCmp((*a)->d_name, (*b)->d_name);
00060 }
00061 #endif
00062
00063 UDirectory::UDirectory(const std::string & path, const std::string & extensions)
00064 {
00065 extensions_ = uListToVector(uSplit(extensions, ' '));
00066 path_ = path;
00067 iFileName_ = fileNames_.begin();
00068 this->update();
00069 }
00070
00071 UDirectory::UDirectory(const UDirectory & dir)
00072 {
00073 *this = dir;
00074 }
00075
00076 UDirectory & UDirectory::operator=(const UDirectory & dir)
00077 {
00078 extensions_ = dir.extensions_;
00079 path_ = dir.path_;
00080 fileNames_ = dir.fileNames_;
00081 for(iFileName_=fileNames_.begin(); iFileName_!=fileNames_.end(); ++iFileName_)
00082 {
00083 if(iFileName_->compare(*dir.iFileName_) == 0)
00084 {
00085 break;
00086 }
00087 }
00088 return *this;
00089 }
00090
00091 UDirectory::~UDirectory()
00092 {
00093 }
00094
00095 void UDirectory::setPath(const std::string & path, const std::string & extensions)
00096 {
00097 extensions_ = uListToVector(uSplit(extensions, ' '));
00098 path_ = path;
00099 fileNames_.clear();
00100 iFileName_ = fileNames_.begin();
00101 this->update();
00102 }
00103
00104 void UDirectory::update()
00105 {
00106 if(exists(path_))
00107 {
00108 std::string lastName;
00109 bool endOfDir = false;
00110 if(iFileName_ != fileNames_.end())
00111 {
00112
00113 lastName = *iFileName_;
00114 }
00115 else if(fileNames_.size())
00116 {
00117 lastName = *fileNames_.rbegin();
00118 endOfDir = true;
00119 }
00120 fileNames_.clear();
00121 #ifdef WIN32
00122 WIN32_FIND_DATA fileInformation;
00123 #ifdef UNICODE
00124 wchar_t * pathAll = createWCharFromChar((path_+"\\*").c_str());
00125 HANDLE hFile = ::FindFirstFile(pathAll, &fileInformation);
00126 delete [] pathAll;
00127 #else
00128 HANDLE hFile = ::FindFirstFile((path_+"\\*").c_str(), &fileInformation);
00129 #endif
00130 if(hFile != INVALID_HANDLE_VALUE)
00131 {
00132 do
00133 {
00134 #ifdef UNICODE
00135 char * fileName = createCharFromWChar(fileInformation.cFileName);
00136 fileNames_.push_back(fileName);
00137 delete [] fileName;
00138 #else
00139 fileNames_.push_back(fileInformation.cFileName);
00140 #endif
00141 } while(::FindNextFile(hFile, &fileInformation) == TRUE);
00142 ::FindClose(hFile);
00143 std::vector<std::string> vFileNames = uListToVector(fileNames_);
00144 std::sort(vFileNames.begin(), vFileNames.end(), sortCallback);
00145 fileNames_ = uVectorToList(vFileNames);
00146 }
00147 #else
00148 int nameListSize;
00149 struct dirent ** nameList = 0;
00150 nameListSize = scandir(path_.c_str(), &nameList, 0, sortCallback);
00151 if(nameList && nameListSize>0)
00152 {
00153 for (int i=0;i<nameListSize;++i)
00154 {
00155 fileNames_.push_back(nameList[i]->d_name);
00156 free(nameList[i]);
00157 }
00158 free(nameList);
00159 }
00160 #endif
00161
00162
00163 std::list<std::string>::iterator iter = fileNames_.begin();
00164 bool valid;
00165 while(iter!=fileNames_.end())
00166 {
00167 valid = false;
00168 if(extensions_.size() == 0 &&
00169 iter->compare(".") != 0 &&
00170 iter->compare("..") != 0)
00171 {
00172 valid = true;
00173 }
00174 for(unsigned int i=0; i<extensions_.size(); ++i)
00175 {
00176 if(UFile::getExtension(*iter).compare(extensions_[i]) == 0)
00177 {
00178 valid = true;
00179 break;
00180 }
00181 }
00182 if(!valid)
00183 {
00184 iter = fileNames_.erase(iter);
00185 }
00186 else
00187 {
00188 ++iter;
00189 }
00190 }
00191 iFileName_ = fileNames_.begin();
00192 if(!lastName.empty())
00193 {
00194 bool found = false;
00195 for(std::list<std::string>::iterator iter=fileNames_.begin(); iter!=fileNames_.end(); ++iter)
00196 {
00197 if(lastName.compare(*iter) == 0)
00198 {
00199 found = true;
00200 iFileName_ = iter;
00201 break;
00202 }
00203 }
00204 if(endOfDir && found)
00205 {
00206 ++iFileName_;
00207 }
00208 else if(endOfDir && fileNames_.size())
00209 {
00210 iFileName_ = --fileNames_.end();
00211 }
00212 }
00213 }
00214 }
00215
00216 bool UDirectory::isValid()
00217 {
00218 return exists(path_);
00219 }
00220
00221 std::string UDirectory::getNextFileName()
00222 {
00223 std::string fileName;
00224 if(iFileName_ != fileNames_.end())
00225 {
00226 fileName = *iFileName_;
00227 ++iFileName_;
00228 }
00229 return fileName;
00230 }
00231
00232 void UDirectory::rewind()
00233 {
00234 iFileName_ = fileNames_.begin();
00235 }
00236
00237
00238 bool UDirectory::exists(const std::string & dirPath)
00239 {
00240 bool r = false;
00241 #if WIN32
00242 #ifdef UNICODE
00243 wchar_t * wDirPath = createWCharFromChar(dirPath.c_str());
00244 DWORD dwAttrib = GetFileAttributes(wDirPath);
00245 delete [] wDirPath;
00246 #else
00247 DWORD dwAttrib = GetFileAttributes(dirPath.c_str());
00248 #endif
00249 r = (dwAttrib != INVALID_FILE_ATTRIBUTES && (dwAttrib & FILE_ATTRIBUTE_DIRECTORY));
00250 #else
00251 DIR *dp;
00252 if((dp = opendir(dirPath.c_str())) != NULL)
00253 {
00254 r = true;
00255 closedir(dp);
00256 }
00257 #endif
00258 return r;
00259 }
00260
00261
00262 std::string UDirectory::getDir(const std::string & filePath)
00263 {
00264 std::string dir = filePath;
00265 int i=dir.size()-1;
00266 for(; i>=0; --i)
00267 {
00268 if(dir[i] == '/' || dir[i] == '\\')
00269 {
00270
00271 dir[i] = 0;
00272 --i;
00273 while(i>=0 && (dir[i] == '/' || dir[i] == '\\'))
00274 {
00275 dir[i] = 0;
00276 --i;
00277 }
00278 break;
00279 }
00280 else
00281 {
00282 dir[i] = 0;
00283 }
00284 }
00285
00286 if(i<0)
00287 {
00288 dir = ".";
00289 }
00290 else
00291 {
00292 dir.resize(i+1);
00293 }
00294
00295 return dir;
00296 }
00297
00298 std::string UDirectory::currentDir(bool trailingSeparator)
00299 {
00300 std::string dir;
00301 char * buffer;
00302
00303 #ifdef WIN32
00304 buffer = _getcwd(NULL, 0);
00305 #else
00306 buffer = getcwd(NULL, MAXPATHLEN);
00307 #endif
00308
00309 if( buffer != NULL )
00310 {
00311 dir = buffer;
00312 free(buffer);
00313 if(trailingSeparator)
00314 {
00315 dir += separator();
00316 }
00317 }
00318
00319 return dir;
00320 }
00321
00322 bool UDirectory::makeDir(const std::string & dirPath)
00323 {
00324 int status;
00325 #if WIN32
00326 status = _mkdir(dirPath.c_str());
00327 #else
00328 status = mkdir(dirPath.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
00329 #endif
00330 return status==0;
00331 }
00332
00333 bool UDirectory::removeDir(const std::string & dirPath)
00334 {
00335 int status;
00336 #if WIN32
00337 status = _rmdir(dirPath.c_str());
00338 #else
00339 status = rmdir(dirPath.c_str());
00340 #endif
00341 return status==0;
00342 }
00343
00344 std::string UDirectory::homeDir()
00345 {
00346 std::string path;
00347 #if WIN32
00348 #ifdef UNICODE
00349 wchar_t wProfilePath[250];
00350 ExpandEnvironmentStrings(L"%userprofile%",wProfilePath,250);
00351 char * profilePath = createCharFromWChar(wProfilePath);
00352 path = profilePath;
00353 delete [] profilePath;
00354 #else
00355 char profilePath[250];
00356 ExpandEnvironmentStrings("%userprofile%",profilePath,250);
00357 path = profilePath;
00358 #endif
00359 #else
00360 path = getenv("HOME");
00361 #endif
00362 return path;
00363 }
00364
00365 std::string UDirectory::separator()
00366 {
00367 #ifdef WIN32
00368 return "\\";
00369 #else
00370 return "/";
00371 #endif
00372 }